annotate Core.lua @ 7:1a815139e4c3 v0.1.1-BETA

Fixed pullout hiding to avoid fatal errors. Updated TOC to include dependencies. Updated summary to stop timer when closing the window and to make AH mods optional.
author Zerotorescue
date Fri, 08 Oct 2010 17:10:34 +0200
parents 9fff13c08f99
children 3bac0bdd59e2
rev   line source
Zerotorescue@0 1 -- You can access this addon's object through: LibStub("AceAddon-3.0"):GetAddon("Inventory")
Zerotorescue@1 2 local addon = LibStub("AceAddon-3.0"):NewAddon("Inventory", "AceEvent-3.0");
Zerotorescue@1 3
Zerotorescue@1 4 local AceGUI = LibStub("AceGUI-3.0");
Zerotorescue@0 5
Zerotorescue@0 6 local Media = LibStub("LibSharedMedia-3.0");
Zerotorescue@0 7 Media:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.wav]]);
Zerotorescue@0 8 Media:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.wav]]);
Zerotorescue@0 9 Media:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.wav]]);
Zerotorescue@0 10 Media:Register("sound", "Fel Nova", [[Sound\Spells\SeepingGaseous_Fel_Nova.wav]]);
Zerotorescue@0 11 Media:Register("sound", "Fel Portal", [[Sound\Spells\Sunwell_Fel_PortalStand.wav]]);
Zerotorescue@0 12 Media:Register("sound", "Magic Click", [[Sound\interface\MagicClick.wav]]);
Zerotorescue@0 13 Media:Register("sound", "Rubber Ducky", [[Sound\Doodad\Goblin_Lottery_Open01.wav]]);
Zerotorescue@0 14 Media:Register("sound", "Shing!", [[Sound\Doodad\PortcullisActive_Closed.wav]]);
Zerotorescue@0 15 Media:Register("sound", "Simon Chime", [[Sound\Doodad\SimonGame_LargeBlueTree.wav]]);
Zerotorescue@0 16 Media:Register("sound", "Simon Error", [[Sound\Spells\SimonGame_Visual_BadPress.wav]]);
Zerotorescue@0 17 Media:Register("sound", "Simon Start", [[Sound\Spells\SimonGame_Visual_GameStart.wav]]);
Zerotorescue@0 18 Media:Register("sound", "War Drums", [[Sound\Event Sounds\Event_wardrum_ogre.wav]]);
Zerotorescue@0 19 Media:Register("sound", "Wham!", [[Sound\Doodad\PVP_Lordaeron_Door_Open.wav]]);
Zerotorescue@0 20 Media:Register("sound", "Whisper Ping", [[Sound\interface\iTellMessage.wav]]);
Zerotorescue@0 21 Media:Register("sound", "You Will Die!", [[Sound\Creature\CThun\CThunYouWillDIe.wav]]);
Zerotorescue@0 22
Zerotorescue@0 23 local AceConfigDialog, AceConfigRegistry, AceSerializer;
Zerotorescue@0 24 local groupIdToName = {};
Zerotorescue@0 25 local options = {};
Zerotorescue@0 26
Zerotorescue@0 27 function addon:OnInitialize()
Zerotorescue@0 28 self:Debug("OnInitialize");
Zerotorescue@0 29
Zerotorescue@0 30 -- SAVED VARIABLES
Zerotorescue@0 31
Zerotorescue@0 32 local defaults = {
Zerotorescue@0 33 global = {
Zerotorescue@0 34 groups = {},
Zerotorescue@0 35 defaults = {
Zerotorescue@0 36 minimumStock = 60,
Zerotorescue@0 37 alertBelowMinimum = true,
Zerotorescue@0 38 summaryThresholdShow = 10,
Zerotorescue@0 39 restockTarget = 60,
Zerotorescue@0 40 minCraftingQueue = 0.05,
Zerotorescue@0 41 bonusQueue = 0.1,
Zerotorescue@0 42 priceThreshold = 0,
Zerotorescue@1 43 hideFromSummaryWhenBelowPriceThreshold = false,
Zerotorescue@0 44 trackAtCharacters = {},
Zerotorescue@0 45 colors = {
Zerotorescue@0 46 red = 0;
Zerotorescue@0 47 orange = 0.3;
Zerotorescue@0 48 yellow = 0.6;
Zerotorescue@0 49 green = 0.95;
Zerotorescue@0 50 },
Zerotorescue@0 51 },
Zerotorescue@0 52 },
Zerotorescue@0 53 factionrealm = {
Zerotorescue@0 54 characters = {},
Zerotorescue@0 55 },
Zerotorescue@0 56 };
Zerotorescue@0 57
Zerotorescue@0 58 -- Register our saved variables database
Zerotorescue@0 59 self.db = LibStub("AceDB-3.0"):New("InventoryDB", defaults, true);
Zerotorescue@0 60
Zerotorescue@0 61 -- SLASH COMMANDS
Zerotorescue@0 62
Zerotorescue@0 63 -- Disable the AddonLoader slash commands
Zerotorescue@0 64 SLASH_INVENTORY1 = nil;
Zerotorescue@0 65 SLASH_IY1 = nil;
Zerotorescue@0 66
Zerotorescue@0 67 -- Register our own slash commands
Zerotorescue@0 68 SLASH_INVENTORY1 = "/inventory";
Zerotorescue@0 69 SLASH_INVENTORY2 = "/iy";
Zerotorescue@0 70 SlashCmdList["INVENTORY"] = function(msg)
Zerotorescue@0 71 self:CommandHandler(msg);
Zerotorescue@0 72 end
Zerotorescue@0 73
Zerotorescue@0 74 -- INTERFACE OPTIONS
Zerotorescue@0 75
Zerotorescue@0 76 -- Attempt to remove the interface options added by AddonLoader (if enabled)
Zerotorescue@0 77 if AddonLoader and AddonLoader.RemoveInterfaceOptions then
Zerotorescue@0 78 AddonLoader:RemoveInterfaceOptions("Inventory");
Zerotorescue@0 79 end
Zerotorescue@0 80
Zerotorescue@0 81 -- Now create our own options frame
Zerotorescue@0 82 local frame = CreateFrame("Frame", nil, UIParent);
Zerotorescue@0 83 frame:Hide();
Zerotorescue@0 84 frame.name = "Inventory";
Zerotorescue@0 85 frame:HookScript("OnShow", function(self)
Zerotorescue@0 86 -- Refresh the frame to instantly show the right options
Zerotorescue@0 87 InterfaceOptionsFrame_OpenToCategory(self.name)
Zerotorescue@0 88 end);
Zerotorescue@0 89 -- And add it to the interface options
Zerotorescue@0 90 InterfaceOptions_AddCategory(frame);
Zerotorescue@0 91
Zerotorescue@1 92 self:MakeItemLinkButtonWidget();
Zerotorescue@1 93 self:MakeConfigItemLinkButtonWidget();
Zerotorescue@0 94
Zerotorescue@0 95 -- Remember this character is mine
Zerotorescue@0 96 local playerName = UnitName("player");
Zerotorescue@0 97 if not self.db.factionrealm.characters[playerName] then
Zerotorescue@0 98 self.db.factionrealm.characters[playerName] = true;
Zerotorescue@0 99
Zerotorescue@0 100 -- Default to tracking on all chars, untracking is a convenience, not tracking by default would probably get multiple issue reports.
Zerotorescue@0 101 self.db.global.defaults.trackAtCharacters[playerName] = true;
Zerotorescue@0 102 end
Zerotorescue@0 103 end
Zerotorescue@0 104
Zerotorescue@1 105 local slashArgs = {};
Zerotorescue@1 106 function addon:RegisterSlash(func, ...)
Zerotorescue@1 107 for _, arg in pairs({ ... }) do
Zerotorescue@1 108 slashArgs[arg] = func;
Zerotorescue@1 109 end
Zerotorescue@1 110 end
Zerotorescue@1 111
Zerotorescue@1 112 function addon:MakeItemLinkButtonWidget()
Zerotorescue@0 113 --[[
Zerotorescue@0 114 [ ItemLinkButton ]
Zerotorescue@1 115 This custom widget has to show an icon with the item link next to it.
Zerotorescue@1 116 Upon hover it must show the item tooltip.
Zerotorescue@1 117 Upon click it must execute the function provided through user data.
Zerotorescue@1 118
Zerotorescue@1 119 UserData: itemId, onClickEvent
Zerotorescue@1 120
Zerotorescue@0 121 OnEnter: tooltip show
Zerotorescue@1 122 OnLeave: tooltip hide
Zerotorescue@1 123 OnClick: UserData.onClickEvent
Zerotorescue@0 124 ]]
Zerotorescue@0 125
Zerotorescue@0 126 local widgetType = "ItemLinkButton";
Zerotorescue@0 127 local widgetVersion = 1;
Zerotorescue@0 128
Zerotorescue@1 129 local function Constructor()
Zerotorescue@1 130 local widget = AceGUI:Create("InteractiveLabel");
Zerotorescue@1 131 widget.type = widgetType;
Zerotorescue@1 132
Zerotorescue@1 133 -- We overwrite the OnAcquire as we want to set our callbacks even
Zerotorescue@1 134 -- when the widget is re-used from the widget pool
Zerotorescue@1 135 widget.originalOnAcquire = widget.OnAcquire;
Zerotorescue@1 136 widget.OnAcquire = function(self, ...)
Zerotorescue@1 137
Zerotorescue@1 138
Zerotorescue@1 139 -- We overwrite the setcallback because we don't want anything else
Zerotorescue@1 140 -- to overwrite our OnEnter, OnLeave and OnClick events
Zerotorescue@1 141 -- which would be done by the AceConfigDialog after a widget gets re-used
Zerotorescue@1 142 if not self.originalSetCallBack then
Zerotorescue@1 143 self.originalSetCallBack = self.SetCallback;
Zerotorescue@1 144 self.SetCallback = function(this, event, func, ...)
Zerotorescue@1 145 if event == "OnEnter" or event == "OnLeave" or event == "OnClick" then
Zerotorescue@1 146 -- Don't allow overwriting of these events
Zerotorescue@1 147 return;
Zerotorescue@1 148 elseif event == "CustomOnEnter" then
Zerotorescue@1 149 return this.originalSetCallBack(this, "OnEnter", func, ...);
Zerotorescue@1 150 elseif event == "CustomOnLeave" then
Zerotorescue@1 151 return this.originalSetCallBack(this, "OnLeave", func, ...);
Zerotorescue@1 152 elseif event == "CustomOnClick" then
Zerotorescue@1 153 return this.originalSetCallBack(this, "OnClick", func, ...);
Zerotorescue@1 154 else
Zerotorescue@1 155 return this.originalSetCallBack(this, event, func, ...);
Zerotorescue@1 156 end
Zerotorescue@1 157 end;
Zerotorescue@1 158 end
Zerotorescue@1 159
Zerotorescue@1 160
Zerotorescue@1 161 -- Set our own events, since we disabled the normal event-names, we'll call them our custom versions
Zerotorescue@1 162 self:SetCallback("CustomOnEnter", function(this)
Zerotorescue@1 163 local itemId = this:GetUserData("itemId");
Zerotorescue@1 164
Zerotorescue@1 165 if itemId then
Zerotorescue@1 166 GameTooltip:SetOwner(this.frame, "ANCHOR_TOPRIGHT");
Zerotorescue@1 167 GameTooltip:SetHyperlink(("item:%d"):format(itemId));
Zerotorescue@1 168 GameTooltip:Show();
Zerotorescue@1 169 end
Zerotorescue@1 170 end);
Zerotorescue@1 171 self:SetCallback("CustomOnLeave", function(this)
Zerotorescue@1 172 GameTooltip:Hide();
Zerotorescue@1 173 end);
Zerotorescue@1 174 self:SetCallback("CustomOnClick", function(this)
Zerotorescue@1 175 if this.OnClick then
Zerotorescue@1 176 this.OnClick(this);
Zerotorescue@1 177 end
Zerotorescue@1 178
Zerotorescue@1 179 local func = this:GetUserData("exec");
Zerotorescue@1 180 local itemId = this:GetUserData("itemId");
Zerotorescue@1 181
Zerotorescue@1 182 if func then
Zerotorescue@1 183 -- If this is a config option we will need the group id
Zerotorescue@1 184 local path = this:GetUserData("path");
Zerotorescue@1 185 local groupId = (path and path[2]) or nil;
Zerotorescue@1 186
Zerotorescue@1 187 func(groupId, itemId);
Zerotorescue@1 188 end
Zerotorescue@1 189 end);
Zerotorescue@1 190
Zerotorescue@1 191
Zerotorescue@1 192
Zerotorescue@1 193 -- Then also do whatever it wanted to do
Zerotorescue@1 194 self.originalOnAcquire(self, ...);
Zerotorescue@1 195 end;
Zerotorescue@1 196
Zerotorescue@1 197 -- Remember the original SetText as this might get overwritten by the config-widget
Zerotorescue@1 198 widget.originalSetText = widget.SetText;
Zerotorescue@1 199
Zerotorescue@1 200 widget.SetItemId = function(self, itemId)
Zerotorescue@1 201 self:SetUserData("itemId", itemId);
Zerotorescue@1 202
Zerotorescue@1 203 -- Put the icon in front of it
Zerotorescue@1 204 self:SetImage(GetItemIcon(itemId));
Zerotorescue@0 205 -- Standardize the size
Zerotorescue@0 206 self:SetImageSize(16, 16);
Zerotorescue@0 207
Zerotorescue@0 208 -- Make readable font
Zerotorescue@0 209 self:SetFontObject(GameFontHighlight);
Zerotorescue@0 210
Zerotorescue@0 211 -- We don't want to set the itemId as text, but rather the item link, so get that.
Zerotorescue@1 212 local itemLink = select(2, GetItemInfo(itemId)) or ("Unknown (#%d)"):format(itemId);
Zerotorescue@0 213
Zerotorescue@1 214 self:originalSetText(itemLink);
Zerotorescue@1 215 end;
Zerotorescue@1 216
Zerotorescue@1 217 return widget;
Zerotorescue@0 218 end
Zerotorescue@1 219
Zerotorescue@1 220 AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion);
Zerotorescue@1 221 end
Zerotorescue@1 222
Zerotorescue@1 223 function addon:MakeConfigItemLinkButtonWidget()
Zerotorescue@1 224 -- Define out custom item link button widget
Zerotorescue@1 225 -- This will be called as if it's an input element, we overwrite some of the related functions which are called for default input fields
Zerotorescue@0 226
Zerotorescue@1 227 local widgetType = "ConfigItemLinkButton";
Zerotorescue@1 228 local widgetVersion = 1;
Zerotorescue@0 229
Zerotorescue@1 230 -- Empty function for disabling functions
Zerotorescue@1 231 local function Dummy() end
Zerotorescue@0 232
Zerotorescue@0 233 -- Makes an instance of our ItemLinkButton widget
Zerotorescue@0 234 local function GetItemLinkButton()
Zerotorescue@1 235 local widget = AceGUI:Create("ItemLinkButton");
Zerotorescue@0 236 widget.type = widgetType;
Zerotorescue@0 237
Zerotorescue@0 238 -- We can only provide custom widgets for input, select and multiselect fields
Zerotorescue@0 239 -- Input being the simplest, we use that - however, it provides two parameters: label and text. We only need one, disable the other.
Zerotorescue@0 240 widget.SetLabel = Dummy;
Zerotorescue@0 241
Zerotorescue@1 242 -- SetText is called when this button is being created and contains the itemId
Zerotorescue@1 243 -- Forward that itemId to the ItemLinkButton
Zerotorescue@1 244 widget.SetText = function(self, value, ...)
Zerotorescue@1 245 if value and tonumber(value) then
Zerotorescue@1 246 self:SetItemId(tonumber(value));
Zerotorescue@1 247 end
Zerotorescue@1 248 end;
Zerotorescue@1 249
Zerotorescue@1 250 widget.OnClick = function(self, ...)
Zerotorescue@1 251 local option = self:GetUserData("option");
Zerotorescue@1 252
Zerotorescue@1 253 if option and option.set then
Zerotorescue@1 254 self:SetUserData("exec", option.set);
Zerotorescue@1 255 end
Zerotorescue@1 256 end;
Zerotorescue@0 257
Zerotorescue@0 258 return widget;
Zerotorescue@0 259 end
Zerotorescue@0 260
Zerotorescue@0 261 AceGUI:RegisterWidgetType(widgetType, GetItemLinkButton, widgetVersion);
Zerotorescue@0 262 end
Zerotorescue@0 263
Zerotorescue@0 264 function addon:CommandHandler(message)
Zerotorescue@0 265 local cmd, arg = string.split(" ", (message or ""), 2);
Zerotorescue@0 266 cmd = string.lower(cmd);
Zerotorescue@0 267
Zerotorescue@0 268 if cmd == "c" or cmd == "config" or cmd == "conf" or cmd == "option" or cmd == "options" or cmd == "opt" or cmd == "setting" or cmd == "settings" then
Zerotorescue@0 269 self:Show();
Zerotorescue@0 270 elseif cmd == "d" or cmd == "debug" then
Zerotorescue@0 271 self.debugChannel = false;
Zerotorescue@0 272 for i = 1, NUM_CHAT_WINDOWS do
Zerotorescue@0 273 local name = GetChatWindowInfo(i);
Zerotorescue@0 274
Zerotorescue@0 275 if name:upper() == "DEBUG" then
Zerotorescue@0 276 self.debugChannel = _G["ChatFrame" .. i];
Zerotorescue@0 277
Zerotorescue@0 278 print("A debug channel already exists, used the old one. (" .. i .. ")");
Zerotorescue@0 279 return;
Zerotorescue@0 280 end
Zerotorescue@0 281 end
Zerotorescue@0 282
Zerotorescue@0 283 if not self.debugChannel then
Zerotorescue@0 284 -- Create a new debug channel
Zerotorescue@0 285 local chatFrame = FCF_OpenNewWindow('Debug');
Zerotorescue@0 286 ChatFrame_RemoveAllMessageGroups(chatFrame);
Zerotorescue@0 287 self.debugChannel = chatFrame;
Zerotorescue@0 288
Zerotorescue@0 289 print("New debug channel created.");
Zerotorescue@0 290 end
Zerotorescue@1 291 elseif slashArgs[cmd] then
Zerotorescue@1 292 slashArgs[cmd]();
Zerotorescue@0 293 else
Zerotorescue@0 294 print("Wrong command, available: /inventory config (or /inventory c)");
Zerotorescue@0 295 end
Zerotorescue@0 296 end
Zerotorescue@0 297
Zerotorescue@0 298 function addon:Load()
Zerotorescue@0 299 if not AceConfigDialog and not AceConfigRegistry then
Zerotorescue@0 300 self:FillOptions();
Zerotorescue@0 301
Zerotorescue@0 302 -- Build options dialog
Zerotorescue@0 303 AceConfigDialog = LibStub("AceConfigDialog-3.0");
Zerotorescue@0 304 AceConfigRegistry = LibStub("AceConfigRegistry-3.0");
Zerotorescue@0 305 -- Register options table
Zerotorescue@0 306 LibStub("AceConfig-3.0"):RegisterOptionsTable("InventoryOptions", options);
Zerotorescue@0 307 -- Set a nice default size (so that 4 normal sized elements fit next to eachother)
Zerotorescue@0 308 AceConfigDialog:SetDefaultSize("InventoryOptions", 975, 600);
Zerotorescue@0 309
Zerotorescue@0 310 -- In case the addon is loaded from another condition, always call the remove interface options
Zerotorescue@0 311 if AddonLoader and AddonLoader.RemoveInterfaceOptions then
Zerotorescue@0 312 AddonLoader:RemoveInterfaceOptions("Inventory");
Zerotorescue@0 313 end
Zerotorescue@0 314
Zerotorescue@0 315 -- Add to the blizzard addons options thing
Zerotorescue@0 316 --AceConfigDialog:AddToBlizOptions("InventoryOptions");
Zerotorescue@0 317 end
Zerotorescue@0 318 end
Zerotorescue@0 319
Zerotorescue@0 320 function addon:Show()
Zerotorescue@0 321 self:Load();
Zerotorescue@0 322
Zerotorescue@0 323 AceConfigDialog:Open("InventoryOptions");
Zerotorescue@0 324 end
Zerotorescue@0 325
Zerotorescue@0 326 function addon:FillOptions()
Zerotorescue@0 327 options = {
Zerotorescue@0 328 type = "group",
Zerotorescue@0 329 name = "Inventory",
Zerotorescue@0 330 childGroups = "tree",
Zerotorescue@0 331 args = {
Zerotorescue@0 332 },
Zerotorescue@0 333 };
Zerotorescue@0 334
Zerotorescue@0 335 self:FillGeneralOptions();
Zerotorescue@0 336
Zerotorescue@0 337 options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db, true);
Zerotorescue@0 338 options.args.profiles.order = 200;
Zerotorescue@0 339
Zerotorescue@0 340 self:MakeGroupOptions();
Zerotorescue@0 341
Zerotorescue@0 342 self:FillGroupOptions();
Zerotorescue@0 343 end
Zerotorescue@0 344
Zerotorescue@1 345 local goldText = "%s%d|cffffd700g|r ";
Zerotorescue@1 346 local silverText = "%s%d|cffc7c7cfs|r ";
Zerotorescue@1 347 local copperText = "%s%d|cffeda55fc|r";
Zerotorescue@1 348
Zerotorescue@1 349 function addon:ReadableMoney(copper, clean)
Zerotorescue@1 350 local text = "";
Zerotorescue@1 351
Zerotorescue@1 352 local gold = floor( copper / COPPER_PER_GOLD );
Zerotorescue@1 353 if gold > 0 then
Zerotorescue@1 354 text = goldText:format(text, gold);
Zerotorescue@1 355 end
Zerotorescue@1 356
Zerotorescue@1 357 if not clean or (not gold or gold < 100) then
Zerotorescue@1 358 local silver = floor( ( copper % COPPER_PER_GOLD ) / COPPER_PER_SILVER );
Zerotorescue@1 359 if silver > 0 then
Zerotorescue@1 360 text = silverText:format(text, silver);
Zerotorescue@1 361 end
Zerotorescue@1 362
Zerotorescue@1 363 if not clean or (not gold or gold < 10) then
Zerotorescue@1 364 local copper = floor( copper % COPPER_PER_SILVER );
Zerotorescue@1 365 if copper > 0 or text == "" then
Zerotorescue@1 366 text = copperText:format(text, copper);
Zerotorescue@1 367 end
Zerotorescue@1 368 end
Zerotorescue@1 369 end
Zerotorescue@1 370
Zerotorescue@1 371
Zerotorescue@1 372 return string.trim(text);
Zerotorescue@1 373 end
Zerotorescue@1 374
Zerotorescue@1 375 function addon:ReadableMoneyToCopper(value)
Zerotorescue@1 376 -- If a player enters a value it will be filled without color codes
Zerotorescue@1 377 -- If it is retrieved from the database, it will be colored coded
Zerotorescue@1 378 -- Thus we look for both
Zerotorescue@1 379 local gold = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+g|r") or string.match(value, "(%d+)g"));
Zerotorescue@1 380 local silver = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+s|r") or string.match(value, "(%d+)s"));
Zerotorescue@1 381 local copper = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+c|r") or string.match(value, "(%d+)c"));
Zerotorescue@1 382
Zerotorescue@1 383 return ( (gold or 0) * COPPER_PER_GOLD ) + ( (silver or 0) * COPPER_PER_SILVER ) + (copper or 0);
Zerotorescue@1 384 end
Zerotorescue@1 385
Zerotorescue@1 386 function addon:ValidateReadableMoney(info, value)
Zerotorescue@1 387 -- If a player enters a value it will be filled without color codes
Zerotorescue@1 388 -- If it is retrieved from the database, it will be colored coded
Zerotorescue@1 389 -- Thus we look for both
Zerotorescue@1 390 local gold = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+g|r") or string.match(value, "(%d+)g"));
Zerotorescue@1 391 local silver = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+s|r") or string.match(value, "(%d+)s"));
Zerotorescue@1 392 local copper = tonumber(string.match(value, "(%d+)|c[a-fA-F0-9]+c|r") or string.match(value, "(%d+)c"));
Zerotorescue@1 393
Zerotorescue@1 394 if not gold and not silver and not copper then
Zerotorescue@1 395 return "The provided amount of money is invalid. Please provide the amount of money as #g#s#c, e.g. 591617g24s43c.";
Zerotorescue@1 396 else
Zerotorescue@1 397 return true;
Zerotorescue@1 398 end
Zerotorescue@1 399 end
Zerotorescue@1 400
Zerotorescue@0 401 function addon:FillGeneralOptions()
Zerotorescue@0 402 options.args.general = {
Zerotorescue@0 403 order = 100,
Zerotorescue@0 404 type = "group",
Zerotorescue@0 405 name = "General",
Zerotorescue@0 406 desc = "Change general Inventory settings.",
Zerotorescue@0 407 args = {
Zerotorescue@0 408 general = {
Zerotorescue@0 409 order = 0,
Zerotorescue@0 410 type = "group",
Zerotorescue@0 411 inline = true,
Zerotorescue@0 412 name = "General",
Zerotorescue@0 413 args = {
Zerotorescue@0 414 description = {
Zerotorescue@0 415 order = 0,
Zerotorescue@0 416 type = "description",
Zerotorescue@0 417 name = "Change general settings unrelated to groups.",
Zerotorescue@0 418 },
Zerotorescue@0 419 header = {
Zerotorescue@0 420 order = 5,
Zerotorescue@0 421 type = "header",
Zerotorescue@0 422 name = "",
Zerotorescue@0 423 },
Zerotorescue@0 424 auctionAddon = {
Zerotorescue@0 425 order = 10,
Zerotorescue@0 426 type = "select",
Zerotorescue@0 427 name = "Prefered pricing addon",
Zerotorescue@0 428 values = {
Zerotorescue@0 429 Auctioneer = "Auctioneer",
Zerotorescue@0 430 Auctionator = "Auctionator",
Zerotorescue@0 431 },
Zerotorescue@0 432 get = function() end,
Zerotorescue@0 433 set = function(i, v) end,
Zerotorescue@0 434 },
Zerotorescue@0 435 itemCountAddon = {
Zerotorescue@0 436 order = 20,
Zerotorescue@0 437 type = "select",
Zerotorescue@0 438 name = "Prefered item count addon",
Zerotorescue@0 439 values = {
Zerotorescue@0 440 Altoholic = "Altoholic",
Zerotorescue@0 441 DataStore = "DataStore",
Zerotorescue@0 442 ItemCount = "ItemCount",
Zerotorescue@0 443 },
Zerotorescue@0 444 get = function() end,
Zerotorescue@0 445 set = function(i, v) end,
Zerotorescue@0 446 },
Zerotorescue@0 447 },
Zerotorescue@0 448 },
Zerotorescue@0 449 minimumStock = {
Zerotorescue@0 450 order = 10,
Zerotorescue@0 451 type = "group",
Zerotorescue@0 452 inline = true,
Zerotorescue@0 453 name = "Minimum stock",
Zerotorescue@0 454 args = {
Zerotorescue@0 455 description = {
Zerotorescue@0 456 order = 0,
Zerotorescue@0 457 type = "description",
Zerotorescue@0 458 name = "Here you can specify the default minimum amount of items you wish to keep in stock and related settings. The settings entered here will be used when you choose not to override the settings within an individual group.",
Zerotorescue@0 459 },
Zerotorescue@0 460 header = {
Zerotorescue@0 461 order = 5,
Zerotorescue@0 462 type = "header",
Zerotorescue@0 463 name = "",
Zerotorescue@0 464 },
Zerotorescue@0 465 minimumStock = {
Zerotorescue@0 466 order = 10,
Zerotorescue@0 467 type = "range",
Zerotorescue@0 468 min = 0,
Zerotorescue@0 469 max = 100000,
Zerotorescue@0 470 softMax = 1000,
Zerotorescue@0 471 step = 1,
Zerotorescue@0 472 name = "Minimum stock",
Zerotorescue@0 473 desc = "You can manually enter a value between 1.000 and 100.000 in the edit box if the provided range is insufficient.",
Zerotorescue@0 474 get = function() return self.db.global.defaults.minimumStock; end,
Zerotorescue@0 475 set = function(i, v) self.db.global.defaults.minimumStock = v; end,
Zerotorescue@0 476 },
Zerotorescue@0 477 summaryThresholdShow = {
Zerotorescue@0 478 order = 20,
Zerotorescue@0 479 type = "range",
Zerotorescue@0 480 min = 0,
Zerotorescue@0 481 max = 100,
Zerotorescue@0 482 softMax = 10,
Zerotorescue@0 483 step = 0.05,
Zerotorescue@0 484 isPercent = true,
Zerotorescue@0 485 name = "Show in summary when below",
Zerotorescue@0 486 desc = "Show items in the summary when below this percentage of the minimum stock.\n\nYou can manually enter a value between 1.000% and 10.000% in the edit box if the provided range is insufficient.",
Zerotorescue@0 487 get = function() return self.db.global.defaults.summaryThresholdShow; end,
Zerotorescue@0 488 set = function(i, v) self.db.global.defaults.summaryThresholdShow = v; end,
Zerotorescue@0 489 },
Zerotorescue@0 490 alertBelowMinimum = {
Zerotorescue@0 491 order = 30,
Zerotorescue@0 492 type = "toggle",
Zerotorescue@0 493 name = "Alert when below minimum",
Zerotorescue@0 494 desc = "Show an alert when this item gets below this threshold.",
Zerotorescue@0 495 get = function() return self.db.global.defaults.alertBelowMinimum; end,
Zerotorescue@0 496 set = function(i, v) self.db.global.defaults.alertBelowMinimum = v; end,
Zerotorescue@0 497 },
Zerotorescue@0 498 trackAtCharacters = {
Zerotorescue@0 499 order = 40,
Zerotorescue@0 500 type = "multiselect",
Zerotorescue@0 501 name = "Track at",
Zerotorescue@0 502 desc = "Select at which characters this should appear in the summary and generate alerts.",
Zerotorescue@0 503 values = function()
Zerotorescue@0 504 local temp = {};
Zerotorescue@0 505 for charName in pairs(self.db.factionrealm.characters) do
Zerotorescue@0 506 temp[charName] = charName;
Zerotorescue@0 507 end
Zerotorescue@0 508
Zerotorescue@0 509 return temp;
Zerotorescue@0 510 end,
Zerotorescue@1 511 get = function(i, v) return self.db.global.defaults.trackAtCharacters[v]; end,
Zerotorescue@0 512 set = function(i, v, e)
Zerotorescue@0 513 self.db.global.defaults.trackAtCharacters[v] = e or nil;
Zerotorescue@1 514
Zerotorescue@1 515 -- We MUST close this pullout or we can get errors or even game client crashes once we click another group or close the config dialog!
Zerotorescue@1 516 local count = AceGUI:GetNextWidgetNum("Dropdown-Pullout");
Zerotorescue@7 517 for i = 1, count do
Zerotorescue@1 518 if _G['AceGUI30Pullout' .. i] then
Zerotorescue@1 519 _G['AceGUI30Pullout' .. i]:Hide();
Zerotorescue@1 520 end
Zerotorescue@1 521 end
Zerotorescue@0 522 end,
Zerotorescue@1 523 dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead.
Zerotorescue@0 524 },
Zerotorescue@0 525 },
Zerotorescue@0 526 },
Zerotorescue@0 527 refill = {
Zerotorescue@0 528 order = 20,
Zerotorescue@0 529 type = "group",
Zerotorescue@0 530 inline = true,
Zerotorescue@0 531 name = "Replenishing stock",
Zerotorescue@0 532 args = {
Zerotorescue@0 533 description = {
Zerotorescue@0 534 order = 0,
Zerotorescue@0 535 type = "description",
Zerotorescue@0 536 name = function()
Zerotorescue@0 537 local r = "Here you can specify the default amount of items to which you wish to restock when you are collecting new items. This may be higher than the minimum stock. The settings entered here will be used when you choose not to override the settings within an individual group.\n\n";
Zerotorescue@0 538
Zerotorescue@0 539 r = r .. "When restocking the target amount is |cfffed000" .. self.db.global.defaults.restockTarget .. "|r of every item. Not queueing craftable items when only missing |cfffed000" .. floor( self.db.global.defaults.minCraftingQueue * self.db.global.defaults.restockTarget ) .. "|r (|cfffed000" .. ( self.db.global.defaults.minCraftingQueue * 100 ) .. "%|r) of the restock target.";
Zerotorescue@0 540
Zerotorescue@0 541 return r;
Zerotorescue@0 542 end,
Zerotorescue@0 543 },
Zerotorescue@0 544 header = {
Zerotorescue@0 545 order = 5,
Zerotorescue@0 546 type = "header",
Zerotorescue@0 547 name = "",
Zerotorescue@0 548 },
Zerotorescue@0 549 restockTarget = {
Zerotorescue@0 550 order = 10,
Zerotorescue@0 551 type = "range",
Zerotorescue@0 552 min = 0,
Zerotorescue@0 553 max = 100000,
Zerotorescue@0 554 softMax = 1000,
Zerotorescue@0 555 step = 1,
Zerotorescue@0 556 name = "Restock target",
Zerotorescue@0 557 desc = "You can manually enter a value between 1.000 and 100.000 in the edit box if the provided range is insufficient.",
Zerotorescue@0 558 get = function() return self.db.global.defaults.restockTarget; end,
Zerotorescue@0 559 set = function(i, v) self.db.global.defaults.restockTarget = v; end,
Zerotorescue@0 560 },
Zerotorescue@0 561 minCraftingQueue = {
Zerotorescue@0 562 order = 20,
Zerotorescue@0 563 type = "range",
Zerotorescue@0 564 min = 0,
Zerotorescue@0 565 max = 1,
Zerotorescue@0 566 step = 0.01, -- 1%
Zerotorescue@0 567 isPercent = true,
Zerotorescue@0 568 name = "Don't queue if I only miss",
Zerotorescue@0 569 desc = "Don't add a craftable item to the queue if I only miss this much or less of the restock target.\n\nExample: if your restock target is set to 60 and this is set to 5%, an item won't be queued unless you are missing more than 3 of it.",
Zerotorescue@0 570 get = function() return self.db.global.defaults.minCraftingQueue; end,
Zerotorescue@0 571 set = function(i, v) self.db.global.defaults.minCraftingQueue = v; end,
Zerotorescue@0 572 },
Zerotorescue@0 573 bonusQueue = {
Zerotorescue@0 574 order = 30,
Zerotorescue@0 575 type = "range",
Zerotorescue@0 576 min = 0,
Zerotorescue@0 577 max = 10, -- 1000%
Zerotorescue@0 578 step = 0.01, -- 1%
Zerotorescue@0 579 isPercent = true,
Zerotorescue@0 580 name = "Bonus queue",
Zerotorescue@1 581 desc = "Get additional items when there are none left.\n\nExample: if your restock target is set to 60 and this is set to 10%, you will get 66 items instead of just 60 if you end up with none left while queueing.",
Zerotorescue@0 582 get = function() return self.db.global.defaults.bonusQueue; end,
Zerotorescue@0 583 set = function(i, v) self.db.global.defaults.bonusQueue = v; end,
Zerotorescue@0 584 },
Zerotorescue@0 585 priceThreshold = {
Zerotorescue@0 586 order = 40,
Zerotorescue@0 587 type = "input",
Zerotorescue@0 588 name = "Price threshold",
Zerotorescue@1 589 desc = "Only queue craftable items when they are worth at least this much according to your auction house addon.\n\nSet to 0 to ignore auction prices.",
Zerotorescue@1 590 validate = function(info, value) return self:ValidateReadableMoney(info, value); end,
Zerotorescue@1 591 get = function() return self:ReadableMoney(self.db.global.defaults.priceThreshold); end,
Zerotorescue@1 592 set = function(i, v) self.db.global.defaults.priceThreshold = self:ReadableMoneyToCopper(v); end,
Zerotorescue@0 593 },
Zerotorescue@1 594 hideFromSummaryWhenBelowPriceThreshold = { -- I wish this var could be a little bit shorter...
Zerotorescue@0 595 order = 50,
Zerotorescue@0 596 type = "toggle",
Zerotorescue@1 597 name = "Hide when below threshold",
Zerotorescue@0 598 desc = "Hide items from the summary when their value is below the set price threshold.",
Zerotorescue@1 599 get = function() return self.db.global.defaults.hideFromSummaryWhenBelowPriceThreshold; end,
Zerotorescue@1 600 set = function(i, v) self.db.global.defaults.hideFromSummaryWhenBelowPriceThreshold = v; end,
Zerotorescue@0 601 },
Zerotorescue@0 602 },
Zerotorescue@0 603 },
Zerotorescue@0 604 colorCodes = {
Zerotorescue@0 605 order = 30,
Zerotorescue@0 606 type = "group",
Zerotorescue@0 607 inline = true,
Zerotorescue@0 608 name = "Color codes",
Zerotorescue@0 609 args = {
Zerotorescue@0 610 description = {
Zerotorescue@0 611 order = 0,
Zerotorescue@0 612 type = "description",
Zerotorescue@0 613 name = "Change the color code thresholds based on the current stock remaining of the required minimum stock.",
Zerotorescue@0 614 },
Zerotorescue@0 615 header = {
Zerotorescue@0 616 order = 5,
Zerotorescue@0 617 type = "header",
Zerotorescue@0 618 name = "",
Zerotorescue@0 619 },
Zerotorescue@0 620 green = {
Zerotorescue@0 621 order = 10,
Zerotorescue@0 622 type = "range",
Zerotorescue@0 623 min = 0,
Zerotorescue@0 624 max = 1,
Zerotorescue@0 625 step = 0.01,
Zerotorescue@0 626 isPercent = true,
Zerotorescue@0 627 name = "|cff00ff00Green|r",
Zerotorescue@0 628 desc = "Show quantity in green when at least this much of the minimum stock is available.",
Zerotorescue@0 629 get = function() return self.db.global.defaults.colors.green; end,
Zerotorescue@0 630 set = function(i, v) self.db.global.defaults.colors.green = v; end,
Zerotorescue@0 631 },
Zerotorescue@0 632 yellow = {
Zerotorescue@0 633 order = 20,
Zerotorescue@0 634 type = "range",
Zerotorescue@0 635 min = 0,
Zerotorescue@0 636 max = 1,
Zerotorescue@0 637 step = 0.01,
Zerotorescue@0 638 isPercent = true,
Zerotorescue@0 639 name = "|cffffff00Yellow|r",
Zerotorescue@0 640 desc = "Show quantity in yellow when at least this much of the minimum stock is available.",
Zerotorescue@0 641 get = function() return self.db.global.defaults.colors.yellow; end,
Zerotorescue@0 642 set = function(i, v) self.db.global.defaults.colors.yellow = v; end,
Zerotorescue@0 643 },
Zerotorescue@0 644 orange = {
Zerotorescue@0 645 order = 30,
Zerotorescue@0 646 type = "range",
Zerotorescue@0 647 min = 0,
Zerotorescue@0 648 max = 1,
Zerotorescue@0 649 step = 0.01,
Zerotorescue@0 650 isPercent = true,
Zerotorescue@0 651 name = "|cffff9933Orange|r",
Zerotorescue@0 652 desc = "Show quantity in orange when at least this much of the minimum stock is available.",
Zerotorescue@0 653 get = function() return self.db.global.defaults.colors.orange; end,
Zerotorescue@0 654 set = function(i, v) self.db.global.defaults.colors.orange = v; end,
Zerotorescue@0 655 },
Zerotorescue@0 656 red = {
Zerotorescue@0 657 order = 40,
Zerotorescue@0 658 type = "range",
Zerotorescue@0 659 min = 0,
Zerotorescue@0 660 max = 1,
Zerotorescue@0 661 step = 0.01,
Zerotorescue@0 662 isPercent = true,
Zerotorescue@0 663 name = "|cffff0000Red|r",
Zerotorescue@0 664 desc = "Show quantity in red when at least this much of the minimum stock is available.",
Zerotorescue@0 665 get = function() return self.db.global.defaults.colors.red; end,
Zerotorescue@0 666 set = function(i, v) self.db.global.defaults.colors.red = v; end,
Zerotorescue@0 667 },
Zerotorescue@0 668 },
Zerotorescue@0 669 },
Zerotorescue@0 670 },
Zerotorescue@0 671 };
Zerotorescue@0 672 end
Zerotorescue@0 673
Zerotorescue@0 674 local count = 0;
Zerotorescue@0 675 local temp = {};
Zerotorescue@0 676
Zerotorescue@1 677 local function SetOption(info, value, multiSelectEnabled)
Zerotorescue@0 678 local groupName = groupIdToName[info[2]];
Zerotorescue@0 679 local optionName = info[#info];
Zerotorescue@0 680
Zerotorescue@0 681 -- No need to store a setting if it's disabled (false)
Zerotorescue@0 682 if not value and info.arg and not info.arg:find("override") then
Zerotorescue@0 683 value = nil;
Zerotorescue@0 684
Zerotorescue@0 685 -- If this is an override toggler then also set the related field to nil
Zerotorescue@0 686 addon.db.global.groups[groupName][info.arg] = nil;
Zerotorescue@0 687 end
Zerotorescue@0 688
Zerotorescue@1 689 if multiSelectEnabled ~= nil then
Zerotorescue@1 690 -- The saved vars for a multiselect will always be an array, it may not yet exist in which case it must be created.
Zerotorescue@1 691 if not addon.db.global.groups[groupName][optionName] then
Zerotorescue@1 692 addon.db.global.groups[groupName][optionName] = {};
Zerotorescue@1 693 end
Zerotorescue@1 694
Zerotorescue@1 695 addon.db.global.groups[groupName][optionName][value] = multiSelectEnabled or nil;
Zerotorescue@1 696 else
Zerotorescue@1 697 addon.db.global.groups[groupName][optionName] = value;
Zerotorescue@1 698 end
Zerotorescue@0 699 end
Zerotorescue@0 700
Zerotorescue@1 701 function addon:GetOptionByKey(groupName, optionName, noDefault)
Zerotorescue@0 702 if addon.db.global.groups[groupName][optionName] ~= nil then
Zerotorescue@0 703 return addon.db.global.groups[groupName][optionName];
Zerotorescue@0 704 elseif addon.db.global.defaults[optionName] and not noDefault then
Zerotorescue@0 705 return addon.db.global.defaults[optionName];
Zerotorescue@0 706 else
Zerotorescue@0 707 return nil;
Zerotorescue@0 708 end
Zerotorescue@0 709 end
Zerotorescue@0 710
Zerotorescue@0 711 local function GetOption(info)
Zerotorescue@0 712 local groupName = groupIdToName[info[2]];
Zerotorescue@0 713 local optionName = info[#info];
Zerotorescue@0 714
Zerotorescue@1 715 return addon:GetOptionByKey(groupName, optionName);
Zerotorescue@1 716 end
Zerotorescue@1 717
Zerotorescue@1 718 local function GetMultiOption(info, value)
Zerotorescue@1 719 local groupName = groupIdToName[info[2]];
Zerotorescue@1 720 local optionName = info[#info];
Zerotorescue@1 721
Zerotorescue@1 722 if addon.db.global.groups[groupName][optionName] ~= nil then
Zerotorescue@1 723 return addon.db.global.groups[groupName][optionName][value];
Zerotorescue@1 724 elseif addon.db.global.defaults[optionName] then
Zerotorescue@1 725 return addon.db.global.defaults[optionName][value];
Zerotorescue@1 726 else
Zerotorescue@1 727 return nil;
Zerotorescue@1 728 end
Zerotorescue@0 729 end
Zerotorescue@0 730
Zerotorescue@0 731 local function GetDisabled(info)
Zerotorescue@0 732 if not info.arg or not info.arg:find("override") then
Zerotorescue@0 733 return false;
Zerotorescue@0 734 end
Zerotorescue@0 735
Zerotorescue@0 736 local groupName = groupIdToName[info[2]];
Zerotorescue@0 737 local optionName = info[#info];
Zerotorescue@0 738
Zerotorescue@1 739 return (addon:GetOptionByKey(groupName, info.arg, true) == nil);
Zerotorescue@0 740 end
Zerotorescue@0 741
Zerotorescue@0 742 local function ValidateGroupName(_, value)
Zerotorescue@0 743 value = string.lower(string.trim(value or ""));
Zerotorescue@0 744
Zerotorescue@0 745 for name, _ in pairs(addon.db.global.groups) do
Zerotorescue@0 746 if string.lower(name) == value then
Zerotorescue@0 747 return ("A group named \"%s\" already exists."):format(name);
Zerotorescue@0 748 end
Zerotorescue@0 749 end
Zerotorescue@0 750
Zerotorescue@0 751 return true;
Zerotorescue@0 752 end
Zerotorescue@0 753
Zerotorescue@0 754 local function InGroup(itemId)
Zerotorescue@0 755 -- Go through all groups to see if this item is already somewhere
Zerotorescue@0 756 for groupName, values in pairs(addon.db.global.groups) do
Zerotorescue@0 757 if values.items and values.items[itemId] then
Zerotorescue@0 758 return groupName;
Zerotorescue@0 759 end
Zerotorescue@0 760 end
Zerotorescue@0 761
Zerotorescue@0 762 return;
Zerotorescue@0 763 end
Zerotorescue@0 764
Zerotorescue@0 765 local function AddToGroup(groupName, itemId)
Zerotorescue@0 766 if InGroup(itemId) then
Zerotorescue@0 767 return false;
Zerotorescue@0 768 end
Zerotorescue@0 769
Zerotorescue@0 770 if not addon.db.global.groups[groupName].items then
Zerotorescue@0 771 addon.db.global.groups[groupName].items = {};
Zerotorescue@0 772 end
Zerotorescue@0 773
Zerotorescue@0 774 -- Set this item
Zerotorescue@0 775 addon.db.global.groups[groupName].items[itemId] = true;
Zerotorescue@0 776
Zerotorescue@0 777 -- Now rebuild the list
Zerotorescue@0 778 AceConfigRegistry:NotifyChange("InventoryOptions");
Zerotorescue@0 779
Zerotorescue@0 780 return true;
Zerotorescue@0 781 end
Zerotorescue@0 782
Zerotorescue@0 783 local tblAddItemTemplate = {
Zerotorescue@0 784 order = 0,
Zerotorescue@0 785 type = "input",
Zerotorescue@0 786 name = function(info)
Zerotorescue@0 787 local itemName, _, itemRarity = GetItemInfo(info[#info]);
Zerotorescue@0 788 return tostring( 7 - (itemRarity or 0) ) .. (itemName or "");
Zerotorescue@0 789 end,
Zerotorescue@0 790 get = function(info)
Zerotorescue@0 791 return tostring(info[#info]); -- Ace is going to be anal about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side
Zerotorescue@0 792 end,
Zerotorescue@1 793 set = function(groupId, itemId)
Zerotorescue@0 794 -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info.
Zerotorescue@0 795
Zerotorescue@1 796 if itemId then
Zerotorescue@1 797 local groupName = groupIdToName[groupId];
Zerotorescue@0 798
Zerotorescue@1 799 if not AddToGroup(groupName, itemId) then
Zerotorescue@1 800 print("|cffff0000Couldn't add the item with itemId (" .. itemId .. ") because it is already in a group.|r");
Zerotorescue@0 801 end
Zerotorescue@0 802 end
Zerotorescue@0 803 end,
Zerotorescue@0 804 width = "double",
Zerotorescue@1 805 dialogControl = "ConfigItemLinkButton",
Zerotorescue@0 806 };
Zerotorescue@0 807
Zerotorescue@0 808 local tblRemoveItemTemplate = {
Zerotorescue@0 809 order = 0,
Zerotorescue@0 810 type = "input",
Zerotorescue@0 811 name = function(info)
Zerotorescue@0 812 local itemName, _, itemRarity = GetItemInfo(info[#info]);
Zerotorescue@0 813 return tostring( 7 - (itemRarity or 0) ) .. (itemName or "");
Zerotorescue@0 814 end,
Zerotorescue@0 815 get = function(info)
Zerotorescue@0 816 return tostring(info[#info]); -- Ace is going to be anal about this if it's a numeric value, so we transmute it into a string here then back to a number on the other side
Zerotorescue@0 817 end,
Zerotorescue@1 818 set = function(groupId, itemId)
Zerotorescue@0 819 -- This is NOT a real "set", we pass the widget reference to this function which contains similar, but not the same, info.
Zerotorescue@0 820
Zerotorescue@1 821 if itemId then
Zerotorescue@1 822 local groupName = groupIdToName[groupId];
Zerotorescue@0 823
Zerotorescue@0 824 -- Unset this item
Zerotorescue@1 825 addon.db.global.groups[groupName].items[itemId] = nil;
Zerotorescue@0 826
Zerotorescue@0 827 -- Now rebuild the list
Zerotorescue@0 828 AceConfigRegistry:NotifyChange("InventoryOptions");
Zerotorescue@0 829 end
Zerotorescue@0 830 end,
Zerotorescue@0 831 width = "double",
Zerotorescue@1 832 dialogControl = "ConfigItemLinkButton",
Zerotorescue@0 833 };
Zerotorescue@0 834
Zerotorescue@0 835 local function UpdateAddItemList(info)
Zerotorescue@0 836 local groupName = groupIdToName[info[2]];
Zerotorescue@0 837
Zerotorescue@0 838 if not addon.db.global.groups[groupName].items then
Zerotorescue@0 839 addon.db.global.groups[groupName].items = {};
Zerotorescue@0 840 end
Zerotorescue@0 841
Zerotorescue@0 842 -- Merge all items from all groups together
Zerotorescue@0 843 local items = {};
Zerotorescue@0 844 for groupName, values in pairs(addon.db.global.groups) do
Zerotorescue@0 845 if values.items then
Zerotorescue@0 846 for itemId, _ in pairs(values.items) do
Zerotorescue@0 847 items[itemId] = true;
Zerotorescue@0 848 end
Zerotorescue@0 849 end
Zerotorescue@0 850 end
Zerotorescue@0 851
Zerotorescue@0 852 local ref = options.args.groups.args[info[2]].args.add.args.list.args;
Zerotorescue@0 853
Zerotorescue@0 854 -- Parse bags and show these
Zerotorescue@0 855 for bagID = 4, 0, -1 do
Zerotorescue@0 856 for slot = 1, GetContainerNumSlots(bagID) do
Zerotorescue@0 857 local itemId = addon:GetItemId(GetContainerItemLink(bagID, slot));
Zerotorescue@0 858
Zerotorescue@0 859 if itemId then
Zerotorescue@0 860 if not items[itemId] then
Zerotorescue@0 861 -- If this item isn't used in any group yet
Zerotorescue@0 862 ref[itemId] = tblAddItemTemplate;
Zerotorescue@0 863 else
Zerotorescue@0 864 -- It's already used in a group, don't show it
Zerotorescue@0 865 ref[itemId] = nil;
Zerotorescue@0 866 end
Zerotorescue@0 867 end
Zerotorescue@0 868 end
Zerotorescue@0 869 end
Zerotorescue@0 870 end
Zerotorescue@0 871
Zerotorescue@0 872 local function UpdateRemoveItemList(info)
Zerotorescue@0 873 local groupName = groupIdToName[info[2]];
Zerotorescue@0 874
Zerotorescue@0 875 if not addon.db.global.groups[groupName].items then
Zerotorescue@0 876 addon.db.global.groups[groupName].items = {};
Zerotorescue@0 877 end
Zerotorescue@0 878
Zerotorescue@0 879 local ref = options.args.groups.args[info[2]].args.remove.args.list.args;
Zerotorescue@0 880
Zerotorescue@0 881 -- Unset all
Zerotorescue@0 882 for itemId, _ in pairs(ref) do
Zerotorescue@0 883 ref[itemId] = nil;
Zerotorescue@0 884 end
Zerotorescue@0 885
Zerotorescue@0 886 -- Parse items in group and show these
Zerotorescue@0 887 for itemId, _ in pairs(addon.db.global.groups[groupName].items) do
Zerotorescue@0 888 ref[itemId] = tblRemoveItemTemplate;
Zerotorescue@0 889 end
Zerotorescue@0 890 end
Zerotorescue@0 891
Zerotorescue@0 892 function addon:GetItemId(itemLink)
Zerotorescue@0 893 itemLink = itemLink and select(3, string.find(itemLink, "|Hitem:([-0-9]+):")); -- if itemLink is nil, it won't execute the second part
Zerotorescue@0 894 itemLink = itemLink and tonumber(itemLink);
Zerotorescue@0 895
Zerotorescue@0 896 return itemLink;
Zerotorescue@0 897 end
Zerotorescue@0 898
Zerotorescue@0 899 -- Default group
Zerotorescue@0 900 local defaultGroup = {
Zerotorescue@0 901 order = 0,
Zerotorescue@0 902 type = "group",
Zerotorescue@0 903 childGroups = "tab",
Zerotorescue@0 904 name = function(info)
Zerotorescue@0 905 return groupIdToName[info[#info]];
Zerotorescue@0 906 end,
Zerotorescue@0 907 args = {
Zerotorescue@0 908 general = {
Zerotorescue@0 909 order = 10,
Zerotorescue@0 910 type = "group",
Zerotorescue@0 911 name = "Stock settings",
Zerotorescue@0 912 desc = "Change the stock settings for just this group.",
Zerotorescue@0 913 args = {
Zerotorescue@0 914 minimumStock = {
Zerotorescue@0 915 order = 10,
Zerotorescue@0 916 type = "group",
Zerotorescue@0 917 inline = true,
Zerotorescue@0 918 name = "Minimum stock",
Zerotorescue@0 919 set = SetOption,
Zerotorescue@0 920 get = GetOption,
Zerotorescue@0 921 disabled = GetDisabled,
Zerotorescue@0 922 args = {
Zerotorescue@0 923 description = {
Zerotorescue@0 924 order = 0,
Zerotorescue@0 925 type = "description",
Zerotorescue@0 926 name = "Here you can specify the minimum amount of items you wish to keep in stock and related settings for the currently selected group.",
Zerotorescue@0 927 },
Zerotorescue@0 928 header = {
Zerotorescue@0 929 order = 5,
Zerotorescue@0 930 type = "header",
Zerotorescue@0 931 name = "",
Zerotorescue@0 932 },
Zerotorescue@0 933 overrideMinimumStock = {
Zerotorescue@0 934 order = 9,
Zerotorescue@0 935 type = "toggle",
Zerotorescue@0 936 name = "Override min stock",
Zerotorescue@0 937 desc = "Allows you to override the minimum stock setting for this group.",
Zerotorescue@0 938 arg = "minimumStock",
Zerotorescue@0 939 },
Zerotorescue@0 940 minimumStock = {
Zerotorescue@0 941 order = 10,
Zerotorescue@0 942 type = "range",
Zerotorescue@0 943 min = 0,
Zerotorescue@0 944 max = 100000,
Zerotorescue@0 945 softMax = 1000,
Zerotorescue@0 946 step = 1,
Zerotorescue@0 947 name = "Minimum stock",
Zerotorescue@0 948 desc = "You can manually enter a value between 1.000 and 100.000 in the edit box if the provided range is insufficient.",
Zerotorescue@0 949 arg = "overrideMinimumStock",
Zerotorescue@0 950 },
Zerotorescue@0 951 overrideSummaryThresholdShow = {
Zerotorescue@0 952 order = 19,
Zerotorescue@0 953 type = "toggle",
Zerotorescue@0 954 name = "Override summary showing",
Zerotorescue@0 955 desc = "Allows you to override when this group should appear in the summary.",
Zerotorescue@0 956 arg = "summaryThresholdShow",
Zerotorescue@0 957 },
Zerotorescue@0 958 summaryThresholdShow = {
Zerotorescue@0 959 order = 20,
Zerotorescue@0 960 type = "range",
Zerotorescue@0 961 min = 0,
Zerotorescue@0 962 max = 100,
Zerotorescue@0 963 softMax = 10,
Zerotorescue@0 964 step = 0.05,
Zerotorescue@0 965 isPercent = true,
Zerotorescue@0 966 name = "Show in summary when below",
Zerotorescue@0 967 desc = "Show items in the summary when below the specified percentage of the minimum stock.\n\nYou can manually enter a value between 1.000% and 10.000% in the edit box if the provided range is insufficient.",
Zerotorescue@0 968 arg = "overrideSummaryThresholdShow",
Zerotorescue@0 969 },
Zerotorescue@0 970 overrideAlertBelowMinimum = {
Zerotorescue@0 971 order = 29,
Zerotorescue@0 972 type = "toggle",
Zerotorescue@0 973 name = "Override minimum alert",
Zerotorescue@0 974 desc = "Allows you to override wether an alert should be shown when an item in this group gets below the minimum stock threshold.",
Zerotorescue@0 975 arg = "alertBelowMinimum",
Zerotorescue@0 976 },
Zerotorescue@0 977 alertBelowMinimum = {
Zerotorescue@0 978 order = 30,
Zerotorescue@0 979 type = "toggle",
Zerotorescue@0 980 name = "Alert when below minimum",
Zerotorescue@0 981 desc = "Show an alert when an item in this group gets below the minimum stock threshold.",
Zerotorescue@0 982 arg = "overrideAlertBelowMinimum",
Zerotorescue@0 983 },
Zerotorescue@1 984 overrideTrackAtCharacters = {
Zerotorescue@1 985 order = 39,
Zerotorescue@1 986 type = "toggle",
Zerotorescue@1 987 name = "Override track at",
Zerotorescue@1 988 desc = "Allows you to override at which characters items in this group should appear in the summary and generate alerts.",
Zerotorescue@1 989 arg = "trackAtCharacters",
Zerotorescue@1 990 },
Zerotorescue@1 991 trackAtCharacters = {
Zerotorescue@1 992 order = 40,
Zerotorescue@1 993 type = "multiselect",
Zerotorescue@1 994 name = "Track at",
Zerotorescue@1 995 desc = "Select at which characters this should appear in the summary and generate alerts.",
Zerotorescue@1 996 values = function()
Zerotorescue@1 997 local temp = {};
Zerotorescue@1 998 for charName in pairs(addon.db.factionrealm.characters) do
Zerotorescue@1 999 temp[charName] = charName;
Zerotorescue@1 1000 end
Zerotorescue@1 1001
Zerotorescue@1 1002 -- We MUST close this pullout or we can get errors or even game client crashes once we click another group or close the config dialog!
Zerotorescue@1 1003 local count = AceGUI:GetNextWidgetNum("Dropdown-Pullout");
Zerotorescue@7 1004 for i = 1, count do
Zerotorescue@1 1005 if _G['AceGUI30Pullout' .. i] then
Zerotorescue@1 1006 _G['AceGUI30Pullout' .. i]:Hide();
Zerotorescue@1 1007 end
Zerotorescue@1 1008 end
Zerotorescue@1 1009
Zerotorescue@1 1010 return temp;
Zerotorescue@1 1011 end,
Zerotorescue@1 1012 get = GetMultiOption,
Zerotorescue@1 1013 dialogControl = "Dropdown", -- this is not standard, normal multiselect control gives us a list of all chars with toggle-boxes. UGLY! We want a multiselect-box instead.
Zerotorescue@1 1014 arg = "overrideTrackAtCharacters",
Zerotorescue@1 1015 },
Zerotorescue@0 1016 },
Zerotorescue@0 1017 },
Zerotorescue@0 1018 refill = {
Zerotorescue@0 1019 order = 20,
Zerotorescue@0 1020 type = "group",
Zerotorescue@0 1021 inline = true,
Zerotorescue@0 1022 name = "Replenishing stock",
Zerotorescue@0 1023 set = SetOption,
Zerotorescue@0 1024 get = GetOption,
Zerotorescue@0 1025 disabled = GetDisabled,
Zerotorescue@0 1026 args = {
Zerotorescue@0 1027 description = {
Zerotorescue@0 1028 order = 0,
Zerotorescue@0 1029 type = "description",
Zerotorescue@0 1030 name = function(info)
Zerotorescue@0 1031 local groupName = groupIdToName[info[2]];
Zerotorescue@0 1032 local r = "Here you can specify the amount of items to which you wish to restock when you are collecting new items for the currently selected group. This may be higher than the minimum stock.\n\n";
Zerotorescue@0 1033
Zerotorescue@1 1034 r = r .. "When restocking the target amount is |cfffed000" .. addon:GetOptionByKey(groupName, "restockTarget") .. "|r of every item. Not queueing craftable items when only missing |cfffed000" .. floor( addon:GetOptionByKey(groupName, "minCraftingQueue") * addon:GetOptionByKey(groupName, "restockTarget") ) .. "|r (|cfffed000" .. ( addon:GetOptionByKey(groupName, "minCraftingQueue") * 100 ) .. "%|r) of the restock target.";
Zerotorescue@0 1035
Zerotorescue@0 1036 return r;
Zerotorescue@0 1037 end,
Zerotorescue@0 1038 },
Zerotorescue@0 1039 header = {
Zerotorescue@0 1040 order = 5,
Zerotorescue@0 1041 type = "header",
Zerotorescue@0 1042 name = "",
Zerotorescue@0 1043 },
Zerotorescue@0 1044 overrideRestockTarget = {
Zerotorescue@0 1045 order = 9,
Zerotorescue@0 1046 type = "toggle",
Zerotorescue@0 1047 name = "Override restock target",
Zerotorescue@0 1048 desc = "Allows you to override the restock target setting for this group.",
Zerotorescue@0 1049 arg = "restockTarget",
Zerotorescue@0 1050 },
Zerotorescue@0 1051 restockTarget = {
Zerotorescue@0 1052 order = 10,
Zerotorescue@0 1053 type = "range",
Zerotorescue@0 1054 min = 0,
Zerotorescue@0 1055 max = 100000,
Zerotorescue@0 1056 softMax = 1000,
Zerotorescue@0 1057 step = 1,
Zerotorescue@0 1058 name = "Restock target",
Zerotorescue@0 1059 desc = "You can manually enter a value between 1.000 and 100.000 in the edit box if the provided range is insufficient.",
Zerotorescue@0 1060 arg = "overrideRestockTarget",
Zerotorescue@0 1061 },
Zerotorescue@0 1062 overrideMinCraftingQueue = {
Zerotorescue@0 1063 order = 19,
Zerotorescue@0 1064 type = "toggle",
Zerotorescue@0 1065 name = "Override min queue",
Zerotorescue@0 1066 desc = "Allows you to override the minimum craftable items queue setting for this group.",
Zerotorescue@0 1067 arg = "minCraftingQueue",
Zerotorescue@0 1068 },
Zerotorescue@0 1069 minCraftingQueue = {
Zerotorescue@0 1070 order = 20,
Zerotorescue@0 1071 type = "range",
Zerotorescue@0 1072 min = 0,
Zerotorescue@0 1073 max = 1,
Zerotorescue@0 1074 step = 0.01,
Zerotorescue@0 1075 isPercent = true,
Zerotorescue@0 1076 name = "Don't queue if I only miss",
Zerotorescue@0 1077 desc = "Don't add a craftable item to the queue if I only miss this much or less of the restock target.\n\nExample: if your restock target is set to 60 and this is set to 5%, an item won't be queued unless you are missing more than 3 of it.",
Zerotorescue@0 1078 arg = "overrideMinCraftingQueue",
Zerotorescue@0 1079 },
Zerotorescue@1 1080 overrideBonusQueue = {
Zerotorescue@1 1081 order = 29,
Zerotorescue@1 1082 type = "toggle",
Zerotorescue@1 1083 name = "Override bonus queue",
Zerotorescue@1 1084 desc = "Allows you to override the bonus craftable items queue setting for this group.",
Zerotorescue@1 1085 arg = "bonusQueue",
Zerotorescue@1 1086 },
Zerotorescue@1 1087 bonusQueue = {
Zerotorescue@1 1088 order = 30,
Zerotorescue@1 1089 type = "range",
Zerotorescue@1 1090 min = 0,
Zerotorescue@1 1091 max = 10, -- 1000%
Zerotorescue@1 1092 step = 0.01, -- 1%
Zerotorescue@1 1093 isPercent = true,
Zerotorescue@1 1094 name = "Bonus queue",
Zerotorescue@1 1095 desc = "Get additional items when there are none left.\n\nExample: if your restock target is set to 60 and this is set to 10%, you will get 66 items instead of just 60 if you end up with none left while queueing.",
Zerotorescue@1 1096 arg = "overrideBonusQueue",
Zerotorescue@1 1097 },
Zerotorescue@1 1098 overridePriceThreshold = {
Zerotorescue@1 1099 order = 39,
Zerotorescue@1 1100 type = "toggle",
Zerotorescue@1 1101 name = "Override price threshold",
Zerotorescue@1 1102 desc = "Allows you to override the price threshold setting for this group.",
Zerotorescue@1 1103 arg = "priceThreshold",
Zerotorescue@1 1104 },
Zerotorescue@1 1105 priceThreshold = {
Zerotorescue@1 1106 order = 40,
Zerotorescue@1 1107 type = "input",
Zerotorescue@1 1108 name = "Price threshold",
Zerotorescue@1 1109 desc = "Only queue craftable items when they are worth at least this much according to your auction house addon.\n\nSet to 0 to ignore auction prices.",
Zerotorescue@1 1110 validate = function(info, value) return addon:ValidateReadableMoney(info, value); end,
Zerotorescue@1 1111 get = function(i) return addon:ReadableMoney(GetOption(i)); end,
Zerotorescue@1 1112 set = function(i, v) SetOption(i, addon:ReadableMoneyToCopper(v)); end,
Zerotorescue@1 1113 arg = "overridePriceThreshold",
Zerotorescue@1 1114 },
Zerotorescue@1 1115 overrideHideFromSummaryWhenBelowPriceThreshold = {
Zerotorescue@1 1116 order = 49,
Zerotorescue@1 1117 type = "toggle",
Zerotorescue@1 1118 name = "Override summary showing",
Zerotorescue@1 1119 desc = "Allows you to override if items in this group should be hidden from the summary while their value is below the price threshold.",
Zerotorescue@1 1120 arg = "hideFromSummaryWhenBelowPriceThreshold",
Zerotorescue@1 1121 },
Zerotorescue@1 1122 hideFromSummaryWhenBelowPriceThreshold = { -- I wish this var could be a little bit shorter...
Zerotorescue@1 1123 order = 50,
Zerotorescue@1 1124 type = "toggle",
Zerotorescue@1 1125 name = "Hide when below threshold",
Zerotorescue@1 1126 desc = "Hide items from the summary when their value is below the set price threshold.",
Zerotorescue@1 1127 arg = "overrideHideFromSummaryWhenBelowPriceThreshold",
Zerotorescue@1 1128 },
Zerotorescue@0 1129 },
Zerotorescue@0 1130 },
Zerotorescue@0 1131 },
Zerotorescue@0 1132 },
Zerotorescue@0 1133 group = {
Zerotorescue@0 1134 order = 20,
Zerotorescue@0 1135 type = "group",
Zerotorescue@0 1136 name = "Group Management",
Zerotorescue@0 1137 desc = "Rename, delete or export this group.",
Zerotorescue@0 1138 args = {
Zerotorescue@0 1139 rename = {
Zerotorescue@0 1140 order = 10,
Zerotorescue@0 1141 type = "group",
Zerotorescue@0 1142 name = "Rename",
Zerotorescue@0 1143 inline = true,
Zerotorescue@0 1144 args = {
Zerotorescue@0 1145 rename = {
Zerotorescue@0 1146 order = 10,
Zerotorescue@0 1147 type = "input",
Zerotorescue@0 1148 name = "New group name",
Zerotorescue@0 1149 desc = "Change the name of this group to something else. You can also use item links here as you wish.",
Zerotorescue@0 1150 validate = ValidateGroupName,
Zerotorescue@0 1151 set = function(info, value)
Zerotorescue@0 1152 local oldGroupName = groupIdToName[info[2]];
Zerotorescue@0 1153
Zerotorescue@0 1154 addon.db.global.groups[value] = CopyTable(addon.db.global.groups[oldGroupName]);
Zerotorescue@0 1155 addon.db.global.groups[oldGroupName] = nil;
Zerotorescue@0 1156
Zerotorescue@0 1157 groupIdToName[info[2]] = value;
Zerotorescue@0 1158 groupIdToName[value] = true;
Zerotorescue@0 1159 groupIdToName[oldGroupName] = nil;
Zerotorescue@0 1160
Zerotorescue@0 1161 addon:FillGroupOptions();
Zerotorescue@0 1162 end,
Zerotorescue@0 1163 get = function(info)
Zerotorescue@0 1164 return groupIdToName[info[2]];
Zerotorescue@0 1165 end,
Zerotorescue@0 1166 width = "double",
Zerotorescue@0 1167 },
Zerotorescue@0 1168 },
Zerotorescue@0 1169 },
Zerotorescue@0 1170 delete = {
Zerotorescue@0 1171 order = 20,
Zerotorescue@0 1172 type = "group",
Zerotorescue@0 1173 name = "Delete",
Zerotorescue@0 1174 inline = true,
Zerotorescue@0 1175 args = {
Zerotorescue@0 1176 delete = {
Zerotorescue@0 1177 order = 10,
Zerotorescue@0 1178 type = "execute",
Zerotorescue@0 1179 name = "Delete group",
Zerotorescue@0 1180 desc = "Delete the currently selected group.",
Zerotorescue@0 1181 confirm = true,
Zerotorescue@0 1182 confirmText = "Are you sure you wish to |cffff0000DELETE|r this group? This action is not reversable!",
Zerotorescue@0 1183 func = function(info)
Zerotorescue@0 1184 local groupName = groupIdToName[info[2]];
Zerotorescue@0 1185
Zerotorescue@0 1186 addon.db.global.groups[groupName] = nil;
Zerotorescue@0 1187
Zerotorescue@0 1188 addon:FillGroupOptions();
Zerotorescue@0 1189 end,
Zerotorescue@0 1190 },
Zerotorescue@0 1191 },
Zerotorescue@0 1192 },
Zerotorescue@0 1193 export = {
Zerotorescue@0 1194 order = 30,
Zerotorescue@0 1195 type = "group",
Zerotorescue@0 1196 name = "Export",
Zerotorescue@0 1197 inline = true,
Zerotorescue@0 1198 args = {
Zerotorescue@0 1199 input = {
Zerotorescue@0 1200 order = 10,
Zerotorescue@0 1201 type = "input",
Zerotorescue@0 1202 multiline = true,
Zerotorescue@0 1203 name = "Group data",
Zerotorescue@0 1204 width = "full",
Zerotorescue@0 1205 desc = "Export the group data for the currently selected group. Press CTRL-A to select all and CTRL-C to copy the text.",
Zerotorescue@0 1206 set = false,
Zerotorescue@0 1207 get = function(info)
Zerotorescue@0 1208 local groupName = groupIdToName[info[2]];
Zerotorescue@0 1209
Zerotorescue@0 1210 -- We want to include the group name, so we copy the table then set another value
Zerotorescue@0 1211 local temp = CopyTable(addon.db.global.groups[groupName]);
Zerotorescue@0 1212 temp.name = groupName;
Zerotorescue@0 1213
Zerotorescue@0 1214 if not AceSerializer then
Zerotorescue@0 1215 AceSerializer = LibStub("AceSerializer-3.0");
Zerotorescue@0 1216 end
Zerotorescue@0 1217
Zerotorescue@0 1218 return AceSerializer:Serialize(temp);
Zerotorescue@0 1219 end,
Zerotorescue@0 1220 },
Zerotorescue@0 1221 },
Zerotorescue@0 1222 },
Zerotorescue@0 1223 },
Zerotorescue@0 1224 },
Zerotorescue@0 1225 add = {
Zerotorescue@0 1226 order = 30,
Zerotorescue@0 1227 type = "group",
Zerotorescue@0 1228 name = "Add items",
Zerotorescue@0 1229 args = {
Zerotorescue@0 1230 singleAdd = {
Zerotorescue@0 1231 order = 10,
Zerotorescue@0 1232 type = "group",
Zerotorescue@0 1233 inline = true,
Zerotorescue@0 1234 name = "Add items",
Zerotorescue@0 1235 args = {
Zerotorescue@0 1236 help = {
Zerotorescue@0 1237 order = 10,
Zerotorescue@0 1238 type = "description",
Zerotorescue@0 1239 name = "You can add a single item to this group at a time by pasting the item-id or an item-link in the field to the left or you can also import multiple items at once by pasting exported item data in the field to the right. Scroll further down to add items based on your inventory contents.",
Zerotorescue@0 1240 },
Zerotorescue@0 1241 itemLink = {
Zerotorescue@0 1242 order = 20,
Zerotorescue@0 1243 type = "input",
Zerotorescue@0 1244 name = "Single item add (item-link or item-id)",
Zerotorescue@0 1245 desc = "Shift-click an item-link or enter an item-id to add the related item to this group. You can only add one item link or item id at a time.",
Zerotorescue@0 1246 validate = function(info, value)
Zerotorescue@0 1247 -- If the value is empty we'll allow passing to clear the carret
Zerotorescue@0 1248 if value == "" then return true; end
Zerotorescue@0 1249
Zerotorescue@0 1250 local groupName = groupIdToName[info[2]];
Zerotorescue@0 1251
Zerotorescue@0 1252 local itemId = addon:GetItemId(string.trim(value or "")) or tonumber(string.trim(value or ""));
Zerotorescue@0 1253
Zerotorescue@0 1254 if not itemId then
Zerotorescue@0 1255 return "This is not a valid item link.";
Zerotorescue@0 1256 elseif InGroup(itemId) then
Zerotorescue@0 1257 return ("This item is already in the group \"%s\"."):format(InGroup(itemId));
Zerotorescue@0 1258 end
Zerotorescue@0 1259
Zerotorescue@0 1260 return true;
Zerotorescue@0 1261 end,
Zerotorescue@0 1262 set = function(info, value)
Zerotorescue@0 1263 if value and value ~= "" then
Zerotorescue@0 1264 local groupName = groupIdToName[info[2]];
Zerotorescue@0 1265
Zerotorescue@0 1266 local itemId = addon:GetItemId(string.trim(value or "")) or tonumber(string.trim(value or ""));
Zerotorescue@0 1267
Zerotorescue@0 1268 AddToGroup(groupName, itemId);
Zerotorescue@0 1269
Zerotorescue@0 1270 print(("Added %s"):format(select(2, GetItemInfo(itemId)) or ("Unknown (#%d)"):format(itemId)));
Zerotorescue@0 1271 end
Zerotorescue@0 1272 end,
Zerotorescue@0 1273 get = false,
Zerotorescue@0 1274 },
Zerotorescue@0 1275 import = {
Zerotorescue@0 1276 order = 40,
Zerotorescue@0 1277 type = "input",
Zerotorescue@0 1278 name = "Import item data",
Zerotorescue@0 1279 desc = "Import item data from an exported item data-string. Any items already grouped will be skipped.",
Zerotorescue@0 1280 set = function(info, value)
Zerotorescue@0 1281 local groupName = groupIdToName[info[2]];
Zerotorescue@0 1282
Zerotorescue@0 1283 local allItemIds = { string.split(";", value or "") };
Zerotorescue@0 1284
Zerotorescue@0 1285 for _, value in pairs(allItemIds) do
Zerotorescue@0 1286 local itemId = tonumber(value);
Zerotorescue@0 1287
Zerotorescue@0 1288 if not itemId then
Zerotorescue@0 1289 print(("\"%s\" is not a number."):format(value));
Zerotorescue@0 1290 elseif InGroup(itemId) then
Zerotorescue@0 1291 print(("Skipping %s (#%d) as it is already in the group |cfffed000%s|r."):format(select(2, GetItemInfo(itemId)) or "Unknown", itemId, InGroup(itemId)));
Zerotorescue@0 1292 else
Zerotorescue@0 1293 AddToGroup(groupName, itemId);
Zerotorescue@0 1294 end
Zerotorescue@0 1295 end
Zerotorescue@0 1296 end,
Zerotorescue@0 1297 get = false,
Zerotorescue@0 1298 },
Zerotorescue@0 1299 },
Zerotorescue@0 1300 },
Zerotorescue@0 1301 massAdd = {
Zerotorescue@0 1302 order = 20,
Zerotorescue@0 1303 type = "group",
Zerotorescue@0 1304 inline = true,
Zerotorescue@0 1305 name = "Mass add",
Zerotorescue@0 1306 args = {
Zerotorescue@0 1307 help = {
Zerotorescue@0 1308 order = 10,
Zerotorescue@0 1309 type = "description",
Zerotorescue@0 1310 name = "Click the items you wish to add to this group or add multiple of these items at once by providing a name filter in the field below.",
Zerotorescue@0 1311 },
Zerotorescue@0 1312 massAdd = {
Zerotorescue@0 1313 order = 20,
Zerotorescue@0 1314 type = "input",
Zerotorescue@0 1315 name = "Add all items matching...",
Zerotorescue@0 1316 desc = "Add every item in your inventory matching the name entered in this field. If you enter \"Glyph\" as a filter, any items in your inventory containing this in their name will be added to this group.",
Zerotorescue@0 1317 --set = massAddItems,
Zerotorescue@0 1318 get = false,
Zerotorescue@0 1319 },
Zerotorescue@0 1320 },
Zerotorescue@0 1321 },
Zerotorescue@0 1322 list = {
Zerotorescue@0 1323 order = 30,
Zerotorescue@0 1324 type = "group",
Zerotorescue@0 1325 inline = true,
Zerotorescue@0 1326 name = "Item list",
Zerotorescue@0 1327 hidden = UpdateAddItemList,
Zerotorescue@0 1328 args = {
Zerotorescue@0 1329
Zerotorescue@0 1330 },
Zerotorescue@0 1331 },
Zerotorescue@0 1332 },
Zerotorescue@0 1333 },
Zerotorescue@0 1334 remove = {
Zerotorescue@0 1335 order = 40,
Zerotorescue@0 1336 type = "group",
Zerotorescue@0 1337 name = "Current items",
Zerotorescue@0 1338 args = {
Zerotorescue@0 1339 help = {
Zerotorescue@0 1340 order = 10,
Zerotorescue@0 1341 type = "group",
Zerotorescue@0 1342 inline = true,
Zerotorescue@0 1343 name = "Help",
Zerotorescue@0 1344 hidden = false,
Zerotorescue@0 1345 args = {
Zerotorescue@0 1346 help = {
Zerotorescue@0 1347 order = 10,
Zerotorescue@0 1348 type = "description",
Zerotorescue@0 1349 name = "Click the items you wish to remove from this group.",
Zerotorescue@0 1350 },
Zerotorescue@0 1351 },
Zerotorescue@0 1352 },
Zerotorescue@0 1353 list = {
Zerotorescue@0 1354 order = 20,
Zerotorescue@0 1355 type = "group",
Zerotorescue@0 1356 inline = true,
Zerotorescue@0 1357 name = "Item list",
Zerotorescue@0 1358 hidden = UpdateRemoveItemList,
Zerotorescue@0 1359 args = {
Zerotorescue@0 1360
Zerotorescue@0 1361 },
Zerotorescue@0 1362 },
Zerotorescue@0 1363 export = {
Zerotorescue@0 1364 order = 30,
Zerotorescue@0 1365 type = "group",
Zerotorescue@0 1366 name = "Export",
Zerotorescue@0 1367 inline = true,
Zerotorescue@0 1368 args = {
Zerotorescue@0 1369 input = {
Zerotorescue@0 1370 order = 10,
Zerotorescue@0 1371 type = "input",
Zerotorescue@0 1372 name = "Item data",
Zerotorescue@0 1373 width = "full",
Zerotorescue@0 1374 desc = "Export the item data for the currently selected group. Press CTRL-A to select all and CTRL-C to copy the text.",
Zerotorescue@0 1375 set = false,
Zerotorescue@0 1376 get = function(info)
Zerotorescue@0 1377 local groupName = groupIdToName[info[2]];
Zerotorescue@0 1378
Zerotorescue@0 1379 local combinedItemIds;
Zerotorescue@0 1380 -- Parse items in group and show these
Zerotorescue@0 1381 for itemId, _ in pairs(addon.db.global.groups[groupName].items) do
Zerotorescue@0 1382 if not combinedItemIds then
Zerotorescue@0 1383 combinedItemIds = tostring(itemId);
Zerotorescue@0 1384 else
Zerotorescue@0 1385 combinedItemIds = combinedItemIds .. (";%d"):format(itemId);
Zerotorescue@0 1386 end
Zerotorescue@0 1387 end
Zerotorescue@0 1388
Zerotorescue@0 1389 return combinedItemIds; -- We don't serialize this because we actually DO want people to be able to manually modify it - besides, parsing it isn't going to be hard
Zerotorescue@0 1390 end,
Zerotorescue@0 1391 },
Zerotorescue@0 1392 },
Zerotorescue@0 1393 },
Zerotorescue@0 1394 },
Zerotorescue@0 1395 },
Zerotorescue@0 1396 },
Zerotorescue@0 1397 };
Zerotorescue@0 1398
Zerotorescue@0 1399 function addon:MakeGroupOptions()
Zerotorescue@0 1400 options.args.groups = {
Zerotorescue@0 1401 order = 1100,
Zerotorescue@0 1402 type = "group",
Zerotorescue@0 1403 name = "Groups",
Zerotorescue@0 1404 desc = "Change a group.",
Zerotorescue@0 1405 args = {
Zerotorescue@0 1406 create = {
Zerotorescue@0 1407 order = 10,
Zerotorescue@0 1408 type = "group",
Zerotorescue@0 1409 inline = true,
Zerotorescue@0 1410 name = "Create a brand new group",
Zerotorescue@0 1411 args = {
Zerotorescue@0 1412 name = {
Zerotorescue@0 1413 order = 10,
Zerotorescue@0 1414 type = "input",
Zerotorescue@0 1415 name = "Group name",
Zerotorescue@0 1416 desc = "The name of the group. You can also use item links as you wish.",
Zerotorescue@0 1417 validate = ValidateGroupName,
Zerotorescue@0 1418 set = function(_, value)
Zerotorescue@0 1419 self.db.global.groups[value] = {};
Zerotorescue@0 1420
Zerotorescue@0 1421 addon:FillGroupOptions();
Zerotorescue@0 1422 end,
Zerotorescue@0 1423 get = false,
Zerotorescue@0 1424 width = "double",
Zerotorescue@0 1425 },
Zerotorescue@0 1426 },
Zerotorescue@0 1427 },
Zerotorescue@0 1428 import = {
Zerotorescue@0 1429 order = 20,
Zerotorescue@0 1430 type = "group",
Zerotorescue@0 1431 inline = true,
Zerotorescue@0 1432 name = "Import a group",
Zerotorescue@0 1433 args = {
Zerotorescue@0 1434 input = {
Zerotorescue@0 1435 order = 10,
Zerotorescue@0 1436 type = "input",
Zerotorescue@0 1437 multiline = true,
Zerotorescue@0 1438 name = "Group data",
Zerotorescue@0 1439 desc = "Paste the group data as provided by a group export. If you are trying to import multiple groups at the same time, make sure to use newlines to seperate them.",
Zerotorescue@0 1440 set = function(info, value)
Zerotorescue@0 1441 local temp = { string.split("\n", value or "") };
Zerotorescue@0 1442
Zerotorescue@0 1443 for no, current in pairs(temp) do
Zerotorescue@0 1444 if not AceSerializer then
Zerotorescue@0 1445 AceSerializer = LibStub("AceSerializer-3.0");
Zerotorescue@0 1446 end
Zerotorescue@0 1447
Zerotorescue@0 1448 local result, temp = AceSerializer:Deserialize(current);
Zerotorescue@0 1449 local name;
Zerotorescue@0 1450
Zerotorescue@0 1451 if not temp.name then
Zerotorescue@0 1452 print("|cffff0000The provided data is not supported.|r");
Zerotorescue@0 1453 return;
Zerotorescue@0 1454 else
Zerotorescue@0 1455 name = temp.name;
Zerotorescue@0 1456 temp.name = nil;
Zerotorescue@0 1457 end
Zerotorescue@0 1458
Zerotorescue@0 1459 local newGroupName = string.trim(string.lower(name or ""));
Zerotorescue@0 1460
Zerotorescue@0 1461 for name in pairs(self.db.global.groups) do
Zerotorescue@0 1462 if string.lower(name) == newGroupName then
Zerotorescue@0 1463 print(("|cffff0000A group named \"%s\" already exists.|r"):format(name));
Zerotorescue@0 1464 return;
Zerotorescue@0 1465 end
Zerotorescue@0 1466 end
Zerotorescue@0 1467
Zerotorescue@0 1468 self.db.global.groups[name] = temp;
Zerotorescue@7 1469
Zerotorescue@7 1470 self:FillGroupOptions();
Zerotorescue@0 1471 end
Zerotorescue@0 1472 end,
Zerotorescue@0 1473 get = false,
Zerotorescue@0 1474 width = "full",
Zerotorescue@0 1475 },
Zerotorescue@0 1476 },
Zerotorescue@0 1477 },
Zerotorescue@0 1478 },
Zerotorescue@0 1479 };
Zerotorescue@0 1480 end
Zerotorescue@0 1481
Zerotorescue@0 1482 function addon:FillGroupOptions()
Zerotorescue@0 1483 for id, name in pairs(groupIdToName) do
Zerotorescue@0 1484 if type(name) == "string" and not self.db.global.groups[name] then
Zerotorescue@0 1485 options.args.groups.args[id] = nil;
Zerotorescue@0 1486 groupIdToName[id] = nil;
Zerotorescue@0 1487 groupIdToName[name] = nil;
Zerotorescue@0 1488 end
Zerotorescue@0 1489 end
Zerotorescue@0 1490
Zerotorescue@0 1491 for name, values in pairs(self.db.global.groups) do
Zerotorescue@0 1492 if not groupIdToName[name] then
Zerotorescue@0 1493 options.args.groups.args[tostring(count)] = CopyTable(defaultGroup);
Zerotorescue@0 1494
Zerotorescue@0 1495 groupIdToName[tostring(count)] = name;
Zerotorescue@0 1496 groupIdToName[name] = true;
Zerotorescue@0 1497
Zerotorescue@0 1498 count = ( count + 1 );
Zerotorescue@0 1499 end
Zerotorescue@0 1500 end
Zerotorescue@0 1501 end
Zerotorescue@0 1502
Zerotorescue@0 1503 function addon:GetItemCount(itemId)
Zerotorescue@0 1504 return Altoholic:GetItemCount(itemId);
Zerotorescue@0 1505 end
Zerotorescue@0 1506
Zerotorescue@1 1507 function addon:GetAuctionValue(link)
Zerotorescue@1 1508 if GetAuctionBuyout then
Zerotorescue@1 1509 -- Auctionator support
Zerotorescue@1 1510
Zerotorescue@1 1511 local lowBuy = GetAuctionBuyout(link);
Zerotorescue@1 1512
Zerotorescue@1 1513 if lowBuy == nil then
Zerotorescue@1 1514 -- No auctions up at this time
Zerotorescue@1 1515 return -1;
Zerotorescue@1 1516 end
Zerotorescue@1 1517
Zerotorescue@1 1518 return lowBuy;
Zerotorescue@1 1519 elseif AucAdvanced ~= nil and AucAdvanced.Modules.Util.SimpleAuction ~= nil and AucAdvanced.Modules.Util.SimpleAuction.Private.GetItems ~= nil then
Zerotorescue@1 1520 -- Auctioneer support
Zerotorescue@1 1521
Zerotorescue@1 1522 local imgSeen, _, _, _, _, lowBuy, _, _ = AucAdvanced.Modules.Util.SimpleAuction.Private.GetItems(link);
Zerotorescue@1 1523 --local imgseen, image, matchBid, matchBuy, lowBid, lowBuy, aveBuy, aSeen
Zerotorescue@1 1524
Zerotorescue@1 1525 if imgSeen <= 0 then
Zerotorescue@1 1526 -- No auctions up at this time
Zerotorescue@1 1527 return -1;
Zerotorescue@1 1528 end
Zerotorescue@1 1529
Zerotorescue@1 1530 return lowBuy;
Zerotorescue@1 1531 end
Zerotorescue@7 1532
Zerotorescue@7 1533 return -2;
Zerotorescue@1 1534 end
Zerotorescue@1 1535
Zerotorescue@0 1536
Zerotorescue@0 1537
Zerotorescue@0 1538
Zerotorescue@0 1539 function addon:Debug(t)
Zerotorescue@0 1540 if not self.debugChannel and self.debugChannel ~= false then
Zerotorescue@0 1541 -- We want to check just once, so if you add a debug channel later just do a /reload (registering an event for this is wasted resources)
Zerotorescue@0 1542 self.debugChannel = false;
Zerotorescue@0 1543
Zerotorescue@0 1544 for i = 1, NUM_CHAT_WINDOWS do
Zerotorescue@0 1545 local name = GetChatWindowInfo(i);
Zerotorescue@0 1546
Zerotorescue@0 1547 if name:upper() == "DEBUG" then
Zerotorescue@0 1548 self.debugChannel = _G["ChatFrame" .. i];
Zerotorescue@0 1549 end
Zerotorescue@0 1550 end
Zerotorescue@0 1551 end
Zerotorescue@0 1552
Zerotorescue@0 1553 if self.debugChannel then
Zerotorescue@0 1554 self.debugChannel:AddMessage(t);
Zerotorescue@0 1555 end
Zerotorescue@0 1556 end