-- gui/family-affairs -- derived from v1.2 @ http://www.bay12forums.com/smf/index.php?topic=147779 local help = [[=begin gui/family-affairs ================== A user-friendly interface to view romantic relationships, with the ability to add, remove, or otherwise change them at your whim - fantastic for depressed dwarves with a dead spouse (or matchmaking players...). The target/s must be alive, sane, and in fortress mode. .. image:: /docs/images/family-affairs.png :align: center ``gui/family-affairs [unitID]`` shows GUI for the selected unit, or the specified unit ID ``gui/family-affairs divorce [unitID]`` removes all spouse and lover information from the unit and it's partner, bypassing almost all checks. ``gui/family-affairs [unitID] [unitID]`` divorces the two specificed units and their partners, then arranges for the two units to marry, bypassing almost all checks. Use with caution. =end]] local dlg = require ('gui.dialogs') function ErrorPopup (msg,color) if not tostring(msg) then msg = "Error" end if not color then color = COLOR_LIGHTRED end dlg.showMessage("Dwarven Family Affairs", msg, color, nil) end function AnnounceAndGamelog (text,l) if not l then l = true end dfhack.gui.showAnnouncement(text, _G["COLOR_LIGHTMAGENTA"]) if l then local log = io.open('gamelog.txt', 'a') log:write(text.."\n") log:close() end end function ListPrompt (msg, choicelist, bool, yes_func) dlg.showListPrompt( "Dwarven Family Affairs", msg, COLOR_WHITE, choicelist, --called if choice is yes yes_func, --called on cancel function() end, 15, bool ) end function GetMarriageSummary (source) local familystate = "" if source.relations.spouse_id ~= -1 then if dfhack.units.isSane(df.unit.find(source.relations.spouse_id)) then familystate = dfhack.TranslateName(source.name).." has a spouse ("..dfhack.TranslateName(df.unit.find(source.relations.spouse_id).name)..")" end if dfhack.units.isSane(df.unit.find(source.relations.spouse_id)) == false then familystate = dfhack.TranslateName(source.name).."'s spouse is dead or not sane, would you like to choose a new one?" end end if source.relations.spouse_id == -1 and source.relations.lover_id ~= -1 then if dfhack.units.isSane(df.unit.find(source.relations.lover_id)) then familystate = dfhack.TranslateName(source.name).." already has a lover ("..dfhack.TranslateName(df.unit.find(source.relations.spouse_id).name)..")" end if dfhack.units.isSane(df.unit.find(source.relations.lover_id)) == false then familystate = dfhack.TranslateName(source.name).."'s lover is dead or not sane, would you like that love forgotten?" end end if source.relations.spouse_id == -1 and source.relations.lover_id == -1 then familystate = dfhack.TranslateName(source.name).." is not involved in romantic relationships with anyone" end if source.relations.pregnancy_timer > 0 then familystate = familystate.."\nShe is pregnant." local father = df.historical_figure.find(source.relations.pregnancy_spouse) if father then familystate = familystate.." The father is "..dfhack.TranslateName(father.name).."." end end return familystate end function GetSpouseData (source) local spouse = df.unit.find(source.relations.spouse_id) local spouse_hf if spouse then spouse_hf = df.historical_figure.find (spouse.hist_figure_id) end return spouse,spouse_hf end function GetLoverData (source) local lover = df.unit.find(source.relations.spouse_id) local lover_hf if lover then lover_hf = df.historical_figure.find (lover.hist_figure_id) end return lover,lover_hf end function EraseHFLinksLoverSpouse (hf) for i = #hf.histfig_links-1,0,-1 do if hf.histfig_links[i]._type == df.histfig_hf_link_spousest or hf.histfig_links[i]._type == df.histfig_hf_link_loverst then local todelete = hf.histfig_links[i] hf.histfig_links:erase(i) todelete:delete() end end end function Divorce (source) local source_hf = df.historical_figure.find(source.hist_figure_id) local spouse,spouse_hf = GetSpouseData (source) local lover,lover_hf = GetLoverData (source) source.relations.spouse_id = -1 source.relations.lover_id = -1 if source_hf then EraseHFLinksLoverSpouse (source_hf) end if spouse then spouse.relations.spouse_id = -1 spouse.relations.lover_id = -1 end if lover then spouse.relations.spouse_id = -1 spouse.relations.lover_id = -1 end if spouse_hf then EraseHFLinksLoverSpouse (spouse_hf) end if lover_hf then EraseHFLinksLoverSpouse (lover_hf) end local partner = spouse or lover if not partner then AnnounceAndGamelog(dfhack.TranslateName(source.name).." is now single") else AnnounceAndGamelog(dfhack.TranslateName(source.name).." and "..dfhack.TranslateName(partner.name).." are now single") end end function Marriage (source,target) local source_hf = df.historical_figure.find(source.hist_figure_id) local target_hf = df.historical_figure.find(target.hist_figure_id) source.relations.spouse_id = target.id target.relations.spouse_id = source.id local new_link = df.histfig_hf_link_spousest:new() -- adding hf link to source new_link.target_hf = target_hf.id new_link.link_strength = 100 source_hf.histfig_links:insert('#',new_link) new_link = df.histfig_hf_link_spousest:new() -- adding hf link to target new_link.target_hf = source_hf.id new_link.link_strength = 100 target_hf.histfig_links:insert('#',new_link) end function ChooseNewSpouse (source) if not source then qerror("no unit") return end if (source.profession == 103 or source.profession == 104) then ErrorPopup("target is too young") return end if not (source.relations.spouse_id == -1 and source.relations.lover_id == -1) then ErrorPopup("target already has a spouse or a lover") qerror("source already has a spouse or a lover") return end local choicelist = {} targetlist = {} for k,v in pairs (df.global.world.units.active) do if dfhack.units.isCitizen(v) and v.race == source.race and v.sex ~= source.sex and v.relations.spouse_id == -1 and v.relations.lover_id == -1 and not (v.profession == 103 or v.profession == 104) then table.insert(choicelist,dfhack.TranslateName(v.name)..', '..dfhack.units.getProfessionName(v)) table.insert(targetlist,v) end end if #choicelist > 0 then ListPrompt( "Assign new spouse for "..dfhack.TranslateName(source.name), choicelist, true, function(a,b) local target = targetlist[a] Marriage (source,target) AnnounceAndGamelog(dfhack.TranslateName(source.name).." and "..dfhack.TranslateName(target.name).." have married!") end) else ErrorPopup("No suitable candidates") end end function MainDialog (source) local familystate = GetMarriageSummary(source) familystate = familystate.."\nSelect action:" local choicelist = {} local on_select = {} local child = (source.profession == 103 or source.profession == 104) local is_single = source.relations.spouse_id == -1 and source.relations.lover_id == -1 local ready_for_marriage = single and not child if not child then table.insert(choicelist,"Remove romantic relationships (if any)") table.insert(on_select, Divorce) if ready_for_marriage then table.insert(choicelist,"Assign a new spouse") table.insert(on_select,ChooseNewSpouse) end if not ready_for_marriage then table.insert(choicelist,"[Assign a new spouse]") table.insert(on_select,function () ErrorPopup ("Existing relationships must be removed if you wish to assign a new spouse.") end) end else table.insert(choicelist,"Leave this child alone") table.insert(on_select,nil) end ListPrompt(familystate, choicelist, false, function(a,b) if on_select[a] then on_select[a](source) end end) end local args = {...} if args[1] == "help" or args[1] == "?" then print(helpstr) return end if not df.global.gamemode == 0 then print (helpstr) qerror ("invalid gamemode") return end if args[1] == "divorce" and tonumber(args[2]) then local unit = df.unit.find(args[2]) if unit then Divorce (unit) return end end if tonumber(args[1]) and tonumber(args[2]) then local unit1 = df.unit.find(args[1]) local unit2 = df.unit.find(args[2]) if unit1 and unit2 then Divorce (unit1) Divorce (unit2) Marriage (unit1,unit2) return end end local selected = dfhack.gui.getSelectedUnit(true) if tonumber(args[1]) then selected = df.unit.find(tonumber(args[1])) or selected end if selected then if dfhack.units.isCitizen(selected) and dfhack.units.isSane(selected) then MainDialog(selected) else qerror("You must select sane fortress citizen.") return end else print (helpstr) qerror("select a sane fortress dwarf") end