@@ -52,6 +52,23 @@ local DIRECTION_MAP = {
52
52
53
53
local DIRECTION_MAP_REVERSE = utils .invert (DIRECTION_MAP )
54
54
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
+
55
72
TrackStopOverlay = defclass (TrackStopOverlay , overlay .OverlayWidget )
56
73
TrackStopOverlay .ATTRS {
57
74
default_pos = {x =- 73 , y = 29 },
@@ -120,7 +137,11 @@ function TrackStopOverlay:setDumpDirection(direction)
120
137
end
121
138
122
139
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
+
124
145
local friction = building .friction
125
146
local friction_cycle = self .subviews .friction
126
147
@@ -201,7 +222,10 @@ function RollerOverlay:setSpeed(speed)
201
222
end
202
223
203
224
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
205
229
206
230
self .subviews .direction :setOption (DIRECTION_MAP_REVERSE [building .direction ])
207
231
self .subviews .speed :setOption (SPEED_MAP_REVERSE [building .speed ])
@@ -236,7 +260,170 @@ function RollerOverlay:init()
236
260
}
237
261
end
238
262
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
+
239
425
OVERLAY_WIDGETS = {
240
426
trackstop = TrackStopOverlay ,
241
427
rollers = RollerOverlay ,
428
+ reorderstops = ReorderStopsOverlay ,
242
429
}
0 commit comments