setUnlockForwardBackward
Definition
-- @/lua/ge/extensions/gameplay/missions/unlocks.lua:209
-- the "main" unlocking additional data caluculation method.
local function setUnlockForwardBackward(missions)
local backward, forward = {}, {}
local highestLevelForMission = {}
local branchTagForMission = {}
local missionById = {}
-- first, get the base data for all missions: associated missions, branch levels.
for _, m in ipairs(missions) do
missionById[m.id] = m
backward[m.id] = {}
forward[m.id] = {}
getMissionsForCondition(m.startCondition, backward[m.id])
local levelForBranch = {}
getBranchLevelForCondition(m.startCondition, levelForBranch)
highestLevelForMission[m.id] = nil
branchTagForMission[m.id] = nil
for bId, lvl in pairs(levelForBranch) do
branchTagForMission[m.id] = branchTagForMission[m.id] or {}
branchTagForMission[m.id][bId] = true
if not highestLevelForMission[m.id] then
highestLevelForMission[m.id] = lvl
else
highestLevelForMission[m.id] = math.max(highestLevelForMission[m.id], lvl)
end
end
m.unlocks.maxBranchlevel = highestLevelForMission[m.id] or 0
m.unlocks.branchTags = branchTagForMission[m.id] or {}
end
-- double-link the missions, so that missions know which ones come after that (conditions are looking "backward")
for bId, list in pairs(backward) do
for _, fId in ipairs(list or {}) do
if not forward[fId] then forward[fId] = {} end
table.insert(forward[fId], bId)
end
end
-- set the data to the unlocks field of the mission.
for _, m in ipairs(missions) do
if #backward[m.id] > 0 then
--log(m.id .. " Backwards: " .. dumps(backward[m.id]))
end
if #forward[m.id] > 0 then
--log(m.id .. " Forwards: " .. dumps(forward[m.id]))
end
m.unlocks.forward = forward[m.id]
m.unlocks.backward = backward[m.id]
end
-- propagate the max lvl of a mission forward, so each mission knows the minimum branch level needed through predecessors
local missionIdsWithBranchCondition = tableKeysSorted(highestLevelForMission)
for _, mId in ipairs(missionIdsWithBranchCondition) do
propagateBranchLevel(mId, missionById)
end
--propagate missions go get initial "depth"
local front, nxt, open = {}, {}, {}
local depth = 0
for _, m in ipairs(missions) do
m.unlocks.depth = -1
if #m.unlocks.backward == 0 then
table.insert(front, m.id)
end
end
while depth < 1000 and next(front) do
nxt = {}
for _, mId in ipairs(front) do
missionById[mId].unlocks.depth = math.max(missionById[mId].unlocks.depth, depth)
for _, nId in ipairs(missionById[mId].unlocks.forward) do
nxt[nId] = true
end
end
front = tableKeysSorted(nxt)
depth = depth+1
end
-- get max depth for each level. then sum up to get depth offset
local maxDepthPerBranchlevel = {}
local maxLevel = 0
for _, m in ipairs(missions) do
maxDepthPerBranchlevel[m.unlocks.maxBranchlevel] = math.max(m.unlocks.depth, maxDepthPerBranchlevel[m.unlocks.maxBranchlevel] or 0)
maxLevel = math.max(maxLevel, m.unlocks.maxBranchlevel)
end
local prev = 0
for i = 0, maxLevel do
maxDepthPerBranchlevel[i] = prev + maxDepthPerBranchlevel[i]
prev = maxDepthPerBranchlevel[i]
end
-- shift the depth of a mission based on the amount of branches, branch depth, branch level
for _, m in ipairs(missions) do
m.unlocks.depth = m.unlocks.depth + maxDepthPerBranchlevel[m.unlocks.maxBranchlevel] + (m.unlocks.maxBranchlevel)*1
end
end
Callers
@/lua/ge/extensions/gameplay/missions/missions.lua
gameplay_missions_unlocks.setUnlockForwardBackward(missions)
gameplay_missions_unlocks.updateUnlockStatus(missions)