141 lines
4.4 KiB
Lua
141 lines
4.4 KiB
Lua
-- Pauses the game with a warning if a creature is starving, dehydrated, or very drowsy.
|
|
-- By Meneth32, PeridexisErrant, Lethosor
|
|
--@ module = true
|
|
--[[=begin
|
|
|
|
warn-starving
|
|
=============
|
|
If any (live) units are starving, very thirsty, or very drowsy, the game will
|
|
be paused and a warning shown and logged to the console. Use with the
|
|
`repeat` command for regular checks.
|
|
|
|
Use ``warn-starving all`` to display a list of all problematic units.
|
|
|
|
=end]]
|
|
|
|
starvingUnits = starvingUnits or {}
|
|
dehydratedUnits = dehydratedUnits or {}
|
|
sleepyUnits = sleepyUnits or {}
|
|
|
|
function clear()
|
|
starvingUnits = {}
|
|
dehydratedUnits = {}
|
|
sleepyUnits = {}
|
|
end
|
|
|
|
local gui = require 'gui'
|
|
local utils = require 'utils'
|
|
local units = df.global.world.units.active
|
|
|
|
local args = utils.invert({...})
|
|
if args.all or args.clear then
|
|
clear()
|
|
end
|
|
|
|
warning = defclass(warning, gui.FramedScreen)
|
|
warning.ATTRS = {
|
|
frame_style = gui.GREY_LINE_FRAME,
|
|
frame_title = 'Warning',
|
|
frame_width = 20,
|
|
frame_height = 18,
|
|
frame_inset = 1,
|
|
focus_path = 'warn-starving',
|
|
}
|
|
|
|
function warning:init(args)
|
|
self.start = 1
|
|
self.messages = args.messages
|
|
self.frame_height = math.min(18, #self.messages)
|
|
self.max_start = #self.messages - self.frame_height + 1
|
|
for _, msg in pairs(self.messages) do
|
|
self.frame_width = math.max(self.frame_width, #msg + 2)
|
|
end
|
|
self.frame_width = math.min(df.global.gps.dimx - 2, self.frame_width)
|
|
end
|
|
|
|
function warning:onRenderBody(p)
|
|
for i = self.start, math.min(self.start + self.frame_height - 1, #self.messages) do
|
|
p:string(self.messages[i]):newline()
|
|
end
|
|
if #self.messages > self.frame_height then
|
|
if self.start > 1 then
|
|
p:seek(self.frame_width - 1, 0):string(string.char(24), COLOR_LIGHTCYAN) -- up
|
|
end
|
|
if self.start < self.max_start then
|
|
p:seek(self.frame_width - 1, self.frame_height - 1):string(string.char(25), COLOR_LIGHTCYAN) -- down
|
|
end
|
|
end
|
|
end
|
|
|
|
function warning:onInput(keys)
|
|
if keys.LEAVESCREEN or keys.SELECT then
|
|
self:dismiss()
|
|
elseif keys.CURSOR_UP or keys.STANDARDSCROLL_UP then
|
|
self.start = math.max(1, self.start - 1)
|
|
elseif keys.CURSOR_DOWN or keys.STANDARDSCROLL_DOWN then
|
|
self.start = math.min(self.start + 1, self.max_start)
|
|
end
|
|
end
|
|
|
|
local function findRaceCaste(unit)
|
|
local rraw = df.creature_raw.find(unit.race)
|
|
return rraw, safe_index(rraw, 'caste', unit.caste)
|
|
end
|
|
|
|
local function getSexString(sex)
|
|
local sexStr = ""
|
|
if sex==0 then sexStr=string.char(12)
|
|
elseif sex==1 then sexStr=string.char(11)
|
|
end
|
|
return string.char(40)..sexStr..string.char(41)
|
|
end
|
|
|
|
local function nameOrSpeciesAndNumber(unit)
|
|
if unit.name.has_name then
|
|
return dfhack.TranslateName(dfhack.units.getVisibleName(unit))..' '..getSexString(unit.sex),true
|
|
else
|
|
return 'Unit #'..unit.id..' ('..df.creature_raw.find(unit.race).caste[unit.caste].caste_name[0]..' '..getSexString(unit.sex)..')',false
|
|
end
|
|
end
|
|
|
|
local function checkVariable(var, limit, description, map, unit)
|
|
local rraw = findRaceCaste(unit)
|
|
local species = rraw.name[0]
|
|
local profname = dfhack.units.getProfessionName(unit)
|
|
if #profname == 0 then profname = nil end
|
|
local name = nameOrSpeciesAndNumber(unit)
|
|
if var > limit then
|
|
if not map[unit.id] then
|
|
map[unit.id] = true
|
|
return name .. ", " .. (profname or species) .. " is " .. description .. "!"
|
|
end
|
|
else
|
|
map[unit.id] = false
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function doCheck()
|
|
local messages = {}
|
|
for i=#units-1, 0, -1 do
|
|
local unit = units[i]
|
|
local rraw = findRaceCaste(unit)
|
|
if rraw and not unit.flags1.dead and not dfhack.units.isOpposedToLife(unit) then
|
|
table.insert(messages, checkVariable(unit.counters2.hunger_timer, 75000, 'starving', starvingUnits, unit))
|
|
table.insert(messages, checkVariable(unit.counters2.thirst_timer, 50000, 'dehydrated', dehydratedUnits, unit))
|
|
table.insert(messages, checkVariable(unit.counters2.sleepiness_timer, 150000, 'very drowsy', sleepyUnits, unit))
|
|
end
|
|
end
|
|
if #messages > 0 then
|
|
dfhack.color(COLOR_LIGHTMAGENTA)
|
|
for _, msg in pairs(messages) do
|
|
print(dfhack.df2console(msg))
|
|
end
|
|
dfhack.color()
|
|
df.global.pause_state = true
|
|
warning{messages=messages}:show()
|
|
end
|
|
end
|
|
|
|
if not moduleMode then doCheck() end
|