Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.5.2 #91

Merged
merged 3 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Features/Currency.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function Currency:CURRENCY_DISPLAY_UPDATE(_, ...)
end

local info = C_CurrencyInfo.GetCurrencyInfo(currencyType)
if info == nil or info.description == "" then
if info == nil or info.description == "" or info.iconFileID == nil then
return
end

Expand Down
251 changes: 98 additions & 153 deletions Features/Reputation.lua
Original file line number Diff line number Diff line change
@@ -1,195 +1,140 @@
local Rep = G_RLF.RLF:NewModule("Reputation", "AceEvent-3.0")

local repData = {}
local paragonRepData = {}
local majorRepData = {}
local cachedFactionCount
local showLegacyReps
local firstNilIndex = 1
local Rep = G_RLF.RLF:NewModule("Reputation", "AceEvent-3.0", "AceTimer-3.0")

local locale
function Rep:OnInitialize()
locale = GetLocale()
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
self:Enable()
else
self:Disable()
end
end

local function snapshot()
showLegacyReps = C_Reputation.AreLegacyReputationsShown()
local function countMappedFactions()
local count = 0
local i = 1
local factionData = C_Reputation.GetFactionDataByIndex(i)
while factionData ~= nil do
if not factionData.isHeader or factionData.isHeaderWithRep then
if C_Reputation.IsFactionParagon(factionData.factionID) then
-- Need to support Paragon factions
local value, max = C_Reputation.GetFactionParagonInfo(factionData.factionID)
paragonRepData[factionData.factionID] = value
elseif C_Reputation.IsMajorFaction(factionData.factionID) then
-- Need to support Major factions
local majorFactionData = C_MajorFactions.GetMajorFactionData(factionData.factionID)
local level = majorFactionData.renownLevel
local rep = majorFactionData.renownReputationEarned
local max = majorFactionData.renownLevelThreshold
majorRepData[factionData.factionID] = { level, rep, max }
else
repData[factionData.factionID] = factionData.currentStanding
end
for k, v in pairs(G_RLF.db.global.factionMaps[locale]) do
if v then
count = count + 1
end
i = i + 1
factionData = C_Reputation.GetFactionDataByIndex(i)
end

firstNilIndex = i
cachedFactionCount = count
end

function Rep:OnDisable()
self:UnregisterEvent("PLAYER_ENTERING_WORLD")
self:UnregisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
self:UnregisterEvent("MAJOR_FACTION_RENOWN_LEVEL_CHANGED")
return count
end

function Rep:OnEnable()
self:RegisterEvent("PLAYER_ENTERING_WORLD")
self:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
self:RegisterEvent("MAJOR_FACTION_RENOWN_LEVEL_CHANGED")
if showLegacyReps == nil then
snapshot()
end
end

local function initializeParagonFaction(fId)
if not paragonRepData[fId] then
paragonRepData[fId] = 0
local function buildFactionLocaleMap(findName)
local numFactions = C_Reputation.GetNumFactions()
if countMappedFactions() == numFactions and not findName then
return
end
end

local function initializeMajorFaction(fId, mfd)
if not majorRepData[fId] then
local level = mfd.renownLevel
local max = mfd.renownLevelThreshold
majorRepData[fId] = { level, 0, max }
for i = 1, numFactions do
local factionData = C_Reputation.GetFactionDataByIndex(i)
if factionData then
if not G_RLF.db.global.factionMaps[locale][factionData.name] then
G_RLF.db.global.factionMaps[locale][factionData.name] = factionData.factionID
end
if findName and factionData.name == findName then
break
end
end
end
end

local function initializeNormalFaction(fId)
if not repData[fId] then
repData[fId] = 0
-- Function to extract faction and reputation change using precomputed patterns
local function extractFactionAndRep(message, patterns)
for _, segments in ipairs(patterns) do
local prePattern, midPattern, postPattern = unpack(segments)
local preMatchStart, preMatchEnd = string.find(message, prePattern, 1, true)
if preMatchStart then
local msgLoop = message:sub(preMatchEnd + 1)
local midMatchStart, midMatchEnd = string.find(msgLoop, midPattern, 1, true)
if midMatchStart then
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)
return faction, tonumber(rep)
end
end
end
end
return nil, nil
end

