mirror of
https://github.com/Lacustat/Freewood-OctoWoW-Codex.git
synced 2026-11-03 16:06:56 +00:00
0.1.224: Wegzeiten des Plans auf grobem Raster (viel schneller), Ruckler beim Anmelden behoben
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016onJCSHLwhs9udhC9ZLzk9
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
c045446264
commit
ea945b98f8
+50
-13
@@ -758,6 +758,8 @@ end
|
||||
local NAV_COST = { [0] = 0, 1.0 / 1.4, 1.0, 1.4, 1.8, 2.2 } -- Kostenfaktor je Klasse (a gesperrt, b Strasse, c normal, d huegelig, e steil, f Wasser)
|
||||
local NAV_WALKED = 0.8
|
||||
local NAV_MAX_EXPAND = 30000
|
||||
local NAV_PLAN_MAX = 8000 -- Luftlinie, bis zu der der Plan (Wegzeiten) auf dem Raster rechnet
|
||||
local NAV_PLAN_EXPAND = 1500 -- Suchschritte je Wegzeit-Berechnung (mehr gibt es nur fuer die Anzeige des Wegs)
|
||||
local NAV_SNAP = 6 -- Zellen, so weit darf ein Ort von begehbarem Gelaende entfernt sein
|
||||
local navs = {} -- [welt] = { w, h, cell, left, top, cls = { [idx] = klasse }, walked = { [idx] = true }, rev, built, cache = {} }
|
||||
|
||||
@@ -777,11 +779,38 @@ local function NavLoad(world)
|
||||
end
|
||||
end
|
||||
end
|
||||
n = { w = src.w, h = src.h, cell = src.cell, left = src.left, top = src.top, cls = cls, walked = {}, rev = -1, built = 0, cache = {} }
|
||||
n = { w = src.w, h = src.h, cell = src.cell, left = src.left, top = src.top, cls = cls, walked = {}, rev = -1, built = 0, cache = {}, fail = {}, costs = NAV_COST }
|
||||
navs[world] = n
|
||||
return n
|
||||
end
|
||||
|
||||
-- grobes Raster (4 x 4 Zellen = 167 Yards) fuer die Wegzeiten des Plans: viel schneller zu durchsuchen
|
||||
local COARSE = 4
|
||||
local function NavCoarse(n)
|
||||
if n.coarse then return n.coarse end
|
||||
local w, h, cls = n.w, n.h, n.cls
|
||||
local cw, ch = math.ceil(w / COARSE), math.ceil(h / COARSE)
|
||||
local c = {}
|
||||
for cr = 0, ch - 1 do
|
||||
for cc = 0, cw - 1 do
|
||||
local sum, open, tot = 0, 0, 0
|
||||
for r = cr * COARSE, math.min(h, cr * COARSE + COARSE) - 1 do
|
||||
local base = r * w + 1
|
||||
for k = cc * COARSE, math.min(w, cc * COARSE + COARSE) - 1 do
|
||||
tot = tot + 1
|
||||
local cl = cls[base + k]
|
||||
if cl ~= 0 then open = open + 1 sum = sum + NAV_COST[cl] end
|
||||
end
|
||||
end
|
||||
local v = 0
|
||||
if open > 0 then v = (sum / open) * (1 + 0.5 * (1 - open / tot)) end
|
||||
c[cr * cw + cc + 1] = v
|
||||
end
|
||||
end
|
||||
n.coarse = { w = cw, h = ch, cell = n.cell * COARSE, left = n.left, top = n.top, cls = c, walked = {}, cache = {}, fail = {} }
|
||||
return n.coarse
|
||||
end
|
||||
|
||||
-- gelaufene Zellen auf das Raster legen (hoechstens alle GRAPH_STALE Sekunden neu, wenn es neue Daten gibt)
|
||||
local function NavWalked(n, world)
|
||||
local rev = Path.rev or 0
|
||||
@@ -797,7 +826,7 @@ local function NavWalked(n, world)
|
||||
if row >= 0 and row < n.h and col >= 0 and col < n.w then walked[row * n.w + col + 1] = true end
|
||||
end
|
||||
end
|
||||
n.walked, n.rev, n.built, n.cache = walked, rev, now, {}
|
||||
n.walked, n.rev, n.built, n.cache, n.fail = walked, rev, now, {}, {}
|
||||
end
|
||||
|
||||
local function NavCell(n, x, y)
|
||||
@@ -833,8 +862,8 @@ end
|
||||
local NAV_DIRS = { { 1, 0, 1 }, { -1, 0, 1 }, { 0, 1, 1 }, { 0, -1, 1 }, { 1, 1, 1.4142 }, { 1, -1, 1.4142 }, { -1, 1, 1.4142 }, { -1, -1, 1.4142 } }
|
||||
|
||||
-- A* von Zelle a nach Zelle b. Rueckgabe: Liste von Zellindizes (a ... b) oder nil
|
||||
local function NavSearch(n, a, b)
|
||||
local w, h, cls, walked = n.w, n.h, n.cls, n.walked
|
||||
local function NavSearch(n, a, b, maxExp)
|
||||
local w, h, cls, walked, costs = n.w, n.h, n.cls, n.walked, n.costs
|
||||
local bi = b - 1
|
||||
local br, bc = math.floor(bi / w), bi % w
|
||||
local g, prev, closed = { [a] = 0 }, {}, {}
|
||||
@@ -869,7 +898,7 @@ local function NavSearch(n, a, b)
|
||||
end
|
||||
return top
|
||||
end
|
||||
local function H(r, c) return 0.7 * math.sqrt((r - br) ^ 2 + (c - bc) ^ 2) * 1.15 end
|
||||
local function H(r, c) return math.sqrt((r - br) ^ 2 + (c - bc) ^ 2) end
|
||||
local ai = a - 1
|
||||
Push(a, H(math.floor(ai / w), ai % w))
|
||||
local expanded = 0
|
||||
@@ -884,7 +913,7 @@ local function NavSearch(n, a, b)
|
||||
if not closed[k] then
|
||||
closed[k] = true
|
||||
expanded = expanded + 1
|
||||
if expanded > NAV_MAX_EXPAND then return nil end
|
||||
if expanded > (maxExp or NAV_MAX_EXPAND) then return nil end
|
||||
local ki = k - 1
|
||||
local r, c = math.floor(ki / w), ki % w
|
||||
local gk = g[k]
|
||||
@@ -895,8 +924,13 @@ local function NavSearch(n, a, b)
|
||||
local nk = rr * w + cc + 1
|
||||
local cl = cls[nk]
|
||||
if cl and cl ~= 0 and not closed[nk] then
|
||||
local f = walked[nk] and NAV_WALKED or NAV_COST[cl]
|
||||
if walked[nk] and cl == 5 then f = NAV_COST[5] end
|
||||
local f
|
||||
if costs then
|
||||
f = costs[cl]
|
||||
if walked[nk] and cl ~= 5 then f = NAV_WALKED end
|
||||
else
|
||||
f = cl
|
||||
end
|
||||
local ng = gk + d[3] * f
|
||||
if not g[nk] or ng < g[nk] then
|
||||
g[nk] = ng
|
||||
@@ -912,10 +946,11 @@ local function NavSearch(n, a, b)
|
||||
end
|
||||
|
||||
-- Weg zwischen zwei Orten (Yards im Zellraum): Zellmitten als { x, y }, Laenge in Yards (ohne Anschluss an die Enden), Entfernung der Enden zum Netz
|
||||
local function NavPath(world, ax, ay, bx, by)
|
||||
local function NavPath(world, ax, ay, bx, by, maxExp, coarse)
|
||||
local n = NavLoad(world)
|
||||
if not n then return nil end
|
||||
NavWalked(n, world)
|
||||
if coarse then n = NavCoarse(n) end
|
||||
local ar, ac = NavCell(n, ax, ay)
|
||||
local br, bc = NavCell(n, bx, by)
|
||||
local a, ar2, ac2 = NavSnap(n, ar, ac)
|
||||
@@ -924,11 +959,12 @@ local function NavPath(world, ax, ay, bx, by)
|
||||
local ck = a .. ":" .. b
|
||||
local hit = n.cache[ck]
|
||||
local chain
|
||||
if hit ~= nil then
|
||||
if hit ~= nil and (hit or (n.fail[ck] or 0) >= (maxExp or NAV_MAX_EXPAND)) then
|
||||
chain = hit or nil
|
||||
else
|
||||
chain = a == b and { a } or NavSearch(n, a, b)
|
||||
chain = a == b and { a } or NavSearch(n, a, b, maxExp)
|
||||
n.cache[ck] = chain or false
|
||||
n.fail[ck] = (not chain) and (maxExp or NAV_MAX_EXPAND) or nil
|
||||
end
|
||||
if not chain then return nil end
|
||||
local pts = {}
|
||||
@@ -1072,8 +1108,9 @@ function Path.Distance(world, ax, ay, bx, by)
|
||||
if type(world) ~= "number" then return nil end
|
||||
local straight = math.sqrt((ax - bx) ^ 2 + (ay - by) ^ 2)
|
||||
if straight < 2 * BLOCK * CELL then return nil end
|
||||
local pts, len, na, nb = NavPath(world, ax, ay, bx, by)
|
||||
if pts then return na + len + nb end
|
||||
if straight > NAV_PLAN_MAX then return nil end
|
||||
local pts, len, na, nb = NavPath(world, ax, ay, bx, by, NAV_PLAN_EXPAND, true)
|
||||
if pts then return na + len * 0.93 + nb end
|
||||
local g = Graph(world)
|
||||
if not g then return nil end
|
||||
local sa, da = Snap(g, ax, ay)
|
||||
|
||||
Reference in New Issue
Block a user