Skip to content

Commit

Permalink
Add health syncing mod for Ashenvale (#120)
Browse files Browse the repository at this point in the history
The changes to the health tracker are a bit messy, but it works.
Would be nicer to refactor it into a proper object some time.

Also indirectly improves other mods using the health tracker (Alterac)
because the list is now sorted by config and shows bosses prior to first
sync.
  • Loading branch information
emmericp authored Dec 11, 2023
1 parent a97c2c5 commit 2a4ebbf
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ globals = {
"C_GossipInfo",
"C_Map",
"C_PvP",
"C_Seasons",
"C_Timer",
"C_UIWidgetManager",
"C_VignetteInfo",
"CompleteQuest",
"CreateFrame",
"Enum",
"GetBattlefieldInstanceRunTime",
"GetCurrencyInfo",
"GetItemCount",
Expand Down
89 changes: 89 additions & 0 deletions DBM-PvP/Ashenvale.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
if WOW_PROJECT_ID ~= WOW_PROJECT_CLASSIC or not C_Seasons or C_Seasons.GetActiveSeason() < 2 then
return
end
local MAP_ASHENVALE = 1440
local mod = DBM:NewMod("m" .. MAP_ASHENVALE, "DBM-PvP")

mod:SetRevision("@file-date-integer@")
-- TODO: we could teach this thing to handle outdoor zones instead of only instances
-- when implementing this make sure that the stop functions are called properly, i.e., that ZONE_CHANGED_NEW_AREA still fires when leaving
mod:SetZone(DBM_DISABLE_ZONE_DETECTION)
mod:RegisterEvents(
"LOADING_SCREEN_DISABLED",
"ZONE_CHANGED_NEW_AREA",
"PLAYER_ENTERING_WORLD",
"UPDATE_UI_WIDGET"
)

local widgetIDs = {
[5360] = true, -- Alliance progress
[5361] = true, -- Horde progress
[5367] = true, -- Alliance bosses remaining
[5368] = true, -- Horde bosses remaining
[5378] = true, -- Event time remaining
}

function mod:StartEvent()
DBM:Debug("Detected start of Ashenvale event")
local generalMod = DBM:GetModByName("PvPGeneral")
generalMod:StopTrackHealth()
generalMod:TrackHealth(212804, "RunestoneBoss", true, "YELL")
generalMod:TrackHealth(212707, "GlaiveBoss", true, "YELL")
generalMod:TrackHealth(212803, "ResearchBoss", true, "YELL")
generalMod:TrackHealth(212970, "MoonwellBoss", true, "YELL")
generalMod:TrackHealth(212801, "ShredderBoss", true, "YELL")
generalMod:TrackHealth(212730, "CatapultBoss", true, "YELL")
generalMod:TrackHealth(212802, "LumberBoss", true, "YELL")
generalMod:TrackHealth(212969, "BonfireBoss", true, "YELL")
end

function mod:StopEvent()
DBM:Debug("Detected end of Ashenvale event or leaving zone")
local generalMod = DBM:GetModByName("PvPGeneral")
generalMod:StopTrackHealth()
end

function mod:CheckEventState()
local eventTime = C_UIWidgetManager.GetIconAndTextWidgetVisualizationInfo(5378)
if eventTime and eventTime.state ~= Enum.IconAndTextWidgetState.Hidden then
if not self.eventRunning then
self.eventRunning = true
self:StartEvent()
end
elseif self.eventRunning then
self.eventRunning = false
self:StopEvent()
end
end

function mod:UPDATE_UI_WIDGET(tbl)
if not self.inZone then
return
end
if tbl and widgetIDs[tbl.widgetID] then
self:CheckEventState()
end
end

function mod:EnterAshenvale()
self.inZone = true
self:CheckEventState()
end

function mod:LeaveAshenvale()
self.inZone = false
self:StopEvent()
end

function mod:ZoneChanged()
local map = C_Map.GetBestMapForUnit("player")
if map == MAP_ASHENVALE and not self.inZone then
self:EnterAshenvale()
elseif map ~= MAP_ASHENVALE and self.inZone then
self:LeaveAshenvale()
end
end
mod.LOADING_SCREEN_DISABLED = mod.ZoneChanged
mod.ZONE_CHANGED_NEW_AREA = mod.ZoneChanged
mod.PLAYER_ENTERING_WORLD = mod.ZoneChanged
mod.OnInitialize = mod.ZoneChanged
1 change: 1 addition & 0 deletions DBM-PvP/DBM-PvP.toc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ localization.tw.lua

PvPGeneral.lua

Ashenvale.lua
Battlegrounds\Alterac.lua
Battlegrounds\Arathi.lua
Battlegrounds\Deepwind.lua
Expand Down
58 changes: 45 additions & 13 deletions DBM-PvP/PvPGeneral.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,50 +118,72 @@ do
end

do
local pairs, strsplit, tostring, format, twipe = pairs, strsplit, tostring, string.format, table.wipe
local strsplit, format, twipe = strsplit, string.format, table.wipe
local UnitGUID, UnitHealth, UnitHealthMax, SendAddonMessage, RegisterAddonMessagePrefix, IsAddonMessagePrefixRegistered, NewTicker = UnitGUID, UnitHealth, UnitHealthMax, C_ChatInfo.SendAddonMessage, C_ChatInfo.RegisterAddonMessagePrefix, C_ChatInfo.IsAddonMessagePrefixRegistered, C_Timer.NewTicker
local healthScan, trackedUnits, trackedUnitsCount, syncTrackedUnits = nil, {}, 0, {}
local healthScan, trackedUnits, trackedUnitsCount, syncTrackedUnits, sortedTrackedUnits = nil, {}, 0, {}, {}

local function UpdateInfoFrame()
local lines, sortedLines = {}, {}
for cid, health in pairs(syncTrackedUnits) do
if trackedUnits[cid] then
lines[trackedUnits[cid]] = health .. "%"
sortedLines[#sortedLines + 1] = trackedUnits[cid]
for _, cid in ipairs(sortedTrackedUnits) do
local health = syncTrackedUnits[cid]
local hp = health and health.hp or 100
local lastUpdate = GetTime() - (health and health.time or 0)
if lastUpdate < 60 then
lines[trackedUnits[cid]] = ("%d%%"):format(hp)
else
lines[trackedUnits[cid]] = ("(stale) %d%%"):format(hp)
end
sortedLines[#sortedLines + 1] = trackedUnits[cid]
end
return lines, sortedLines
end

local scanTargetsRaid = {"target"}
local scanTargetsWithNameplates = {"target"}
for i = 1, 40 do
scanTargetsRaid[#scanTargetsRaid + 1] = "raid" .. i .. "target"
scanTargetsWithNameplates[#scanTargetsWithNameplates + 1] = "raid" .. i .. "target"
scanTargetsWithNameplates[#scanTargetsWithNameplates + 1] = "nameplate" .. i
end

local function sendSync(cid, hp)
hp = math.floor(hp + 0.5)
if not syncTrackedUnits[cid] or syncTrackedUnits[cid].hp ~= hp then
SendAddonMessage("DBM-PvP", format("%s:%d", cid, hp), mod.syncChannel)
end
end

local function HealthScanFunc()
local syncs, syncCount = {}, 0
for i = 1, 40 do
for _, target in ipairs(mod.scanNameplates and scanTargetsWithNameplates or scanTargetsRaid) do
if syncCount >= trackedUnitsCount then -- We've already scanned all our tracked units, exit out to save CPU
break
end
local target = "raid" .. i .. "target"
local guid = UnitGUID(target)
if guid then
local cid = mod:GetCIDFromGUID(guid)
if trackedUnits[cid] and not syncs[cid] then
syncs[cid] = true
syncCount = syncCount + 1
SendAddonMessage("DBM-PvP", format("%s:%.1f", cid, UnitHealth(target) / UnitHealthMax(target) * 100), "INSTANCE_CHAT")
sendSync(cid, UnitHealth(target) / UnitHealthMax(target) * 100)
end
end
end
end

function mod:TrackHealth(cid, name)
function mod:TrackHealth(cid, name, scanNameplates, syncChannel)
self.scanNameplates = scanNameplates
self.syncChannel = syncChannel or "INSTANCE_CHAT"
if not healthScan then
healthScan = NewTicker(1, HealthScanFunc)
RegisterAddonMessagePrefix("DBM-PvP")
if not IsAddonMessagePrefixRegistered("Capping") then
RegisterAddonMessagePrefix("Capping") -- Listen to capping for extra data
end
end
trackedUnits[tostring(cid)] = L[name] or name
trackedUnits[cid] = L[name] or name
trackedUnitsCount = trackedUnitsCount + 1
sortedTrackedUnits[#sortedTrackedUnits + 1] = cid
self:RegisterShortTermEvents("CHAT_MSG_ADDON")
if not DBM.InfoFrame:IsShown() then
DBM.InfoFrame:SetHeader(L.InfoFrameHeader)
Expand All @@ -178,16 +200,26 @@ do
trackedUnitsCount = 0
twipe(trackedUnits)
twipe(syncTrackedUnits)
twipe(sortedTrackedUnits)
self.scanNameplates = nil
self.syncChannel = nil
self:UnregisterShortTermEvents()
DBM.InfoFrame:Hide()
end

function mod:CHAT_MSG_ADDON(prefix, msg, channel)
if channel ~= "INSTANCE_CHAT" or (prefix ~= "DBM-PvP" and prefix ~= "Capping") then -- Lets listen to capping as well, for extra data.
if channel ~= self.syncChannel or (prefix ~= "DBM-PvP" and prefix ~= "Capping") then -- Lets listen to capping as well, for extra data.
return
end
local cid, hp = strsplit(":", msg)
syncTrackedUnits[cid] = hp
if cid and tonumber(cid) and hp and tonumber(hp) and tonumber(hp) >= 0 and tonumber(hp) <= 100 then
hp = tonumber(hp)
cid = tonumber(cid)
local tbl = syncTrackedUnits[cid] or {}
syncTrackedUnits[cid] = tbl
tbl.hp = math.floor(hp + 0.5)
tbl.time = GetTime()
end
end
end

Expand Down
5 changes: 4 additions & 1 deletion DBM-PvP/localization.de.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ L:SetMiscLocalization({
ExprFlagCaptured = "(.+) hat die Flagge der (%w+) errungen!",
ExprFlagReturn = "Die Flagge der (%w+) wurde von (.+) zu ihrem Stützpunkt zurückgebracht!",
Vulnerable1 = "Eure Angriffe verursachen nun schwerere Verletzungen bei Flaggenträgern!",
Vulnerable2 = "Eure Angriffe verursachen nun sehr schwere Verletzungen bei Flaggenträgern!"
Vulnerable2 = "Eure Angriffe verursachen nun sehr schwere Verletzungen bei Flaggenträgern!",
InfoFrameHeader = "[DBM] Boss HP",
HordeBoss = "Horde-Boss",
AllianceBoss = "Allianz-Boss",
})
----------------------
-- Alterac Valley --
Expand Down
12 changes: 10 additions & 2 deletions DBM-PvP/localization.en.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,22 @@ L:SetMiscLocalization({
ExprFlagReturn = "The (%w+) Flag was returned to its base by (.+)!", -- Unused
Vulnerable1 = "The flag carriers have become vulnerable to attack!",
Vulnerable2 = "The flag carriers have become increasingly vulnerable to attack!",
-- Alterac/IsleOfConquest bosses
InfoFrameHeader = "Boss Health",
-- Alterac/IsleOfConquest/Ashenvale bosses
InfoFrameHeader = "[DBM] Boss Health",
HordeBoss = "Horde Boss",
AllianceBoss = "Alliance Boss",
Galvangar = "Galvangar",
Balinda = "Balinda",
Ivus = "Ivus",
Lokholar = "Lokholar",
RunestoneBoss = "Runestone",
GlaiveBoss = "Glaive",
ResearchBoss = "Research",
MoonwellBoss = "Moonwell",
ShredderBoss = "Shredder",
CatapultBoss = "Catapult",
LumberBoss = "Lumber",
BonfireBoss = "Bonfire",
-- Ashran bosses
Tremblade = "Grand Marshall Tremblade",
Volrath = "High WArlord Volrath",
Expand Down

0 comments on commit 2a4ebbf

Please sign in to comment.