forked from DFHack/dfhack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogistics.lua
More file actions
167 lines (147 loc) · 6.03 KB
/
logistics.lua
File metadata and controls
167 lines (147 loc) · 6.03 KB
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
local _ENV = mkmodule('plugins.logistics')
local argparse = require('argparse')
local utils = require('utils')
local function make_stat(name, stockpile_number, stats, configs)
return {
enabled=configs[stockpile_number] and configs[stockpile_number][name] == 'true',
designated=stats[name..'_designated'][stockpile_number] or 0,
can_designate=stats[name..'_can_designate'][stockpile_number] or 0,
}
end
function getStockpileData()
local stats, configs = logistics_getStockpileData()
local data = {}
for _,bld in ipairs(df.global.world.buildings.other.STOCKPILE) do
local stockpile_number, name = bld.stockpile_number, bld.name
local sort_key = tostring(name):lower()
if #name == 0 then
name = ('Stockpile #%d'):format(bld.stockpile_number)
sort_key = ('stockpile #%09d'):format(bld.stockpile_number)
end
table.insert(data, {
stockpile_number=stockpile_number,
name=name,
sort_key=sort_key,
melt=make_stat('melt', stockpile_number, stats, configs),
trade=make_stat('trade', stockpile_number, stats, configs),
dump=make_stat('dump', stockpile_number, stats, configs),
train=make_stat('train', stockpile_number, stats, configs),
melt_masterworks=configs[stockpile_number] and configs[stockpile_number].melt_masterworks == 'true',
})
end
table.sort(data, function(a, b) return a.sort_key < b.sort_key end)
return data
end
local function print_stockpile_data(data)
local name_len = 4
for _,sp in ipairs(data) do
name_len = math.min(40, math.max(name_len, #sp.name))
end
local has_melt_mastworks = false
print('Designated/designatable items in stockpiles:')
print()
local fmt = '%6s %-' .. name_len .. 's %4s %10s %5s %11s %4s %10s %5s %11s';
print(fmt:format('number', 'name', 'melt', 'melt items', 'trade', 'trade items', 'dump', 'dump items', 'train', 'train items'))
local function uline(len) return ('-'):rep(len) end
print(fmt:format(uline(6), uline(name_len), uline(4), uline(10), uline(5), uline(11), uline(4), uline(10), uline(5), uline(11)))
local function get_enab(stats, ch) return ('[%s]'):format(stats.enabled and (ch or 'x') or ' ') end
local function get_dstat(stats) return ('%d/%d'):format(stats.designated, stats.designated + stats.can_designate) end
for _,sp in ipairs(data) do
has_melt_mastworks = has_melt_mastworks or sp.melt_masterworks
print(fmt:format(sp.stockpile_number, sp.name, get_enab(sp.melt, sp.melt_masterworks and 'X'), get_dstat(sp.melt),
get_enab(sp.trade), get_dstat(sp.trade), get_enab(sp.dump), get_dstat(sp.dump), get_enab(sp.train), get_dstat(sp.train)))
end
if has_melt_mastworks then
print()
print('An "X" in the "melt" column indicates that masterworks in the stockpile will be melted.')
end
end
local function print_status()
print(('logistics is %sactively monitoring stockpiles and marking items')
:format(isEnabled() and '' or 'not '))
if df.global.gamemode ~= df.game_mode.DWARF or not dfhack.isMapLoaded() then
return
end
local data = getStockpileData()
print()
if not data[1] then
print 'No stockpiles defined -- go make some!'
else
print_stockpile_data(data)
end
local global_stats = logistics_getGlobalCounts()
print()
print(('Total items marked for melting: %5d'):format(global_stats.total_melt))
print(('Total items marked for trading: %5d'):format(global_stats.total_trade))
print(('Total items marked for dumping: %5d'):format(global_stats.total_dump))
print(('Total animals marked for training: %2d'):format(global_stats.total_train))
end
local function for_stockpiles(opts, fn)
if not opts.sp then
local selected_sp = dfhack.gui.getSelectedStockpile()
if not selected_sp then qerror('please specify or select a stockpile') end
fn(selected_sp.stockpile_number)
return
end
for _,sp in ipairs(argparse.stringList(opts.sp)) do
fn(sp)
end
end
local function do_add_stockpile_config(features, opts)
for_stockpiles(opts, function(sp)
local configs = logistics_getStockpileConfigs(tonumber(sp) or sp)
if not configs then
dfhack.printerr('invalid stockpile: '..sp)
else
for _,config in ipairs(configs) do
logistics_setStockpileConfig(config.stockpile_number,
features.melt or config.melt == 1,
features.trade or config.trade == 1,
features.dump or config.dump == 1,
features.train or config.train == 1,
not not opts.melt_masterworks)
end
end
end)
end
local function do_clear_stockpile_config(all, opts)
if all then
logistics_clearAllStockpileConfigs()
return
end
for_stockpiles(opts, function(sp)
logistics_clearStockpileConfig(tonumber(sp) or sp)
end)
end
local function process_args(opts, args)
if args[1] == 'help' then
opts.help = true
return
end
return argparse.processArgsGetopt(args, {
{'h', 'help', handler=function() opts.help = true end},
{'m', 'melt-masterworks', handler=function() opts.melt_masterworks = true end},
{'s', 'stockpile', hasArg=true, handler=function(arg) opts.sp = arg end},
})
end
function parse_commandline(args)
local opts = {}
local positionals = process_args(opts, args)
if opts.help or not positionals then
return false
end
local command = table.remove(positionals, 1)
if not command or command == 'status' then
print_status()
elseif command == 'now' then
logistics_cycle()
elseif command == 'add' then
do_add_stockpile_config(utils.invert(positionals), opts)
elseif command == 'clear' then
do_clear_stockpile_config(utils.invert(positionals).all, opts)
else
return false
end
return true
end
return _ENV