Hello there.
I'm developing an Illithid Mod, so I want to force every single illithid in my current world to worship a unique deity (Ilsensine). But the moddable-gods script of @Putnam and @expwnent doesn't set the created god to anyone, and the Monotheism script of @fortunawhisk only applies to the citizens of your current fort, so I attempted to merge them into a single script. The result was this:
-- Enforce monotheism on an entire civ
-- Fortress mode script called from DFHack
-- Based on Monotheism.lua of fortunawhisk and moddable-gods.lua of Putnam and expwnent
local utils=require('utils')
validArgs = utils.invert({
'help',
'name',
'spheres',
'gender',
'depictedAs',
'domain',
'description',
'entity',
'verbose',
'level'
})
local args = utils.processArgs({...}, validArgs)
local verbose = false
local override = false
local helpme = [===[
set-god.lua
=========
This script sets a specific entity to only worship a single deity.
arguments:
-help
print this help message
-verbose
prints debug data to the dfhack console. Default is false
-name godName
sets the name of the god to godName
if there's already a god of that name, the script stops
-spheres [ sphereList ]
define a space-separated list of spheres of influence of the god
-depictedAs str
often depicted as a str
-domain str
set the domain of the god
-description str
set the description of the god
-entity str
set the entity that worships the god
-level
Expects an integer value. 1=ardent, 2=faithful, 3=normal, 4=casual, and 5=dubious
]===]
-- Handle help requests
if args.help then
print(helpme)
return
end
if not args.name or not args.depictedAs or not args.domain or not args.description or not args.spheres or not args.gender or not args.entity or not args.level then
error('All arguments must be specified.')
end
if ( args.verbose ) then
verbose = true
end
-- Moddable-Gods stuff
local templateGod
for _,fig in ipairs(df.global.world.history.figures) do
if fig.flags.deity then
templateGod = fig
break
end
end
if not templateGod then
error 'Could not find template god.'
end
local gender
if args.gender == 'male' then
gender = 1
elseif args.gender == 'female' then
gender = 0
else
error 'invalid gender'
end
for _,fig in ipairs(df.global.world.history.figures) do
if fig.name.first_name == args.name then
error 'this deity already exists'
return
end
end
local godFig = df.historical_figure:new()
godFig.appeared_year = -1
godFig.born_year = -1
godFig.born_seconds = -1
godFig.curse_year = -1
godFig.curse_seconds = -1
godFig.old_year = -1
godFig.old_seconds = -1
godFig.died_year = -1
godFig.died_seconds = -1
godFig.name.has_name = true
godFig.breed_id = -1
godFig.flags:assign(templateGod.flags)
godFig.id = df.global.hist_figure_next_id
df.global.hist_figure_next_id = 1+df.global.hist_figure_next_id
godFig.info = df.historical_figure_info:new()
godFig.info.spheres = {new=true}
godFig.info.secret = df.historical_figure_info.T_secret:new()
godFig.sex = gender
godFig.name.first_name = args.name
for _,sphere in ipairs(args.spheres) do
godFig.info.spheres:insert('#',df.sphere_type[sphere])
end
df.global.world.history.figures:insert('#',godFig)
--Monotheism Stuff
if (args.name and args.level) then
override = true
force_deity = tonumber(godFig.id)
force_level = tonumber(args.level)
end
local entity = df.historical_entity.find(unit.civ_id)
if not entity then
return
end
if args.entity then
local success
for _,entity in ipairs(df.global.world.entities.all) do
if entity.entity_raw.code == args.entity then
success = true
break
end
end
if not success then
error 'Invalid entity'
end
entities[args.entity] = true
end
function EraseHFLinksDeity (hf)
for i = #hf.histfig_links-1,0,-1 do
if hf.histfig_links._type == df.histfig_hf_link_deityst then
local todelete = hf.histfig_links
hf.histfig_links:erase(i)
todelete:delete()
end
end
end
function EraseDeityNeeds (needs)
for i = #needs-1,0,-1 do
if needs.id == 2 then
needs:erase(i)
end
end
end
function set_deities ()
for i, unit in ipairs(df.global.world.units.all) do
if unit.civ_id == args.entity then
-- Per citizen variables
local d_counter = 0
local keep_deity = 0
local keep_linkstrength = 0
local keep_focus = 0
local keep_need_level = 0
local hf = df.historical_figure.find(unit.hist_figure_id)
if verbose then dfhack.println(dfhack.TranslateName(df.historical_figure.find(unit.hist_figure_id).name, true)) end
-- Identify and count deity related relationships
-- We'll grab the the first deity, delete everything, then reinsert it. Anything else leads to index order errors
for k, histfig_link in ipairs(hf.histfig_links) do
if histfig_link._type == df.histfig_hf_link_deityst then
d_counter = d_counter + 1
if d_counter == 1 then
keep_deity = hf.histfig_links[k].target_hf
keep_linkstrength = hf.histfig_links[k].link_strength
if verbose then dfhack.println(" == Will Keep " .. dfhack.TranslateName(df.historical_figure.find(keep_deity).name, true) .. " | " .. hf.histfig_links[k].link_strength ) end
end
if d_counter > 1 then
-- Delete relationship
if verbose then dfhack.println(" == Will Remove " .. dfhack.TranslateName(df.historical_figure.find(histfig_link.target_hf).name, true) .. " | " .. hf.histfig_links[k].link_strength) end
end
end
end
-- Now we need to remove the needs. Just removing needs is not a great plan. They don't seem to regenerate.
needs = unit.status.current_soul.personality.needs
for i = #needs-1,0,-1 do
if needs.id == 2 then
if verbose then dfhack.println(" == Deity Need " .. dfhack.TranslateName(df.historical_figure.find(needs.deity_id).name, true) .. ":" .. needs.focus_level .. ":" .. needs.need_level ) end
if needs.deity_id == keep_deity then
keep_focus = needs.focus_level
keep_need_level = needs.need_level
if verbose then dfhack.println(" == Keep Deity Need " .. dfhack.TranslateName(df.historical_figure.find(keep_deity).name, true) .. ":" .. keep_focus .. ":" .. keep_need_level ) end
end
end
end
-- We'll now remove all the deity relations
EraseHFLinksDeity(hf)
-- We'll now remove all Deity Needs
EraseDeityNeeds(needs)
-- Sometimes there isn't a need created for a deity?
-- Oddly, need level doesn't seem directly linked to the linkstrength ranges for deity relationships?
if(keep_need_level == 0) then
if( keep_linkstrength >= 90 ) then
keep_need_level = 10
elseif( keep_linkstrength >= 70 ) then
keep_need_level = 5
elseif( keep_linkstrength >= 50 ) then
keep_need_level = 2
else
keep_need_level = 1
end
end
-- We can test for an override here
if(override) then
if verbose then dfhack.println(" == Force Deity to " .. force_deity .. "|" .. force_level ) end
keep_deity = force_deity
if( force_level == 1 ) then
keep_need_level = 10
keep_linkstrength = 90
elseif( force_level == 2 ) then
keep_need_level = 5
keep_linkstrength = 75
elseif( force_level == 3 ) then
keep_need_level = 2
keep_linkstrength = 50
elseif( force_level == 4 ) then
keep_need_level = 2
keep_linkstrength = 10
else
keep_need_level = 1
keep_linkstrength = 1
end
if verbose then dfhack.println(" == Force Deity to " .. dfhack.TranslateName(df.historical_figure.find(keep_deity).name, true) .. "|" .. keep_linkstrength .. "|" .. keep_need_level ) end
end
-- We'll now add a deity link.
local new_link = df.histfig_hf_link_deityst:new() -- adding hf link to source
new_link.target_hf = keep_deity
new_link.link_strength = keep_linkstrength
hf.histfig_links:insert('#',new_link)
-- Recreate our single deity need
local new_need = df.unit_personality.T_needs:new()
new_need.id = 2
new_need.deity_id = keep_deity
new_need.focus_level = keep_focus
new_need.need_level = keep_need_level
unit.status.current_soul.personality.needs:insert("#",new_need)
end
end
end
set_deities ()
But this script (the second one I've done in my entire life as DF modder) doesn't actually work, giving me the following error:
...nstaladas\df_44_12_win/hack/scripts/modtools/set-god.lua:133: attempt to index a nil value (global 'unit')
stack traceback:
...nstaladas\df_44_12_win/hack/scripts/modtools/set-god.lua:133: in local 'script_code'
...esktop\Cosas Instaladas\df_44_12_win\hack\lua\dfhack.lua:680: in function 'dfhack.run_script_with_env'
(...tail calls...)