-
-
Save Phanx/2e9f77fb210a25dea90f22dfe9abc26f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
------------------------------------------------------------------------ | |
-- Local variables | |
------------------------------------------------------------------------ | |
local BREAKITDOWN, ns = ... | |
local defaults = { | |
width = 250, -- width of the list window | |
rowHeight = 24, -- height of each item in the list window | |
maxRows = 10, -- maximum number of rows to show at once | |
sortKey = "name", -- name or total? | |
sortDirection = "ascending", -- ascending or descending? | |
confirmReset = false, -- require confirmation when clicking reset? | |
saveResults = true, -- save results between sessions? | |
} | |
local actions = {} | |
for _, id in pairs({ | |
13262, -- Disenchant | |
51005, -- Milling | |
31252, -- Prospecting | |
11993, -- Herb Gathering | |
10248, -- Mining | |
}) do | |
local name = GetSpellInfo(id) | |
if name then | |
actions[name] = true | |
end | |
end | |
local L = setmetatable({}, { __index = function(t, k) | |
local v = tostring(k) | |
rawset(t, k, v) | |
return v | |
end }) | |
local db | |
local gathering | |
local results | |
------------------------------------------------------------------------ | |
-- Initialization | |
------------------------------------------------------------------------ | |
local addon = CreateFrame("Frame", "BreakItDown", UIParent) | |
addon:SetScript("OnEvent", function(self, event, ...) return self[event] and self[event](self, ...) end) | |
addon:RegisterEvent("ADDON_LOADED") | |
addon:Hide() | |
function addon:ADDON_LOADED(name) | |
if name ~= BREAKITDOWN then return end | |
local function copyDefaults(src, dst) | |
if not src then return {} end | |
if not dst then dst = {} end | |
for k, v in pairs(src) do | |
if type(v) == "table" then | |
dst[k] = copyDefaults(v, dst[k]) | |
elseif type(dst[k]) ~= type(v) then | |
dst[k] = v | |
end | |
end | |
return dst | |
end | |
db = copyDefaults(defaults, BreakItDownDB) | |
BreakItDownDB = db | |
if db.saveResults then | |
results = type(db.results) == "table" and db.results or {} | |
db.results = results | |
else | |
results = {} | |
db.results = nil | |
end | |
self.results = results -- outside access for debugging | |
self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") | |
self:RegisterEvent("LOOT_OPENED") | |
end | |
------------------------------------------------------------------------ | |
-- Core logic | |
------------------------------------------------------------------------ | |
function addon:UNIT_SPELLCAST_SUCCEEDED(unit, spell) | |
if unit ~= "player" or not actions[spell] then return end | |
-- print(spell, "succeeded.") | |
gathering = true | |
end | |
function addon:LOOT_OPENED() | |
if not gathering then return end | |
local n = GetNumLootItems() | |
-- print("Loot window opened with", n, "items.") | |
for i = 1, n do | |
local icon, name, quantity, locked = GetLootSlotInfo(i) | |
if quantity > 0 then | |
local t = results[name] | |
if not t then | |
t = {} | |
results[name] = t | |
end | |
local link = GetLootSlotLink(i) | |
t.color = link:match("|cff(%x%x%x%x%x%x)") | |
t.name = name | |
t.icon = icon | |
t.link = link | |
t.total = (t.total or 0) + quantity | |
local _, size = DEFAULT_CHAT_FRAME:GetFont() | |
-- print(string.format("|T%s:%d:%d:0:%d|t |cff%s%s|r x%d (%d)", icon, size * 0.6, size * 0.6, 1, t.color, name, quantity, t.total)) | |
end | |
end | |
gathering = nil | |
if self:IsShown() then | |
self:Update() | |
end | |
end | |
------------------------------------------------------------------------ | |
-- Display logic | |
------------------------------------------------------------------------ | |
do | |
local sorted = {} | |
local sortby = { | |
ascending = function(a, b) return results[a][db.sortKey] < results[b][db.sortKey] end, -- A-Z, 0-9 | |
descending = function(a, b) return results[a][db.sortKey] > results[b][db.sortKey] end, -- Z-A, 9-0 | |
} | |
function addon:Update() | |
for name in pairs(results) do | |
-- print("Processing result:", name) | |
table.insert(sorted, name) | |
end | |
local numResultsToShow = math.min(db.maxRows, #sorted) | |
if numResultsToShow == 0 then | |
-- print("Populating row 1") | |
local row = self.itemButtons[1] | |
row.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark") | |
row.name:SetText(L["Nothing to report!"]) | |
row.name:SetTextColor(GameFontDisable:GetTextColor()) | |
row.total:SetText(" ") | |
self:SetHeight(12 + self.titleText:GetHeight() + 6 + db.rowHeight + 6 + 24 + 12) | |
numResultsToShow = 1 | |
else | |
table.sort(sorted, sortby[db.sortDirection]) | |
for i = 1, numResultsToShow do | |
-- print("Populating row", i) | |
local data = results[sorted[i]] | |
local row = self.itemButtons[i] | |
row.icon:SetTexture(data.icon) | |
row.name:SetFormattedText("|cff%s%s|r", data.color, data.name) | |
row.name:SetTextColor(GameFontHighlight:GetTextColor()) | |
row.total:SetText(data.total) | |
row.link = data.link | |
row:Show() | |
end | |
wipe(sorted) | |
self:SetHeight(12 + self.titleText:GetHeight() + 6 + (numResultsToShow * db.rowHeight) + (numResultsToShow - 1) + 6 + 24 + 12) | |
end | |
for i = numResultsToShow + 1, #self.itemButtons do | |
-- print("Clearing row", i) | |
local row = self.itemButtons[i] | |
row:Hide() | |
row.icon:SetTexture("") | |
row.name:SetText(" ") | |
row.total:SetText(" ") | |
row.link = nil | |
end | |
end | |
end | |
------------------------------------------------------------------------ | |
-- Visual elements | |
------------------------------------------------------------------------ | |
function addon:SetupFrame() | |
tinsert(UISpecialFrames, "BreakItDown") | |
if db.x and db.y then | |
self:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", db.x, db.y) | |
else | |
self:SetPoint("CENTER") | |
end | |
self:SetWidth(db.width) | |
self:SetBackdrop({ | |
bgFile = "Interface\\BUTTONS\\WHITE8X8", tile = false, tileSize = 8, | |
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16, | |
insets = { left = 4, right = 4, top = 4, bottom = 4 } | |
}) | |
self:SetBackdropColor(10/255, 10/255, 10/255, 1) | |
self:SetBackdropBorderColor(1, 1, 1, 1) | |
local function StopMoving(self) | |
self:StopMovingOrSizing() | |
local x, y = self:GetLeft(), self:GetTop() | |
self:ClearAllPoints() | |
self:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y) | |
end | |
self:EnableMouse(true) | |
self:SetMovable(true) | |
self:SetClampedToScreen(true) | |
self:RegisterForDrag("LeftButton") | |
self:SetScript("OnDragStart", self.StartMoving) | |
self:SetScript("OnDragStop", StopMoving) | |
self:SetScript("OnHide", StopMoving) | |
local tt = self:CreateFontString(nil, "OVERLAY", "NumberFontNormal") | |
tt:SetPoint("TOPLEFT", 10, -12) | |
tt:SetPoint("TOPRIGHT", -10, -12) | |
tt:SetJustifyH("CENTER") | |
tt:SetText(L["Break It Down"]) | |
tt:SetTextColor(GameFontNormal:GetTextColor()) | |
self.titleText = tt | |
local function item_OnEnter(item) | |
if item.link then | |
-- print("OnEnter", item.link) | |
GameTooltip:SetOwner(item, "ANCHOR_NONE") | |
GameTooltip:SetPoint("TOPLEFT", item, "TOPRIGHT", 14, 5) | |
GameTooltip:SetHyperlink(item.link) | |
end | |
end | |
local function item_OnLeave(item) | |
GameTooltip:Hide() | |
end | |
local function item_OnClick(item, button) | |
if button == "RightButton" then | |
if IsAltKeyDown() then | |
results[item.name] = nil | |
self:Update() | |
end | |
elseif IsModifiedClick() then | |
HandleModifiedItemClick(item.link) | |
end | |
end | |
local items = setmetatable({}, { __index = function(items, i) | |
local item = CreateFrame("Button", nil, self) | |
item:SetHeight(db.rowHeight) | |
if i == 1 then | |
item:SetPoint("TOPLEFT", tt, "BOTTOMLEFT", 2, -6) | |
item:SetPoint("TOPRIGHT", tt, "BOTTOMRIGHT", -2, -6) | |
else | |
item:SetPoint("TOPLEFT", items[i-1], "BOTTOMLEFT", 0, -1) | |
item:SetPoint("TOPRIGHT", items[i-1], "BOTTOMRIGHT", 0, -1) | |
end | |
local icon = item:CreateTexture(nil, "OVERLAY") | |
icon:SetPoint("TOPLEFT") | |
icon:SetPoint("BOTTOMLEFT") | |
icon:SetWidth(db.rowHeight) | |
item.icon = icon | |
local total = item:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") | |
total:SetPoint("TOPRIGHT") | |
total:SetPoint("BOTTOMRIGHT") | |
total:SetJustifyH("RIGHT") | |
item.total = total | |
local name = item:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") | |
name:SetPoint("TOPLEFT", icon, "TOPRIGHT", 4, 0) | |
name:SetPoint("BOTTOMLEFT", icon, "BOTTOMRIGHT", 4, 0) | |
name:SetPoint("RIGHT", total, "LEFT", -4, 0) | |
name:SetJustifyH("LEFT") | |
item.name = name | |
item.id = i | |
item:EnableMouse(true) | |
item:RegisterForClicks("AnyUp") | |
item:SetScript("OnEnter", item_OnEnter) | |
item:SetScript("OnLeave", item_OnLeave) | |
item:SetScript("OnClick", item_OnClick) | |
rawset(items, i, item) | |
return item | |
end }) | |
self.itemButtons = items | |
local reset = CreateFrame("Button", nil, self) | |
reset:SetNormalFontObject(GameFontNormalSmall) | |
reset:SetDisabledFontObject(GameFontDisable) | |
reset:SetHighlightFontObject(GameFontHighlightSmall) | |
reset:SetNormalTexture([[Interface\Buttons\UI-Panel-Button-Up]]) | |
reset:GetNormalTexture():SetTexCoord(0, 0.625, 0, 0.6875) | |
reset:SetPushedTexture([[Interface\Buttons\UI-Panel-Button-Down]]) | |
reset:GetPushedTexture():SetTexCoord(0, 0.625, 0, 0.6875) | |
reset:SetHighlightTexture([[Interface\Buttons\UI-Panel-Button-Highlight]]) | |
reset:GetHighlightTexture():SetTexCoord(0, 0.625, 0, 0.6875) | |
reset:GetHighlightTexture():SetBlendMode("ADD") | |
reset:SetDisabledTexture([[Interface\Buttons\UI-Panel-Button-Disabled]]) | |
reset:GetDisabledTexture():SetTexCoord(0, 0.625, 0, 0.6875) | |
reset:SetPoint("BOTTOMLEFT", 12, 12) | |
reset:SetWidth(80) | |
reset:SetHeight(24) | |
reset:SetText(RESET) | |
reset:SetScript("OnClick", function() | |
wipe(results) | |
if self:IsShown() then | |
self:Update() | |
end | |
end) | |
self.resetButton = reset | |
local close = CreateFrame("Button", nil, self) | |
close:SetNormalFontObject(GameFontNormalSmall) | |
close:SetHighlightFontObject(GameFontHighlightSmall) | |
close:SetNormalTexture([[Interface\Buttons\UI-Panel-Button-Up]]) | |
close:GetNormalTexture():SetTexCoord(0, 0.625, 0, 0.6875) | |
close:SetPushedTexture([[Interface\Buttons\UI-Panel-Button-Down]]) | |
close:GetPushedTexture():SetTexCoord(0, 0.625, 0, 0.6875) | |
close:SetHighlightTexture([[Interface\Buttons\UI-Panel-Button-Highlight]]) | |
close:GetHighlightTexture():SetTexCoord(0, 0.625, 0, 0.6875) | |
close:GetHighlightTexture():SetBlendMode("ADD") | |
close:SetPoint("BOTTOMRIGHT", -12, 12) | |
close:SetPoint("TOPLEFT", reset, "TOPRIGHT", 4, 0) | |
close:SetText(CLOSE) | |
close:SetScript("OnClick", function() | |
self:Hide() | |
end) | |
self.closeButton = close | |
self.SetupFrame = nil | |
self:Show() | |
end | |
------------------------------------------------------------------------ | |
-- Display actions | |
------------------------------------------------------------------------ | |
addon:SetScript("OnShow", function(self) | |
if self.SetupFrame then | |
self:SetupFrame() | |
end | |
self:Update() | |
end) | |
SLASH_BREAKITDOWN1 = "/bid" | |
SlashCmdList.BREAKITDOWN = function() | |
if addon:IsShown() then | |
addon:Hide() | |
else | |
addon:Show() | |
end | |
end | |
------------------------------------------------------------------------ | |
-- Tests | |
------------------------------------------------------------------------ | |
do | |
local items = { | |
-- Herbs | |
{ 52989, 52987, 52988, 52986, 52985, 52984, 85983, 36908, 36906, 36905, 36903, 39970, 37921, 36901, 36907, 36904 }, | |
-- Ore | |
{ 52183, 52184, 52185, 53038, 36910, 36912, 36909 }, | |
-- Disenchant | |
{ 52722, 52721, 52720, 52719, 52718, 52555, 34057, 34052, 34053, 34055, 34056, 34054 }, | |
-- Milling | |
{ 61979, 61980, 39343, 43109 }, | |
-- Prospecting | |
{ 52327, 52179, 52177, 52181, 52182, 52180, 52178, 52192, 52195, 52194, 52193, 52190, 52191, 36923, 36929, 36926, 36917, 36932, 36920, 36930, 36933, 36924, 36921, 36918, 36927, 36931, 36934, 36922, 36925, 36919, 36928, 46849, 24243 }, | |
} | |
function addon:Test(np, ni, clear) | |
self:Hide() | |
if clear then | |
wipe(results) | |
end | |
for i = 1, (np or 2) do | |
local set = items[math.random(#items)] | |
for i = 1, (ni or 5) do | |
local id = set[math.random(#set)] | |
local name, link, _, _, _, _, _, _, _, icon = GetItemInfo(id) | |
if name then | |
local t = results[name] | |
if not t then | |
t = {} | |
results[name] = t | |
end | |
t.color = link:match("|cff(%x%x%x%x%x%x)") | |
t.name = name | |
t.icon = icon | |
t.total = GetItemCount(id) > 0 and GetItemCount(id) or math.random(1, 300) | |
t.link = link | |
end | |
end | |
end | |
self:Show() | |
end | |
end | |
--[[ | |
Example tests: | |
/run BreakItDown:Test() | |
/run BreakItDown:Test(3, 3) | |
/run BreakItDown:Test(nil, nil, true) | |
/run wipe(BreakItDown.results) | |
]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment