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

[fix/wildlife] don't poof wildlife that is currently onscreen #1358

Merged
merged 1 commit into from
Dec 29, 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 @@ -39,6 +39,7 @@ Template for new versions:
## Misc Improvements
- `immortal-cravings`: goblins and other naturally non-eating/non-drinking races will now also satisfy their needs for eating and drinking
- `caravan`: add filter for written works in display furniture assignment dialog
- `fix/wildlife`: don't vaporize stuck wildlife that is onscreen -- kill them instead (as if they died from old age)

## Removed

Expand Down
18 changes: 14 additions & 4 deletions fix/wildlife.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

local argparse = require('argparse')
local exterminate = reqscript('exterminate')
local guidm = require('gui.dwarfmode')

local GLOBAL_KEY = 'fix/wildlife'

Expand Down Expand Up @@ -61,7 +62,7 @@ local function refund_population(entry)
end
end

-- refund unit to population and ensure it doesn't get picked up by unstick_surface_wildlife in the future
-- refund unit to population and ensure it doesn't get picked up by unstick_wildlife in the future
local function detach_unit(unit)
unit.flags2.roaming_wilderness_population_source = false
unit.flags2.roaming_wilderness_population_source_not_a_map_feature = false
Expand All @@ -74,6 +75,7 @@ local TICKS_PER_MONTH = 28 * TICKS_PER_DAY
local TICKS_PER_SEASON = 3 * TICKS_PER_MONTH
local TICKS_PER_YEAR = 4 * TICKS_PER_SEASON

-- time checks near year turnover is wishy-washy until we have a datetime API available
local WEEK_BEFORE_EOY_TICKS = TICKS_PER_YEAR - TICKS_PER_WEEK

-- update stuck_creatures records and check timeout
Expand Down Expand Up @@ -113,9 +115,15 @@ function free_all_wildlife(include_hidden)
end
end

local function unstick_surface_wildlife(opts)
local function is_onscreen(unit, viewport)
viewport = viewport or guidm.Viewport.get()
return viewport:isVisible(xyz2pos(dfhack.units.getPosition(unit))), viewport
end

local function unstick_wildlife(opts)
local unstuck = {}
local week_ago_ticks = math.max(0, df.global.cur_year_tick - TICKS_PER_WEEK)
local viewport
for _,unit in ipairs(df.global.world.units.active) do
if not is_active_wildlife(unit) or unit.animal.leave_countdown > 0 then
goto skip
Expand All @@ -132,7 +140,9 @@ local function unstick_surface_wildlife(opts)
unstuck_entry.count = unstuck_entry.count + 1
if not opts.dry_run then
stuck_creatures[unit.id] = nil
exterminate.killUnit(unit, exterminate.killMethod.DISINTEGRATE)
local unit_is_visible
unit_is_visible, viewport = is_onscreen(unit, viewport)
exterminate.killUnit(unit, not unit_is_visible and exterminate.killMethod.DISINTEGRATE or nil)
end
::skip::
end
Expand Down Expand Up @@ -188,5 +198,5 @@ if positionals[1] == 'ignore' then
print(('%s will now be ignored by fix/wildlife'):format(dfhack.units.getReadableName(unit)))
end
else
unstick_surface_wildlife(opts)
unstick_wildlife(opts)
end
Loading