Files
gen1recomp/src/mods/LoadOrder.lua
T

110 lines
2.7 KiB
Lua

local SaveData = require("src.core.SaveData")
local LoadOrder = {}
local function priorityOf(entry)
local p = entry and (entry.priority or (entry.manifest and entry.manifest.priority))
return tonumber(p) or 0
end
function LoadOrder.byPriority(entries)
local list = {}
for _, e in ipairs(entries or {}) do
if type(e) == "table" and type(e.id) == "string" then list[#list + 1] = e end
end
table.sort(list, function(a, b)
local pa, pb = priorityOf(a), priorityOf(b)
if pa == pb then return a.id < b.id end
return pa < pb
end)
local ids = {}
for i, e in ipairs(list) do ids[i] = e.id end
return ids
end
function LoadOrder.materialize(saved, entries)
local listed = SaveData.modOrder({ modOrder = saved })
local seen, prio = {}, {}
for _, id in ipairs(listed) do seen[id] = true end
for _, e in ipairs(entries or {}) do
if type(e) == "table" and type(e.id) == "string" then prio[e.id] = priorityOf(e) end
end
local tail = {}
for _, id in ipairs(LoadOrder.byPriority(entries)) do
if not seen[id] then
seen[id] = true
tail[#tail + 1] = id
end
end
local out, t = {}, 1
for _, id in ipairs(listed) do
local p = prio[id]
if p then
while tail[t] and prio[tail[t]] < p do
out[#out + 1] = tail[t]
t = t + 1
end
end
out[#out + 1] = id
end
for i = t, #tail do out[#out + 1] = tail[i] end
return out
end
function LoadOrder.rank(list)
local rank = {}
local clean = SaveData.modOrder({ modOrder = list })
for i, id in ipairs(clean) do rank[id] = i end
return rank, #clean + 1
end
function LoadOrder.move(list, id, delta)
local out, at = {}, nil
for i, v in ipairs(list or {}) do
out[i] = v
if v == id then at = i end
end
if not at or #out < 2 then return out, false end
local to = at + (tonumber(delta) or 0)
if to ~= to then return out, false end
to = math.max(1, math.min(#out, to))
if to == at then return out, false end
table.remove(out, at)
table.insert(out, to, id)
return out, true
end
function LoadOrder.moveWithin(full, visible, id, delta)
local shown = {}
for _, v in ipairs(visible or full or {}) do shown[v] = true end
local sub = {}
for _, v in ipairs(full or {}) do
if shown[v] then sub[#sub + 1] = v end
end
local moved, changed = LoadOrder.move(sub, id, delta)
if not changed then
local copy = {}
for i, v in ipairs(full or {}) do copy[i] = v end
return copy, false
end
local out, k = {}, 0
for i, v in ipairs(full) do
if shown[v] then
k = k + 1
out[i] = moved[k]
else
out[i] = v
end
end
return out, true
end
function LoadOrder.position(list, id)
for i, v in ipairs(list or {}) do
if v == id then return i end
end
return nil
end
return LoadOrder