-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathstatus.lua
211 lines (159 loc) · 6.58 KB
/
status.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
--todo: move date formatting to utils
TU_PER_DAY = 1200
TU_PER_MONTH = TU_PER_DAY * 28
TU_PER_YEAR = TU_PER_MONTH * 12
MONTHS = {
'Granite',
'Slate',
'Felsite',
'Hematite',
'Malachite',
'Galena',
'Limestone',
'Sandstone',
'Timber',
'Moonstone',
'Opal',
'Obsidian',
}
function format_date(year, ticks)
local month = math.floor(ticks / TU_PER_MONTH)
local day = math.floor((ticks-month*TU_PER_MONTH) / TU_PER_DAY) + 1
local b = day % 10
local suf = math.floor((day % 100) / 10) == 1 and 'th' or b == 1 and 'st' or b == 2 and 'nd' or b == 3 and 'rd' or 'th'
local datestr = day .. suf .. ' ' .. MONTHS[month+1] .. ', ' .. year
return datestr
end
local seasons = { 'Spring', 'Summer', 'Autumn', 'Winter' }
local seasonparts = { 'Early ', 'Mid-', 'Late ' }
local site_ranks = { 'Outpost', 'Hamlet', 'Village', 'Town', 'City', 'Metropolis' }
--xxx: this is done manually because the in-game display doesn't quite match ui.tasks.unit_counts and df.profession structures
function get_unit_counts()
local c = df.global.ui.tasks.unit_counts
local count_nobles = c.CLERK + c.ADMINISTRATOR + c.TRADER +
c.ARCHITECT + c.ALCHEMIST +
c.DOCTOR + c.DIAGNOSER + c.BONE_SETTER + c.SUTURER + c.SURGEON
local ret_civil = {
{ 'Miners', c.MINER, 7 },
{ 'Woodworkers', c.WOODWORKER, 6+8 },
{ 'Stoneworkers', c.STONEWORKER, 15 },
{ 'Rangers', c.HUNTER, 2 },
{ 'Metalsmiths', c.METALSMITH, 0+8},
{ 'Jewelers', c.JEWELER, 2+8 },
{ 'Craftsdwarves', c.CRAFTSMAN },
{ 'Nobles & Admins', count_nobles, 5 },
{ 'Peasants', c.STANDARD, 3 },
{ 'Dwarven Children', c.CHILD, 4 },
{ 'Fishery Workers', c.FISHERY_WORKER, 1 },
{ 'Farmers', c.FARMER, 6 },
{ 'Engineers', c.ENGINEER, 4+8 },
}
local ret_animal = {
{ 'Trained Animals', df.global.ui.tasks.trained_animals, 15 },
{ 'Other Animals', df.global.ui.tasks.other_animals, 7 },
}
local ret_mil = {
{ 'Axedwarves', c.AXEMAN, 1 },
{ 'Axe Lords', c.MASTER_AXEMAN, 1+8 },
{ 'Swordsdwarves', c.SWORDSMAN, 3 },
{ 'Swordmasters', c.MASTER_SWORDSMAN, 3+8 },
{ 'Macedwarves', c.MACEMAN, 4 },
{ 'Mace Lords', c.MASTER_MACEMAN, 4+8 },
{ 'Hammerdwarves', c.HAMMERMAN, 5 },
{ 'Hammer Lords', c.MASTER_HAMMERMAN, 5+8 },
{ 'Speardwarves', c.SPEARMAN, 6 },
{ 'Spearmasters', c.MASTER_SPEARMAN, 6+8 },
{ 'Marksdwarves', c.CROSSBOWMAN, 2 },
{ 'Elite Marksdwarves', c.MASTER_CROSSBOWMAN, 2+8 },
{ 'Wrestlers', c.WRESTLER, 7 },
{ 'Elite Wrestlers', c.MASTER_WRESTLER, 15 },
{ 'Recruit & Others', c.RECRUIT, 0+8 },
}
return ret_civil, ret_mil, ret_animal
end
--luacheck: in=
function status_get_overview()
local wealth = df.global.ui.tasks.wealth
local food = df.global.ui.tasks.food
local have_appraisal = have_broker_appraisal()
local created_wealth = { wealth.total, wealth.weapons, wealth.armor, wealth.furniture, wealth.other, wealth.architecture, wealth.displayed, wealth.held }
local ret_food = { food.total, food.meat, food.fish, food.plant, food.seeds, food.drink, food.other }
local site = df.world_site.find(df.global.ui.site_id)
local is_mountainhome = have_noble('MONARCH') --todo: what if monarch dies? there should be more correct way
local site_title = (is_mountainhome and 'Mountainhome' or site_ranks[df.global.ui.fortress_rank+1]) .. ' ' .. translatename(site.name) .. ', "' .. dfhack.TranslateName(site.name, true) .. '"'
local month = math.floor(df.global.cur_year_tick / TU_PER_MONTH)
local datestr = format_date(df.global.cur_year, df.global.cur_year_tick) .. ', ' .. seasonparts[month%3+1] .. seasons[math.floor(month/3)+1]
local population = df.global.ui.tasks.population
local c1,c2,c3 = get_unit_counts()
local precision = df.global.ui.nobles.bookkeeper_precision
return { site_title, datestr, created_wealth, wealth.imported, wealth.exported, ret_food, population, c1,c2,c3, have_appraisal, precision }
end
--luacheck: in=bool
function status_get_health(include_healthy)
if not have_noble('CHIEF_MEDICAL_DWARF') then
return { false }
end
include_healthy = istrue(include_healthy)
return execute_with_status_page(status_pages.Health, function(ws)
local ws = ws --as:df.viewscreen_layer_overall_healthst
local ret = {}
for i,unit in ipairs(ws.unit) do
local b1 = ws.bits1[i].whole
local b2 = ws.bits2[i].whole
local b3 = ws.bits3[i].whole
if include_healthy or b1 ~= 0 or b2 ~= 0 or b3 ~= 0 then
table.insert(ret, { unit_fulltitle(unit), unit.id, b1, b2, b3 })
end
end
return { true, ret }
end)
end
--luacheck: in=number[]
function performance_skill_get_description(_id)
local type = _id[1]
local id = _id[2]
-- instrument
if type == 0 then
local inst = df.global.world.raws.itemdefs.instruments[id]
local text = fixspaces(inst.description)
text = dfhack.df2utf(text)
return { text }
end
local unit = df.unit:new()
local scr = df.viewscreen_unitlistst:new()
local act = df.activity_entry:new()
act.id = 9999999
act.type = 8
df.global.world.activities.all:insert(#df.global.world.activities.all, act)
unit.social_activities:insert(0,9999999)
local event = df.activity_event_performancest:new()
event.type = type
event.event = id
act.events:insert(0,event)
scr.units[0]:insert(0, unit)
scr.jobs[0]:insert(0, nil)
scr.page = df.viewscreen_unitlist_page.Citizens
scr.cursor_pos[0] = 0
gui.simulateInput(scr, 'UNITJOB_VIEW_JOB')
df.global.world.activities.all:erase(#df.global.world.activities.all-1)
scr.units[0]:erase(0)
unit:delete()
event:delete()
act:delete()
scr:delete()
local ws = dfhack.gui.getCurViewscreen() --as:df.viewscreen_textviewerst
if ws._type ~= df.viewscreen_textviewerst then
error('can not switch to form description screen')
end
ws.breakdown_level = df.interface_breakdown_types.STOPSCREEN
local text = ''
for i,v in ipairs(ws.src_text) do
if #v.value > 0 then
text = text .. dfhack.df2utf(v.value) .. ' '
end
end
text = fixspaces(text)
return { text }
end
--print(pcall(function() return json:encode(status_get_health()) end))
--print(pcall(function() return json:encode(performance_skill_get_description({1,2})) end))