Skip to content

Commit a7f269b

Browse files
committed
Add reorderstops overlay
1 parent 87e6f1a commit a7f269b

File tree

3 files changed

+195
-4
lines changed

3 files changed

+195
-4
lines changed

changelog.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ Template for new versions:
2828

2929
## New Tools
3030
- `sync-windmills`: synchronize or randomize movement of active windmills
31-
- `trackstop`: new overlay to allow changing track stop dump direction and friction and roller direction and speed after construction
31+
- `trackstop`: provides 3 new overlays:
32+
- trackstop: allow changing track stop dump direction and friction
33+
- rollers: allow changing roller direction and speed
34+
- reorderstops: reorder stops in hauling routes
3235

3336
## New Features
3437
- `gui/design`: show selected dimensions next to the mouse cursor when designating with vanilla tools, for example when painting a burrow or designating digging

docs/trackstop.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ trackstop
55
:summary: Add dynamic configuration options for track stops.
66
:tags: fort buildings interface
77

8-
This script provides 2 overlays that are managed by the `overlay` framework. The script does nothing when executed.
8+
This script provides 3 overlays that are managed by the `overlay` framework. The script does nothing when executed.
99
The trackstop overlay allows the player to change the friction and dump direction of a selected track stop after it has been constructed.
1010
The rollers overlay allows the player to change the roller direction and speed of a selected roller after it has been constructed.
11+
The reorderstops overlay allows the player to change the order of stops in a hauling route.

trackstop.lua

