Two scripts that helped me with testing socialization and relationships:
Watching relationship metrics:
http://www.bay12forums.com/smf/index.php?topic=171707.msg7835921#msg7835921Removing relationships (not reversible):
-- Remove relationships
-- erase_relations 1.0
-- Fortress mode script called from DFHack
-- LNP: [04412r02-x64]
local utils=require('utils')
validArgs = utils.invert({
'help',
'targets',
'verbose'
})
local args = utils.processArgs({...}, validArgs)
local verbose = false
local helpme = [===[
erase_relations.lua
=========
This script erases the relationships for one or more units: aquaintences, grudges/friends, lovers/spouses, extended family, and deities
arguments:
-help
print this help message
-targets
Provide the comma separated list of units to erase relationships from
-verbose
Print extra log messages
Examples
erase_relations -verbose -targets 526,11395
]===]
-- Handle help requests
if args.help then
print(helpme)
return
end
if ( args.verbose ) then
verbose = true
end
if ( args.targets ) then
targetTable = {}
-- Set the units to watch
for i in (args.targets .. ","):gmatch("([^,]*),") do
-- if verbose then print("Targeting: ".. i) end
table.insert(targetTable, i)
end
end
function SetTargets(targetTable)
local tmpTargetTable = {}
local citizenTable={}
for k,u in ipairs(df.global.world.units.active) do
if (dfhack.units.isCitizen(u)) then
table.insert(citizenTable,u)
end
end
for k, v in pairs(targetTable) do
local check = targetTable[k]
if verbose then print("Targeting: "..check) end
if (string.lower(check) == string.lower("all")) then
tmpTargetTable = citizenTable
break -- Break out of the loop
elseif tonumber(check) ~= nil then
table.insert(tmpTargetTable, df.unit.find(check))
else
qerror('Error: Unhandled string. Was expecting a unit id or all')
end
end
-- Overwrite target table with new targets
targetTable = tmpTargetTable
return targetTable
end
function EraseHFLinksAll (hf)
-- Erase casual relationships
for i = #hf.info.relationships.list-1, 0, -1 do
local todelete = hf.info.relationships.list[i]
hf.info.relationships.list:erase(i)
todelete:delete()
end
-- Erase deity/lover/spouse relationships
for i = #hf.histfig_links-1, 0, -1 do
local todelete = hf.histfig_links[i]
hf.histfig_links:erase(i)
todelete:delete()
end
end
function EraseSpouseLover (unit)
unit.relationship_ids.Lover = -1
unit.relationship_ids.Spouse = -1
end
-- Set the units to erase
targetTable = SetTargets(targetTable)
-- Get list of valid targets(citizens)
for k,u in ipairs(targetTable) do
if verbose then print("Removing relations for: ", dfhack.TranslateName(dfhack.units.getVisibleName(u))) end
local uKVPTable={}
local unitName = dfhack.TranslateName(dfhack.units.getVisibleName(u), true) .."(".. u.id .. ")"
local hf = df.historical_figure.find(u.hist_figure_id)
EraseHFLinksAll(hf)
EraseSpouseLover(u)
end
A couple of notes from various tests and watching rank values here:
gui/gm-editor df.historical_figure.find(unit.hist_figure_id).info.relationships.list
1) Relations are formed the first time a unit is idle or socializing next to another unit*
2) When a relationship rank hits 15, a friendship or grudge is formed, depending on compatibility.
3) When the rank is around 40, if the units are friends and are romantically inclined, they become lovers. I've seen 31-42 so far, probably influenced by one or more personality facets.
4) When the rank hits 50, and the units are lovers, they can get married.
5) Talking to grudges can really spike a unit's stress level (700+ per day), depending on personality.
6) Socializing units can increase rank with busy adjacent units if they don't move. I tested pumpstacks, libraries, and temples.
* - It doesn't look like units socialize with same tile or diagonally adjacent units. Only N,S,E,W adjacent units show increases in rank.
I'm sure I'm skipping over or unaware of any number of subtleties here.
Edit - 20190327:
-
Looks like I made a mistake in testing. It's not same square AND N,S,E,W. It's ONLY N,S,E,W adjacent tiles.Edit - 20190328: The rank at which dwarves become lovers isn't static.
Edit - 20190401: Socialization can occur with same tile and diagonally adjacent units, but ONLY when there is a unit in a NSEW adjacent position. When that condition is met, socialization happens with every dwarf in a 3x3 grid centered on the socializing dwarf. Put another way: Socialization is a 1 tile omnidirectional interaction, but requires a unit in a NSEW adjacent tile to activate.