GE Lua Documentation

Press F to search!

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)