+189-2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ local DIRECTION_MAP = {
5252

5353
local DIRECTION_MAP_REVERSE = utils.invert(DIRECTION_MAP)
5454

55+
local function swapElements(tbl, index1, index2)
56+
tbl[index1], tbl[index2] = tbl[index2], tbl[index1]
57+
return tbl
58+
end
59+
60+
local function reset_guide_paths(conditions)
61+
for _i, condition in ipairs(conditions) do
62+
local gpath = condition.guide_path
63+
64+
if gpath then
65+
gpath.x:resize(0)
66+
gpath.y:resize(0)
67+
gpath.z:resize(0)
68+
end
69+
end
70+
end
71+
5572
TrackStopOverlay = defclass(TrackStopOverlay, overlay.OverlayWidget)
5673
TrackStopOverlay.ATTRS{
5774
default_pos={x=-73, y=29},
@@ -120,7 +137,11 @@ function TrackStopOverlay:setDumpDirection(direction)
120137
end
121138

122139
function TrackStopOverlay:render(dc)
123-
local building = dfhack.gui.getSelectedBuilding()
140+
local building = dfhack.gui.getSelectedBuilding(true)
141+
if not building then
142+
return
143+
end
144+
124145
local friction = building.friction
125146
local friction_cycle = self.subviews.friction
126147

@@ -201,7 +222,10 @@ function RollerOverlay:setSpeed(speed)
201222
end
202223

203224
function RollerOverlay:render(dc)
204-
local building = dfhack.gui.getSelectedBuilding()
225+
local building = dfhack.gui.getSelectedBuilding(true)
226+
if not building then
227+
return
228+
end
205229

206230
self.subviews.direction:setOption(DIRECTION_MAP_REVERSE[building.direction])
207231
self.subviews.speed:setOption(SPEED_MAP_REVERSE[building.speed])
@@ -236,7 +260,170 @@ function RollerOverlay:init()
236260
}
237261
end
238262

263+
selected_stop = selected_stop or nil
264+
265+
ReorderStopsWindow = defclass(ReorderStopsWindow, widgets.Window)
266+
ReorderStopsWindow.ATTRS {
267+
frame={t=4,l=60,w=45, h=28},
268+
frame_title='Reorder Stops',
269+
view_id='main',
270+
}
271+
272+
local SELECT_STOP_HINT = 'Select a stop to move'
273+
local SELECT_ANOTHER_STOP_HINT = 'Select another stop on the same route'
274+
275+
function ReorderStopsWindow:init()
276+
self:addviews{
277+
widgets.Label{
278+
frame={t=0,l=0},
279+
view_id='hint',
280+
text=SELECT_STOP_HINT,
281+
},
282+
widgets.List{
283+
view_id='routes',
284+
frame={t=1,l=1},
285+
choices={},
286+
on_select=function(index, item)
287+
if not item then return end
288+
if item.type == 'stop' then
289+
local item_pos = df.global.plotinfo.hauling.routes[item.route_index].stops[item.stop_index].pos
290+
df.global.game.main_interface.recenter_indicator_m.x = item_pos.x
291+
df.global.game.main_interface.recenter_indicator_m.y = item_pos.y
292+
df.global.game.main_interface.recenter_indicator_m.z = item_pos.z
293+
dfhack.gui.revealInDwarfmodeMap(item_pos, true)
294+
end
295+
end,
296+
on_submit=function(index, item)
297+
if selected_stop then
298+
local hauling = df.global.plotinfo.hauling
299+
local routes = hauling.routes
300+
local view_stops = hauling.view_stops
301+
local route = routes[item.route_index]
302+
303+
-- rearrange stops
304+
if item.type == 'stop' then
305+
local stop_index = item.stop_index
306+
307+
-- don't allow moving stops to a different route
308+
if selected_stop.route_index ~= item.route_index then
309+
return
310+
end
311+
312+
swapElements(route.stops, stop_index, selected_stop.stop_index)
313+
swapElements(view_stops, selected_stop.list_position, index - 1)
314+
315+
-- loop over each stop in the route, make the ids sequental and reset guide paths
316+
-- TODO: what else does this break?
317+
for i, stop in ipairs(route.stops) do
318+
stop.id = i + 1
319+
reset_guide_paths(stop.conditions)
320+
end
321+
322+
selected_stop = nil
323+
end
324+
else
325+
if item.stop_index then
326+
selected_stop = item
327+
end
328+
end
329+
330+
self:updateList()
331+
end,
332+
},
333+
}
334+
335+
self:updateList()
336+
end
337+
338+
function ReorderStopsWindow:updateList()
339+
local routes = df.global.plotinfo.hauling.routes
340+
local choices = {}
341+
local list_position = 0
342+
343+
if selected_stop then
344+
self.subviews.hint:setText(SELECT_ANOTHER_STOP_HINT)
345+
else
346+
self.subviews.hint:setText(SELECT_STOP_HINT)
347+
end
348+
349+
for i, route in ipairs(routes) do
350+
local stops = route.stops
351+
local route_name = route.name
352+
353+
if route_name == '' then
354+
route_name = 'Route ' .. route.id
355+
end
356+
357+
table.insert(choices, {text=route_name, type='route', route_index=i, list_position=list_position})
358+
list_position = list_position + 1
359+
360+
for j, stop in ipairs(stops) do
361+
local stop_name = stop.name
362+
363+
if stop_name == '' then
364+
stop_name = 'Stop ' .. stop.id
365+
end
366+
367+
if selected_stop and selected_stop.list_position == list_position then
368+
stop_name = '=> ' .. stop_name
369+
end
370+
371+
stop_name = ' ' .. stop_name
372+
373+
table.insert(choices, {text=stop_name, type='stop', stop_index=j, route_index=i, list_position=list_position})
374+
list_position = list_position + 1
375+
end
376+
end
377+
378+
self.subviews.routes:setChoices(choices)
379+
end
380+
381+
ReorderStopsModal = defclass(ReorderStopsModal, gui.ZScreenModal)
382+
383+
ReorderStopsModal.ATTRS = {
384+
focus_path = 'ReorderStops',
385+
}
386+
387+
function ReorderStopsModal:init()
388+
self:addviews{ReorderStopsWindow{}}
389+
end
390+
391+
function ReorderStopsModal:onDismiss()
392+
reorder_stops_modal = nil
393+
selected_stop = nil
394+
df.global.game.main_interface.recenter_indicator_m.x = -30000
395+
df.global.game.main_interface.recenter_indicator_m.y = -30000
396+
df.global.game.main_interface.recenter_indicator_m.z = -30000
397+
end
398+
399+
ReorderStopsOverlay = defclass(ReorderStopsOverlay, overlay.OverlayWidget)
400+
ReorderStopsOverlay.ATTRS{
401+
default_pos={x=6, y=6},
402+
default_enabled=true,
403+
viewscreens='dwarfmode/Hauling',
404+
frame={w=30, h=1},
405+
frame_background=gui.CLEAR_PEN,
406+
}
407+
408+
function ReorderStopsOverlay:init()
409+
self:addviews{
410+
widgets.BannerPanel{
411+
subviews = {
412+
widgets.HotkeyLabel{
413+
frame={t=0, l=1, r=1},
414+
label='DFHack reorder stops',
415+
key='CUSTOM_CTRL_E',
416+
on_activate=function()
417+
reorder_stops_modal = reorder_stops_modal and reorder_stops_modal:raise() or ReorderStopsModal{}:show()
418+
end,
419+
},
420+
},
421+
},
422+
}
423+
end
424+
239425
OVERLAY_WIDGETS = {
240426
trackstop=TrackStopOverlay,
241427
rollers=RollerOverlay,
428+
reorderstops=ReorderStopsOverlay,
242429
}

0 commit comments

Comments
 (0)