Zerotorescue@0: local addon = LibStub("AceAddon-3.0"):GetAddon("Inventory"); Zerotorescue@1: local mod = addon:NewModule("Summary", "AceEvent-3.0", "AceTimer-3.0"); Zerotorescue@0: Zerotorescue@0: local AceGUI = LibStub("AceGUI-3.0"); Zerotorescue@0: Zerotorescue@0: function mod:OnEnable() Zerotorescue@0: self:RegisterWidgets(); Zerotorescue@0: Zerotorescue@1: -- Register our own slash commands Zerotorescue@1: addon:RegisterSlash(function() Zerotorescue@1: mod:BuildMain(); Zerotorescue@1: mod:Build(); Zerotorescue@1: end, "s", "sum", "summary"); Zerotorescue@0: end Zerotorescue@0: Zerotorescue@0: function mod:RegisterWidgets() Zerotorescue@0: -- Register InlineGroupWithButton-widget Zerotorescue@0: -- This widget adds a button next to the header of an inline group Zerotorescue@0: -- SetPoint doesn't seem usable within AceGUI. Zerotorescue@0: Zerotorescue@0: local widgetType = "InlineGroupWithButton"; Zerotorescue@0: local widgetVersion = 1; Zerotorescue@0: Zerotorescue@0: local function Constructor() Zerotorescue@0: local widget = AceGUI:Create("InlineGroup"); Zerotorescue@0: widget.type = widgetType; Zerotorescue@0: Zerotorescue@0: widget.MakeButton = function(self, buttonSettings) Zerotorescue@0: if type(buttonSettings) == "table" then Zerotorescue@0: local button = CreateFrame("Button", nil, self.frame, "UIPanelButtonTemplate"); Zerotorescue@0: button:SetText(buttonSettings.name); Zerotorescue@0: button:SetHeight(22); Zerotorescue@0: button:SetWidth(120); Zerotorescue@0: button:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -10, 5); Zerotorescue@0: button:SetScript("OnClick", buttonSettings.exec); Zerotorescue@0: button.tooltipTitle = buttonSettings.name; Zerotorescue@0: button.tooltip = buttonSettings.desc or ""; Zerotorescue@0: button:SetScript("OnEnter", function(self) Zerotorescue@0: GameTooltip:SetOwner(self, "ANCHOR_NONE") Zerotorescue@0: GameTooltip:SetPoint("BOTTOM", self, "TOP") Zerotorescue@0: GameTooltip:SetText(self.tooltipTitle, 1, .82, 0, 1) Zerotorescue@0: Zerotorescue@0: if type(self.tooltip) == "string" then Zerotorescue@0: GameTooltip:AddLine(self.tooltip, 1, 1, 1, 1); Zerotorescue@0: end Zerotorescue@0: Zerotorescue@0: GameTooltip:Show(); Zerotorescue@0: end); Zerotorescue@0: button:SetScript("OnLeave", function(self) Zerotorescue@0: GameTooltip:Hide(); Zerotorescue@0: end); Zerotorescue@0: else Zerotorescue@0: error("settings must be a table - usage: MakeButton(table);"); Zerotorescue@0: end Zerotorescue@0: end Zerotorescue@0: Zerotorescue@0: return widget; Zerotorescue@0: end Zerotorescue@0: Zerotorescue@0: AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion); Zerotorescue@0: end Zerotorescue@0: Zerotorescue@1: local itemsCache = {}; Zerotorescue@1: local CACHE_ITEMS_TOTAL, CACHE_ITEMS_CURRENT, CACHE_ITEMS_PER_UPDATE = 0, 0, 5; Zerotorescue@1: local cacheStart; Zerotorescue@1: Zerotorescue@0: function mod:BuildMain() Zerotorescue@1: LibStub("AceConfigDialog-3.0"):Close("InventoryOptions"); Zerotorescue@0: Zerotorescue@10: self:CloseFrame(); Zerotorescue@10: Zerotorescue@1: -- Main Window Zerotorescue@1: mod.frame = AceGUI:Create("Frame"); Zerotorescue@1: mod.frame:SetTitle("Inventory Summary"); Zerotorescue@1: mod.frame:SetLayout("Fill"); Zerotorescue@1: mod.frame:SetCallback("OnClose", function(widget) Zerotorescue@7: mod:CancelTimer(self.tmrUpdater, true); Zerotorescue@9: mod:CloseFrame(); Zerotorescue@1: end); Zerotorescue@0: Zerotorescue@1: -- ScrollFrame child Zerotorescue@1: mod.scrollFrame = AceGUI:Create("ScrollFrame"); Zerotorescue@1: mod.scrollFrame:SetLayout("Flow"); Zerotorescue@0: Zerotorescue@1: mod.frame:AddChild(mod.scrollFrame); Zerotorescue@1: Zerotorescue@1: -- Reset items cache Zerotorescue@1: table.wipe(itemsCache); Zerotorescue@0: end Zerotorescue@0: Zerotorescue@9: function mod:CloseFrame() Zerotorescue@9: if mod.frame then Zerotorescue@9: mod.frame:Release(); Zerotorescue@9: mod.frame = nil; Zerotorescue@10: Zerotorescue@10: -- Stop caching Zerotorescue@10: Zerotorescue@10: -- Stop timer Zerotorescue@10: self:CancelTimer(self.tmrUpdater, true); Zerotorescue@10: Zerotorescue@10: -- Reset trackers Zerotorescue@10: CACHE_ITEMS_TOTAL = 0; Zerotorescue@10: CACHE_ITEMS_CURRENT = 0; Zerotorescue@9: end Zerotorescue@9: end Zerotorescue@9: Zerotorescue@0: local sortMethod = "item"; Zerotorescue@0: local sortDirectory = "ASC"; Zerotorescue@0: local function ReSort(subject) Zerotorescue@0: if sortMethod == subject then Zerotorescue@0: sortDirectory = (sortDirectory == "ASC" and "DESC") or "ASC"; Zerotorescue@0: else Zerotorescue@0: sortDirectory = "ASC"; Zerotorescue@0: end Zerotorescue@0: sortMethod = subject; Zerotorescue@0: Zerotorescue@0: mod:Build(); Zerotorescue@0: end Zerotorescue@10: Zerotorescue@10: -- From http://www.wowwiki.com/API_sort Zerotorescue@10: local function pairsByKeys (t, f) Zerotorescue@10: local a = {} Zerotorescue@10: for n in pairs(t) do table.insert(a, n) end Zerotorescue@10: table.sort(a, f) Zerotorescue@10: local i = 0 -- iterator variable Zerotorescue@10: local iter = function () -- iterator function Zerotorescue@10: i = i + 1 Zerotorescue@10: if a[i] == nil then return nil Zerotorescue@10: else return a[i], t[a[i]] Zerotorescue@10: end Zerotorescue@10: end Zerotorescue@10: return iter Zerotorescue@10: end Zerotorescue@0: Zerotorescue@0: function mod:Build() Zerotorescue@10: local buildStartTime, times = GetTime(), {}; Zerotorescue@0: Zerotorescue@1: -- 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 Zerotorescue@1: -- This appears to be required for each container we wish to pause, so also do this for the contents Zerotorescue@1: mod.scrollFrame:PauseLayout(); Zerotorescue@1: Zerotorescue@10: mod.scrollFrame:ReleaseChildren(); Zerotorescue@10: Zerotorescue@10: -- Refresh button Zerotorescue@10: local btnRefresh = AceGUI:Create("Button"); Zerotorescue@10: btnRefresh:SetText("Refresh"); Zerotorescue@10: -- SetTooltip: Reload all item counts and auction values. Zerotorescue@10: btnRefresh:SetRelativeWidth(.2); Zerotorescue@10: btnRefresh:SetCallback("OnClick", function() Zerotorescue@10: -- Reset items cache Zerotorescue@10: table.wipe(itemsCache); Zerotorescue@10: Zerotorescue@10: -- Rebuild itemlist and start caching Zerotorescue@10: mod:Build(); Zerotorescue@10: end); Zerotorescue@10: Zerotorescue@10: mod.scrollFrame:AddChild(btnRefresh); Zerotorescue@10: Zerotorescue@10: -- Speed slider Zerotorescue@10: local btnRefresh = AceGUI:Create("Slider"); Zerotorescue@10: btnRefresh:SetLabel("Processing speed"); Zerotorescue@10: btnRefresh:SetSliderValues(0.01, 1, 0.01); Zerotorescue@10: btnRefresh:SetIsPercent(true); Zerotorescue@10: -- SetTooltip: Change the speed at which item counts and auction values are being cached. Higher is faster but may drastically reduce your FPS while caching. Zerotorescue@10: btnRefresh:SetRelativeWidth(.3); Zerotorescue@10: btnRefresh:SetCallback("OnMouseUp", function(self, event, value) Zerotorescue@10: CACHE_ITEMS_PER_UPDATE = ceil( value * 100 / 5 ); -- max = 20, min = 1 Zerotorescue@10: end); Zerotorescue@10: btnRefresh:SetValue( CACHE_ITEMS_PER_UPDATE * 5 / 100 ); Zerotorescue@10: Zerotorescue@10: mod.scrollFrame:AddChild(btnRefresh); Zerotorescue@10: Zerotorescue@10: times.init = ceil( ( GetTime() - buildStartTime ) * 1000 ); Zerotorescue@10: addon:Debug("Time spent legend: (init / sorting / preparing / building / all)."); Zerotorescue@10: Zerotorescue@1: local playerName = UnitName("player"); Zerotorescue@1: Zerotorescue@1: -- Go through all our stored groups Zerotorescue@10: for groupName, values in pairsByKeys(addon.db.global.groups, function(a, b) return a:lower() < b:lower(); end) do Zerotorescue@10: local groupStartTime, groupTimes = GetTime(), {}; Zerotorescue@10: Zerotorescue@1: local trackAt = (values.trackAtCharacters or (values.trackAtCharacters == nil and addon.db.global.defaults.trackAtCharacters)); Zerotorescue@1: Zerotorescue@1: -- Does this group have any items and do we want to track it at this char? Zerotorescue@1: if values.items and trackAt[playerName] then Zerotorescue@10: Zerotorescue@10: Zerotorescue@0: -- Get group settings Zerotorescue@9: local minimumStock = (values.minimumStock or (values.minimumStock == nil and addon.db.global.defaults.minimumStock)); Zerotorescue@1: local showWhenBelow = (values.summaryThresholdShow or (values.summaryThresholdShow == nil and addon.db.global.defaults.summaryThresholdShow)); Zerotorescue@1: local priceThreshold = (values.priceThreshold or (values.priceThreshold == nil and addon.db.global.defaults.priceThreshold)); Zerotorescue@1: local hideWhenBelowPriceThreshold = (values.hideFromSummaryWhenBelowPriceThreshold or (values.hideFromSummaryWhenBelowPriceThreshold == nil and addon.db.global.defaults.hideFromSummaryWhenBelowPriceThreshold)); Zerotorescue@0: Zerotorescue@10: Zerotorescue@0: -- Make group container Zerotorescue@0: local iGroup = AceGUI:Create("InlineGroupWithButton"); Zerotorescue@1: iGroup:PauseLayout(); Zerotorescue@0: iGroup:SetTitle(groupName); Zerotorescue@0: iGroup:SetFullWidth(true); Zerotorescue@0: iGroup:SetLayout("Flow"); Zerotorescue@0: iGroup:MakeButton({ Zerotorescue@0: name = "Queue", Zerotorescue@0: desc = "Queue all items in this group.", Zerotorescue@0: exec = function() Zerotorescue@0: print(groupName); Zerotorescue@0: end, Zerotorescue@0: }); Zerotorescue@0: Zerotorescue@10: Zerotorescue@10: Zerotorescue@0: -- Headers Zerotorescue@1: Zerotorescue@0: -- Itemlink Zerotorescue@0: local lblItem = AceGUI:Create("InteractiveLabel"); Zerotorescue@0: lblItem:SetText("|cfffed000Item|r"); Zerotorescue@0: lblItem:SetFontObject(GameFontHighlight); Zerotorescue@10: lblItem:SetRelativeWidth(.7); Zerotorescue@0: lblItem:SetCallback("OnClick", function() ReSort("item"); end); Zerotorescue@0: Zerotorescue@0: iGroup:AddChild(lblItem); Zerotorescue@0: Zerotorescue@0: -- Current quantity Zerotorescue@0: local lblQuantity = AceGUI:Create("InteractiveLabel"); Zerotorescue@0: lblQuantity:SetText("|cfffed000Cur.|r"); Zerotorescue@0: lblQuantity:SetFontObject(GameFontHighlight); Zerotorescue@10: lblQuantity:SetRelativeWidth(.099); Zerotorescue@0: lblQuantity:SetCallback("OnClick", function() ReSort("current"); end); Zerotorescue@0: Zerotorescue@0: iGroup:AddChild(lblQuantity); Zerotorescue@0: Zerotorescue@0: -- Required stock Zerotorescue@9: local lblMinimumStock = AceGUI:Create("InteractiveLabel"); Zerotorescue@9: lblMinimumStock:SetText("|cfffed000Req.|r"); Zerotorescue@9: lblMinimumStock:SetFontObject(GameFontHighlight); Zerotorescue@10: lblMinimumStock:SetRelativeWidth(.099); Zerotorescue@9: lblMinimumStock:SetCallback("OnClick", function() ReSort("percentage"); end); Zerotorescue@0: Zerotorescue@9: iGroup:AddChild(lblMinimumStock); Zerotorescue@0: Zerotorescue@1: -- Lowest value Zerotorescue@1: local lblValue = AceGUI:Create("InteractiveLabel"); Zerotorescue@1: lblValue:SetText("|cfffed000Value|r"); Zerotorescue@1: lblValue:SetFontObject(GameFontHighlight); Zerotorescue@10: lblValue:SetRelativeWidth(.099); Zerotorescue@1: lblValue:SetCallback("OnClick", function() ReSort("value"); end); Zerotorescue@1: Zerotorescue@1: iGroup:AddChild(lblValue); Zerotorescue@1: Zerotorescue@10: Zerotorescue@10: -- Retrieve items list Zerotorescue@1: if not itemsCache[groupName] then Zerotorescue@1: itemsCache[groupName] = {}; Zerotorescue@0: Zerotorescue@1: -- Sort item list Zerotorescue@1: for itemId in pairs(values.items) do Zerotorescue@1: local itemName, itemLink, itemRarity = GetItemInfo(itemId); Zerotorescue@1: Zerotorescue@1: table.insert(itemsCache[groupName], { Zerotorescue@1: id = itemId, Zerotorescue@1: name = itemName, Zerotorescue@1: link = itemLink, Zerotorescue@10: value = ((priceThreshold == 0) and 0) or -3,-- if no price threshold is set for this item, then don't look it up either --addon:GetAuctionValue(itemLink), Zerotorescue@1: rarity = itemRarity, Zerotorescue@9: count = -3,--addon:GetItemCount(itemId), Zerotorescue@1: set = {}, Zerotorescue@1: }); Zerotorescue@1: CACHE_ITEMS_TOTAL = CACHE_ITEMS_TOTAL + 1; Zerotorescue@1: end Zerotorescue@0: end Zerotorescue@0: Zerotorescue@10: groupTimes.init = ceil( ( GetTime() - groupStartTime ) * 1000 ); Zerotorescue@10: Zerotorescue@10: Zerotorescue@10: Zerotorescue@10: -- Sort items Zerotorescue@1: table.sort(itemsCache[groupName], function(a, b) Zerotorescue@1: if sortMethod == "item" and a.rarity == b.rarity then Zerotorescue@1: -- Do a name-compare for items of the same rarity Zerotorescue@1: -- Otherwise epics first, then junk Zerotorescue@0: if sortDirectory == "ASC" then Zerotorescue@1: return a.name:upper() < b.name:upper(); Zerotorescue@0: else Zerotorescue@1: return a.name:upper() > b.name:upper(); Zerotorescue@1: end Zerotorescue@1: elseif sortMethod == "item" then Zerotorescue@1: if sortDirectory == "ASC" then Zerotorescue@1: return a.rarity > b.rarity; -- the comparers were reversed because we want epics first Zerotorescue@1: else Zerotorescue@1: return a.rarity < b.rarity; -- the comparers were reversed because we want epics first Zerotorescue@0: end Zerotorescue@0: elseif sortMethod == "current" then Zerotorescue@0: if sortDirectory == "ASC" then Zerotorescue@0: return a.count < b.count; Zerotorescue@0: else Zerotorescue@0: return a.count > b.count; Zerotorescue@0: end Zerotorescue@0: elseif sortMethod == "percentage" then Zerotorescue@0: if sortDirectory == "ASC" then Zerotorescue@10: return ( a.count / minimumStock ) < ( b.count / minimumStock ); Zerotorescue@0: else Zerotorescue@10: return ( a.count / minimumStock ) > ( b.count / minimumStock ); Zerotorescue@0: end Zerotorescue@1: elseif sortMethod == "value" then Zerotorescue@1: if sortDirectory == "ASC" then Zerotorescue@1: return a.value < b.value; Zerotorescue@1: else Zerotorescue@1: return a.value > b.value; Zerotorescue@1: end Zerotorescue@0: end Zerotorescue@0: end); Zerotorescue@0: Zerotorescue@10: groupTimes.sorting = ceil( ( GetTime() - groupStartTime ) * 1000 ); Zerotorescue@10: Zerotorescue@10: Zerotorescue@10: Zerotorescue@10: Zerotorescue@10: -- Show itemslist Zerotorescue@1: for i, item in pairs(itemsCache[groupName]) do Zerotorescue@9: if ( item.count / minimumStock ) < showWhenBelow and not (hideWhenBelowPriceThreshold and item.value < priceThreshold) then Zerotorescue@0: local btnItemLink = AceGUI:Create("ItemLinkButton"); Zerotorescue@10: --btnItemLink:SetUserData("exec", function() Zerotorescue@10: -- print("Nothing happening yet."); Zerotorescue@10: --end); Zerotorescue@10: btnItemLink:SetRelativeWidth(.7); Zerotorescue@1: btnItemLink:SetItemId(item.id); Zerotorescue@0: Zerotorescue@0: iGroup:AddChild(btnItemLink); Zerotorescue@0: Zerotorescue@0: -- Current quantity Zerotorescue@0: local lblQuantity = AceGUI:Create("Label"); Zerotorescue@9: lblQuantity:SetText(self:DisplayItemCount(item.count, minimumStock)); Zerotorescue@10: lblQuantity:SetRelativeWidth(.099); Zerotorescue@0: Zerotorescue@0: iGroup:AddChild(lblQuantity); Zerotorescue@0: Zerotorescue@0: -- Required stock Zerotorescue@9: local lblMinimumStock = AceGUI:Create("Label"); Zerotorescue@9: lblMinimumStock:SetText(minimumStock); Zerotorescue@10: lblMinimumStock:SetRelativeWidth(.099); Zerotorescue@0: Zerotorescue@9: iGroup:AddChild(lblMinimumStock); Zerotorescue@1: Zerotorescue@1: -- Value Zerotorescue@1: local lblValue = AceGUI:Create("Label"); Zerotorescue@1: lblValue:SetText(self:DisplayMoney(item.value, priceThreshold)); Zerotorescue@10: lblValue:SetRelativeWidth(.099); Zerotorescue@1: Zerotorescue@1: iGroup:AddChild(lblValue); Zerotorescue@1: Zerotorescue@1: -- Remember references to the value and current fields so we can fill them later Zerotorescue@1: if item.set then Zerotorescue@10: -- -3 means the price is unknown, queue look up Zerotorescue@10: if item.value == -3 then Zerotorescue@10: item.set.value = lblValue; Zerotorescue@10: end Zerotorescue@10: if item.count == -3 then Zerotorescue@10: item.set.current = lblQuantity; Zerotorescue@10: end Zerotorescue@10: Zerotorescue@10: -- Don't queue if we already know everything we want to know Zerotorescue@10: if item.value ~= -3 and item.count ~= -3 then Zerotorescue@10: item.set = nil; Zerotorescue@10: end Zerotorescue@1: end Zerotorescue@0: end Zerotorescue@0: end Zerotorescue@0: Zerotorescue@10: groupTimes.preparing = ceil( ( GetTime() - groupStartTime ) * 1000 ); Zerotorescue@10: Zerotorescue@1: iGroup:ResumeLayout(); Zerotorescue@1: mod.scrollFrame:AddChild(iGroup); -- this can take up to .5 seconds, might need to look into again at a later time Zerotorescue@10: Zerotorescue@10: groupTimes.building = ceil( ( GetTime() - groupStartTime ) * 1000 ); Zerotorescue@0: end Zerotorescue@10: Zerotorescue@10: addon:Debug(("Building of %s took %d ms (%d / %d / %d / %d / %d)."):format(groupName, ceil( ( GetTime() - groupStartTime ) * 1000 ), groupTimes.init, groupTimes.sorting, groupTimes.preparing, groupTimes.building, ceil( ( GetTime() - buildStartTime ) * 1000 ))); Zerotorescue@0: end Zerotorescue@1: Zerotorescue@1: mod.scrollFrame:ResumeLayout(); Zerotorescue@1: mod.scrollFrame:DoLayout(); Zerotorescue@1: Zerotorescue@10: addon:Debug(("Done building summary after %d ms."):format(ceil( ( GetTime() - buildStartTime ) * 1000 ))); Zerotorescue@10: Zerotorescue@1: if CACHE_ITEMS_TOTAL > 0 then Zerotorescue@1: cacheStart = GetTime(); Zerotorescue@7: self:CancelTimer(self.tmrUpdater, true); Zerotorescue@1: 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) Zerotorescue@1: end Zerotorescue@1: end Zerotorescue@1: Zerotorescue@1: function mod:UpdateNextItem() Zerotorescue@1: local i = 0; Zerotorescue@1: Zerotorescue@1: for groupName, items in pairs(itemsCache) do Zerotorescue@1: local minimumStock = addon:GetOptionByKey(groupName, "minimumStock"); Zerotorescue@1: local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold"); Zerotorescue@1: Zerotorescue@1: for _, item in pairs(items) do Zerotorescue@1: if item.set then Zerotorescue@10: if item.count == -3 then Zerotorescue@10: -- Only if item count was queued, update it Zerotorescue@10: item.count = addon:GetItemCount(item.id); Zerotorescue@10: if item.set.current and item.set.current.SetText then Zerotorescue@10: item.set.current:SetText(self:DisplayItemCount(item.count, minimumStock)); Zerotorescue@10: end Zerotorescue@1: end Zerotorescue@1: Zerotorescue@10: if item.value == -3 then Zerotorescue@10: -- Only if item value was queued, update it Zerotorescue@10: item.value = addon:GetAuctionValue(item.link); Zerotorescue@10: if item.set.value and item.set.value.SetText then Zerotorescue@10: item.set.value:SetText(self:DisplayMoney(item.value, priceThreshold)); Zerotorescue@10: end Zerotorescue@1: end Zerotorescue@1: Zerotorescue@1: item.set = nil; Zerotorescue@1: Zerotorescue@1: i = i + 1; Zerotorescue@1: CACHE_ITEMS_CURRENT = CACHE_ITEMS_CURRENT + 1; Zerotorescue@1: Zerotorescue@9: if mod.frame then Zerotorescue@9: mod.frame:SetStatusText(("Caching auction values and item-counts... %d%% has already been processed."):format(floor(CACHE_ITEMS_CURRENT / CACHE_ITEMS_TOTAL * 100))); Zerotorescue@9: end Zerotorescue@1: Zerotorescue@1: if i >= CACHE_ITEMS_PER_UPDATE then Zerotorescue@1: return; Zerotorescue@1: end Zerotorescue@1: end Zerotorescue@1: end Zerotorescue@1: end Zerotorescue@1: Zerotorescue@1: -- Reset trackers Zerotorescue@1: CACHE_ITEMS_TOTAL = 0; Zerotorescue@1: CACHE_ITEMS_CURRENT = 0; Zerotorescue@1: Zerotorescue@1: -- Stop timer Zerotorescue@1: self:CancelTimer(self.tmrUpdater, true); Zerotorescue@10: Zerotorescue@10: -- Rebuild list so hidden items due to too low prices get added Zerotorescue@10: self:Build(); Zerotorescue@1: Zerotorescue@1: -- Announce Zerotorescue@10: mod.frame:SetStatusText("All required prices and itemcounts have been cached. This process took " .. ceil(GetTime() - cacheStart) .. " seconds."); Zerotorescue@1: Zerotorescue@1: -- Forget time Zerotorescue@1: cacheStart = nil; Zerotorescue@0: end Zerotorescue@0: Zerotorescue@0: function mod:ColorCode(num, required) Zerotorescue@0: local percentage = ( num / required ); Zerotorescue@0: Zerotorescue@0: if percentage >= addon.db.global.defaults.colors.green then Zerotorescue@0: return ("|cff00ff00%d|r"):format(num); Zerotorescue@0: elseif percentage >= addon.db.global.defaults.colors.yellow then Zerotorescue@0: return ("|cffffff00%d|r"):format(num); Zerotorescue@0: elseif percentage >= addon.db.global.defaults.colors.orange then Zerotorescue@0: return ("|cffff9933%d|r"):format(num); Zerotorescue@0: elseif percentage >= addon.db.global.defaults.colors.red then Zerotorescue@0: return ("|cffff0000%d|r"):format(num); Zerotorescue@0: end Zerotorescue@0: end Zerotorescue@0: Zerotorescue@1: function mod:DisplayMoney(value, priceThreshold) Zerotorescue@7: if value == -1 then Zerotorescue@7: return "|cff0000ffNone up|r"; Zerotorescue@7: elseif value == -2 then Zerotorescue@7: return "|cff0000ffNo AH mod|r"; Zerotorescue@9: elseif value == -3 then Zerotorescue@9: return "|cffffff00Unknown|r"; Zerotorescue@7: elseif value < priceThreshold then Zerotorescue@1: return ("|cffff0000%s|r"):format(addon:ReadableMoney(value or 0, true)); Zerotorescue@1: else Zerotorescue@1: return addon:ReadableMoney(value or 0, true); Zerotorescue@1: end Zerotorescue@1: end Zerotorescue@1: Zerotorescue@9: function mod:DisplayItemCount(value, minimumStock) Zerotorescue@9: if value == -3 then Zerotorescue@9: return "|cffffff00Unknown|r"; Zerotorescue@9: else Zerotorescue@9: return self:ColorCode(value, minimumStock); Zerotorescue@9: end Zerotorescue@9: end Zerotorescue@9: Zerotorescue@0: function mod:NumberFormat(num) Zerotorescue@0: local formatted = string.gsub(num, "(%d)(%d%d%d)$", "%1,%2", 1); Zerotorescue@0: Zerotorescue@0: while true do Zerotorescue@0: formatted, matches = string.gsub(formatted, "(%d)(%d%d%d),", "%1,%2,", 1); Zerotorescue@0: Zerotorescue@0: if matches == 0 then Zerotorescue@0: break; Zerotorescue@0: end Zerotorescue@0: end Zerotorescue@0: Zerotorescue@0: return formatted; Zerotorescue@1: end Zerotorescue@1: Zerotorescue@1: --[[ Zerotorescue@1: No longer used, we're now caching complete item data instead of just AH values. Zerotorescue@1: local AuctionValueCache = {}; Zerotorescue@1: function mod:GetAuctionValue(link) Zerotorescue@1: local itemId = addon:GetItemId(link); Zerotorescue@1: Zerotorescue@1: if AuctionValueCache[itemId] then Zerotorescue@1: return AuctionValueCache[itemId]; Zerotorescue@1: else Zerotorescue@1: local value = addon:GetAuctionValue(link); Zerotorescue@1: Zerotorescue@1: AuctionValueCache[itemId] = value; Zerotorescue@1: Zerotorescue@1: -- Reset the cache 1 minute after last updating it Zerotorescue@1: self:CancelTimer(self.tmrResetCache, true); Zerotorescue@1: self.tmrResetCache = self:ScheduleTimer(function() Zerotorescue@1: table.wipe(AuctionValueCache); Zerotorescue@1: Zerotorescue@1: mod.frame:SetStatusText("The auction item value cache has been reset."); Zerotorescue@1: end, 60); Zerotorescue@1: mod.frame:SetStatusText(""); Zerotorescue@1: Zerotorescue@1: return value; Zerotorescue@1: end Zerotorescue@1: end Zerotorescue@1: ]]