Hiranus icon

DFHack religion

Hiranus | PRO | 02/24/24 02:58:20 PM UTC | 0 ⭐ | 1119 👁️ | Never ⏰ | []
Lua |

4.97 KB

|

None

|

0 👍

/

0 👎

local argparse = require('argparse')
 
local MyCivId = df.global.world.world_data.active_site[0].entity_links[0].entity_id
 
local options = {
  mode = "",
  allunits = false,
}
local args = { ... }
 
local function ValidateMode(arg)
  local argLower = string.lower(arg);
  local validModes = {
    ["atheism"] = true,
    ["monotheism"] = true
  }
  if not validModes[argLower] then
    qerror('Invalid mode')
  end
  options.mode = argLower
end
 
argparse.processArgsGetopt(args, {
  { 'm', 'mode', handler = ValidateMode,                             hasArg = true },
  { 'a', 'all',  handler = function(arg) options.allunits = true end },
})
 
local function GetGodToLeave(needs, histFigLinks)
  if options.mode == "monotheism" then
    --check if needs correpond to hist flag links
    for _, link in pairs(histFigLinks) do
      for _, need in pairs(needs) do
        if link.target_hf == need.deity_id then
          return need.deity_id
        end
      end
    end
    --no links or unit is not hist fig, pick first pray need
    if needs[1] then
      return needs[1].deity_id
    end
  end
end
 
local function CleanupReligion(histfigId, religion)
  --remove all mentions of this citizen in religion, making it ass if he never belonged here
  for i = #religion.histfig_ids - 1, 0, -1 do
    if religion.histfig_ids[i] == histfigId then
      religion.histfig_ids:erase(i)
    end
  end
  for i = #religion.hist_figures - 1, 0, -1 do
    if religion.hist_figures[i].id == histfigId then
      religion.hist_figures:erase(i)
    end
  end
end
 
local function TableCleanup(tab, valsToRemove, checkFunc, useDelete)
  for i = #tab - 1, 0, -1 do
    for _, val in pairs(valsToRemove) do
      if checkFunc(tab[i], val) then
        local todel = tab[i]
        tab:erase(i)
        if useDelete then
          todel:delete()
        end
        break
      end
    end
  end
end
 
local function CleanupReligions(histfig, needGod)
  local religions = {}
  local religionToLeave
  --find all dwarf religions
  for _, link in pairs(histfig.entity_links) do
    local ent = df.historical_entity.find(link.entity_id)
    if ent.type == 5 then -- religion
      table.insert(religions, ent)
      --if we will leave one religion we need to make sure that the religion matches a god
      if not religionToLeave and needGod then
        for _, god in pairs(ent.relations.deities) do
          if needGod == god then
            religionToLeave = ent.id
          end
        end
      end
    end
  end
  for _, rel in pairs(religions) do
    if religionToLeave ~= rel.id then
      CleanupReligion(histfig.id, rel)
      local id
      for key, value in pairs(histfig.entity_links) do
        if value.entity_id == rel.id then
          id = key
        end
      end
      local del = histfig.entity_links[id]
      histfig.entity_links:erase(id)
      del:delete()
    end
  end
end
 
local function ProceessUnit(dwarf)
  --Needs to be checked for tamed sentients and other similar cases
  if not (dwarf and dwarf.civ_id == MyCivId and dfhack.units.isCitizen(dwarf)) then
    return
  end
  local needTargets = {}
  local histfigLinkTargets = {}
 
  for _, need in pairs(dwarf.status.current_soul.personality.needs) do
    if need.id == 2 then
      table.insert(needTargets,
        {
          deity_id = need.deity_id,
          focus_level = need.focus_level,
          need_level = need.need_level,
        })
    end
  end
  local dwarf_hist_fig
 
  if dwarf.hist_figure_id ~= -1 then
    dwarf_hist_fig = df.historical_figure.find(dwarf.hist_figure_id)
  end
 
  if dwarf_hist_fig then
    for _, histfig_link in pairs(dwarf_hist_fig.histfig_links) do
      if histfig_link._type == df.histfig_hf_link_deityst then
        table.insert(histfigLinkTargets,
          { target_hf = histfig_link.target_hf, link_strength = histfig_link.link_strength })
      end
    end
  end
 
  local needGod = GetGodToLeave(needTargets, histfigLinkTargets)
 
  TableCleanup(dwarf.status.current_soul.personality.needs, needTargets,
    function(elem, target)
      return (needGod == nil or needGod ~= target.deity_id) and
          elem.id == 2 and
          elem.deity_id == target.deity_id
    end, false)
 
  if dwarf_hist_fig then
    TableCleanup(dwarf_hist_fig.histfig_links, histfigLinkTargets,
      function(elem, target)
        return (needGod == nil or needGod ~= target.target_hf) and
            elem._type == df.histfig_hf_link_deityst and
            target.target_hf == elem.target_hf
      end, true)
    CleanupReligions(dwarf_hist_fig, needGod)
  end
end
 
if not dfhack.isMapLoaded() then
  qerror('This script requires a fortress map to be loaded')
end
 
if options.allunits then
  for i, unit in pairs(df.global.world.units.all) do
    ProceessUnit(unit)
  end
else
  local unit = dfhack.gui.getSelectedUnit()
  if not unit then
    qerror("Select a unit and run the script again.")
  end
  ProceessUnit(unit)
end
 

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