comparison Modules/Summary v2.lua @ 89:a12d22ef3f39

AceSerializer has been enabled again as it?s used when exporting/importing groups. All other unused libraries are now really removed. Adjusted debug function to format only when a debug channel is available. Fixed moving from guild banks, checking if items are locked is different then with banks. Now unregistering the item locking event so it doesn?t continue to try to move every time an item is switched after the automated cycle has finished. (geeezus, this description is a total overkill) Fixed item queueing. Queue all when there?s a group without any items inside no longer crashes. Removing cached container data after closing a container.
author Zerotorescue
date Fri, 07 Jan 2011 22:19:03 +0100
parents
children 252292b703ce
comparison
equal deleted inserted replaced
88:f1c035694545 89:a12d22ef3f39
1 local addon = select(2, ...); -- Get a reference to the main addon object
2 local mod = addon:NewModule("Summary", "AceEvent-3.0", "AceTimer-3.0"); -- register a new module, Summary: resposible for building the summary window
3
4 local unknownItemName = "Unknown (#%d)";
5
6 local CACHE_ITEMS_TOTAL, CACHE_ITEMS_CURRENT, itemsCache = 0, 0, {};
7 local AceGUI, cacheStart;
8
9 local _G = _G; -- prevent looking up of the global table
10 local printf, sgsub, supper, tinsert, pairs, ceil, GetItemInfo = _G.string.format, _G.string.gsub, _G.string.upper, _G.table.insert, _G.pairs, _G.ceil, _G.GetItemInfo; -- prevent looking up of the most used globals all the time
11
12 function mod:OnEnable()
13 -- Register the summary specific widget
14 addon:GetModule("Widgets"):InlineGroupWithButton();
15
16 AceGUI = LibStub("AceGUI-3.0");
17
18 -- Register our own slash commands
19 -- /im summary
20 addon:RegisterSlash(function()
21 mod:BuildMain();
22 mod:Build();
23 end, { "s", "sum", "summary" }, "|Hfunction:InventoriumCommandHandler:summary|h|cff00fff7/im summary|r|h (or /im s) - Show the summary window containing an overview of all items within the groups tracked at this current character.");
24
25 -- /im reset
26 addon:RegisterSlash(function()
27 if mod.frame then
28 mod.frame:SetWidth(700);
29 mod.frame:SetHeight(600);
30
31 print("Resetting width and height of the summary frame.");
32 end
33 end, { "r", "reset" }, "|Hfunction:InventoriumCommandHandler:reset|h|cff00fff7/im reset|r|h (or /im r) - Reset the size of the summary frame.");
34 end
35
36 local function ShowTooltip(self)
37 -- If this function is called from a widget, self is the widget and self.frame the actual frame
38 local this = self.frame or self;
39
40 GameTooltip:SetOwner(this, "ANCHOR_NONE");
41 GameTooltip:SetPoint("BOTTOM", this, "TOP");
42 GameTooltip:SetText(this.tooltipTitle, 1, .82, 0, 1);
43
44 if type(this.tooltip) == "string" then
45 GameTooltip:AddLine(this.tooltip, 1, 1, 1, 1);
46 end
47
48 GameTooltip:Show();
49 end
50
51 local function HideTooltip()
52 GameTooltip:Hide();
53 end
54
55 function mod:BuildMain()
56 LibStub("AceConfigDialog-3.0"):Close("InventoriumOptions");
57
58 self:CloseFrame();
59
60 -- Main Window
61 mod.frame = AceGUI:Create("Frame");
62 _G["InventoriumSummary"] = mod.frame; -- name the global frame so it can be put in the UISpecialFrames
63 mod.frame:SetTitle("Inventory Summary");
64 mod.frame:SetLayout("Fill");
65 mod.frame:SetCallback("OnClose", function(widget)
66 mod:CancelTimer(self.tmrUpdater, true);
67 mod:CloseFrame();
68 end);
69 mod.frame:SetWidth(addon.db.profile.defaults.summary.width);
70 mod.frame:SetHeight(addon.db.profile.defaults.summary.height);
71 mod.frame.OnWidthSet = function(_, width)
72 addon.db.profile.defaults.summary.width = width;
73 end;
74 mod.frame.OnHeightSet = function(_, height)
75 addon.db.profile.defaults.summary.height = height;
76 end;
77
78 -- Close on escape
79 tinsert(UISpecialFrames, "InventoriumSummary");
80
81 -- ScrollFrame child
82 mod.scrollFrame = AceGUI:Create("ScrollFrame");
83 mod.scrollFrame:SetLayout("Flow");
84
85 mod.frame:AddChild(mod.scrollFrame);
86
87 -- Reset items cache
88 table.wipe(itemsCache);
89 end
90
91 function mod:CloseFrame()
92 if mod.frame then
93 mod.frame:Release();
94 mod.frame = nil;
95
96 -- Stop caching
97
98 -- Stop timer
99 self:CancelTimer(self.tmrUpdater, true);
100 end
101 end
102
103 local sortMethod = "item";
104 local sortDirectory = "ASC";
105 local function ReSort(subject)
106 if sortMethod == subject then
107 sortDirectory = (sortDirectory == "ASC" and "DESC") or "ASC";
108 else
109 sortDirectory = "ASC";
110 end
111 sortMethod = subject;
112
113 mod:Build();
114 end
115
116 -- From http://www.wowwiki.com/API_sort
117 local function pairsByKeys (t, f)
118 local a = {}
119 for n in pairs(t) do tinsert(a, n) end
120 table.sort(a, f)
121 local i = 0 -- iterator variable
122 local iter = function () -- iterator function
123 i = i + 1
124 if a[i] == nil then return nil
125 else return a[i], t[a[i]]
126 end
127 end
128 return iter
129 end
130
131 local summaryData = {};
132 local cacheMe = {};
133
134 --[[
135 GroupName
136 minLocalStock
137 minGlobalStock
138 showWhenBelow
139 priceThreshold
140 hideWhenBelowPriceThreshold
141 alwaysGetAuctionValue
142 Items
143 ItemData
144 ItemData
145 ItemData
146 GroupName
147 etc.
148 ]]
149 --[[
150 ItemData
151 -- Standard info everything needs
152 self.id = itemId;
153 self.name = itemName;
154 self.link = itemLink;
155 self.rarity = itemRarity;
156 self.icon = itemTexture;
157
158 -- Detailed stuff
159 self.value = -3;
160 self.globalCount = -3;
161 self.localCount = -3;
162 self.set = {};
163 ]]
164
165 function mod:MakeList()
166 local playerName = UnitName("player");
167
168 -- Item data is being reset
169 table.wipe(cacheMe);
170 table.wipe(summaryData);
171
172 -- Go through all our stored groups
173 for groupName, values in addon.db.profile.groups do
174 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
175
176 -- Does this group have any items and do we want to track it at this char?
177 if values.items and trackAt[playerName] then
178 -- Get group settings
179 local groupTemplate = {
180 minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock"),
181 minGlobalStock = addon:GetOptionByKey(groupName, "minGlobalStock"),
182 showWhenBelow = addon:GetOptionByKey(groupName, "summaryThresholdShow"),
183 priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold"),
184 hideWhenBelowPriceThreshold = addon:GetOptionByKey(groupName, "summaryHidePriceThreshold"),
185 alwaysGetAuctionValue = addon:GetOptionByKey(groupName, "alwaysGetAuctionValue"),
186 items = {},
187 };
188
189 -- Generate itemslist
190 for itemId, _ in pairs(values.items) do
191 -- Go through all items for this group
192
193 local itemData = addon.ItemData:New(itemId);
194
195 -- if no price threshold is set for this item and you don't want to always get the auction value, then don't look it up either
196 if groupTemplate.priceThreshold == 0 and not groupTemplate.alwaysGetAuctionValue then
197 itemData.value = -4;
198 end
199
200 groupTemplate.items[itemId] = itemData;
201 table.insert(cacheMe, itemData);
202 end
203
204 summaryData[groupName] = groupTemplate;
205 end
206 end
207 end
208
209 local function DisplayItemCount(value, minimumStock)
210 if value == -1 then
211 return "|cffffff00Unknown|r"; -- addon doesn't support local
212 elseif value == -3 then
213 return "|cffffff00Unknown|r"; -- not yet cached
214 elseif value == -5 then
215 return "|cffff9933Error|r"; -- item not found
216 else
217 return printf("%s / %d", self:ColorCode(value, minimumStock), minimumStock);
218 end
219 end
220 local function GetLocalItemCount(groupName, itemId)
221 local count = ((summaryData[groupName] and summaryData[groupName][itemId] and summaryData[groupName][itemId].localCount) or -5);
222 local minStock = (summaryData[groupName] and summaryData[groupName].minLocalStock);
223
224 return DisplayItemCount(count, minStock);
225 end
226 local function GetGlobalItemCount(groupName, itemId)
227 local count = ((summaryData[groupName] and summaryData[groupName][itemId] and summaryData[groupName][itemId].globalCount) or -5);
228 local minStock = (summaryData[groupName] and summaryData[groupName].minGlobalStock);
229
230 return DisplayItemCount(count, minStock);
231 end
232 local function GetAuctionValue(groupName, itemId)
233 local value = ((summaryData[groupName] and summaryData[groupName][itemId] and summaryData[groupName][itemId].value) or -5);
234 local threshold = (summaryData[groupName] and summaryData[groupName].priceThreshold);
235
236 if value == -1 then
237 return "|cff0000ffNone up|r"; -- no auctions up
238 elseif value == -2 then
239 return "|cff0000ffNo AH mod|r"; -- no (working) auction house addon available
240 elseif value == -3 then
241 return "|cffffff00Unknown|r"; -- not yet cached
242 elseif value == -4 then
243 return "|cff00ff00-|r"; -- don't want to know
244 elseif value == -5 then
245 return "|cffff9933Error|r"; -- item not found
246 elseif threshold and value < threshold then
247 return printf("|cffaaaaaa%s|r", sgsub(addon:ReadableMoney(value or 0, true), "|([a-fA-F0-9]+)([gsc]+)|r", "%2"));
248 else
249 return addon:ReadableMoney(value or 0, true);
250 end
251 end
252
253 function mod:Build()
254 -- We are going to add hunderds of widgets to this container, but don't want it to also cause hunderds of reflows, thus pause reflowing and just do it once when everything is prepared
255 -- This appears to be required for each container we wish to pause, so also do this for the contents
256 mod.scrollFrame:PauseLayout();
257
258 mod.scrollFrame:ReleaseChildren();
259
260 -- Refresh button
261 local btnRefresh = AceGUI:Create("Button");
262 btnRefresh:SetText("Refresh");
263 btnRefresh:SetRelativeWidth(.2);
264 btnRefresh:SetCallback("OnClick", function()
265 -- Reset items cache
266 table.wipe(itemsCache);
267
268 -- Rebuild itemlist and start caching
269 mod:Build();
270 end);
271 btnRefresh:SetCallback("OnEnter", ShowTooltip);
272 btnRefresh:SetCallback("OnLeave", HideTooltip);
273 btnRefresh.frame.tooltipTitle = "Refresh Cache";
274 btnRefresh.frame.tooltip = "Refresh the list and recache the item counts and auction values.";
275
276 mod.scrollFrame:AddChild(btnRefresh);
277
278 local lblSpacer = AceGUI:Create("Label");
279 lblSpacer:SetRelativeWidth(.03);
280
281 mod.scrollFrame:AddChild(lblSpacer);
282
283 -- Speed slider
284 local sdrSpeed = AceGUI:Create("Slider");
285 sdrSpeed:SetLabel("Processing speed");
286 sdrSpeed:SetSliderValues(0.01, 5, 0.01); -- min, max, interval
287 sdrSpeed:SetIsPercent(true);
288 sdrSpeed:SetRelativeWidth(.3);
289 sdrSpeed:SetCallback("OnMouseUp", function(self, event, value)
290 addon.db.profile.defaults.summary.speed = ceil( ( ( value * 100 ) / 5) - .5 );
291
292 CACHE_ITEMS_PER_UPDATE = addon.db.profile.defaults.summary.speed; -- max = 20, min = 1
293 end);
294 sdrSpeed:SetValue( addon.db.profile.defaults.summary.speed * 5 / 100 );
295 sdrSpeed:SetCallback("OnEnter", ShowTooltip);
296 sdrSpeed:SetCallback("OnLeave", HideTooltip);
297 sdrSpeed.frame.tooltipTitle = "Caching Processing Speed";
298 sdrSpeed.frame.tooltip = "Change the speed at which item counts and auction values are being cached. Higher is faster but may drastically reduce your FPS while caching.\n\nAnything above 100% will probably become uncomfortable.";
299
300 mod.scrollFrame:AddChild(sdrSpeed);
301
302 local lblSpacer = AceGUI:Create("Label");
303 lblSpacer:SetRelativeWidth(.23);
304
305 mod.scrollFrame:AddChild(lblSpacer);
306
307 local lblSpacer = AceGUI:Create("Label");
308 lblSpacer:SetRelativeWidth(.03);
309
310 mod.scrollFrame:AddChild(lblSpacer);
311
312 -- Queue all button
313 local btnQueueAll = AceGUI:Create("Button");
314 btnQueueAll:SetText("Queue All");
315 btnQueueAll:SetRelativeWidth(.2);
316 btnQueueAll:SetCallback("OnClick", function()
317 self:SendMessage("IM_QUEUE_ALL");
318 end);
319 btnQueueAll:SetCallback("OnEnter", ShowTooltip);
320 btnQueueAll:SetCallback("OnLeave", HideTooltip);
321 btnQueueAll.frame.tooltipTitle = "Queue all";
322 btnQueueAll.frame.tooltip = "Queue everything that requires restocking within every single visible group.";
323
324 mod.scrollFrame:AddChild(btnQueueAll);
325
326 for groupName, items in pairs(summaryData) do
327 -- Make group container
328 local iGroup = AceGUI:Create("InlineGroupWithButton");
329 iGroup:PauseLayout();
330 iGroup:SetTitle(groupName);
331 iGroup:SetFullWidth(true);
332 iGroup:SetLayout("Flow");
333 iGroup:MakeButton({
334 name = "Queue",
335 desc = "Queue all items in this group.",
336 exec = function()
337 print("Queueing all items within " .. groupName .. " craftable by the currently open profession.");
338 self:SendMessage("IM_QUEUE_GROUP", groupName);
339 end,
340 });
341
342 -- Headers
343
344 -- Itemlink
345 local lblItem = AceGUI:Create("InteractiveLabel");
346 lblItem:SetText("|cfffed000Item|r");
347 lblItem:SetFontObject(GameFontHighlight);
348 lblItem:SetRelativeWidth(.7);
349 lblItem:SetCallback("OnClick", function() ReSort("item"); end);
350 lblItem:SetCallback("OnEnter", ShowTooltip);
351 lblItem:SetCallback("OnLeave", HideTooltip);
352 lblItem.frame.tooltipTitle = "Item";
353 lblItem.frame.tooltip = "Sort on the item quality, then name.";
354
355 iGroup:AddChild(lblItem);
356
357 -- Local quantity
358 local lblLocal = AceGUI:Create("InteractiveLabel");
359 lblLocal:SetText("|cfffed000Loc.|r");
360 lblLocal:SetFontObject(GameFontHighlight);
361 lblLocal:SetRelativeWidth(.099);
362 lblLocal:SetCallback("OnClick", function() ReSort("local"); end);
363 lblLocal:SetCallback("OnEnter", ShowTooltip);
364 lblLocal:SetCallback("OnLeave", HideTooltip);
365 lblLocal.frame.tooltipTitle = "Local stock";
366 lblLocal.frame.tooltip = "Sort on the amount of items currently in local stock.";
367
368 iGroup:AddChild(lblLocal);
369
370 -- Current quantity
371 local lblQuantity = AceGUI:Create("InteractiveLabel");
372 lblQuantity:SetText("|cfffed000Cur.|r");
373 lblQuantity:SetFontObject(GameFontHighlight);
374 lblQuantity:SetRelativeWidth(.099);
375 lblQuantity:SetCallback("OnClick", function() ReSort("current"); end);
376 lblQuantity:SetCallback("OnEnter", ShowTooltip);
377 lblQuantity:SetCallback("OnLeave", HideTooltip);
378 lblQuantity.frame.tooltipTitle = "Current stock";
379 lblQuantity.frame.tooltip = "Sort on the amount of items currently in stock.";
380
381 iGroup:AddChild(lblQuantity);
382
383 -- Lowest value
384 local lblValue = AceGUI:Create("InteractiveLabel");
385 lblValue:SetText("|cfffed000Value|r");
386 lblValue:SetFontObject(GameFontHighlight);
387 lblValue:SetRelativeWidth(.099);
388 lblValue:SetCallback("OnClick", function() ReSort("value"); end);
389 lblValue:SetCallback("OnEnter", ShowTooltip);
390 lblValue:SetCallback("OnLeave", HideTooltip);
391 lblValue.frame.tooltipTitle = "Value";
392 lblValue.frame.tooltip = "Sort on the item auction value.";
393
394 iGroup:AddChild(lblValue);
395
396
397 -- Sort items
398 table.sort(itemsCache[groupName], function(a, b)
399 local aRarity = a.rarity or 1;
400 local bRarity = b.rarity or 1;
401
402 if sortMethod == "item" and aRarity == bRarity then
403 -- Do a name-compare for items of the same rarity
404 -- Otherwise epics first, then junk
405
406 local aName = a.name or printf(unknownItemName, a.id);
407 local bName = b.name or printf(unknownItemName, b.id);
408
409 if sortDirectory == "ASC" then
410 return supper(aName) < supper(bName);
411 else
412 return supper(aName) > supper(bName);
413 end
414 elseif sortMethod == "item" then
415 if sortDirectory == "ASC" then
416 return aRarity > bRarity; -- the comparers were reversed because we want epics first
417 else
418 return aRarity < bRarity; -- the comparers were reversed because we want epics first
419 end
420 elseif sortMethod == "current" then
421 if sortDirectory == "ASC" then
422 return a.globalCount < b.globalCount;
423 else
424 return a.globalCount > b.globalCount;
425 end
426 elseif sortMethod == "local" then
427 if sortDirectory == "ASC" then
428 return a.localCount < b.localCount;
429 else
430 return a.localCount > b.localCount;
431 end
432 elseif sortMethod == "value" then
433 if sortDirectory == "ASC" then
434 return a.value < b.value;
435 else
436 return a.value > b.value;
437 end
438 end
439 end);
440
441 -- Show itemslist
442 for i, item in pairs(itemsCache[groupName]) do
443 -- Go through all items for this group
444
445 if (( item.globalCount / minGlobalStock ) < showWhenBelow or ( item.localCount / minLocalStock ) < showWhenBelow) and (not hideWhenBelowPriceThreshold or priceThreshold == 0 or item.value < 0 or item.value >= priceThreshold) then
446 -- if the option "hide when below threshold" is disabled or no price threshold is set or the value is above the price threshold or the value could not be determined, proceed
447
448 local btnItemLink = AceGUI:Create("ItemLinkButton");
449 btnItemLink:SetUserData("exec", function(_, itemId, _, buttonName)
450 local itemName, itemLink = GetItemInfo(itemId);
451
452 if buttonName == "LeftButton" and IsShiftKeyDown() and itemLink then
453 ChatEdit_InsertLink(itemLink);
454 elseif buttonName == "LeftButton" and IsAltKeyDown() and itemName and AuctionFrame and AuctionFrame:IsShown() and AuctionFrameBrowse then
455 -- Start search at page 0
456 AuctionFrameBrowse.page = 0;
457
458 -- Set the search field (even though we could use "ChatEdit_InsertLink", this ensures the right field is updated)
459 BrowseName:SetText(itemName)
460
461 QueryAuctionItems(itemName, nil, nil, 0, 0, 0, 0, 0, 0);
462 end
463 end);
464 btnItemLink:SetRelativeWidth(.7);
465 btnItemLink:SetItem(item);
466
467 iGroup:AddChild(btnItemLink);
468
469 -- Local quantity
470 local lblLocal = AceGUI:Create("Label");
471 lblLocal:SetText(self:DisplayItemCount(item.localCount, minLocalStock));
472 lblLocal:SetRelativeWidth(.099);
473
474 iGroup:AddChild(lblLocal);
475
476 -- Current quantity
477 local lblQuantity = AceGUI:Create("Label");
478 lblQuantity:SetText(self:DisplayItemCount(item.globalCount, minGlobalStock));
479 lblQuantity:SetRelativeWidth(.099);
480
481 iGroup:AddChild(lblQuantity);
482
483 -- Value
484 local lblValue = AceGUI:Create("Label");
485 lblValue:SetText(self:DisplayMoney(item.value, priceThreshold));
486 lblValue:SetRelativeWidth(.099);
487
488 iGroup:AddChild(lblValue);
489
490 -- Remember references to the value and current fields so we can fill them later
491 item.set.value = lblValue;
492 item.set.globalCount = lblQuantity;
493 item.set.localCount = lblLocal;
494 end
495 end
496
497 groupTimes.preparing = ceil( ( GetTime() - groupStartTime ) * 1000 );
498
499 iGroup:ResumeLayout();
500 mod.scrollFrame:AddChild(iGroup); -- this can take up to .5 seconds, might need to look into again at a later time
501
502 groupTimes.building = ceil( ( GetTime() - groupStartTime ) * 1000 );
503 end
504
505 if groupStartTime and groupTimes then
506 addon:Debug("Building of %s took %d ms (%d / %d / %d / %d / %d).", groupName, ceil( ( GetTime() - groupStartTime ) * 1000 ), groupTimes.init or 0, groupTimes.sorting or 0, groupTimes.preparing or 0, groupTimes.building or 0, ceil( ( GetTime() - buildStartTime ) * 1000 ));
507 end
508 end
509
510 mod.scrollFrame:ResumeLayout();
511 mod.scrollFrame:DoLayout();
512
513 addon:Debug("Done building summary after %d ms.", ceil( ( GetTime() - buildStartTime ) * 1000 ));
514
515 if CACHE_ITEMS_TOTAL > 0 then
516 cacheStart = GetTime();
517 self:CancelTimer(self.tmrUpdater, true);
518 self.tmrUpdater = self:ScheduleRepeatingTimer("UpdateNextItem", .01); -- Once every 100 frames (or once every x frames if you have less than 100 FPS, basically, once every frame)
519 end
520 end
521
522 function mod:UpdateNextItem()
523 local i = 0;
524
525 for groupName, items in pairs(itemsCache) do
526 local minGlobalStock = addon:GetOptionByKey(groupName, "minGlobalStock");
527 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
528 local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
529
530 for _, item in pairs(items) do
531 if item.globalCount == -3 or item.localCount == -3 or item.value == -3 then
532 if item.globalCount == -3 then
533 -- Only if item count was queued, update it
534 item.globalCount = addon:GetItemCount(item.id, groupName);
535 if item.set.globalCount and item.set.globalCount.SetText then
536 item.set.globalCount:SetText(self:DisplayItemCount(item.globalCount, minGlobalStock));
537 end
538 end
539
540 if item.localCount == -3 then
541 -- Only if item count was queued, update it
542 item.localCount = addon:GetLocalItemCount(item.id, groupName);
543 if item.set.localCount and item.set.localCount.SetText then
544 item.set.localCount:SetText(self:DisplayItemCount(item.localCount, minLocalStock));
545 end
546 end
547
548 if item.value == -3 then
549 -- Only if item value was queued, update it
550
551 -- The itemlink might not have been loaded yet in which case we retry
552 item.link = item.link or select(2, GetItemInfo(item.id));
553
554 if item.link then
555 item.value = addon:GetAuctionValue(item.link, groupName);
556 if item.set.value and item.set.value.SetText then
557 item.set.value:SetText(self:DisplayMoney(item.value, priceThreshold));
558 end
559 end
560 end
561
562 i = i + 1;
563 CACHE_ITEMS_CURRENT = CACHE_ITEMS_CURRENT + 1;
564
565 if mod.frame then
566 mod.frame:SetStatusText(printf("Caching auction values and item-counts... %d%% has already been processed.", floor(CACHE_ITEMS_CURRENT / CACHE_ITEMS_TOTAL * 100)));
567 end
568
569 if i >= addon.db.profile.defaults.summary.speed then
570 return;
571 end
572 end
573 end
574 end
575
576 -- Reset trackers
577 CACHE_ITEMS_TOTAL = 0;
578 CACHE_ITEMS_CURRENT = 0;
579
580 -- Stop timer
581 self:CancelTimer(self.tmrUpdater, true);
582
583 -- Rebuild list so hidden items due to too low prices get added
584 self:Build();
585
586 -- Announce
587 mod.frame:SetStatusText("All required prices and itemcounts have been cached. This process took " .. ceil(GetTime() - cacheStart) .. " seconds.");
588
589 -- Forget time
590 cacheStart = nil;
591 end
592
593 function mod:ColorCode(num, required)
594 local percentage = ( num / required );
595
596 if percentage >= addon.db.profile.defaults.colors.green then
597 return printf("|cff00ff00%d|r", num);
598 elseif percentage >= addon.db.profile.defaults.colors.yellow then
599 return printf("|cffffff00%d|r", num);
600 elseif percentage >= addon.db.profile.defaults.colors.orange then
601 return printf("|cffff9933%d|r", num);
602 elseif percentage >= addon.db.profile.defaults.colors.red then
603 return printf("|cffff0000%d|r", num);
604 else
605 return num;
606 end
607 end
608
609 function mod:DisplayMoney(value, priceThreshold)
610 if value == -1 then
611 return "|cff0000ffNone up|r";
612 elseif value == -2 then
613 return "|cff0000ffNo AH mod|r";
614 elseif value == -3 then
615 return "|cffffff00Unknown|r";
616 elseif value == -4 then
617 return "|cff00ff00-|r";
618 elseif value == -5 then
619 return "|cffff9933Error|r";
620 elseif priceThreshold and value < priceThreshold then
621 return printf("|cffaaaaaa%s|r", sgsub(addon:ReadableMoney(value or 0, true), "|([a-fA-F0-9]+)([gsc]+)|r", "%2"));
622 else
623 return addon:ReadableMoney(value or 0, true);
624 end
625 end
626
627 function mod:NumberFormat(num)
628 local formatted = sgsub(num, "(%d)(%d%d%d)$", "%1,%2", 1);
629
630 while true do
631 formatted, matches = sgsub(formatted, "(%d)(%d%d%d),", "%1,%2,", 1);
632
633 if matches == 0 then
634 break;
635 end
636 end
637
638 return formatted;
639 end