You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
334 lines
12 KiB
334 lines
12 KiB
local ADDON, Addon = ...
|
|
local Mod = Addon:NewModule('ProgressTracker')
|
|
Mod.playerDeaths = {}
|
|
|
|
local lastQuantity
|
|
local lastDied
|
|
local lastDiedName
|
|
local lastDiedTime
|
|
local lastAmount
|
|
local lastAmountTime
|
|
local lastQuantity
|
|
|
|
local PRIDEFUL_AFFIX_ID = 121
|
|
|
|
local progressPresets = {}
|
|
|
|
local function ProcessLasts()
|
|
if lastDied and lastDiedTime and lastAmount and lastAmountTime then
|
|
if abs(lastAmountTime - lastDiedTime) < 0.1 then
|
|
if not AngryKeystones_Data.progress[lastDied] then AngryKeystones_Data.progress[lastDied] = {} end
|
|
if AngryKeystones_Data.progress[lastDied][lastAmount] then
|
|
AngryKeystones_Data.progress[lastDied][lastAmount] = AngryKeystones_Data.progress[lastDied][lastAmount] + 1
|
|
else
|
|
AngryKeystones_Data.progress[lastDied][lastAmount] = 1
|
|
end
|
|
lastDied, lastDiedTime, lastAmount, lastAmountTime, lastDiedName = nil, nil, nil, nil, nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function Mod:COMBAT_LOG_EVENT_UNFILTERED()
|
|
local timestamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, spellID, spellName, spellSchool, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10 = CombatLogGetCurrentEventInfo()
|
|
if event == "UNIT_DIED" then
|
|
if bit.band(destFlags, COMBATLOG_OBJECT_TYPE_NPC) > 0
|
|
and bit.band(destFlags, COMBATLOG_OBJECT_CONTROL_NPC) > 0
|
|
and (bit.band(destFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) > 0 or bit.band(destFlags, COMBATLOG_OBJECT_REACTION_NEUTRAL) > 0) then
|
|
local type, zero, server_id, instance_id, zone_uid, npc_id, spawn_uid = strsplit("-", destGUID)
|
|
lastDied = tonumber(npc_id)
|
|
lastDiedTime = GetTime()
|
|
lastDiedName = destName
|
|
ProcessLasts()
|
|
end
|
|
if bit.band(destFlags, COMBATLOG_OBJECT_TYPE_PLAYER) > 0 then
|
|
if UnitIsFeignDeath(destName) then
|
|
-- Feign Death
|
|
elseif Mod.playerDeaths[destName] then
|
|
Mod.playerDeaths[destName] = Mod.playerDeaths[destName] + 1
|
|
else
|
|
Mod.playerDeaths[destName] = 1
|
|
end
|
|
--Addon.ObjectiveTracker:UpdatePlayerDeaths()
|
|
end
|
|
end
|
|
end
|
|
|
|
function Mod:SCENARIO_CRITERIA_UPDATE()
|
|
local scenarioType = select(10, C_Scenario.GetInfo())
|
|
if scenarioType == LE_SCENARIO_TYPE_CHALLENGE_MODE then
|
|
local numCriteria = select(3, C_Scenario.GetStepInfo())
|
|
for criteriaIndex = 1, numCriteria do
|
|
local criteriaString, criteriaType, _, quantity, totalQuantity, _, _, quantityString, _, _, _, _, isWeightedProgress = C_Scenario.GetCriteriaInfo(criteriaIndex)
|
|
if isWeightedProgress then
|
|
local currentQuantity = quantityString and tonumber( strsub(quantityString, 1, -2) )
|
|
if lastQuantity and currentQuantity < totalQuantity and currentQuantity > lastQuantity then
|
|
lastAmount = currentQuantity - lastQuantity
|
|
lastAmountTime = GetTime()
|
|
ProcessLasts()
|
|
end
|
|
lastQuantity = currentQuantity
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function StartTime()
|
|
Mod:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
|
local numCriteria = select(3, C_Scenario.GetStepInfo())
|
|
for criteriaIndex = 1, numCriteria do
|
|
local criteriaString, criteriaType, _, quantity, totalQuantity, _, _, quantityString, _, _, _, _, isWeightedProgress = C_Scenario.GetCriteriaInfo(criteriaIndex)
|
|
if isWeightedProgress then
|
|
local quantityString = select(8, C_Scenario.GetCriteriaInfo(criteriaIndex))
|
|
lastQuantity = quantityString and tonumber( strsub(quantityString, 1, -2) )
|
|
end
|
|
end
|
|
end
|
|
|
|
local function StopTime()
|
|
Mod:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
|
end
|
|
|
|
local function CheckTime(...)
|
|
for i = 1, select("#", ...) do
|
|
local timerID = select(i, ...)
|
|
local _, elapsedTime, type = GetWorldElapsedTime(timerID)
|
|
if type == LE_WORLD_ELAPSED_TIMER_TYPE_CHALLENGE_MODE then
|
|
local mapID = C_ChallengeMode.GetActiveChallengeMapID()
|
|
if mapID then
|
|
StartTime()
|
|
return
|
|
end
|
|
end
|
|
end
|
|
StopTime()
|
|
end
|
|
|
|
local function OnTooltipSetUnit(tooltip)
|
|
local scenarioType = select(10, C_Scenario.GetInfo())
|
|
if scenarioType == LE_SCENARIO_TYPE_CHALLENGE_MODE and Addon.Config.progressTooltip then
|
|
local name, unit = tooltip:GetUnit()
|
|
local guid = unit and UnitGUID(unit)
|
|
if guid then
|
|
local type, zero, server_id, instance_id, zone_uid, npc_id, spawn_uid = strsplit("-", guid)
|
|
npc_id = tonumber(npc_id)
|
|
local info = AngryKeystones_Data.progress[npc_id]
|
|
local preset = progressPresets[npc_id]
|
|
if info or preset then
|
|
local numCriteria = select(3, C_Scenario.GetStepInfo())
|
|
local total
|
|
local progressName
|
|
for criteriaIndex = 1, numCriteria do
|
|
local criteriaString, _, _, quantity, totalQuantity, _, _, quantityString, _, _, _, _, isWeightedProgress = C_Scenario.GetCriteriaInfo(criteriaIndex)
|
|
if isWeightedProgress then
|
|
progressName = criteriaString
|
|
total = totalQuantity
|
|
end
|
|
end
|
|
|
|
local value, valueCount
|
|
if info then
|
|
for amount, count in pairs(info) do
|
|
if not valueCount or count > valueCount or (count == valueCount and amount < value) then
|
|
value = amount
|
|
valueCount = count
|
|
end
|
|
end
|
|
end
|
|
if preset and (not value or valueCount == 1) then
|
|
value = preset
|
|
end
|
|
if value and total then
|
|
local forcesFormat = format(" - %s: %%s", progressName)
|
|
local text
|
|
if Addon.Config.progressFormat == 1 or Addon.Config.progressFormat == 4 then
|
|
text = format( format(forcesFormat, "+%.2f%%"), value/total*100)
|
|
elseif Addon.Config.progressFormat == 2 or Addon.Config.progressFormat == 5 then
|
|
text = format( format(forcesFormat, "+%d"), value)
|
|
elseif Addon.Config.progressFormat == 3 or Addon.Config.progressFormat == 6 then
|
|
text = format( format(forcesFormat, "+%.2f%% - +%d"), value/total*100, value)
|
|
end
|
|
|
|
if text then
|
|
local matcher = format(forcesFormat, "%d+%%")
|
|
for i=2, tooltip:NumLines() do
|
|
local tiptext = _G["GameTooltipTextLeft"..i]
|
|
local linetext = tiptext and tiptext:GetText()
|
|
|
|
if linetext and linetext:match(matcher) then
|
|
tiptext:SetText(text)
|
|
tooltip:Show()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Mod:GeneratePreset()
|
|
local ret = {}
|
|
for npcID, info in pairs(AngryKeystones_Data.progress) do
|
|
local value, valueCount
|
|
for amount, count in pairs(info) do
|
|
if not valueCount or count > valueCount or (count == valueCount and amount < value) then
|
|
value = amount
|
|
valueCount = count
|
|
end
|
|
end
|
|
ret[npcID] = value
|
|
end
|
|
AngryKeystones_Data.preset = ret
|
|
return ret
|
|
end
|
|
|
|
function Mod:PLAYER_ENTERING_WORLD(...) CheckTime(GetWorldElapsedTimers()) end
|
|
function Mod:WORLD_STATE_TIMER_START(...) local timerID = ...; CheckTime(timerID) end
|
|
function Mod:WORLD_STATE_TIMER_STOP(...) local timerID = ...; StopTime(timerID) end
|
|
function Mod:CHALLENGE_MODE_START(...) CheckTime(GetWorldElapsedTimers()) end
|
|
function Mod:CHALLENGE_MODE_RESET(...) wipe(Mod.playerDeaths) end
|
|
|
|
local function ProgressBar_SetValue(self, percent)
|
|
if self.criteriaIndex then
|
|
local _, _, _, _, totalQuantity, _, _, quantityString, _, _, _, _, _ = C_Scenario.GetCriteriaInfo(self.criteriaIndex)
|
|
local currentQuantity = quantityString and tonumber( strsub(quantityString, 1, -2) )
|
|
if currentQuantity and totalQuantity then
|
|
if Addon.Config.progressFormat == 1 then
|
|
self.Bar.Label:SetFormattedText("%.2f%%", currentQuantity/totalQuantity*100)
|
|
elseif Addon.Config.progressFormat == 2 then
|
|
self.Bar.Label:SetFormattedText("%d/%d", currentQuantity, totalQuantity)
|
|
elseif Addon.Config.progressFormat == 3 then
|
|
self.Bar.Label:SetFormattedText("%.2f%% - %d/%d", currentQuantity/totalQuantity*100, currentQuantity, totalQuantity)
|
|
elseif Addon.Config.progressFormat == 4 then
|
|
self.Bar.Label:SetFormattedText("%.2f%% (%.2f%%)", currentQuantity/totalQuantity*100, (totalQuantity-currentQuantity)/totalQuantity*100)
|
|
elseif Addon.Config.progressFormat == 5 then
|
|
self.Bar.Label:SetFormattedText("%d/%d (%d)", currentQuantity, totalQuantity, totalQuantity - currentQuantity)
|
|
elseif Addon.Config.progressFormat == 6 then
|
|
self.Bar.Label:SetFormattedText("%.2f%% (%.2f%%) - %d/%d (%d)", currentQuantity/totalQuantity*100, (totalQuantity-currentQuantity)/totalQuantity*100, currentQuantity, totalQuantity, totalQuantity - currentQuantity)
|
|
end
|
|
end
|
|
|
|
local isPridefulActive = false
|
|
local _, affixes = C_ChallengeMode.GetActiveKeystoneInfo()
|
|
if affixes then
|
|
for i = 1, #affixes do
|
|
if affixes[i] == PRIDEFUL_AFFIX_ID then
|
|
isPridefulActive = true
|
|
end
|
|
end
|
|
end
|
|
|
|
if isPridefulActive and currentQuantity < totalQuantity then
|
|
if not self.ReapingFrame then
|
|
local reapingFrame = CreateFrame("Frame", nil, self)
|
|
reapingFrame:SetSize(56, 16)
|
|
reapingFrame:SetPoint("BOTTOMRIGHT", self, "TOPRIGHT", 0, 0)
|
|
|
|
reapingFrame.Icon = CreateFrame("Frame", nil, reapingFrame, "ScenarioChallengeModeAffixTemplate")
|
|
reapingFrame.Icon:SetPoint("LEFT", reapingFrame, "LEFT", 0, 0)
|
|
reapingFrame.Icon:SetSize(16, 16)
|
|
reapingFrame.Icon.Portrait:SetSize(16, 16)
|
|
reapingFrame.Icon:SetUp(PRIDEFUL_AFFIX_ID)
|
|
|
|
reapingFrame.Text = reapingFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
|
reapingFrame.Text:SetPoint("LEFT", reapingFrame.Icon, "RIGHT", 4, 0)
|
|
|
|
self.ReapingFrame = reapingFrame
|
|
|
|
self:HookScript("OnShow", function(self) self.ReapingFrame:Show(); self.ReapingFrame.Icon:Show() end )
|
|
self:HookScript("OnHide", function(self) self.ReapingFrame:Hide(); self.ReapingFrame.Icon:Hide() end )
|
|
end
|
|
local threshold = totalQuantity / 5
|
|
local current = currentQuantity
|
|
local value = threshold - current % threshold
|
|
local total = totalQuantity
|
|
if Addon.Config.progressFormat == 1 or Addon.Config.progressFormat == 4 then
|
|
self.ReapingFrame.Text:SetFormattedText("%.2f%%", value/total*100)
|
|
elseif Addon.Config.progressFormat == 2 or Addon.Config.progressFormat == 5 then
|
|
self.ReapingFrame.Text:SetFormattedText("%d", ceil(value))
|
|
elseif Addon.Config.progressFormat == 3 or Addon.Config.progressFormat == 6 then
|
|
self.ReapingFrame.Text:SetFormattedText("%.2f%% - %d", value/total*100, ceil(value))
|
|
else
|
|
self.ReapingFrame.Text:SetFormattedText("%d%%", value/total*100)
|
|
end
|
|
self.ReapingFrame:Show()
|
|
self.ReapingFrame.Icon:Show()
|
|
elseif self.ReapingFrame then
|
|
self.ReapingFrame:Hide()
|
|
self.ReapingFrame.Icon:Hide()
|
|
end
|
|
else
|
|
if self.ReapingFrame then
|
|
self.ReapingFrame:Hide()
|
|
self.ReapingFrame.Icon:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
local function DeathCount_OnEnter(self)
|
|
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
|
|
GameTooltip:SetText(CHALLENGE_MODE_DEATH_COUNT_TITLE:format(self.count), 1, 1, 1)
|
|
GameTooltip:AddLine(CHALLENGE_MODE_DEATH_COUNT_DESCRIPTION:format(SecondsToClock(self.timeLost, false)))
|
|
|
|
GameTooltip:AddLine(" ")
|
|
local list = {}
|
|
local deathsCount = 0
|
|
for unit,count in pairs(Mod.playerDeaths) do
|
|
local _, class = UnitClass(unit)
|
|
deathsCount = deathsCount + count
|
|
table.insert(list, { count = count, unit = unit, class = class })
|
|
end
|
|
table.sort(list, function(a, b)
|
|
if a.count ~= b.count then
|
|
return a.count > b.count
|
|
else
|
|
return a.unit < b.unit
|
|
end
|
|
end)
|
|
|
|
for _,item in ipairs(list) do
|
|
local color = RAID_CLASS_COLORS[item.class] or HIGHLIGHT_FONT_COLOR
|
|
GameTooltip:AddDoubleLine(item.unit, item.count, color.r, color.g, color.b, HIGHLIGHT_FONT_COLOR:GetRGB())
|
|
end
|
|
GameTooltip:Show()
|
|
end
|
|
|
|
function Mod:Blizzard_ObjectiveTracker()
|
|
ScenarioChallengeModeBlock.DeathCount:SetScript("OnEnter", DeathCount_OnEnter)
|
|
end
|
|
|
|
function Mod:Startup()
|
|
if not AngryKeystones_Data then
|
|
AngryKeystones_Data = {}
|
|
end
|
|
if not AngryKeystones_Data.progress then
|
|
AngryKeystones_Data = { progress = AngryKeystones_Data }
|
|
end
|
|
if not AngryKeystones_Data.state then AngryKeystones_Data.state = {} end
|
|
local mapID = C_ChallengeMode.GetActiveChallengeMapID()
|
|
if select(10, C_Scenario.GetInfo()) == LE_SCENARIO_TYPE_CHALLENGE_MODE and mapID and mapID == AngryKeystones_Data.state.mapID and AngryKeystones_Data.state.playerDeaths then
|
|
Mod.playerDeaths = AngryKeystones_Data.state.playerDeaths
|
|
else
|
|
AngryKeystones_Data.state.mapID = nil
|
|
AngryKeystones_Data.state.playerDeaths = Mod.playerDeaths
|
|
end
|
|
|
|
self:RegisterEvent("SCENARIO_CRITERIA_UPDATE")
|
|
self:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
self:RegisterEvent("WORLD_STATE_TIMER_START")
|
|
self:RegisterEvent("WORLD_STATE_TIMER_STOP")
|
|
self:RegisterEvent("CHALLENGE_MODE_START")
|
|
self:RegisterEvent("CHALLENGE_MODE_RESET")
|
|
self:RegisterAddOnLoaded("Blizzard_ObjectiveTracker")
|
|
CheckTime(GetWorldElapsedTimers())
|
|
TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Unit, OnTooltipSetUnit)
|
|
|
|
Addon.Config:RegisterCallback('progressFormat', function()
|
|
local usedBars = SCENARIO_TRACKER_MODULE.usedProgressBars[ScenarioObjectiveBlock] or {}
|
|
for _, bar in pairs(usedBars) do
|
|
ProgressBar_SetValue(bar)
|
|
end
|
|
end)
|
|
end
|
|
|
|
hooksecurefunc("ScenarioTrackerProgressBar_SetValue", ProgressBar_SetValue)
|
|
|