forked from DFHack/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
list-waves.lua
209 lines (185 loc) · 6.47 KB
/
list-waves.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
-- displays migration wave information for citizens/units
-- Written by Josh Cooper(cppcooper) sometime around Decement 2019, last modified: 2020-02-19
utils ={}
utils = require('utils')
local validArgs = utils.invert({
'unit',
'all',
'granularity',
'showarrival',
'help'
})
local args = utils.processArgs({...}, validArgs)
local help = [====[
list-waves
==========
This script displays information about migration waves of the specified citizen(s).
Examples::
list-waves -all -showarrival -granularity days
list-waves -all -showarrival
list-waves -unit -granularity days
list-waves -unit
list-waves -unit -all -showarrival -granularity days
**Selection options:**
These options are used to specify what wave information to display
``-unit``:
Displays the highlighted unit's arrival wave information
``-all``:
Displays all citizens' arrival wave information
**Other options:**
``-granularity <value>``:
Specifies the granularity of wave enumeration: ``years``, ``seasons``, ``months``, ``days``
If omitted, the default granularity is ``seasons``, the same as Dwarf Therapist
``-showarrival``:
Shows the arrival information for the selected unit.
If ``-all`` is specified the info displayed will be relative to the
granularity used. Note: this option is always used when ``-unit`` is used.
]====]
--[[
The script must loop through all active units in df.global.world.units.active and build
each wave one dwarf at a time. This requires calculating arrival information for each
dwarf and combining this information into a sort of unique wave ID number. After this
is finished these wave UIDs are loops through and normalized so they start at zero and
incremented by one for each new wave UID.
As you might surmise, this is a relatively dumb script and every execution has the
worst case big O execution. I've taken the liberty of only counting citizen units,
this should only include dwarves as far as I know.
]]
selected = dfhack.gui.getSelectedUnit()
local ticks_per_day = 1200
local ticks_per_month = 28 * ticks_per_day
local ticks_per_season = 3 * ticks_per_month
local ticks_per_year = 12 * ticks_per_month
local current_tick = df.global.cur_year_tick
local seasons = {
'spring',
'summer',
'autumn',
'winter',
}
function TableLength(table)
local count = 0
for i,k in pairs(table) do
count = count + 1
end
return count
end
--sorted pairs
function spairs(t, cmp)
-- collect the keys
local keys = {}
for k,v in pairs(t) do
table.insert(keys,k)
end
utils.sort_vector(keys, nil, cmp)
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
function isDwarfCitizen(dwf)
return dfhack.units.isCitizen(dwf)
end
waves={}
function getWave(dwf)
arrival_time = current_tick - dwf.curse.time_on_site
--print(string.format("Current year %s, arrival_time = %s, ticks_per_year = %s", df.global.cur_year, arrival_time, ticks_per_year))
arrival_year = df.global.cur_year + (arrival_time // ticks_per_year)
arrival_season = 1 + (arrival_time % ticks_per_year) // ticks_per_season
arrival_month = 1 + (arrival_time % ticks_per_year) // ticks_per_month
arrival_day = 1 + ((arrival_time % ticks_per_year) % ticks_per_month) // ticks_per_day
if args.granularity then
if args.granularity == "days" then
wave = arrival_day + (100 * arrival_month) + (10000 * arrival_year)
elseif args.granularity == "months" then
wave = arrival_month + (100 * arrival_year)
elseif args.granularity == "seasons" then
wave = arrival_season + (10 * arrival_year)
elseif args.granularity == "years" then
wave = arrival_year
else
error("Invalid granularity value. Omit the option if you want 'seasons'. Note: plurals only.")
end
else
wave = 10 * arrival_year + arrival_season
end
if waves[wave] == nil then
waves[wave] = {}
end
table.insert(waves[wave],dwf)
if args.unit and dwf == selected then
print(string.format(" Selected citizen arrived in the %s of year %d, month %d, day %d.",seasons[arrival_season],arrival_year,arrival_month,arrival_day))
end
end
for _,v in ipairs(df.global.world.units.active) do
if isDwarfCitizen(v) then
getWave(v)
end
end
if args.help or (not args.all and not args.unit) then
print(help)
else
zwaves = {}
i = 0
for k,v in spairs(waves, utils.compare) do
if args.showarrival then
season = nil
month = nil
day = nil
if args.granularity then
if args.granularity == "days" then
year = k // 10000
month = (k - (10000 * year)) // 100
season = 1 + (month // 3)
day = k - ((100 * month) + (10000 * year))
elseif args.granularity == "months" then
year = k // 100
month = k - (100 * year)
season = 1 + (month // 3)
elseif args.granularity == "seasons" then
year = k // 10
season = k - (10 * year)
elseif args.granularity == "years" then
year = k
end
else
year = k // 10
season = k - (10 * year)
end
if season ~= nil then
season = string.format("the %s of",seasons[season])
else
season = ""
end
if month ~= nil then
month = string.format(", month %d", month)
else
month = ""
end
if day ~= nil then
day = string.format(", day %d", day)
else
day = ""
end
if args.all then
print(string.format(" Wave %d of citizens arrived in %s year %d%s%s.",i,season,year,month,day))
end
end
zwaves[i] = waves[k]
for _,dwf in spairs(v, utils.compare) do
if args.unit and dwf == selected then
print(string.format(" Selected citizen belongs to wave %d",i))
end
end
i = i + 1
end
if args.all then
for i = 0, TableLength(zwaves)-1 do
print(string.format(" Wave %2s has %2d dwarf citizens.", i, #zwaves[i]))
end
end
end