-
Notifications
You must be signed in to change notification settings - Fork 200
/
Copy pathmechanisms.lua
146 lines (119 loc) · 3.99 KB
/
mechanisms.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
-- Shows mechanisms linked to the current building.
--[====[
gui/mechanisms
==============
To use, bind to a key (the example config uses :kbd:`Ctrl`:kbd:`M`)
and activate in :kbd:`q` mode.
.. image:: /docs/images/mechanisms.png
Lists mechanisms connected to the building, and their links. Navigating
the list centers the view on the relevant linked buildings.
To exit, press :kbd:`Esc` or :kbd:`Enter`; :kbd:`Esc` recenters on
the original building, while :kbd:`Enter` leaves focus on the current
one. :kbd:`Shift`:kbd:`Enter` has an effect equivalent to pressing
:kbd:`Enter`, and then re-entering the mechanisms UI.
]====]
local utils = require 'utils'
local gui = require 'gui'
local guidm = require 'gui.dwarfmode'
function listMechanismLinks(building)
local lst = {}
local function push(item, mode)
if item then
lst[#lst+1] = {
obj = item, mode = mode,
name = utils.getBuildingName(item)
}
end
end
push(building, 'self')
if not df.building_actual:is_instance(building) then
return lst
end
local item, tref, tgt
for _,v in ipairs(building.contained_items) do
item = v.item
if df.item_trappartsst:is_instance(item) then
tref = dfhack.items.getGeneralRef(item, df.general_ref_type.BUILDING_TRIGGER)
if tref then
push(tref:getBuilding(), 'trigger')
end
tref = dfhack.items.getGeneralRef(item, df.general_ref_type.BUILDING_TRIGGERTARGET)
if tref then
push(tref:getBuilding(), 'target')
end
end
end
return lst
end
MechanismList = defclass(MechanismList, guidm.MenuOverlay)
MechanismList.focus_path = 'mechanisms'
function MechanismList:init(info)
self:assign{
links = {}, selected = 1
}
self:fillList(info.building)
end
function MechanismList:fillList(building)
local links = listMechanismLinks(building)
self.old_viewport = self:getViewport()
self.old_cursor = guidm.getCursorPos()
if #links <= 1 then
links[1].mode = 'none'
end
self.links = links
self.selected = 1
end
local colors = {
self = COLOR_CYAN, none = COLOR_CYAN,
trigger = COLOR_GREEN, target = COLOR_GREEN
}
local icons = {
self = 128, none = 63, trigger = 27, target = 26
}
function MechanismList:onRenderBody(dc)
dc:clear()
dc:seek(1,1):string("Mechanism Links", COLOR_WHITE):newline()
for i,v in ipairs(self.links) do
local pen = { fg=colors[v.mode], bold = (i == self.selected) }
dc:newline(1):pen(pen):char(icons[v.mode])
dc:advance(1):string(v.name)
end
local nlinks = #self.links
if nlinks <= 1 then
dc:newline():newline(1):string("This building has no links", COLOR_LIGHTRED)
end
dc:newline():newline(1):pen(COLOR_WHITE)
dc:key('LEAVESCREEN'):string(": Back, ")
dc:key('SELECT'):string(": Switch")
end
function MechanismList:changeSelected(delta)
if #self.links <= 1 then return end
self.selected = 1 + (self.selected + delta - 1) % #self.links
self:selectBuilding(self.links[self.selected].obj)
end
function MechanismList:onInput(keys)
if keys.SECONDSCROLL_UP then
self:changeSelected(-1)
elseif keys.SECONDSCROLL_DOWN then
self:changeSelected(1)
elseif keys.LEAVESCREEN then
self:dismiss()
if self.selected ~= 1 then
self:selectBuilding(self.links[1].obj, self.old_cursor, self.old_view)
end
elseif keys.SELECT_ALL then
if self.selected > 1 then
self:fillList(self.links[self.selected].obj)
end
elseif keys.SELECT then
self:dismiss()
elseif self:simulateViewScroll(keys) then
return
end
end
if not string.match(dfhack.gui.getCurFocus(), '^dwarfmode/QueryBuilding/Some') then
qerror("This script requires the main dwarfmode view in 'q' mode")
end
local list = MechanismList{ building = df.global.world.selected_building }
list:show()
list:changeSelected(1)