Mercurial > wow > skeletonkey
comparison KeyButton.lua @ 70:131d9190db6b
Curseforge migration
| author | Nenue |
|---|---|
| date | Wed, 28 Dec 2016 16:31:15 -0500 |
| parents | |
| children | ca3118127e5e |
comparison
equal
deleted
inserted
replaced
| 69:b14d0611c8d9 | 70:131d9190db6b |
|---|---|
| 1 -- SkeletonKey | |
| 2 -- KeyButton.lua | |
| 3 -- Created: 7/28/2016 11:26 PM | |
| 4 -- %file-revision% | |
| 5 -- Deals with display and manipulation of binding slots | |
| 6 | |
| 7 local _, kb = ... | |
| 8 local print = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('SkeletonKey', ...) end or function() end | |
| 9 local cprint = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('Cfg', ...) end or function() end | |
| 10 local L = kb.L | |
| 11 local type, tonumber, tostring, tinsert, tremove, ipairs, pairs = type, tonumber, tostring, tinsert, tremove, ipairs, pairs | |
| 12 local _G, unpack, select, tostring = _G, unpack, select, tostring | |
| 13 local GetSpellBookItemName, GetSpellBookItemTexture, GetSpellBookItemInfo, GetPetActionInfo = GetSpellBookItemName, GetSpellBookItemTexture, GetSpellBookItemInfo, GetPetActionInfo | |
| 14 local GetSpellInfo, GetMacroInfo, GetItemInfo, GetItemIcon = GetSpellInfo, GetMacroInfo, GetItemInfo, GetItemIcon | |
| 15 local GetCursorInfo, ClearCursor, ResetCursor = GetCursorInfo, ClearCursor, ResetCursor | |
| 16 local GetSpellTexture, IsTalentSpell, GetMacroIndexByName, IsAltKeyDown, IsControlKeyDown, IsShiftKeyDown = GetSpellTexture, IsTalentSpell, GetMacroIndexByName, IsAltKeyDown, IsControlKeyDown,IsShiftKeyDown | |
| 17 local GetBindingKey, GetProfessionInfo = GetBindingKey, GetProfessionInfo | |
| 18 local GetMountInfoByID, GetPetInfoByPetID = C_MountJournal.GetMountInfoByID, C_PetJournal.GetPetInfoByPetID | |
| 19 local skb = SkeletonKeyButtonMixin | |
| 20 local CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_PETACTION, CURSOR_TEXTURE | |
| 21 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544 | |
| 22 local BORDER_UNASSIGNED = {0.6,0.6,0.6,1} | |
| 23 local BORDER_ASSIGNED = {1,1,1,1} | |
| 24 local BORDER_DYNAMIC = {1,1,0,1} | |
| 25 local BORDER_PENDING = {1,0.5,0,1 } | |
| 26 local BUTTON_HEADERS = { | |
| 27 ['spell'] = SPELLS, | |
| 28 ['macro'] = MACRO, | |
| 29 ['petaction'] = PET, | |
| 30 ['mount'] = MOUNT, | |
| 31 ['battlepet'] = BATTLEPET, | |
| 32 | |
| 33 | |
| 34 [5] = PROFESSIONS_FIRST_AID, | |
| 35 [7] = PROFESSIONS_COOKING, | |
| 36 [9] = PROFESSIONS_FISHING, | |
| 37 [10] = PROFESSIONS_ARCHAEOLOGY, | |
| 38 | |
| 39 } | |
| 40 | |
| 41 local PROFESSION_HEADERS = { | |
| 42 [1] = 'Profession 1', | |
| 43 [2] = 'Profession 2', | |
| 44 [3] = 10, | |
| 45 [4] = 7, | |
| 46 [5] = 9, | |
| 47 [6] = 5 | |
| 48 } | |
| 49 | |
| 50 | |
| 51 -- This is needed to identify a spells that aren't reflected by GetCursorInfo() | |
| 52 kb.OnPickupPetAction = function(slot, ...) | |
| 53 local isPickup = GetCursorInfo() | |
| 54 print(slot, ...) | |
| 55 if kb.PetCache.action[slot] then | |
| 56 if isPickup then | |
| 57 local key, _, texture = unpack(kb.PetCache.action[slot]) | |
| 58 local spellName = _G[key] or key | |
| 59 if spellName and kb.PetCache.spellslot[spellName] then | |
| 60 CURSOR_SPELLSLOT = kb.PetCache.spellslot[spellName][1] | |
| 61 CURSOR_BOOKTYPE = BOOKTYPE_PET | |
| 62 CURSOR_TEXTURE = _G[texture] or texture | |
| 63 end | |
| 64 else | |
| 65 CURSOR_SPELLSLOT = nil | |
| 66 CURSOR_BOOKTYPE = nil | |
| 67 CURSOR_TEXTURE = nil | |
| 68 end | |
| 69 print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION) | |
| 70 end | |
| 71 | |
| 72 local name, subtext, texture, isToken = GetPetActionInfo(slot) | |
| 73 if name then | |
| 74 kb.PetCache.action[slot] = {name, subtext, texture, isToken} | |
| 75 end | |
| 76 | |
| 77 | |
| 78 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE) | |
| 79 | |
| 80 end | |
| 81 | |
| 82 kb.OnPickupSpellBookItem = function(slot, bookType) | |
| 83 print('|cFFFF4400PickupSpellBookItem('.. tostring(slot).. ', '..tostring(bookType)..')') | |
| 84 CURSOR_SPELLSLOT = slot | |
| 85 CURSOR_BOOKTYPE = bookType | |
| 86 CURSOR_TEXTURE = GetSpellBookItemTexture(slot, bookType) | |
| 87 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE) | |
| 88 end | |
| 89 | |
| 90 kb.CreateHooks = function() | |
| 91 hooksecurefunc("PickupSpellBookItem", kb.OnPickupSpellBookItem) | |
| 92 hooksecurefunc("PickupPetAction", kb.OnPickupPetAction) | |
| 93 end | |
| 94 | |
| 95 | |
| 96 | |
| 97 function skb:OnLoad() | |
| 98 self:EnableKeyboard(false) | |
| 99 self:EnableMouse(true) | |
| 100 self:RegisterForDrag('LeftButton') | |
| 101 self:RegisterForClicks('AnyUp') | |
| 102 end | |
| 103 | |
| 104 function skb:OnEnter() | |
| 105 if not self.command then | |
| 106 return | |
| 107 end | |
| 108 if self.statusText then | |
| 109 SkeletonKey.statustext:SetText(self.statusText .. ': '..self.actionName) | |
| 110 SkeletonKey.bindingstext:SetText(self.bindingText) | |
| 111 end | |
| 112 | |
| 113 | |
| 114 if kb.db.hoverInput and kb.saveTarget ~= self then | |
| 115 self:GetParent():ActivateSlot(self) | |
| 116 SkeletonKey:Update() | |
| 117 end | |
| 118 end | |
| 119 | |
| 120 function skb:OnLeave() | |
| 121 if kb.db.hoverInput and kb.saveTarget == self then | |
| 122 self:GetParent():DeactivateSlot(self) | |
| 123 SkeletonKey:Update() | |
| 124 end | |
| 125 end | |
| 126 | |
| 127 function skb:OnUpdate() | |
| 128 end | |
| 129 function skb:OnClick(click) | |
| 130 print(self:GetName(), 'OnMouseDown', click) | |
| 131 local cursorType = GetCursorInfo() | |
| 132 if click == 'LeftButton' then | |
| 133 if cursorType then | |
| 134 self:DropToSlot() | |
| 135 else | |
| 136 if self.command and self.isAvailable then | |
| 137 if IsShiftKeyDown() then | |
| 138 kb.db.stickyMode = true | |
| 139 KeyBinderStickyMode:SetChecked(true) | |
| 140 end | |
| 141 self:GetParent():ActivateSlot(self) | |
| 142 end | |
| 143 end | |
| 144 elseif click == 'RightButton' then | |
| 145 self:ReleaseSlot() | |
| 146 else | |
| 147 kb.ProcessInput(strupper(click)) | |
| 148 end | |
| 149 SkeletonKey:Update() | |
| 150 end | |
| 151 | |
| 152 function skb:OnDragStart() | |
| 153 self:PickupSlot() | |
| 154 end | |
| 155 | |
| 156 function skb:OnReceiveDrag(...) | |
| 157 self:DropToSlot() | |
| 158 end | |
| 159 | |
| 160 function skb:DropToSlot () | |
| 161 print(self:GetName(),'|cFF0088FFreceived|r') | |
| 162 local actionType, actionID, subType, subData = GetCursorInfo() | |
| 163 print('GetCursorInfo', GetCursorInfo()) | |
| 164 if actionType then | |
| 165 | |
| 166 if actionType == 'flyout' then | |
| 167 ClearCursor() | |
| 168 ResetCursor() | |
| 169 return | |
| 170 end | |
| 171 | |
| 172 | |
| 173 local name, icon, _ | |
| 174 local pickupID, pickupBook | |
| 175 | |
| 176 if actionType == 'spell' then | |
| 177 actionID = subData | |
| 178 name, _, icon = GetSpellInfo(actionID) | |
| 179 | |
| 180 elseif actionType == 'macro' then | |
| 181 name, icon = GetMacroInfo(actionID) | |
| 182 elseif actionType == 'petaction' then | |
| 183 if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then | |
| 184 | |
| 185 local spellType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) | |
| 186 local spellName, spellText = GetSpellBookItemName(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) | |
| 187 if spellType == 'PETACTION' then | |
| 188 name = spellName | |
| 189 actionID = spellText | |
| 190 icon = CURSOR_TEXTURE | |
| 191 else | |
| 192 name, _, icon = GetSpellInfo(spellID) | |
| 193 actionID = spellID | |
| 194 end | |
| 195 | |
| 196 pickupID = CURSOR_SPELLSLOT | |
| 197 pickupBook = CURSOR_BOOKTYPE | |
| 198 else | |
| 199 | |
| 200 | |
| 201 end | |
| 202 | |
| 203 elseif actionType == 'mount' then | |
| 204 if subType == 0 then | |
| 205 name, _, icon = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL) | |
| 206 actionID = 0 | |
| 207 else | |
| 208 name, _, icon = GetMountInfoByID(actionID) | |
| 209 end | |
| 210 elseif actionType == 'item' then | |
| 211 name = GetItemInfo(actionID) | |
| 212 icon = GetItemIcon(actionID) | |
| 213 elseif actionType == 'battlepet' then | |
| 214 | |
| 215 local speciesID, customName, level, xp, maxXp, displayID, isFavorite, petName, petIcon, petType, creatureID = GetPetInfoByPetID(actionID) | |
| 216 name = customName or petName | |
| 217 icon = petIcon | |
| 218 | |
| 219 end | |
| 220 local macroName, macroText, command = kb.RegisterAction(actionType, actionID, name) | |
| 221 local slotInfo = { | |
| 222 command = command, | |
| 223 actionName = name, | |
| 224 iconPath = icon, | |
| 225 actionType = actionType, | |
| 226 actionID = actionID, | |
| 227 macroName = macroName, | |
| 228 macroText = macroText, | |
| 229 spellbookSlot = pickupID, | |
| 230 spellbookType = pickupBook, | |
| 231 assignedKeys = {GetBindingKey(command)} | |
| 232 } | |
| 233 | |
| 234 local isAssigned, isBound, assignedBy, boundBy = kb.IsCommandBound(self, command) | |
| 235 if isAssigned then | |
| 236 local popup = StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] | |
| 237 popup.slot = self | |
| 238 popup.text = "Currently assigned in |cFFFFFF00"..tostring(kb.configHeaders[assignedBy]).."|r. Are you sure?" | |
| 239 popup.oldProfile = assignedBy | |
| 240 popup.args = {slotInfo} | |
| 241 SkeletonKey:SetScript('OnMouseWheel', nil) -- disable scrolling | |
| 242 StaticPopup_Show('SKELETONKEY_CONFIRM_ASSIGN_SLOT') | |
| 243 else | |
| 244 kb.currentProfile.buttons[self:GetID()] = slotInfo | |
| 245 self:SetSlot(slotInfo) | |
| 246 self:UpdateSlot() | |
| 247 self.active = nil | |
| 248 ClearCursor() | |
| 249 ResetCursor() | |
| 250 end | |
| 251 end | |
| 252 end | |
| 253 | |
| 254 | |
| 255 do | |
| 256 local PickupAction = { | |
| 257 spell = _G.PickupSpell, | |
| 258 petaction = | |
| 259 function(...) | |
| 260 -- needs to be enclosed to acquire hooksecurefunc effects | |
| 261 _G.PickupSpellBookItem(...) | |
| 262 end, | |
| 263 macro = _G.PickupMacro, | |
| 264 item = _G.PickupItem, | |
| 265 mount = _G.C_MountJournal.Pickup | |
| 266 } | |
| 267 local GetPickupValue = { | |
| 268 spell = function(self) return select(7, GetSpellInfo(self.actionID)) end, | |
| 269 petaction = function(self) return self.pickupSlot, self.pickupBook end, | |
| 270 } | |
| 271 function skb:PickupSlot () | |
| 272 if not (self.command and self.isAvailable) then | |
| 273 return | |
| 274 end | |
| 275 print(self.actionType) | |
| 276 if self.actionType == 'spell' then | |
| 277 -- It can't be picked up if SpellInfo(name) returns void | |
| 278 local dummy = GetSpellInfo(self.actionName) | |
| 279 if not dummy then | |
| 280 return | |
| 281 end | |
| 282 end | |
| 283 if PickupAction[self.actionType] then | |
| 284 if GetPickupValue[self.actionType] then | |
| 285 PickupAction[self.actionType](GetPickupValue[self.actionType](self)) | |
| 286 else | |
| 287 PickupAction[self.actionType](self.actionID) | |
| 288 end | |
| 289 self:ReleaseSlot() | |
| 290 self:UpdateSlot() | |
| 291 end | |
| 292 end | |
| 293 end | |
| 294 | |
| 295 | |
| 296 | |
| 297 | |
| 298 --- Updates profile assignment and button contents | |
| 299 function skb:UpdateSlot (force) | |
| 300 local slot = self:GetID() | |
| 301 | |
| 302 if force then | |
| 303 if kb.currentProfile.buttons[slot] then | |
| 304 print('loading in', slot, kb.db.bindMode) | |
| 305 self:SetSlot(kb.currentProfile.buttons[slot]) | |
| 306 else | |
| 307 self:ReleaseSlot() | |
| 308 end | |
| 309 end | |
| 310 | |
| 311 local borderType = BORDER_UNASSIGNED | |
| 312 | |
| 313 if self.command then | |
| 314 | |
| 315 if not self.isAvailable then | |
| 316 borderType = BORDER_DYNAMIC | |
| 317 self.ignoreTexture:Show() | |
| 318 else | |
| 319 self.ignoreTexture:Hide() | |
| 320 | |
| 321 if self.pending then | |
| 322 borderType = BORDER_PENDING | |
| 323 elseif self.dynamicType then | |
| 324 borderType = BORDER_DYNAMIC | |
| 325 else | |
| 326 borderType = BORDER_ASSIGNED | |
| 327 end | |
| 328 end | |
| 329 | |
| 330 | |
| 331 if self.actionType == 'macro' then | |
| 332 self.macro:Show() | |
| 333 else | |
| 334 self.macro:Hide() | |
| 335 if self.actionType == 'spell' then | |
| 336 local dummy = GetSpellInfo(self.actionName) | |
| 337 if not dummy then | |
| 338 self.icon:SetDesaturated(true) | |
| 339 else | |
| 340 self.icon:SetDesaturated(false) | |
| 341 end | |
| 342 | |
| 343 end | |
| 344 end | |
| 345 | |
| 346 | |
| 347 if self.dynamicType == 'profession' then | |
| 348 if self.isAvailable then | |
| 349 | |
| 350 self.statusText = '|cFFFFFF00Profession|r' | |
| 351 self.bindingText = kb.BindingString(GetBindingKey(self.command)) | |
| 352 else | |
| 353 | |
| 354 self.statusText = '|cFFFF4400'..PROFESSION_HEADERS[self.dynamicIndex]..'|r' | |
| 355 self.actionName = '(#'..self.dynamicIndex..')' | |
| 356 self.bindingText ='?' | |
| 357 end | |
| 358 elseif self.dynamicType == 'talent' then | |
| 359 | |
| 360 self.statusText = '|cFF00FFFF'.. TALENT .. '|r' | |
| 361 if self.isAvailable then | |
| 362 self.bindingText = kb.BindingString(GetBindingKey(self.command)) | |
| 363 else | |
| 364 if kb.TalentBindings[self.actionID] then | |
| 365 print(self.actionID, #kb.TalentBindings[self.actionID]) | |
| 366 self.bindingText= kb.BindingString(unpack(kb.TalentBindings[self.actionID])) | |
| 367 end | |
| 368 | |
| 369 end | |
| 370 elseif self.dynamicType == 'petaction' then | |
| 371 self.bindingText = kb.BindingString(GetBindingKey(self.command)) | |
| 372 else | |
| 373 self.bindingText = kb.BindingString(GetBindingKey(self.command)) | |
| 374 end | |
| 375 | |
| 376 local locked, layer = kb.IsCommandBound(self) | |
| 377 if locked then | |
| 378 self.icon:SetAlpha(0.5) | |
| 379 else | |
| 380 self.icon:SetAlpha(1) | |
| 381 end | |
| 382 | |
| 383 | |
| 384 if self.actionType == 'spell' then | |
| 385 self.icon:SetTexture(GetSpellTexture(self.actionID)) | |
| 386 end | |
| 387 print('|cFF00BBFFUpdateSlot|r:', '['..slot..'] =', self.command, self.bindingText, self.dynamicType, self.isAvailable, self.actionID) | |
| 388 else | |
| 389 if kb.saveTarget == self then | |
| 390 kb.DeactivateSlot(self) | |
| 391 end | |
| 392 | |
| 393 end | |
| 394 | |
| 395 self.ignoreTexture:SetShown(self.command and not self.isAvailable) | |
| 396 | |
| 397 if not self.isAvailable then | |
| 398 self.bind:SetTextColor(0.7,0.7,0.7,1) | |
| 399 else | |
| 400 self.bind:SetTextColor(1,1,1,1) | |
| 401 end | |
| 402 | |
| 403 | |
| 404 if kb.saveTarget and kb.saveTarget ~= self then | |
| 405 self:SetAlpha(0.25) | |
| 406 else | |
| 407 | |
| 408 self:SetAlpha(1) | |
| 409 end | |
| 410 | |
| 411 --self.alert:SetShown(self.command and not self.isBound) | |
| 412 | |
| 413 self.icon:SetTexture(self.iconPath) | |
| 414 | |
| 415 self.border:SetColorTexture(unpack(borderType)) | |
| 416 self.header:SetText(self.statusText) | |
| 417 self.bind:SetText(self.bindingText) | |
| 418 self.details:SetText(self.actionName) | |
| 419 end | |
| 420 | |
| 421 --- Resets button command | |
| 422 function skb:ReleaseSlot () | |
| 423 local slot = self:GetID() | |
| 424 | |
| 425 | |
| 426 if kb.currentProfile.buttons[slot] then | |
| 427 kb.currentProfile.buttons[slot] = nil | |
| 428 end | |
| 429 if self.command then | |
| 430 kb.currentProfile.commands[self.command] = nil | |
| 431 end | |
| 432 local talentName = self.actionName | |
| 433 if self.actionType == 'macro' then | |
| 434 talentName = GetMacroSpell(self.actionID) | |
| 435 end | |
| 436 -- remove any matching talent data | |
| 437 if talentName and kb.currentProfile.talents[talentName] then | |
| 438 kb.currentProfile.talents[talentName] = nil | |
| 439 end | |
| 440 local droppedKeys = {} | |
| 441 | |
| 442 -- doing removal in second loop to avoid possible iterator shenanigans | |
| 443 for k,v in pairs(kb.currentProfile.bindings) do | |
| 444 if v == self.command then | |
| 445 tinsert(droppedKeys, k) | |
| 446 end | |
| 447 end | |
| 448 if #droppedKeys >=1 then | |
| 449 for i, k in ipairs(droppedKeys) do | |
| 450 kb.currentProfile.bindings[k] = nil | |
| 451 end | |
| 452 end | |
| 453 | |
| 454 self.isAvailable = nil | |
| 455 self.dynamicType = nil | |
| 456 self.bindingText = nil | |
| 457 self.statusText = nil | |
| 458 self.command = nil | |
| 459 self.iconPath = nil | |
| 460 self.actionType = nil | |
| 461 self.actionID = nil | |
| 462 self.actionName = nil | |
| 463 self.pickupSlot = nil | |
| 464 self.pickupBook = nil | |
| 465 self.macroName = nil | |
| 466 self.profile = nil | |
| 467 self.border:SetColorTexture(unpack(BORDER_UNASSIGNED)) | |
| 468 self:EnableKeyboard(false) | |
| 469 self:SetScript('OnKeyDown', nil) | |
| 470 self.bindingText = nil | |
| 471 self.icon:SetTexture(nil) | |
| 472 self.ignoreTexture:Hide() | |
| 473 | |
| 474 end | |
| 475 | |
| 476 local spells = {} | |
| 477 local SkeletonKey_GetGenericSpell = function(spellName, spellID, icon) | |
| 478 if not spells[spellID] then | |
| 479 spells[spellID] = {} | |
| 480 spells[spellID].actionType = 'spell' | |
| 481 spells[spellID].actionID = spellID | |
| 482 spells[spellID].actionName = spellName | |
| 483 spells[spellID].iconPath = icon | |
| 484 spells[spellID].statusText = '|cFFBBBBBBSpell|r' | |
| 485 spells[spellID].dynamicType = nil | |
| 486 end | |
| 487 return spells[spellID] | |
| 488 end | |
| 489 | |
| 490 local tempInfo = {} | |
| 491 -- tries to resolve spells from talent overrides/profession book/etc | |
| 492 local dynamicTypes = {['profession'] = 'ProfessionCache', ['talent'] = 'TalentCache', ['petaction'] = 'PetInfoCache'} | |
| 493 local SkeletonKey_GetSpellDetails = function(self) | |
| 494 | |
| 495 local spellName, spellID, command, icon = self.actionName, self.actionID, self.command, self.iconPath | |
| 496 | |
| 497 | |
| 498 cprint(' In:', spellName, spellID, command) | |
| 499 cprint(GetSpellInfo(spellName or spellID)) | |
| 500 local internalName, _, internalIcon, _, _, _, _ = GetSpellInfo(spellName or spellID) | |
| 501 local isAvailable = internalName and true | |
| 502 | |
| 503 if internalName and (internalName ~= spellName) then | |
| 504 -- it's a binding for the originating spell, leave it as is | |
| 505 cprint(' |cFFFF4400spell is an override(', internalName, '~=', spellName,') leave the name info alone') | |
| 506 self.statusText = '|cFFFFFF00Spell|r' | |
| 507 self.isAvailable = true | |
| 508 return | |
| 509 end | |
| 510 | |
| 511 -- let's us match spells replaced by talents | |
| 512 local info = kb.DynamicSpells[internalName or spellName] | |
| 513 if not info then | |
| 514 local dynamicType, dynamicIndex, dynamicSubIndex = command:match("(%a+)_(%S+)_(%S+)") | |
| 515 if kb.DynamicSpells[dynamicType] then | |
| 516 cprint('|cFFFF4400resolving dynamic type index:', internalName, spellName, command) | |
| 517 dynamicIndex = tonumber(dynamicIndex) | |
| 518 dynamicSubIndex = tonumber(dynamicSubIndex) | |
| 519 local cache = kb.DynamicSpells[dynamicType] | |
| 520 cprint('type:', dynamicType) | |
| 521 if dynamicIndex and cache[dynamicIndex] then | |
| 522 info = kb.DynamicSpells[dynamicType][dynamicIndex] | |
| 523 cprint('index:', dynamicIndex) | |
| 524 if dynamicSubIndex and info[dynamicSubIndex] then | |
| 525 info = info[dynamicSubIndex] | |
| 526 cprint('sub-index:', dynamicSubIndex) | |
| 527 end | |
| 528 isAvailable = true | |
| 529 end | |
| 530 end | |
| 531 if not info then | |
| 532 info = SkeletonKey_GetGenericSpell(spellName, spellID, internalIcon or icon) | |
| 533 end | |
| 534 end | |
| 535 info.isAvailable = isAvailable | |
| 536 | |
| 537 cprint('|cFF00FF88SpellDetails:|r', info.actionName, info.actionID, info.dynamicType) | |
| 538 for k,v in pairs(info) do | |
| 539 cprint(' ',k,v) | |
| 540 self[k] = v | |
| 541 end | |
| 542 | |
| 543 return info | |
| 544 end | |
| 545 | |
| 546 --- Assigns the slot via table copy; any manipulations from this point are temporary and | |
| 547 function skb:SetSlot(slotInfo) | |
| 548 print('slot info', self:GetID()) | |
| 549 | |
| 550 for k,v in pairs(slotInfo) do | |
| 551 print(' -', k, v) | |
| 552 self[k] = v | |
| 553 end | |
| 554 self.dynamicType = slotInfo.dynamicType | |
| 555 local command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook | |
| 556 = self.command, self.actionName, self.iconPath, self.actionType, self.actionID, self.macroName, self.macroText, self.spellbookSlot, self.spellbookType | |
| 557 | |
| 558 | |
| 559 local slot = self:GetID() | |
| 560 local isBound = false | |
| 561 print('|cFFFFFF00SetSlot|r:', self:GetID()) | |
| 562 if self.command then | |
| 563 | |
| 564 isBound = kb.IsCommandBound(self, self.command) | |
| 565 if actionType == 'spell' then | |
| 566 local info = SkeletonKey_GetSpellDetails(self) | |
| 567 name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook = self.actionName, self.iconPath, self.actionType, self.actionID, self.macroName, self.macroText, self.spellbookSlot, self.spellbookType | |
| 568 | |
| 569 elseif actionType == 'petaction' then | |
| 570 self.dynamicType = 'petaction' | |
| 571 local specialType, specialNum = command:match(actionType..'_([%a%s]+)_(%d)') | |
| 572 | |
| 573 if kb.PetCache.subtext[specialType] then | |
| 574 | |
| 575 local info = kb.PetCache.subtext[specialType][tonumber(specialNum)] | |
| 576 if info then | |
| 577 print('***dynamic pet skill', specialType, specialNum) | |
| 578 --[[ i, spellName, subText, spellID, texture, specialNum[subText ]] | |
| 579 | |
| 580 for k,v in pairs(info) do | |
| 581 self[k] = v | |
| 582 end | |
| 583 end | |
| 584 | |
| 585 end | |
| 586 self.statusText = 'Pet Action' | |
| 587 self.isAvailable = (kb.PetCache.spellslot[name]) | |
| 588 elseif actionType == 'macro' then | |
| 589 if actionID then | |
| 590 -- look for corruption | |
| 591 local nameByID, _, bodyByID = GetMacroInfo(actionID) | |
| 592 local nameByName, _, bodyByName = GetMacroInfo(name) | |
| 593 if (nameByID ~= name) or (bodyByID ~= macroText) then | |
| 594 local prevIndex = actionID | |
| 595 actionID = GetMacroIndexByName(name) | |
| 596 local firstName, _, firstBody = GetMacroInfo(actionID) | |
| 597 if (firstName ~= name) or (firstBody ~= macroText) then | |
| 598 -- go even deeper | |
| 599 for i = 1, GetNumMacros() do | |
| 600 local searchName, _ , searchBody = GetMacroInfo(i) | |
| 601 if (searchName == name) and (searchBody == macroText) then | |
| 602 -- complete match | |
| 603 actionID = i | |
| 604 break | |
| 605 elseif (searchName == name) or (searchBody == macroText) then | |
| 606 -- partial match, continue the search | |
| 607 actionID = i | |
| 608 end | |
| 609 end | |
| 610 end | |
| 611 kb:print('Macro index changed: |cFFFFFF00', actionType, '|r', name, '(was '..tostring(prevIndex)..', now '..tostring(actionID)..')') | |
| 612 end | |
| 613 else | |
| 614 actionID = GetMacroIndexByName(name) | |
| 615 end | |
| 616 self.statusText = 'Macro' | |
| 617 self.isAvailable = true | |
| 618 else | |
| 619 if not actionID then | |
| 620 actionID = command:match("^KeyBinderMacro:(.+)") | |
| 621 end | |
| 622 self.isAvailable = true | |
| 623 end | |
| 624 | |
| 625 if self.isAvailable then | |
| 626 local oldCommand = command | |
| 627 command = kb.LoadBinding(self) | |
| 628 if oldCommand ~= command then | |
| 629 print('|cFFFF4400fixing command string', actionType, actionID, name) | |
| 630 kb.currentProfile.bound[oldCommand] = nil | |
| 631 kb.currentProfile.bound[command] = slot | |
| 632 for k,v in pairs(kb.currentProfile.bindings) do | |
| 633 if v == oldCommand then | |
| 634 kb.currentProfile.bindings[k] = command | |
| 635 end | |
| 636 end | |
| 637 end | |
| 638 end | |
| 639 | |
| 640 | |
| 641 actionID = actionID or 0 | |
| 642 self:EnableKeyboard(true) | |
| 643 | |
| 644 -- this is done to keep legacy key-values from breaking algorithm assumptions | |
| 645 local slotInfo = { | |
| 646 command = command, | |
| 647 actionName = name, | |
| 648 iconPath = icon, | |
| 649 actionID = actionID, | |
| 650 actionType = actionType, | |
| 651 macroName = macroName, | |
| 652 macroText = macroText, | |
| 653 spellbookSlot = pickupSlot, | |
| 654 spellbookType = pickupBook, | |
| 655 assignedKeys = {GetBindingKey(command)} | |
| 656 } | |
| 657 kb.currentProfile.buttons[slot] = slotInfo | |
| 658 | |
| 659 -- Clean up conflicting entries for loaded button | |
| 660 local previous = kb.currentProfile.commands[command] | |
| 661 if previous ~= slot and kb.buttons[previous] then | |
| 662 kb.ReleaseSlot(kb.buttons[previous]) | |
| 663 end | |
| 664 | |
| 665 local binds = {GetBindingKey(command) } | |
| 666 if self.isAvailable and (#binds >= 1) then | |
| 667 local found | |
| 668 for i, key in ipairs(binds) do | |
| 669 if not tContains(self.assignedKeys, key) then | |
| 670 tinsert(self.assignedKeys, key) | |
| 671 kb.currentProfile.bindings[key] = command | |
| 672 kb.currentProfile.bound[command] = true | |
| 673 found = true | |
| 674 end | |
| 675 end | |
| 676 if found then | |
| 677 kb:print('Recovered key binding for', name) | |
| 678 end | |
| 679 end | |
| 680 | |
| 681 kb.currentProfile.commands[command] = slot | |
| 682 end | |
| 683 | |
| 684 | |
| 685 | |
| 686 self.isBound = isBound | |
| 687 self.pickupSlot = pickupSlot | |
| 688 self.pickupBook = pickupBook | |
| 689 self.macroText = macroText | |
| 690 self.macroName = macroName | |
| 691 self.actionType = actionType | |
| 692 self.actionID = actionID | |
| 693 self.actionName = name | |
| 694 self.command = command | |
| 695 self.iconPath = icon | |
| 696 self.profile = kb.db.bindMode | |
| 697 self:RegisterForDrag('LeftButton') | |
| 698 end | |
| 699 | |
| 700 kb.GetCommandAction = function(command) | |
| 701 for i, data in ipairs(kb.loadedProfiles) do | |
| 702 if data.commands[command] then | |
| 703 if data.buttons[data.commands[command]] then | |
| 704 local _, _, _, actionType, actionID = unpack(data.buttons[data.commands[command]]) | |
| 705 return actionType, actionID | |
| 706 end | |
| 707 end | |
| 708 end | |
| 709 end | |
| 710 |