local function initializeRepFaction(fId)
if C_Reputation.IsFactionParagon(fId) then
initializeParagonFaction(fId)
elseif C_Reputation.IsMajorFaction(fId) then
local mfd = C_MajorFactions.GetMajorFactionData(fId)
initializeMajorFaction(fId, mfd)
else
initializeNormalFaction(fId)
-- Precompute pattern segments to optimize runtime message parsing
local function precomputePatternSegments(patterns)
local computedPatterns = {}
for _, pattern in ipairs(patterns) do
local preStart, preEnd = string.find(pattern, "%%s")
local prePattern = string.sub(pattern, 1, preStart - 1)
local midStart, midEnd = string.find(pattern, "%%d", preEnd + 1)
local midPattern = string.sub(pattern, preEnd + 1, midStart - 1)
local postPattern = string.sub(pattern, midEnd + 1)
table.insert(computedPatterns, { prePattern, midPattern, postPattern })
end
return computedPatterns
end

local function handleMajorFactionRepChange(id, level)
local factionData = C_Reputation.GetFactionDataByID(id)
local majorFactionData = C_MajorFactions.GetMajorFactionData(id)
local level = level or C_MajorFactions.GetCurrentRenownLevel(id)
local rep = majorFactionData.renownReputationEarned
local max = majorFactionData.renownLevelThreshold
local oldLevel, oldRep, oldMax = unpack(majorRepData[id])
local increasePatterns = precomputePatternSegments({
FACTION_STANDING_INCREASED,
FACTION_STANDING_INCREASED_ACCOUNT_WIDE,
FACTION_STANDING_INCREASED_ACH_BONUS,
FACTION_STANDING_INCREASED_ACH_BONUS_ACCOUNT_WIDE,
FACTION_STANDING_INCREASED_BONUS,
FACTION_STANDING_INCREASED_DOUBLE_BONUS,
})

if rep > oldRep then
G_RLF.LootDisplay:ShowRep(rep - oldRep, factionData)
elseif rep < oldRep then
G_RLF.LootDisplay:ShowRep(oldMax - oldRep + rep, factionData)
elseif rep == oldRep and level > oldLevel then
G_RLF.LootDisplay:ShowRep(oldMax - oldRep + rep, factionData)
end
majorRepData[id] = { level, rep, max }
end
local decreasePatterns = precomputePatternSegments({
FACTION_STANDING_DECREASED,
FACTION_STANDING_DECREASED_ACCOUNT_WIDE,
})

local function factionListHasNotChanged()
return C_Reputation.GetFactionDataByIndex(firstNilIndex) == nil -- if a new index hasn't been added
and firstNilIndex > 1 -- we had at least 1 faction before
and C_Reputation.GetFactionDataByIndex(firstNilIndex - 1) -- the previous faction is still not nil
and showLegacyReps == C_Reputation.AreLegacyReputationsShown() -- Showing Legacy Reputations hasn't changed
end

local function addAnyNewFactions()
if factionListHasNotChanged() then
-- No new factions, skipping
return
end

showLegacyReps = C_Reputation.AreLegacyReputationsShown()

local i = 1
local factionData = C_Reputation.GetFactionDataByIndex(i)
while factionData ~= nil do
if not factionData.isHeader or factionData.isHeaderWithRep then
local fId = factionData.factionID
initializeRepFaction(fId)
end
i = i + 1
factionData = C_Reputation.GetFactionDataByIndex(i)
end

firstNilIndex = i
function Rep:OnDisable()
self:UnregisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
end

function Rep:PLAYER_ENTERING_WORLD()
G_RLF:fn(snapshot)
function Rep:OnEnable()
self:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
end

local function findDelta()
addAnyNewFactions()

