-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
5 changed files
with
113 additions
and
176 deletions.
There are no files selected for viewing
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
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
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 |
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
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
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