-
Notifications
You must be signed in to change notification settings - Fork 200
/
Copy pathassign-rack.lua
209 lines (181 loc) · 5.88 KB
/
assign-rack.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
-- Assign weapon racks to squads (needs binpatch)
--[====[
gui/assign-rack
===============
`This script requires a binpatch <binpatches/needs-patch>`, which has not
been available since DF 0.34.11
See :bug:`1445` for more info about the patches.
]====]
local utils = require 'utils'
local gui = require 'gui'
local guidm = require 'gui.dwarfmode'
local widgets = require 'gui.widgets'
local dlg = require 'gui.dialogs'
local bp = require 'binpatch'
AssignRack = defclass(AssignRack, guidm.MenuOverlay)
AssignRack.focus_path = 'assign-rack'
AssignRack.ATTRS {
building = DEFAULT_NIL,
frame_inset = 1,
frame_background = COLOR_BLACK,
}
function list_squads(building,squad_table,squad_list)
local sqlist = building:getSquads()
if not sqlist then
return
end
for i,v in ipairs(sqlist) do
local obj = df.squad.find(v.squad_id)
if obj then
if not squad_table[v.squad_id] then
squad_table[v.squad_id] = { id = v.squad_id, obj = obj }
table.insert(squad_list, squad_table[v.squad_id])
end
-- Set specific use flags
for n,ok in pairs(v.mode) do
if ok then
squad_table[v.squad_id][n] = true
end
end
-- Check if any use is possible
local btype = building:getType()
if btype == df.building_type.Bed then
if v.mode.sleep then
squad_table[v.squad_id].any = true
end
elseif btype == df.building.Weaponrack then
if v.mode.train or v.mode.indiv_eq then
squad_table[v.squad_id].any = true
end
else
if v.mode.indiv_eq then
squad_table[v.squad_id].any = true
end
end
end
end
for i,v in ipairs(building.parents) do
list_squads(v, squad_table, squad_list)
end
end
function filter_invalid(list, id)
for i=#list-1,0,-1 do
local bld = df.building.find(list[i])
if not bld or bld:getSpecificSquad() ~= id then
list:erase(i)
end
end
end
function AssignRack:init(args)
self.squad_table = {}
self.squad_list = {}
list_squads(self.building, self.squad_table, self.squad_list)
table.sort(self.squad_list, function(a,b) return a.id < b.id end)
self.choices = {}
for i,v in ipairs(self.squad_list) do
if v.any and (v.train or v.indiv_eq) then
local name = v.obj.alias
if name == '' then
name = dfhack.TranslateName(v.obj.name, true)
end
filter_invalid(v.obj.rack_combat, v.id)
filter_invalid(v.obj.rack_training, v.id)
table.insert(self.choices, {
icon = self:callback('isSelected', v),
icon_pen = COLOR_LIGHTGREEN,
obj = v,
text = {
name, NEWLINE, ' ',
{ text = function()
return string.format('%d combat, %d training', #v.obj.rack_combat, #v.obj.rack_training)
end }
}
})
end
end
self:addviews{
widgets.Label{
frame = { l = 0, t = 0 },
text = {
'Assign Weapon Rack'
}
},
widgets.List{
view_id = 'list',
frame = { t = 2, b = 2 },
icon_width = 2, row_height = 2,
scroll_keys = widgets.SECONDSCROLL,
choices = self.choices,
on_submit = self:callback('onSubmit'),
},
widgets.Label{
frame = { l = 0, t = 2 },
text_pen = COLOR_LIGHTRED,
text = 'No appropriate barracks\n\nNote: weapon racks use the\nIndividual equipment flag',
visible = (#self.choices == 0),
},
widgets.Label{
frame = { l = 0, b = 0 },
text = {
{ key = 'LEAVESCREEN', text = ': Back',
on_activate = self:callback('dismiss') }
}
},
}
end
function AssignRack:isSelected(info)
if self.building.specific_squad == info.id then
return '\xfb'
else
return nil
end
end
function AssignRack:onSubmit(idx, choice)
local rid = self.building.id
local curid = self.building.specific_squad
local cur = df.squad.find(curid)
if cur then
utils.erase_sorted(cur.rack_combat, rid)
utils.erase_sorted(cur.rack_training, rid)
end
self.building.specific_squad = -1
df.global.ui.equipment.update.buildings = true
local new = df.squad.find(choice.obj.id)
if new and choice.obj.id ~= curid then
self.building.specific_squad = choice.obj.id
if choice.obj.indiv_eq then
utils.insert_sorted(new.rack_combat, rid)
end
if choice.obj.train then
utils.insert_sorted(new.rack_training, rid)
end
end
end
function AssignRack:onInput(keys)
if self:propagateMoveKeys(keys) then
if df.global.world.selected_building ~= self.building then
self:dismiss()
end
else
AssignRack.super.onInput(self, keys)
end
end
if dfhack.gui.getCurFocus() ~= 'dwarfmode/QueryBuilding/Some/Weaponrack' then
qerror("This script requires a weapon rack selected in the 'q' mode")
end
AssignRack{ building = dfhack.gui.getSelectedBuilding() }:show()
if not already_patched then
local patch = bp.load_dif_file('weaponrack-unassign')
if patch and patch:isApplied() then
already_patched = true
end
end
if not already_patched then
dlg.showMessage(
'BUG ALERT',
{ 'This script requires applying the binary patch', NEWLINE,
'named weaponrack-unassign. Otherwise the game', NEWLINE,
'will lose your settings due to a bug.' },
COLOR_YELLOW
)
end