if G_RLF.db.global.repFeed then
-- Normal rep factions
for k, v in pairs(repData) do
local factionData = C_Reputation.GetFactionDataByID(k)
if factionData.currentStanding ~= v then
G_RLF.LootDisplay:ShowRep(factionData.currentStanding - v, factionData)
repData[k] = factionData.currentStanding
function Rep:CHAT_MSG_COMBAT_FACTION_CHANGE(_, message)
G_RLF:fn(function()
local faction, repChange = extractFactionAndRep(message, increasePatterns)
if not faction then
faction, repChange = extractFactionAndRep(message, decreasePatterns)
if repChange then
repChange = -repChange
end
end
-- Paragon facions
for k, v in pairs(paragonRepData) do
local factionData = C_Reputation.GetFactionDataByID(k)
local value, max = C_Reputation.GetFactionParagonInfo(k)
if value ~= v then
-- Not thoroughly tested
if v == max then
-- We were at paragon cap, then the reward was obtained, so we started back at 0
G_RLF.LootDisplay:ShowRep(value, factionData)
else
G_RLF.LootDisplay:ShowRep(value - v, factionData)
local r, g, b, color
if G_RLF.db.global.factionMaps[locale][faction] == nil then
-- attempt to find the missing faction's ID
buildFactionLocaleMap(faction)
end

if G_RLF.db.global.factionMaps[locale][faction] then
local fId = G_RLF.db.global.factionMaps[locale][faction]
if C_Reputation.IsMajorFaction(fId) then
color = ACCOUNT_WIDE_FONT_COLOR
elseif C_Reputation.IsFactionParagon(fId) then
color = FACTION_GREEN_COLOR
else
local factionData = C_Reputation.GetFactionDataByID(fId)
if factionData.reaction then
color = FACTION_BAR_COLORS[factionData.reaction]
end
paragonRepData[k] = value
end
end
-- Major factions
for k, v in pairs(majorRepData) do
-- Delay in case the rep change caused a level up,
-- the level up event should take precedent.
C_Timer.After(0.5, function()
handleMajorFactionRepChange(k)
end)
end
end
end

function Rep:MAJOR_FACTION_RENOWN_LEVEL_CHANGED(_, mfID, newLevel, oldLevel)
G_RLF:fn(addAnyNewFactions)
G_RLF:fn(initializeMajorFaction, mfID)

G_RLF:fn(handleMajorFactionRepChange, mfID, newLevel)
end
if color then
r, g, b = color.r, color.g, color.b
end

function Rep:CHAT_MSG_COMBAT_FACTION_CHANGE()
G_RLF:fn(findDelta)
if faction and repChange then
G_RLF.LootDisplay:ShowRep(repChange, faction, r, g, b)
end
end)
end

return Rep
21 changes: 4 additions & 17 deletions LootDisplay.lua
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ function LootDisplay:ShowXP(experience)
row.fadeOutAnimation:Play()
end

function LootDisplay:ShowRep(rep, factionData)
local key = "REP_" .. factionData.factionID -- Use ID as a unique key
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
Expand All @@ -262,22 +262,9 @@ function LootDisplay:ShowRep(rep, factionData)
if rep < 0 then
sign = "-"
end
text = sign .. math.abs(row.rep) .. " " .. factionData.name
text = sign .. math.abs(row.rep) .. " " .. factionName
row.amountText:SetText(text)
local r, g, b
if
factionData.reaction
and not C_Reputation.IsFactionParagon(factionData.factionID)
and not C_Reputation.IsMajorFaction(factionData.factionID)
then
r = FACTION_BAR_COLORS[factionData.reaction].r
g = FACTION_BAR_COLORS[factionData.reaction].g
b = FACTION_BAR_COLORS[factionData.reaction].b
else
r = 0.26
g = 1
b = 1
end
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()
Expand Down
10 changes: 5 additions & 5 deletions config/Positioning.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ G_RLF.defaults.global.frameStrata = "MEDIUM" -- Default frame strata
-- Enumerate available frames to anchor to
local function EnumerateFrames()
local frames = {
[-1] = "Screen",
[-1] = G_RLF.L["Screen"],
}
local framesToCheck = {
["UIParent"] = "UIParent",
["PlayerFrame"] = "PlayerFrame",
["Minimap"] = "Minimap",
["MainMenuBarBackpackButton"] = "BagBar",
["UIParent"] = G_RLF.L["UIParent"],
["PlayerFrame"] = G_RLF.L["PlayerFrame"],
["Minimap"] = G_RLF.L["Minimap"],
["MainMenuBarBackpackButton"] = G_RLF.L["BagBar"],
}
for f, s in pairs(framesToCheck) do
if _G[f] then
Expand Down
5 changes: 5 additions & 0 deletions locale/enUS.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ L["Drag to Move"] = true
L["PositioningDesc"] = "Position and anchor the loot feed."
L["Anchor Relative To"] = true
L["RelativeToDesc"] = "Select a frame to anchor the loot feed to"
L["Screen"] = true
L["UIParent"] = true
L["PlayerFrame"] = true
L["Minimap"] = true
L["BagBar"] = true
L["Anchor Point"] = true
L["AnchorPointDesc"] = "Where on the screen to base the loot feed positioning (also impacts sizing direction)"
L["Top Left"] = true
Expand Down
Loading
Loading