I want to run a fortress that only breeds using the starting seven. So I'm trying to write a script that prints all possible hetero couples(those who can marry and have children). It is still a WIP, but it can already print all necessary informations(age, orientation and valid mating candidates).
I'm still working on how to calculate the number of valid couples(I haven't do any math for ages so I'm a bit rusty).
For example there are two possible combinations: AB and AC, since A can only marry one from B and C, so there'll be only 1 possible couple.
local utils = require('utils')
local args = utils.processArgs({...})
if args.help then
print('Dwarven marriage test script.')
return
end
local function round(n, d)
local m= 10^(d or 0)
return math.floor(n*m+ 0.5) / m
end
local function getAgeString(unit)
return ''..round(dfhack.units.getAge(unit,true),2)
end
local function getInfoString(unit)
local infStr
if unit.sex==0 then
infStr='female, '
elseif unit.sex==1 then
infStr='male, '
else
infStr=""
end
infStr=infStr..getAgeString(unit)
return '('..infStr..')'
end
--this is from gaydar.lua
local function determineorientation(unit)
if unit.sex~=-1 then
local return_string=''
local orientation=unit.status.current_soul.orientation_flags
local male_interested,asexual=false,true
if orientation.romance_male then
return_string=return_string..' likes males'
male_interested=true
asexual=false
elseif orientation.marry_male then
return_string=return_string..' will marry males'
male_interested=true
asexual=false
end
if orientation.romance_female then
if male_interested then
return_string=return_string..' and likes females'
else
return_string=return_string..' likes females'
end
asexual=false
elseif orientation.marry_female then
if male_interested then
return_string=return_string..' and will marry females'
else
return_string=return_string..' will marry females'
end
asexual=false
end
if asexual then
return_string=' is asexual'
end
return return_string
else
return "is not biologically capable of sex"
end
end
local function nameOrSpeciesAndNumber(unit)
if unit.name.has_name then
return dfhack.TranslateName(dfhack.units.getVisibleName(unit))..' '..getInfoString(unit),true
else
return 'Unit #'..unit.id..' ('..df.creature_raw.find(unit.race).caste[unit.caste].caste_name[0]..getInfoString(unit)..')',false
end
end
local validcitizens={}
for k,v in ipairs(df.global.world.units.active) do
if dfhack.units.isCitizen(v)
and ((v.sex==0 and v.status.current_soul.orientation_flags.marry_male)
or (v.sex==1 and v.status.current_soul.orientation_flags.marry_female)) then
table.insert(validcitizens,{v,nameOrSpeciesAndNumber(v) .. determineorientation(v)})
end
end
local validpairs = {}
local validcount = {[0]=0,[1]=0}
local function checkAndAddValidPair(p)
--sort first
if p[1].sex==1 then
local t = p[1]
p[1] = p[2]
p[2] = t
end
for j,v in ipairs(validpairs) do
if p[1]==v[1] and p[2]==v[2] then
return false
end
end
table.insert(validpairs,p)
return true
end
-- only find valid couples
for k,v in ipairs(validcitizens) do
print(v[2])
if v[1].relations.spouse_id~=-1 then
print(' Already has a spouse')
end
if v[1].relations.lover_id~=-1 then
print(' Already has a lover')
end
local valid = false
for i,x in ipairs(validcitizens) do
if x[1]~=v[1] and x[1].sex~=v[1].sex then
if v[1].relations.spouse_id==x[1].id or v[1].relations.lover_id==x[1].id then
print(' '..dfhack.TranslateName(dfhack.units.getVisibleName(x[1]))..' (arranged)')
checkAndAddValidPair({v[1],x[1]})
valid = true
elseif v[1].relations.lover_id==-1 and v[1].relations.spouse_id==-1
and x[1].relations.lover_id==-1 and x[1].relations.spouse_id==-1
and math.abs(dfhack.units.getAge(x[1],true)-dfhack.units.getAge(v[1],true))<10 then
print(' '..dfhack.TranslateName(dfhack.units.getVisibleName(x[1])))
checkAndAddValidPair({v[1],x[1]})
valid = true
end
end
end
if valid then
validcount[v[1].sex] = validcount[v[1].sex]+1
end
end
print('')
print('There are ' ..math.min(validcount[1],validcount[0]).. ' possible valid couples')
for k,v in ipairs(validpairs) do
print(' '..dfhack.TranslateName(dfhack.units.getVisibleName(v[1]))..' x '..dfhack.TranslateName(dfhack.units.getVisibleName(v[2])))
end