-
Notifications
You must be signed in to change notification settings - Fork 198
/
warn-starving.lua
140 lines (123 loc) · 4.35 KB
/
warn-starving.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
-- Pause and warn if a unit is starving
-- By Meneth32, PeridexisErrant, Lethosor
--@ module = true
--[====[
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.
]====]
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