Mercurial > wow > skeletonkey
comparison SkeletonKey.lua @ 70:131d9190db6b
Curseforge migration
| author | Nenue |
|---|---|
| date | Wed, 28 Dec 2016 16:31:15 -0500 |
| parents | |
| children | c48913c5924c |
comparison
equal
deleted
inserted
replaced
| 69:b14d0611c8d9 | 70:131d9190db6b |
|---|---|
| 1 -------------------------------------------- | |
| 2 -- SkeletonKey | |
| 3 -- Krakyn-Mal'Ganis | |
| 4 -- @project-revision@ @project-hash@ | |
| 5 -- @file-revision@ @file-hash@ | |
| 6 -- Created: 6/16/2016 3:47 AM | |
| 7 -------------------------------------------- | |
| 8 -- Header script | |
| 9 | |
| 10 local addonName, kb = ... | |
| 11 local print = DEVIAN_WORKSPACE and function(...) print('SK',...) end or nop | |
| 12 SkeletonKeyMixin = { | |
| 13 scrollCache = {}, | |
| 14 tabButtons = {}, | |
| 15 keyButtons = {}, | |
| 16 panelButtons = {}, | |
| 17 numTabs = 0, | |
| 18 } | |
| 19 kb.L = setmetatable({}, { | |
| 20 __call = function(t, k, ...) return format(t[k] or k, ...) end | |
| 21 }) | |
| 22 local L = kb.L | |
| 23 | |
| 24 --- Caps Lock literals | |
| 25 L.UNSELECTED_TALENT_ASSIGNED = '|cFF00FF00%s|r added for |cFFFFFF00%s|r (%s).' | |
| 26 L.BINDING_ASSIGNED = '|cFF00FF00%s|r assigned to |cFFFFFF00%s|r (%s).' | |
| 27 L.BINDING_REMOVED = '|cFFFFFF00%s|r (|cFF00FFFF%s|r) unbound.' | |
| 28 L.BINDING_FAILED_PROTECTED = '|cFFFF4400Cannot use |r|cFF00FF00%s|r|cFFFF4400 (currently |cFFFFFF00%s|r|cFFFF4400). Uncheck "Safety" to ignore this restraint.|r' | |
| 29 | |
| 30 | |
| 31 local BINDING_TYPE_SPECIALIZATION = 3 | |
| 32 local BINDING_TYPE_CHARACTER = 2 | |
| 33 local BINDING_TYPE_GLOBAL = 1 | |
| 34 kb.configTitle = { | |
| 35 [BINDING_TYPE_GLOBAL] = L('Global Binds'), | |
| 36 [BINDING_TYPE_CHARACTER] = L('%%s'), | |
| 37 [BINDING_TYPE_SPECIALIZATION] = L('%%s') | |
| 38 } | |
| 39 kb.configDescription = { | |
| 40 [BINDING_TYPE_GLOBAL] = L('The bindings are applied globally.'), | |
| 41 [BINDING_TYPE_CHARACTER] = L('Applied when you log onto this character.'), | |
| 42 [BINDING_TYPE_SPECIALIZATION] = L('Applied when you select this specialization.'), | |
| 43 } | |
| 44 | |
| 45 | |
| 46 kb.ChangedBindings = {} | |
| 47 kb.SystemBindings = {} | |
| 48 kb.ActionTypes = {} | |
| 49 kb.TalentBindings = {} | |
| 50 kb.PetCache = { | |
| 51 spell = {}, | |
| 52 spellslot = {}, | |
| 53 action = {}, | |
| 54 special = {}, | |
| 55 subtext = {} | |
| 56 } | |
| 57 kb.DynamicSpells = { | |
| 58 profession = {}, | |
| 59 petaction = {}, | |
| 60 talent = {}, | |
| 61 } | |
| 62 kb.TalentCache = {} | |
| 63 kb.ProfessionCache = {} | |
| 64 kb.pendingCalls = {} | |
| 65 kb.pendingAttributes = {} | |
| 66 | |
| 67 kb.configHeaders = {} | |
| 68 kb.loadedProfiles = {} | |
| 69 kb.orderedProfiles = {} | |
| 70 kb.buttons = {} | |
| 71 kb.macros = {} | |
| 72 kb.bindings = {} | |
| 73 kb.petFrames = {} -- pet data is slightly delayed, their buttons are indexed here so they can be refreshed | |
| 74 kb.talentFrames = {} | |
| 75 kb.professionFrames = {} | |
| 76 | |
| 77 -- these are sent to plugin | |
| 78 | |
| 79 | |
| 80 local db | |
| 81 local _G = _G | |
| 82 local UnitName, SelectedRealmName, InCombatLockdown, UnitClass = UnitName, SelectedRealmName, InCombatLockdown, UnitClass | |
| 83 local tostring, select, tinsert, pairs = tostring, select, tinsert, pairs | |
| 84 local concat, wipe = table.concat, table.wipe | |
| 85 local classHeader, className, classID = '', '', 0 | |
| 86 | |
| 87 | |
| 88 local CloseButton_OnClick = function() | |
| 89 | |
| 90 kb.db.showUI = false | |
| 91 print(kb.db.showUI) | |
| 92 SkeletonKey:SetShown(kb.db.showUI) | |
| 93 end | |
| 94 | |
| 95 --- Returns conflicting assignment and binding profiles for use in displaying confirmations | |
| 96 kb.IsCommandBound = function(self, command) | |
| 97 local isAssigned, assignedBy = false, kb.db.bindMode | |
| 98 local isBound, boundBy = false, kb.db.bindMode | |
| 99 command = command or self.command | |
| 100 for i = 1, #kb.orderedProfiles do | |
| 101 local profile = kb.orderedProfiles[i] | |
| 102 if i ~= kb.db.bindMode then | |
| 103 | |
| 104 if profile.commands[command] then | |
| 105 print(' command: ', i , kb.configHeaders[i], profile.commands[command]) | |
| 106 isAssigned = true | |
| 107 assignedBy = i | |
| 108 end | |
| 109 if profile.bound[command] then | |
| 110 print(' bound: ', i , kb.configHeaders[i], profile.bound[command]) | |
| 111 isBound = true | |
| 112 boundBy = i | |
| 113 end | |
| 114 | |
| 115 | |
| 116 | |
| 117 | |
| 118 if isAssigned and isBound then | |
| 119 print(' hit: ', i , kb.configHeaders[i], profile.commands[command], profile.bound[command]) | |
| 120 break | |
| 121 end | |
| 122 end | |
| 123 | |
| 124 end | |
| 125 | |
| 126 print('|cFFFFFF00IsCommandBound:|r', command,'|r [profile:', kb.db.bindMode .. ']', isAssigned, isBound, assignedBy, boundBy) | |
| 127 return isAssigned, isBound, assignedBy, boundBy | |
| 128 end | |
| 129 | |
| 130 local talentSpellHardCodes = { | |
| 131 [109248] = 'Binding Shot', | |
| 132 } | |
| 133 | |
| 134 --- Returns a value for use with Texture:SetDesaturated() | |
| 135 kb.BindingIsLocked = function(key) | |
| 136 local success = false | |
| 137 for i = 1, db.bindMode-1 do | |
| 138 local tier = kb.orderedProfiles[i] | |
| 139 if tier.bindings[key] then | |
| 140 success = true | |
| 141 break | |
| 142 end | |
| 143 end | |
| 144 return success | |
| 145 end | |
| 146 | |
| 147 --- Translates GetBindingKey() results into a printable string. | |
| 148 kb.BindingString = function(...) | |
| 149 local stack = {} | |
| 150 for i = 1, select('#', ...) do | |
| 151 local key = select(i, ...) | |
| 152 if type(key) == 'string' then | |
| 153 stack[i] = key:gsub('SHIFT', 's'):gsub('ALT', 'a'):gsub('CTRL', 'c'):gsub('SPACE', 'Sp'):gsub('BUTTON', 'M '):gsub('NUMPAD', '# ') | |
| 154 end | |
| 155 end | |
| 156 | |
| 157 if #stack >= 1 then | |
| 158 return concat(stack, ',') | |
| 159 else | |
| 160 return nil | |
| 161 end | |
| 162 end | |
| 163 | |
| 164 | |
| 165 function kb:print(...) | |
| 166 | |
| 167 local msg = '|cFF0088FFSkeletonKey|r:' | |
| 168 for i = 1, select('#', ...) do | |
| 169 msg = msg .. ' ' .. tostring(select(i, ...)) | |
| 170 end | |
| 171 DEFAULT_CHAT_FRAME:AddMessage(msg) | |
| 172 end | |
| 173 | |
| 174 | |
| 175 kb.Command = function(args, editor) | |
| 176 if args:match("import") then | |
| 177 kb.ImportCommmit(args) | |
| 178 return | |
| 179 elseif args:match("scan") then | |
| 180 kb.ImportScan(args) | |
| 181 SkeletonKey:Update() | |
| 182 return | |
| 183 elseif args:match("load") then | |
| 184 kb:ApplyAllBindings() | |
| 185 return | |
| 186 end | |
| 187 | |
| 188 if db.showUI then | |
| 189 db.showUI = false | |
| 190 else | |
| 191 db.showUI = true | |
| 192 if not InCombatLockdown() then | |
| 193 kb:print(L('Config frame opened.')) | |
| 194 else | |
| 195 kb:print(L('Config frame will open upon exiting combat.')) | |
| 196 end | |
| 197 end | |
| 198 SkeletonKey:SetShown(db.showUI) | |
| 199 SkeletonKey:Update(true) | |
| 200 end | |
| 201 | |
| 202 kb.InitProfile = function(profile, prototype) | |
| 203 print('|cFF00FFFFkb.InitProfile()', profile, prototype) | |
| 204 if not profile then | |
| 205 profile = {} | |
| 206 end | |
| 207 if prototype then | |
| 208 for k,v in pairs(prototype) do | |
| 209 if not profile[k] then | |
| 210 profile[k] = v | |
| 211 end | |
| 212 end | |
| 213 end | |
| 214 | |
| 215 profile.bound = profile.bound or {} | |
| 216 profile.buttons = profile.buttons or {} | |
| 217 profile.commands = profile.commands or {} | |
| 218 profile.bindings = profile.bindings or {} | |
| 219 profile.macros = profile.macros or {} | |
| 220 profile.talents = profile.talents or {} | |
| 221 return profile | |
| 222 end | |
| 223 | |
| 224 kb.ResetProfile = function(profile, prototype) | |
| 225 if profile == kb.currentProfile then | |
| 226 for i, button in pairs(kb.buttons) do | |
| 227 kb.ReleaseSlot(button) | |
| 228 end | |
| 229 end | |
| 230 wipe(profile) | |
| 231 kb.InitProfile(profile, prototype) | |
| 232 end | |
| 233 | |
| 234 | |
| 235 | |
| 236 --- Handles constructing spec profiles as they are selected | |
| 237 | |
| 238 | |
| 239 --- Obtains profile data or creates the necessary tables | |
| 240 kb.SelectProfileSet = function(name) | |
| 241 | |
| 242 local defaultMode | |
| 243 --- General info | |
| 244 classHeader, className, classID = UnitClass('player') | |
| 245 print('|cFF00FF00profile:|r', name) | |
| 246 print('|cFF00FF00class:|r', UnitClass('player')) | |
| 247 | |
| 248 defaultMode = BINDING_TYPE_GLOBAL | |
| 249 if db[name] then | |
| 250 defaultMode = BINDING_TYPE_CHARACTER | |
| 251 if db[name][kb.specInfo.id] then | |
| 252 defaultMode = BINDING_TYPE_SPECIALIZATION | |
| 253 end | |
| 254 end | |
| 255 | |
| 256 db[name] = kb.InitProfile(db[name], | |
| 257 { | |
| 258 classHeader = classHeader, | |
| 259 className = className, | |
| 260 classID = classID | |
| 261 }) | |
| 262 db[name][kb.specInfo.id] = kb.InitProfile(db[name][kb.specInfo.id], | |
| 263 { | |
| 264 specID = kb.specInfo.id, | |
| 265 specName = kb.specInfo.name | |
| 266 }) | |
| 267 | |
| 268 kb.loadedProfiles[BINDING_TYPE_GLOBAL] = db | |
| 269 kb.loadedProfiles[BINDING_TYPE_CHARACTER] = db[name] | |
| 270 kb.loadedProfiles[BINDING_TYPE_SPECIALIZATION] = db[name][kb.specInfo.id] | |
| 271 kb.orderedProfiles = {db, db[name], db[name][kb.specInfo.id]} | |
| 272 | |
| 273 if (not db.bindMode) or (not kb.configTitle[db.bindMode]) then | |
| 274 print('fixing bad bindMode value, was', db.bindMode) | |
| 275 db.bindMode = defaultMode | |
| 276 end | |
| 277 | |
| 278 | |
| 279 print(BINDING_TYPE_GLOBAL) | |
| 280 kb.configHeaders[BINDING_TYPE_GLOBAL] = kb.configTitle[BINDING_TYPE_GLOBAL] | |
| 281 kb.configHeaders[BINDING_TYPE_CHARACTER] = kb.configTitle[BINDING_TYPE_CHARACTER]:format(UnitName('player', true)) | |
| 282 kb.configHeaders[BINDING_TYPE_SPECIALIZATION] = kb.configTitle[BINDING_TYPE_SPECIALIZATION]:format(kb.specInfo.name or '') | |
| 283 | |
| 284 | |
| 285 setmetatable(kb.loadedProfiles[BINDING_TYPE_GLOBAL], {__tostring =function() return kb.configHeaders[BINDING_TYPE_GLOBAL] end}) | |
| 286 setmetatable(kb.loadedProfiles[BINDING_TYPE_CHARACTER], {__tostring =function() return kb.configHeaders[BINDING_TYPE_CHARACTER] end}) | |
| 287 setmetatable(kb.loadedProfiles[BINDING_TYPE_SPECIALIZATION], {__tostring =function() return kb.configHeaders[BINDING_TYPE_SPECIALIZATION] end}) | |
| 288 | |
| 289 print('|cFF00FF00bindMode:|r', db.bindMode) | |
| 290 kb.currentProfile = kb.loadedProfiles[db.bindMode] | |
| 291 kb.currentHeader = kb.configHeaders[db.bindMode] | |
| 292 end | |
| 293 | |
| 294 | |
| 295 function SkeletonKeyMixin:SetTab (id) | |
| 296 self.scrollCache[db.bindMode] = kb.scrollOffset | |
| 297 db.bindMode =id | |
| 298 kb.currentProfile = kb.loadedProfiles[id] | |
| 299 kb.currentHeader = kb.configHeaders[db.bindMode] | |
| 300 kb.scrollOffset = self.scrollCache[db.bindMode] or 0 | |
| 301 self:Update(true) | |
| 302 end | |
| 303 | |
| 304 kb.ConfirmBindings = function() | |
| 305 kb.ApplyAllBindings() | |
| 306 if #kb.pendingAttributes == 0 then | |
| 307 kb:print(L("Manual bindings update finished.")) | |
| 308 else | |
| 309 kb:print(L("Manual update will complete upon exiting combat.")) | |
| 310 end | |
| 311 SkeletonKey:Update() | |
| 312 end | |
| 313 | |
| 314 function SkeletonKeyMixin:OnLoad() | |
| 315 kb.frame = self | |
| 316 print('|cFF0088FF'..self:GetName()..':OnLoad()') | |
| 317 | |
| 318 self.CloseButton:SetScript('OnClick', CloseButton_OnClick) | |
| 319 self:RegisterEvent('PLAYER_ENTERING_WORLD') | |
| 320 self:RegisterEvent('ADDON_LOADED') | |
| 321 self:EnableKeyboard(false) | |
| 322 | |
| 323 self.zoomScale = self:GetScale() | |
| 324 self.backdrop = self:GetBackdrop() | |
| 325 self.backdropColor = {self:GetBackdropColor() } | |
| 326 self.backdropBorder = {self:GetBackdropBorderColor() } | |
| 327 | |
| 328 end | |
| 329 | |
| 330 function SkeletonKeyMixin:OnEvent(event, arg) | |
| 331 if event == 'ADDON_LOADED' then | |
| 332 | |
| 333 print('|cFF00FFFF'..event ..'|r', arg or '', IsLoggedIn()) | |
| 334 if IsLoggedIn() and not self.initialized then | |
| 335 self:Setup() | |
| 336 self.initialized = true | |
| 337 self:Update() | |
| 338 end | |
| 339 | |
| 340 | |
| 341 elseif kb[event] then | |
| 342 if self.initialized then | |
| 343 print('|cFF0088FF'..event ..'|r', arg or '') | |
| 344 kb[event](self, event, arg) | |
| 345 else | |
| 346 | |
| 347 print('|cFF004488'..event ..'|r', arg or '') | |
| 348 end | |
| 349 end | |
| 350 end | |
| 351 | |
| 352 | |
| 353 --- post ADDON_LOADED | |
| 354 function SkeletonKeyMixin:Setup () | |
| 355 print('|cFF00FFFF'..self:GetName()..':Setup()') | |
| 356 SkeletonKeyDB = kb.InitProfile(SkeletonKeyDB, {}) | |
| 357 kb.db = _G.SkeletonKeyDB | |
| 358 kb.playerName = UnitName('player') | |
| 359 kb.playerRealm = SelectedRealmName() | |
| 360 kb.profileName = kb.playerRealm .. '_' .. kb.playerName | |
| 361 db = kb.db | |
| 362 | |
| 363 kb.UpdateSpecInfo() | |
| 364 kb.UpdateTalentInfo() | |
| 365 kb.SelectProfileSet(kb.profileName) | |
| 366 -- todo: redo import checking | |
| 367 | |
| 368 kb.UpdateSystemBinds() | |
| 369 kb.ApplyAllBindings() | |
| 370 | |
| 371 if not InCombatLockdown() then | |
| 372 kb.CreateHooks() | |
| 373 else | |
| 374 kb:print('Some functionality will not load until breaking combat.') | |
| 375 tinsert(kb.pendingCalls, kb.CreateHooks) | |
| 376 end | |
| 377 SLASH_SKB1 = "/skb" | |
| 378 SLASH_SKB2 = "/skeletonkey" | |
| 379 SlashCmdList.SKB = kb.Command | |
| 380 | |
| 381 self:SetShown(kb.db.showUI) | |
| 382 self:Update(true) | |
| 383 | |
| 384 self:RegisterEvent('UPDATE_MACROS') | |
| 385 self:RegisterEvent('UPDATE_BINDINGS') | |
| 386 self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player', 'pet') | |
| 387 self:RegisterUnitEvent('PLAYER_SPECIALIZATION_CHANGED', 'player', 'pet') | |
| 388 self:RegisterUnitEvent('SPELLS_CHANGED') | |
| 389 self:RegisterUnitEvent('TALENT_UPDATE', 'player', 'pet') | |
| 390 self:RegisterEvent('PLAYER_REGEN_DISABLED') | |
| 391 self:RegisterEvent('PLAYER_REGEN_ENABLED') | |
| 392 | |
| 393 self:RegisterForDrag('LeftButton') | |
| 394 self:SetMovable(true) | |
| 395 for index, frame in ipairs(self.Plugins) do | |
| 396 frame:Setup() | |
| 397 end | |
| 398 end | |
| 399 | |
| 400 | |
| 401 -- Volatiles Access | |
| 402 kb.FormatActionID = function(actionType, actionID) return tostring(actionType) .. '_' .. tostring(actionID) end | |
| 403 kb.GetBindings = function() return kb.bindings end | |
| 404 kb.GetButtons = function() return kb.buttons end | |
| 405 kb.GetCharacterProfile = function () return kb.loadedProfiles[BINDING_TYPE_CHARACTER] end | |
| 406 kb.GetGlobalProfile = function () return kb.loadedProfiles[BINDING_TYPE_GLOBAL] end | |
| 407 kb.GetSpecProfile = function () return kb.loadedProfiles[BINDING_TYPE_SPECIALIZATION] end | |
| 408 | |
| 409 |
