Rolled back changes committed in r116 and r118. Implemented 'remapping' suggested by lonadar in comment 8 on issue 307. This is a far cleaner hack than it was. I'm sure further modifications will be necessary, but this is a start.
Cette révision appartient à :
Parent
617f265558
révision
9fe0b3c0fa
|
@ -131,12 +131,10 @@ local prepared = false
|
|||
local linktime = 0
|
||||
|
||||
function QH_Graph_Pathmultifind(st, nda, reverse, make_path)
|
||||
QuestHelper: Assert(st.x and st.y and st.p)
|
||||
if st.p == 26 then return nil end -- DENIED!!!!
|
||||
|
||||
--QuestHelper:TextOut("Starting PMF")
|
||||
QuestHelper: Assert(not active)
|
||||
QuestHelper: Assert(prepared)
|
||||
QuestHelper: Assert(st.x and st.y and st.p)
|
||||
active = true -- The fun thing about coroutines is that this is actually safe.
|
||||
local out = QuestHelper:CreateTable("graphcore output") -- THIS HAD BETTER BE RELEASABLE OR IT WILL BE BAD
|
||||
|
||||
|
@ -149,9 +147,12 @@ function QH_Graph_Pathmultifind(st, nda, reverse, make_path)
|
|||
|
||||
--stats.dests_complex = 0
|
||||
--stats.dests_total = 0
|
||||
|
||||
if st.p == 26 then st.p = 48 end -- Alterac Mountains merged to Hillsbrad Foothills
|
||||
|
||||
for k, v in ipairs(nda) do
|
||||
QuestHelper: Assert(v.x and v.y and v.p)
|
||||
if v.p == 26 then v.p = 48 end -- Alterac Mountains merged to Hillsbrad Foothills
|
||||
local cpvp = canoplane(v.p)
|
||||
if plane[cpvp] then
|
||||
--print("Destination plane insertion")
|
||||
|
@ -183,14 +184,12 @@ function QH_Graph_Pathmultifind(st, nda, reverse, make_path)
|
|||
local stnode = QuestHelper:CreateTable("graphcore stnode")
|
||||
do
|
||||
stnode.x, stnode.y, stnode.p, stnode.c, stnode.scan_id, stnode.scan_cost = st.x, st.y, canoplane(st.p), st.c, grid, 0
|
||||
if canoplane(st.p) ~= 26 then
|
||||
QuestHelper: Assert(plane[canoplane(st.p)], "Plane " .. canoplane(st.p) .. " does not exist.")
|
||||
tinsert(plane[stnode.p], stnode)
|
||||
QuestHelper: Assert(plane[canoplane(st.p)], "Plane " .. canoplane(st.p) .. " does not exist.")
|
||||
tinsert(plane[stnode.p], stnode)
|
||||
|
||||
local hep = QuestHelper:CreateTable("graphcore heap")
|
||||
hep.c, hep.n = 0, stnode -- more than the subtraction, less than the minimum
|
||||
heap_insert(dijheap, hep)
|
||||
end
|
||||
local hep = QuestHelper:CreateTable("graphcore heap")
|
||||
hep.c, hep.n = 0, stnode -- more than the subtraction, less than the minimum
|
||||
heap_insert(dijheap, hep)
|
||||
end
|
||||
|
||||
--stats.heap_max = #dijheap
|
||||
|
|
|
@ -101,16 +101,12 @@ local function GetCachedPath(loc1, loc2)
|
|||
-- Not in either, time to create
|
||||
misses = misses + 1
|
||||
local nrt = QH_Graph_Pathfind(loc1.loc, loc2.loc, false, true)
|
||||
if nrt then
|
||||
QuestHelper: Assert(nrt)
|
||||
if not pathcache_active[loc1] then pathcache_active[loc1] = new_pathcache_table() end
|
||||
if not pathcache_inactive[loc1] then pathcache_inactive[loc1] = new_pathcache_table() end
|
||||
pathcache_active[loc1][loc2] = nrt
|
||||
pathcache_inactive[loc1][loc2] = nrt
|
||||
return nrt
|
||||
else
|
||||
return nil
|
||||
end
|
||||
QuestHelper: Assert(nrt)
|
||||
if not pathcache_active[loc1] then pathcache_active[loc1] = new_pathcache_table() end
|
||||
if not pathcache_inactive[loc1] then pathcache_inactive[loc1] = new_pathcache_table() end
|
||||
pathcache_active[loc1][loc2] = nrt
|
||||
pathcache_inactive[loc1][loc2] = nrt
|
||||
return nrt
|
||||
else
|
||||
hits = hits + 1
|
||||
if not pathcache_active[loc1] then pathcache_active[loc1] = new_pathcache_table() end
|
||||
|
@ -138,53 +134,51 @@ local function ReplotPath(progress)
|
|||
|
||||
if last_path[k + 1] then
|
||||
local nrt = GetCachedPath(last_path[k], last_path[k + 1])
|
||||
if nrt then
|
||||
distance = distance + nrt.d
|
||||
QuestHelper: Assert(nrt)
|
||||
distance = distance + nrt.d
|
||||
QuestHelper: Assert(nrt)
|
||||
|
||||
-- The "condense" is kind of weird - we're actually condensing descriptions, but we condense to the *last* item. Urgh.
|
||||
local condense_start = nil
|
||||
local condense_class = nil
|
||||
local condense_to = nil
|
||||
-- The "condense" is kind of weird - we're actually condensing descriptions, but we condense to the *last* item. Urgh.
|
||||
local condense_start = nil
|
||||
local condense_class = nil
|
||||
local condense_to = nil
|
||||
|
||||
-- ugh this is just easier
|
||||
local function condense_doit()
|
||||
--print("start condense doit, was", real_path[condense_start].map_desc[1])
|
||||
for i = condense_start, #real_path do
|
||||
real_path[i].map_desc = condense_to
|
||||
end
|
||||
--print("end condense doit, now", real_path[condense_start].map_desc[1])
|
||||
condense_start, condense_class, condense_to = nil, nil, nil
|
||||
-- ugh this is just easier
|
||||
local function condense_doit()
|
||||
--print("start condense doit, was", real_path[condense_start].map_desc[1])
|
||||
for i = condense_start, #real_path do
|
||||
real_path[i].map_desc = condense_to
|
||||
end
|
||||
|
||||
if #nrt > 0 then for _, wp in ipairs(nrt) do
|
||||
QuestHelper: Assert(wp.c)
|
||||
|
||||
--print(wp.condense_class)
|
||||
if condense_class and condense_class ~= wp.condense_class then condense_doit() end
|
||||
|
||||
local pathnode = QuestHelper:CreateTable("pathnode")
|
||||
pathnode.loc = QuestHelper:CreateTable("pathnode.loc")
|
||||
pathnode.loc.x = wp.x
|
||||
pathnode.loc.y = wp.y
|
||||
pathnode.loc.c = wp.c
|
||||
pathnode.ignore = true
|
||||
pathnode.map_desc = wp.map_desc
|
||||
pathnode.map_desc_chain = last_path[k + 1]
|
||||
pathnode.local_allocated = true
|
||||
pathnode.cluster = last_path[k + 1].cluster
|
||||
table.insert(real_path, pathnode) -- Technically, we'll end up with the distance to the next objective. I'm okay with this.
|
||||
|
||||
if not condense_class and wp.condense_class then
|
||||
condense_start, condense_class = #real_path, wp.condense_class
|
||||
end
|
||||
if condense_class then
|
||||
condense_to = wp.map_desc
|
||||
end
|
||||
end end
|
||||
|
||||
if condense_class then condense_doit() end -- in case we have stuff left over
|
||||
--print("end condense doit, now", real_path[condense_start].map_desc[1])
|
||||
condense_start, condense_class, condense_to = nil, nil, nil
|
||||
end
|
||||
|
||||
if #nrt > 0 then for _, wp in ipairs(nrt) do
|
||||
QuestHelper: Assert(wp.c)
|
||||
|
||||
--print(wp.condense_class)
|
||||
if condense_class and condense_class ~= wp.condense_class then condense_doit() end
|
||||
|
||||
local pathnode = QuestHelper:CreateTable("pathnode")
|
||||
pathnode.loc = QuestHelper:CreateTable("pathnode.loc")
|
||||
pathnode.loc.x = wp.x
|
||||
pathnode.loc.y = wp.y
|
||||
pathnode.loc.c = wp.c
|
||||
pathnode.ignore = true
|
||||
pathnode.map_desc = wp.map_desc
|
||||
pathnode.map_desc_chain = last_path[k + 1]
|
||||
pathnode.local_allocated = true
|
||||
pathnode.cluster = last_path[k + 1].cluster
|
||||
table.insert(real_path, pathnode) -- Technically, we'll end up with the distance to the next objective. I'm okay with this.
|
||||
|
||||
if not condense_class and wp.condense_class then
|
||||
condense_start, condense_class = #real_path, wp.condense_class
|
||||
end
|
||||
if condense_class then
|
||||
condense_to = wp.map_desc
|
||||
end
|
||||
end end
|
||||
|
||||
if condense_class then condense_doit() end -- in case we have stuff left over
|
||||
end
|
||||
|
||||
if progress then progress:SetPercentage(k / #last_path) end
|
||||
|
@ -377,66 +371,62 @@ Route_Core_Init(
|
|||
|
||||
rvv = QuestHelper:CreateTable("route controller path shunt returnvalue")
|
||||
local rv = QH_Graph_Pathmultifind(loc1.loc, lt, reverse, true)
|
||||
if rv ~= nil then
|
||||
QuestHelper: Assert(#lt == #rv, string.format("lt has %d items, rt has %d items. Both should be the same.", #lt, #rv))
|
||||
QuestHelper: Assert(#lt == #rv, string.format("lt has %d items, rt has %d items. Both should be the same.", #lt, #rv))
|
||||
|
||||
-- We want to store the math.max(sqrt(#rv), 10) shortest paths
|
||||
local tostore = complete_pass and math.max(sqrt(#rv), 10) or #rv
|
||||
--print("would store", #rv, "am store", tostore)
|
||||
local linkity = QuestHelper:CreateTable("shortest path summary")
|
||||
for k, v in ipairs(rv) do
|
||||
local tk = QuestHelper:CreateTable("shortest path summary item")
|
||||
tk.k = k
|
||||
tk.v = v
|
||||
table.insert(linkity, tk)
|
||||
-- We want to store the math.max(sqrt(#rv), 10) shortest paths
|
||||
local tostore = complete_pass and math.max(sqrt(#rv), 10) or #rv
|
||||
--print("would store", #rv, "am store", tostore)
|
||||
local linkity = QuestHelper:CreateTable("shortest path summary")
|
||||
for k, v in ipairs(rv) do
|
||||
local tk = QuestHelper:CreateTable("shortest path summary item")
|
||||
tk.k = k
|
||||
tk.v = v
|
||||
table.insert(linkity, tk)
|
||||
|
||||
rvv[k] = rv[k].d
|
||||
end
|
||||
|
||||
table.sort(linkity, function(a, b) return a.v.d < b.v.d end)
|
||||
while #linkity > tostore do
|
||||
local rip = table.remove(linkity)
|
||||
QuestHelper:ReleaseTable(rip.v)
|
||||
QuestHelper:ReleaseTable(rip)
|
||||
end
|
||||
|
||||
for _, it in pairs(linkity) do
|
||||
local k, v = it.k, it.v
|
||||
|
||||
if not rv[k] then
|
||||
QuestHelper:TextOut(QuestHelper:StringizeTable(loc1.loc))
|
||||
QuestHelper:TextOut(QuestHelper:StringizeTable(lt[k]))
|
||||
end
|
||||
QuestHelper: Assert(rv[k], string.format("%d to %d", loc1.loc.p, loctable[k].loc.p))
|
||||
QuestHelper: Assert(rv[k].d)
|
||||
|
||||
-- We're only setting the inactive to give the garbage collector potentially a little more to clean up (i.e. the old path.)
|
||||
if not reverse then
|
||||
QuestHelper: Assert(pathcache_active[loc1])
|
||||
QuestHelper: Assert(pathcache_inactive[loc1])
|
||||
pathcache_active[loc1][loctable[k]] = rv[k]
|
||||
pathcache_inactive[loc1][loctable[k]] = rv[k]
|
||||
else
|
||||
QuestHelper: Assert(loctable[k])
|
||||
QuestHelper: Assert(pathcache_active[loctable[k]])
|
||||
QuestHelper: Assert(pathcache_inactive[loctable[k]])
|
||||
pathcache_active[loctable[k]][loc1] = rv[k]
|
||||
pathcache_inactive[loctable[k]][loc1] = rv[k]
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(linkity) do
|
||||
-- we do not release v.v, since that's now stored in our path cache
|
||||
QuestHelper:ReleaseTable(v)
|
||||
end
|
||||
QuestHelper:ReleaseTable(linkity)
|
||||
QuestHelper:ReleaseTable(lt)
|
||||
QuestHelper:ReleaseTable(rv) -- this had better be releasable
|
||||
|
||||
return rvv
|
||||
else
|
||||
return nil
|
||||
rvv[k] = rv[k].d
|
||||
end
|
||||
|
||||
table.sort(linkity, function(a, b) return a.v.d < b.v.d end)
|
||||
while #linkity > tostore do
|
||||
local rip = table.remove(linkity)
|
||||
QuestHelper:ReleaseTable(rip.v)
|
||||
QuestHelper:ReleaseTable(rip)
|
||||
end
|
||||
|
||||
for _, it in pairs(linkity) do
|
||||
local k, v = it.k, it.v
|
||||
|
||||
if not rv[k] then
|
||||
QuestHelper:TextOut(QuestHelper:StringizeTable(loc1.loc))
|
||||
QuestHelper:TextOut(QuestHelper:StringizeTable(lt[k]))
|
||||
end
|
||||
QuestHelper: Assert(rv[k], string.format("%d to %d", loc1.loc.p, loctable[k].loc.p))
|
||||
QuestHelper: Assert(rv[k].d)
|
||||
|
||||
-- We're only setting the inactive to give the garbage collector potentially a little more to clean up (i.e. the old path.)
|
||||
if not reverse then
|
||||
QuestHelper: Assert(pathcache_active[loc1])
|
||||
QuestHelper: Assert(pathcache_inactive[loc1])
|
||||
pathcache_active[loc1][loctable[k]] = rv[k]
|
||||
pathcache_inactive[loc1][loctable[k]] = rv[k]
|
||||
else
|
||||
QuestHelper: Assert(loctable[k])
|
||||
QuestHelper: Assert(pathcache_active[loctable[k]])
|
||||
QuestHelper: Assert(pathcache_inactive[loctable[k]])
|
||||
pathcache_active[loctable[k]][loc1] = rv[k]
|
||||
pathcache_inactive[loctable[k]][loc1] = rv[k]
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(linkity) do
|
||||
-- we do not release v.v, since that's now stored in our path cache
|
||||
QuestHelper:ReleaseTable(v)
|
||||
end
|
||||
QuestHelper:ReleaseTable(linkity)
|
||||
QuestHelper:ReleaseTable(lt)
|
||||
QuestHelper:ReleaseTable(rv) -- this had better be releasable
|
||||
|
||||
return rvv
|
||||
end
|
||||
)
|
||||
|
||||
|
|
|
@ -773,19 +773,17 @@ function QH_Route_Core_Process()
|
|||
-- Refresh a subset of things.
|
||||
local forward = DistBatch(NodeList[idx], tlnod)
|
||||
local backward = DistBatch(NodeList[idx], tlnod, true)
|
||||
if forward and backward then
|
||||
|
||||
for k, v in ipairs(ActiveNodes) do
|
||||
Distance[idx][v] = forward[k]
|
||||
Distance[v][idx] = backward[k]
|
||||
end
|
||||
|
||||
QuestHelper:ReleaseTable(forward)
|
||||
QuestHelper:ReleaseTable(backward)
|
||||
|
||||
ctd = ctd + 1
|
||||
resynch_progress:SetPercentage(ctd / ct)
|
||||
for k, v in ipairs(ActiveNodes) do
|
||||
Distance[idx][v] = forward[k]
|
||||
Distance[v][idx] = backward[k]
|
||||
end
|
||||
|
||||
QuestHelper:ReleaseTable(forward)
|
||||
QuestHelper:ReleaseTable(backward)
|
||||
|
||||
ctd = ctd + 1
|
||||
resynch_progress:SetPercentage(ctd / ct)
|
||||
end
|
||||
QuestHelper:ReleaseTable(tlnod)
|
||||
end
|
||||
|
@ -1126,24 +1124,22 @@ end
|
|||
|
||||
local forward = DistBatch(NodeList[1], tlnod)
|
||||
|
||||
if forward then
|
||||
local ct = 1
|
||||
for _, v in ipairs(ActiveNodes) do
|
||||
if v ~= 1 then
|
||||
QuestHelper: Assert(forward[ct])
|
||||
Distance[1][v] = forward[ct]
|
||||
ct = ct + 1
|
||||
local ct = 1
|
||||
for _, v in ipairs(ActiveNodes) do
|
||||
if v ~= 1 then
|
||||
QuestHelper: Assert(forward[ct])
|
||||
Distance[1][v] = forward[ct]
|
||||
ct = ct + 1
|
||||
|
||||
Distance[v][1] = 65500 -- this should never be used anyway
|
||||
end
|
||||
Distance[v][1] = 65500 -- this should never be used anyway
|
||||
end
|
||||
|
||||
if last_best and #last_best > 1 then
|
||||
last_best.distance = last_best.distance + Distance[last_best[1]][last_best[2]]
|
||||
end
|
||||
|
||||
QuestHelper:ReleaseTable(forward)
|
||||
end
|
||||
|
||||
if last_best and #last_best > 1 then
|
||||
last_best.distance = last_best.distance + Distance[last_best[1]][last_best[2]]
|
||||
end
|
||||
|
||||
QuestHelper:ReleaseTable(forward)
|
||||
QuestHelper:ReleaseTable(tlnod)
|
||||
|
||||
Storage_Distance_StoreFromIDToAll(1)
|
||||
|
@ -1466,10 +1462,8 @@ function QH_Route_Core_DistanceClear(progress)
|
|||
for ani, idx in ipairs(ActiveNodes) do
|
||||
local forward = DistBatch(NodeList[idx], tlnod, false, true)
|
||||
|
||||
if forward then
|
||||
for k, v in ipairs(ActiveNodes) do
|
||||
Distance[idx][v] = forward[k]
|
||||
end
|
||||
for k, v in ipairs(ActiveNodes) do
|
||||
Distance[idx][v] = forward[k]
|
||||
end
|
||||
|
||||
if QuestHelper.loading_preroll and #ActiveNodes > 1 then QuestHelper.loading_preroll:SetPercentage(ani / #ActiveNodes) end
|
||||
|
|
Référencer dans un nouveau ticket