131 lines
3.9 KiB
Lua
131 lines
3.9 KiB
Lua
|
--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
|
||
|
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 u.race ~= df.global.ui.race_id
|
||
|
or u.civ_id ~= df.global.ui.civ_id
|
||
|
or dfhack.units.isDead(u)
|
||
|
or dfhack.units.isOpposedToLife(u)
|
||
|
or u.flags1.merchant
|
||
|
or u.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()
|
||
|
checkmigrationnow()
|
||
|
dfhack.timeout(1, 'months', event_loop)
|
||
|
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
|
||
|
|