Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist the last cycle tick in emigration for a more consistent gameplay experience #1330

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Template for new versions:
- `fix/loyaltycascade`: allow the fix to work on non-dwarven citizens
- `control-panel`: fix setting numeric preferences from the commandline
- `gui/quickfort`: fix build mode evluation rules to allow placement of various furniture and constructions on tiles with stair shapes or without orthagonal floor.
- `emigration`: save-and-reload no longer resets the emigration cycle timeout, making gameplay more consistent

## Misc Improvements
- `control-panel`: Add realistic-melting tweak to control-panel registry
Expand Down
42 changes: 30 additions & 12 deletions emigration.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
--@module = true
--@enable = true

local utils = require('utils')

local GLOBAL_KEY = 'emigration' -- used for state change hooks and persistence

enabled = enabled or false
local function get_default_state()
return {enabled=false, last_cycle_tick=0}
end

state = state or get_default_state()

function isEnabled()
return enabled
return state.enabled
end

local function persist_state()
dfhack.persistent.saveSiteData(GLOBAL_KEY, {enabled=enabled})
dfhack.persistent.saveSiteData(GLOBAL_KEY, state)
end

local TICKS_PER_MONTH = 33600
local TICKS_PER_YEAR = 12 * TICKS_PER_MONTH

function desireToStay(unit,method,civ_id)
-- on a percentage scale
local value = 100 - unit.status.current_soul.personality.stress / 5000
Expand Down Expand Up @@ -191,27 +200,36 @@ function checkmigrationnow()
else
for _, civ_id in pairs(merchant_civ_ids) do checkForDeserters('merchant', civ_id) end
end

state.last_cycle_tick = dfhack.world.ReadCurrentTick() + TICKS_PER_YEAR * dfhack.world.ReadCurrentYear()
end

local function event_loop()
if enabled then
checkmigrationnow()
dfhack.timeout(1, 'months', event_loop)
if state.enabled then
local current_tick = dfhack.world.ReadCurrentTick() + TICKS_PER_YEAR * dfhack.world.ReadCurrentYear()
if current_tick - state.last_cycle_tick < TICKS_PER_MONTH then
local timeout_ticks = state.last_cycle_tick - current_tick + TICKS_PER_MONTH
dfhack.timeout(timeout_ticks, 'ticks', event_loop)
else
checkmigrationnow()
dfhack.timeout(1, 'months', event_loop)
end
end
end

dfhack.onStateChange[GLOBAL_KEY] = function(sc)
if sc == SC_MAP_UNLOADED then
enabled = false
state.enabled = false
return
end

if sc ~= SC_MAP_LOADED or df.global.gamemode ~= df.game_mode.DWARF then
return
end

local persisted_data = dfhack.persistent.getSiteData(GLOBAL_KEY, {enabled=false})
enabled = persisted_data.enabled
state = get_default_state()
utils.assign(state, dfhack.persistent.getSiteData(GLOBAL_KEY, state))

event_loop()
end

Expand All @@ -230,11 +248,11 @@ if dfhack_flags and dfhack_flags.enable then
end

if args[1] == "enable" then
enabled = true
state.enabled = true
elseif args[1] == "disable" then
enabled = false
state.enabled = false
else
print('emigration is ' .. (enabled and 'enabled' or 'not enabled'))
print('emigration is ' .. (state.enabled and 'enabled' or 'not enabled'))
return
end

Expand Down