mirror of
https://github.com/Lacustat/Freewood-OctoWoW-Codex.git
synced 2026-11-04 07:16:56 +00:00
0.1.219: Flugnetz und Weg zum Ziel im Levelplan (Version)
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
fbbd324609
commit
e1b89f4843
+38
-2
@@ -776,7 +776,7 @@ local function Snap(g, x, y)
|
||||
end
|
||||
|
||||
-- A* ueber die Bloecke. Rueckgabe: Strecke in Yards oder nil
|
||||
local function Search(g, from, to)
|
||||
local function Search(g, from, to, wantPrev)
|
||||
local nodes = g.nodes
|
||||
local goal = nodes[to]
|
||||
if not goal then return nil end
|
||||
@@ -785,6 +785,7 @@ local function Search(g, from, to)
|
||||
return 1.2 * math.sqrt(((n.bx + 0.5) * BLOCK * CELL - gx) ^ 2 + ((n.by + 0.5) * BLOCK * CELL - gy) ^ 2)
|
||||
end
|
||||
local dist, heap, size, done = { [from] = 0 }, {}, 0, {}
|
||||
local prev = wantPrev and {} or nil
|
||||
local function Push(k, pr)
|
||||
size = size + 1
|
||||
local i = size
|
||||
@@ -816,7 +817,7 @@ local function Search(g, from, to)
|
||||
local expanded = 0
|
||||
while size > 0 do
|
||||
local k = Pop()
|
||||
if k == to then return dist[k] end
|
||||
if k == to then return dist[k], prev end
|
||||
if not done[k] then
|
||||
done[k] = true
|
||||
expanded = expanded + 1
|
||||
@@ -825,6 +826,7 @@ local function Search(g, from, to)
|
||||
local nd = dist[k] + cost
|
||||
if not dist[nk] or nd < dist[nk] then
|
||||
dist[nk] = nd
|
||||
if prev then prev[nk] = k end
|
||||
Push(nk, nd + H(nodes[nk]))
|
||||
end
|
||||
end
|
||||
@@ -890,6 +892,40 @@ function Path.Distance(world, ax, ay, bx, by)
|
||||
return da + cost + db_
|
||||
end
|
||||
|
||||
-- Zwischenziele laengs des Wegenetzes von (ax, ay) nach (bx, by) (Zellraum, Yards): Liste { x, y } mit etwa "step" Yards Abstand,
|
||||
-- ohne Start, mit Ziel als letztem Punkt. nil, wenn kein zusammenhaengendes Netz bekannt ist (dann Luftlinie).
|
||||
function Path.Route(world, ax, ay, bx, by, step)
|
||||
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 g = Graph(world)
|
||||
if not g then return nil end
|
||||
local sa = Snap(g, ax, ay)
|
||||
local sb = Snap(g, bx, by)
|
||||
if not sa or not sb or sa == sb or g.comp[sa] ~= g.comp[sb] then return nil end
|
||||
local cost, prev = Search(g, sa, sb, true)
|
||||
if not cost or not prev then return nil end
|
||||
local chain, k, guard = {}, sb, 0
|
||||
while k and guard < 5000 do
|
||||
local nd = g.nodes[k]
|
||||
table.insert(chain, 1, { (nd.bx + 0.5) * BLOCK * CELL, (nd.by + 0.5) * BLOCK * CELL })
|
||||
if k == sa then break end
|
||||
k = prev[k]
|
||||
guard = guard + 1
|
||||
end
|
||||
step = step or 250
|
||||
local out, last = {}, { ax, ay }
|
||||
for i, p in ipairs(chain) do
|
||||
if i == #chain then
|
||||
out[#out + 1] = { bx, by }
|
||||
elseif math.sqrt((p[1] - last[1]) ^ 2 + (p[2] - last[2]) ^ 2) >= step then
|
||||
out[#out + 1] = p
|
||||
last = p
|
||||
end
|
||||
end
|
||||
return out, cost
|
||||
end
|
||||
|
||||
function Path.ResetGraphs()
|
||||
graphs = {}
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user