Skip to content

Commit 4e39b7e

Browse files
realSquidCoderchdoc
andcommitted
Fix up from testing
improvements to `autotraining`: - fix the argument error - avoid the double execution of the loop when enabling - consistently only count ignored units when they would otherwise qualify for training - allow enabling the tool from within `gui/autotraining` - sort the list of training candidates, so that the most needed candidates are preferred for training - move the argument handling out of the `start` function Co-Authored-By: Christian Doczkal <20443222+chdoc@users.noreply.github.com>
1 parent 8cee911 commit 4e39b7e

File tree

2 files changed

+77
-42
lines changed

2 files changed

+77
-42
lines changed

autotraining.lua

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -99,38 +99,43 @@ end
9999
--######
100100
--Functions
101101
--######
102+
local function isIgnoredNoble(unit)
103+
local noblePos = dfhack.units.getNoblePositions(unit)
104+
if noblePos ~= nil then
105+
for _, position in ipairs(noblePos) do
106+
if state.ignored_nobles[position.position.code] then
107+
return true
108+
end
109+
end
110+
end
111+
return false
112+
end
113+
114+
---@return table<integer, { ['unit']: df.unit, ['need']: integer }>
102115
function getTrainingCandidates()
103116
local ret = {}
104117
ignore_count = 0
105118
for _, unit in ipairs(dfhack.units.getCitizens(true)) do
106-
if state.ignored[unit.id] then
107-
ignore_count = ignore_count +1
108-
goto next_unit
109-
end
110119
if not dfhack.units.isAdult(unit) then
111120
goto next_unit
112121
end
113122
local need = getTrainingNeed(unit)
114123
if not need or need.focus_level >= state.threshold then
115124
goto next_unit
116125
end
117-
local noblePos = dfhack.units.getNoblePositions(unit)
118-
local isIgnNoble = false
119-
if noblePos ~=nil then
120-
for _, position in ipairs(noblePos) do
121-
if state.ignored_nobles[position.position.code] then
122-
isIgnNoble = true
123-
break
124-
end
125-
end
126+
-- ignored units are those that would like to train but are forbidden from doing so
127+
if state.ignored[unit.id] then
128+
ignore_count = ignore_count + 1
129+
goto next_unit
126130
end
127-
if isIgnNoble then
128-
ignore_count = ignore_count +1
131+
if isIgnoredNoble(unit) then
132+
ignore_count = ignore_count + 1
129133
goto next_unit
130134
end
131-
table.insert(ret, unit)
135+
table.insert(ret, { unit = unit, need = need.focus_level })
132136
::next_unit::
133137
end
138+
table.sort(ret, function (a, b) return a.need < b.need end)
134139
return ret
135140
end
136141

@@ -229,52 +234,63 @@ function check()
229234
local unit = df.unit.find(hf.unit_id)
230235
local training_need = getTrainingNeed(unit)
231236
if not training_need or training_need.focus_level >= state.threshold then
232-
dfhack.military.removeFromSquad(unit)
237+
dfhack.military.removeFromSquad(unit.id)
233238
end
234239
end
235240
end
236241
end
237242
end
238-
for _, unit in ipairs(getTrainingCandidates()) do
239-
local added = addTraining(unit, squads)
243+
for _, p in ipairs(getTrainingCandidates()) do
244+
local added = addTraining(p.unit, squads)
240245
if added then
241246
intraining_count = intraining_count +1
242247
else
243248
inque_count = inque_count +1
244249
end
245250
end
246-
247-
dfhack.println(GLOBAL_KEY .. " | IGNORED: " .. ignore_count .. " TRAINING: " .. intraining_count .. " QUEUE: " ..inque_count )
251+
print(("%s: %d training, %d waiting, and %d excluded units with training needs"):
252+
format(GLOBAL_KEY, intraining_count, inque_count, ignore_count))
248253
end
249254

250255
function start()
251-
if args.t then
252-
state.threshold = 0-tonumber(args.t)
253-
end
254256
repeatUtil.scheduleEvery(GLOBAL_KEY, 1, 'days', check)
255257
end
256258

