Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Adoption!
-- lets babies be adopted by couples with no infants.
local function getSpouseOrLover(unit)
local lover_unit=df.unit.find(unit.relations.lover_id) or df.unit.find(unit.relations.spouse_id)
if lover_unit then
return lover_unit.hist_figure_id
else
local hist_fig=df.historical_figure.find(unit.hist_figure_id)
for k,v in ipairs(hist_fig.histfig_links) do
if df.histfig_hf_link_spousest:is_instance(v) or df.histfig_hf_link_loverst:is_instance(v) then
return v.target_hf
end
end
end
return false
end
local function getNumberOfChildren(unit)
local children=0
for k,v in ipairs(df.historical_figure.find(unit.hist_figure_id).histfig_links) do
if df.histfig_hf_link_childst:is_instance(v) then children=children+1 end
end
return children
end
local function figureIsAlive(hist_figure)
return hist_figure.died_year==-1
end
local function unitIsChild(unit)
return df.global.cur_year-unit.relations.birth_year<12
end
local function unitIsOrphan(unit)
if unitIsChild(unit) then
local fatherIsAlive,motherIsAlive=false,false
for k,v in ipairs(df.historical_figure.find(unit.hist_figure_id).histfig_links) do
if df.histfig_hf_link_motherst:is_instance(v) then
if figureIsAlive(df.historical_figure.find(v.hist_figure_id)) then motherIsAlive=true end
elseif df.histfig_hf_link_fatherst:is_instance(v) then
if figureIsAlive(df.historical_figure.find(v.hist_figure_id)) then fatherIsAlive=true end
end
end
return (fatherIsAlive or motherIsAlive)
end
return false
end
local function adopt(baby,couple)
local mother,father=false,false
if df.historical_figure.find(couple.unit).sex==0 then
mother=couple.unit
father=couple.lover --yeah, the "father" will be female if the unit's lover is female, but the game will correctly display both as "mother"
else
father=couple.unit
mother=couple.lover --similar to the above, the "mother" will be male if the unit's lover is male, but they'll both be "father" pretty elegantly.
end
local mother_fig=df.historical_figure.find(mother)
local father_fig=df.historical_figure.find(father)
local baby_hist_fig=df.historical_figure.find(baby.hist_figure_id)
for k,v in ipairs(baby_hist_fig.histfig_links) do
if df.histfig_hf_link_motherst:is_instance(v) then
v.target_hf=mother --yeah, adoption will remove any relation other than genetics between biological parents and children.
elseif df.histfig_hf_link_fatherst:is_instance(v) then
v.target_hf=father
end
end
mother_fig.histfig_links:insert('#',{new=df.histfig_hf_link_childst,target_hf=baby.hist_figure_id,link_strength=100})
father_fig.histfig_links:insert('#',{new=df.histfig_hf_link_childst,target_hf=baby.hist_figure_id,link_strength=100})
baby.relations.mother_id=mother_fig.unit_id
baby.relations.father_id=father_fig.unit_id
local message = dfhack.TranslateName(mother_fig.name) .. ' and ' .. dfhack.TranslateName(father_fig.name) .. ' have adopted ' .. dfhack.TranslateName(dfhack.units.getVisibleName(baby)) .. '.'
dfhack.gui.showAnnouncement(message)
dfhack.gui.writeToGamelog(message) --too lazy to use makeAnnouncement right now
end
local function findBabiesWithNoParents()
local couples_histfig={}
local orphans={}
for k,unit in ipairs(df.global.world.units.active) do
if dfhack.units.isCitizen(unit) then
local spouseOrLover=getSpouseOrLover(unit)
if spouseOrLover then
couples_histfig[unit.hist_figure_id]=couples_histfig[unit.hist_figure_id] or {children=getNumberOfChildren(unit),lover=spouseOrLover,unit=unit.hist_figure_id}
couples_histfig[spouseOrLover]=true --this weird sequence of crap makes it so that 1. I can easily cull redundant units and 2. I can still sort the table
elseif unitIsOrphan(unit) then
table.insert(orphans,unit)
end
end
end
local couples={}
for k in pairs(couples_histfig) do
if couples[k]==true then couples[k]=nil end --not doing this will make an error show up when sorting the couples table due to true.children being nonsense
end
for k,v in pairs(couples_histfig) do
table.insert(couples,v) --makes the keys of the couples table be 1,2,3 etc. instead of being all over the place as histfigs
end
table.sort(couples,function(a,b) return a.children<b.children end)
if #orphans>1 then
for k,orphan in ipairs(orphans) do
adopt(orphan,math.ceil(couples[k]/2))
end
end
end
require('repeat-util').scheduleUnlessAlreadyScheduled('Orphan Adoption Service',1,'days',findBabiesWithNoParents)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment