diff --git a/.pkgmeta b/.pkgmeta
index 7ac6d6f..fac3c0f 100644
--- a/.pkgmeta
+++ b/.pkgmeta
@@ -10,6 +10,7 @@ externals:
Libs/AceHook-3.0: https://repos.wowace.com/wow/ace3/trunk/AceHook-3.0
Libs/AceTimer-3.0: https://repos.wowace.com/wow/ace3/trunk/AceTimer-3.0
Libs/AceLocale-3.0: https://repos.wowace.com/wow/ace3/trunk/AceLocale-3.0
+ Libs/AceBucket-3.0: https://repos.wowace.com/wow/ace3/trunk/AceBucket-3.0
enable-nolib-creation: yes
diff --git a/.scripts/hardcode_string_check.py b/.scripts/hardcode_string_check.py
index cf0f6fb..a34cd46 100644
--- a/.scripts/hardcode_string_check.py
+++ b/.scripts/hardcode_string_check.py
@@ -4,6 +4,8 @@
# Function to check if a file or directory should be ignored
def should_ignore(path, ignore_files, ignore_dirs):
+ if os.path.basename(path) in ignore_dirs:
+ return True
for dir in ignore_dirs:
if path.startswith(f"./{dir}/"):
return True
@@ -65,8 +67,19 @@ def scan_directory(directory, ignore_files=None, ignore_dirs=None):
def main():
- ignore_files = ["TestMode.lua"]
- ignore_dirs = [".git", ".scripts", ".release", "locale"]
+ ignore_files = []
+ ignore_dirs = [
+ ".git",
+ ".github",
+ ".release",
+ ".scripts",
+ ".trunk",
+ ".venv",
+ "Icons",
+ "locale",
+ "luacov-html",
+ "spec",
+ ]
# Scan the current directory
issues = scan_directory(".", ignore_files, ignore_dirs)
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index 3121128..cdcbb9c 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -21,6 +21,9 @@ lint:
- linters: [stylua]
paths:
- locale/**
+ - linters: [no-invalid-prints]
+ paths:
+ - spec/**
enabled:
- stylua@0.20.0
- actionlint@1.7.1
diff --git a/AddonScope.lua b/AddonScope.lua
index dcee3cc..3d77bc1 100644
--- a/AddonScope.lua
+++ b/AddonScope.lua
@@ -3,8 +3,52 @@ G_RLF = {}
local addonName = "RPGLootFeed"
local dbName = addonName .. "DB"
local localeName = addonName .. "Locale"
+
+local xpcall = xpcall
+
+local function errorhandler(err)
+ local suffix = "\n\n==== Addon Info " .. G_RLF.addonName .. " " .. G_RLF.addonVersion .. " ====\n\n"
+ suffix = suffix .. G_RLF.L["Issues"] .. "\n\n"
+
+ return geterrorhandler()(err .. suffix)
+end
+
+function G_RLF:fn(func, ...)
+ -- Borrowed from AceAddon-3.0
+ if type(func) == "function" then
+ return xpcall(func, errorhandler, ...)
+ end
+end
+
G_RLF.RLF = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0", "AceTimer-3.0")
G_RLF.RLF:SetDefaultModuleState(true)
+G_RLF.RLF:SetDefaultModulePrototype({
+ getLogger = function(self)
+ return G_RLF.RLF:GetModule("Logger")
+ end,
+ fn = function(s, func, ...)
+ local function errorhandler(err)
+ local suffix = "\n\n==== Addon Info " .. G_RLF.addonName .. " " .. G_RLF.addonVersion .. " ====\n\n"
+ local status, trace = pcall(function()
+ return s:getLogger():Trace(s.moduleName)
+ end)
+ if status then
+ suffix = suffix .. "Log traces related to " .. s.moduleName .. "\n"
+ suffix = suffix .. "-------------------------------------------------\n"
+ suffix = suffix .. trace
+ suffix = suffix .. "-------------------------------------------------\n\n"
+ end
+ suffix = suffix .. G_RLF.L["Issues"] .. "\n\n"
+
+ return geterrorhandler()(err .. suffix)
+ end
+
+ -- Borrowed from AceAddon-3.0
+ if type(func) == "function" then
+ return xpcall(func, errorhandler, ...)
+ end
+ end,
+})
G_RLF.addonName = addonName
G_RLF.dbName = dbName
G_RLF.localeName = localeName
@@ -20,19 +64,3 @@ G_RLF.DisableBossBanner = {
function G_RLF:Print(...)
G_RLF.RLF:Print(...)
end
-
-local xpcall = xpcall
-
-local function errorhandler(err)
- local suffix = "\n\n==== Addon Info " .. G_RLF.addonName .. " " .. G_RLF.addonVersion .. " ====\n\n"
- suffix = suffix .. G_RLF.L["Issues"] .. "\n\n"
-
- return geterrorhandler()(err .. suffix)
-end
-
-function G_RLF:fn(func, ...)
- -- Borrowed from AceAddon-3.0
- if type(func) == "function" then
- return xpcall(func, errorhandler, ...)
- end
-end
diff --git a/Features/Currency.lua b/Features/Currency.lua
index d400de5..12dabf1 100644
--- a/Features/Currency.lua
+++ b/Features/Currency.lua
@@ -1,5 +1,11 @@
local Currency = G_RLF.RLF:NewModule("Currency", "AceEvent-3.0")
+local hiddenCurrencies
+
+local function isHiddenCurrency(id)
+ return hiddenCurrencies[id] == true
+end
+
function Currency:OnInitialize()
if G_RLF.db.global.currencyFeed then
self:Enable()
@@ -16,20 +22,51 @@ function Currency:OnEnable()
self:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
end
-function Currency:CURRENCY_DISPLAY_UPDATE(_, ...)
+function Currency:CURRENCY_DISPLAY_UPDATE(eventName, ...)
local currencyType, _quantity, quantityChange, _quantityGainSource, _quantityLostSource = ...
+ self:getLogger():Info(eventName, "WOWEVENT", self.moduleName, currencyType, eventName, quantityChange)
+
if currencyType == nil or not quantityChange or quantityChange <= 0 then
+ self:getLogger():Debug(
+ "Skip showing currency",
+ G_RLF.addonName,
+ self.moduleName,
+ currencyType,
+ "SKIP: Something was missing, don't display",
+ quantityChange
+ )
+ return
+ end
+
+ if isHiddenCurrency(currencyType) then
+ self:getLogger():Debug(
+ "Skip showing currency",
+ G_RLF.addonName,
+ self.moduleName,
+ currencyType,
+ "SKIP: This is a known hidden currencyType",
+ quantityChange
+ )
return
end
local info = C_CurrencyInfo.GetCurrencyInfo(currencyType)
if info == nil or info.description == "" or info.iconFileID == nil then
+ self:getLogger():Debug(
+ "Skip showing currency",
+ G_RLF.addonName,
+ self.moduleName,
+ currencyType,
+ "SKIP: Description or icon was empty",
+ quantityChange
+ )
return
end
- G_RLF:fn(function()
+ self:fn(function()
G_RLF.LootDisplay:ShowLoot(
+ self.moduleName,
info.currencyID,
C_CurrencyInfo.GetCurrencyLink(currencyType),
info.iconFileID,
@@ -38,4 +75,316 @@ function Currency:CURRENCY_DISPLAY_UPDATE(_, ...)
end)
end
+hiddenCurrencies = {
+ [2918] = true,
+ [2919] = true,
+ [2899] = true,
+ [2793] = true,
+ [2902] = true,
+ [2897] = true,
+ [3045] = true,
+ [2912] = true,
+ [1822] = true,
+ [3066] = true,
+ [3040] = true,
+ [2785] = true,
+ [1810] = true,
+ [3002] = true,
+ [2795] = true,
+ [3041] = true,
+ [2901] = true,
+ [1191] = true,
+ [3054] = true,
+ [3068] = true,
+ [2034] = true,
+ [2789] = true,
+ [3003] = true,
+ [3050] = true,
+ [2035] = true,
+ [3004] = true,
+ [2813] = true,
+ [2786] = true,
+ [2026] = true,
+ [2792] = true,
+ [1728] = true,
+ [3051] = true,
+ [3047] = true,
+ [2794] = true,
+ [3052] = true,
+ [2787] = true,
+ [2033] = true,
+ [2024] = true,
+ [2788] = true,
+ [2900] = true,
+ [2023] = true,
+ [3065] = true,
+ [3057] = true,
+ [1889] = true,
+ [3086] = true,
+ [2791] = true,
+ [3071] = true,
+ [2029] = true,
+ [3042] = true,
+ [3046] = true,
+ [2898] = true,
+ [3059] = true,
+ [3061] = true,
+ [3048] = true,
+ [2027] = true,
+ [2167] = true,
+ [1744] = true,
+ [2706] = true,
+ [2030] = true,
+ [3064] = true,
+ [3067] = true,
+ [2790] = true,
+ [3058] = true,
+ [3043] = true,
+ [1703] = true,
+ [2709] = true,
+ [3063] = true,
+ [2025] = true,
+ [2921] = true,
+ [2904] = true,
+ [2903] = true,
+ [2533] = true,
+ [2166] = true,
+ [3070] = true,
+ [3049] = true,
+ [1171] = true,
+ [1877] = true,
+ [2715] = true,
+ [2796] = true,
+ [3069] = true,
+ [3060] = true,
+ [3075] = true,
+ [3013] = true,
+ [2814] = true,
+ [2707] = true,
+ [2267] = true,
+ [2153] = true,
+ [2805] = true,
+ [3074] = true,
+ [2920] = true,
+ [2652] = true,
+ [2819] = true,
+ [2106] = true,
+ [3023] = true,
+ [3073] = true,
+ [3083] = true,
+ [2922] = true,
+ [3053] = true,
+ [2808] = true,
+ [2649] = true,
+ [2028] = true,
+ [3044] = true,
+ [1891] = true,
+ [1907] = true,
+ [2171] = true,
+ [1579] = true,
+ [3062] = true,
+ [1838] = true,
+ [1559] = true,
+ [2109] = true,
+ [1747] = true,
+ [1982] = true,
+ [3077] = true,
+ [3079] = true,
+ [2000] = true,
+ [1745] = true,
+ [2031] = true,
+ [2410] = true,
+ [2036] = true,
+ [3080] = true,
+ [1757] = true,
+ [1880] = true,
+ [3085] = true,
+ [3099] = true,
+ [2408] = true,
+ [1325] = true,
+ [3005] = true,
+ [2169] = true,
+ [3009] = true,
+ [1878] = true,
+ [3010] = true,
+ [1593] = true,
+ [2278] = true,
+ [2866] = true,
+ [1807] = true,
+ [2908] = true,
+ [2874] = true,
+ [2420] = true,
+ [2172] = true,
+ [2645] = true,
+ [2149] = true,
+ [3094] = true,
+ [3076] = true,
+ [2710] = true,
+ [1750] = true,
+ [2413] = true,
+ [2419] = true,
+ [2780] = true,
+ [2810] = true,
+ [2151] = true,
+ [2152] = true,
+ [2708] = true,
+ [1347] = true,
+ [2910] = true,
+ [1501] = true,
+ [1752] = true,
+ [2170] = true,
+ [1540] = true,
+ [1722] = true,
+ [2021] = true,
+ [2094] = true,
+ [1541] = true,
+ [1804] = true,
+ [3088] = true,
+ [2402] = true,
+ [1746] = true,
+ [3103] = true,
+ [1598] = true,
+ [3115] = true,
+ [1837] = true,
+ [2087] = true,
+ [2002] = true,
+ [2784] = true,
+ [2653] = true,
+ [1594] = true,
+ [2150] = true,
+ [2906] = true,
+ [2409] = true,
+ [2165] = true,
+ [2872] = true,
+ [2858] = true,
+ [2088] = true,
+ [2862] = true,
+ [2173] = true,
+ [2108] = true,
+ [2175] = true,
+ [2244] = true,
+ [1595] = true,
+ [1805] = true,
+ [1324] = true,
+ [2856] = true,
+ [2873] = true,
+ [2909] = true,
+ [2717] = true,
+ [3081] = true,
+ [2861] = true,
+ [1842] = true,
+ [1884] = true,
+ [2275] = true,
+ [1592] = true,
+ [2277] = true,
+ [1794] = true,
+ [2148] = true,
+ [3000] = true,
+ [1596] = true,
+ [1806] = true,
+ [1848] = true,
+ [1903] = true,
+ [1597] = true,
+ [2266] = true,
+ [1808] = true,
+ [2871] = true,
+ [1748] = true,
+ [2268] = true,
+ [1852] = true,
+ [3078] = true,
+ [1997] = true,
+ [2716] = true,
+ [3007] = true,
+ [2911] = true,
+ [1506] = true,
+ [1714] = true,
+ [2876] = true,
+ [2878] = true,
+ [2913] = true,
+ [3082] = true,
+ [3084] = true,
+ [1738] = true,
+ [1769] = true,
+ [2231] = true,
+ [1742] = true,
+ [3026] = true,
+ [1847] = true,
+ [3001] = true,
+ [3027] = true,
+ [2854] = true,
+ [2907] = true,
+ [1599] = true,
+ [1349] = true,
+ [1600] = true,
+ [2269] = true,
+ [2411] = true,
+ [3006] = true,
+ [1853] = true,
+ [2270] = true,
+ [2412] = true,
+ [2271] = true,
+ [2859] = true,
+ [1840] = true,
+ [2800] = true,
+ [3011] = true,
+ [1883] = true,
+ [2107] = true,
+ [2865] = true,
+ [3025] = true,
+ [3087] = true,
+ [2279] = true,
+ [2867] = true,
+ [2264] = true,
+ [2280] = true,
+ [2265] = true,
+ [2869] = true,
+ [1849] = true,
+ [1850] = true,
+ [1749] = true,
+ [2857] = true,
+ [1350] = true,
+ [1705] = true,
+ [2875] = true,
+ [2272] = true,
+ [2718] = true,
+ [2860] = true,
+ [1758] = true,
+ [2273] = true,
+ [2774] = true,
+ [1723] = true,
+ [1841] = true,
+ [2274] = true,
+ [1762] = true,
+ [3022] = true,
+ [1887] = true,
+ [2276] = true,
+ [2864] = true,
+ [1888] = true,
+ [2811] = true,
+ [1740] = true,
+ [1845] = true,
+ [1846] = true,
+ [1902] = true,
+ [2868] = true,
+ [2853] = true,
+ [2870] = true,
+ [1947] = true,
+ [2855] = true,
+ [3104] = true,
+ [1851] = true,
+ [1986] = true,
+ [1839] = true,
+ [1761] = true,
+ [2863] = true,
+ [1763] = true,
+ [1843] = true,
+ [2174] = true,
+ [1739] = true,
+ [1844] = true,
+ [3024] = true,
+ [2655] = true,
+ [3072] = true,
+ [2799] = true,
+}
+
return Currency
diff --git a/Features/Experience.lua b/Features/Experience.lua
index effe96b..24e15d4 100644
--- a/Features/Experience.lua
+++ b/Features/Experience.lua
@@ -24,21 +24,24 @@ function Xp:OnEnable()
self:RegisterEvent("PLAYER_ENTERING_WORLD")
self:RegisterEvent("PLAYER_XP_UPDATE")
if currentXP == nil then
- G_RLF:fn(initXpValues)
+ self:fn(initXpValues)
end
end
-function Xp:PLAYER_ENTERING_WORLD()
- G_RLF:fn(initXpValues)
+function Xp:PLAYER_ENTERING_WORLD(eventName)
+ self:getLogger():Info(eventName, "WOWEVENT", self.moduleName)
+ self:fn(initXpValues)
end
-function Xp:PLAYER_XP_UPDATE(_, unitTarget)
- G_RLF:fn(function()
+function Xp:PLAYER_XP_UPDATE(eventName, unitTarget)
+ self:getLogger():Info(eventName, "WOWEVENT", self.moduleName, unitTarget)
+ self:fn(function()
if unitTarget == "player" then
local newLevel = UnitLevel(unitTarget)
local newCurrentXP = UnitXP(unitTarget)
local delta = 0
if newLevel == nil then
+ self:getLogger():Warn("Could not get player level", G_RLF.addonName, self.moduleName)
return
end
currentLevel = currentLevel or newLevel
@@ -51,7 +54,10 @@ function Xp:PLAYER_XP_UPDATE(_, unitTarget)
currentLevel = newLevel
currentMaxXP = UnitXPMax(unitTarget)
if delta > 0 then
- G_RLF.LootDisplay:ShowXP(delta)
+ G_RLF.LootDisplay:ShowLoot(self.moduleName, delta)
+ else
+ self:getLogger()
+ :Warn(eventName .. " fired but delta was not positive", G_RLF.addonName, self.moduleName)
end
end
end)
diff --git a/Features/ItemLoot.lua b/Features/ItemLoot.lua
index 143d571..2d4fa84 100644
--- a/Features/ItemLoot.lua
+++ b/Features/ItemLoot.lua
@@ -23,6 +23,7 @@ local ItemLoot = G_RLF.RLF:NewModule("ItemLoot", "AceEvent-3.0")
-- ["INVTYPE_RANGEDRIGHT"] = INVSLOT_RANGED, -- Ranged weapons
-- }
+local logger
function ItemLoot:OnInitialize()
if G_RLF.db.global.itemLootFeed then
self:Enable()
@@ -40,10 +41,11 @@ function ItemLoot:OnEnable()
end
local function showItemLoot(msg, itemLink)
- local amount = msg:match("r ?x(%d+)") or 1
+ local amount = tonumber(msg:match("r ?x(%d+)") or 1)
local _, _, itemQuality, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, sellPrice, classID, subclassID, bindType, expansionID, setID, isCraftingReagent =
C_Item.GetItemInfo(itemLink)
if not G_RLF.db.global.itemQualityFilter[itemQuality] then
+ self:getLogger():Debug("Item Ignored by quality", G_RLF.addonName, "ItemLoot", "", msg, amount)
return
end
local itemId = itemLink:match("Hitem:(%d+)")
@@ -59,24 +61,28 @@ local function showItemLoot(msg, itemLink)
-- end
-- end
- G_RLF.LootDisplay:ShowLoot(itemId, itemLink, itemTexture, amount)
+ G_RLF.LootDisplay:ShowLoot("ItemLoot", itemId, itemLink, itemTexture, amount)
end
-function ItemLoot:CHAT_MSG_LOOT(_, ...)
+function ItemLoot:CHAT_MSG_LOOT(eventName, ...)
local msg, _, _, _, _, _, _, _, _, _, _, guid = ...
local raidLoot = msg:match("HlootHistory:")
+ self:getLogger():Info(eventName, "WOWEVENT", self.moduleName, nil, eventName .. " " .. msg)
if raidLoot then
-- Ignore this message as it's a raid loot message
+ self:getLogger():Debug("Raid Loot Ignored", "WOWEVENT", self.moduleName, "", msg)
return
end
local me = guid == GetPlayerGuid()
if not me then
+ self:getLogger():Debug("Group Member Loot Ignored", "WOWEVENT", self.moduleName, "", msg)
return
end
+
local itemLink = msg:match("|c%x+|Hitem:.-|h%[.-%]|h|r")
if itemLink then
- G_RLF:fn(showItemLoot, msg, itemLink)
+ self:fn(showItemLoot, msg, itemLink)
end
end
diff --git a/Features/Money.lua b/Features/Money.lua
index a13cf72..cc818cb 100644
--- a/Features/Money.lua
+++ b/Features/Money.lua
@@ -1,6 +1,5 @@
local Money = G_RLF.RLF:NewModule("Money", "AceEvent-3.0")
-local oldMethod
local startingMoney
function Money:OnInitialize()
@@ -12,55 +11,22 @@ function Money:OnInitialize()
end
function Money:OnDisable()
- self:UnregisterEvent("LOOT_READY")
- self:UnregisterEvent("CHAT_MSG_MONEY")
+ self:UnregisterEvent("PLAYER_MONEY")
end
function Money:OnEnable()
- self:RegisterEvent("LOOT_READY")
- self:RegisterEvent("CHAT_MSG_MONEY")
-end
-
-function Money:LOOT_READY()
- -- Get current money to calculate the delta later
- startingMoney = GetMoney()
-end
-
-local function showMoneyLoot(msg)
- local amountInCopper
- if startingMoney == nil then
- -- Old method that doesn't work well with locales that are missing translation
- amountInCopper = oldMethod(msg)
- else
- amountInCopper = GetMoney() - startingMoney
- end
+ self:RegisterEvent("PLAYER_MONEY")
startingMoney = GetMoney()
- G_RLF.LootDisplay:ShowMoney(amountInCopper)
end
-function Money:CHAT_MSG_MONEY(_, msg)
- G_RLF:fn(showMoneyLoot, msg)
-end
-
-oldMethod = function(msg)
- -- Initialize default values
- local gold, silver, copper = 0, 0, 0
-
- -- Patterns to match optional sections
- local goldPattern = "(%d+) " .. G_RLF.L["Gold"]
- local silverPattern = "(%d+) " .. G_RLF.L["Silver"]
- local copperPattern = "(%d+) " .. G_RLF.L["Copper"]
-
- -- Find and convert matches to numbers if they exist
- gold = tonumber(msg:match(goldPattern)) or gold
- silver = tonumber(msg:match(silverPattern)) or silver
- copper = tonumber(msg:match(copperPattern)) or copper
-
- local amountInCopper = (gold * 100 * 100)
- amountInCopper = amountInCopper + (silver * 100)
- amountInCopper = amountInCopper + copper
-
- return amountInCopper
+function Money:PLAYER_MONEY(eventName)
+ self:getLogger():Info(eventName, "WOWEVENT", self.moduleName)
+ self:fn(function()
+ local newMoney = GetMoney()
+ local amountInCopper = newMoney - startingMoney
+ startingMoney = newMoney
+ G_RLF.LootDisplay:ShowLoot("Money", amountInCopper)
+ end)
end
return Money
diff --git a/Features/Reputation.lua b/Features/Reputation.lua
index 3913054..ad9a7f4 100644
--- a/Features/Reputation.lua
+++ b/Features/Reputation.lua
@@ -3,6 +3,7 @@ local Rep = G_RLF.RLF:NewModule("Reputation", "AceEvent-3.0", "AceTimer-3.0")
local locale
function Rep:OnInitialize()
locale = GetLocale()
+ -- TODO: Move this to db defaults
G_RLF.db.global.factionMaps = G_RLF.db.global.factionMaps or {}
G_RLF.db.global.factionMaps[locale] = G_RLF.db.global.factionMaps[locale] or {}
if G_RLF.db.global.repFeed then
@@ -53,7 +54,12 @@ local function extractFactionAndRep(message, patterns)
local postMatchStart, postMatchEnd = string.find(msgLoop, postPattern, midMatchEnd, true)
if postMatchStart then
local faction = msgLoop:sub(1, midMatchStart - 1)
- local rep = msgLoop:sub(midMatchEnd + 1, postMatchStart - 1)
+ local rep
+ if midMatchEnd == postMatchStart then
+ rep = msgLoop:sub(midMatchEnd + 1)
+ else
+ rep = msgLoop:sub(midMatchEnd + 1, postMatchStart - 1)
+ end
return faction, tonumber(rep)
end
end
@@ -98,8 +104,9 @@ function Rep:OnEnable()
self:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
end
-function Rep:CHAT_MSG_COMBAT_FACTION_CHANGE(_, message)
- G_RLF:fn(function()
+function Rep:CHAT_MSG_COMBAT_FACTION_CHANGE(eventName, message)
+ self:getLogger():Info(eventName .. " " .. message, "WOWEVENT", self.moduleName)
+ return self:fn(function()
local faction, repChange = extractFactionAndRep(message, increasePatterns)
if not faction then
faction, repChange = extractFactionAndRep(message, decreasePatterns)
@@ -107,9 +114,21 @@ function Rep:CHAT_MSG_COMBAT_FACTION_CHANGE(_, message)
repChange = -repChange
end
end
+ if not faction or not repChange then
+ self:getLogger():Error(
+ "Could not determine faction and/or rep change from message",
+ G_RLF.addonName,
+ self.moduleName,
+ faction,
+ nil,
+ repChange
+ )
+ return
+ end
local r, g, b, color
if G_RLF.db.global.factionMaps[locale][faction] == nil then
-- attempt to find the missing faction's ID
+ self:getLogger():Debug(faction .. " not cached for " .. locale, G_RLF.addonName, self.moduleName)
buildFactionLocaleMap(faction)
end
@@ -125,15 +144,15 @@ function Rep:CHAT_MSG_COMBAT_FACTION_CHANGE(_, message)
color = FACTION_BAR_COLORS[factionData.reaction]
end
end
+ else
+ self:getLogger():Warn(faction .. " is STILL not cached for " .. locale, G_RLF.addonName, self.moduleName)
end
if color then
r, g, b = color.r, color.g, color.b
end
- if faction and repChange then
- G_RLF.LootDisplay:ShowRep(repChange, faction, r, g, b)
- end
+ G_RLF.LootDisplay:ShowLoot(self.moduleName, repChange, faction, r, g, b)
end)
end
diff --git a/Logger.lua b/Logger.lua
new file mode 100644
index 0000000..b8bbb34
--- /dev/null
+++ b/Logger.lua
@@ -0,0 +1,340 @@
+local Logger = G_RLF.RLF:NewModule("Logger", "AceEvent-3.0")
+local gui = LibStub("AceGUI-3.0")
+
+local loggerName = G_RLF.addonName .. "Logger"
+local defaults = {
+ sessionsLogged = 0,
+ logs = {},
+}
+
+local updateContent
+local getLogger
+local WOWEVENT = "WOWEVENT"
+
+local eventSource = {
+ [G_RLF.addonName] = true,
+ [WOWEVENT] = false,
+}
+local function OnEventSourceChange(_, _, k, v)
+ eventSource[k] = v
+ updateContent()
+end
+
+local debug = "DEBUG"
+local info = "INFO"
+local warn = "WARN"
+local error = "ERROR"
+local eventLevel = {
+ [debug] = false,
+ [info] = true,
+ [warn] = true,
+ [error] = true,
+}
+local function OnEventLevelChange(_, _, k, v)
+ eventLevel[k] = v
+ updateContent()
+end
+
+local ItemLoot = "ItemLoot"
+local Currency = "Currency"
+local Money = "Money"
+local Reputation = "Reputation"
+local Experience = "Experience"
+local eventType = {
+ [ItemLoot] = true,
+ [Currency] = true,
+ [Money] = true,
+ [Reputation] = true,
+ [Experience] = true,
+}
+local function OnEventTypeChange(_, _, k, v)
+ eventType[k] = v
+ updateContent()
+end
+
+local function OnClearLog()
+ local count = #getLogger()
+ for i = 0, count do
+ getLogger()[i] = nil
+ end
+ updateContent()
+end
+
+local frame, contentBox
+local function initializeFrame()
+ if not frame then
+ frame = gui:Create("Frame")
+ frame:SetTitle("Loot Log")
+ frame:EnableResize(false)
+ frame:SetCallback("OnClose", function(widget)
+ gui:Release(widget)
+ frame = nil
+ end)
+ frame:SetLayout("Flow")
+
+ local filterBar = gui:Create("SimpleGroup")
+ filterBar:SetFullWidth(true)
+ filterBar:SetLayout("Flow")
+ frame:AddChild(filterBar)
+
+ contentBox = gui:Create("MultiLineEditBox")
+ contentBox:SetLabel("Logs")
+ contentBox:DisableButton(true)
+ contentBox:SetFullWidth(true)
+ contentBox:SetNumLines(23)
+ frame:AddChild(contentBox)
+
+ local logSources = gui:Create("Dropdown")
+ logSources:SetLabel("Log Sources")
+ logSources:SetMultiselect(true)
+ logSources:SetList({
+ [G_RLF.addonName] = G_RLF.addonName,
+ [WOWEVENT] = WOWEVENT,
+ }, {
+ G_RLF.addonName,
+ WOWEVENT,
+ })
+ logSources:SetCallback("OnValueChanged", OnEventSourceChange)
+ for k, v in pairs(eventSource) do
+ logSources:SetItemValue(k, v)
+ end
+ filterBar:AddChild(logSources)
+
+ local logLevels = gui:Create("Dropdown")
+ logLevels:SetLabel("Log Levels")
+ logLevels:SetMultiselect(true)
+ logLevels:SetList({
+ [debug] = debug,
+ [info] = info,
+ [warn] = warn,
+ [error] = error,
+ })
+ logLevels:SetCallback("OnValueChanged", OnEventLevelChange)
+ for k, v in pairs(eventLevel) do
+ logLevels:SetItemValue(k, v)
+ end
+ filterBar:AddChild(logLevels)
+
+ local logTypes = gui:Create("Dropdown")
+ logTypes:SetLabel("Log Types")
+ logTypes:SetMultiselect(true)
+ logTypes:SetList({
+ [ItemLoot] = ItemLoot,
+ [Currency] = Currency,
+ [Money] = Money,
+ [Reputation] = Reputation,
+ [Experience] = Experience,
+ })
+ logTypes:SetCallback("OnValueChanged", OnEventTypeChange)
+ for k, v in pairs(eventType) do
+ logTypes:SetItemValue(k, v)
+ end
+ filterBar:AddChild(logTypes)
+
+ local clearButton = gui:Create("Button")
+ clearButton:SetText("Clear Current Log")
+ clearButton:SetCallback("OnClick", OnClearLog)
+ filterBar:AddChild(clearButton)
+
+ frame:DoLayout()
+ end
+end
+
+getLogger = function()
+ if G_RLF.db.global.logger ~= nil and G_RLF.db.global.logger.sessionsLogged > 0 then
+ return G_RLF.db.global.logger.logs[G_RLF.db.global.logger.sessionsLogged]
+ end
+end
+
+function Logger:OnInitialize()
+ self:RegisterEvent("PLAYER_ENTERING_WORLD")
+end
+
+function Logger:PLAYER_ENTERING_WORLD(_, isLogin, isReload)
+ if isLogin then
+ G_RLF.db.global.logger.sessionsLogged = (G_RLF.db.global.logger.sessionsLogged or 0) + 1
+ G_RLF.db.global.logger.logs = G_RLF.db.global.logger.logs or {}
+ G_RLF.db.global.logger.logs[G_RLF.db.global.logger.sessionsLogged] = {}
+ while G_RLF.db.global.logger.sessionsLogged > 3 do
+ tremove(G_RLF.db.global.logger.logs, 1)
+ G_RLF.db.global.logger.sessionsLogged = G_RLF.db.global.logger.sessionsLogged - 1
+ end
+ self:Debug("Logger is ready", G_RLF.addonName)
+ end
+end
+
+local function getLevel(logEntry)
+ local level = logEntry.level
+ local levelColors = {
+ [debug] = "|cFF808080{D}|r", -- Gray for DEBUG
+ [info] = "|cFFADD8E6{I}|r", -- Light blue for INFO (ADD8E6 in hex)
+ [warn] = "|cFFFFD700{W}|r", -- Gold for WARN
+ [error] = "|cFFFF0000{E}|r", -- Red for ERROR
+ }
+
+ -- Return the formatted level or an empty string if the level is not recognized
+ return levelColors[level] or ""
+end
+
+local function getType(logEntry)
+ local type = logEntry.type
+ local typeColors = {
+ [ItemLoot] = "|cFF00FF00[ITEM]|r ", -- Green for item loot
+ [Currency] = "|cFFFFD700[CURR]|r ", -- Gold for currency
+ [Money] = "|cFFC0C0C0[GOLD]|r ", -- Silver/Gray for money
+ [Reputation] = "|cFF1E90FF[REPU]|r ", -- Blue for reputation
+ [Experience] = "|cFF9932CC[EXPR]|r ", -- Purple for experience
+ }
+
+ -- Return an empty string for "General" and the corresponding value for others
+ return typeColors[type] or ""
+end
+
+local function getSource(logEntry)
+ local source = logEntry.source
+ local sourceStrings = {
+ [G_RLF.addonName] = "(RLF)",
+ [WOWEVENT] = "(WOW)",
+ }
+ return sourceStrings[source] or ""
+end
+
+local function getTimestamp(logEntry)
+ -- Extract the time portion from the timestamp using pattern matching
+ local timeOnly = logEntry.timestamp:match("%d%d:%d%d:%d%d")
+
+ -- Return the formatted timestamp with dark gray color
+ return "|cFF808080" .. timeOnly .. "|r"
+end
+
+local function getContent(logEntry)
+ if logEntry.content == "" then
+ return logEntry.message
+ end
+ return logEntry.content
+end
+
+local function getAmount(logEntry)
+ if logEntry.amount == "" then
+ return ""
+ end
+ return format(" x%s", logEntry.amount)
+end
+
+local function isUpdatedRow(logEntry)
+ if logEntry.new == false then
+ return " ~UPDATE~"
+ end
+ return ""
+end
+
+local function getId(logEntry)
+ if logEntry.id == "" then
+ return ""
+ end
+ return format(" [%s]", logEntry.id)
+end
+
+local function formatLogEntry(logEntry)
+ return format(
+ "[%s]%s%s%s:%s%s%s%s\n",
+ getTimestamp(logEntry),
+ getLevel(logEntry),
+ getSource(logEntry),
+ getType(logEntry),
+ getContent(logEntry),
+ getAmount(logEntry),
+ isUpdatedRow(logEntry),
+ getId(logEntry)
+ )
+end
+
+updateContent = function()
+ local text = ""
+
+ local function addText(logEntry)
+ text = formatLogEntry(logEntry) .. text
+ end
+
+ for i, logEntry in ipairs(getLogger()) do
+ if eventSource[logEntry.source] then
+ if eventLevel[logEntry.level] then
+ if eventType[logEntry.type] or logEntry.type == "General" then
+ addText(logEntry)
+ end
+ end
+ end
+ end
+ contentBox:SetText(text)
+end
+
+local function addLogEntry(level, message, source, type, id, content, amount, isNew)
+ local entry = {
+ timestamp = date("%Y-%m-%d %H:%M:%S"),
+ level = level,
+ source = source or G_RLF.addonName,
+ type = type or "General",
+ id = id or "",
+ content = content or "",
+ amount = amount or "",
+ new = isNew,
+ message = message,
+ }
+ local logTable = getLogger()
+ if not logTable then
+ -- error("Log Table not ready")
+ return
+ end
+ table.insert(logTable, entry)
+ if frame and frame:IsShown() then
+ updateContent()
+ end
+end
+
+function Logger:Debug(message, source, type, id, content, amount, isNew)
+ addLogEntry(debug, message, source, type, id, content, amount, isNew)
+end
+
+function Logger:Info(message, source, type, id, content, amount, isNew)
+ addLogEntry(info, message, source, type, id, content, amount, isNew)
+end
+
+function Logger:Warn(message, source, type, id, content, amount, isNew)
+ addLogEntry(warn, message, source, type, id, content, amount, isNew)
+end
+
+function Logger:Error(message, source, type, id, content, amount, isNew)
+ addLogEntry(error, message, source, type, id, content, amount, isNew)
+end
+
+function Logger:Trace(type, traceSize)
+ local trace = ""
+ traceSize = traceSize or 10
+ local count = 0
+ local logs = getLogger()
+ for i = #logs, 1, -1 do
+ if logs[i].type == type then
+ count = count + 1
+ trace = trace .. formatLogEntry(logs[i])
+ end
+ if count >= traceSize then
+ break
+ end
+ end
+
+ return trace
+end
+
+function Logger:Show()
+ if frame then
+ self:Hide()
+ else
+ initializeFrame()
+ updateContent()
+ frame:Show()
+ end
+end
+
+function Logger:Hide()
+ frame:Hide()
+end
diff --git a/LootDisplay.lua b/LootDisplay.lua
index 698d1ed..d14c2eb 100644
--- a/LootDisplay.lua
+++ b/LootDisplay.lua
@@ -1,9 +1,11 @@
-local LootDisplay = {}
+local LootDisplay = G_RLF.RLF:NewModule("LootDisplay", "AceBucket-3.0", "AceEvent-3.0")
local Masque = LibStub and LibStub("Masque", true)
local iconGroup = Masque and Masque:Group(G_RLF.addonName)
-- Private method declaration
+local processRow
+local processFromQueue
local configureFeedFrame
local applyRowStyles
local doesRowExist
@@ -18,9 +20,6 @@ local rowBackground
local rowFadeOutAnimation
local rowHighlightBorder
local rowIcon
-local rowMoneyIcon
-local rowMoneyStyles
-local rowMoneyText
local rowStyles
local configureTestArea
local createArrowsTestArea
@@ -46,6 +45,7 @@ local defaults = {
rowBackgroundGradientEnd = { 0.1, 0.1, 0.1, 0 }, -- Default to dark grey with 0% opacity
font = "GameFontNormalSmall",
}
+local defaultColor
local config = nil
local rows = G_RLF.list()
local rowFramePool = {}
@@ -54,7 +54,9 @@ local boundingBox = nil
local tempFontString = nil
-- Public methods
-function LootDisplay:Initialize()
+local logger
+
+function LootDisplay:OnInitialize()
config = DynamicPropertyTable(G_RLF.db.global, defaults)
configureFeedFrame()
@@ -64,6 +66,7 @@ function LootDisplay:Initialize()
tempFontString = UIParent:CreateFontString(nil, "ARTWORK")
tempFontString:Hide() -- Prevent it from showing up
+ self:RegisterBucketMessage("RLF_LootDisplay_RowReturned", 0.2, processFromQueue)
end
function LootDisplay:SetBoundingBoxVisibility(show)
@@ -107,168 +110,175 @@ function LootDisplay:UpdateFadeDelay()
end
end
-function LootDisplay:ShowLoot(id, link, icon, amountLooted)
- local key = tostring(id) -- Use ID as a unique key
-
- -- Check if the item or currency is already displayed
- local row = getRow(key)
- if row then
- -- Update existing entry
- row.amount = row.amount + amountLooted
- row.highlightAnimation:Stop()
- row.highlightAnimation:Play()
- if row.fadeOutAnimation:IsPlaying() then
- row.fadeOutAnimation:Stop()
- row.fadeOutAnimation:Play()
+function LootDisplay:ShowLoot(type, ...)
+ local key, textFn, isLink, icon, quantity, quality, r, g, b, a
+ isLink = false
+ local logType = type
+ if type == "Currency" or type == "ItemLoot" then
+ isLink = true
+ local t, k
+ k, t, icon, quantity = ...
+ key = tostring(k)
+ textFn = function(existingQuantity, truncatedLink)
+ if not truncatedLink then
+ return t
+ end
+ return truncatedLink .. " x" .. ((existingQuantity or 0) + quantity)
end
- else
- row = leaseRow(key)
- if row == nil then
+ if type == "Currency" then
+ quality = C_CurrencyInfo.GetCurrencyInfo(k).quality
+ end
+ elseif type == "Money" then
+ key = "MONEY_LOOT"
+ quantity = ...
+ if not quantity then
return
end
-
- -- Initialize row content
- rowStyles(row)
- if Masque and iconGroup then
- local found = string.find(link, "item:")
- if found then
- row.icon:SetItem(link)
- else
- local quality = C_CurrencyInfo.GetCurrencyInfo(id).quality
- row.icon:SetItemButtonTexture(icon)
- row.icon:SetItemButtonQuality(quality, link)
+ textFn = function(existingCopper)
+ local sign = ""
+ local total = (existingCopper or 0) + quantity
+ if total < 0 then
+ sign = "-"
end
- else
- row.icon:SetTexture(icon)
- end
- row.amount = amountLooted
- local extraWidth = getTextWidth(" x" .. row.amount)
- row.link = truncateItemLink(link, extraWidth)
- row.fadeOutAnimation:Stop()
- row.fadeOutAnimation:Play()
- end
- row.amountText:SetText(row.link .. " x" .. row.amount)
- -- Add Tooltip
- row.amountText:SetScript("OnEnter", function()
- row.fadeOutAnimation:Stop()
- row.highlightAnimation:Stop()
- row.highlightBorder:SetAlpha(0)
- if not G_RLF.db.global.tooltip then
- return
+ return sign .. C_CurrencyInfo.GetCoinTextureString(math.abs(total))
end
- if G_RLF.db.global.tooltipOnShift and not IsShiftKeyDown() then
- return
+ elseif type == "Experience" then
+ key = "EXPERIENCE"
+ quantity = ...
+ r, g, b, a = 1, 0, 1, 0.8
+ textFn = function(existingXP)
+ return "+" .. ((existingXP or 0) + quantity) .. " " .. G_RLF.L["XP"]
end
- local inCombat = UnitAffectingCombat("player")
- if inCombat then
- GameTooltip:Hide()
- return
+ elseif type == "Reputation" then
+ local factionName, rL, gL, bL
+ quantity, factionName, rL, gL, bL = ...
+ r, g, b = rL or 0.5, gL or 0.5, bL or 1
+ a = 1
+ key = "REP_" .. factionName
+ textFn = function(existingRep)
+ local sign = "+"
+ local rep = (existingRep or 0) + quantity
+ if rep < 0 then
+ sign = "-"
+ end
+ return sign .. math.abs(rep) .. " " .. factionName
end
- GameTooltip:SetOwner(row.amountText, "ANCHOR_RIGHT")
- GameTooltip:SetHyperlink(row.link) -- Use the item's link to show the tooltip
- GameTooltip:Show()
- end)
- row.amountText:SetScript("OnLeave", function()
- row.fadeOutAnimation:Play()
- GameTooltip:Hide()
- end)
+ else
+ self:getLogger():Error("Unknown type? " .. type, G_RLF.addonName, type)
+ end
+ processRow(key, textFn, icon, quantity, quality, r, g, b, a, logType)
end
-function LootDisplay:ShowMoney(copper)
- local key = "MONEY_LOOT" -- Use ID as a unique key
+local overflowQueue = {}
+processRow = function(...)
+ local key, textFn, icon, quantity, quality, r, g, b, a, logType = ...
+ local isLink = not not icon
+ local new = true
local text
- if not copper or copper <= 0 then
- return
- end
+ local rD, gD, bD, aD = unpack(defaultColor or { 1, 1, 1, 1 })
- -- Check if the item or currency is already displayed
local row = getRow(key)
if row then
-- Update existing entry
- row.copper = row.copper + copper
- row.highlightAnimation:Stop()
- row.highlightAnimation:Play()
+ new = false
+ row.meta = { ... }
+ text = textFn(row.amount, row.link)
+ row.amount = row.amount + quantity
+ if not G_RLF.db.global.disableRowHighlight then
+ row.highlightAnimation:Stop()
+ row.highlightAnimation:Play()
+ end
+ if row.fadeOutAnimation:IsPlaying() then
+ row.fadeOutAnimation:Stop()
+ row.fadeOutAnimation:Play()
+ end
else
+ -- New row
row = leaseRow(key)
if row == nil then
+ tinsert(overflowQueue, { ... })
return
end
- -- Initialize row content
- rowMoneyStyles(row)
- row.copper = copper
+ row.meta = { ... }
+ row.amount = quantity
+ rowStyles(row, icon)
+ if isLink then
+ local extraWidth = getTextWidth(" x" .. row.amount)
+ row.link = truncateItemLink(textFn(), extraWidth)
+ text = textFn(0, row.link)
+
+ if icon then
+ if Masque and iconGroup then
+ if logType == "ItemLoot" then
+ row.icon:SetItem(row.link)
+ else
+ local quality = C_CurrencyInfo.GetCurrencyInfo(key).quality
+ row.icon:SetItemButtonTexture(icon)
+ row.icon:SetItemButtonQuality(quality, row.link)
+ end
+ else
+ row.icon:SetTexture(icon)
+ end
+ end
+ -- Add Tooltip
+ row.amountText:SetScript("OnEnter", function()
+ row.fadeOutAnimation:Stop()
+ row.highlightAnimation:Stop()
+ row.highlightBorder:SetAlpha(0)
+ if not G_RLF.db.global.tooltip then
+ return
+ end
+ if G_RLF.db.global.tooltipOnShift and not IsShiftKeyDown() then
+ return
+ end
+ local inCombat = UnitAffectingCombat("player")
+ if inCombat then
+ GameTooltip:Hide()
+ return
+ end
+ GameTooltip:SetOwner(row.amountText, "ANCHOR_RIGHT")
+ GameTooltip:SetHyperlink(row.link) -- Use the item's link to show the tooltip
+ GameTooltip:Show()
+ end)
+ row.amountText:SetScript("OnLeave", function()
+ row.fadeOutAnimation:Play()
+ GameTooltip:Hide()
+ end)
+ else
+ text = textFn()
+ end
end
-
- text = C_CurrencyInfo.GetCoinTextureString(row.copper)
row.amountText:SetText(text)
-
- row.fadeOutAnimation:Stop()
- row.fadeOutAnimation:Play()
-end
-
-function LootDisplay:ShowXP(experience)
- local key = "EXPERIENCE" -- Use ID as a unique key
- local text
-
- -- Check if the item or currency is already displayed
- local row = getRow(key)
- if row then
- -- Update existing entry
- row.experience = row.experience + experience
- row.highlightAnimation:Stop()
- row.highlightAnimation:Play()
+ if r == nil and g == nil and b == nil and row.amount ~= nil and row.amount < 0 then
+ r, g, b, a = 1, 0, 0, 0.8
else
- row = leaseRow(key)
- if row == nil then
- return
- end
-
- -- Initialize row content
- rowMoneyStyles(row)
- row.experience = experience
+ r, g, b, a = r or rD, g or gD, b or bD, a or aD
end
-
- text = "+" .. row.experience .. " " .. G_RLF.L["XP"]
- row.amountText:SetText(text)
- row.amountText:SetTextColor(1, 0, 1, 0.8)
-
+ row.amountText:SetTextColor(r, g, b, a)
+ local amountLogText = row.amount
+ if not new then
+ amountLogText = format("%s (+%s)", row.amount, quantity)
+ end
+ LootDisplay:getLogger():Info(logType .. " Shown", G_RLF.addonName, logType, key, text, amountLogText, new)
row.fadeOutAnimation:Stop()
row.fadeOutAnimation:Play()
end
-function LootDisplay:ShowRep(rep, factionName, r, g, b)
- local key = "REP_" .. factionName -- Use ID as a unique key
- local text
-
- -- Check if the item or currency is already displayed
- local row = getRow(key)
- if row then
- -- Update existing entry
- row.rep = row.rep + rep
- row.highlightAnimation:Stop()
- row.highlightAnimation:Play()
- else
- row = leaseRow(key)
- if row == nil then
- return
+processFromQueue = function()
+ local snapshotQueueSize = #overflowQueue
+ if snapshotQueueSize > 0 then
+ -- error("Test")
+ local rowsToProcess = math.min(snapshotQueueSize, config.maxRows)
+ LootDisplay:getLogger():Debug("Processing " .. rowsToProcess .. " items from overflow queue", G_RLF.addonName)
+ for i = 1, math.min(snapshotQueueSize, config.maxRows) do
+ -- Get the first set of args from the queue
+ local args = tremove(overflowQueue, 1) -- Remove and return the first element
+ -- Call processRow with the unpacked arguments
+ processRow(unpack(args))
end
-
- -- Initialize row content
- rowMoneyStyles(row)
- row.rep = rep
- end
- local sign = "+"
- if rep < 0 then
- sign = "-"
end
- text = sign .. math.abs(row.rep) .. " " .. factionName
- row.amountText:SetText(text)
- local r, g, b = r or 0.5, g or 0.5, b or 1
- row.amountText:SetTextColor(r, g, b, 1)
-
- row.fadeOutAnimation:Stop()
- row.fadeOutAnimation:Play()
end
function LootDisplay:HideLoot()
@@ -353,48 +363,7 @@ rowIcon = function(row)
row.icon:Show()
end
-rowMoneyIcon = function(row)
- if row.icon == nil then
- if Masque and iconGroup then
- row.icon = CreateFrame("ItemButton", nil, row)
- iconGroup:AddButton(row.icon)
- else
- row.icon = row:CreateTexture(nil, "ARTWORK")
- end
- else
- row.icon:ClearAllPoints()
- end
- row.icon:SetSize(config.iconSize, config.iconSize)
- local anchor = "LEFT"
- local xOffset = config.iconSize / 4
- if G_RLF.db.global.leftAlign == false then
- anchor = "RIGHT"
- xOffset = xOffset * -1
- end
- row.icon:SetPoint(anchor, xOffset, 0)
- row.icon:Hide()
-end
-
-local defaultColor
-rowMoneyText = function(row)
- if row.amountText == nil then
- row.amountText = row:CreateFontString(nil, "ARTWORK")
- if not defaultColor then
- local r, g, b, a = row.amountText:GetTextColor()
- defaultColor = { r, g, b, a }
- end
- else
- row.amountText:ClearAllPoints()
- end
- local anchor = "LEFT"
- if G_RLF.db.global.leftAlign == false then
- anchor = "RIGHT"
- end
- row.amountText:SetFontObject(config.font)
- row.amountText:SetPoint(anchor, row.icon, anchor, 0, 0)
-end
-
-rowAmountText = function(row)
+rowAmountText = function(row, icon)
if row.amountText == nil then
row.amountText = row:CreateFontString(nil, "ARTWORK")
if not defaultColor then
@@ -413,7 +382,11 @@ rowAmountText = function(row)
xOffset = xOffset * -1
end
row.amountText:SetFontObject(config.font)
- row.amountText:SetPoint(anchor, row.icon, iconAnchor, xOffset, 0)
+ if icon then
+ row.amountText:SetPoint(anchor, row.icon, iconAnchor, xOffset, 0)
+ else
+ row.amountText:SetPoint(anchor, row.icon, anchor, 0, 0)
+ end
end
rowFadeOutAnimation = function(row)
@@ -471,33 +444,21 @@ rowHighlightBorder = function(row)
end
end
-rowMoneyStyles = function(row)
+rowStyles = function(row, icon)
row:SetSize(config.feedWidth, config.rowHeight)
-
- rowBackground(row)
- rowMoneyIcon(row)
- rowHighlightBorder(row)
- rowMoneyText(row)
- rowFadeOutAnimation(row)
-end
-
-rowStyles = function(row)
- row:SetSize(config.feedWidth, config.rowHeight)
-
rowBackground(row)
rowIcon(row)
+ if not icon then
+ row.icon:Hide()
+ end
rowHighlightBorder(row)
- rowAmountText(row)
+ rowAmountText(row, icon)
rowFadeOutAnimation(row)
end
-applyRowStyles = function(row)
- if row.copper ~= nil or row.experience ~= nil or row.rep ~= nil then
- rowMoneyStyles(row)
- else
- rowStyles(row)
- end
- if iconGroup then
+applyRowStyles = function(row, icon)
+ rowStyles(row, icon)
+ if icon and iconGroup then
iconGroup:ReSkin(row.icon)
end
end
@@ -506,7 +467,12 @@ updateRowPositions = function()
local index = 0
for row in rows:iterate() do
if row:IsShown() then
- applyRowStyles(row)
+ local icon
+ if row.meta then
+ local _, _, ic = unpack(row.meta)
+ icon = ic
+ end
+ applyRowStyles(row, icon)
row:ClearAllPoints()
local vertDir = "BOTTOM"
local yOffset = index * (config.rowHeight + config.padding)
@@ -585,13 +551,13 @@ local function createArrow(f, direction)
arrow:SetRotation(0)
elseif direction == "DOWN" then
arrow:SetPoint("BOTTOM", f, "BOTTOM", 0, 20)
- arrow:SetRotation(math.pi) -- Rotate 180 degrees
+ arrow:SetRotation(math.pi)
elseif direction == "LEFT" then
arrow:SetPoint("LEFT", f, "LEFT", 20, 0)
- arrow:SetRotation(math.pi * 0.5) -- Rotate 270 degrees
+ arrow:SetRotation(math.pi * 0.5)
elseif direction == "RIGHT" then
arrow:SetPoint("RIGHT", f, "RIGHT", -20, 0)
- arrow:SetRotation(math.pi * 1.5) -- Rotate 90 degrees
+ arrow:SetRotation(math.pi * 1.5)
end
arrow:Hide()
@@ -657,10 +623,8 @@ leaseRow = function(key)
row = tremove(rowFramePool)
row:ClearAllPoints()
row.amount = nil
- row.copper = nil
row.link = nil
- row.experience = nil
- row.rep = nil
+ row.meta = nil
if row.highlightBorder then
row.highlightBorder:SetAlpha(0)
end
@@ -700,4 +664,5 @@ end
returnRow = function(row)
row:Hide()
tinsert(rowFramePool, row)
+ LootDisplay:SendMessage("RLF_LootDisplay_RowReturned")
end
diff --git a/RPGLootFeed.lua b/RPGLootFeed.lua
index 6560684..dd433ad 100644
--- a/RPGLootFeed.lua
+++ b/RPGLootFeed.lua
@@ -1,12 +1,10 @@
local addonName = G_RLF.addonName
local acd = LibStub("AceConfigDialog-3.0")
RLF = G_RLF.RLF
-G_RLF.L = LibStub("AceLocale-3.0"):GetLocale(G_RLF.localeName)
function RLF:OnInitialize()
G_RLF.db = LibStub("AceDB-3.0"):New(G_RLF.dbName, G_RLF.defaults, true)
LibStub("AceConfig-3.0"):RegisterOptionsTable(addonName, G_RLF.options)
- G_RLF.LootDisplay:Initialize()
self:Hook(acd, "Open", "OnOptionsOpen")
self:RegisterEvent("PLAYER_ENTERING_WORLD")
self:RegisterChatCommand("rlf", "SlashCommand")
@@ -30,6 +28,8 @@ function RLF:SlashCommand(msg, editBox)
G_RLF.TestMode:ToggleTestMode()
elseif msg == "clear" then
G_RLF.LootDisplay:HideLoot()
+ elseif msg == "log" then
+ self:GetModule("Logger"):Show()
else
acd:Open(addonName)
end
diff --git a/RPGLootFeed.toc b/RPGLootFeed.toc
index b1dbd89..ce2c1da 100644
--- a/RPGLootFeed.toc
+++ b/RPGLootFeed.toc
@@ -19,13 +19,12 @@ DoubleLinkedList.lua
locale/locales.xml
-Features/features.xml
-
BlizzOverrides/overrides.xml
-RPGLootFeed.lua
-
config/config.xml
+RPGLootFeed.lua
+Logger.lua
+Features/features.xml
TestMode.lua
LootDisplay.lua
diff --git a/TestMode.lua b/TestMode.lua
index 7427d84..a5d8335 100644
--- a/TestMode.lua
+++ b/TestMode.lua
@@ -1,5 +1,7 @@
TestMode = {}
+local logger
+
local function idExistsInTable(id, table)
for _, item in pairs(table) do
if item.id == id then
@@ -10,20 +12,7 @@ local function idExistsInTable(id, table)
end
-- Initial test items with color variables
-local testItemIds = {
- 50818,
- 2589,
- 2592,
- 1515,
- 730,
- 19019,
- 128507,
- 132842,
- 23538,
- 11754,
- 128827,
- 219325,
-}
+local testItemIds = { 50818, 2589, 2592, 1515, 730, 19019, 128507, 132842, 23538, 11754, 128827, 219325 }
local testItems = {}
local function initializeTestItems()
@@ -42,23 +31,7 @@ local function initializeTestItems()
end
end
-local testCurrencyIds = {
- 2245,
- 1191,
- 1828,
- 1792,
- 1755,
- 1580,
- 1273,
- 1166,
- 515,
- 241,
- 1813,
- 2778,
- 3089,
- 1101,
- 1704,
-}
+local testCurrencyIds = { 2245, 1191, 1828, 1792, 1755, 1580, 1273, 1166, 515, 241, 1813, 2778, 3089, 1101, 1704 }
local testCurrencies = {}
local function initializeTestCurrencies()
@@ -77,6 +50,12 @@ local function initializeTestCurrencies()
end
end
+local testFactions = {
+ "Undercity",
+ "Thunder Bluff",
+ "Orgrimmar",
+}
+
local function generateRandomLoot()
if #testItems ~= #testItemIds then
initializeTestItems()
@@ -86,25 +65,45 @@ local function generateRandomLoot()
initializeTestCurrencies()
end
-- Randomly decide whether to generate an item or currency
- local rng = math.random()
- if rng < 0.8 then
- -- Generate random item
- local item = testItems[math.random(#testItems)]
- local amountLooted = math.random(1, 5)
- G_RLF.LootDisplay:ShowLoot(item.id, item.link, item.icon, amountLooted)
- if rng < 0.1 then
+ local numberOfRowsToGenerate = math.random(1, 5)
+ for i = 1, numberOfRowsToGenerate do
+ local rng = math.random()
+
+ if rng >= 0.8 then
+ local experienceGained = math.random(100, 10000)
+ G_RLF.LootDisplay:ShowLoot("Experience", experienceGained)
+ end
+
+ if rng <= 0.2 then
local copper = math.random(1, 100000000)
- G_RLF.LootDisplay:ShowMoney(copper)
+ G_RLF.LootDisplay:ShowLoot("Money", copper)
+ end
+
+ -- 50% chance to show items
+ if rng > 0.2 and rng <= 0.7 then
+ local item = testItems[math.random(#testItems)]
+ local amountLooted = math.random(1, 5)
+ G_RLF.LootDisplay:ShowLoot("ItemLoot", item.id, item.link, item.icon, amountLooted)
+
+ -- 15% chance to show currency
+ elseif rng > 0.7 and rng <= 0.85 then
+ local currency = testCurrencies[math.random(#testCurrencies)]
+ local amountLooted = math.random(1, 500)
+ G_RLF.LootDisplay:ShowLoot("Currency", currency.id, currency.link, currency.icon, amountLooted)
+
+ -- 10% chance to show reputation (least frequent)
+ elseif rng > 0.85 then
+ local reputationGained = math.random(10, 100)
+ local factionName = testFactions[math.random(#testFactions)]
+ G_RLF.LootDisplay:ShowLoot("Reputation", reputationGained, factionName)
end
- else
- -- Generate random currency
- local currency = testCurrencies[math.random(#testCurrencies)]
- local amountLooted = math.random(1, 500)
- G_RLF.LootDisplay:ShowLoot(currency.id, currency.link, currency.icon, amountLooted)
end
end
function TestMode:ToggleTestMode()
+ if not logger then
+ logger = G_RLF.RLF:GetModule("Logger")
+ end
if self.testMode then
-- Stop test mode
self.testMode = false
@@ -113,10 +112,12 @@ function TestMode:ToggleTestMode()
self.testTimer = nil
end
G_RLF:Print(G_RLF.L["Test Mode Disabled"])
+ logger:Debug("Test Mode Disabled", G_RLF.addonName)
else
-- Start test mode
self.testMode = true
G_RLF:Print(G_RLF.L["Test Mode Enabled"])
+ logger:Debug("Test Mode Enabled", G_RLF.addonName)
self.testTimer = C_Timer.NewTicker(1.5, function()
G_RLF:fn(generateRandomLoot)
end)
diff --git a/config/ConfigOptions.lua b/config/ConfigOptions.lua
index b682cab..3f0b8ef 100644
--- a/config/ConfigOptions.lua
+++ b/config/ConfigOptions.lua
@@ -2,7 +2,12 @@ local ConfigOptions = {}
G_RLF.defaults = {
profile = {},
- global = {},
+ global = {
+ logger = {
+ sessionsLogged = 0,
+ logs = {},
+ },
+ },
}
G_RLF.options = {
diff --git a/config/Sizing.lua b/config/Sizing.lua
index 9304b3c..f5689b5 100644
--- a/config/Sizing.lua
+++ b/config/Sizing.lua
@@ -27,8 +27,9 @@ G_RLF.options.args.sizing = {
type = "range",
name = G_RLF.L["Maximum Rows to Display"],
desc = G_RLF.L["MaxRowsDesc"],
- min = 10,
- max = 1000,
+ min = 1,
+ softMin = 3,
+ max = 20,
step = 1,
bigStep = 5,
get = "GetMaxRows",
diff --git a/config/Styling.lua b/config/Styling.lua
index 0922226..91ea041 100644
--- a/config/Styling.lua
+++ b/config/Styling.lua
@@ -4,6 +4,7 @@ G_RLF.defaults.global.leftAlign = true
G_RLF.defaults.global.growUp = true
G_RLF.defaults.global.rowBackgroundGradientStart = { 0.1, 0.1, 0.1, 0.8 } -- Default to dark grey with 80% opacity
G_RLF.defaults.global.rowBackgroundGradientEnd = { 0.1, 0.1, 0.1, 0 } -- Default to dark grey with 0% opacity
+G_RLF.defaults.global.disableRowHighlight = false
G_RLF.defaults.global.font = "GameFontNormalSmall"
G_RLF.options.args.styles = {
@@ -49,6 +50,15 @@ G_RLF.options.args.styles = {
set = "SetGradientEndColor",
order = 4,
},
+ rowHighlight = {
+ type = "toggle",
+ name = G_RLF.L["Disable Row Highlight"],
+ desc = G_RLF.L["DisableRowHighlightDesc"],
+ width = "double",
+ get = "GetRowHighlight",
+ set = "SetRowHighlight",
+ order = 5,
+ },
font = {
type = "select",
name = G_RLF.L["Font"],
@@ -57,7 +67,7 @@ G_RLF.options.args.styles = {
values = "GetFonts",
get = "GetRowFont",
set = "SetRowFont",
- order = 5,
+ order = 6,
},
},
}
@@ -117,6 +127,14 @@ function Styling:SetGrowUp(info, value)
G_RLF.LootDisplay:UpdateRowPositions()
end
+function Styling:GetRowHighlight(info, value)
+ return G_RLF.db.global.disableRowHighlight
+end
+
+function Styling:SetRowHighlight(info, value)
+ G_RLF.db.global.disableRowHighlight = value
+end
+
function Styling:SetRowFont(info, value)
G_RLF.db.global.font = value
G_RLF.LootDisplay:UpdateRowStyles()
diff --git a/embeds.xml b/embeds.xml
index ef3512a..95aa53d 100644
--- a/embeds.xml
+++ b/embeds.xml
@@ -10,4 +10,5 @@
+
diff --git a/locale/enUS.lua b/locale/enUS.lua
index 286c0e2..1bea837 100644
--- a/locale/enUS.lua
+++ b/locale/enUS.lua
@@ -120,6 +120,8 @@ L["Background Gradient Start"] = true
L["GradientStartDesc"] = "The start color of the row background gradient."
L["Background Gradient End"] = true
L["GradientEndDesc"] = "The end color of the row background gradient."
+L["Disable Row Highlight"] = true
+L["DisableRowHighlightDesc"] = "If checked, don't highlight a row when you loot the same item again and the quanity is updated."
L["Font"] = true
L["FontDesc"] = "The font object for the loot text."
diff --git a/locale/locales.xml b/locale/locales.xml
index 1b717fb..4d381a3 100644
--- a/locale/locales.xml
+++ b/locale/locales.xml
@@ -15,4 +15,5 @@
+
\ No newline at end of file
diff --git a/locale/main.lua b/locale/main.lua
new file mode 100644
index 0000000..29e2d66
--- /dev/null
+++ b/locale/main.lua
@@ -0,0 +1 @@
+G_RLF.L = LibStub("AceLocale-3.0"):GetLocale(G_RLF.localeName)
diff --git a/spec/AddonScope_spec.lua b/spec/AddonScope_spec.lua
index 55aba7d..0ee10f2 100644
--- a/spec/AddonScope_spec.lua
+++ b/spec/AddonScope_spec.lua
@@ -5,12 +5,13 @@ describe("AddonScope module", function()
NewAddon = function()
return {
SetDefaultModuleState = function() end,
+ SetDefaultModulePrototype = function() end,
}
end,
}
end
-- Load the list module before each test
- dofile("AddonScope.lua")
+ require("AddonScope")
end)
it("TODO", function()
diff --git a/spec/DoubleLinkedList_spec.lua b/spec/DoubleLinkedList_spec.lua
index 3d38cb2..0caee7e 100644
--- a/spec/DoubleLinkedList_spec.lua
+++ b/spec/DoubleLinkedList_spec.lua
@@ -8,9 +8,9 @@ describe("List module", function()
before_each(function()
-- Define the global G_RLF
- _G.G_RLF = {}
+ _G.G_RLF = _G.G_RLF or {}
-- Load the list module before each test
- dofile("DoubleLinkedList.lua")
+ require("DoubleLinkedList")
list = _G.G_RLF.list
end)
diff --git a/spec/Features/Currency_spec.lua b/spec/Features/Currency_spec.lua
index 4bfb06e..f80bc22 100644
--- a/spec/Features/Currency_spec.lua
+++ b/spec/Features/Currency_spec.lua
@@ -9,7 +9,7 @@ describe("Currency module", function()
common_stubs.stub_C_CurrencyInfo()
-- Load the list module before each test
- CurrencyModule = dofile("Features/Currency.lua")
+ CurrencyModule = require("Features/Currency")
end)
it("does not show loot if the currency type is nil", function()
@@ -74,6 +74,9 @@ describe("Currency module", function()
CurrencyModule:CURRENCY_DISPLAY_UPDATE(_, 123, 5, 2)
- assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called_with(_, 123, "|c12345678|Hcurrency:123|r", 123456, 2)
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called()
+ assert
+ .stub(_G.G_RLF.LootDisplay.ShowLoot).was
+ .called_with(_, "Currency", 123, "|c12345678|Hcurrency:123|r", 123456, 2)
end)
end)
diff --git a/spec/Features/Experience_spec.lua b/spec/Features/Experience_spec.lua
index b00d887..ecc78f4 100644
--- a/spec/Features/Experience_spec.lua
+++ b/spec/Features/Experience_spec.lua
@@ -8,15 +8,15 @@ describe("Experience module", function()
common_stubs.setup_G_RLF(spy)
common_stubs.stub_Unit_Funcs()
-- Load the list module before each test
- XpModule = dofile("Features/Experience.lua")
+ XpModule = require("Features/Experience")
end)
it("does not show xp if the unit target is not player", function()
_G.G_RLF.db.global.xpFeed = true
- XpModule:PLAYER_XP_UPDATE(_, "target")
+ XpModule:PLAYER_XP_UPDATE("PLAYER_XP_UPDATE", "target")
- assert.stub(_G.G_RLF.LootDisplay.ShowXP).was_not_called()
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was_not_called()
end)
it("does not show xp if the calculated delta is 0", function()
@@ -24,9 +24,9 @@ describe("Experience module", function()
XpModule:PLAYER_ENTERING_WORLD()
- XpModule:PLAYER_XP_UPDATE(_, "player")
+ XpModule:PLAYER_XP_UPDATE("PLAYER_XP_UPDATE", "player")
- assert.stub(_G.G_RLF.LootDisplay.ShowXP).was_not_called()
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was_not_called()
end)
it("does not show xp if the calculated delta is 0", function()
@@ -41,8 +41,9 @@ describe("Experience module", function()
return 100
end
- XpModule:PLAYER_XP_UPDATE(_, "player")
+ XpModule:PLAYER_XP_UPDATE("PLAYER_XP_UPDATE", "player")
- assert.stub(_G.G_RLF.LootDisplay.ShowXP).was_called_with(_, 50)
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called()
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called_with(_, "Experience", 50)
end)
end)
diff --git a/spec/Features/ItemLoot_spec.lua b/spec/Features/ItemLoot_spec.lua
index 5afe492..ebc7eaa 100644
--- a/spec/Features/ItemLoot_spec.lua
+++ b/spec/Features/ItemLoot_spec.lua
@@ -7,7 +7,7 @@ describe("ItemLoot module", function()
-- Define the global G_RLF
common_stubs.setup_G_RLF(spy)
-- Load the list module before each test
- LootModule = dofile("Features/ItemLoot.lua")
+ LootModule = require("Features/ItemLoot")
end)
it("LootModule is not nil", function()
diff --git a/spec/Features/Money_spec.lua b/spec/Features/Money_spec.lua
index ba66052..efb4848 100644
--- a/spec/Features/Money_spec.lua
+++ b/spec/Features/Money_spec.lua
@@ -5,8 +5,9 @@ describe("Money module", function()
before_each(function()
common_stubs.setup_G_RLF(spy)
+ common_stubs.stub_Money_Funcs()
-- Load the list module before each test
- MoneyModule = dofile("Features/Money.lua")
+ MoneyModule = require("Features/Money")
end)
it("MoneyModule is not nil", function()
diff --git a/spec/Features/Reputation_spec.lua b/spec/Features/Reputation_spec.lua
index d5aa96f..4d6a6cc 100644
--- a/spec/Features/Reputation_spec.lua
+++ b/spec/Features/Reputation_spec.lua
@@ -1,15 +1,51 @@
local common_stubs = require("spec/common_stubs")
describe("Reputation module", function()
+ local _ = match._
local RepModule
before_each(function()
- common_stubs.setup_G_RLF(spy)
+ common_stubs.setup_G_RLF(spy, assert)
+ common_stubs.stub_C_Reputation()
-- Load the list module before each test
- RepModule = dofile("Features/Reputation.lua")
+ RepModule = require("Features/Reputation")
+ RepModule:OnInitialize()
end)
it("RepModule is not nil", function()
assert.is_not_nil(RepModule)
end)
+
+ it("does not show rep if the faction and/or repChange can't be determined from the message", function()
+ local success =
+ RepModule:CHAT_MSG_COMBAT_FACTION_CHANGE("CHAT_MSG_COMBAT_FACTION_CHANGE", "10x Reputation with Faction A")
+
+ assert.is_true(success)
+
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.not_called()
+ end)
+
+ it("handles rep increases", function()
+ local success =
+ RepModule:CHAT_MSG_COMBAT_FACTION_CHANGE("CHAT_MSG_COMBAT_FACTION_CHANGE", "Rep with Faction A inc by 10.")
+
+ assert.is_true(success)
+
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called()
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called_with(_, "Reputation", 10, "Faction A", 1, 0, 0)
+ -- Successfully populates the locale cache
+ assert.equal(_G.G_RLF.db.global.factionMaps.enUS["Faction A"], 1)
+ end)
+
+ it("handles rep increases despite locale cache miss", function()
+ local success =
+ RepModule:CHAT_MSG_COMBAT_FACTION_CHANGE("CHAT_MSG_COMBAT_FACTION_CHANGE", "Rep with Faction B inc by 100.")
+
+ assert.is_true(success)
+
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called()
+ assert.stub(_G.G_RLF.LootDisplay.ShowLoot).was.called_with(_, "Reputation", 100, "Faction B", nil, nil, nil)
+ assert.spy(RepModule:getLogger().Warn).was.called()
+ assert.spy(RepModule:getLogger().Warn).was.called_with(_, "Faction B is STILL not cached for enUS", _, _)
+ end)
end)
diff --git a/spec/LootDisplay_spec.lua b/spec/LootDisplay_spec.lua
index 946b475..9396fc8 100644
--- a/spec/LootDisplay_spec.lua
+++ b/spec/LootDisplay_spec.lua
@@ -1,14 +1,15 @@
+local common_stubs = require("spec.common_stubs")
+
describe("LootDisplay module", function()
+ local LootDisplayModule
before_each(function()
-- Define the global G_RLF
- _G.G_RLF = {
- list = function() end,
- }
+ common_stubs.setup_G_RLF(spy)
-- Load the list module before each test
- dofile("LootDisplay.lua")
+ LootDisplayModule = require("LootDisplay")
end)
- it("TODO", function()
- assert.are.equal(true, true)
+ it("creates the module", function()
+ assert.is_not_nil(LootDisplayModule)
end)
end)
diff --git a/spec/RPGLootFeed_spec.lua b/spec/RPGLootFeed_spec.lua
index 1c33b34..722658b 100644
--- a/spec/RPGLootFeed_spec.lua
+++ b/spec/RPGLootFeed_spec.lua
@@ -10,7 +10,7 @@ describe("RPGLootFeed module", function()
RLF = {},
}
-- Load the list module before each test
- dofile("RPGLootFeed.lua")
+ require("RPGLootFeed")
end)
it("TODO", function()
diff --git a/spec/common_stubs.lua b/spec/common_stubs.lua
index b55d156..8d95584 100644
--- a/spec/common_stubs.lua
+++ b/spec/common_stubs.lua
@@ -2,18 +2,49 @@
local common_stubs = {}
function common_stubs.setup_G_RLF(spy)
+ _G.unpack = table.unpack
+ _G.handledError = function(err)
+ print("\n")
+ print(err)
+ print("The above error was thrown during a test and caught by xpcall")
+ print("This is usually indicative of an issue, or an improperly mocked test")
+ print("\n")
+ return false
+ end
+ local logger = {
+ Debug = spy.new(),
+ Info = spy.new(),
+ Warn = spy.new(),
+ Error = spy.new(),
+ }
_G.G_RLF = {
db = {
global = {
currencyFeed = true,
+ factionMaps = {},
},
},
LootDisplay = {
ShowLoot = function() end,
},
+ list = function()
+ return {}
+ end,
RLF = {
- NewModule = function()
- return {}
+ NewModule = function(_, name, libs)
+ return {
+ moduleName = name,
+ getLogger = function(self)
+ return logger
+ end,
+ Enable = function() end,
+ Disable = function() end,
+ fn = function(s, func, ...)
+ if type(func) == "function" then
+ return xpcall(func, _G.handledError, ...)
+ end
+ end,
+ }
end,
},
fn = function(_, func, ...)
@@ -22,9 +53,12 @@ function common_stubs.setup_G_RLF(spy)
Print = function(msg) end,
}
+ _G.GetLocale = function()
+ return "enUS"
+ end
+
-- Spy or stub common methods if needed
spy.on(_G.G_RLF.LootDisplay, "ShowLoot")
- spy.on(_G.G_RLF.LootDisplay, "ShowXP")
end
function common_stubs.stub_C_CurrencyInfo()
@@ -42,6 +76,48 @@ function common_stubs.stub_C_CurrencyInfo()
}
end
+function common_stubs.stub_C_Reputation()
+ _G.ACCOUNT_WIDE_FONT_COLOR = { r = 0, g = 0, b = 1 }
+ _G.FACTION_GREEN_COLOR = { r = 0, g = 1, b = 0 }
+ _G.FACTION_BAR_COLORS = {
+ [1] = { r = 1, g = 0, b = 0 },
+ }
+ _G.FACTION_STANDING_INCREASED = "Rep with %s inc by %d."
+ _G.FACTION_STANDING_INCREASED_ACCOUNT_WIDE = "AccRep with %s inc by %d."
+ _G.FACTION_STANDING_INCREASED_ACH_BONUS = "Rep with %s inc by %d (+.1f bonus)."
+ _G.FACTION_STANDING_INCREASED_ACH_BONUS_ACCOUNT_WIDE = "AccRep with %s inc by %d (+.1f bonus)."
+ _G.FACTION_STANDING_INCREASED_BONUS = "Rep with %s inc by %d (+.1f bonus)."
+ _G.FACTION_STANDING_INCREASED_DOUBLE_BONUS = "Rep with %s inc by %d (+.1f bonus)."
+ _G.FACTION_STANDING_DECREASED = "Rep with %s dec by %d."
+ _G.FACTION_STANDING_DECREASED_ACCOUNT_WIDE = "AccRep with %s dec by %d."
+ _G.C_Reputation = {
+ GetNumFactions = function()
+ return 1
+ end,
+ GetFactionDataByIndex = function()
+ return {
+ name = "Faction A",
+ factionID = 1,
+ }
+ end,
+ GetFactionDataByID = function(id)
+ if id == 1 then
+ return {
+ name = "Faction A",
+ factionID = 1,
+ reaction = 1,
+ }
+ end
+ end,
+ IsMajorFaction = function()
+ return false
+ end,
+ IsFactionParagon = function()
+ return false
+ end,
+ }
+end
+
function common_stubs.stub_Unit_Funcs()
_G.UnitLevel = function()
return 2
@@ -54,4 +130,10 @@ function common_stubs.stub_Unit_Funcs()
end
end
+function common_stubs.stub_Money_Funcs()
+ _G.GetMoney = function()
+ return 123456
+ end
+end
+
return common_stubs