--Allow stressed dwarves to emigrate from the fortress -- For 34.11 by IndigoFenix; update and cleanup by PeridexisErrant -- old version: http://dffd.bay12games.com/file.php?id=8404 --[[=begin emigration ========== Allows dwarves to emigrate from the fortress when stressed, in proportion to how badly stressed they are and adjusted for who they would have to leave with - a dwarven merchant being more attractive than leaving alone (or with an elf). The check is made monthly. A happy dwarf (ie with negative stress) will never emigrate. Usage: ``emigration enable|disable`` =end]] local args = {...} if args[1] == "enable" then enabled = true elseif args[1] == "disable" then enabled = false end function desireToStay(unit,method,civ_id) -- on a percentage scale local value = 100 - unit.status.current_soul.personality.stress_level / 5000 if method == 'merchant' or method == 'diplomat' then if civ_id ~= unit.civ_id then value = value*2 end end if method == 'wild' then value = value*5 end return value end function desert(u,method,civ) u.relations.following = nil local line = dfhack.TranslateName(dfhack.units.getVisibleName(u)) .. " has " if method == 'merchant' then line = line.."joined the merchants" u.flags1.merchant = true u.civ_id = civ elseif method == 'diplomat' then line = line.."followed the diplomat" u.flags1.diplomat = true u.civ_id = civ else line = line.."abandoned the settlement in search of a better life." u.civ_id = -1 u.flags1.forest = true u.animal.leave_countdown = 2 end print(line) dfhack.gui.showAnnouncement(line, COLOR_WHITE) end function canLeave(unit) for _, skill in pairs(unit.status.current_soul.skills) do if skill.rating > 14 then return false end end if unit.flags1.caged or unit.race ~= df.global.ui.race_id or unit.civ_id ~= df.global.ui.civ_id or dfhack.units.isDead(unit) or dfhack.units.isOpposedToLife(unit) or unit.flags1.merchant or unit.flags1.diplomat or unit.flags1.chained or dfhack.units.getNoblePositions(unit) ~= nil or unit.military.squad_id ~= -1 or dfhack.units.isCitizen(unit) or dfhack.units.isSane(unit) or unit.profession ~= 103 or not dfhack.units.isDead(unit) then return false end return true end function checkForDeserters(method,civ_id) local allUnits = df.global.world.units.active for i=#allUnits-1,0,-1 do -- search list in reverse local u = allUnits[i] if canLeave(u) and math.random(100) < desireToStay(u,method,civ_id) then desert(u,method,civ_id) end end end function checkmigrationnow() local merchant_civ_ids = {} local diplomat_civ_ids = {} local allUnits = df.global.world.units.active for i=0, #allUnits-1 do local unit = allUnits[i] if dfhack.units.isSane(unit) and not dfhack.units.isDead(unit) and not dfhack.units.isOpposedToLife(unit) and not unit.flags1.tame then if unit.flags1.merchant then table.insert(merchant_civ_ids, unit.civ_id) end if unit.flags1.diplomat then table.insert(diplomat_civ_ids, unit.civ_id) end end end for _, civ_id in pairs(merchant_civ_ids) do checkForDeserters('merchant', civ_id) end for _, civ_id in pairs(diplomat_civ_ids) do checkForDeserters('diplomat', civ_id) end checkForDeserters('wild', -1) end local function event_loop() if enabled then checkmigrationnow() dfhack.timeout(1, 'months', event_loop) end end dfhack.onStateChange.loadEmigration = function(code) if code==SC_MAP_LOADED then if enabled then print("Emigration enabled.") event_loop() else print("Emigration disabled.") end end end if dfhack.isMapLoaded() then dfhack.onStateChange.loadEmigration(SC_MAP_LOADED) end