vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2  
3 Wardrobe-AL
4  
5 By AnduinLothar karlkfi@yahoo.com
6  
7 Wardrobe lets you define up to 20 distinct equipment profiles
8 (called "outfits") and lets you switch among them on the fly.
9 For example, you can define a Normal Outfit that consists of
10 your regular equipment, an Around Town Outfit that consists of
11 what you'd like to wear when inside a city or roleplaying, a
12 Stamina Outfit that consists of all your best +stam gear, etc.
13 You can then switch amongst these outfits using a simple slash chat
14 command (/wardrobe wear Around Town Outfit), or using a small
15 interactive button docked beneath your radar.
16  
17 ]]--
18  
19 Wardrobe = {};
20  
21 ---------------------------------------------------------------------------------
22 -- Info
23 ---------------------------------------------------------------------------------
24  
25 local WARDROBE_VERSION = "1.82-AL";
26  
27 ---------------------------------------------------------------------------------
28 -- Localization Registration
29 ---------------------------------------------------------------------------------
30  
31 Localization.SetAddonDefault("Wardrobe", "enUS");
32 Localization.AssignAddonGlobalStrings("Wardrobe"); --For Bindings
33 local function TEXT(key) return Localization.GetString("Wardrobe", key) end
34  
35 local Wardrobe_XMLTextAssignment = {
36 NamePopupText = "POPUP_TITLE";
37 PopupConfirmText = "POPUP_TITLE";
38 NamePopupAcceptButton = "TXT_ACCEPT";
39 PopupConfirmAcceptButton = "TXT_ACCEPT";
40 NamePopupCancelButton = "TXT_CANCEL";
41 PopupConfirmCancelButton = "TXT_CANCEL";
42 CheckboxToggle = "TXT_TOGGLE";
43 CheckboxAccept = "TXT_ACCEPT";
44 CheckboxColorpick = "TXT_COLOR";
45 MainMenuFrameTitle = "TXT_EDITOUTFITS";
46 MainMenuFrameNewButton = "TXT_NEW";
47 MainMenuFrameCloseButton = "TXT_CLOSE";
48 ColorPickFrameTitle = "TXT_SELECTCOLOR";
49 ColorPickFrameOKButton = "TXT_OK";
50 ColorPickFrameCancelButton = "TXT_CANCEL";
51 }
52  
53 function Wardrobe.UpdateXMLText()
54 for frameName, key in Wardrobe_XMLTextAssignment do
55 if (Wardrobe[frameName]) then
56 Wardrobe[frameName]:SetText(TEXT(key));
57 else
58 --print(frameName)
59 end
60 end
61 end
62  
63 Localization.RegisterCallback("WardrobeXML", Wardrobe.UpdateXMLText);
64  
65 ---------------------------------------------------------------------------------
66 -- Variables
67 ---------------------------------------------------------------------------------
68  
69 WARDROBE_DEBUG = false;
70 WARDROBE_NUM_OUTFITS = 20;
71 WARDROBE_NUM_POPUP_FUNCTION_BUTTONS = 1;
72  
73 WARDROBE_TEMP_OUTFIT_NAME = "#temp#";
74  
75 local WARDROBE_UNMOUNT_OUTFIT_NAME = "#unmount#";
76 local WARDROBE_UNPLAGUE_OUTFIT_NAME = "#unplague#";
77 local WARDROBE_DONEEATING_OUTFIT_NAME = "#uneating#";
78 local WARDROBE_DONESWIMMING_OUTFIT_NAME = "#unswimming#";
79  
80 Wardrobe.SpecialOutfitVirtualNames = {
81 -- [specialID] -> virtualOutfitName
82 ["mounted"] = WARDROBE_UNMOUNT_OUTFIT_NAME,
83 ["chowing"] = WARDROBE_DONEEATING_OUTFIT_NAME,
84 ["plague"] = WARDROBE_UNPLAGUE_OUTFIT_NAME,
85 ["swimming"] = WARDROBE_DONESWIMMING_OUTFIT_NAME
86 };
87  
88 Wardrobe.SpecialOutfitVirtualIDs = {
89 -- [virtualOutfitName] -> specialID
90 [WARDROBE_UNMOUNT_OUTFIT_NAME] = "mounted",
91 [WARDROBE_DONEEATING_OUTFIT_NAME] = "chowing",
92 [WARDROBE_UNPLAGUE_OUTFIT_NAME] = "plague",
93 [WARDROBE_DONESWIMMING_OUTFIT_NAME] = "swimming"
94 };
95  
96 Wardrobe.WaitingListVirtualNames = {
97 -- [specialID] -> virtualOutfitName
98 ["mount"] = {id="mounted",toggle=true},
99 ["unmount"] = {id="mounted",toggle= false},
100 ["eating"] = {id="chowing",toggle=true},
101 ["uneating"] = {id="chowing",toggle=false},
102 ["plague"] = {id="plague",toggle=true},
103 ["unplague"] = {id="plague",toggle=false},
104 ["swim"] = {id="swimming",toggle=true},
105 ["unswim"] = {id="swimming",toggle= false}
106 };
107  
108 WARDROBE_MAX_SCROLL_ENTRIES = 9;
109  
110 WARDROBE_NOISY = false;
111  
112 function Wardrobe.GetPlagueZones()
113 return {
114 TEXT("TXT_WPLAGUELANDS"),
115 TEXT("TXT_EPLAGUELANDS"),
116 TEXT("TXT_STRATHOLME"),
117 TEXT("TXT_SCHOLOMANCE")
118 }
119 end
120  
121 WARDROBE_DEFAULT_BUTTON_COLOR = 11; -- corresponds to the entry in WARDROBE_CONSTANTS_TEXTCOLORS (in this case, #11 is green)
122  
123 Wardrobe.InventorySlots = {
124 "HeadSlot",
125 "NeckSlot",
126 "ShoulderSlot",
127 "BackSlot",
128 "ChestSlot",
129 "ShirtSlot",
130 "TabardSlot",
131 "WristSlot",
132 "HandsSlot",
133 "WaistSlot",
134 "LegsSlot",
135 "FeetSlot",
136 "Finger0Slot",
137 "Finger1Slot",
138 "Trinket0Slot",
139 "Trinket1Slot",
140 "MainHandSlot",
141 "SecondaryHandSlot",
142 "RangedSlot"
143 };
144  
145 Wardrobe.InventorySlotsSize = table.getn( Wardrobe.InventorySlots )
146  
147 -- the variable that stores all the wardrobe info
148 -- and gets saved when you quit the game
149 Wardrobe_Config = {};
150 Wardrobe_Config.Enabled = true;
151 Wardrobe_Config.xOffset = 10;
152 Wardrobe_Config.yOffset = 39;
153 Wardrobe_Config.DefaultCheckboxState = 1; -- default state for the checkboxes when specifying what equipment slots make up an outfit on the character paperdoll screen
154 Wardrobe_Config.MustClickUIButton = false; -- default state for the checkboxes when specifying what equipment slots make up an outfit on the character paperdoll screen
155 Wardrobe_Config.version = WARDROBE_VERSION;
156  
157 Wardrobe.Current_Outfit = 0;
158 Wardrobe.InventorySearchForward = 1;
159 Wardrobe.AlreadySetCharactersWardrobeID = false; -- set this to true once we've looked up this character's wardrobe info
160 Wardrobe.PopupFunction = ""; -- tells the popup confirmation box what it's confirming (deleting an outfit, adding one, etc)
161 WARDROBE_CONSTANTS_POPUP_TITLE = ""; -- the title of the popup confirmation box
162 Wardrobe.Rename_OldName = ""; -- remembers original outfit name in case we cancel a rename
163 Wardrobe.BeingDragged = false; -- flag for dragging the wardrobe UI button
164 Wardrobe.DragLock = false; -- true if we're not allowed to drag the wardrobe UI button
165 Wardrobe.InCombat = false; -- true if we're in combat
166 Wardrobe.RegenEnabled = true; -- true if we can't regen (usually means we're in combat)
167 Wardrobe.ShowingCharacterPanel = false; -- true if the character paperdoll frame is visible
168 Wardrobe.PressedAcceptButton = false; -- remembers if we pressed the accept button in case the character paperdoll frame closes via other means
169 Wardrobe.WaitingList = {};
170  
171 --============================================================================================--
172 --============================================================================================--
173 -- --
174 -- INITIALIZATION FUNCTIONS --
175 -- --
176 --============================================================================================--
177 --============================================================================================--
178  
179  
180 ---------------------------------------------------------------------------------
181 -- Stuff done when the plugin first loads
182 ---------------------------------------------------------------------------------
183 function Wardrobe.OnLoad()
184  
185 -- watch our bags and update our wardrobe availability
186 this:RegisterEvent("BAG_UPDATE");
187 this:RegisterEvent("PLAYER_REGEN_DISABLED");
188 this:RegisterEvent("PLAYER_REGEN_ENABLED");
189 this:RegisterEvent("PLAYER_ENTER_COMBAT");
190 this:RegisterEvent("PLAYER_LEAVE_COMBAT");
191 this:RegisterEvent("PLAYER_ENTERING_WORLD");
192 this:RegisterEvent("PLAYER_AURAS_CHANGED");
193 this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
194 --this:RegisterEvent("MIRROR_TIMER_START"); --Swimming Currently Disabled
195  
196 Wardrobe.RegisterXMLRefrences();
197 Wardrobe.DropDown_OnLoad();
198 Wardrobe.RegisterOptionConfigs();
199 end
200  
201 ---------------------------------------------------------------------------------
202 -- Convert all XML frames with the prefix "Wardrobe_Blah" to be refrenced by the Wardrobe.Blah equiv
203 -- An experiment in global namespace minimization
204 ---------------------------------------------------------------------------------
205  
206 function Wardrobe.RegisterXMLRefrences()
207 local globalNameSpace = getfenv(0);
208 local tempTable = {};
209 local newName, newValue, foundString, number;
210 local globalName, globalValue = next(globalNameSpace);
211 while (globalName ~= nil) do
212 newName, newValue = next(globalNameSpace, globalName);
213 if ( type(globalName) == "string" ) and ( type(globalValue) == "table" ) and ( strfind(globalName, "Wardrobe_") ) then
214 foundString, number = string.gsub(globalName, "^Wardrobe_", "")
215 if (number > 0) and (globalValue.GetName) then
216 tempTable[foundString] = globalValue;
217 if (foundString ~= "MainMenuFrameTitle") and (foundString ~= "IconFrame") and (foundString ~= "PopupTitle") and (not strfind(foundString, "SortScrollFrame")) and (not strfind(foundString, "MainMenuFrameEntry")) then
218 --Leave ScrollFrame refrences for template Compatibility
219 --Leave Minimap Button refrences for MobileMinimapFrame Use
220 --Leave PopupTitle refrences for ColorCycle Use
221 --Leave MainMenuFrameTitle refrences for ColorCycle Use
222 --Leave MainMenuFrameEntrys refrences for ColorCycle Use
223 globalNameSpace[globalName] = nil;
224 end
225 end
226 end
227 globalName,globalValue = newName,newValue;
228 end
229 for n, v in tempTable do
230 globalNameSpace.Wardrobe[n] = v;
231 end
232 end
233  
234  
235 ---------------------------------------------------------------------------------
236 -- Register Option Configs
237 ---------------------------------------------------------------------------------
238 function Wardrobe.RegisterOptionConfigs()
239  
240 if (Khaos) then
241 Wardrobe.RegisterKhaos();
242 end
243  
244 local WardrobeCommands = {"/wardrobe","/wd"};
245 if (Sky) then
246 Sky.registerSlashCommand(
247 {
248 id="Wardrobe";
249 commands = WardrobeCommands;
250 onExecute = Wardrobe.ChatCommandHandler;
251 helpText = function() return TEXT("CHAT_COMMAND_INFO") end;
252 }
253 );
254 else
255 SlashCmdList["WARDROBESLASH"] = Wardrobe.ChatCommandHandler;
256 for i, slash in WardrobeCommands do
257 setglobal("SLASH_WARDROBESLASH"..i, slash);
258 end
259 end
260  
261 -- makes sure we have a Print() command
262 if(not Print) then
263 function Print(msg, r, g, b, frame)
264 if (not r) then r = 1.0; end
265 if (not g) then g = 1.0; end
266 if (not b) then b = 1.0; end
267 if ( frame ) then
268 frame:AddMessage(msg, r, g, b);
269 else
270 if ( DEFAULT_CHAT_FRAME ) then
271 DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b);
272 end
273 end
274 end
275 end
276 end
277  
278 function Wardrobe.RegisterKhaos()
279 local optionSet = {
280 id="Wardrobe";
281 text=function() return TEXT("CONFIG_HEADER") end;
282 helptext=function() return TEXT("CONFIG_HEADER_INFO") end;
283 callback=function(state) Wardrobe.Toggle(state and 1); end;
284 feedback=function(state) return state and TEXT("TXT_ENABLED") or TEXT("TXT_DISABLED") end;
285 difficulty=1;
286 default={checked=true};
287 options={
288 {
289 id = "Header";
290 text = function() return TEXT("CONFIG_HEADER").." "..Wardrobe_Config.version end;
291 helptext = function() return TEXT("CONFIG_HEADER_INFO") end;
292 type = K_HEADER;
293 };
294 {
295 id = "WearOutfit";
296 text = function() return TEXT("CONFIG_WEAROUTFIT") end;
297 helptext = function() return TEXT("CONFIG_WEAROUTFIT_INFO") end;
298 feedback = function(state) return format(TEXT("CONFIG_WEAROUTFIT_FEEDBACK"), Wardrobe_Config[WD_realmID][WD_charID].Outfit[state.value].OutfitName) end;
299 callback = function(state)
300 if (state.value) then
301 Wardrobe.WearOutfit(state.value);
302 end
303 end;
304 setup = {
305 options = Wardrobe.GetListOfOutfits;
306 orderedOptions = true;
307 multiSelect = false;
308 noSelect = true;
309 };
310 default = {
311 value = nil;
312 };
313 disabled = {
314 value = nil;
315 };
316 type = K_PULLDOWN;
317 };
318 {
319 id = "EditOutfits";
320 text = function() return TEXT("CONFIG_EDIT") end;
321 helptext = function() return TEXT("CONFIG_EDIT_INFO") end;
322 feedback = function() return TEXT("CONFIG_EDIT_FEEDBACK") end;
323 callback = Wardrobe.ShowMainMenu;
324 type = K_BUTTON;
325 setup = {
326 buttonText = function() return TEXT("CONFIG_EDIT_BUTTON") end;
327 };
328 };
329 {
330 id = "OutfitKeyHeader";
331 text = function() return TEXT("CONFIG_KEY_HEADER") end;
332 helptext = function() return TEXT("CONFIG_KEY_HEADER") end;
333 type = K_HEADER;
334 };
335 {
336 id = "HelpText1";
337 text = function() return TEXT("HELP_13") end;
338 helptext = function() return TEXT("HELP_13") end;
339 type = K_TEXT;
340 };
341 {
342 id = "HelpText2";
343 text = function() return TEXT("HELP_14") end;
344 helptext = function() return TEXT("HELP_14") end;
345 type = K_TEXT;
346 };
347 {
348 id = "HelpText3";
349 text = function() return TEXT("HELP_15") end;
350 helptext = function() return TEXT("HELP_15") end;
351 type = K_TEXT;
352 };
353 {
354 id = "HelpText4";
355 text = function() return TEXT("HELP_16") end;
356 helptext = function() return TEXT("HELP_16") end;
357 type = K_TEXT;
358 };
359 {
360 id = "OptionsHeader";
361 text = function() return TEXT("CONFIG_OPTIONS_HEADER") end;
362 helptext = function() return TEXT("CONFIG_OPTIONS_HEADER") end;
363 type = K_HEADER;
364 };
365 {
366 id = "RequireClick";
367 text = function() return TEXT("CONFIG_REQCLICK") end;
368 helptext = function() return TEXT("CONFIG_REQCLICK_INFO") end;
369 feedback = function(state)
370 if (state.checked) then
371 return TEXT("TXT_BUTTONONCLICK");
372 else
373 return TEXT("TXT_BUTTONONMOUSEOVER");
374 end
375 end;
376 callback = function(state) Wardrobe_Config.MustClickUIButton = (state.checked) end;
377 check = true;
378 type = K_CHECKBOX;
379 default = {
380 checked = false;
381 };
382 disabled = {
383 checked = false;
384 };
385 };
386 {
387 id = "LockButton";
388 text = function() return TEXT("CONFIG_LOCKBUTTON") end;
389 helptext = function() return TEXT("CONFIG_LOCKBUTTON_INFO") end;
390 feedback = function(state)
391 if (state.checked) then
392 return TEXT("TXT_BUTTONLOCKED");
393 else
394 return TEXT("TXT_BUTTONUNLOCKED");
395 end
396 end;
397 callback = function(state) Wardrobe.DragLock = (state.checked) end;
398 check = true;
399 type = K_CHECKBOX;
400 default = {
401 checked = false;
402 };
403 disabled = {
404 checked = false;
405 };
406 };
407 {
408 id = "DropDownScale";
409 text = function() return TEXT("CONFIG_DROPDOWNSCALE") end;
410 helptext = function() return TEXT("CONFIG_DROPDOWNSCALE_INFO") end;
411 feedback = function(state)
412 return format(TEXT("CONFIG_DROPDOWNSCALE_FEEDBACK"), state.slider*100);
413 end;
414 callback = function(state) Wardrobe.SetDropDownScale(state.slider) end;
415 check = true;
416 type = K_SLIDER;
417 dependencies = {["DropDownScale"]={checked=true}};
418 default = {
419 checked = false;
420 slider = UIParent:GetScale();
421 };
422 disabled = {
423 checked = false;
424 slider = UIParent:GetScale();
425 };
426 setup = {
427 sliderMin = 0.5;
428 sliderMax = 1.0;
429 sliderStep = 0.1;
430 sliderSignificantDigits = 1;
431 };
432 };
433 {
434 id = "Reset";
435 text = function() return TEXT("CONFIG_RESET") end;
436 helptext = function() return TEXT("CONFIG_RESET_INFO") end;
437 feedback = function() return TEXT("CONFIG_RESET_FEEDBACK") end;
438 callback = Wardrobe.EraseAllOutfits;
439 type = K_BUTTON;
440 setup = {
441 buttonText = function() return TEXT("CONFIG_RESET_BUTTON") end;
442 };
443 };
444 };
445 };
446 Khaos.registerOptionSet(
447 "inventory",
448 optionSet
449 );
450 end
451  
452 ---------------------------------------------------------------------------------
453 -- Event handler
454 ---------------------------------------------------------------------------------
455 function Wardrobe.OnEvent(event)
456  
457 if (Wardrobe_Config.Enabled) then
458 if (event == "PLAYER_REGEN_DISABLED") then
459 --Sea.io.print("PLAYER_REGEN_DISABLED");
460 Wardrobe.RegenEnabled = false;
461 elseif (event == "PLAYER_REGEN_ENABLED") then
462 Wardrobe.RegenEnabled = true;
463 --Sea.io.print("PLAYER_REGEN_ENABLED ", Wardrobe.IsPlayerInCombat());
464 if (not Wardrobe.IsPlayerInCombat()) then
465 Wardrobe.CheckWaitingList();
466 Wardrobe.CheckForMounted();
467 Wardrobe.CheckForEatDrink();
468 end
469 elseif (event == "PLAYER_ENTER_COMBAT") then
470 --Sea.io.print("PLAYER_ENTER_COMBAT");
471 Wardrobe.InCombat = true;
472 elseif (event == "PLAYER_LEAVE_COMBAT") then
473 Wardrobe.InCombat = false;
474 --Sea.io.print("PLAYER_LEAVE_COMBAT ", Wardrobe.IsPlayerInCombat());
475 if (not Wardrobe.IsPlayerInCombat()) then
476 --Wardrobe.CheckWaitingList();
477 end
478 elseif (event == "PLAYER_AURAS_CHANGED") then
479 --if (not Wardrobe.IsPlayerInCombat()) then
480 if (Chronos) then
481 Chronos.scheduleByName("WardrobeAuraCheck", .2, Wardrobe.AuraCheck);
482 else
483 Wardrobe.CheckForMounted();
484 Wardrobe.CheckForEatDrink();
485 end
486 --end
487 elseif (event == "ZONE_CHANGED_NEW_AREA") then
488 Wardrobe.ChangedZone();
489 elseif (event == "MIRROR_TIMER_START") then
490 Wardrobe.CheckForSwimming();
491 elseif (event == "PLAYER_ENTERING_WORLD") then
492 Wardrobe.UpdateOldConfigVersions();
493 Wardrobe.CheckForMounted();
494 Wardrobe.CurrentZone = GetZoneText();
495 Wardrobe.ChangedZone();
496 Wardrobe.SetDropDownScale(Wardrobe_Config.DropDownScale);
497 end
498 end
499 end
500  
501 function Wardrobe.AuraCheck()
502 Wardrobe.CheckForMounted();
503 Wardrobe.CheckForEatDrink();
504 end
505  
506  
507  
508 ---------------------------------------------------------------------------------
509 -- Return true if we're in combat
510 ---------------------------------------------------------------------------------
511 function Wardrobe.IsPlayerInCombat()
512 if (Wardrobe.InCombat) or (not Wardrobe.RegenEnabled) then
513 return true;
514 else
515 return false;
516 end
517 end
518  
519  
520 ---------------------------------------------------------------------------------
521 -- Update outdated config information
522 ---------------------------------------------------------------------------------
523 function Wardrobe.UpdateOldConfigVersions()
524 if (Wardrobe_Config.DefaultCheckboxState == nil) then
525 Wardrobe.Debug("Adding DefaultCheckboxState to Wardrobe_Config.");
526 Wardrobe_Config.DefaultCheckboxState = 1;
527 else
528 Wardrobe.Debug("Wardrobe_Config.DefaultCheckboxState = "..tostring(Wardrobe_Config.DefaultCheckboxState));
529 end
530  
531 -- Clear out unused items
532 Wardrobe.CheckForOurWardrobeID();
533 for i, outfit in Wardrobe_Config[WD_realmID][WD_charID].Outfit do
534 for j = 1, Wardrobe.InventorySlotsSize do
535 if (outfit.Item[j]) then
536 if (outfit.Item[j].IsSlotUsed ~= 1) then
537 outfit.Item[j] = nil;
538 elseif (outfit.Item[j].Name == "") then
539 outfit.Item[j] = {IsSlotUsed = 1};
540 end
541 end
542 end
543 end
544  
545 Wardrobe_Config.version = WARDROBE_VERSION;
546 end
547  
548  
549 --============================================================================================--
550 --============================================================================================--
551 -- --
552 -- CHAT COMMAND FUNCTIONS --
553 -- --
554 --============================================================================================--
555 --============================================================================================--
556  
557  
558 ---------------------------------------------------------------------------------
559 -- Break a chat command into its command and variable parts (i.e. "debug on"
560 -- will break into command = "debug" and variable = "on", or "add my spiffy wardrobe"
561 -- breaks into command = "add" and variable = "my spiffy wardrobe"
562 ---------------------------------------------------------------------------------
563 function Wardrobe.ParseCommand(msg)
564 firstSpace = string.find(msg, " ", 1, true);
565 if (firstSpace) then
566 local command = string.sub(msg, 1, firstSpace - 1);
567 local var = string.sub(msg, firstSpace + 1);
568 return command, var
569 else
570 return msg, nil;
571 end
572 end
573  
574  
575 ---------------------------------------------------------------------------------
576 -- A simple chat command handler. takes commands in the form "/wardrobe command var"
577 ---------------------------------------------------------------------------------
578 function Wardrobe.ChatCommandHandler(msg)
579 local command, var = Wardrobe.ParseCommand(msg);
580 if ((not command) and msg) then
581 command = msg;
582 end
583 if (command) then
584 command = string.lower(command);
585 if (command == TEXT("CMD_RESET")) then
586 Wardrobe.EraseAllOutfits();
587 elseif (command == TEXT("CMD_LIST")) then
588 Wardrobe.ListOutfits(var);
589 elseif (command == TEXT("CMD_WEAR") or command == TEXT("CMD_WEAR2") or command == TEXT("CMD_WEAR3")) then
590 Wardrobe.WearOutfit(var);
591 elseif (command == TEXT("CMD_ON")) then
592 Wardrobe.Toggle(1);
593 elseif (command == TEXT("CMD_OFF")) then
594 Wardrobe.Toggle(0);
595 elseif (command == TEXT("CMD_LOCK")) then
596 Wardrobe.ToggleLockButton(true);
597 elseif (command == TEXT("CMD_UNLOCK")) then
598 Wardrobe.ToggleLockButton(false);
599 elseif (command == TEXT("CMD_CLICK")) then
600 Wardrobe.ToggleClickButton(true);
601 elseif (command == TEXT("CMD_MOUSEOVER")) then
602 Wardrobe.ToggleClickButton(false);
603 elseif (command == TEXT("CMD_SCALE")) then
604 Wardrobe.SetDropDownScale(var);
605 elseif (command == TEXT("CMD_VERSION")) then
606 Wardrobe.Print(TEXT("TXT_WARDROBEVERSION").." "..WARDROBE_VERSION);
607 elseif (command == "testcheck") then
608 Wardrobe.ShowWardrobe_ConfigurationScreen();
609 elseif (command == "testsort") then
610 Wardrobe.ShowMainMenu();
611 elseif (command == "debug") then
612 Wardrobe.ToggleDebug();
613 elseif (command == "report") then
614 Wardrobe.DumpDebugReport();
615 elseif (command == "itemlist") then
616 Wardrobe.BuildItemList();
617 elseif (command == "struct") then
618 Wardrobe.DumpDebugStruct();
619 else
620 Wardrobe.ShowHelp();
621 end
622 end
623 end
624  
625  
626  
627 --============================================================================================--
628 --============================================================================================--
629 -- --
630 -- WARDROBE MAIN FUNCTIONS --
631 -- --
632 --============================================================================================--
633 --============================================================================================--
634  
635 ---------------------------------------------------------------------------------
636 -- Each character on an account has an ID assigned to it that specifies its wardrobes
637 -- This function returns the ID associated with this character
638 ---------------------------------------------------------------------------------
639 function Wardrobe.GetThisCharactersWardrobeID()
640  
641 Wardrobe.Debug("Looking up this character's wardrobe number...");
642  
643 -- upgrade old versions
644 if ( Wardrobe_Config.version == nil ) then
645 Wardrobe_Config = nil;
646 Wardrobe_Config = { };
647 Wardrobe_Config.Enabled = true;
648 Wardrobe_Config.xOffset = 10;
649 Wardrobe_Config.yOffset = 39;
650 Wardrobe_Config.DefaultCheckboxState = 1; -- default state for the checkboxes when specifying what equipment slots make up an outfit on the character paperdoll screen
651 Wardrobe_Config.MustClickUIButton = false; -- default state for the checkboxes when specifying what equipment slots make up an outfit on the character paperdoll screen
652 Wardrobe_Config.version = WARDROBE_VERSION;
653 Wardrobe.Print("Erasing old Wardrobe_Config because it don't support realm");
654 elseif ( not Wardrobe_Config.version == WARDOBE_VERSION ) then
655 Wardrobe_Config.version = WARDROBE_VERSION;
656 end
657  
658 -- Look for this realm in the wardrobe table
659 WD_RealmName = GetRealmName();
660 WD_realmID = nil;
661  
662 for i = 1, table.getn(Wardrobe_Config) do
663 if ( Wardrobe_Config[i].RealmName == WD_RealmName ) then
664 WD_realmID = i;
665 break;
666 end
667 end
668  
669 -- if we didn't find this realm, add us to the wardrobe table
670 if (not WD_realmID) then
671 Wardrobe.AddThisRealmToWardrobeTable();
672 WD_realmID = table.getn(Wardrobe_Config);
673 end
674  
675  
676 -- look for this character in the wardrobe table
677 WD_charID = nil;
678 WD_PlayerName = UnitName("player")
679  
680 for i = 1, table.getn(Wardrobe_Config[WD_realmID]) do
681 if (Wardrobe_Config[WD_realmID][i].PlayerName == WD_PlayerName) then
682 WD_charID = i;
683 break;
684 end
685 end
686  
687 -- if we didn't find this character, add us to the wardrobe table
688 if (not WD_charID) then
689 Wardrobe.AddThisCharacterToWardrobeTable();
690 WD_charID = table.getn(Wardrobe_Config[WD_realmID]);
691 end
692  
693 Wardrobe.ButtonUpdateVisibility();
694  
695 Wardrobe.Debug("This character's wardrobe number is: "..WD_charID);
696  
697 -- flag that we've already found / created this character's wardrobe entry
698 Wardrobe.AlreadySetCharactersWardrobeID = true;
699 end
700  
701  
702 ---------------------------------------------------------------------------------
703 -- Checks to see if we've already looked up the number associated with this character
704 -- If not, grab the number
705 ---------------------------------------------------------------------------------
706 function Wardrobe.CheckForOurWardrobeID()
707 if (not Wardrobe.AlreadySetCharactersWardrobeID) then
708 Wardrobe.GetThisCharactersWardrobeID();
709 end
710 end
711  
712  
713 -- NOTES ABOUT DATASTRUCTURES:
714 --
715 -- For each character, the wardrobes are stored in a datastructure that looks like this
716 --
717 -- x = total number of outfits
718 -- y = total slots on a character (head, feet, hands, etc)
719 --
720 -- Outfit[x] -- the datastructure for a single outfit
721 --
722 -- SortNumber -- specifies the position this outfit will appear in the list of outfits when the list is sorted
723 -- OutfitName -- the name of this outfit
724 -- Available -- true if all of the items in this outfit are in our bags or equiped
725 -- Mounted -- true if this is the outfit to be worn when we mount
726 -- Virtual -- true if this outfit is virtual (not a real outfit, but only used as temporary storage)
727 -- Selected -- true if this outfit is the currently selected outfit on the menu screen (highlighted white)
728 -- Item[1] -- the data structure for all the items in this outfit
729 -- Name -- the name of the item
730 -- IsSlotUsed -- 1 if this outfit uses this slot, 0 if not (i.e. an outfit might not involve your trinkets, or might only consist of your rings)
731 -- .
732 -- .
733 -- .
734 -- Item[y]
735 --
736 -- So, let's say you have two outfits in your wardrobe. Wardrobe[1] represents outfit 1, and Wardrobe[2]
737 -- represents outfit 2. for outfit 1, Wardrobe[1].OutfitName would be the name of this outfit (say, "In town outfit").
738 -- the item on your character slot 5 would be Wardrobe[1].Item[5].Name. Since all these are stored per character, the
739 -- actual datastructure would look like:
740 --
741 -- Wardrobe_Config[WD_realmID][3].Wardrobe[1].Item[5].Name --> for character 3, outfit 1, item 5
742  
743  
744 ---------------------------------------------------------------------------------
745 -- Add an entry for this realm to the main table of wardrobes
746 ---------------------------------------------------------------------------------
747 function Wardrobe.AddThisRealmToWardrobeTable()
748  
749 Wardrobe.Debug("Didn't find a wardrobe ID for this realm. Adding this realm to the table...");
750  
751 -- build the structure for this realm's wardrobe
752 tempTable = { };
753 tempTable.RealmName = WD_RealmName;
754  
755 -- stick this structure into the main table of wardrobes
756 table.insert(Wardrobe_Config, tempTable);
757 end
758  
759  
760 ---------------------------------------------------------------------------------
761 -- Add an entry for this character to the main table of wardrobes
762 ---------------------------------------------------------------------------------
763 function Wardrobe.AddThisCharacterToWardrobeTable()
764  
765 Wardrobe.Debug("Didn't find a wardrobe ID for this character. Adding this character to the table...");
766  
767 -- build the structure for this char's wardrobe
768 tempTable = { };
769 tempTable.PlayerName = WD_PlayerName
770 tempTable.Outfit = { };
771  
772 -- stick this structure into the main table of wardrobes
773 table.insert(Wardrobe_Config[WD_realmID], tempTable);
774 end
775  
776  
777 ---------------------------------------------------------------------------------
778 -- Create and return a blank outfit structure
779 ---------------------------------------------------------------------------------
780 function Wardrobe.CreateBlankOutfit()
781 local tempTable2 = { };
782 tempTable2.SortNumber = nil;
783 tempTable2.OutfitName = "";
784 tempTable2.Available = false;
785 tempTable2.Special = "";
786 tempTable2.Virtual = false;
787 tempTable2.Selected = false;
788 tempTable2.ButtonColor = WARDROBE_DEFAULT_BUTTON_COLOR;
789 tempTable2.Item = { };
790 --[[
791 for i = 1, Wardrobe.InventorySlotsSize do
792 tempTable3 = { };
793 tempTable3.Name = "";
794 tempTable3.IsSlotUsed = Wardrobe_Config.DefaultCheckboxState;
795 table.insert(tempTable2.Item, tempTable3);
796 end
797 ]]--
798  
799 return tempTable2;
800 end
801  
802  
803 ---------------------------------------------------------------------------------
804 -- Add the named outfit to our wardrobe
805 ---------------------------------------------------------------------------------
806 function Wardrobe.AddNewOutfit(outfitName, buttonColor)
807  
808 if (Wardrobe_Config.Enabled) then
809  
810 -- if we haven't already looked up our character's number
811 Wardrobe.CheckForOurWardrobeID();
812  
813 if (not outfitName) then
814 return;
815 end
816  
817 -- make sure we don't already have an outfit with the same name
818 if (Wardrobe.FoundOutfitName(outfitName)) then
819 Wardrobe.Print(TEXT("TXT_OUTFITNAMEEXISTS"));
820 return;
821 end
822  
823 Wardrobe.Debug("Trying to set this wardrobe as \""..outfitName.."\"");
824  
825 -- if we found a free outfit slot
826 local outfitNum = Wardrobe.GetNextFreeOutfitSlot();
827 if (outfitNum ~= 0) then
828  
829 -- store our current equipment in this outfit
830 Wardrobe.StoreItemsInOutfit(outfitName, outfitNum, "added");
831 Wardrobe_Config[WD_realmID][WD_charID].Outfit[outfitNum].ButtonColor = buttonColor;
832 -- otherwise we've used the maximum number of outfits
833 else
834 Wardrobe.Print(TEXT("TXT_USEDUPALL").." "..WARDROBE_NUM_OUTFITS.." "..TEXT("TXT_OFYOUROUTFITS"), 1.0, 0.0, 0.0);
835 end
836 end
837 end
838  
839  
840 ---------------------------------------------------------------------------------
841 -- Create and return the index of the next free outfit slot
842 ---------------------------------------------------------------------------------
843 function Wardrobe.GetNextFreeOutfitSlot(virtualOutfitName)
844  
845 -- find next unused outfit slot
846 local outfitNum = 0;
847  
848 local outfitCount = 0;
849 local outfits = Wardrobe_Config[WD_realmID][WD_charID].Outfit;
850 local duplicate = false;
851 for i, oufit in outfits do
852 if (not oufit.Virtual) then
853 outfitCount = outfitCount + 1;
854 end
855 if (oufit.OutfitName == virtualOutfitName) then
856 table.remove(outfits, i);
857 duplicate = true;
858 end
859 end
860  
861 if (duplicate) then
862 Wardrobe.RenumberSortNumbers();
863 end
864  
865 -- if we aren't already using our max number of outfits
866 if (outfitCount < WARDROBE_NUM_OUTFITS or addingVirtualOutfit) then
867 -- add another outfit to the list and return its index
868 table.insert(outfits, Wardrobe.CreateBlankOutfit());
869 outfitNum = table.getn(outfits);
870 outfits[outfitNum].SortNumber = outfitNum;
871 end
872  
873 return outfitNum;
874 end
875  
876  
877 ---------------------------------------------------------------------------------
878 -- Store our currently equipped items in the specified outfit name
879 ---------------------------------------------------------------------------------
880 function Wardrobe.StoreItemsInOutfit(outfitName, outfitNum, printMessage)
881  
882 -- store the name of this outfit
883 local outfit = Wardrobe_Config[WD_realmID][WD_charID].Outfit[outfitNum];
884 outfit.OutfitName = outfitName;
885 outfit.Special = nil;
886 outfit.Virtual = false;
887  
888 -- for each slot on our character's person (hands, feet, etc)
889 for i = 1, Wardrobe.InventorySlotsSize do
890 if (Wardrobe.ItemCheckState[i] == 1) then
891 if (not outfit.Item[i]) then
892 outfit.Item[i] = {};
893 end
894 local item = outfit.Item[i];
895 item.IsSlotUsed = 1
896 local itemID, permEnchant, tempEnchant, suffix, itemName = Wardrobe.GetItemInfoAtInventorySlotNumber(i);
897 item.Name = itemName;
898 item.ItemID = itemID;
899 item.Suffix = suffix;
900 item.PermEnchant = permEnchant;
901 Wardrobe.Debug(" Setting USED slot "..Wardrobe.InventorySlots[i].." = ["..tostring(item.Name).."]");
902 else
903 outfit.Item[i] = nil;
904 Wardrobe.Debug(" Setting unused slot "..Wardrobe.InventorySlots[i]);
905 end
906 end
907  
908 -- all the items in this outfit are currently available in the player's inventory
909 outfit.Available = true;
910  
911 if (printMessage) then
912 Wardrobe.Print(TEXT("TXT_OUTFIT").." \""..outfitName.."\" "..printMessage..".");
913 end
914 end
915  
916  
917 ---------------------------------------------------------------------------------
918 -- Update an outfit
919 ---------------------------------------------------------------------------------
920 function Wardrobe.UpdateOutfit(outfitName, buttonColor)
921  
922 if (Wardrobe_Config.Enabled) then
923  
924 -- if we haven't already looked up our character's number
925 Wardrobe.CheckForOurWardrobeID();
926  
927 -- check to see if the wardrobe doesn't exist
928 if (outfitName == nil or outfitName == "") then
929 Wardrobe.Print(TEXT("TXT_PLEASEENTERNAME"));
930 elseif (not Wardrobe.FoundOutfitName(outfitName)) then
931 Wardrobe.Print(TEXT("TXT_OUTFITNOTEXIST"));
932 UIErrorsFrame:AddMessage(TEXT("TXT_NOTEXISTERROR"), 1.0, 0.0, 0.0, 1.0, UIERRORS_HOLD_TIME);
933 else
934  
935 -- find the outfit to update
936 for i, outfit in Wardrobe_Config[WD_realmID][WD_charID].Outfit do
937  
938 -- if we found the outfit, store our equipment
939 if (outfit.OutfitName == outfitName) then
940 Wardrobe.StoreItemsInOutfit(outfitName, i, TEXT("TXT_UPDATED"));
941 outfit.ButtonColor = buttonColor;
942 end
943 end
944 end
945 end
946 end
947  
948  
949 ---------------------------------------------------------------------------------
950 -- Erase the named outfit
951 ---------------------------------------------------------------------------------
952 function Wardrobe.EraseOutfit(outfitName, silent, eraseAll)
953  
954 if (Wardrobe_Config.Enabled) then
955  
956 -- if we haven't already looked up our character's number
957 Wardrobe.CheckForOurWardrobeID();
958  
959 Wardrobe.Debug("Trying to delete outfit \""..outfitName.."\"");
960  
961 local found = false;
962 -- find the outfit to erase
963 local outfits = Wardrobe_Config[WD_realmID][WD_charID].Outfit;
964 for i = 1, table.getn(outfits) do
965  
966 -- if we found the outfit
967 if (outfits[i]) and (outfits[i].OutfitName == outfitName) then
968  
969 -- remove the outfit
970 table.remove(outfits, i);
971  
972 --Wardrobe.RemoveAPopupButton(outfitName);
973  
974 found = true;
975  
976 if (not eraseAll) then
977 break;
978 else
979 i = 1;
980 end
981 end
982 end
983  
984 Wardrobe.RenumberSortNumbers();
985  
986 if (found) then
987 if (not eraseAll) and (not silent) then
988 Wardrobe.Print(TEXT("TXT_OUTFIT").." \""..outfitName.."\" "..TEXT("TXT_DELETED"));
989 Wardrobe.ListOutfits();
990 UIErrorsFrame:AddMessage(TEXT("TXT_OUTFIT").." \""..outfitName.."\" "..TEXT("TXT_DELETED"), 0.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME);
991 end
992 else
993 Wardrobe.Print(TEXT("TXT_UNABLETOFIND").." \""..outfitName.."!\"");
994 UIErrorsFrame:AddMessage(TEXT("TXT_UNABLEFINDERROR"), 1.0, 0.0, 0.0, 1.0, UIERRORS_HOLD_TIME);
995 end
996 return found;
997 end
998 end
999  
1000  
1001 ---------------------------------------------------------------------------------
1002 -- Erase all our outfits
1003 ---------------------------------------------------------------------------------
1004 function Wardrobe.EraseAllOutfits()
1005  
1006 if (Wardrobe_Config.Enabled) then
1007  
1008 -- if we haven't already looked up our character's number
1009 Wardrobe.CheckForOurWardrobeID();
1010  
1011 -- delete all the outfits
1012 Wardrobe_Config[WD_realmID][WD_charID].Outfit = { };
1013  
1014 -- hide the main menu
1015 Wardrobe.ToggleMainMenuFrameVisibility(false);
1016  
1017 Wardrobe.Print(TEXT("TXT_ALLOUTFITSDELETED"));
1018 UIErrorsFrame:AddMessage(TEXT("TXT_ALLOUTFITSDELETED"), 0.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME);
1019 end
1020 end
1021  
1022  
1023 ---------------------------------------------------------------------------------
1024 -- Print a list of our outfits
1025 ---------------------------------------------------------------------------------
1026 function Wardrobe.ListOutfits(var)
1027  
1028 if (Wardrobe_Config.Enabled) then
1029  
1030 -- if we haven't already looked up our character's number
1031 Wardrobe.CheckForOurWardrobeID();
1032  
1033 local foundOutfits = false;
1034 Wardrobe.Print(TEXT("TXT_YOURCURRENTARE"));
1035  
1036 -- for each outfit
1037 for i, outfit in Wardrobe_Config[WD_realmID][WD_charID].Outfit do
1038  
1039 -- if it has a name and isn't virtual
1040 if (outfit.OutfitName ~= "" and (not outfit.Virtual)) then
1041 Wardrobe.Print(" o ".. outfit.OutfitName);
1042 foundOutfits = true;
1043  
1044 -- if we asked for a detailed printout, show all the items
1045 if (var == "items") then
1046 for j = 1, Wardrobe.InventorySlotsSize do
1047 local item = outfit.Item[j];
1048 if (item) and (item.Name) and (item.Name ~= "") then
1049 Wardrobe.Print(" ["..Wardrobe.InventorySlots[j].." -> ".. item.Name.."]");
1050 end
1051 end
1052 end
1053 end
1054 end
1055  
1056 if (not foundOutfits) then
1057 Wardrobe.Print(" "..TEXT("TXT_NOOUTFITSFOUND"));
1058 end
1059 end
1060 end
1061  
1062  
1063 ---------------------------------------------------------------------------------
1064 -- Wear an outfit
1065 ---------------------------------------------------------------------------------
1066 function Wardrobe.WearOutfit(wardrobeName, silent)
1067  
1068 if (Wardrobe_Config.Enabled) then
1069  
1070 -- if we haven't already looked up our character's number
1071 Wardrobe.CheckForOurWardrobeID();
1072  
1073 local outfit;
1074  
1075 -- if the user didn't specify a wardrobe to wear
1076 if (not wardrobeName) then
1077  
1078 Wardrobe.Print(TEXT("TXT_SPECIFYOUTFITTOWEAR"));
1079 return;
1080  
1081 -- else use the specified wardrobe
1082 elseif (type(wardrobeName) == "number") then
1083 local outfitNumber = wardrobeName;
1084 wardrobeName = Wardrobe_Config[WD_realmID][WD_charID].Outfit[outfitNumber].OutfitName;
1085 if (wardrobeName) then
1086 Wardrobe.Debug("Wardrobe.WearOutfit: Found outfit at #".. outfitNumber);
1087 outfit = Wardrobe_Config[WD_realmID][WD_charID].Outfit[outfitNumber];
1088 else
1089 Wardrobe.Print(TEXT("TXT_UNABLEFIND").." \""..wardrobeName.."\" "..TEXT("TXT_INYOURLISTOFOUTFITS"));
1090 return;
1091 end
1092 else
1093 local outfitNumber = 0;
1094 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1095 Wardrobe.Debug("In WearOutfit, Looking at outfit #"..i.." name = ["..Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].OutfitName.."]");
1096 if (Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].OutfitName == wardrobeName) then
1097 outfitNumber = i;
1098 Wardrobe.Debug("Wardrobe.WearOutfit: Found outfit at #"..outfitNumber);
1099 break;
1100 end
1101 end
1102  
1103 if (outfitNumber == 0) then
1104 Wardrobe.Print(TEXT("TXT_UNABLEFIND").." \""..wardrobeName.."\" "..TEXT("TXT_INYOURLISTOFOUTFITS"));
1105 return;
1106 end
1107  
1108 outfit = Wardrobe_Config[WD_realmID][WD_charID].Outfit[outfitNumber];
1109 end
1110  
1111  
1112 Wardrobe.Debug(TEXT("TXT_SWITCHINGTOOUTFIT").." \""..wardrobeName.."\"");
1113  
1114 -- this variable "freeBagSpacesUsed" lets us track which empty pack spaces we've
1115 -- already assigned an item to be put into. we need to do this because when we remove
1116 -- items from our character and put them into our bags, the server takes time to actually
1117 -- move the item into the bag. during this delay, we may be still removing items, and we
1118 -- may see a slot that LOOKS empty but really the server just hasn't gotten around to moving
1119 -- a previous item into the slot. this variable lets us mark each empty slot once we've assigned
1120 -- an item to it so that we don't try to use the same empty slot for another item.
1121 local freeBagSpacesUsed = { };
1122  
1123 -- tracks how our switching is going. if at any point we can't remove an item (bags are full, etc),
1124 -- this will get set to false
1125 local switchResult = true;
1126 local itemID, permEnchant, tempEnchant, suffix, invItemName, theSlotID, outfitItemName, outfitItemID, outfitPermEnchant, equipingTwoHandWeapon;
1127 -- for each slot on our character (hands, neck, head, feet, etc)
1128 for i = 1, Wardrobe.InventorySlotsSize do
1129 local outfitItem = outfit.Item[i];
1130 -- if this slot is used in this outfit
1131 if (equipingTwoHandWeapon) and (Wardrobe.InventorySlots[i] == "SecondaryHandSlot") then
1132 itemID, permEnchant, tempEnchant, suffix, invItemName = Wardrobe.GetItemInfoAtInventorySlotNumber(i);
1133 if (itemID) and (Chronos) then
1134 Wardrobe.Debug(" Moving offhand to back of bags: "..invItemName);
1135 Chronos.scheduleByName("ReBag:"..invItemName, 1, ReBagContainerItem, invItemName);
1136 end
1137 elseif (outfitItem) and (outfitItem.IsSlotUsed == 1) then
1138  
1139 theSlotID = GetInventorySlotInfo(Wardrobe.InventorySlots[i]);
1140 outfitItemName = outfitItem.Name;
1141 outfitItemID = outfitItem.ItemID;
1142 outfitSuffix = outfitItem.Suffix;
1143 outfitPermEnchant = outfitItem.PermEnchant;
1144 Wardrobe.Debug("Working on slot -> "..Wardrobe.InventorySlots[i]);
1145  
1146  
1147 itemID, permEnchant, tempEnchant, suffix, invItemName = Wardrobe.GetItemInfoAtInventorySlotNumber(i);
1148  
1149 -- if we've set an item for this slot
1150 if (((outfitItemID) and (outfitSuffix) and (outfitPermEnchant)) and ((outfitItemID ~= itemID) or (outfitSuffix ~= suffix) or (outfitPermEnchant ~= permEnchant))) or ((outfitItemName) and (outfitItemName ~= "") and (outfitItemName ~= invItemName)) then
1151 -- equip the correct item
1152 Wardrobe.Debug(" Didn't match! Switching out "..Wardrobe.InventorySlots[i].." for ["..outfitItemName.."]");
1153 if (not Wardrobe.Equip(outfitItemName, theSlotID, outfitItemID, outfitSuffix, outfitPermEnchant)) then
1154 Wardrobe.Print(TEXT("TXT_WARNINGUNABLETOFIND").." \""..outfitItemName.."\" "..TEXT("TXT_INYOURBAGS"));
1155 elseif (not outfitItemID) or (not outfitSuffix) or (not outfitPermEnchant) then
1156 -- Item not stored with itemID info
1157 --outfitItem.ItemID = itemID;
1158 --outfitItem.Suffix = suffix;
1159 --outfitItem.PermEnchant = permEnchant;
1160 --outfitItem.TempEnchant = tempEnchant;
1161 end
1162  
1163 -- Check for 2h weapon
1164 if (Wardrobe.InventorySlots[i] == "MainHandSlot") and (outfitItemID) then
1165 local _, _, _, _, _, _, _, equipLoc = GetItemInfo(outfitItemID);
1166 equipingTwoHandWeapon = (equipLoc == "INVTYPE_2HWEAPON");
1167 end
1168  
1169 -- Forced Empty Slot, slot currently has an item in it
1170 elseif (invItemName) and ((not outfitItemName) or (outfitItemName == "")) then
1171 -- if inventory slot has an item equipped and it's a duel slot then check the next slots for swapping
1172 local swapped = false;
1173 if (equipingTwoHandWeapon) and (Wardrobe.InventorySlots[i] == "SecondaryHandSlot") then
1174 -- Should never be hit, is caught in first escape clause.
1175 swapped = true;
1176 result = true;
1177  
1178 elseif (Wardrobe.InventorySlots[i] == "MainHandSlot") or (Wardrobe.InventorySlots[i] == "Finger0Slot") or (Wardrobe.InventorySlots[i] == "Trinket0Slot") then
1179 -- Next Inv Slot
1180 outfitItem = outfit.Item[i+1];
1181 outfitItemName = outfitItem.Name;
1182 outfitItemID = outfitItem.ItemID;
1183 outfitSuffix = outfitItem.Suffix;
1184 outfitPermEnchant = outfitItem.PermEnchant;
1185 if ((outfitItemID) and (outfitSuffix) and (outfitPermEnchant) and (outfitItemID == itemID) and (outfitSuffix == suffix) and (outfitPermEnchant == permEnchant)) or ((outfitItemName) and (outfitItemName == invItemName)) then
1186 -- Put secondary slot item in bag
1187 local secondarySlotID = GetInventorySlotInfo(Wardrobe.InventorySlots[i+1]);
1188 PickupInventoryItem(secondarySlotID);
1189 result, freeBagSpacesUsed = BagItem(freeBagSpacesUsed);
1190 switchResult = switchResult and result;
1191 Wardrobe.Debug(" Trying to remove "..Wardrobe.InventorySlots[i].." ( slot ID #"..theSlotID..")");
1192  
1193 -- Equip primary slot item to secondary slot
1194 PickupInventoryItem(theSlotID);
1195 EquipCursorItem(secondarySlotID);
1196 Wardrobe.Debug(" Matched Next Slot! Moving "..Wardrobe.InventorySlots[i].." item to "..Wardrobe.InventorySlots[i+1]..".");
1197 swapped = true;
1198 end
1199 end
1200  
1201 -- this outfit doesn't use an item for this inventory slot (i.e. no gloves in this wardrobe)
1202 if (not swapped) then
1203 -- grab the inventory item and bag it
1204 PickupInventoryItem(theSlotID);
1205 result, freeBagSpacesUsed = BagItem(freeBagSpacesUsed);
1206 Wardrobe.Debug(" Trying to remove "..Wardrobe.InventorySlots[i].." ( slot ID #"..theSlotID..")");
1207 end
1208  
1209 -- if we failed to switch, this will let us know
1210 switchResult = switchResult and result;
1211  
1212 -- Item found was item desired
1213 else
1214 Wardrobe.Debug(" Matched! No need to switch out "..Wardrobe.InventorySlots[i]..".");
1215 end
1216 end
1217 end
1218  
1219 -- only errorcheck when dealing with non-virtual outfits
1220 if (not outfit.Virtual and not silent) then
1221  
1222 -- if everything went OK
1223 if (switchResult) then
1224 if ( WARDROBE_NOISY ) then
1225 Wardrobe.Print(TEXT("TXT_SWITCHEDTOOUTFIT").." \""..wardrobeName..".\"");
1226 end
1227 Wardrobe.Current_Outfit = outfitNumber;
1228 else
1229 Wardrobe.Print(TEXT("TXT_PROBLEMSCHANGING"));
1230 end
1231 end
1232  
1233 if (mrpOnMRPEvent) then
1234 --MyRolePlay support for swapping outfits
1235 mrpOnMRPEvent("CHANGE_OUTFIT", wardrobeName);
1236 end
1237  
1238 end
1239 end
1240  
1241  
1242 ---------------------------------------------------------------------------------
1243 -- Rename an outfit
1244 ---------------------------------------------------------------------------------
1245 function Wardrobe.RenameOutfit(oldName, newName)
1246  
1247 if (Wardrobe_Config.Enabled) then
1248  
1249 -- check to see if the new name is already being used
1250 if (not Wardrobe.FoundOutfitName(newName) and newName ~= "") then
1251 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1252 if (Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].OutfitName == oldName) then
1253 Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].OutfitName = newName;
1254 break;
1255 end
1256 end
1257 UIErrorsFrame:AddMessage(TEXT("TXT_OUTFITRENAMEDERROR"), 0.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME);
1258 Wardrobe.Print(TEXT("TXT_OUTFITRENAMEDTO").." \""..oldName.."\" "..TEXT("TXT_TOWORDONLY").." \""..newName.."\"");
1259 end
1260 end
1261 end
1262  
1263  
1264  
1265 ---------------------------------------------------------------------------------
1266 -- Comparison function for sorting outfits
1267 ---------------------------------------------------------------------------------
1268 function Wardrobe.SortOutfitCompare(outfit1, outfit2)
1269 if (Wardrobe.SpecialOutfitVirtualIDs[outfit1.Name]) then
1270 return false
1271 elseif (outfit1.SortNumber < outfit2.SortNumber) then
1272 return true;
1273 else
1274 return false;
1275 end
1276 end
1277  
1278  
1279 ---------------------------------------------------------------------------------
1280 -- Sort the outfits based on the .SortNumber property
1281 ---------------------------------------------------------------------------------
1282 function Wardrobe.SortOutfits()
1283 table.sort(Wardrobe_Config[WD_realmID][WD_charID].Outfit, Wardrobe.SortOutfitCompare);
1284  
1285 Wardrobe.RenumberSortNumbers();
1286 end
1287  
1288  
1289 ---------------------------------------------------------------------------------
1290 -- Re-number the .SortNumbers so they start at 1 and go up by 1
1291 ---------------------------------------------------------------------------------
1292 function Wardrobe.RenumberSortNumbers()
1293 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1294 Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].SortNumber = i;
1295 end
1296 end
1297  
1298  
1299 ---------------------------------------------------------------------------------
1300 -- Re-order an outfit in the list of outfits
1301 ---------------------------------------------------------------------------------
1302 function Wardrobe.OrderOutfit(outfitNum, direction)
1303 if (outfitNum == 1 and direction < 0) then return; end
1304 if (outfitNum == table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) and direction > 0) then return; end
1305  
1306 local outfit = Wardrobe_Config[WD_realmID][WD_charID].Outfit[outfitNum];
1307  
1308 if (direction > 0) then
1309  
1310 swapNum = 0;
1311 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1312 if (Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].SortNumber == outfit.SortNumber + 1) then
1313 swapNum = i;
1314 break;
1315 end
1316 end
1317 Wardrobe_Config[WD_realmID][WD_charID].Outfit[swapNum].SortNumber = outfit.SortNumber
1318 outfit.SortNumber = outfit.SortNumber + 1;
1319 else
1320 swapNum = 0;
1321 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1322 if (Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].SortNumber == outfit.SortNumber - 1) then
1323 swapNum = i;
1324 break;
1325 end
1326 end
1327 Wardrobe_Config[WD_realmID][WD_charID].Outfit[swapNum].SortNumber = outfit.SortNumber
1328 outfit.SortNumber = outfit.SortNumber - 1;
1329 end
1330  
1331 return swapNum;
1332 end
1333  
1334  
1335 ---------------------------------------------------------------------------------
1336 -- return the index of the selected outfit, or nil if none
1337 ---------------------------------------------------------------------------------
1338 function Wardrobe.FindSelectedOutfit()
1339 local outfitNum = nil;
1340 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1341 if (Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].Selected) then
1342 outfitNum = i;
1343 break;
1344 end
1345 end
1346  
1347 return outfitNum;
1348 end
1349  
1350  
1351 ---------------------------------------------------------------------------------
1352 -- Tag this outfit to be worn when mounted
1353 ---------------------------------------------------------------------------------
1354 function Wardrobe.SetMountedOutfit(outfitName)
1355 local outfitNumber;
1356 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1357 Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].Special = "";
1358 if (Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].OutfitName == outfitName) then
1359 outfitNumber = i;
1360 end
1361 end
1362 if (not outfitNumber) then
1363 Wardrobe.Print(TEXT("TXT_UNABLETOFINDOUTFIT").." \""..outfitName..".\"");
1364 else
1365 Wardrobe_Config[WD_realmID][WD_charID].Outfit[outfitNumber].Special = "mounted";
1366 Wardrobe.Print(TEXT("TXT_OUTFIT").." \""..outfitName.."\" "..TEXT("TXT_WILLBEWORNWHENMOUNTED"));
1367 end
1368 end
1369  
1370  
1371 ---------------------------------------------------------------------------------
1372 -- See if we're mounted
1373 ---------------------------------------------------------------------------------
1374 function Wardrobe.PlayerIsMounted()
1375 if (not IsMounted) then return end
1376 return UnitIsMounted("player");
1377 end
1378  
1379 function Wardrobe.CheckForMounted()
1380 --Sea.io.print("CheckForMounted");
1381 if (not IsMounted) then return end
1382 local mounted = Wardrobe.PlayerIsMounted();
1383 Wardrobe.EventTaskToggle(mounted, "MountState", "mount", "unmount");
1384 end
1385  
1386  
1387 ---------------------------------------------------------------------------------
1388 -- See if we're eating/drinking
1389 ---------------------------------------------------------------------------------
1390 function Wardrobe.PlayerIsEatingOrDrinking()
1391 -- check our buffs for an eat or drink buff
1392 for i = 1, 16 do
1393 local texture = UnitBuff("player", i);
1394 if (texture) then
1395 if (string.find(texture,"INV_Misc_Fork") or string.find(texture,"INV_Drink")) then
1396 return 1;
1397 end
1398 end
1399 end
1400 end
1401  
1402 function Wardrobe.CheckForEatDrink()
1403 local chowing = Wardrobe.PlayerIsEatingOrDrinking();
1404 Wardrobe.EventTaskToggle(chowing, "ChowingState", "eating", "uneating");
1405 end
1406  
1407 ---------------------------------------------------------------------------------
1408 -- See if we switched into or out of the plaguelands
1409 ---------------------------------------------------------------------------------
1410  
1411 function Wardrobe.PlayerIsInPlagueZone()
1412 local currZone = GetZoneText();
1413 Wardrobe.CurrentZone = currZone;
1414 local plaguezones = Wardrobe.GetPlagueZones();
1415 for i = 1, table.getn(plaguezones) do
1416 if (currZone == plaguezones[i]) then
1417 return 1;
1418 end
1419 end
1420 end
1421  
1422 function Wardrobe.ChangedZone()
1423 if (Wardrobe.CurrentZone ~= GetZoneText()) then
1424 local inPlagueZone = Wardrobe.PlayerIsInPlagueZone();
1425 Wardrobe.EventTaskToggle(inPlagueZone, nil, "plague", "unplague");
1426 end
1427 end
1428  
1429 ---------------------------------------------------------------------------------
1430 -- See if we're swimming, or at least if the breath bar is up.
1431 ---------------------------------------------------------------------------------
1432 function Wardrobe.PlayerIsSwimming()
1433 local breathBar;
1434 for i=1,3 do
1435 breathBar = getglobal("MirrorTimer"..i.."Text");
1436 if (breathBar:IsVisible()) and (breathBar:GetText() == BREATH_LABEL) then
1437 return 1;
1438 end
1439 end
1440 end
1441  
1442 function Wardrobe.CheckForSwimming()
1443 local swimming = Wardrobe.PlayerIsSwimming();
1444 Wardrobe.EventTaskToggle(swimming, nil, "swim", "unswim");
1445 end
1446  
1447 ---------------------------------------------------------------------------------
1448 -- Wear the outfit specially tagged as indicated
1449 ---------------------------------------------------------------------------------
1450 function Wardrobe.WearSpecialOutfit(specialID, virtualOutfitName, wearIt)
1451  
1452 Wardrobe.CheckForOurWardrobeID();
1453  
1454 local outfitNumber;
1455 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1456 if (Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].Special == specialID) then
1457 outfitNumber = i;
1458 break;
1459 end
1460 end
1461  
1462 if (outfitNumber) then
1463 if (wearIt) then
1464 -- remember what we're wearing before we put on the special outfit
1465 Wardrobe.StoreVirtualOutfit(virtualOutfitName, outfitNumber);
1466 -- wear our special outfit
1467 Wardrobe.WearOutfit(outfitNumber, true);
1468 else
1469 -- re-equip the virtual outfit
1470 Wardrobe.CheckForEquipVirtualOutfit(virtualOutfitName);
1471 end
1472 end
1473 end
1474  
1475 ---------------------------------------------------------------------------------
1476 -- Trigger special outfits or add task to task list based on event trigger
1477 ---------------------------------------------------------------------------------
1478  
1479 function Wardrobe.EventTaskToggle(value, variableName, trueTaskID, falseTaskID)
1480  
1481 local taskID;
1482 -- toggle the state and schedule wearing our tasked outfit
1483 if (variableName) then
1484 --Sea.io.print("Value: ", value, " ", variableName, " ", Wardrobe[variableName]);
1485 if (value) and (not Wardrobe_Config[variableName]) then
1486 taskID = trueTaskID;
1487 elseif (not value) and (Wardrobe_Config[variableName]) then
1488 taskID = falseTaskID;
1489 end
1490 else
1491 if (value) then
1492 taskID = trueTaskID;
1493 else
1494 taskID = falseTaskID;
1495 end
1496 end
1497  
1498 if (taskID) then
1499 local taskInfo = Wardrobe.WaitingListVirtualNames[taskID];
1500 if (variableName) then
1501 Wardrobe_Config[variableName] = taskInfo.toggle;
1502 end
1503 if (Wardrobe.IsPlayerInCombat()) then
1504 Wardrobe.AddToWaitingList(taskID);
1505 else
1506 local eventID = taskInfo.id;
1507 Wardrobe.WearSpecialOutfit(eventID, Wardrobe.SpecialOutfitVirtualNames[eventID], taskInfo.toggle);
1508 end
1509 end
1510  
1511 end
1512  
1513 ---------------------------------------------------------------------------------
1514 -- Waiting Task List Functions
1515 ---------------------------------------------------------------------------------
1516  
1517 function Wardrobe.AddToWaitingList(theTask)
1518 --Sea.io.print("Adding "..theTask.." to waiting list!");
1519 table.insert(Wardrobe.WaitingList, theTask);
1520 end
1521  
1522  
1523 function Wardrobe.CheckWaitingList()
1524 --Sea.io.print("Checking Wardrobe.WaitingList: "..asText(Wardrobe.WaitingList));
1525 for i = 1, table.getn(Wardrobe.WaitingList) do
1526 local theTask = table.remove(Wardrobe.WaitingList, 1);
1527 --Sea.io.print("Popped "..theTask.." from waiting list!");
1528 local taskID;
1529 for taskName, taskInfo in Wardrobe.WaitingListVirtualNames do
1530 if (theTask == taskName) then
1531 --Sea.io.print("Putting on ".. taskName.." from virtual outfits.");
1532 Wardrobe.WearSpecialOutfit(taskInfo.id, Wardrobe.SpecialOutfitVirtualNames[taskInfo.id], taskInfo.toggle);
1533 break;
1534 end
1535 end
1536 end
1537 end
1538  
1539  
1540 ---------------------------------------------------------------------------------
1541 -- Store what we're currently wearing in a virtual outfit
1542 ---------------------------------------------------------------------------------
1543 function Wardrobe.StoreVirtualOutfit(virtualOutfitName, currentOutfitName)
1544  
1545 local currentOutfitNum;
1546 if (type(currentOutfitName) == "number") then
1547 currentOutfitNum = currentOutfitName;
1548 else
1549 currentOutfitNum = Wardrobe.GetOutfitNum(currentOutfitName);
1550 end
1551  
1552 Wardrobe.ItemCheckState = { };
1553 local outfit = Wardrobe_Config[WD_realmID][WD_charID].Outfit[currentOutfitNum];
1554 for i = 1, Wardrobe.InventorySlotsSize do
1555 local item = outfit.Item[i];
1556 if (item) and (item.IsSlotUsed == 1) then
1557 Wardrobe.ItemCheckState[i] = 1;
1558 end
1559 end
1560  
1561 local newOutfitNum = Wardrobe.GetNextFreeOutfitSlot(true);
1562  
1563 -- this new outfit will remember what we're about to remove in order to wear our special outfit
1564 Wardrobe.StoreItemsInOutfit(virtualOutfitName, newOutfitNum);
1565  
1566 -- set this outfit to virtual so it'll be hidden and not show up as a normal outfit
1567 Wardrobe_Config[WD_realmID][WD_charID].Outfit[newOutfitNum].Virtual = true;
1568 end
1569  
1570  
1571 ---------------------------------------------------------------------------------
1572 -- If we have a virtual outfit, wear it and delete it
1573 ---------------------------------------------------------------------------------
1574 function Wardrobe.CheckForEquipVirtualOutfit(virtualOutfitName)
1575  
1576 if (not virtualOutfitName) then
1577 virtualOutfitName = WARDROBE_TEMP_OUTFIT_NAME;
1578 end
1579  
1580 if (Wardrobe.FoundOutfitName(virtualOutfitName)) then
1581 Wardrobe.WearOutfit(virtualOutfitName, true);
1582 Wardrobe.EraseOutfit(virtualOutfitName, true, true);
1583 end
1584 end
1585  
1586  
1587 ---------------------------------------------------------------------------------
1588 -- Update whether we have all the items for our outfits in our bags
1589 ---------------------------------------------------------------------------------
1590 function Wardrobe.UpdateOutfitAvailability()
1591  
1592 if (Wardrobe_Config.Enabled and not Wardrobe.InCombat) then
1593  
1594 -- if we haven't already looked up our character's number
1595 Wardrobe.CheckForOurWardrobeID();
1596  
1597 Wardrobe.Debug("Wardrobe Availability:");
1598  
1599 local masterItemList = Wardrobe.BuildItemList();
1600  
1601 -- for each outfit
1602 --for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1603 for i, outfit in Wardrobe_Config[WD_realmID][WD_charID].Outfit do
1604  
1605 -- if it has a name
1606 if (outfit.OutfitName) and (outfit.OutfitName ~= "") then
1607  
1608 local foundAllItems = true;
1609  
1610 -- for each item in the outfit
1611 --for j = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit[i].Item) do
1612 for j, item in outfit.Item do
1613  
1614 -- if this slot is used in this outfit
1615 if (item) and (item.IsSlotUsed == 1) then
1616  
1617 if (item.ItemID) and (item.Suffix) and (item.PermEnchant) then
1618 local foundTheItem = false;
1619 for k = 1, table.getn(masterItemList) do
1620 if (item.ItemID == masterItemList[k].ItemID) and (item.Suffix == masterItemList[k].Suffix) and (item.PermEnchant == masterItemList[k].PermEnchant) then
1621 foundTheItem = true;
1622 break;
1623 end
1624 end
1625 if (not foundTheItem) then
1626 foundAllItems = false;
1627 break;
1628 end
1629  
1630 elseif (item.Name) and (item.Name ~= "") then
1631  
1632 local foundTheItem = false;
1633 for k = 1, table.getn(masterItemList) do
1634 --{Name = itemName, ItemID = itemID, TempEnchant = tempEnchant}
1635 if (item.Name == masterItemList[k].Name) then
1636 foundTheItem = true;
1637 break;
1638 end
1639 end
1640 if (not foundTheItem) then
1641 foundAllItems = false;
1642 break;
1643 end
1644 end
1645 end
1646 end
1647  
1648 -- if we found all items in our inventory
1649 outfit.Available = foundAllItems;
1650 Wardrobe.Debug(" Outfit \"".. outfit.OutfitName.."\" -- found all items = "..tostring(foundAllItems));
1651 end
1652 end
1653 end
1654 end
1655  
1656  
1657 ---------------------------------------------------------------------------------
1658 -- Determine which outfit we're currently wearing
1659 ---------------------------------------------------------------------------------
1660 function Wardrobe.DetermineActiveOutfit()
1661  
1662 Wardrobe.Debug("Wardrobe.DetermineActiveOutfit: Updating Active Outfit");
1663 local ActiveOutfitList = { };
1664 local foundOutfit = false;
1665  
1666 -- build a reference table of the currently equipped items
1667 Wardrobe.CurrentlyEquippedItemList = { };
1668 for j = 1, Wardrobe.InventorySlotsSize do
1669 local itemID, permEnchant, tempEnchant, suffix, itemName = Wardrobe.GetItemInfoAtInventorySlotNumber(j);
1670 if (itemID) then
1671 Wardrobe.CurrentlyEquippedItemList[j] = {Name = itemName, ItemID = itemID, PermEnchant = permEnchant, TempEnchant = tempEnchant, Suffix = suffix};
1672 end
1673 end
1674  
1675 -- for each outfit
1676 for i, outfit in Wardrobe_Config[WD_realmID][WD_charID].Outfit do
1677  
1678 Wardrobe.Debug(" Working on outfit "..i..": "..outfit.OutfitName);
1679  
1680 foundOutfit = true;
1681  
1682 -- for each slot on our character (hands, neck, head, feet, etc)
1683 for j = 1, Wardrobe.InventorySlotsSize do
1684 local item = outfit.Item[j];
1685 -- if this slot is used in this outfit
1686 if (item) and (item.IsSlotUsed == 1) then
1687 local thisItem = Wardrobe.CurrentlyEquippedItemList[j];
1688 -- if this item is different from what we're already wearing
1689 Wardrobe.Debug(" Working on slot -> "..Wardrobe.InventorySlots[j]);
1690 -- item in inv slot
1691 if (thisItem) and (thisItem.Name) then
1692 Wardrobe.Debug(" Comparing ["..tostring(item.Name).."] with ["..tostring(thisItem.Name).."]");
1693 if (item.ItemID) and (item.Suffix) and (item.PermEnchant) then
1694 if (item.ItemID ~= thisItem.ItemID) or (item.Suffix ~= thisItem.Suffix) or (item.PermEnchant ~= thisItem.PermEnchant) then
1695 foundOutfit = false;
1696 break;
1697 end
1698 elseif (item.Name) and (item.Name ~= "") then
1699 if (item.Name ~= thisItem.Name) then
1700 foundOutfit = false;
1701 break;
1702 end
1703 else
1704 -- Forced empty slot
1705 foundOutfit = false;
1706 break;
1707 end
1708  
1709 -- no item in inv slot
1710 elseif (item.Name) and (item.Name ~= "") then
1711 foundOutfit = false;
1712 break;
1713 end
1714 end
1715 end
1716  
1717 if (foundOutfit) then
1718 table.insert(ActiveOutfitList, i);
1719 end
1720 end
1721  
1722 return ActiveOutfitList;
1723 end
1724  
1725  
1726 function Wardrobe.GetActiveOutfitsTextList()
1727 local activeOutfitList = Wardrobe.DetermineActiveOutfit();
1728 local outfitText = "";
1729 local outfits = Wardrobe_Config[WD_realmID][WD_charID].Outfit;
1730 for i, outfitID in activeOutfitList do
1731 -- don't match special outfits
1732 local buttonColorTable = WARDROBE_TEXTCOLORS[outfits[outfitID].ButtonColor];
1733 local name = outfits[outfitID].OutfitName;
1734 if (strsub(name, 1, 1) ~= "#") then
1735 outfitText = outfitText..", |c"..Wardrobe.colorToString(buttonColorTable)..name.."|r";
1736 end
1737 end
1738 if (outfitText == "") then
1739 return TEXT("TXT_NO_OUTFIT");
1740 else
1741 return strsub(outfitText, 3);
1742 end
1743 end
1744  
1745 function Wardrobe.GetListOfOutfits()
1746 Wardrobe.CheckForOurWardrobeID();
1747 Wardrobe.UpdateOutfitAvailability();
1748 local activeOutfits = Wardrobe.DetermineActiveOutfit();
1749 Wardrobe.ActiveOutfitList = activeOutfits;
1750 local outfitTable = {};
1751 for i, outfit in Wardrobe_Config[WD_realmID][WD_charID].Outfit do
1752 local nameString = outfit.OutfitName;
1753 if (strsub(nameString, 1, 1) ~= "#") then
1754 if ( Wardrobe.isInList(activeOutfits, i) ) then
1755 nameString = "|c"..Wardrobe.colorToString(WARDROBE_TEXTCOLORS[outfit.ButtonColor])..nameString.."|r";
1756 elseif ( outfit.Available ) then
1757 nameString = "|c"..Wardrobe.colorToString(WARDROBE_DRABCOLORS[outfit.ButtonColor])..nameString.."|r";
1758 else
1759 nameString = "|c"..Wardrobe.colorToString(WARDROBE_UNAVAILIBLECOLOR)..nameString.."|r";
1760 end
1761  
1762 tinsert(outfitTable, nameString);
1763 end
1764 end
1765 return outfitTable;
1766 end
1767  
1768 --============================================================================================--
1769 --============================================================================================--
1770 -- --
1771 -- UTILITY FUNCTIONS --
1772 -- --
1773 --============================================================================================--
1774 --============================================================================================--
1775  
1776  
1777 -----------------------------------------------------------------------------------
1778 -- for in-line coloring (from Sea)
1779 -----------------------------------------------------------------------------------
1780 function Wardrobe.colorToString( color )
1781 if ( not color ) then
1782 return "FFFFFFFF";
1783 end
1784 return format( "%.2X%.2X%.2X%.2X", 255, color[1]*255, color[2]*255, color[3]*255 );
1785 end
1786  
1787 -----------------------------------------------------------------------------------
1788 -- value comparison, returns key/index
1789 -----------------------------------------------------------------------------------
1790 function Wardrobe.isInList( list, value )
1791 if ( not list or not value ) then
1792 return;
1793 end
1794 for k, v in list do
1795 if (v == value) then
1796 return k;
1797 end
1798 end
1799 end
1800  
1801 -----------------------------------------------------------------------------------
1802 -- Our own print function
1803 -----------------------------------------------------------------------------------
1804 function Wardrobe.Print(theMsg, r, g, b)
1805  
1806 -- 0.50, 0.50, 1.00
1807 if (not r) then r = 0.50; end
1808 if (not g) then g = 0.50; end
1809 if (not b) then b = 1.00; end
1810  
1811 if (type(theMsg) == "table") then
1812 Print(asText(theMsg), r, g, b);
1813 else
1814 Print(theMsg, r, g, b);
1815 end
1816 end
1817  
1818  
1819 -----------------------------------------------------------------------------------
1820 -- Toggle the plugin on and off
1821 -----------------------------------------------------------------------------------
1822 function Wardrobe.Toggle(toggle)
1823 if (toggle == 1) then
1824 if (not Khaos) then
1825 Wardrobe.Print(TEXT("TXT_ENABLED"));
1826 end
1827 Wardrobe_Config.Enabled = true;
1828 Wardrobe.TitanUpdateMinimapStatus(true);
1829 else
1830 if (not Khaos) then
1831 Wardrobe.Print(TEXT("TXT_DISABLED"));
1832 end
1833 Wardrobe_Config.Enabled = false;
1834 Wardrobe.TitanUpdateMinimapStatus(false);
1835 end
1836 end
1837  
1838  
1839 -----------------------------------------------------------------------------------
1840 -- Nifty little function to view any lua object as text
1841 -----------------------------------------------------------------------------------
1842 function asText(obj)
1843  
1844 visitRef = {}
1845 visitRef.n = 0
1846  
1847 asTxRecur = function(obj, asIndex)
1848 if type(obj) == "table" then
1849 if visitRef[obj] then
1850 return "@"..visitRef[obj]
1851 end
1852 visitRef.n = visitRef.n +1
1853 visitRef[obj] = visitRef.n
1854  
1855 local begBrac, endBrac
1856 if asIndex then
1857 begBrac, endBrac = "[{", "}]"
1858 else
1859 begBrac, endBrac = "{", "}"
1860 end
1861 local t = begBrac
1862 local k, v = nil, nil
1863 repeat
1864 k, v = next(obj, k)
1865 if k ~= nil then
1866 if t > begBrac then
1867 t = t..", "
1868 end
1869 t = t..asTxRecur(k, 1).."="..asTxRecur(v)
1870 end
1871 until k == nil
1872 return t..endBrac
1873 else
1874 if asIndex then
1875 -- we're on the left side of an "="
1876 if type(obj) == "string" then
1877 return obj
1878 else
1879 return "["..obj.."]"
1880 end
1881 else
1882 -- we're on the right side of an "="
1883 if type(obj) == "string" then
1884 return '"'..obj..'"'
1885 else
1886 return tostring(obj)
1887 end
1888 end
1889 end
1890 end -- asTxRecur
1891  
1892 return asTxRecur(obj)
1893 end -- asText
1894  
1895  
1896 ---------------------------------------------------------------------------------
1897 -- Display the help text
1898 ---------------------------------------------------------------------------------
1899 function Wardrobe.ShowHelp()
1900 Wardrobe.Print(TEXT("HELP_1")..WARDROBE_VERSION);
1901 Wardrobe.Print(TEXT("HELP_2"));
1902 Wardrobe.Print(TEXT("HELP_3"));
1903 Wardrobe.Print(TEXT("HELP_4"));
1904 Wardrobe.Print(TEXT("HELP_5"));
1905 Wardrobe.Print(TEXT("HELP_6"));
1906 Wardrobe.Print(TEXT("HELP_7"));
1907 Wardrobe.Print(TEXT("HELP_8"));
1908 Wardrobe.Print(TEXT("HELP_9"));
1909 Wardrobe.Print(TEXT("HELP_10"));
1910 Wardrobe.Print(TEXT("HELP_11"));
1911 Wardrobe.Print(TEXT("HELP_12"));
1912 Wardrobe.Print(TEXT("HELP_13"));
1913 Wardrobe.Print(TEXT("HELP_14"));
1914 Wardrobe.Print(TEXT("HELP_15"));
1915 Wardrobe.Print(TEXT("HELP_16"));
1916 end
1917  
1918  
1919  
1920 --============================================================================================--
1921 --============================================================================================--
1922 -- --
1923 -- DEBUG FUNCTIONS --
1924 -- --
1925 --============================================================================================--
1926 --============================================================================================--
1927  
1928  
1929 -----------------------------------------------------------------------------------
1930 -- Print out a debug statement if the WARDROBE_DEBUG flag is set
1931 -----------------------------------------------------------------------------------
1932 function Wardrobe.Debug(theMsg)
1933 if (WARDROBE_DEBUG) then
1934 ChatFrame1:AddMessage(theMsg, 1.0, 1.0, 0.7);
1935 end
1936 end
1937  
1938  
1939 ---------------------------------------------------------------------------------
1940 -- Toggle debug output
1941 ---------------------------------------------------------------------------------
1942 function Wardrobe.ToggleDebug()
1943 WARDROBE_DEBUG = not WARDROBE_DEBUG;
1944 if (WARDROBE_DEBUG) then
1945 Print("Wardrobe: Debug ON",1.0,1.0,0.5);
1946 else
1947 Print("Wardrobe: Debug OFF",1.0,1.0,0.5);
1948 end
1949 end
1950  
1951  
1952 ---------------------------------------------------------------------------------
1953 -- Debug routine to print the current state of the plugin
1954 ---------------------------------------------------------------------------------
1955 function Wardrobe.DumpDebugReport()
1956  
1957 Wardrobe.CheckForOurWardrobeID();
1958  
1959 Wardrobe.Debug("Wardrobe.DumpDebugReport: Character's wardrobe database");
1960 local WardrobeDatabase = Wardrobe_Config[WD_realmID][WD_charID];
1961 for outfitNum, outfit in WardrobeDatabase.Outfit do
1962 Wardrobe.Debug("Outfit: "..tostring(outfit.OutfitName));
1963 for i, item in outfit.Item do
1964 if (item) then
1965 Wardrobe.Debug(Wardrobe.InventorySlots[i].." = "..tostring(item.Name));
1966 end
1967 end
1968 end
1969 end
1970  
1971  
1972  
1973 ---------------------------------------------------------------------------------
1974 -- Print a debug report
1975 ---------------------------------------------------------------------------------
1976 function Wardrobe.DumpDebugStruct()
1977 for i = 1, table.getn(Wardrobe_Config[WD_realmID][WD_charID].Outfit) do
1978 Print("Outfit #"..i..":");
1979 Print(asText(Wardrobe_Config[WD_realmID][WD_charID].Outfit[i]));
1980 Print("--------------------");
1981 end
1982 end
1983  
1984