Nenue@16
|
1 -- SkeletonKey
|
Nenue@16
|
2 -- ActionTypes.lua
|
Nenue@16
|
3 -- Created: 7/29/2016 9:14 PM
|
Nenue@16
|
4 -- %file-revision%
|
Nenue@16
|
5 --
|
Nenue@16
|
6 local kb, print, wrap = LibStub('LibKraken').register(KeyBinder)
|
Nenue@17
|
7 local cprint = DEVIAN_WORKSPACE and function(...) _G.print('Cfg', ...) end or function() end
|
Nenue@16
|
8
|
Nenue@16
|
9 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544
|
Nenue@17
|
10 local CLICK_KEYBINDER_MACRO = "CLICK KeyBinderMacro:"
|
Nenue@17
|
11 local CLICK_KEYBINDER_KEY = "CLICK KeyBinderKey:"
|
Nenue@16
|
12
|
Nenue@16
|
13 local PETACTION_SCRIPT = {
|
Nenue@16
|
14 [PET_ACTION_MOVE_TO] = {SLASH_PET_MOVE_TO1, 'pet_move_to'},
|
Nenue@16
|
15 [PET_ACTION_ATTACK] = {SLASH_PET_ATTACK1, 'pet_attack'},
|
Nenue@16
|
16 [PET_ACTION_FOLLOW] = {SLASH_PET_FOLLOW1, 'pet_follow'},
|
Nenue@16
|
17 [PET_ACTION_WAIT] = {SLASH_PET_STAY1, 'pet_stay'},
|
Nenue@16
|
18 [PET_MODE_AGGRESSIVE] = {SLASH_PET_AGGRESSIVE1, 'pet_aggressive'},
|
Nenue@16
|
19 [PET_MODE_DEFENSIVE] = {SLASH_PET_DEFENSIVE1, 'pet_defensive'},
|
Nenue@16
|
20 [PET_MODE_PASSIVE] = {SLASH_PET_PASSIVE1, 'pet_passive'},
|
Nenue@16
|
21 [PET_MODE_ASSIST] = {SLASH_PET_ASSIST1, 'pet_assist'},
|
Nenue@16
|
22 }
|
Nenue@16
|
23
|
Nenue@19
|
24 kb.ActionTypes = {}
|
Nenue@19
|
25 kb.PetCache = {}
|
Nenue@19
|
26 kb.TalentCache = {}
|
Nenue@19
|
27 kb.ProfessionCache = {}
|
Nenue@19
|
28
|
Nenue@19
|
29 local atype = kb.ActionTypes
|
Nenue@19
|
30
|
Nenue@17
|
31 --- Caps Lock
|
Nenue@19
|
32 atype['mount'] = function(id, name)
|
Nenue@17
|
33 if id == SUMMON_RANDOM_FAVORITE_MOUNT_SPELL then
|
Nenue@17
|
34 return 'mount_random', "/script C_MountJournal.SummonByID(0)", CLICK_KEYBINDER_MACRO
|
Nenue@17
|
35 else
|
Nenue@17
|
36 return 'mount_'..id, "/script C_MountJournal.SummonByID("..id..")", CLICK_KEYBINDER_MACRO
|
Nenue@17
|
37 end
|
Nenue@16
|
38 end
|
Nenue@19
|
39
|
Nenue@19
|
40 atype['macro'] = function(id, name)
|
Nenue@17
|
41 return CLICK_KEYBINDER_MACRO, 'macro_' .. tostring(name), id
|
Nenue@17
|
42 end
|
Nenue@19
|
43
|
Nenue@19
|
44 atype['equipset'] = function(id, name)
|
Nenue@17
|
45 return CLICK_KEYBINDER_MACRO, 'equipset_'..tostring(name), "/script UseEquipmentSet("..tostring(id)..")"
|
Nenue@17
|
46 end
|
Nenue@19
|
47
|
Nenue@19
|
48 atype['spell'] = function(id, name)
|
Nenue@17
|
49 local attributeName = name
|
Nenue@17
|
50 if kb.ProfessionCache[id] then
|
Nenue@17
|
51 attributeName = "profession_".. kb.ProfessionCache[id].profOffset .. '_' .. kb.ProfessionCache[id].spellNum
|
Nenue@17
|
52 end
|
Nenue@17
|
53 return CLICK_KEYBINDER_KEY, attributeName, name
|
Nenue@17
|
54 end
|
Nenue@19
|
55
|
Nenue@19
|
56 atype['petaction'] = function(_, name)
|
Nenue@17
|
57 -- ID doesn't exist for basic commands, even though they can be picked up
|
Nenue@17
|
58 local attributeName, attributeValue = "petaction_" .. tostring(name), "/cast "..tostring(name)
|
Nenue@17
|
59 if PETACTION_SCRIPT[name] then
|
Nenue@17
|
60 attributeValue, attributeName = unpack(PETACTION_SCRIPT[name])
|
Nenue@19
|
61 elseif kb.PetCache.special[name] then
|
Nenue@19
|
62 attributeName = "petaction_special" .. tonumber(kb.PetCache.special[name][2])
|
Nenue@17
|
63 end
|
Nenue@17
|
64 return CLICK_KEYBINDER_MACRO, attributeName, attributeValue
|
Nenue@16
|
65 end
|
Nenue@16
|
66
|
Nenue@19
|
67 atype['battlepet'] = function(id, name)
|
Nenue@17
|
68 return CLICK_KEYBINDER_MACRO, 'battlepet_' .. tostring(name), SLASH_SUMMON_BATTLE_PET1 .. " " .. tostring(name)
|
Nenue@17
|
69 end
|
Nenue@19
|
70
|
Nenue@19
|
71 atype['item'] = function(id, name)
|
Nenue@17
|
72 return CLICK_KEYBINDER_KEY, 'item_' .. tostring(name), id
|
Nenue@17
|
73 end
|
Nenue@16
|
74
|
Nenue@16
|
75
|
Nenue@17
|
76 --- Resolves the SecureActionButton attribute names used for the given action
|
Nenue@16
|
77 kb.RegisterAction = function(actionType, id, name)
|
Nenue@16
|
78
|
Nenue@19
|
79 assert(atype[actionType], 'Missing actionType handler for `'..tostring(actionType)..'`')
|
Nenue@19
|
80 local target, attributeName, attributeValue = atype[actionType](id, name)
|
Nenue@17
|
81
|
Nenue@17
|
82 local command = target .. attributeName
|
Nenue@17
|
83 local baseName, iterative = attributeName, 1
|
Nenue@17
|
84 while (kb.macros[attributeName] and kb.macros[attributeName][1] ~= attributeValue) do
|
Nenue@17
|
85 print(' * cannot use|cFF00FF00', attributeName, '|r"'.. tostring(kb.macros[attributeName][1]) .. '"')
|
Nenue@17
|
86 attributeName = baseName .. '_' .. iterative
|
Nenue@17
|
87 iterative = iterative + 1
|
Nenue@17
|
88 end
|
Nenue@17
|
89 if macroName ~= baseName then
|
Nenue@17
|
90 print(' * Creating|cFF00FF00', macroName)
|
Nenue@17
|
91 else
|
Nenue@17
|
92 print(' * Re-using|cFF00FF00', macroName)
|
Nenue@17
|
93 end
|
Nenue@17
|
94 kb.macros[attributeName] = {attributeValue, command}
|
Nenue@17
|
95
|
Nenue@17
|
96
|
Nenue@17
|
97 print('RegisterAction', actionType, id, '->', attributeName, attributeValue, target .. attributeName)
|
Nenue@17
|
98 return attributeName, attributeValue, command
|
Nenue@17
|
99 end
|
Nenue@17
|
100
|
Nenue@17
|
101
|
Nenue@17
|
102
|
Nenue@17
|
103
|
Nenue@17
|
104 kb.ApplyTalentBinding = function(talentInfo, cache)
|
Nenue@17
|
105 for i = 5, #talentInfo do
|
Nenue@17
|
106 local command = CLICK_KEYBINDER_KEY.. talentInfo[2]
|
Nenue@17
|
107 SetBinding(talentInfo[i], command)
|
Nenue@17
|
108 cprint(' **', talentInfo[i], '->', command)
|
Nenue@17
|
109 tinsert(cache, talentInfo[i])
|
Nenue@17
|
110 end
|
Nenue@17
|
111 end
|
Nenue@17
|
112 kb.CacheTalentBinding = function(talentInfo, cache)
|
Nenue@17
|
113
|
Nenue@17
|
114 local spellID = talentInfo[4]
|
Nenue@19
|
115 cache[spellID] = cache[spellID] or {}
|
Nenue@19
|
116 cache[spellID] = {select(5,unpack(talentInfo)) }
|
Nenue@19
|
117 --cprint(spellID, unpack(kb.TalentBindings[spellID]))
|
Nenue@17
|
118 end
|
Nenue@17
|
119
|
Nenue@17
|
120 do
|
Nenue@17
|
121 local bindings = kb.bindings
|
Nenue@17
|
122 local key, macro = KeyBinderKey, KeyBinderMacro
|
Nenue@17
|
123 kb.LoadBinding = function(command, name, icon, actionType, actionID, macroName, macroText )
|
Nenue@17
|
124
|
Nenue@17
|
125 if actionType == 'spell' then
|
Nenue@17
|
126 key:SetAttribute("*type-"..name, actionType)
|
Nenue@17
|
127 key:SetAttribute("*"..actionType.."-"..name, name)
|
Nenue@17
|
128 elseif actionType == 'item' then
|
Nenue@17
|
129 key:SetAttribute("*type-"..name, actionType)
|
Nenue@17
|
130 key:SetAttribute("*"..actionType.."-"..name, name)
|
Nenue@17
|
131 elseif actionType == 'macro' then
|
Nenue@17
|
132 macro:SetAttribute("*macro-"..macroName, actionID)
|
Nenue@16
|
133 else
|
Nenue@17
|
134 macro:SetAttribute("*macrotext-"..macroName, macroText)
|
Nenue@16
|
135 end
|
Nenue@16
|
136
|
Nenue@17
|
137 cprint('Loading binding', actionType, actionID)
|
Nenue@17
|
138 bindings[actionType] = bindings[actionType] or {}
|
Nenue@17
|
139 bindings[actionType][actionID] = bindings[actionType][actionID] or {}
|
Nenue@17
|
140 bindings[command] = bindings[actionType][actionID]
|
Nenue@17
|
141 return bindings[actionType], actionID
|
Nenue@16
|
142 end
|
Nenue@16
|
143
|
Nenue@17
|
144 kb.ApplyBindings = function (profile)
|
Nenue@17
|
145 cprint('binding profile', profile)
|
Nenue@17
|
146 for slot, data in pairs(profile.buttons) do
|
Nenue@17
|
147 kb.LoadBinding(unpack(data))
|
Nenue@17
|
148 end
|
Nenue@17
|
149
|
Nenue@17
|
150 for key, command in pairs(profile.bindings) do
|
Nenue@17
|
151
|
Nenue@17
|
152 cprint(' *', key, '->', command)
|
Nenue@17
|
153
|
Nenue@17
|
154 --_G.print('HotKey','loading', key, command)
|
Nenue@17
|
155 SetBinding(key, command)
|
Nenue@17
|
156 if bindings[command] and not tContains(bindings[command], key) then
|
Nenue@17
|
157 tinsert(bindings[command], key)
|
Nenue@17
|
158 end
|
Nenue@17
|
159 end
|
Nenue@17
|
160
|
Nenue@17
|
161 for spellName, talentInfo in pairs(profile.talents) do
|
Nenue@17
|
162 local dummy = GetSpellInfo(spellName)
|
Nenue@17
|
163 local func = kb.CacheTalentBinding
|
Nenue@19
|
164 local dest = kb.TalentBindings
|
Nenue@17
|
165 if dummy then
|
Nenue@17
|
166 cprint('|cFFBBFF00Active:|r', dummy)
|
Nenue@17
|
167 local macroName, spellName, actionType, actionID = unpack(talentInfo)
|
Nenue@17
|
168 bindings[actionType] = bindings[actionType] or {}
|
Nenue@17
|
169 bindings[actionType][actionID] = {}
|
Nenue@17
|
170 func = kb.ApplyTalentBinding
|
Nenue@17
|
171 dest = kb.bindings[actionType][actionID]
|
Nenue@17
|
172 else
|
Nenue@17
|
173
|
Nenue@17
|
174 cprint('|cFFFF4400Inactive:|r', talentInfo[2])
|
Nenue@17
|
175 end
|
Nenue@17
|
176 func(talentInfo, dest)
|
Nenue@17
|
177 end
|
Nenue@17
|
178
|
Nenue@17
|
179 end
|
Nenue@17
|
180
|
Nenue@17
|
181 kb.ApplyAllBindings =function ()
|
Nenue@19
|
182 table.wipe(kb.TalentBindings)
|
Nenue@17
|
183
|
Nenue@17
|
184
|
Nenue@17
|
185 -- reflect action key settings
|
Nenue@17
|
186 if GetCVarBool("ActionButtonUseKeyDown") then
|
Nenue@17
|
187 KeyBinderMacro:RegisterForClicks("AnyDown")
|
Nenue@17
|
188 KeyBinderKey:RegisterForClicks("AnyDown")
|
Nenue@17
|
189 else
|
Nenue@17
|
190 KeyBinderMacro:RegisterForClicks("AnyUp")
|
Nenue@17
|
191 KeyBinderKey:RegisterForClicks("AnyUp")
|
Nenue@17
|
192 end
|
Nenue@17
|
193
|
Nenue@17
|
194 for i, profile in ipairs(kb.orderedProfiles) do
|
Nenue@17
|
195 kb.ApplyBindings(profile)
|
Nenue@17
|
196 end
|
Nenue@17
|
197 -- do this after to ensure that profession binds are properly overridden
|
Nenue@17
|
198 kb.UpdateProfessionInfo()
|
Nenue@17
|
199
|
Nenue@17
|
200
|
Nenue@17
|
201 SaveBindings(GetCurrentBindingSet())
|
Nenue@17
|
202 end
|
Nenue@19
|
203 end
|
Nenue@19
|
204
|
Nenue@19
|
205
|
Nenue@19
|
206 local PET_SPECIAL_SUBTEXT = 'Special Ability'
|
Nenue@19
|
207 local SECONDARY_PROFESSIONS = {
|
Nenue@19
|
208 [5] = 3,
|
Nenue@19
|
209 [7] = 4,
|
Nenue@19
|
210 [9] = 5,
|
Nenue@19
|
211 [10] = 6
|
Nenue@19
|
212 }
|
Nenue@19
|
213
|
Nenue@19
|
214 kb.TalentCache = {}
|
Nenue@19
|
215 kb.ProfessionCache = {}
|
Nenue@19
|
216 kb.PetCache = {}
|
Nenue@19
|
217 kb.specInfo = {}
|
Nenue@19
|
218 kb.UpdateSpecInfo = function()
|
Nenue@19
|
219 kb.specInfo.id = GetSpecialization()
|
Nenue@19
|
220 kb.specInfo.globalID, kb.specInfo.name, kb.specInfo.desc, kb.specInfo.texture = GetSpecializationInfo(kb.specInfo.id)
|
Nenue@19
|
221 print('|cFF00FF00current spec:|r', kb.specInfo.id, 'of', GetNumSpecializations())
|
Nenue@19
|
222 end
|
Nenue@19
|
223
|
Nenue@19
|
224 kb.UpdateTalentInfo = function()
|
Nenue@19
|
225 if kb.talentsPushed then
|
Nenue@19
|
226 return
|
Nenue@19
|
227 end
|
Nenue@19
|
228 table.wipe(kb.TalentCache)
|
Nenue@19
|
229 for row =1, MAX_TALENT_TIERS do
|
Nenue@19
|
230 for col = 1, NUM_TALENT_COLUMNS do
|
Nenue@19
|
231 local talentID, talentName, icon, selected, available, spellID = GetTalentInfo(row, col, 1)
|
Nenue@19
|
232 local talentInfo = kb.TalentCache[spellID] or {}
|
Nenue@19
|
233 talentInfo.row = 1
|
Nenue@19
|
234 talentInfo.col = col
|
Nenue@19
|
235 talentInfo.name = talentName
|
Nenue@19
|
236 talentInfo.talentID = talentID
|
Nenue@19
|
237 talentInfo.selected = selected
|
Nenue@19
|
238 talentInfo.available = available
|
Nenue@19
|
239 talentInfo.spellID = spellID
|
Nenue@19
|
240 kb.TalentCache[spellID] = talentInfo
|
Nenue@19
|
241 kb.TalentCache[talentName] = talentInfo
|
Nenue@19
|
242 print('Talent ', row, col, spellID, talentName)
|
Nenue@19
|
243 end
|
Nenue@19
|
244 end
|
Nenue@19
|
245 kb.talentsPushed = true
|
Nenue@19
|
246
|
Nenue@19
|
247 kb.UpdateDynamicButtons('talent')
|
Nenue@19
|
248 end
|
Nenue@19
|
249
|
Nenue@19
|
250 kb.UpdateProfessionInfo = function()
|
Nenue@19
|
251 table.wipe(kb.ProfessionCache)
|
Nenue@19
|
252 local profs = {GetProfessions() }
|
Nenue@19
|
253 local primaryNum = 0
|
Nenue@19
|
254 for i, index in ipairs(profs) do
|
Nenue@19
|
255 local profName, texture, rank, maxRank, numSpells, spellOffset = GetProfessionInfo(index)
|
Nenue@19
|
256 print(i, index, profName, numSpells, spellOffset)
|
Nenue@19
|
257 if not SECONDARY_PROFESSIONS[index] then
|
Nenue@19
|
258 primaryNum = primaryNum + 1
|
Nenue@19
|
259 end
|
Nenue@19
|
260 local profNum = SECONDARY_PROFESSIONS[index] or primaryNum
|
Nenue@19
|
261
|
Nenue@19
|
262
|
Nenue@19
|
263 kb.ProfessionCache[profNum] = kb.ProfessionCache[i] or {}
|
Nenue@19
|
264
|
Nenue@19
|
265 for j = 1, numSpells do
|
Nenue@19
|
266 local spellName, _, icon, _, _, _, spellID = GetSpellInfo(spellOffset+j, BOOKTYPE_PROFESSION)
|
Nenue@19
|
267
|
Nenue@19
|
268 local profInfo = {
|
Nenue@19
|
269 spellName = spellName,
|
Nenue@19
|
270 spellID = spellID,
|
Nenue@19
|
271 icon = icon,
|
Nenue@19
|
272 profOffset = i,
|
Nenue@19
|
273 profIndex = index,
|
Nenue@19
|
274 spellOffset = (spellOffset+j),
|
Nenue@19
|
275 spellNum = j
|
Nenue@19
|
276 }
|
Nenue@19
|
277 KeyBinderKey:SetAttribute("*type-profession_"..i .. '_' ..j, "spell")
|
Nenue@19
|
278 KeyBinderKey:SetAttribute("*spell-profession_"..i .. '_' ..j, spellName)
|
Nenue@19
|
279
|
Nenue@19
|
280 kb.ProfessionCache[i .. '_' .. j] = profInfo
|
Nenue@19
|
281 kb.ProfessionCache[spellName] = profInfo
|
Nenue@19
|
282 kb.ProfessionCache[spellID] = profInfo
|
Nenue@19
|
283 print(' |cFF0088FF['..i..']|r|cFFFF44BB['..spellOffset+i..']|r', spellName, "profession_"..i .. '_' ..j)
|
Nenue@19
|
284 end
|
Nenue@19
|
285
|
Nenue@19
|
286 end
|
Nenue@19
|
287
|
Nenue@19
|
288 kb.UpdateDynamicButtons('profession')
|
Nenue@19
|
289 end
|
Nenue@19
|
290
|
Nenue@19
|
291
|
Nenue@19
|
292
|
Nenue@19
|
293 kb.UpdatePetInfo = function()
|
Nenue@19
|
294 kb.PetCache.spell = kb.PetCache.spell or {}
|
Nenue@19
|
295 kb.PetCache.spellslot = kb.PetCache.spellslot or {}
|
Nenue@19
|
296 kb.PetCache.action = kb.PetCache.action or {}
|
Nenue@19
|
297 kb.PetCache.special = kb.PetCache.action or {}
|
Nenue@19
|
298 local hasPetSpells, petType = HasPetSpells()
|
Nenue@19
|
299 if PetHasSpellbook() then
|
Nenue@19
|
300 print('PET SPELLBOOK')
|
Nenue@19
|
301 local i = 1
|
Nenue@19
|
302 local specialNum = 0
|
Nenue@19
|
303 repeat
|
Nenue@19
|
304
|
Nenue@19
|
305 local spellType, spellID = GetSpellBookItemInfo(i, BOOKTYPE_PET)
|
Nenue@19
|
306 local spellName, subText = GetSpellBookItemName(i, BOOKTYPE_PET)
|
Nenue@19
|
307 local isPassive = IsPassiveSpell(i, BOOKTYPE_PET)
|
Nenue@19
|
308 if not isPassive then
|
Nenue@19
|
309 if spellName then
|
Nenue@19
|
310 kb.PetCache.spellslot[spellName] = {i, spellName, subText}
|
Nenue@19
|
311 print('|cFF00FF88spellslot['..spellName..']|r', '=>', i, subText)
|
Nenue@19
|
312
|
Nenue@19
|
313 if subText == PET_SPECIAL_SUBTEXT then
|
Nenue@19
|
314 specialNum = specialNum + 1
|
Nenue@19
|
315 kb.PetCache.special[spellName] = {i, specialNum, spellID, subText }
|
Nenue@19
|
316 print('|cFF00FFFFspecial['..spellName..']|r', '=>', i, specialNum, spellID, subText)
|
Nenue@19
|
317 KeyBinderMacro:SetAttribute("*macrotext-pet_special_"..specialNum, "/cast "..spellName)
|
Nenue@19
|
318 end
|
Nenue@19
|
319
|
Nenue@19
|
320 if spellID then
|
Nenue@19
|
321 kb.PetCache.spell[i] = {spellID, spellName, subText}
|
Nenue@19
|
322 print('|cFF0088FFspell['..i..']|r', '=>', spellID, spellName, subText)
|
Nenue@19
|
323 end
|
Nenue@19
|
324 end
|
Nenue@19
|
325
|
Nenue@19
|
326
|
Nenue@19
|
327 end
|
Nenue@19
|
328
|
Nenue@19
|
329 i = i + 1
|
Nenue@19
|
330 until spellType == nil
|
Nenue@19
|
331 else
|
Nenue@19
|
332 print('NO PET SPELLBOOK')
|
Nenue@19
|
333 table.wipe(kb.PetCache.spell)
|
Nenue@19
|
334 table.wipe(kb.PetCache.spellslot)
|
Nenue@19
|
335 end
|
Nenue@19
|
336
|
Nenue@19
|
337 if PetHasActionBar() then
|
Nenue@19
|
338 print('PET ACTION BAR')
|
Nenue@19
|
339 for i = 1, 10 do
|
Nenue@19
|
340
|
Nenue@19
|
341
|
Nenue@19
|
342 local name, subtext, texture, isToken, isActive = GetPetActionInfo(i)
|
Nenue@19
|
343 if name then
|
Nenue@19
|
344 kb.PetCache.action[i] = {name, subtext, texture, isToken, isActive }
|
Nenue@19
|
345
|
Nenue@19
|
346
|
Nenue@19
|
347 end
|
Nenue@19
|
348 print('|cFFFFFF00action['..i..']|r', name, subtext, texture)
|
Nenue@19
|
349 end
|
Nenue@19
|
350 else
|
Nenue@19
|
351 print('NO PET ACTION BAR')
|
Nenue@19
|
352 table.wipe(kb.PetCache.action)
|
Nenue@19
|
353 end
|
Nenue@19
|
354
|
Nenue@19
|
355 kb.UpdateDynamicButtons('petaction')
|
Nenue@19
|
356
|
Nenue@19
|
357 end
|
Nenue@19
|
358
|
Nenue@19
|
359 kb.UpdateSystemBinds = function()
|
Nenue@19
|
360 table.wipe(kb.SystemBindings)
|
Nenue@19
|
361 local n = GetNumBindings()
|
Nenue@19
|
362 for i=1, n do
|
Nenue@19
|
363 local command, key1, key2 = GetBinding(i)
|
Nenue@19
|
364 if key1 then
|
Nenue@19
|
365 kb.SystemBindings[key1] = command
|
Nenue@19
|
366 end
|
Nenue@19
|
367 if key2 then
|
Nenue@19
|
368 kb.SystemBindings[key2] = command
|
Nenue@19
|
369 end
|
Nenue@19
|
370 end
|
Nenue@19
|
371 end
|
Nenue@19
|
372
|
Nenue@19
|
373 kb.UpdateDynamicButtons = function(dynamicType)
|
Nenue@19
|
374 for i, button in ipairs(kb.buttons) do
|
Nenue@19
|
375 if button.isDynamic == dynamicType then
|
Nenue@19
|
376 kb.UpdateSlot(button, true)
|
Nenue@19
|
377 end
|
Nenue@19
|
378 end
|
Nenue@16
|
379 end |