257259
function stop()
258260
repeatUtil.cancel(GLOBAL_KEY)
259261
end
260262

261-
if dfhack_flags.enable then
262-
if dfhack_flags.enable_state then
263-
state.enabled = true
264-
else
265-
state.enabled = false
266-
end
263+
function enable()
264+
state.enabled = true
267265
persist_state()
266+
start()
267+
end
268+
269+
function disable()
270+
state.enabled = false
271+
persist_state()
272+
stop()
273+
removeAll()
268274
end
269275

270276
if dfhack_flags.module then
271277
return
272278
end
273279

274-
if state.enabled then
275-
start()
280+
if dfhack_flags.enable then
281+
if dfhack_flags.enable_state then
282+
enable()
283+
else
284+
disable()
285+
end
276286
else
277-
stop()
278-
removeAll()
287+
-- called on the command-line
288+
if args.t then
289+
state.threshold = 0-tonumber(args.t)
290+
end
291+
print(("autotraining is %s"):format(state.enabled and "enabled" or "disabled"))
279292
end
280-
persist_state()
293+
294+
295+
296+

gui/autotraining.lua

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function AutoTrain:getSquads()
3232
goto continue
3333
end
3434
table.insert(squads, {
35-
text = dfhack.translation.translateName(squad.name, true)..' ('..squad.alias..')',
35+
text = dfhack.translation.translateName(squad.name, true)..(squad.alias ~= '' and ' ('..squad.alias..')' or ''),
3636
icon = self:callback("getSquadIcon", squad.id ),
3737
id = squad.id
3838
})
@@ -192,25 +192,40 @@ function AutoTrain:init()
192192
self.subviews.threshold:setText(tostring(entered_number))
193193
end
194194
},
195-
widgets.Divider{ frame={t=9, h=1}, frame_style_l = false, frame_style_r = false},
195+
widgets.ToggleHotkeyLabel {
196+
view_id = 'enable_toggle',
197+
frame = { t = 9, h = 1 },
198+
label = 'Autotraining is',
199+
key = 'CUSTOM_E',
200+
options = { { value = true, label = 'Enabled', pen = COLOR_GREEN },
201+
{ value = false, label = 'Disabled', pen = COLOR_RED } },
202+
on_change = function(val)
203+
if val then
204+
autotraining.enable()
205+
else
206+
autotraining.disable()
207+
end
208+
end,
209+
},
210+
widgets.Divider{ frame={t=10, h=1}, frame_style_l = false, frame_style_r = false},
196211
widgets.Label{
197-
frame={ t = 10 , h = 1 },
212+
frame={ t = 11 , h = 1 },
198213
text = "Ignored noble positions:",
199214
},
200215
widgets.List{
201-
frame = { t = 11 , h = 11},
216+
frame = { t = 12 , h = 11},
202217
view_id = "nobles_list",
203218
icon_width = 2,
204219
choices = self:getPositions(),
205220
on_submit=self:callback("toggleNoble")
206221
},
207-
widgets.Divider{ frame={t=22, h=1}, frame_style_l = false, frame_style_r = false},
222+
widgets.Divider{ frame={t=23, h=1}, frame_style_l = false, frame_style_r = false},
208223
widgets.Label{
209-
frame={ t = 23 , h = 1 },
224+
frame={ t = 24 , h = 1 },
210225
text = "Select units to exclude from automatic training:"
211226
},
212227
widgets.FilteredList{
213-
frame = { t = 24 },
228+
frame = { t = 25 },
214229
view_id = "unit_list",
215230
edit_key = "CUSTOM_CTRL_F",
216231
icon_width = 2,
@@ -221,6 +236,10 @@ function AutoTrain:init()
221236
--self.subviews.unit_list:setChoices(unit_choices)
222237
end
223238

239+
function AutoTrain:onRenderBody(painter)
240+
self.subviews.enable_toggle:setOption(autotraining.state.enabled)
241+
end
242+
224243
function AutoTrain:onDismiss()
225244
view = nil
226245
end

0 commit comments

Comments
 (0)