local tablet = AceLibrary("Tablet-2.0") local dewdrop = AceLibrary("Dewdrop-2.0") local metro = AceLibrary("Metrognome-2.0") local abacus = AceLibrary("Abacus-2.0") local compost = AceLibrary("Compost-2.0") local L = AceLibrary("AceLocale-2.0"):new("MoneyFu") MoneyFu = AceLibrary("AceAddon-2.0"):new("FuBarPlugin-2.0", "AceDB-2.0", "AceEvent-2.0", "AceHook-2.0", "AceConsole-2.0") MoneyFu.hasIcon = true MoneyFu:RegisterDB("MoneyFuDB", "MoneyFuCharDB") MoneyFu:RegisterDefaults('profile', { style = "GRAPHICAL", trackByRealm = true, simpleTooltip = false }) MoneyFu:RegisterDefaults('char', { spent = {}, gained = {}, time = {} }) MoneyFu:RegisterDefaults('realm', { chars = {}, spent = {}, gained = {}, time = {} }) MoneyFu:RegisterChatCommand(L["COMMANDS"], { desc = L["DESCRIPTION"], type = 'group', args = {}, }) MoneyFu.frame = MoneyFu:CreateBasicPluginFrame("MoneyFuFrame") function MoneyFu:SetStyle(style) style = string.upper(style) if style ~= "GRAPHICAL" and style ~= "FULL" and style ~= "SHORT" and style ~= "CONDENSED" then style = "GRAPHICAL" end self.db.profile.style = style self:UpdateText() end function MoneyFu:ResetSession() self.initialMoney = GetMoney() self.sessionTime = time() self.gained = 0 self.spent = 0 end function MoneyFu:OnInitialize() self.hasIcon = true self.canHideText = true local frame = self.frame local icon = frame:CreateTexture("MoneyFuFrameIcon", "ARTWORK") icon:SetWidth(16) icon:SetHeight(16) icon:SetPoint("LEFT", frame, "LEFT") self.iconFrame = icon local text = frame:CreateFontString("MoneyFuFrameText", "OVERLAY") text:SetJustifyH("RIGHT") text:SetPoint("RIGHT", frame, "RIGHT", 0, 1) text:SetFontObject(GameFontNormal) self.textFrame = text self:SetIcon(true) local goldIcon = frame:CreateTexture("MoneyFuFrameGoldIcon", "ARTWORK") goldIcon:SetWidth(16) goldIcon:SetHeight(16) goldIcon:SetTexture("Interface\\MoneyFrame\\UI-MoneyIcons") goldIcon:SetTexCoord(0, 0.25, 0, 1) local silverIcon = frame:CreateTexture("MoneyFuFrameSilverIcon", "ARTWORK") silverIcon:SetWidth(16) silverIcon:SetHeight(16) silverIcon:SetTexture("Interface\\MoneyFrame\\UI-MoneyIcons") silverIcon:SetTexCoord(0.25, 0.5, 0, 1) local copperIcon = frame:CreateTexture("MoneyFuFrameCopperIcon", "ARTWORK") copperIcon:SetWidth(16) copperIcon:SetHeight(16) copperIcon:SetTexture("Interface\\MoneyFrame\\UI-MoneyIcons") copperIcon:SetTexCoord(0.5, 0.75, 0, 1) local goldText = frame:CreateFontString("MoneyFuFrameGoldText", "OVERLAY") goldText:SetJustifyH("RIGHT") goldText:SetPoint("RIGHT", goldIcon, "LEFT", 0, 1) goldText:SetFontObject(GameFontNormal) local silverText = frame:CreateFontString("MoneyFuFrameSilverText", "OVERLAY") silverText:SetJustifyH("RIGHT") silverText:SetPoint("RIGHT", silverIcon, "LEFT", 0, 1) silverText:SetFontObject(GameFontNormal) local copperText = frame:CreateFontString("MoneyFuFrameCopperText", "OVERLAY") copperText:SetJustifyH("RIGHT") copperText:SetPoint("RIGHT", copperIcon, "LEFT", 0, 1) copperText:SetFontObject(GameFontNormal) copperIcon:SetPoint("RIGHT", frame, "RIGHT") silverIcon:SetPoint("RIGHT", copperText, "LEFT") goldIcon:SetPoint("RIGHT", silverText, "LEFT") end local function GetToday(self) return floor((time() / 60 / 60 + self:GetServerOffset()) / 24) end function MoneyFu:OnEnable() self.initialMoney = GetMoney() self.lastMoney = self.initialMoney self.lastTime = GetToday(self) local lastWeek = self.lastTime - 6 for day in pairs(self.db.char.gained) do if day < lastWeek then self.db.char.gained[day] = nil end end for day in pairs(self.db.char.spent) do if day < lastWeek then self.db.char.spent[day] = nil end end for day in pairs(self.db.char.time) do if day < lastWeek then self.db.char.time[day] = nil end end for day in pairs(self.db.realm.gained) do if day < lastWeek then self.db.realm.gained[day] = nil end end for day in pairs(self.db.realm.spent) do if day < lastWeek then self.db.realm.spent[day] = nil end end for day in pairs(self.db.realm.time) do if day < lastWeek then self.db.realm.time[day] = nil end end for i = self.lastTime - 6, self.lastTime do if not self.db.char.gained[i] then self.db.char.gained[i] = 0 end if not self.db.char.spent[i] then self.db.char.spent[i] = 0 end if not self.db.char.time[i] then self.db.char.time[i] = 0 end if not self.db.realm.gained[i] then self.db.realm.gained[i] = 0 end if not self.db.realm.spent[i] then self.db.realm.spent[i] = 0 end if not self.db.realm.time[i] then self.db.realm.time[i] = 0 end end self.gained = 0 self.spent = 0 self.sessionTime = time() self.savedTime = time() if self.db.profile.style == "GRAPHICAL" then self:HideIcon() self.iconFrame:Hide() self.hasIcon = false end self:RegisterEvent("PLAYER_MONEY", "Update") self:RegisterEvent("PLAYER_TRADE_MONEY", "Update") self:RegisterEvent("TRADE_MONEY_CHANGED", "Update") self:RegisterEvent("SEND_MAIL_MONEY_CHANGED", "Update") self:RegisterEvent("SEND_MAIL_COD_CHANGED", "Update") self:Hook("OpenCoinPickupFrame") MoneyFuFrameGoldIcon:ClearAllPoints() MoneyFuFrameGoldIcon:SetPoint("RIGHT", MoneyFuFrameSilverText, "LEFT", 0, -1) MoneyFuFrameSilverIcon:ClearAllPoints() MoneyFuFrameSilverIcon:SetPoint("RIGHT", MoneyFuFrameCopperText, "LEFT", 0, -1) metro:RegisterMetro(self.name, self.UpdateTooltip, 1, self) metro:StartMetro(self.name) end function MoneyFu:OnDisable() metro:UnregisterMetro(self.name) end function MoneyFu:OnMenuRequest(level, value) if level == 1 then dewdrop:AddLine( 'text', L["MENU_RESET_SESSION"], 'arg1', self, 'func', "ResetSession", 'closeWhenClicked', true ) dewdrop:AddLine( 'text', L["MENU_CHARACTER_SPECIFIC_CASHFLOW"], 'arg1', self, 'func', function() self.db.profile.trackByRealm = not self.db.profile.trackByRealm self:UpdateTooltip() end, 'checked', not self.db.profile.trackByRealm ) dewdrop:AddLine() dewdrop:AddLine( 'text', L["MENU_SHOW_GRAPHICAL"], 'arg1', self, 'func', self.db.profile.style ~= "GRAPHICAL" and "SetStyle", 'arg2', "GRAPHICAL", 'checked', self.db.profile.style == "GRAPHICAL", 'isRadio', true ) dewdrop:AddLine( 'text', L["MENU_SHOW_FULL"], 'arg1', self, 'func', self.db.profile.style ~= "FULL" and "SetStyle", 'arg2', "FULL", 'checked', self.db.profile.style == "FULL", 'isRadio', true ) dewdrop:AddLine( 'text', L["MENU_SHOW_SHORT"], 'arg1', self, 'func', self.db.profile.style ~= "SHORT" and "SetStyle", 'arg2', "SHORT", 'checked', self.db.profile.style == "SHORT", 'isRadio', true ) dewdrop:AddLine( 'text', L["MENU_SHOW_CONDENSED"], 'arg1', self, 'func', self.db.profile.style ~= "CONDENSED" and "SetStyle", 'arg2', "CONDENSED", 'checked', self.db.profile.style == "CONDENSED", 'isRadio', true ) dewdrop:AddLine( 'text', L["SIMPLIFIED_TOOLTIP"], 'arg1', self, 'func', function() self.db.profile.simpleTooltip = not self.db.profile.simpleTooltip self:Update() end, 'checked', self.db.profile.simpleTooltip ) if next(self.db.realm.chars) ~= UnitName("player") or next(self.db.realm.chars, UnitName("player")) then dewdrop:AddLine() dewdrop:AddLine( 'text', L["MENU_PURGE"], 'hasArrow', true, 'value', "purge" ) end elseif level == 2 then if value == "purge" then for name in self.db.realm.chars do if name ~= UnitName("player") then dewdrop:AddLine( 'text', name, 'arg1', name, 'func', function(name) self.db.realm.chars[name] = nil end, 'closeWhenClicked', true ) end end end end end function MoneyFu:UpdateData() local today = GetToday(self) if not self.lastTime then self.lastTime = today end if today > self.lastTime then self.db.char.gained[today - 7] = nil self.db.char.spent[today - 7] = nil self.db.char.time[today - 7] = nil self.db.realm.gained[today - 7] = nil self.db.realm.spent[today - 7] = nil self.db.realm.time[today - 7] = nil self.db.char.gained[today] = self.db.char.gained[today] or 0 self.db.char.spent[today] = self.db.char.spent[today] or 0 self.db.char.time[today] = self.db.char.time[today] or 0 self.db.realm.gained[today] = self.db.realm.gained[today] or 0 self.db.realm.spent[today] = self.db.realm.spent[today] or 0 self.db.realm.time[today] = self.db.realm.time[today] or 0 self.lastTime = today end local current = GetMoney() if not self.lastMoney then self.lastMoney = current end if self.lastMoney < current then self.gained = (self.gained or 0) + current - self.lastMoney self.db.char.gained[today] = (self.db.char.gained[today] or 0) + current - self.lastMoney self.db.realm.gained[today] = (self.db.realm.gained[today] or 0) + current - self.lastMoney elseif self.lastMoney > current then self.spent = (self.spent or 0) + self.lastMoney - current self.db.char.spent[today] = (self.db.char.spent[today] or 0) + self.lastMoney - current self.db.realm.spent[today] = (self.db.realm.spent[today] or 0) + self.lastMoney - current end self.lastMoney = current self.db.realm.chars[UnitName("player")] = current local now = time() self.db.char.time[today] = self.db.char.time[today] + now - self.savedTime self.db.realm.time[today] = self.db.realm.time[today] + now - self.savedTime self.savedTime = now end function MoneyFu:UpdateText() if self.db.profile == nil then return end if self.db.profile.style == "GRAPHICAL" then if self:IsIconShown() then self.db.profile.iconVisible = true self:HideIcon() end self.hasIcon = false MoneyFuFrameIcon:Hide() MoneyFuFrameText:Hide() local copper = GetMoney() local gold = floor(copper / 10000) local silver = mod(floor(copper / 100), 100) copper = mod(copper, 100) local width = 0 if gold == 0 then MoneyFuFrameGoldIcon:Hide() MoneyFuFrameGoldText:Hide() else MoneyFuFrameGoldIcon:Show() MoneyFuFrameGoldText:Show() MoneyFuFrameGoldText:SetWidth(0) MoneyFuFrameGoldText:SetText(gold) width = width + MoneyFuFrameGoldIcon:GetWidth() + MoneyFuFrameGoldText:GetWidth() end if gold == 0 and silver == 0 then MoneyFuFrameSilverIcon:Hide() MoneyFuFrameSilverText:Hide() else MoneyFuFrameSilverIcon:Show() MoneyFuFrameSilverText:Show() MoneyFuFrameSilverText:SetWidth(0) MoneyFuFrameSilverText:SetText(silver) width = width + MoneyFuFrameSilverIcon:GetWidth() + MoneyFuFrameSilverText:GetWidth() end MoneyFuFrameCopperIcon:Show() MoneyFuFrameCopperText:Show() MoneyFuFrameCopperText:SetWidth(0) MoneyFuFrameCopperText:SetText(copper) width = width + MoneyFuFrameCopperIcon:GetWidth() + MoneyFuFrameCopperText:GetWidth() self.frame:SetWidth(width) else if not self.hasIcon then self.hasIcon = true if self.db.profile.iconVisible then self:ShowIcon() end end self.db.profile.iconVisible = false MoneyFuFrameGoldIcon:Hide() MoneyFuFrameSilverIcon:Hide() MoneyFuFrameCopperIcon:Hide() MoneyFuFrameGoldText:Hide() MoneyFuFrameSilverText:Hide() MoneyFuFrameCopperText:Hide() MoneyFuFrameText:Show() if self.db.profile.style == "CONDENSED" then self:SetText(abacus:FormatMoneyCondensed(GetMoney(), true)) elseif self.db.profile.style == "FULL" then self:SetText(abacus:FormatMoneyFull(GetMoney(), true)) else self:SetText(abacus:FormatMoneyShort(GetMoney(), true)) end self:CheckWidth(true) end end function MoneyFu:OnTooltipUpdate() local now = time() local today = self.lastTime self.db.char.time[today] = self.db.char.time[today] + now - self.savedTime self.db.realm.time[today] = self.db.realm.time[today] + now - self.savedTime self.savedTime = now local func if self.db.profile.style == "CONDENSED" then func = abacus.FormatMoneyCondensed elseif self.db.profile.style == "SHORT" then func = abacus.FormatMoneyShort else func = abacus.FormatMoneyFull end local supercat = tablet:AddCategory( 'columns', 3, 'child_text2', L["TEXT_AMOUNT"], 'child_text3', L["TEXT_PER_HOUR"], 'child_child_textR', 1, 'child_child_textG', 1, 'child_child_textB', 0, 'child_child_text2R', 1, 'child_child_text2G', 1, 'child_child_text2B', 1, 'child_child_text3R', 1, 'child_child_text3G', 1, 'child_child_text3B', 1 ) ------------ if not self.db.profile.simpleTooltip then local cat = supercat:AddCategory( 'text', L["TEXT_THIS_SESSION"] ) cat:AddLine( 'text', L["TEXT_GAINED"], 'text2', func(abacus, self.gained, true), 'text3', func(abacus, self.gained / (now - self.sessionTime) * 3600, true) ) cat:AddLine( 'text', L["TEXT_SPENT"], 'text2', func(abacus, self.spent, true), 'text3', func(abacus, self.spent / (now - self.sessionTime) * 3600, true) ) local profit = self.gained - self.spent cat:AddLine( 'text', profit >= 0 and L["TEXT_PROFIT"] or L["TEXT_LOSS"], 'text2', func(abacus, profit, true, true), 'text3', func(abacus, profit / (now - self.sessionTime) * 3600, true, true) ) local t if self.db.profile.trackByRealm then t = self.db.realm else t = self.db.char end local gained = t.gained local spent = t.spent local time = t.time -- ------------ -- Session totals -- ------------ cat = supercat:AddCategory( 'text', HONOR_THIS_SESSION ) cat:AddLine( 'text', L["TEXT_GAINED"], 'text2', func(abacus, gained[self.lastTime], true), 'text3', func(abacus, gained[self.lastTime] / time[self.lastTime] * 3600, true) ) cat:AddLine( 'text', L["TEXT_SPENT"], 'text2', func(abacus, spent[self.lastTime], true), 'text3', func(abacus, spent[self.lastTime] / time[self.lastTime] * 3600, true) ) local profit = gained[self.lastTime] - spent[self.lastTime] cat:AddLine( 'text', profit >= 0 and L["TEXT_PROFIT"] or L["TEXT_LOSS"], 'text2', func(abacus, profit, true, true), 'text3', func(abacus, profit / time[self.lastTime] * 3600, true, true) ) -- ----------- -- Yesterday totals -- ----------- cat = supercat:AddCategory( 'text', HONOR_YESTERDAY ) cat:AddLine( 'text', L["TEXT_GAINED"], 'text2', func(abacus, gained[self.lastTime - 1], true), 'text3', func(abacus, gained[self.lastTime - 1] / time[self.lastTime - 1] * 3600, true) ) cat:AddLine( 'text', L["TEXT_SPENT"], 'text2', func(abacus, spent[self.lastTime - 1], true), 'text3', func(abacus, spent[self.lastTime - 1] / time[self.lastTime - 1] * 3600, true) ) local profit = gained[self.lastTime - 1] - spent[self.lastTime - 1] cat:AddLine( 'text', profit >= 0 and L["TEXT_PROFIT"] or L["TEXT_LOSS"], 'text2', func(abacus, profit, true, true), 'text3', func(abacus, profit / time[self.lastTime - 1] * 3600, true, true) ) -- ----------- -- Week totals -- ----------- local weekGained = 0 local weekSpent = 0 local weekTime = 0 for i = self.lastTime - 6, self.lastTime do weekGained = weekGained + gained[i] weekSpent = weekSpent + spent[i] weekTime = weekTime + time[i] end cat = supercat:AddCategory( 'text', HONOR_THISWEEK ) cat:AddLine( 'text', L["TEXT_GAINED"], 'text2', func(abacus, weekGained, true), 'text3', func(abacus, weekGained / weekTime * 3600, true) ) cat:AddLine( 'text', L["TEXT_SPENT"], 'text2', func(abacus, weekSpent, true), 'text3', func(abacus, weekSpent / weekTime * 3600, true) ) local profit = weekGained - weekSpent cat:AddLine( 'text', profit >= 0 and L["TEXT_PROFIT"] or L["TEXT_LOSS"], 'text2', func(abacus, profit, true, true), 'text3', func(abacus, profit / weekTime * 3600, true, true) ) end -- ------------- -- Character Totals, we always show this bit. -- ------------- local total = 0 local addedCat = false if next(self.db.realm.chars) ~= UnitName("player") or next(self.db.realm.chars, UnitName("player")) then local t = compost:Acquire() for name in pairs(self.db.realm.chars) do table.insert(t, name) end if not self.sort_func then self.sort_func = function(alpha, bravo) return self.db.realm.chars[alpha] < self.db.realm.chars[bravo] end end table.sort(t, self.sort_func) cat = tablet:AddCategory( 'columns', 2, 'text', L["TEXT_CHARACTERS"], 'text2', "Amount", 'child_textR', 1, 'child_textG', 1, 'child_textB', 0, 'child_text2R', 1, 'child_text2G', 1, 'child_text2B', 1 ) for _,name in t do local value = self.db.realm.chars[name] cat:AddLine( 'text', name, 'text2', func(abacus, value, true) ) total = total + value end else total = self.db.realm.chars[UnitName("player")] end cat = tablet:AddCategory( 'columns', 2, 'child_textR', 1, 'child_textG', 1, 'child_textB', 1, 'child_text2R', 1, 'child_text2G', 1, 'child_text2B', 1 ) cat:AddLine( 'text', L["TEXT_TOTAL"], 'text2', func(abacus, total, true) ) tablet:SetHint(L["HINT"]) end local function getsecond(_, value) return value end function MoneyFu:OnClick(button) local money = GetMoney() if money < 100 then money = 1 elseif money < 10000 then money = 100 else money = 10000 end self.frame.moneyType = "PLAYER" OpenCoinPickupFrame(money, GetMoney(), self.frame) self.frame.hasPickup = 1 CoinPickupFrame:ClearAllPoints() local frame = self.frame if self:IsMinimapAttached() then frame = self.minimapFrame end if frame:GetCenter() < GetScreenWidth()/2 then if getsecond(frame:GetCenter()) < GetScreenHeight()/2 then CoinPickupFrame:SetPoint("BOTTOMLEFT", frame, "TOPLEFT") else CoinPickupFrame:SetPoint("TOPLEFT", frame, "BOTTOMLEFT") end else if getsecond(frame:GetCenter()) < GetScreenHeight()/2 then CoinPickupFrame:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT") else CoinPickupFrame:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT") end end end function MoneyFu:OpenCoinPickupFrame(multiplier, maxMoney, parent) CoinPickupFrame:ClearAllPoints() self.hooks.OpenCoinPickupFrame.orig(multiplier, maxMoney, parent) end function MoneyFu:SetFontSize(size) if MoneyFuFrameGoldIcon == nil then self.fontSize = size return end MoneyFuFrameGoldIcon:SetWidth(size) MoneyFuFrameGoldIcon:SetHeight(size) MoneyFuFrameSilverIcon:SetWidth(size) MoneyFuFrameSilverIcon:SetHeight(size) MoneyFuFrameCopperIcon:SetWidth(size) MoneyFuFrameCopperIcon:SetHeight(size) self.iconFrame:SetWidth(size) self.iconFrame:SetHeight(size) local font,_,flags = MoneyFuFrameGoldText:GetFont() if font ~= nil then MoneyFuFrameGoldText:SetFont(font, size, flags) MoneyFuFrameSilverText:SetFont(font, size, flags) MoneyFuFrameCopperText:SetFont(font, size, flags) self.textFrame:SetFont(font, size) end self:UpdateText() end local offset function MoneyFu:GetServerOffset() if offset then return offset end local serverHour, serverMinute = GetGameTime() local utcHour = tonumber(date("!%H")) local utcMinute = tonumber(date("!%M")) local ser = serverHour + serverMinute / 60 local utc = utcHour + utcMinute / 60 offset = floor((ser - utc) * 2 + 0.5) / 2 if offset >= 12 then offset = offset - 24 elseif offset < -12 then offset = offset + 24 end return offset end