-
Notifications
You must be signed in to change notification settings - Fork 0
/
logPaths.lua
154 lines (129 loc) · 4.04 KB
/
logPaths.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
--@enable = true
--@module = true
-- define module name
local GLOBAL_KEY = 'logPaths'
-- import repeat
local repeatUtil = require("repeat-util")
-- define modId
local modId = "logPaths"
-- define filePrefix to pathViz/ data directory
local filePrefix = ""
-- assert enabled
enabled = enabled or false
function isEnabled()
return enabled
end
local function get_paths()
-- define final data array
local data = {}
-- loop through all citizens
for _, v in ipairs(dfhack.units.getCitizens(true, true)) do
-- check that the unit is a dwarf...
if (v.race == 572) then
-- define the new unit data struc
local newUnit = {
goal = v.path.goal,
path = {
x = v.path.path.x,
y = v.path.path.y,
z = v.path.path.z
}
}
-- if newUnit exists...
if newUnit ~= nil then
-- insert to final data array
table.insert(data, newUnit)
end
end
end
-- return the final data array
return data
end
-- Get the date of the world as a string
-- Format: "YYYYY-MM-DD"
local function get_world_date_str()
local month = dfhack.world.ReadCurrentMonth() + 1 --days and months are 1-indexed
local day = dfhack.world.ReadCurrentDay()
local date_str = string.format('%05d-%02d-%02d', df.global.cur_year, month, day)
return date_str
end
local function write_to_file(data)
local filepath = string.gsub(get_world_date_str(), "-", "") .. ".txt"
local logFile = io.open(filePrefix .. filepath, "w")
local unitCount = 0
if logFile ~= nil then
for i, u in ipairs(data) do
-- save unit-level features
local unitId = tostring(i)
local unitGoal = tostring(u.goal)
-- loop through unit path vectors
-- where n = length of unit.path vectors
local vLen = #u.path.x
if vLen > 1 then
-- for each path vector
for v = 1, vLen - 1, 1 do
local textRow = tostring(unitId) ..
"," ..
tostring(unitGoal) ..
"," ..
tostring(u.path.x[v]) .. "," .. tostring(u.path.y[v]) .. "," .. tostring(u.path.z[v]) .. "\n"
logFile:write(textRow)
end
end
unitCount = unitCount + 1
end
end
print('Logged ' .. unitCount .. ' dwarf paths...')
end
dfhack.onStateChange[GLOBAL_KEY] = function(sc)
if sc == SC_MAP_UNLOADED then
dfhack.run_command('disable', 'logPaths')
-- ensure our mod doesn't try to enable itself when a different
-- world is loaded where we are *not* active
dfhack.onStateChange[GLOBAL_KEY] = nil
return
end
if sc ~= SC_MAP_LOADED or df.global.gamemode ~= df.game_mode.DWARF then
return
end
dfhack.run_command('enable', 'logPaths')
end
if dfhack_flags.module then
return
end
if not dfhack_flags.enable then
print(dfhack.script_help())
print()
local flag = 'disabled'
if enabled then
flag = 'enabled'
end
print('logPaths is currently ' .. flag)
return
end
-- check if module enabled...
if dfhack_flags.enable_state then
-- if module is enabled
-- monitor dwarf positions every 1wk or 8400 ticks
-- *called before setting enabled flag for immediate logging*
repeatUtil.scheduleEvery(modId .. 'every 1wk', 8400, 'ticks', function()
-- get the data
local newData = get_paths()
-- if data exists, write to file
if newData then
write_to_file(newData)
end
end)
-- set enabled
enabled = true
-- update user
print("Logging dwarf positions every 1 week...")
else
-- if module is not enabled
-- cancel script repeat
repeatUtil.cancel(modId .. 'every 1wk')
-- set enabled
enabled = false
-- update user
print("Stopped logging dwarf positions")
end