diff --git a/changelog.txt b/changelog.txt index 7491c9e391..dc3bcd11e9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -30,6 +30,9 @@ Template for new versions: ## New Features +## New Scripts +- `warn-stranded`: new repeatable maintenance script to check for stranded units, based off warn-starving + ## Fixes ## Misc Improvements diff --git a/docs/warn-stranded.rst b/docs/warn-stranded.rst new file mode 100644 index 0000000000..b5db2dd496 --- /dev/null +++ b/docs/warn-stranded.rst @@ -0,0 +1,27 @@ +warn-stranded +============= + +.. dfhack-tool:: + :summary: Reports citizens that are stranded and can't reach any other unit + :tags: fort units + +If any (live) units are stranded the game will pause and you'll get a warning dialog telling you +which units are isolated. This gives you a chance to rescue them before +they get overly stressed or start starving. + +You can enable ``warn-stranded`` notifications in `gui/control-panel` on the "Maintenance" tab. + +Usage +----- + +:: + + warn-stranded + +Examples +-------- + +``warn-stranded`` + +Options +------- diff --git a/gui/control-panel.lua b/gui/control-panel.lua index 24689c0c6b..707ad22dce 100644 --- a/gui/control-panel.lua +++ b/gui/control-panel.lua @@ -130,6 +130,9 @@ local REPEATS = { ['warn-starving']={ desc='Show a warning dialog when units are starving or dehydrated.', command={'--time', '10', '--timeUnits', 'days', '--command', '[', 'warn-starving', ']'}}, + ['warn-stranded']={ + desc='Show a warning dialog when units are stranded from all others.' + command={'--time', '300', '--timeUnits', 'ticks', '--command', '[', 'warn-stranded', ']'}}, ['empty-wheelbarrows']={ desc='Empties wheelbarrows which have rocks stuck in them.', command={'--time', '1', '--timeUnits', 'days', '--command', '[', 'fix/empty-wheelbarrows', '-q', ']'}}, diff --git a/warn-stranded.lua b/warn-stranded.lua index 74e181224e..b08b0be080 100644 --- a/warn-stranded.lua +++ b/warn-stranded.lua @@ -1,7 +1,41 @@ -- Detects and alerts when a citizen is stranded -- by Azrazalea +-- Heavily based off of warn-starving +-- Thanks myk002 for telling me about pathability groups! +--@ module = true + +local gui = require 'gui' +local utils = require 'utils' +local widgets = require 'gui.widgets' + +warning = defclass(warning, gui.ZScreen) +warning.ATTRS = { + focus_path='warn-stranded', + force_pause=true, + pass_mouse_clicks=false, +} + +function warning:init(info) + local main = widgets.Window{ + frame={w=80, h=18}, + frame_title='Stranded Citizen Warning', + resizable=true, + autoarrange_subviews=true + } + + main:addviews{ + widgets.WrappedLabel{ + text_to_wrap=table.concat(info.messages, NEWLINE), + } + } + + self:addviews{main} +end + +function warning:onDismiss() + view = nil +end --- Taken from warn-starving local function getSexString(sex) local sym = df.pronoun_type.attrs[sex].symbol if not sym then @@ -30,17 +64,37 @@ function doCheck() local strandedUnits = {} + for _, units in pairs(grouped) do if #units == 1 then table.insert(strandedUnits, units[1]) end end - print("Number of stranded: ") - print(#strandedUnits) - for _, unit in pairs(strandedUnits) do - print('['..dfhack.units.getProfessionName(unit)..'] '..dfhack.TranslateName(dfhack.units.getVisibleName(unit))..' '..getSexString(unit.sex)..' Stress category: '..dfhack.units.getStressCategory(unit)) - end + if #strandedUnits > 0 then + dfhack.color(COLOR_LIGHTMAGENTA) + + local messages = {} + local preface = "Number of stranded: "..#strandedUnits + print(dfhack.df2console(preface)) + table.insert(messages, preface) + for _, unit in pairs(strandedUnits) do + local unitString = '['..dfhack.units.getProfessionName(unit)..'] '..dfhack.TranslateName(dfhack.units.getVisibleName(unit))..' '..getSexString(unit.sex)..' Stress category: '..dfhack.units.getStressCategory(unit) + print(dfhack.df2console(unitString)) + table.insert(messages, unitString) + end + + dfhack.color() + return warning{messages=messages}:show() + end +end + +if dfhack_flags.module then + return +end + +if not dfhack.isMapLoaded() then + qerror('warn-stranded requires a map to be loaded') end -doCheck() +view = view and view:raise() or doCheck()