vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 -------------------------------------------------------------------------------
2 -- Locals --
3 -------------------------------------------------------------------------------
4  
5 local L = AceLibrary("AceLocale-2.2"):new("ClosetGnome")
6 local gratuity = AceLibrary("Gratuity-2.0")
7 local dewdrop = AceLibrary("Dewdrop-2.0")
8 local tablet = AceLibrary("Tablet-2.0")
9 local compost = AceLibrary("Compost-2.0")
10  
11 local deequipQueue = nil
12 local queuedSet = nil
13 local lastEquippedSet = nil
14 local slotLocks = nil
15 local queuedForDelete = nil
16  
17 local lua51 = nil
18 local keybindingFrame = "ClosetGnomeKeybindingFrame"
19  
20 local _G = getfenv(0)
21  
22 local slots = {
23 {slot = "Head"},
24 {slot = "Shoulder"},
25 {slot = "Chest"},
26 {slot = "Waist"},
27 {slot = "Legs"},
28 {slot = "Feet"},
29 {slot = "Wrist"},
30 {slot = "Hands"},
31 {slot = "MainHand"},
32 {slot = "SecondaryHand"},
33 {slot = "Ranged"},
34 {slot = "Ammo"},
35 {slot = "Neck"},
36 {slot = "Back"},
37 {slot = "Finger0"},
38 {slot = "Finger1"},
39 {slot = "Trinket0"},
40 {slot = "Trinket1"},
41 {slot = "Relic"},
42 }
43  
44 -------------------------------------------------------------------------------
45 -- Localization --
46 -------------------------------------------------------------------------------
47  
48 L:RegisterTranslations("enUS", function() return {
49 ["ClosetGnome"] = true,
50 ["ClosetGnome options."] = true,
51 ["Enable or disable the slots you want in this set by clicking the items in your character frame. Green slots are enabled, red are disabled. Type in the set name below, and click Add."] = true,
52 ["Add"] = true,
53 ["Creates a new set, or updates an existing one."] = true,
54 ["Wear"] = true,
55 ["Change equipment set."] = true,
56 ["Cancel"] = true,
57 ["Always equip weapons"] = true,
58 ["Equip weapons in sets even if you are in combat."] = true,
59 ["Equip %s."] = true,
60 ["Quips"] = true,
61 ["Toggle outputting random quips when equipping sets."] = true,
62 ["Delete"] = true,
63 ["Deletes the equipment set %s."] = true,
64 ["Delete a set."] = true,
65 ["Are you sure you want to delete the set %s?"] = true,
66 ["<set name>"] = true,
67 ["Couldn't find %s in your inventory."] = true,
68 ["Enter the set name to delete it."] = true,
69 ["Keybinding"] = true,
70 ["Assign a keybinding to a set."] = true,
71 ["Assign a keybinding to %s (or empty to clear)."] = true,
72 ["<key binding>"] = true,
73 ["%s is not a valid keybinding."] = true,
74 ["Registering keybinding %s to set %s."] = true,
75 ["%s is already registered to %s."] = true,
76 ["Removing keybinding %s from set %s."] = true,
77  
78 ["In combat: %s queued for swap."] = true,
79 ["Added set: %s."] = true,
80 ["Deleted set: %s."] = true,
81 ["Updating set: %s."] = true,
82 ["Please use a proper name for your set."] = true,
83  
84 ["Available sets"] = true,
85 ["Last equipped:"] = true,
86 ["Click a set above to change your equipment. Ctrl-click a set to try it on. The last equipped set is indicated by a star."] = true,
87 ["You have not created any equipment sets yet, please right-click the icon and click 'Add' to create a set."] = true,
88  
89 -- This is what a normal bag is called, as returned from GetItemInfo's
90 -- subType
91 ["Bag"] = true,
92 ["Container"] = true,
93  
94 -- Random quips when you equip a set.
95 [1] = "Your ClosetGnome rapidly dresses you up in %s before he runs off with another sock.",
96 [2] = "Once in a blue moon your ClosetGnome will equip you with an Artifact item. Not today, however, you'll have to settle for %s.",
97 [3] = "ClosetGnomes are tidy creatures. Not yours, though, as he equips %s he just piles your old outfit in the corner.",
98 [4] = "It's almost as if he dances around you while he dresses you up in %s. Although it's a very ugly dance.",
99 [5] = "Since you forgot to feed your ClosetGnome today, he expresses his anger by equipping your %s backwards.",
100 [6] = "Never let your ClosetGnome tend to other needs than %s.",
101 [7] = "%s looks good on you today, at least compared to how it looked on your ClosetGnome when you caught him wearing it.",
102 [8] = "ClosetGnome equips %s.",
103 [9] = "Your ClosetGnome flinches in disgust as he equips %s. You're not sure why, but what's that smell ...",
104 [10] = "Is that a whirlwind?! No, it's ClosetGnome dressing you in %s!",
105 [11] = "Recently returned from the ClosetGnome convention, he's got a lot to talk about while dressing you in %s.",
106 [12] = "Noone knows if ClosetGnomes party, but you do. This is how it looked last time you dressed yourself in %s after a party.",
107 [13] = "'Getting Jiggy With It' was never your favorite, but you have to admit that it fits nicely with %s.",
108 [14] = "Even though your washer is clearly labeled 'Certified by ClosetGnomes, Inc.', it's clear that %s has not been cleaned in a while.",
109 [15] = "%s has the same color socks as your last set, and the one before that, and before that.",
110 [16] = "Instead of equipping %s, your ClosetGnome starts gnawing on your leg. You shake him off and do it yourself.",
111 [17] = "Noone has ever suspected you of having a ClosetGnome. Most of them are actually good at equipping things like %s.",
112 [18] = "What kind of person are you that dresses up in %s so often? Your ClosetGnome eyes you up and down. He looks .. hungry.",
113 [19] = "Your ClosetGnome is hungry and scavenges the pockets of %s for food, but finds nothing. Do you ever feed him?",
114 [20] = "The first rule of the ClosetGnomes is that they do not talk about %s.",
115 [21] = "%s seems different somehow.",
116 [22] = "There is no %s.",
117 [23] = "You feel the need - the need for %s!",
118 [24] = "Your ClosetGnome equips %s. Shaken, not stirred.",
119 [25] = "ClosetGnome puts %s in a corner. Then comes back and equips it.",
120 [26] = "Hasta la vista, %s.",
121 [27] = "Keep your %s close, but your ClosetGnome closer.",
122 [28] = "A boy's best friend is a ClosetGnome that comes with %s.",
123 [29] = "You love the smell of %s in the morning.",
124 [30] = "May your ClosetGnome be with you. And may he bring %s.",
125 [31] = "You make your ClosetGnome an offer he can't refuse, and so he equips %s.",
126 } end)
127  
128 L:RegisterTranslations("koKR", function() return {
129 -- ["ClosetGnome"] = true,
130 ["ClosetGnome options."] = "ClosetGnome 설정.",
131 ["Enable or disable the slots you want in this set by clicking the items in your character frame. Green slots are enabled, red are disabled. Type in the set name below, and click Add."] = "이 세트에 케릭터 창의 아이템을 클릭해서 원하는 슬롯을 활성화 하거나 비활성화 합니다. 활성화 된 슬롯은 녹색, 비활성화 된 것은 붉은색입니다. 세트명을 입력하고 추가를 클릭하세요.",
132 ["Add"] = "추가",
133 ["Creates a new set."] = "새로운 세트를 생성합니다.",
134 ["Wear"] = "착용",
135 ["Change equipment set."] = "착용장비 세트를 변경합니다.",
136 ["Cancel"] = "취소",
137 ["Always equip weapons"] = "항상 무기 착용",
138 -- ["Quips"] = true,
139 -- ["Toggle outputting random quips when equipping sets."] = true,
140 ["Equip weapons in sets even if you are in combat."] = "전투중에도 세트에 속하는 무기를 착용합니다.",
141 ["Equip %s."] = "%s|1을;를; 착용합니다.",
142 ["Delete"] = "삭제",
143 ["Enter the set name to delete it."] = "삭제를 세트명을 입력하세요.",
144 ["<set name>"] = "<세트명>",
145 ["Couldn't find %s in your inventory."] = "인벤토리에서 %s|1을;를; 찾을 수 없습니다.",
146  
147 ["In combat: %s queued for swap."] = "전투중: %s|1이;가; 스왑을 위해 대기합니다.",
148 ["Added set: %s."] = "세트 추가: %s.",
149 ["Deleted set: %s."] = "세트 삭제: %s.",
150 ["Updating set: %s."] = "세트 갱신: %s.",
151  
152 ["Available sets"] = "이용가능한 세트",
153 --["Click a set above to change your equipment. Ctrl-click a set to try it on. The last equipped set is indicated by a star."] = true,
154 ["You have not created any equipment sets yet, please right-click the icon and click 'Add' to create a set."] = "아직 생성된 장비 세트가 없습니다, 아이콘을 우클릭 한 후 '추가'를 클릭해서 세트를 생성하세요.",
155  
156 -- This is what a normal bag is called, as returned from GetItemInfo's
157 -- subType
158 ["Bag"] = "가방",
159  
160 -- Random quips when you equip a set.
161 [1] = "그가 다른 신발을 신고 도망치기 전에 ClosetGnome 은 %s 세트를 신속히 착용합니다.",
162 [8] = "ClosetGnome이 %s 세트를 착용합니다.",
163 [18] = "%s 세트를 자주 입는 당신은 뭐하는 사람이에요? 당신의 ClosetGnome이 당신을 위아래로 훌터봅니다. 그는 굶주린것 같습니다...",
164 [19] = "당신의 ClosetGnome이 굶주려 %s 세트를 뒤지지만 아무것도 찾지 못했습니다. 그에게 먹을것 좀 주시겠습니까?",
165 } end)
166  
167 L:RegisterTranslations("deDE", function() return {
168 ["ClosetGnome options."] = "ClosetGnome Optionen",
169 ["Enable or disable the slots you want in this set by clicking the items in your character frame. Green slots are enabled, red are disabled. Type in the set name below, and click Add."] = "Aktiviere und deaktiviere die einzelnen Slots f\195\188r dieses Set durch klicken im Charakterbildschirm. Gr\195\188n bedeutet aktiviert, rot deaktiviert. Gebe einen Namen f\195\188r das set ein und dr\195\188cke Hinzuf\195\188gen",
170 ["Add"] = "Hinzuf\195\188gen",
171 ["Creates a new set, or updates an existing one."] = "Legt ein neues Set an, oder aktualisiert ein bestehendes.",
172 ["Wear"] = "Anziehen",
173 ["Change equipment set."] = "Wechsle Set",
174 ["Cancel"] = "Abbrechen",
175 ["Always equip weapons"] = "Waffen immer anlegen",
176 -- ["Quips"] = true,
177 -- ["Toggle outputting random quips when equipping sets."] = true,
178 ["Equip weapons in sets even if you are in combat."] = "Waffen schon im Kampf wechseln",
179 ["Equip %s."] = "Trage %s",
180 ["Delete"] = "L\195\182schen",
181 ["Enter the set name to delete it."] = "Gib den Namen des zu l\195\182schemdem Sets ein",
182 ["<set name>"] = "<Name des Sets>",
183 ["Couldn't find %s in your inventory."] = "Konnte %s nicht im Inventar finden",
184  
185 ["In combat: %s queued for swap."] = "Kampf: %s in der Warteschlange",
186 ["Added set: %s."] = "Set hinzugef\195\188gt: %s",
187 ["Deleted set: %s."] = "Set gel\195\182scht: %s",
188 ["Updating set: %s."] = "Set upgedatet: %s",
189  
190 ["Last equipped:"] = "Zuletzt angelegt:",
191 ["Available sets"] = "Verf\195\188gbare Sets:",
192 --["Click a set above to change your equipment. Ctrl-click a set to try it on. The last equipped set is indicated by a star."] = true,
193 ["You have not created any equipment sets yet, please right-click the icon and click 'Add' to create a set."] = "Es wurden noch keine Ausr\195\188stungssets erstellt, Klicke mit der rechten Maustaste auf das Icon, dann 'Hinzuf\195\188gen' um ein Set zu erstellen",
194  
195 -- This is what a normal bag is called, as returned from GetItemInfo's
196 -- subType
197 ["Bag"] = "Beh\195\164lter",
198 } end)
199  
200 L:RegisterTranslations("zhCN", function() return {
201 ["ClosetGnome"] = "ClosetGnome",
202 ["ClosetGnome options."] = "ClosetGnome 设置.",
203 ["Enable or disable the slots you want in this set by clicking the items in your character frame. Green slots are enabled, red are disabled. Type in the set name below, and click Add."] = "在人物装备框架上点击物品, 可决定在套装设置中是否使用此槽. 绿色框为使用, 红色框为忽略. 如果你想在换装时使一个槽为空.那么在创建设置时就要先移出此槽的物品,并确定此槽框体为绿色. 按住CTRL并点击装备, 则为使用该物品的图标作为套装设置的图标. 选好后在下面栏内输入设置名, 并点击添加. ",
204 ["Add"] = "添加",
205 ["Creates a new set, or updates an existing one."] = "创建新设置, 或更新一个现有的设置",
206 ["Wear"] = "穿上",
207 ["Change equipment set."] = "换装",
208 ["Cancel"] = "取消",
209 ["Always equip weapons"] = "一直装备武器",
210 ["Equip weapons in sets even if you are in combat."] = "进入战斗状态时, 仍使用套装设置中的武器",
211 ["Equip %s."] = "装备 %s.",
212 ["Quips"] = "讽剌",
213 ["Toggle outputting random quips when equipping sets."] = "当使用装备设定时, 随机说出讽剌的话. ",
214 ["Delete"] = "删除",
215 ["Deletes the equipment set %s."] = "删除装备设置 %s",
216 ["Delete a set."] = "删除一个设置",
217 ["Are you sure you want to delete the set %s?"] = "你确定想删除设置 %s 吗?",
218 ["<set name>"] = "<设置名称>",
219 ["Couldn't find %s in your inventory."] = "在你的物品中无法找到 %s.",
220 ["Enter the set name to delete it."] = "输入设置名称以删除它",
221 ["Keybinding"] = "按键捆绑",
222 ["Assign a keybinding to a set."] = "给设定分配一个按键绑定",
223 ["Assign a keybinding to %s (or empty to clear)."] = "分配一个按键绑定给 %s (或清空).",
224 ["<key binding>"] = "<按钮绑定>",
225 ["%s is not a valid keybinding."] = "%s 是一个无效的按键绑定",
226 ["Registering keybinding %s to set %s."] = "寄存按键绑定 %s 给设置 %s",
227 ["%s is already registered to %s."] = "%s 已经注册给 %s ",
228 ["Removing keybinding %s from set %s."] = "从设置 %s 中移除按键绑定 %s",
229  
230 ["In combat: %s queued for swap."] = "进入战斗: %s 交换队列.",
231 ["Added set: %s."] = "添加设置: %s.",
232 ["Deleted set: %s."] = "删除设置: %s.",
233 ["Updating set: %s."] = "更新设置: %s.",
234 ["Please use a proper name for your set."] = "请为你的设置使用正确的名字",
235  
236 ["Available sets"] = "可用套装",
237 ["Last equipped:"] = "最后装备的套装",
238 ["Click a set above to change your equipment. Ctrl-click a set to try it on. The last equipped set is indicated by a star."] = "在一个设置上点击以更换你的装备. 按住Ctrl并点击一个设置尝试打开它. 最后一次使用的套装用星号表示",
239 ["You have not created any equipment sets yet, please right-click the icon and click 'Add' to create a set."] = "你仍未创建任何装备设置, 请用右键点击图标, 并点击 '添加' 创建设置.",
240  
241 -- This is what a normal bag is called, as returned from GetItemInfo's
242 -- subType
243 ["Bag"] = "背包",
244  
245 -- 当你配备一个设置时, 随机说出讽剌的话.
246 [1] = "Your ClosetGnome rapidly dresses you up in %s before he runs off with another sock.",
247 [2] = "Once in a blue moon your ClosetGnome will equip you with an Artifact item. Not today, however, you'll have to settle for %s.",
248 [3] = "ClosetGnomes are tidy creatures. Not yours, though, as he equips %s he just piles your old outfit in the corner.",
249 [4] = "It's almost as if he dances around you while he dresses you up in %s. Although it's a very ugly dance.",
250 [5] = "Since you forgot to feed your ClosetGnome today, he expresses his anger by equipping your %s backwards.",
251 [6] = "Never let your ClosetGnome tend to other needs than %s.",
252 [7] = "%s looks good on you today, at least compared to how it looked on your ClosetGnome when you caught him wearing it.",
253 [8] = "ClosetGnome equips %s.",
254 [9] = "Your ClosetGnome flinches in disgust as he equips %s. You're not sure why, but what's that smell ...",
255 [10] = "Is that a whirlwind?! No, it's ClosetGnome dressing you in %s!",
256 [11] = "Recently returned from the ClosetGnome convention, he's got a lot to talk about while dressing you in %s.",
257 [12] = "Noone knows if ClosetGnomes party, but you do. This is how it looked last time you dressed yourself in %s after a party.",
258 [13] = "'Getting Jiggy With It' was never your favorite, but you have to admit that it fits nicely with %s.",
259 [14] = "Even though your washer is clearly labeled 'Certified by ClosetGnomes, Inc.', it's clear that %s has not been cleaned in a while.",
260 [15] = "%s has the same color socks as your last set, and the one before that, and before that.",
261 [16] = "Instead of equipping %s, your ClosetGnome starts gnawing on your leg. You shake him off and do it yourself.",
262 [17] = "Noone has ever suspected you of having a ClosetGnome. Most of them are actually good at equipping things like %s.",
263 [18] = "What kind of person are you that dresses up in %s so often? Your ClosetGnome eyes you up and down. He looks .. hungry.",
264 [19] = "Your ClosetGnome is hungry and scavenges the pockets of %s for food, but finds nothing. Do you ever feed him?",
265 [20] = "The first rule of the ClosetGnomes is that they do not talk about %s.",
266 [21] = "%s seems different somehow.",
267 [22] = "There is no %s.",
268 [23] = "You feel the need - the need for %s!",
269 [24] = "Your ClosetGnome equips %s. Shaken, not stirred.",
270 [25] = "ClosetGnome puts %s in a corner. Then comes back and equips it.",
271 [26] = "Hasta la vista, %s.",
272 [27] = "Keep your %s close, but your ClosetGnome closer.",
273 [28] = "A boy's best friend is a ClosetGnome that comes with %s.",
274 [29] = "You love the smell of %s in the morning.",
275 [30] = "May your ClosetGnome be with you. And may he bring %s.",
276 [31] = "You make your ClosetGnome an offer he can't refuse, and so he equips %s.",
277 } end)
278  
279 -------------------------------------------------------------------------------
280 -- Addon declaration --
281 -------------------------------------------------------------------------------
282  
283 ClosetGnome = AceLibrary("AceAddon-2.0"):new("AceHook-2.1", "AceConsole-2.0", "AceDB-2.0", "AceEvent-2.0", "FuBarPlugin-2.0")
284 ClosetGnome:RegisterDB("ClosetGnomeDB", "ClosetGnomePerCharDB")
285 ClosetGnome:RegisterDefaults("profile", {
286 quips = true,
287 })
288 ClosetGnome:RegisterDefaults("char", {
289 set = {},
290 icons = {},
291 keybindings = {},
292 alwaysWeapons = true,
293 })
294 ClosetGnome.OnMenuRequest = {
295 type = "group",
296 name = L["ClosetGnome"],
297 desc = L["ClosetGnome options."],
298 args = {
299 add = {
300 type = "execute",
301 name = L["Add"],
302 desc = L["Creates a new set, or updates an existing one."],
303 func = function() ClosetGnome:CreateSet() end,
304 order = 101,
305 },
306 wear = {
307 type = "group",
308 name = L["Wear"],
309 desc = L["Change equipment set."],
310 args = {},
311 order = 102,
312 disabled = function() return next(ClosetGnome.OnMenuRequest.args.wear.args) == nil end
313 },
314 key = {
315 type = "group",
316 name = L["Keybinding"],
317 desc = L["Assign a keybinding to a set."],
318 args = {},
319 order = 103,
320 hidden = function() return not lua51 end,
321 disabled = function() return next(ClosetGnome.OnMenuRequest.args.wear.args) == nil end
322 },
323 spacer = { type = "header", order = 104 },
324 alwaysweapons = {
325 type = "toggle",
326 name = L["Always equip weapons"],
327 desc = L["Equip weapons in sets even if you are in combat."],
328 get = function() return ClosetGnome.db.char.alwaysWeapons end,
329 set = function(v) ClosetGnome.db.char.alwaysWeapons = v end,
330 order = 105,
331 },
332 quips = {
333 type = "toggle",
334 name = L["Quips"],
335 desc = L["Toggle outputting random quips when equipping sets."],
336 get = function() return ClosetGnome.db.profile.quips end,
337 set = function(v) ClosetGnome.db.profile.quips = v end,
338 order = 106,
339 },
340 delete = {
341 type = "group",
342 name = L["Delete"],
343 desc = L["Delete a set."],
344 args = {},
345 order = 107,
346 disabled = function() return next(ClosetGnome.OnMenuRequest.args.wear.args) == nil end
347 },
348 },
349 }
350 ClosetGnome:RegisterChatCommand({"/closetgnome", "/cg"}, ClosetGnome.OnMenuRequest, "CLOSETGNOME")
351  
352 -- FuBar stuff.
353 ClosetGnome.hideWithoutStandby = true
354 local defaultIcon = "Interface\\Icons\\INV_Chest_Cloth_17"
355 ClosetGnome.hasIcon = defaultIcon
356 ClosetGnome.hasNoColor = true
357 ClosetGnome.defaultMinimapPosition = 240
358 ClosetGnome.clickableTooltip = true
359  
360 -------------------------------------------------------------------------------
361 -- Initialization --
362 -------------------------------------------------------------------------------
363  
364 function ClosetGnome:OnInitialize()
365 if not StaticPopupDialogs then
366 StaticPopupDialogs = {}
367 end
368 StaticPopupDialogs["ClosetGnomeAdd"] = {
369 text = L["Enable or disable the slots you want in this set by clicking the items in your character frame. Green slots are enabled, red are disabled. Type in the set name below, and click Add."],
370 button1 = L["Add"],
371 button2 = L["Cancel"],
372 OnCancel = function() self:CancelCreateSet() end,
373 sound = "levelup2",
374 whileDead = 1,
375 hideOnEscape = 1,
376 timeout = 0,
377 OnShow = function()
378 -- We have to do this onshow to reset the previous text
379 getglobal(this:GetName().."EditBox"):SetText("")
380 end,
381 OnAccept = function()
382 local name = getglobal(this:GetParent():GetName().."EditBox"):GetText()
383 self:AddSetFromDoll(name)
384 end,
385 hasEditBox = 1,
386 }
387 StaticPopupDialogs["ClosetGnomeDelete"] = {
388 text = L["Are you sure you want to delete the set %s?"],
389 button1 = L["Delete"],
390 button2 = L["Cancel"],
391 showAlert = 1,
392 timeout = 0,
393 OnAccept = function() self:DeleteSet(queuedForDelete, true) end,
394 OnCancel = function() queuedForDelete = nil end,
395 }
396 end
397  
398 function ClosetGnome:OnEnable()
399 -- Temporary table for which slots to use when adding a new set.
400 self.activeSlots = compost:Acquire()
401  
402 -- If we're in TBC, create the button frames for keybindings
403 if lua51 == nil then lua51 = loadstring("return function(...) return ... end") and true or false end
404 if lua51 and _G["UIParent"] ~= nil and SetBindingClick then
405 for k, v in pairs(self.db.char.keybindings) do
406 if v then
407 self:RegisterBinding(v, k)
408 end
409 end
410 end
411  
412 self:RegisterEvent("AceEvent_FullyInitialized")
413  
414 self:UpdateSetMenu()
415 end
416  
417 function ClosetGnome:OnDisable()
418 compost:Reclaim(self.activeSlots)
419 self.activeSlots = nil
420 if slotLocks then
421 compost:Reclaim(slotLocks, 1)
422 slotLocks = nil
423 end
424  
425 if lua51 then
426 for k, v in pairs(self.db.char.keybindings) do
427 self:UnsetBinding(k)
428 end
429 end
430 end
431  
432  
433 -------------------------------------------------------------------------------
434 -- Keybindings --
435 -------------------------------------------------------------------------------
436  
437 local validKeys = nil
438 function ClosetGnome:ValidateBinding(combo)
439 local a, b, modifier, key = string.find(combo, "(%u+)\-([%u%d]+)")
440 if not a or not b or not modifier or not key then return false end
441 if modifier ~= "CTRL" and modifier ~= "ALT" and modifier ~= "SHIFT" then return false end
442 return string.len(key) == 1 or (string.len(key) == 2 and string.find(key, "F%d")) or key == "DELETE" or key == "INSERT"
443 end
444  
445 function ClosetGnome:RegisterBinding(combo, set)
446 if not lua51 or not combo or not set then return end
447  
448 if not self:ValidateBinding(combo) then
449 self:Print(string.format(L["%s is not a valid keybinding."], "|cffd9d919"..combo.."|r"))
450 return
451 end
452  
453 local shouldPrint = true
454 for k, v in pairs(self.db.char.keybindings) do
455 if v == combo then
456 shouldPrint = nil
457 elseif k == set then
458 self:UnsetBinding(set)
459 end
460 end
461  
462 if shouldPrint then
463 self:Print(string.format(L["Registering keybinding %s to set %s."], "|cffd9d919"..combo.."|r", "|cffd9d919"..set.."|r"))
464 end
465  
466 local comboCopy = combo
467 local setCopy = set
468 local frame = _G[keybindingFrame..comboCopy] or CreateFrame("Button", keybindingFrame..comboCopy, _G["UIParent"])
469 frame:SetScript("OnMouseUp", function() ClosetGnome:KeybindingClicked(comboCopy, setCopy) end)
470 self.db.char.keybindings[setCopy] = comboCopy
471 SetBindingClick(comboCopy, keybindingFrame..comboCopy)
472 end
473  
474 function ClosetGnome:UnsetBinding(set)
475 if not lua51 or not set or not self.db.char.keybindings[set] then return end
476 local combo = self.db.char.keybindings[set]
477  
478 local frame = _G[keybindingFrame..combo]
479 if frame then
480 frame:SetScript("OnMouseUp", nil)
481 frame = nil
482 end
483  
484 SetBinding(combo) -- Unset the binding.
485 end
486  
487 function ClosetGnome:ClearBinding(set)
488 if not lua51 or not set or not self.db.char.keybindings[set] then return end
489  
490 self:UnsetBinding(set)
491  
492 local combo = self.db.char.keybindings[set]
493 self:Print(string.format(L["Removing keybinding %s from set %s."], "|cffd9d919"..combo.."|r", "|cffd9d919"..set.."|r"))
494 self.db.char.keybindings[set] = nil
495 end
496  
497 function ClosetGnome:KeybindingClicked(combo, set)
498 if not lua51 or not set or not self:ValidateBinding(combo) then return end
499 self:WearSet(set)
500 end
501  
502 -------------------------------------------------------------------------------
503 -- Menu --
504 -------------------------------------------------------------------------------
505  
506 function ClosetGnome:UpdateSetMenu()
507 compost:Reclaim(self.OnMenuRequest.args.wear.args, 1)
508 self.OnMenuRequest.args.wear.args = compost:Acquire()
509 for k, v in pairs(self.db.char.set) do
510 if not self:HideSetFromUI(k) then
511 local set = k
512 local menuKey = string.gsub(k, " ", "")
513 self.OnMenuRequest.args.wear.args[menuKey] = compost:Acquire()
514 self.OnMenuRequest.args.wear.args[menuKey].type = "execute"
515 self.OnMenuRequest.args.wear.args[menuKey].name = set
516 self.OnMenuRequest.args.wear.args[menuKey].desc = string.format(L["Equip %s."], set)
517 self.OnMenuRequest.args.wear.args[menuKey].func = function() ClosetGnome:WearSet(set) end
518 if self.db.char.icons[set] then
519 self.OnMenuRequest.args.wear.args[menuKey].icon = self.db.char.icons[set]
520 end
521 end
522 end
523  
524 compost:Reclaim(self.OnMenuRequest.args.delete.args, 1)
525 self.OnMenuRequest.args.delete.args = compost:Acquire()
526 for k, v in pairs(self.db.char.set) do
527 local set = k
528 local menuKey = string.gsub(k, " ", "")
529 self.OnMenuRequest.args.delete.args[menuKey] = compost:Acquire()
530 self.OnMenuRequest.args.delete.args[menuKey].type = "execute"
531 self.OnMenuRequest.args.delete.args[menuKey].name = set
532 self.OnMenuRequest.args.delete.args[menuKey].desc = string.format(L["Deletes the equipment set %s."], set)
533 self.OnMenuRequest.args.delete.args[menuKey].func = function() ClosetGnome:DeleteSet(set, false) end
534 if self.db.char.icons[set] then
535 self.OnMenuRequest.args.delete.args[menuKey].icon = self.db.char.icons[set]
536 end
537 end
538  
539 if lua51 then
540 compost:Reclaim(self.OnMenuRequest.args.key.args, 1)
541 self.OnMenuRequest.args.key.args = compost:Acquire()
542 for k, v in pairs(self.db.char.set) do
543 local set = k
544 local menuKey = string.gsub(k, " ", "")
545 self.OnMenuRequest.args.key.args[menuKey] = compost:Acquire()
546 self.OnMenuRequest.args.key.args[menuKey].type = "text"
547 self.OnMenuRequest.args.key.args[menuKey].name = set
548 self.OnMenuRequest.args.key.args[menuKey].desc = string.format(L["Assign a keybinding to %s (or empty to clear)."], set)
549 self.OnMenuRequest.args.key.args[menuKey].usage = L["<key binding>"]
550 self.OnMenuRequest.args.key.args[menuKey].validate = function(input)
551 return ClosetGnome:ValidateBinding(input) or input == ""
552 end
553 self.OnMenuRequest.args.key.args[menuKey].get = function()
554 return ClosetGnome.db.char.keybindings[set]
555 end
556 self.OnMenuRequest.args.key.args[menuKey].set = function(v)
557 if v == "" then
558 ClosetGnome:ClearBinding(set)
559 else
560 ClosetGnome:RegisterBinding(v, set)
561 end
562 end
563 if self.db.char.icons[set] then
564 self.OnMenuRequest.args.key.args[menuKey].icon = self.db.char.icons[set]
565 end
566 end
567 end
568 end
569  
570 -------------------------------------------------------------------------------
571 -- Addon methods --
572 -------------------------------------------------------------------------------
573  
574 -- Opens the character frame and lets the user uncheck the items he doesn't
575 -- want.
576 function ClosetGnome:CreateSet()
577 self.activeSlots = compost:Acquire()
578 for _, item in ipairs(slots) do
579 local gslot = _G["Character" .. item.slot .. "Slot"]
580 if not item.frame and not item.texture and gslot then
581 -- We used to just :GetScript("OnClick") on the existing slot,
582 -- and save that so that we could override it and put it back
583 -- after we close the character frame, but this is not possible
584 -- in TBC with the protected code stuff. WoW will complain that
585 -- the script is tainted, and the normal slots won't work again
586 -- after adding a set, so we create our own frame that we set on
587 -- top of the existing one now.
588 local button = CreateFrame("Button", gslot:GetName() .. "ClosetGnome", gslot)
589 button:SetAlpha(0)
590 button:SetHeight(gslot:GetHeight())
591 button:SetWidth(gslot:GetWidth())
592 button:SetPoint("CENTER", gslot, "CENTER", 0, 1)
593 button:Hide()
594  
595 local texture = gslot:CreateTexture(gslot:GetName() .. "Texture", "OVERLAY")
596 texture:SetTexture("Interface\\Buttons\\UI-ActionButton-Border")
597 texture:SetVertexColor(0, 255, 0)
598 texture:SetBlendMode("ADD")
599 texture:SetAlpha(0.75)
600 texture:SetHeight(68)
601 texture:SetWidth(68)
602 texture:SetPoint("CENTER", gslot, "CENTER", 0, 1)
603 texture:Hide()
604  
605 item.frame = button
606 item.texture = texture
607 end
608 if item.frame and item.texture and gslot then
609 item.frame:EnableMouse(true)
610 item.frame:Show()
611 item.texture:SetVertexColor(0, 255, 0)
612 item.texture:Show()
613 self.activeSlots[gslot:GetName()] = true
614 item.frame:SetScript("OnEnter", function()
615 -- Horrible hack? :(
616 if PaperDollItemSlotButton_OnEnter and type(PaperDollItemSlotButton_OnEnter) == "function" then
617 this = getglobal(string.gsub(this:GetName(), "ClosetGnome", ""))
618 PaperDollItemSlotButton_OnEnter()
619 end
620 end)
621 item.frame:SetScript("OnClick", function()
622 local slot = string.gsub(this:GetName(), "ClosetGnome", "")
623 if IsControlKeyDown() then
624 -- Don't want an empty slot as icon.
625 local id = GetInventorySlotInfo(string.sub(slot, 10))
626 local currentItem = ClosetGnome:ItemNameFromSlot(id)
627 if currentItem == false then return end
628 if ClosetGnome.activeSlots["icon"] then
629 local oldSlot = ClosetGnome.activeSlots["icon"]
630 ClosetGnome.activeSlots[oldSlot] = true
631 getglobal(oldSlot.."Texture"):SetVertexColor(0, 255, 0)
632 end
633 ClosetGnome.activeSlots["icon"] = slot
634 ClosetGnome.activeSlots[slot] = true
635 getglobal(slot.."Texture"):SetVertexColor(0, 0, 255)
636 else
637 ClosetGnome.activeSlots[slot] = not ClosetGnome.activeSlots[slot]
638 if ClosetGnome.activeSlots[slot] then
639 if ClosetGnome.activeSlots["icon"] == slot then
640 getglobal(slot.."Texture"):SetVertexColor(0, 0, 255)
641 else
642 getglobal(slot.."Texture"):SetVertexColor(0, 255, 0)
643 end
644 else
645 getglobal(slot.."Texture"):SetVertexColor(255, 0, 0)
646 end
647 end
648 end)
649 end
650 end
651  
652 -- Hook Fizzle to prevent it from styling the slots while we add a set.
653 if IsAddOnLoaded("Fizzle") and Fizzle and type(Fizzle) == "table" and type(Fizzle.UpdateItems) == "function" then
654 self:Hook(Fizzle, "UpdateItems", "Noop")
655 end
656  
657 ShowUIPanel(CharacterFrame)
658 CharacterFrame_ShowSubFrame("PaperDollFrame")
659 OpenAllBags(1)
660 self:Hook("CharacterFrame_OnHide", true)
661 self:Hook("CharacterFrameTab_OnClick", "Noop", true)
662 if lua51 then
663 self:Hook("PaperDollItemSlotButton_OnModifiedClick", "Noop", true)
664 end
665  
666 dewdrop:Close()
667 StaticPopup_Show("ClosetGnomeAdd")
668 end
669  
670 function ClosetGnome:CancelCreateSet()
671 CloseAllBags()
672 HideUIPanel(CharacterFrame)
673 if self:IsHooked("CharacterFrame_OnHide") then
674 self:Unhook("CharacterFrame_OnHide")
675 end
676 if Fizzle and self:IsHooked(Fizzle, "UpdateItems") then
677 self:Unhook(Fizzle, "UpdateItems")
678 end
679 if lua51 and self:IsHooked("PaperDollItemSlotButton_OnModifiedClick") then
680 self:Unhook("PaperDollItemSlotButton_OnModifiedClick")
681 end
682 end
683  
684 function ClosetGnome:AddSetFromDoll(name)
685 local slots = compost:Acquire()
686 local icon = nil
687 for slot, active in pairs(self.activeSlots) do
688 if slot == "icon" then
689 icon = string.sub(active, 10)
690 elseif active then
691 table.insert(slots, string.sub(slot, 10))
692 end
693 end
694 self:AddSet(name, slots, icon)
695 compost:Reclaim(slots)
696 slots = nil
697 icon = nil
698  
699 HideUIPanel(CharacterFrame)
700 self:CharacterFrame_OnHide()
701 end
702  
703 function ClosetGnome:AddSet(name, activeSlots, iconSlot)
704 local concatedName = string.gsub(name, " ", "")
705 if not name or name == "" or concatedName == "" then
706 self:Print(L["Please use a proper name for your set."])
707 return
708 end
709 if self:HasSet(concatedName) then name = concatedName end
710  
711 local text = string.format(L["Added set: %s."], name)
712 local event = "ClosetGnome_AddSet"
713 if self:HasSet(name) then
714 text = string.format(L["Updating set: %s."], name)
715 event = "ClosetGnome_UpdateSet"
716 end
717  
718 for i, slot in pairs(activeSlots) do
719 local id = GetInventorySlotInfo(slot)
720 if not id then error(string.format("The given slot %q does not exist.", slot)) end
721 local currentItem = self:ItemNameFromSlot(id)
722 if not self.db.char.set[name] then self.db.char.set[name] = {} end
723 self.db.char.set[name][id] = currentItem
724 end
725  
726 if iconSlot then
727 local slotId = GetInventorySlotInfo(iconSlot)
728 if not slotId then error(string.format("The given icon slot %q does not exist.", iconSlot)) end
729 self.db.char.icons[name] = GetInventoryItemTexture("player", slotId)
730 end
731  
732 lastEquippedSet = name
733 self:TriggerEvent(event, name)
734 self:Print(text)
735  
736 self:UpdateSetMenu()
737 self:UpdateDisplay()
738 end
739  
740 function ClosetGnome:DeleteSet(name, verified)
741 if not verified then
742 queuedForDelete = name
743 StaticPopup_Show("ClosetGnomeDelete", name)
744 return
745 end
746  
747 queuedForDelete = nil
748 if self.db.char.set[name] then
749 for i in pairs(self.db.char.set[name]) do
750 self.db.char.set[name][i] = nil
751 end
752 self.db.char.set[name] = nil
753 self.db.char.icons[name] = nil
754 self:ClearBinding(name)
755  
756 if lastEquippedSet == name then
757 lastEquippedSet = nil
758 end
759  
760 self:TriggerEvent("ClosetGnome_DeleteSet", name)
761 self:Print(string.format(L["Deleted set: %s."], name))
762 self:UpdateSetMenu()
763 self:UpdateDisplay()
764  
765 dewdrop:Close()
766 end
767 end
768  
769 function ClosetGnome:WearSet(name)
770 if CursorHasItem() then return end
771  
772 local set = self.db.char.set[name]
773 if not set then return end
774  
775 dewdrop:Close()
776  
777 if self:IsSetFullyEquipped(name) then
778 lastEquippedSet = name
779 return
780 end
781  
782 if UnitAffectingCombat("player") then
783 if self.db.char.alwaysWeapons then
784 if deequipQueue then
785 compost:Reclaim(deequipQueue)
786 deequipQueue = nil
787 end
788 for slot, item in pairs(set) do
789 if slot == 16 or slot == 17 or slot == 18 then
790 local currentItem = self:ItemNameFromSlot(slot)
791 if item ~= currentItem then
792 self:EquipItem(slot, item)
793 end
794 end
795 end
796 self:ProcessDeequipQueue()
797 lastEquippedSet = name
798 self:UpdateDisplay()
799 end
800  
801 if self:IsSetFullyEquipped(name) then
802 self:TriggerEvent("ClosetGnome_WearSet", name)
803 return
804 end
805  
806 self:TriggerEvent("ClosetGnome_PartlyWearSet", name)
807 if not self:IsEventRegistered("PLAYER_REGEN_ENABLED") then
808 self:RegisterEvent("PLAYER_REGEN_ENABLED")
809 end
810 self:Print(string.format(L["In combat: %s queued for swap."], name))
811 queuedSet = name
812 return
813 end
814  
815 if self:IsEventRegistered("PLAYER_REGEN_ENABLED") then
816 self:UnregisterEvent("PLAYER_REGEN_ENABLED")
817 end
818  
819 queuedSet = nil
820  
821 if self.db.profile.quips then
822 -- I don't want the addon name in front for this one.
823 -- Thanks to MrPlow for the color :)
824 DEFAULT_CHAT_FRAME:AddMessage(self:GetQuip(name))
825 end
826  
827 if deequipQueue then
828 compost:Reclaim(deequipQueue)
829 deequipQueue = nil
830 end
831 for slot, item in pairs(set) do
832 local currentItem = self:ItemNameFromSlot(slot)
833 if item ~= currentItem then
834 self:EquipItem(slot, item)
835 end
836 end
837 self:ProcessDeequipQueue()
838 lastEquippedSet = name
839 self:TriggerEvent("ClosetGnome_WearSet", name)
840  
841 self:UpdateDisplay()
842 end
843  
844 -- fizzle
845  
846 -------------------------------------------------------------------------------
847 -- Utility --
848 -------------------------------------------------------------------------------
849  
850 function ClosetGnome:GetQuip(input)
851 local rand = 1
852 repeat rand = math.random(1, 31) until L[rand] ~= nil
853 return "|cffeda55f"..string.format(L[rand], "|cffd9d919"..input.."|cffeda55f").."|r"
854 end
855  
856 function ClosetGnome:ItemNameFromSlot(slot)
857 assert(slot, "Slot must be non-nil.")
858 local slotId = tonumber(slot)
859 if not slotId then slotId = GetInventorySlotInfo(slot) end
860 if not slotId then error(string.format("Unknown inventory slot %q.", slot)) end
861 local hasItem = gratuity:SetInventoryItem("player", slotId)
862 if not hasItem then return false end
863 local currentItem = gratuity:GetLine(1)
864 if not currentItem then currentItem = false end
865 return currentItem
866 end
867  
868 function ClosetGnome:IsSetFullyEquipped(name)
869 local set = self.db.char.set[name]
870 if not set or not name then return false end
871 for slot, item in pairs(set) do
872 local currentItem = self:ItemNameFromSlot(slot)
873 if item ~= currentItem then
874 return false
875 end
876 end
877 return true
878 end
879  
880 function ClosetGnome:IsNormalBag(bagId)
881 if bagId == 0 or bagId == -1 then return true end
882 local _, _, linkId = string.find(GetInventoryItemLink("player", ContainerIDToInventoryID(bagId)), "item:(%d+)")
883 if not linkId then return false end
884 local _, _, _, _, _, bagType = GetItemInfo(linkId)
885 if bagType and (bagType == L["Bag"] or bagType == L["Container"]) then return true end
886 return false
887 end
888  
889 function ClosetGnome:LocateFreeSlot()
890 for theBag = NUM_BAG_FRAMES, 0, -1 do
891 if self:IsNormalBag(theBag) then
892 if not slotLocks then slotLocks = compost:Acquire() end
893 if not slotLocks[theBag] then slotLocks[theBag] = compost:Acquire() end
894 local numSlot = GetContainerNumSlots(theBag)
895 for theSlot = 1, numSlot, 1 do
896 if not slotLocks[theBag][theSlot] then
897 local texture = GetContainerItemInfo(theBag, theSlot)
898 if not texture then
899 return theBag, theSlot
900 end
901 end
902 end
903 end
904 end
905 return nil
906 end
907  
908 function ClosetGnome:ProcessDeequipQueue()
909 if not deequipQueue then return end
910 if not slotLocks then slotLocks = compost:Acquire() end
911 for i, slot in pairs(deequipQueue) do
912 PickupInventoryItem(slot)
913 local toBag, toSlot = self:LocateFreeSlot()
914 if toBag ~= nil then
915 slotLocks[toBag][toSlot] = true
916 PickupContainerItem(toBag, toSlot)
917 else
918 AutoEquipCursorItem()
919 break
920 end
921 end
922 compost:Reclaim(deequipQueue)
923 deequipQueue = nil
924 if slotLocks then
925 compost:Reclaim(slotLocks, 1)
926 slotLocks = nil
927 end
928 end
929  
930 function ClosetGnome:EquipItem(slot, item, secondTry)
931 if item == false then
932 -- We need to find a free slot in the inventory for this item.
933 -- If there's anything in the slot.
934 local hasItem = self:ItemNameFromSlot(slot)
935 if hasItem ~= false then
936 if not deequipQueue then deequipQueue = compost:Acquire() end
937 table.insert(deequipQueue, slot)
938 end
939 else
940 local bagNum, slotNum = self:FindItem(item)
941 if bagNum > -1 then
942 PickupContainerItem(bagNum, slotNum)
943 if slot < 11 or slot == 15 or slot == 19 then
944 AutoEquipCursorItem()
945 else
946 EquipCursorItem(slot)
947 end
948 else
949 if not secondTry then
950 self:ScheduleEvent("cg"..slot..item, self.EquipItem, 0.1, self, slot, item, true)
951 else
952 self:Print(string.format(L["Couldn't find %s in your inventory."], item))
953 end
954 end
955 end
956 end
957  
958 function ClosetGnome:HasSet(name)
959 return self.db.char.set[name] ~= nil
960 end
961  
962 function ClosetGnome:FindItem(item)
963 for i = NUM_BAG_FRAMES, 0, -1 do
964 for j = GetContainerNumSlots(i), 1, -1 do
965 local _, _, locked = GetContainerItemInfo(i, j)
966 if not locked then
967 gratuity:SetBagItem(i, j)
968 local bagItem = gratuity:GetLine(1)
969 if bagItem == item then return i, j end
970 end
971 end
972 end
973 return -1
974 end
975  
976 -------------------------------------------------------------------------------
977 -- Hooks --
978 -------------------------------------------------------------------------------
979  
980 -- Only hooked if we are showing the paper doll frame with set adding
981 function ClosetGnome:CharacterFrame_OnHide()
982 for _, item in ipairs(slots) do
983 if item.frame then
984 item.frame:EnableMouse(false)
985 item.frame:SetScript("OnEnter", nil)
986 item.frame:SetScript("OnClick", nil)
987 item.frame:Hide()
988 item.texture:Hide()
989 end
990 end
991  
992 StaticPopup_Hide("ClosetGnomeAdd")
993 if self:IsHooked("CharacterFrame_OnHide") then
994 self:Unhook("CharacterFrame_OnHide")
995 end
996 if self:IsHooked("CharacterFrameTab_OnClick") then
997 self:Unhook("CharacterFrameTab_OnClick")
998 end
999 if Fizzle and self:IsHooked(Fizzle, "UpdateItems") then
1000 self:Unhook(Fizzle, "UpdateItems")
1001 end
1002 if lua51 and self:IsHooked("PaperDollItemSlotButton_OnModifiedClick") then
1003 self:Unhook("PaperDollItemSlotButton_OnModifiedClick")
1004 end
1005 end
1006  
1007 function ClosetGnome:Noop() --[[ noop ]] end
1008  
1009 -------------------------------------------------------------------------------
1010 -- Events --
1011 -------------------------------------------------------------------------------
1012  
1013 function ClosetGnome:AceEvent_FullyInitialized()
1014 -- Loop through the current sets and check if we have any of them equipped.
1015 for k,v in pairs(self.db.char.set) do
1016 if self:IsSetFullyEquipped(k) then
1017 lastEquippedSet = k
1018 self:TriggerEvent("ClosetGnome_WearSet", k)
1019 break
1020 end
1021 end
1022 self:UpdateDisplay()
1023  
1024 self:Print("|cff00ff00ClosetGnome still has 1 or 2 issues that has to be resolved before release, but I consider it usable. Please direct any comments to me on IRC or to the forum post.|r")
1025 end
1026  
1027 function ClosetGnome:PLAYER_REGEN_ENABLED()
1028 if not queuedSet then return end
1029 self:WearSet(queuedSet)
1030 end
1031  
1032 -------------------------------------------------------------------------------
1033 -- FuBarPlugin --
1034 -------------------------------------------------------------------------------
1035  
1036 function ClosetGnome:OnTextUpdate()
1037 if lastEquippedSet then
1038 self:SetText(lastEquippedSet)
1039 else
1040 self:SetText(L["ClosetGnome"])
1041 end
1042 if self.db.char.icons[lastEquippedSet] then
1043 self:SetIcon(self.db.char.icons[lastEquippedSet])
1044 else
1045 self:SetIcon(defaultIcon)
1046 end
1047 end
1048  
1049 function ClosetGnome:OnDoubleClick()
1050 self:CreateSet()
1051 end
1052  
1053 -- Hook this method and return true for any sets you do not want listed in the
1054 -- tablet.
1055 function ClosetGnome:HideSetFromUI(set)
1056 return false
1057 end
1058  
1059 function ClosetGnome:OnTooltipUpdate()
1060 local cat = nil
1061 local function clickfunc(name)
1062 if IsControlKeyDown() then
1063 local set = self.db.char.set[string.gsub(name, "*$", "")]
1064  
1065 DressUpModel:Undress()
1066 for i=1,19 do
1067 local item = set[i]
1068  
1069 if i ~= 18 and item ~= false then
1070 -- slot isn't to be emptied, and isn't ranged
1071 local link
1072  
1073 if item then
1074 local bagNum, slotNum = self:FindItem(item)
1075 if bagNum > -1 then
1076 link = GetContainerItemLink(bagNum, slotNum)
1077 end
1078 end
1079  
1080 if not link then
1081 -- either unable to find in inventory, or
1082 -- slot not in set. either way, use
1083 -- currently equipped
1084 link = GetInventoryItemLink("player", i)
1085 end
1086  
1087 if link then
1088 DressUpItemLink(link)
1089 end
1090 end
1091 end
1092 else
1093 ClosetGnome:WearSet(name)
1094 end
1095 end
1096  
1097 local sets = compost:Acquire()
1098 for k in pairs(self.db.char.set) do table.insert(sets, k) end
1099 table.sort(sets)
1100  
1101 for i,k in ipairs(sets) do
1102 if not self:HideSetFromUI(k) then
1103 if not cat then
1104 cat = tablet:AddCategory(
1105 "columns", 2,
1106 "text", L["Available sets"],
1107 "showWithoutChildren", false,
1108 "child_justify", "LEFT",
1109 "child_justify2", "RIGHT",
1110 "child_hasCheck", true,
1111 "child_checked", true,
1112 "child_text2R", 0.5,
1113 "child_text2G", 0.5,
1114 "child_text2B", 0.5
1115 )
1116 end
1117 local set = k
1118 if lastEquippedSet == set then set = set .. "*" end
1119 cat:AddLine(
1120 "text", set,
1121 "func", clickfunc,
1122 "arg1", set,
1123 "checkIcon", self.db.char.icons[k] or "",
1124 "text2", self.db.char.keybindings[k] and "("..self.db.char.keybindings[k]..")" or ""
1125 )
1126 end
1127 end
1128 compost:Reclaim(sets)
1129 sets = nil
1130  
1131 if cat ~= nil then
1132 tablet:SetHint(L["Click a set above to change your equipment. Ctrl-click a set to try it on. The last equipped set is indicated by a star."])
1133 else
1134 tablet:SetHint(L["You have not created any equipment sets yet, please right-click the icon and click 'Add' to create a set."])
1135 end
1136 end
1137