flickerstreak@7
|
1 -- The ReAction.ActionType mixin defines 'regular' action button functionality
|
flickerstreak@7
|
2 -- and is an implementation of the ReAction.IActionType interface.
|
flickerstreak@7
|
3 --
|
flickerstreak@7
|
4 -- The Mixin assumes that it is being mixed in with a ReAction-derived class
|
flickerstreak@7
|
5 -- which implements the ReAction.IDisplay and ReAction.ActionType.IDisplay interfaces.
|
flickerstreak@7
|
6 --
|
flickerstreak@7
|
7 -- This mixin using the following configuration properties:
|
flickerstreak@7
|
8 --
|
flickerstreak@7
|
9 -- self.config = {
|
flickerstreak@7
|
10 -- selfcast = nil / "alt" / "ctrl" / "shift" / "auto" / "none". nil (default) = use Interface Options menu setting.
|
flickerstreak@7
|
11 -- }
|
flickerstreak@7
|
12 --
|
flickerstreak@7
|
13
|
flickerstreak@7
|
14 local AceOO = AceLibrary("AceOO-2.0")
|
flickerstreak@7
|
15
|
flickerstreak@7
|
16 ReAction.ActionType = AceOO.Mixin {
|
flickerstreak@7
|
17 -- ReAction.IActionType interface
|
flickerstreak@7
|
18 "SetID",
|
flickerstreak@7
|
19 "GetID",
|
flickerstreak@7
|
20 "SetupAction",
|
flickerstreak@7
|
21 "UpdateAction",
|
flickerstreak@7
|
22 "PickupAction",
|
flickerstreak@7
|
23 "PlaceAction",
|
flickerstreak@7
|
24 "IsActionEmpty",
|
flickerstreak@7
|
25 "UpdateTooltip",
|
flickerstreak@7
|
26
|
flickerstreak@7
|
27 -- event handlers
|
flickerstreak@7
|
28 "ACTIONBAR_SLOT_CHANGED",
|
flickerstreak@7
|
29 "PLAYER_ENTERING_WORLD",
|
flickerstreak@7
|
30 "ACTIONBAR_SHOWGRID",
|
flickerstreak@7
|
31 "ACTIONBAR_HIDEGRID",
|
flickerstreak@7
|
32 "ACTIONBAR_UPDATE_STATE",
|
flickerstreak@7
|
33 "ACTIONBAR_UPDATE_USABLE",
|
flickerstreak@7
|
34 "UNIT_INVENTORY_CHANGED",
|
flickerstreak@7
|
35 "CRAFT_SHOW",
|
flickerstreak@7
|
36 "PLAYER_ENTER_COMBAT",
|
flickerstreak@7
|
37 "PLAYER_LEAVE_COMBAT",
|
flickerstreak@7
|
38 "START_AUTOREPEAT_SPELL",
|
flickerstreak@7
|
39 "STOP_AUTOREPEAT_SPELL",
|
flickerstreak@7
|
40 "OnAttributeChanged",
|
flickerstreak@7
|
41
|
flickerstreak@7
|
42 -- internal functions
|
flickerstreak@7
|
43 "UpdateSelfcast",
|
flickerstreak@7
|
44 "UpdateIcon",
|
flickerstreak@7
|
45 "UpdateInUse",
|
flickerstreak@7
|
46 "UpdateCount",
|
flickerstreak@7
|
47 "UpdateMacroText",
|
flickerstreak@7
|
48 "UpdateUsable",
|
flickerstreak@7
|
49 "UpdateCooldown",
|
flickerstreak@7
|
50 "UpdateActionEvents",
|
flickerstreak@7
|
51 }
|
flickerstreak@7
|
52
|
flickerstreak@7
|
53 local RAAT = ReAction.ActionType
|
flickerstreak@7
|
54
|
flickerstreak@7
|
55
|
flickerstreak@7
|
56 -- Required display elements
|
flickerstreak@7
|
57 RAAT.IDisplay = AceOO.Interface {
|
flickerstreak@7
|
58 DisplayUsable = "function", -- DisplayUsable(bool, notEnoughMana, outOfRange), change display to indicate action usable/unusable
|
flickerstreak@7
|
59 DisplayEquipped = "function", -- DisplayEquipped(bool)
|
flickerstreak@7
|
60 DisplayAutoRepeat = "function", -- DisplayAutoRepeat(bool)
|
flickerstreak@7
|
61 DisplayInUse = "function", -- DisplayInUse(bool)
|
flickerstreak@7
|
62 DisplayIcon = "function", -- DisplayIcon(texture), nil means empty slot
|
flickerstreak@7
|
63 DisplayName = "function", -- DisplayName(text), macro names
|
flickerstreak@7
|
64 DisplayCount = "function", -- DisplayCount(number), stack count
|
flickerstreak@7
|
65 DisplayCooldown = "function", -- DisplayCooldown(start,duration,enable)
|
flickerstreak@7
|
66 }
|
flickerstreak@7
|
67
|
flickerstreak@7
|
68
|
flickerstreak@7
|
69 ---------------------------------------
|
flickerstreak@7
|
70 -- ReAction.IActionType interface implementation
|
flickerstreak@7
|
71 ---------------------------------------
|
flickerstreak@7
|
72 function RAAT:SetID( id, page )
|
flickerstreak@7
|
73 local f = self:GetActionFrame()
|
flickerstreak@7
|
74 id = tonumber(id) -- force data integrity
|
flickerstreak@7
|
75 page = tonumber(page)
|
flickerstreak@7
|
76 local button = page and ("-page"..page) or "*"
|
flickerstreak@7
|
77 if id then
|
flickerstreak@7
|
78 f:SetAttribute("*action"..button, id)
|
flickerstreak@7
|
79 if page and page > 1 and self.config.selfcast == "right-click" then
|
flickerstreak@7
|
80 -- disable right-click auto-cast
|
flickerstreak@7
|
81 self.config.selfcast = nil
|
flickerstreak@7
|
82 end
|
flickerstreak@7
|
83 elseif page then
|
flickerstreak@7
|
84 f:SetAttribute("*action"..button, ATTRIBUTE_NOOP)
|
flickerstreak@7
|
85 end
|
flickerstreak@7
|
86 self:UpdateSelfcast()
|
flickerstreak@7
|
87 end
|
flickerstreak@7
|
88
|
flickerstreak@7
|
89 function RAAT:GetID(page)
|
flickerstreak@7
|
90 local f = self:GetActionFrame()
|
flickerstreak@7
|
91 page = tonumber(page)
|
flickerstreak@7
|
92 local button = page and ("page"..page) or SecureStateChild_GetEffectiveButton(f)
|
flickerstreak@7
|
93 return SecureButton_GetModifiedAttribute(f, "action", button)
|
flickerstreak@7
|
94 end
|
flickerstreak@7
|
95
|
flickerstreak@7
|
96 function RAAT:SetupAction()
|
flickerstreak@7
|
97 local f = self:GetActionFrame()
|
flickerstreak@7
|
98 f:SetAttribute("useparent*", true)
|
flickerstreak@7
|
99 f:SetAttribute("type", "action")
|
flickerstreak@7
|
100
|
flickerstreak@7
|
101 self:RegisterEvent("PLAYER_ENTERING_WORLD")
|
flickerstreak@7
|
102 self:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
flickerstreak@7
|
103 self:RegisterEvent("ACTIONBAR_SHOWGRID")
|
flickerstreak@7
|
104 self:RegisterEvent("ACTIONBAR_HIDEGRID")
|
flickerstreak@7
|
105
|
flickerstreak@7
|
106 self:UpdateSelfcast()
|
flickerstreak@7
|
107
|
flickerstreak@7
|
108 f:SetScript("OnAttributeChanged", function(frame,name,value) self:OnAttributeChanged(name,value) end)
|
flickerstreak@7
|
109 end
|
flickerstreak@7
|
110
|
flickerstreak@7
|
111 function RAAT:UpdateAction()
|
flickerstreak@7
|
112 self:UpdateIcon()
|
flickerstreak@7
|
113 self:UpdateCount()
|
flickerstreak@7
|
114 self:UpdateMacroText()
|
flickerstreak@7
|
115 self:UpdateUsable()
|
flickerstreak@7
|
116 self:UpdateCooldown()
|
flickerstreak@7
|
117 self:UpdateActionEvents()
|
flickerstreak@7
|
118 end
|
flickerstreak@7
|
119
|
flickerstreak@7
|
120 function RAAT:PickupAction()
|
flickerstreak@7
|
121 PickupAction(self:GetID())
|
flickerstreak@7
|
122 self:UpdateAction()
|
flickerstreak@7
|
123 end
|
flickerstreak@7
|
124
|
flickerstreak@7
|
125 function RAAT:PlaceAction()
|
flickerstreak@7
|
126 if not InCombatLockdown() then
|
flickerstreak@7
|
127 -- PlaceAction() is protected. However the user can still drop a new action
|
flickerstreak@7
|
128 -- onto a button while in combat by dragging then clicking, because
|
flickerstreak@7
|
129 -- UseAction() appears to swap the cursor action for the current action if
|
flickerstreak@7
|
130 -- an action is on the cursor.
|
flickerstreak@7
|
131 PlaceAction(self:GetID())
|
flickerstreak@8
|
132 -- the ACTIONBAR_SLOT_CHANGED event will handle the update
|
flickerstreak@7
|
133 end
|
flickerstreak@7
|
134 end
|
flickerstreak@7
|
135
|
flickerstreak@7
|
136 function RAAT:IsActionEmpty()
|
flickerstreak@7
|
137 local slot = self:GetID()
|
flickerstreak@7
|
138 return not(slot and HasAction(slot))
|
flickerstreak@7
|
139 end
|
flickerstreak@7
|
140
|
flickerstreak@7
|
141 function RAAT:UpdateTooltip()
|
flickerstreak@7
|
142 local action = self:GetID()
|
flickerstreak@7
|
143 if action and GameTooltip:IsOwned(self:GetActionFrame()) then
|
flickerstreak@7
|
144 GameTooltip:SetAction(action)
|
flickerstreak@7
|
145 end
|
flickerstreak@7
|
146 end
|
flickerstreak@7
|
147
|
flickerstreak@7
|
148
|
flickerstreak@7
|
149
|
flickerstreak@7
|
150
|
flickerstreak@7
|
151
|
flickerstreak@7
|
152
|
flickerstreak@7
|
153
|
flickerstreak@7
|
154 -----------------------------
|
flickerstreak@7
|
155 -- Event Handling
|
flickerstreak@7
|
156 -----------------------------
|
flickerstreak@7
|
157 function RAAT:ACTIONBAR_SLOT_CHANGED(slot)
|
flickerstreak@7
|
158 if slot == 0 or slot == self:GetID() then
|
flickerstreak@7
|
159 self:UpdateAction()
|
flickerstreak@7
|
160 end
|
flickerstreak@7
|
161 end
|
flickerstreak@7
|
162
|
flickerstreak@7
|
163 function RAAT:PLAYER_ENTERING_WORLD()
|
flickerstreak@7
|
164 self:UpdateAction()
|
flickerstreak@7
|
165 end
|
flickerstreak@7
|
166
|
flickerstreak@7
|
167 function RAAT:ACTIONBAR_SHOWGRID()
|
flickerstreak@7
|
168 self:TempShow(true)
|
flickerstreak@7
|
169 end
|
flickerstreak@7
|
170
|
flickerstreak@7
|
171 function RAAT:ACTIONBAR_HIDEGRID()
|
flickerstreak@7
|
172 self:TempShow(false)
|
flickerstreak@7
|
173 end
|
flickerstreak@7
|
174
|
flickerstreak@7
|
175 function RAAT:ACTIONBAR_UPDATE_STATE()
|
flickerstreak@7
|
176 self:UpdateInUse()
|
flickerstreak@7
|
177 end
|
flickerstreak@7
|
178
|
flickerstreak@7
|
179 function RAAT:ACTIONBAR_UPDATE_USABLE()
|
flickerstreak@7
|
180 self:UpdateUsable()
|
flickerstreak@7
|
181 self:UpdateCooldown()
|
flickerstreak@7
|
182 end
|
flickerstreak@7
|
183
|
flickerstreak@7
|
184 function RAAT:UNIT_INVENTORY_CHANGED(unit)
|
flickerstreak@7
|
185 if unit == "player" then
|
flickerstreak@7
|
186 self:UpdateIcon()
|
flickerstreak@7
|
187 self:UpdateCount()
|
flickerstreak@7
|
188 end
|
flickerstreak@7
|
189 end
|
flickerstreak@7
|
190
|
flickerstreak@7
|
191 function RAAT:CRAFT_SHOW()
|
flickerstreak@7
|
192 self:UpdateInUse()
|
flickerstreak@7
|
193 end
|
flickerstreak@7
|
194
|
flickerstreak@7
|
195 function RAAT:PLAYER_ENTER_COMBAT()
|
flickerstreak@7
|
196 if IsAttackAction(self:GetID()) then
|
flickerstreak@7
|
197 self:DisplayAutoRepeat(true)
|
flickerstreak@7
|
198 self:UpdateInUse()
|
flickerstreak@7
|
199 end
|
flickerstreak@7
|
200 end
|
flickerstreak@7
|
201
|
flickerstreak@7
|
202 function RAAT:PLAYER_LEAVE_COMBAT()
|
flickerstreak@7
|
203 if IsAttackAction(self:GetID()) then
|
flickerstreak@7
|
204 self:DisplayAutoRepeat(false)
|
flickerstreak@7
|
205 self:UpdateInUse()
|
flickerstreak@7
|
206 end
|
flickerstreak@7
|
207 end
|
flickerstreak@7
|
208
|
flickerstreak@7
|
209 function RAAT:START_AUTOREPEAT_SPELL()
|
flickerstreak@7
|
210 if IsAutoRepeatAction(self:GetID()) then
|
flickerstreak@7
|
211 self:DisplayAutoRepeat(true)
|
flickerstreak@7
|
212 end
|
flickerstreak@7
|
213 end
|
flickerstreak@7
|
214
|
flickerstreak@7
|
215 function RAAT:STOP_AUTOREPEAT_SPELL()
|
flickerstreak@7
|
216 if not IsAttackAction(self:GetID()) then
|
flickerstreak@7
|
217 self:DisplayAutoRepeat(false)
|
flickerstreak@7
|
218 self:UpdateInUse()
|
flickerstreak@7
|
219 end
|
flickerstreak@7
|
220 end
|
flickerstreak@7
|
221
|
flickerstreak@7
|
222 function RAAT:OnAttributeChanged(name, value)
|
flickerstreak@7
|
223 if self.config then
|
flickerstreak@7
|
224 self:UpdateAction()
|
flickerstreak@7
|
225 self:UpdateDisplay()
|
flickerstreak@7
|
226 end
|
flickerstreak@7
|
227 end
|
flickerstreak@7
|
228
|
flickerstreak@7
|
229
|
flickerstreak@7
|
230
|
flickerstreak@7
|
231
|
flickerstreak@7
|
232 ---------------------------------
|
flickerstreak@7
|
233 -- Internal methods
|
flickerstreak@7
|
234 ---------------------------------
|
flickerstreak@7
|
235 function RAAT:UpdateSelfcast()
|
flickerstreak@7
|
236 if not InCombatLockdown() then
|
flickerstreak@7
|
237 local c = self.config and self.config.selfcast
|
flickerstreak@7
|
238 local f = self:GetActionFrame()
|
flickerstreak@7
|
239
|
flickerstreak@7
|
240 f:SetAttribute("alt-unit*",nil)
|
flickerstreak@7
|
241 f:SetAttribute("ctrl-unit*",nil)
|
flickerstreak@7
|
242 f:SetAttribute("shift-unit*",nil)
|
flickerstreak@7
|
243 f:SetAttribute("*unit2",nil)
|
flickerstreak@7
|
244 if c == nil then
|
flickerstreak@7
|
245 f:SetAttribute("unit",nil)
|
flickerstreak@7
|
246 f:SetAttribute("checkselfcast", true)
|
flickerstreak@7
|
247 else
|
flickerstreak@7
|
248 f:SetAttribute("checkselfcast",ATTRIBUTE_NOOP)
|
flickerstreak@7
|
249 f:SetAttribute("unit","none") -- "none" gives you the glowing cast hand if no target selected, or casts on target if target selected
|
flickerstreak@7
|
250 if c == "none" then
|
flickerstreak@7
|
251 -- nothing to do
|
flickerstreak@7
|
252 elseif c == "alt" or c == "ctrl" or c == "shift" then
|
flickerstreak@7
|
253 f:SetAttribute(c.."-unit*","player")
|
flickerstreak@7
|
254 elseif c == "right-click" then
|
flickerstreak@7
|
255 if f:GetAttribute("*action-page2") then
|
flickerstreak@7
|
256 -- right-click modifier not supported with multipage
|
flickerstreak@7
|
257 self.config.selfcast = nil
|
flickerstreak@7
|
258 f:SetAttribute("unit",nil)
|
flickerstreak@7
|
259 f:SetAttribute("checkselfcast",true)
|
flickerstreak@7
|
260 else
|
flickerstreak@7
|
261 f:SetAttribute("*unit2","player")
|
flickerstreak@7
|
262 end
|
flickerstreak@7
|
263 end
|
flickerstreak@7
|
264 end
|
flickerstreak@7
|
265 end
|
flickerstreak@7
|
266 end
|
flickerstreak@7
|
267
|
flickerstreak@7
|
268 function RAAT:UpdateIcon()
|
flickerstreak@7
|
269 local action = self:GetID()
|
flickerstreak@7
|
270 local texture = action and GetActionTexture(action)
|
flickerstreak@7
|
271
|
flickerstreak@7
|
272 self:DisplayIcon(action and texture)
|
flickerstreak@7
|
273 self:DisplayEquipped(action and IsEquippedAction(action))
|
flickerstreak@7
|
274 self:UpdateInUse()
|
flickerstreak@7
|
275 self:UpdateUsable()
|
flickerstreak@7
|
276 self:UpdateCooldown()
|
flickerstreak@7
|
277 end
|
flickerstreak@7
|
278
|
flickerstreak@7
|
279 function RAAT:UpdateInUse()
|
flickerstreak@7
|
280 local action = self:GetID()
|
flickerstreak@7
|
281 if action and (IsCurrentAction(action) or IsAutoRepeatAction(action)) then
|
flickerstreak@7
|
282 self:DisplayInUse(true)
|
flickerstreak@7
|
283 else
|
flickerstreak@7
|
284 self:DisplayInUse(false)
|
flickerstreak@7
|
285 end
|
flickerstreak@7
|
286 end
|
flickerstreak@7
|
287
|
flickerstreak@7
|
288 function RAAT:UpdateCount()
|
flickerstreak@7
|
289 local action = self:GetID()
|
flickerstreak@7
|
290 if action and (IsConsumableAction(action) or IsStackableAction(action)) then
|
flickerstreak@7
|
291 self:DisplayCount(GetActionCount(action)) -- will display a 0 if none remaining
|
flickerstreak@7
|
292 else
|
flickerstreak@7
|
293 self:DisplayCount(nil) -- will display nothing
|
flickerstreak@7
|
294 end
|
flickerstreak@7
|
295 end
|
flickerstreak@7
|
296
|
flickerstreak@7
|
297 function RAAT:UpdateMacroText()
|
flickerstreak@7
|
298 local action = self:GetID()
|
flickerstreak@7
|
299 self:DisplayName(action and GetActionText(action))
|
flickerstreak@7
|
300 end
|
flickerstreak@7
|
301
|
flickerstreak@7
|
302 function RAAT:UpdateUsable()
|
flickerstreak@7
|
303 local action = self:GetID()
|
flickerstreak@7
|
304 if action and HasAction(action) then
|
flickerstreak@7
|
305 local isUsable, notEnoughMana = IsUsableAction(action)
|
flickerstreak@7
|
306 local outOfRange = IsActionInRange(action) == 0
|
flickerstreak@7
|
307 self:DisplayUsable(isUsable and not outOfRange, notEnoughMana, outOfRange)
|
flickerstreak@7
|
308 else
|
flickerstreak@7
|
309 self:DisplayUsable(false, false, false)
|
flickerstreak@7
|
310 end
|
flickerstreak@7
|
311 end
|
flickerstreak@7
|
312
|
flickerstreak@7
|
313 function RAAT:UpdateCooldown()
|
flickerstreak@7
|
314 local action = self:GetID()
|
flickerstreak@7
|
315 if action then
|
flickerstreak@7
|
316 self:DisplayCooldown(GetActionCooldown(action))
|
flickerstreak@7
|
317 end
|
flickerstreak@7
|
318 end
|
flickerstreak@7
|
319
|
flickerstreak@7
|
320 function RAAT:UpdateActionEvents()
|
flickerstreak@7
|
321 local action = self:GetID()
|
flickerstreak@7
|
322 if action and HasAction(action) then
|
flickerstreak@7
|
323 if not self.actionEventsRegistered then
|
flickerstreak@7
|
324 self:RegisterEvent("ACTIONBAR_UPDATE_STATE")
|
flickerstreak@7
|
325 self:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@7
|
326 self:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@7
|
327 self:RegisterEvent("UPDATE_INVENTORY_ALERTS", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@7
|
328 self:RegisterEvent("PLAYER_AURAS_CHANGED", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@7
|
329 self:RegisterEvent("PLAYER_TARGET_CHANGED", "ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@7
|
330 self:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
flickerstreak@7
|
331 self:RegisterEvent("CRAFT_SHOW")
|
flickerstreak@7
|
332 self:RegisterEvent("CRAFT_CLOSE", "CRAFT_SHOW")
|
flickerstreak@7
|
333 self:RegisterEvent("TRADE_SKILL_SHOW", "CRAFT_SHOW")
|
flickerstreak@7
|
334 self:RegisterEvent("TRADE_SKILL_CLOSE", "CRAFT_SHOW")
|
flickerstreak@7
|
335 self:RegisterEvent("PLAYER_ENTER_COMBAT")
|
flickerstreak@7
|
336 self:RegisterEvent("PLAYER_LEAVE_COMBAT")
|
flickerstreak@7
|
337 self:RegisterEvent("START_AUTOREPEAT_SPELL")
|
flickerstreak@7
|
338 self:RegisterEvent("STOP_AUTOREPEAT_SPELL")
|
flickerstreak@7
|
339 self.actionEventsRegistered = true
|
flickerstreak@7
|
340 end
|
flickerstreak@7
|
341 elseif self.actionEventsRegistered then
|
flickerstreak@7
|
342 self:UnregisterEvent("ACTIONBAR_UPDATE_STATE")
|
flickerstreak@7
|
343 self:UnregisterEvent("ACTIONBAR_UPDATE_USABLE")
|
flickerstreak@7
|
344 self:UnregisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
|
flickerstreak@7
|
345 self:UnregisterEvent("UPDATE_INVENTORY_ALERTS")
|
flickerstreak@7
|
346 self:UnregisterEvent("PLAYER_AURAS_CHANGED")
|
flickerstreak@7
|
347 self:UnregisterEvent("PLAYER_TARGET_CHANGED")
|
flickerstreak@7
|
348 self:UnregisterEvent("UNIT_INVENTORY_CHANGED")
|
flickerstreak@7
|
349 self:UnregisterEvent("CRAFT_SHOW")
|
flickerstreak@7
|
350 self:UnregisterEvent("CRAFT_CLOSE")
|
flickerstreak@7
|
351 self:UnregisterEvent("TRADE_SKILL_SHOW")
|
flickerstreak@7
|
352 self:UnregisterEvent("TRADE_SKILL_CLOSE")
|
flickerstreak@7
|
353 self:UnregisterEvent("PLAYER_ENTER_COMBAT")
|
flickerstreak@7
|
354 self:UnregisterEvent("PLAYER_LEAVE_COMBAT")
|
flickerstreak@7
|
355 self:UnregisterEvent("START_AUTOREPEAT_SPELL")
|
flickerstreak@7
|
356 self:UnregisterEvent("STOP_AUTOREPEAT_SPELL")
|
flickerstreak@7
|
357 self.actionEventsRegistered = false
|
flickerstreak@7
|
358 end
|
flickerstreak@7
|
359 end
|
flickerstreak@7
|
360
|