-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathButtonDef.lua
More file actions
executable file
·669 lines (591 loc) · 26.5 KB
/
ButtonDef.lua
File metadata and controls
executable file
·669 lines (591 loc) · 26.5 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
-------------------------------------------------------------------------------
-- Module Loading
-------------------------------------------------------------------------------
---@type Ufo
local ADDON_NAME, Ufo = ...
Ufo.Wormhole() -- Lua voodoo magic that replaces the current Global namespace with the Ufo object
-------------------------------------------------------------------------------
-- ButtonType
-- identifies a button as a Spell, Item, Pet, etc. as used by most(some?) APIs including GetCursorInfo.
-- and provides methods for unified, consistent behavior in the face of Bliz's inconsistent API
-- For now, this class is tightly coupled with the ButtonDef class -- most methods here require its arg to be a ButtonDef
-------------------------------------------------------------------------------
---@class ButtonType -- IntelliJ-EmmyLua annotation
ButtonType = {
SPELL = "spell",
MOUNT = "mount",
ITEM = "item",
TOY = "toy",
PET = "battlepet",
MACRO = "macro",
PSPELL = "petaction",
BROKENP = "brokenPetCommand",
SNAFU = "companion",
SUMMON_RANDOM_FAVORITE_MOUNT = "summonmount"
}
-------------------------------------------------------------------------------
-- BlizApiFieldDef
-- maps my types into Bliz types.
-------------------------------------------------------------------------------
---@class BlizApiFieldDef -- IntelliJ-EmmyLua annotation
---@field pickerUpper function the Bliz API that can load the mouse pointer
---@field typeForBliz ButtonType the corresponding SecureActionButtonTemplate keyname
---@field key string which field should be used as the ID
-- the key is a ButtonType as returned by GetCursorInfo while the user is dragging it around on the mouse.
BlizApiFieldDef = {
[ButtonType.SPELL] = { pickerUpper = C_Spell.PickupSpell, typeForBliz = ButtonType.SPELL, },
[ButtonType.MOUNT] = { pickerUpper = C_Spell.PickupSpell, typeForBliz = ButtonType.SPELL, },
[ButtonType.ITEM ] = { pickerUpper = C_Item.PickupItem, typeForBliz = ButtonType.ITEM, },
[ButtonType.TOY ] = { pickerUpper = C_Item.PickupItem, typeForBliz = ButtonType.TOY, key = "itemId" },
[ButtonType.MACRO] = { pickerUpper = PickupMacro, typeForBliz = ButtonType.MACRO --[[, key = "name"]] },
[ButtonType.SNAFU] = { pickerUpper = nil, typeForBliz = ButtonType.SPELL, key = "mountId" },
[ButtonType.PET ] = { pickerUpper = C_PetJournal.PickupPet, typeForBliz = ButtonType.PET, key = "petGuid" },
[ButtonType.PSPELL]= { pickerUpper = PickupPetSpell, typeForBliz = ButtonType.SPELL, key="petSpellId" },
[ButtonType.BROKENP]= { pickerUpper = function(id) print("pickerupper not defined for pet action", id) end, typeForBliz=ButtonType.MACRO, key="name" }, -- for attack, assist, stopattack, etc.
-- special cases
[ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT] = {
pickerUpper = function() C_MountJournal.Pickup(0) end,
key = "id",
typeForBliz = ButtonType.MOUNT,
icon = 413588,
name = MOUNT_JOURNAL_SUMMON_RANDOM_FAVORITE_MOUNT, -- I18N global defined by Bliz
macroText = "/run C_AddOns.LoadAddOn('Blizzard_Collections'); C_MountJournal.SummonByID(0)"
},
}
-------------------------------------------------------------------------------
-- Broken Professions
-- In a shocking turn of events, Bliz broke something! IKR?!
-- In the professions tab of the spell book, there are buttons to open its trade skill panel / cookbook.
-- The Bliz API GetCursorInfo() provides a spell ID when you drag those buttons. Sometimes this spell ID is bullshit.
-- Here is a map of IDs suitable for C_TradeSkillUI.OpenTradeSkill()
-- The keys are localized strings, so, this will only work for supported languages.
-------------------------------------------------------------------------------
BrokenProfessions = {
[INSCRIPTION] = 773, -- Bliz provides this localized "Inscription"
[L10N.JEWELCRAFTING] = 755, -- but not these! Blizzard is consistent only in their inconsistency! Blizconsistency!!!
[L10N.BLACKSMITHING] = 164,
[L10N.LEATHERWORKING] = 165,
[L10N.ENGINEERING] = 202,
}
-------------------------------------------------------------------------------
-- ButtonDef
-- data for a single button, its spell/pet/macro/item/etc. and methods for manipulating that data
-------------------------------------------------------------------------------
---@class ButtonDef : UfoMixIn
---@field type ButtonType
---@field name string
---@field spellId number
---@field itemId number
---@field mountId number
---@field petGuid string
---@field petSpellId number
---@field brokenPetCommandId number custom field to solve Blizzard's broken API
---@field macroId number
---@field macroOwner string
ButtonDef = {
ufoType = "ButtonDef"
}
UfoMixIn:mixInto(ButtonDef)
-------------------------------------------------------------------------------
-- Utility Functions
-------------------------------------------------------------------------------
function getPetNameAndIcon(petGuid)
--local speciesID, customName, level, xp, maxXp, displayID, isFavorite, name, icon, petType, creatureID, sourceText, description, isWild, canBattle, tradable, unique, obtainable = C_PetJournal.GetPetInfoByPetID(petGuid)
local _, _, _, _, _, _, _, name, icon = C_PetJournal.GetPetInfoByPetID(petGuid)
return name, icon
end
function isMacroGlobal(macroId)
return macroId <= MAX_GLOBAL_MACRO_ID
end
-------------------------------------------------------------------------------
-- Methods
-------------------------------------------------------------------------------
-- coerce the incoming table into a ButtonDef instance
---@return ButtonDef
function ButtonDef:oneOfUs(self)
zebug.trace:print("self",self)
if self.ufoType == ButtonDef.ufoType then
-- it's already "one of us" so nothing needs to be done.
return
end
-- create a table to store stuff that we do NOT want persisted out to SAVED_VARIABLES
-- and attach methods to get and put that data
local privateData = { }
function privateData:setIdForBlizApi(id) privateData.idForBlizApis = id end
-- tie the privateData table to the ButtonDef class definition
setmetatable(privateData, { __index = ButtonDef })
-- tie the "self" instance to the privateData table (which in turn is tied to the class)
setmetatable(self, { __index = privateData })
end
---@return ButtonDef
---@param id number|string|nil (optional) a value possibly returned by some Bliz API
---@param type string|nil (optional) a value possibly returned by some Bliz API
function ButtonDef:new(id, type)
---@type ButtonDef
local self = {}
ButtonDef:oneOfUs(self)
self:setIdAndType(id, type)
self:installMyToString()
return self
end
function ButtonDef:setIdAndType(id, type)
if not (id and type) then
return
end
self.type = type
if type == ButtonType.SPELL then
self.spellId = id
elseif type == ButtonType.MOUNT then
local name, spellId = C_MountJournal.GetMountInfoByID(id)
self.spellId = spellId
self.mountId = id
elseif type == ButtonType.ITEM then
self.itemId = id
elseif type == ButtonType.TOY then
self.itemId = id
elseif type == ButtonType.MACRO then
self.macroId = id
elseif type == ButtonType.PET then
self.petGuid = id
elseif type == ButtonType.PSPELL then
if id < 10 then
self.type = ButtonType.BROKENP
local brokenPetCommandId, alsoCommand = PetShitShow:get(id)
self.brokenPetCommandId = brokenPetCommandId
self.brokenPetCommandId2 = alsoCommand
else
self.petSpellId = id
end
else
zebug.warn:owner(self):print("Sorry, I don't recognize this type of button:", type)
Ufo.unknownType = type or "UnKnOwN"
type = nil
self = nil
end
if self then
if type then
-- discovering the name requires knowing its type
self:getName()
end
end
return self
end
function ButtonDef:toString()
if not self.type then
return "<ButtonDef: EMPTY>"
else
return string.format("<ButtonDef: %s:%s>", nilStr(self.type), nilStr(self.name))
end
end
function ButtonDef:invalidateCache()
zebug.trace:line(75)
self.name = nil
self:setIdForBlizApi(nil)
end
function ButtonDef:whatsMyBlizApiIdField()
assert(self.type, "can't discern ID key without a type.")
local blizDef = BlizApiFieldDef[self.type]
if not blizDef then return nil end
local type = blizDef.typeForBliz
local idKey = blizDef.key or (type .."Id") -- spellId or itemId or petGuid or etcId
return idKey
end
function ButtonDef:redefine(id, name)
self:invalidateCache()
local idKey = self:whatsMyBlizApiIdField()
self[idKey] = id
self.name = name
end
-- A few different types of buttons share Bliz APIs.
-- For example, you get a mount's icon by calling C_Spell.GetSpellTexture(mountId)
-- This method remaps the various ID fields to match what Bliz API expects
---@return number
function ButtonDef:getIdForBlizApi()
if self.idForBlizApis then
return self.idForBlizApis
end
local idKey = self:whatsMyBlizApiIdField()
local happyBlizId = self[idKey]
zebug.trace:print("self.type",self.type, "idKey",idKey, "happyBlizId",happyBlizId)
self:setIdForBlizApi(happyBlizId) -- cache the result to save processing cycles on repeated calls
return happyBlizId
end
function ButtonDef:getTypeForBlizApi()
local blizApiFieldDef = BlizApiFieldDef[self.type]
return blizApiFieldDef.typeForBliz
end
function ButtonDef:isUsable()
local t = self.type
local id = self:getIdForBlizApi()
local isUsable, err
zebug.trace:owner(self):print("type",t, "spellId", self.spellId, "id",id)
if t == ButtonType.MOUNT then
local mountId = self.mountId
isUsable, err = C_MountJournal.GetMountUsabilityByID(mountId, false --[[checkIndoors]])
local name, spellID, icon, isActive, isUsable, sourceType, isFavorite, isFactionSpecific, faction, shouldHideOnChar, isCollected, mountID, isSteadyFlight = C_MountJournal.GetMountInfoByID(mountId)
--zebug.warn:owner(self):mTriangle():print("mountId",self.mountId, "isUsable",isUsable, "err", err)
--zebug.warn:owner(self):mCircle():print("name",name, "spellID",spellID, "isUsable",isUsable, "isFactionSpecific",isFactionSpecific, "faction",faction, "shouldHideOnChar",shouldHideOnChar, "mountID",mountID)
isUsable = not shouldHideOnChar
return isUsable, (err or "Bliz API provided no explanation why not.")
elseif t == ButtonType.PET then
-- TODO: figure out how to find a mount
return true -- GetMountInfoByID(mountId)
elseif t == ButtonType.TOY then
-- TODO: solve faction specific bug
return PlayerHasToy(id) -- and C_ToyBox.IsToyUsable(id) -- nope, unreliable and overreaching
elseif t == ButtonType.SPELL then
--zebug.trace:print("IsSpellKnownOrOverridesKnown",IsSpellKnownOrOverridesKnown(id))
return IsSpellKnownOrOverridesKnown(id)
elseif t == ButtonType.PSPELL then
--zebug.warn:print("IsSpellKnownOrOverridesKnown PET",IsSpellKnownOrOverridesKnown(id, true))
return IsSpellKnownOrOverridesKnown(id, true)
elseif t == ButtonType.ITEM then
-- isUseable = C_PlayerInfo.CanUseItem(itemID)
local n = C_Item.GetItemCount(id)
zebug.info:owner(self):print("C_Item.GetItemCount",n)
isUsable = n > 0
err = isUsable and "" or L10N.THIS_TOON_HAS_NONE
return isUsable, err
elseif t == ButtonType.MACRO then
zebug.trace:owner(self):print("macroId",self.macroId, "isMacroGlobal",isMacroGlobal(self.macroId), "owner",self.macroOwner, "me",getIdForCurrentToon())
isUsable = isMacroGlobal(self.macroId) or getIdForCurrentToon() == self.macroOwner
err = isUsable or (L10N.NOT_MACRO_OWNER .. " " .. (self.macroOwner or L10N.UNKNOWN))
if not isUsable then
zebug.info:owner(self):print("macroId",self.macroId, "isUsable",isUsable, "err", err)
end
return isUsable, err
elseif t == ButtonType.BROKENP then
return PetShitShow:canHazPet()
elseif t == ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT then
return true
end
end
--[[
local ICON_CACHE = {}
function ButtonDef:cacheIcon(type, id, icon)
if not ICON_CACHE[type] then
ICON_CACHE[type] = {}
end
ICON_CACHE[type][id] = icon
end
function getIconFromCache(type, id)
if not ICON_CACHE[type] then return nil end
return ICON_CACHE[type][id]
end
]]
function ButtonDef:getIcon()
local t = self.type
local id = self:getIdForBlizApi()
local icon -- = getIconFromCache(t, id)
-- if icon then return icon end
if t == ButtonType.SPELL or t == ButtonType.MOUNT or t == ButtonType.PSPELL then
icon = C_Spell.GetSpellTexture(id)
elseif t == ButtonType.ITEM or t == ButtonType.TOY then
icon = C_Item.GetItemIconByID(id)
elseif t == ButtonType.MACRO then
if self:isUsable() then
local _, texture, _ = GetMacroInfo(id)
icon = texture
else
icon = self.fallbackIcon or DEFAULT_ICON_FULL
end
elseif t == ButtonType.PET then
local _, x = getPetNameAndIcon(id)
icon = x
elseif t == ButtonType.BROKENP then
icon = BrokenPetCommand[self.brokenPetCommandId].icon
elseif t == ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT then
icon = BlizApiFieldDef[t].icon
id = t
end
--self:cacheIcon(t, id, icon)
return icon
end
function ButtonDef:getName()
if self.name then
return self.name
end
local t = self.type
local id = self:getIdForBlizApi()
if t == ButtonType.SPELL or t == ButtonType.MOUNT or t == ButtonType.PSPELL then
zebug.trace:owner(self):print("type",t, "id",id, "mountId", self.mountId)
--[[
local foo
local isOk, err = pcall( function() foo = C_Spell.GetSpellInfo(id or self.mountId) end )
if not isOk then
zebug.error:owner(self):print("C_Spell.GetSpellInfo() failed for id",id, "and maybe mountId",self.mountId, "with ERROR",err)
end
]]
local foo = C_Spell.GetSpellInfo(id or self.mountId) -- changed to not barf for the "summon random favorite mount" button aka type == "summonmount"
self.name = foo and foo.name or "UnKnOwN!"
zebug.trace:owner(self):print("name",self.name)
elseif t == ButtonType.ITEM or t == ButtonType.TOY then
self.name = C_Item.GetItemInfo(id)
elseif t == ButtonType.TOY then
self.name = C_Item.GetItemInfo(id)
elseif t == ButtonType.MACRO then
self.name = GetMacroInfo(self.macroId)
elseif t == ButtonType.PET then
self.name = getPetNameAndIcon(id)
elseif t == ButtonType.BROKENP then
--zebug.warn:dumpy("btndef",self)
self.name = BrokenPetCommand[self.brokenPetCommandId].name
elseif t == ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT then
self.name = BlizApiFieldDef[t].name
else
zebug.info:print("Unknown type:",t)
end
self.name = stripEol(self.name)
return self.name
end
function trim1(s)
if not s then return nil end
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function stripEol(s)
if not s then return nil end
return s:gsub("\n", " ")
end
function ButtonDef:getToolTipSetter()
local type = self.type
local id = self:getIdForBlizApi()
zebug.trace:line(20, "type",type, "id",id)
local tooltipSetter
if type == ButtonType.SPELL or type == ButtonType.MOUNT or type == ButtonType.PSPELL then
tooltipSetter = GameTooltip.SetSpellByID
elseif type == ButtonType.ITEM then
tooltipSetter = GameTooltip.SetItemByID
elseif type == ButtonType.TOY then
tooltipSetter = GameTooltip.SetToyByItemID
elseif type == ButtonType.PET then
tooltipSetter = GameTooltip.SetCompanionPet
elseif type == ButtonType.MACRO then
-- START FUNC
tooltipSetter = function(zelf, Cache1macroId)
local upToDateId = self:getIdForBlizApi()
local macroId = self.macroId
local i_name, _, i_body = GetMacroInfo(macroId)
local n_name, _, n_body = GetMacroInfo(self.name)
if not macroId then macroId = "NiL" end
zebug.info:owner(self):print("MACRO! macroId",macroId, "cached1",Cache1macroId,"cahced2",upToDateId, "btnDef name",self.name, "i_name",i_name, "n_name",n_name, "i_body", trim1(i_body), "n_body",trim1(n_body))
zebug.trace:dumpy("self",self)
local text
if self:isUsable() then
text = "Macro: ".. macroId .." " .. (i_name or "UnKnOwNmAcRo")
else
text = "Toon Macro for " .. self.macroOwner
end
return zelf:SetText(text)
end
-- END FUNC
elseif type == ButtonType.BROKENP then
-- START FUNC
tooltipSetter = function(zelf, _)
return zelf:SetText(self.name)
end
-- END FUNC
elseif type == ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT then
-- START FUNC
tooltipSetter = function(zelf, _)
return zelf:SetText(self.name)
end
-- END FUNC
end
if tooltipSetter and id then
return function()
-- because Bliz doesn't understand the concept of immutable IDs
-- and Bliz allows macro IDs to shift will-fucking-nilly
-- we must always refresh the ID
local upToDateId = self:getIdForBlizApi()
return tooltipSetter(GameTooltip, upToDateId)
end
end
return nil
end
local ttData
function ButtonDef:registerToolTipRecorder()
TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, function(tooltip, data)
if tooltip == GameTooltip then
ttData = data
end
end)
end
function ButtonDef:readToolTipForToyType()
ttData = nil -- will be re-populated by the registerToolTipRecorder() event handler above
-- trigger the tooltip
local tooltipSetter = self:getToolTipSetter()
local foo = tooltipSetter and tooltipSetter()
if not ttData then
return false
end
-- scan the text in the tooltip
for i, ttLine in ipairs(ttData.lines) do
zebug.trace:print("ttLine.leftText",ttLine.leftText)
if ttLine.leftText == L10N.TOY then
zebug.trace:out(30,")","TOY !!!")
return true
end
end
return false
end
-- TODO: fixx bug - doesn't understand Bliz flyouts such as Dragon Riding
-- TODO: consolidate / integrate with BlizActionBarButton:get()
---@return ButtonDef
function ButtonDef:getFromCursor(event, silenceWarnings)
local type, c1, c2, c3 = GetCursorInfo() -- c1 is usually the ID; c2 is sometimes a tooltip;
zebug.info:event(event):owner(self):print("type",type, "c1",c1, "c2",c2, "c3",c3)
local shhh = silenceWarnings and zebug.info or zebug.warn
if not type then
Ufo.pickedUpBtn = nil
shhh:event(event):owner(self):print("Empty cursor is empty")
return nil
end
if UfoProxy:isButtonOnCursor(type, c1, c2, c3) then
shhh:event(event):owner(Ufo.pickedUpBtn):print("Ufo.pickedUpBtn")
return Ufo.pickedUpBtn
end
local btnDef = ButtonDef:new()
btnDef.type = type
if type == ButtonType.SPELL then
btnDef.spellId = c3
elseif type == ButtonType.SNAFU then
-- this is an abnormal result containing a useless ID which isn't accepted by any API. Not helpful.
-- It's caused when the mouse pointer is loaded via Bliz's API PickupSpell(withTheSpellIdOfSomeMount)
-- This is a workaround to Bliz's API and retrieves a usable ID from my secret stash created when the user grabbed the mount.
if Ufo.pickedUpBtn then
btnDef = Ufo.pickedUpBtn
else
shhh:event(event):owner(self):print("Sorry, the Blizzard API provided bad data for this mount.")
end
elseif type == ButtonType.MOUNT then
local mountId, mountIndex = c1, c2
local name, spellId = C_MountJournal.GetMountInfoByID(mountId)
btnDef.spellId = spellId
btnDef.mountId = mountId
-- the Bliz API treats the SUMMON_RANDOM_FAVORITE_MOUNT as index 0
if mountIndex == 0 then
btnDef.type = ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT
btnDef.id = ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT
end
elseif type == ButtonType.ITEM then
btnDef.itemId = c1
local isToy = btnDef:readToolTipForToyType()
if isToy then
btnDef.type = ButtonType.TOY
end
elseif type == ButtonType.MACRO then
btnDef.macroId = c1
if not isMacroGlobal(c1) then
btnDef.macroOwner = (Ufo.pickedUpBtn and Ufo.pickedUpBtn.macroOwner) or getIdForCurrentToon()
btnDef.fallbackIcon = btnDef:getIcon()
end
elseif type == ButtonType.PET then
btnDef.petGuid = c1
elseif type == ButtonType.PSPELL then
if c1 < 10 then
--zebug.error:print("BROKENP !!! ",GetCursorInfo() )
btnDef.type = ButtonType.BROKENP
local brokenPetCommandId, alsoCommand = PetShitShow:get(c1)
btnDef.brokenPetCommandId = brokenPetCommandId
btnDef.brokenPetCommandId2 = alsoCommand
--zebug.error:dumpy("BROKENP btnDef",btnDef)
else
btnDef.petSpellId = c1
end
else
shhh:event(event):owner(self):print("Sorry, I don't recognize this type of button:", type)
Ufo.unknownType = type or "UnKnOwN"
type = nil
btnDef = nil
end
if btnDef then
if type then
-- discovering the name requires knowing its type
btnDef:getName()
end
if Ufo.pickedUpBtn then
-- TODO: should this be done as part of receiveDrop instead?
btnDef.noRnd = Ufo.pickedUpBtn.noRnd
end
end
--Ufo.pickedUpBtn = nil -- we can't clear this here because "getFromCursor" doesn't necessarily mean "clearCursor" and we would still need this data
return btnDef
end
function ButtonDef:pickupToCursor(event)
local type = self.type
local id = self:getIdForBlizApi()
local cursor, isOk, err
Ufo.pickedUpBtn = self
zebug.trace:event(event):owner(self):print("actionType", self.type, "name", self.name, "spellId", self.spellId, "itemId", self.itemId, "mountId", self.mountId)
if self:canThisToonPickup() then
local pickup = BlizApiFieldDef[type].pickerUpper
isOk, err = pcall(function() pickup(id) end)
else
cursor = UfoProxy:pickupButtonDefOntoCursor(self, event)
isOk = cursor and true or false
err = isOk and "A-OK" or "couldn't transform myself into a UfoProxy"
end
if isOk then
zebug.info:event(event):owner(self):print("grabbed id", id)
else
shhh:event(event):owner(self):print("pickupToCursor failed! ERROR is",err)
end
return isOk
end
function ButtonDef:canThisToonPickup()
local canPickup = self:isUsable() or ButtonType.ITEM == self.type
return canPickup
end
---@return ButtonType typeOfAction - what kind of action is performed by the btn
---@return string typeOfActionButDumber - usually, same as above but with a little "_" attached to it - for the SecureActionButtonTemplate:SetAttribute(key, val)
---@return string actualAction for the SecureActionButtonTemplate:SetAttribute(key, val) - some macro text, script, or an item/spell/etc's name, eg "Healing Potion" or "Frostbolt"
function ButtonDef:asSecureClickHandlerAttributes(event)
-- Check special (as in "short bus" special) cases for special needs
if ButtonType.PET == self.type then
-- COMPANION PET
-- this fails with "invalid attribute name"
--local snippet = "C_PetJournal.SummonPetByGUID(" .. QUOTE .. self.petGuid .. QUOTE ..")"
--return "UFO_customscript", "_UFO_customscript", snippet
-- summon the pet via a macro
-- TODO: fix bug where this fails in combat - perhaps control:CallMethod(keyName, ...) ?
local petMacro = "/run C_PetJournal.SummonPetByGUID(" .. QUOTE .. self.petGuid .. QUOTE ..")"
return ButtonType.MACRO, "macrotext", petMacro
elseif ButtonType.SPELL == self.type then
-- PROFESSIONS
--local altId = BrokenProfessions[self.name]
local professionSnafuId = ProfessionShitShow:get(self.name)
--zebug.error:event(event):owner(self):print("name",self.name, "id",self.spellId, "altId",altId, "professionSnafuId", professionSnafuId)
if professionSnafuId then
local profMacro = sprintf("/run C_TradeSkillUI.OpenTradeSkill(%d)", professionSnafuId)
zebug.trace:event(event):owner(self):print("name",self.name, "professionSnafuId", professionSnafuId, "profMacro",profMacro)
return ButtonType.MACRO, "macrotext", profMacro
end
-- if the prof name was NOT found in the ProfessionShitShow mapping, then,
-- it was something like "Herbalism Journal" and not "Herbalism"
-- if so, then, the "fall-through" block below will cast it as type "spell" and that works for any "journal"
elseif ButtonType.BROKENP == self.type then
local brokenPetCommand = BrokenPetCommand[self.brokenPetCommandId]
if brokenPetCommand.macro then
local bpc = BrokenPetCommand[self.brokenPetCommandId]
zebug.trace:event(event):owner(self):print("self.brokenPetCommandId",self.brokenPetCommandId, "bpc.macro",bpc.macro)
--zebug.warn:dumpy("BrokenPetCommand bpc",bpc)
return ButtonType.MACRO, "macrotext", bpc.macro
elseif brokenPetCommand.scripty then
local scripty = BrokenPetCommand[self.brokenPetCommandId].scripty
local type = "SCRIPT_FOR_" .. self.brokenPetCommandId
return type, "_"..type, scripty
end
local macroText = BrokenPetCommand[self.brokenPetCommandId]
return ButtonType.MACRO, "macrotext", macroText
elseif ButtonType.ITEM == self.type then
-- because using items by name implies rank 1 and never rank 2 or 3 we must use by the item's ID
return ButtonType.ITEM, ButtonType.ITEM, "item:".. self.itemId -- but not just itemId, it must be item:itemId - I hate you Bliz
elseif ButtonType.SUMMON_RANDOM_FAVORITE_MOUNT == self.type then
local macroText = BlizApiFieldDef[self.type].macroText
return ButtonType.MACRO, "macrotext", macroText
end
-- "fall-through" block - generic handler for standard cases
local blizType = self:getTypeForBlizApi() -- spell, mount, item, etc...
zebug.info:event(event):owner(self):print("blizType",blizType)
return blizType, blizType, self.name -- "standard" types can be cast/summon/use by name
end