Skip to content

Commit 0442774

Browse files
authored
lua error fixes.
1 parent 7dea3d4 commit 0442774

6 files changed

Lines changed: 641 additions & 371 deletions

File tree

Modules/API.lua

Lines changed: 136 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,63 @@ end
3838
local eventMap = {}
3939
local BGFrame = CreateFrame("Frame", "BGFrame", nil)
4040

41+
-- In 12.0+ some UI operations (including event registration on certain frames) can be blocked during combat lockdown.
42+
local function PVPS_InCombatLockdown()
43+
return type(InCombatLockdown) == "function" and InCombatLockdown()
44+
end
45+
46+
function API:_ScheduleDeferredFlush()
47+
if self._deferredTimer == true then return end
48+
self._deferredTimer = true
49+
if type(C_Timer) == "table" and type(C_Timer.After) == "function" then
50+
C_Timer.After(0.5, function() API:_FlushDeferred() end)
51+
else
52+
-- No timer API, try next frame via OnUpdate
53+
if not self._deferredOnUpdateFrame then
54+
local f = CreateFrame("Frame")
55+
f:SetScript("OnUpdate", function()
56+
f:SetScript("OnUpdate", nil)
57+
API:_FlushDeferred()
58+
end)
59+
self._deferredOnUpdateFrame = f
60+
end
61+
end
62+
end
63+
64+
function API:_FlushDeferred()
65+
if PVPS_InCombatLockdown() then
66+
self._deferredTimer = false
67+
self:_ScheduleDeferredFlush()
68+
return
69+
end
70+
71+
self._deferredTimer = false
72+
if not self._deferred then return end
73+
local pending = self._deferred
74+
self._deferred = nil
75+
76+
-- Apply deferred registrations/unregistrations now that combat lockdown is over.
77+
for _, op in ipairs(pending) do
78+
if op.action == "reg" then
79+
pcall(function() BGFrame:RegisterEvent(op.event) end)
80+
elseif op.action == "unreg" then
81+
pcall(function() BGFrame:UnregisterEvent(op.event) end)
82+
end
83+
end
84+
end
85+
86+
4187
BGFrame:SetScript("OnEvent", function(frame, event, ...)
42-
for k, v in pairs(eventMap[event]) do
43-
if type(v) == "function" then
44-
v(event, ...)
45-
else
46-
k[v](k, event, ...)
47-
end
88+
local map = eventMap[event]
89+
if not map then return end
90+
for k, v in pairs(map) do
91+
if type(v) == "function" then
92+
v(event, ...)
93+
else
94+
k[v](k, event, ...)
4895
end
49-
end)
96+
end
97+
end)
5098

5199

52100
function API:ShowRegisteredEvents()
@@ -74,6 +122,14 @@ function API:RegisterEvent(event, func)
74122
end
75123

76124
if BGFrame then
125+
-- Avoid registering events during combat lockdown (can cause ADDON_ACTION_FORBIDDEN in 12.0+).
126+
if PVPS_InCombatLockdown() then
127+
API._deferred = API._deferred or {}
128+
table.insert(API._deferred, { action = "reg", event = event })
129+
API:_ScheduleDeferredFlush()
130+
return true
131+
end
132+
77133
BGFrame:RegisterEvent(event)
78134
if not eventMap[event] then eventMap[event] = {} end
79135
eventMap[event][self] = func or event
@@ -87,6 +143,15 @@ end
87143
function API:UnregisterEvent(event)
88144
if BGFrame and (type(event) == "string") then
89145
eventMap[event] = nil
146+
-- Avoid unregistering events during combat lockdown (can cause UI action blocked/taint warnings).
147+
if PVPS_InCombatLockdown() then
148+
API._deferred = API._deferred or {}
149+
table.insert(API._deferred, { action = "unreg", event = event })
150+
API:_ScheduleDeferredFlush()
151+
-- eventMap cleanup already done below; handler is guarded against nil eventMap[event]
152+
return true
153+
end
154+
90155
BGFrame:UnregisterEvent(event)
91156
return true
92157
elseif type(event) ~= "string" then
@@ -100,6 +165,17 @@ end
100165

101166
function API:UnregisterAllEvents()
102167
if BGFrame then
168+
-- Avoid unregistering events during combat lockdown.
169+
if PVPS_InCombatLockdown() then
170+
API._deferred = API._deferred or {}
171+
for k, _ in pairs(eventMap) do
172+
table.insert(API._deferred, { action = "unreg", event = k })
173+
eventMap[k] = nil
174+
end
175+
API:_ScheduleDeferredFlush()
176+
return true
177+
end
178+
103179
for k, v in pairs(eventMap) do
104180
BGFrame:UnregisterEvent(k)
105181
eventMap[k] = nil
@@ -187,7 +263,8 @@ function API:LoadModules(CurrentZoneId, InstanceType, CurrentInstId)
187263
PVPSound:Debug("alternative loading")
188264
for _, mod in pairs(PVPSound.modules) do
189265
PVPSound:Debug(" try "..mod.name.." instId: "..tostring(mod.instId).." ;cur instanceId: "..(select(8, GetInstanceInfo())))
190-
if mod.instId == CurrentInstId and not mod.loaded then
266+
local curName = select(1, GetInstanceInfo())
267+
if ((mod.instId ~= nil and mod.instId == CurrentInstId) or (curName ~= nil and mod.name ~= nil and string.lower(curName) == string.lower(mod.name))) and (mod.type == nil or mod.type == InstanceType) and not mod.loaded then
191268
PVPSound:TimerReset()
192269
PVPSound:KillersReset()
193270
mod:Initialize()
@@ -232,31 +309,62 @@ end
232309
-----------------------------------
233310
-- BG and Arena Team announcer when BG starts
234311
function API:Announce(zone)
235-
if zone == "BG" then
236-
local MyFaction
237-
-- 1 for Alliance
238-
-- 0 for Horde
239-
if PS.isRetail then
240-
MyFaction = GetBattlefieldArenaFaction()
241-
else
242-
MyFaction = UnitFactionGroup("player")
243-
if MyFaction == "Horde" then
244-
MyFaction = 0
245-
elseif MyFaction == "Alliance" then
246-
MyFaction = 1
312+
if zone == nil then return end
313+
if PS_Announce == false then return end
314+
if AnnouncePlayed == true then return end
315+
316+
-- Determine "effective" faction for the current match.
317+
-- In 12.0+ (cross-faction / merc mode), UnitFactionGroup("player") may reflect your original faction,
318+
-- not the team you're currently playing on.
319+
local MyFaction = nil
320+
321+
if PS.isRetail == true then
322+
-- 1) Scoreboard faction (most reliable once scores are available)
323+
local okInfo, info = pcall(function()
324+
if PVPSound and PVPSound.GetMyScoreInfo then
325+
return PVPSound:GetMyScoreInfo()
247326
end
327+
return nil
328+
end)
329+
if okInfo and info and info.faction ~= nil then
330+
MyFaction = info.faction
248331
end
249332

250-
if MyFaction == 1 then
251-
PVPSound:AddToQueue(PS.SoundPackDirectory.."\\"..PS_SoundPackLanguage.."\\GameStatus\\PlayYouAreOnBlue.mp3")
252-
elseif MyFaction == 0 then
253-
PVPSound:AddToQueue(PS.SoundPackDirectory.."\\"..PS_SoundPackLanguage.."\\GameStatus\\PlayYouAreOnRed.mp3")
333+
-- 2) Arena/BG effective faction (can be nil briefly when first zoning in)
334+
if MyFaction == nil and type(GetBattlefieldArenaFaction) == "function" then
335+
MyFaction = GetBattlefieldArenaFaction()
336+
end
337+
end
338+
339+
-- 3) Fallback to original faction
340+
if MyFaction == nil then
341+
_, MyFaction = UnitFactionGroup("player")
342+
end
343+
344+
-- If we still can't resolve the effective faction yet (common on initial zone-in),
345+
-- retry a few times before giving up.
346+
if zone == "BG" and (MyFaction == nil or (UnitIsMercenary and UnitIsMercenary("player") and type(MyFaction) == "string")) then
347+
API._bgAnnounceRetryCount = (API._bgAnnounceRetryCount or 0) + 1
348+
if API._bgAnnounceRetryCount <= 12 then
349+
if type(C_Timer) == "table" and type(C_Timer.After) == "function" then
350+
C_Timer.After(0.5, function() API:Announce(zone) end)
351+
end
352+
return
254353
end
255-
elseif zone == "Arena" then
256-
PVPSound:AddToQueue(PS.SoundPackDirectory.."\\"..PS_SoundPackLanguage.."\\GameStatus\\PrepareForBattle.mp3")
257-
else
258-
return false
259354
end
355+
API._bgAnnounceRetryCount = 0
356+
357+
-- Alliance (blue)
358+
if MyFaction == 1 then
359+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\Zone_WintergraspBattlefield\\YouAreOnBlueTeam.mp3")
360+
PVPSound:AddToSct("Blue Team", "You Are On Blue Team", "KILL")
361+
-- Horde (red)
362+
elseif MyFaction == 0 then
363+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\Zone_WintergraspBattlefield\\YouAreOnRedTeam.mp3")
364+
PVPSound:AddToSct("Red Team", "You Are On Red Team", "KILL")
365+
end
366+
367+
AnnouncePlayed = true
260368
end
261369

262370
-- winner announcer

Modules/DeephaulRavine.lua

Lines changed: 115 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,139 @@
11
local addon, ns = ...
22
local PVPSound = ns.PVPSound
33
local PS = ns.PS
4-
54
local API = PVPSound.API
5+
local L = PVPSound.L
66

7-
-- Deephaul Ravine (The War Within)
8-
-- UIMapID: 2345
9-
-- InstanceID: 2656
10-
local mod = API:RegisterMod(2345, "pvp", "Deephaul Ravine", 2656)
7+
-- Deephaul Ravine is new-ish; objective text is parsed from BG system messages where possible.
8+
local mod = API:RegisterMod(2552, "pvp", "Deephaul Ravine", 2345)
119

12-
local function DumpPOIs()
13-
if not C_AreaPoiInfo or not C_AreaPoiInfo.GetAreaPOIForMap or not C_AreaPoiInfo.GetAreaPOIInfo then
14-
PVPSound:Debug("Deephaul: C_AreaPoiInfo API not available")
15-
return
16-
end
10+
local L = PVPSound.L
11+
local POIDebug = false
1712

18-
local ids = C_AreaPoiInfo.GetAreaPOIForMap(mod.zoneId)
19-
if not ids then
20-
PVPSound:Debug("Deephaul: no POIs returned for map "..tostring(mod.zoneId))
21-
return
22-
end
13+
-- Reuse existing CTF flag announcements (Deephaul does not have dedicated sound assets in most packs yet)
14+
local FlagSoundZone = "Zone_WarsongGulch"
2315

24-
PVPSound:Debug("Deephaul: POIs for map "..tostring(mod.zoneId).." ("..tostring(#ids)..")")
25-
for _, id in ipairs(ids) do
26-
local info = C_AreaPoiInfo.GetAreaPOIInfo(mod.zoneId, id)
27-
local name = info and info.name or ""
28-
local atlas = info and info.atlasName or ""
29-
local tex = info and info.textureIndex or ""
30-
PVPSound:Debug(" POI "..tostring(id).." name="..tostring(name).." atlas="..tostring(atlas).." textureIndex="..tostring(tex))
31-
end
16+
local function MsgLower(msg)
17+
if msg == nil then return nil end
18+
return string.lower(msg)
3219
end
3320

34-
function mod:Initialize()
35-
API.RegisterEvent(self, "AREA_POIS_UPDATED")
21+
local function IsCrystalTaken(msgLower)
22+
if msgLower == nil then return false end
23+
-- Common English variants seen in-game / community clips:
24+
-- "<name> has taken the crystal!"
25+
-- "<name> picked up the crystal!"
26+
return (msgLower:find("crystal") ~= nil) and
27+
((msgLower:find("has taken") ~= nil) or (msgLower:find("picked") ~= nil) or (msgLower:find("picked up") ~= nil))
28+
end
3629

37-
if not self.loaded then
38-
API:Announce("BG")
39-
end
30+
local function IsCrystalDropped(msgLower)
31+
if msgLower == nil then return false end
32+
return (msgLower:find("crystal") ~= nil) and (msgLower:find(L["dropped"]) ~= nil or msgLower:find("dropped") ~= nil)
33+
end
4034

41-
self.loaded = true
35+
local function IsCrystalReturned(msgLower)
36+
if msgLower == nil then return false end
37+
return (msgLower:find("crystal") ~= nil) and (msgLower:find(L["returned"]) ~= nil or msgLower:find("returned") ~= nil)
38+
end
39+
40+
local function AnnounceCrystal(faction, state)
41+
-- faction: "Alliance" (blue) / "Horde" (red)
42+
-- state: "Taken" / "Dropped" / "Returned"
43+
if faction == nil or state == nil then return end
4244

43-
if PS_PoiDebug == true then
44-
DumpPOIs()
45+
if faction == "Alliance" then
46+
if state == "Taken" then
47+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\" .. FlagSoundZone .. "\\ALLIANCE_Flag_Taken.mp3")
48+
PVPSound:AddToSct("Blue flag taken", PSSctFrame)
49+
elseif state == "Dropped" then
50+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\" .. FlagSoundZone .. "\\ALLIANCE_Flag_Dropped.mp3")
51+
PVPSound:AddToSct("Blue flag dropped", PSSctFrame)
52+
elseif state == "Returned" then
53+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\" .. FlagSoundZone .. "\\ALLIANCE_Flag_Returned.mp3")
54+
PVPSound:AddToSct("Blue flag returned", PSSctFrame)
55+
end
56+
elseif faction == "Horde" then
57+
if state == "Taken" then
58+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\" .. FlagSoundZone .. "\\HORDE_Flag_Taken.mp3")
59+
PVPSound:AddToSct("Red flag taken", PSSctFrame)
60+
elseif state == "Dropped" then
61+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\" .. FlagSoundZone .. "\\HORDE_Flag_Dropped.mp3")
62+
PVPSound:AddToSct("Red flag dropped", PSSctFrame)
63+
elseif state == "Returned" then
64+
PVPSound:AddToQueue(PS.SoundPackDirectory .. "\\" .. PS_SoundPackLanguage .. "\\" .. FlagSoundZone .. "\\HORDE_Flag_Returned.mp3")
65+
PVPSound:AddToSct("Red flag returned", PSSctFrame)
66+
end
4567
end
4668
end
4769

70+
function mod:Setup()
71+
--Keep track of POIs
72+
API:RegisterEvent("PLAYER_ENTERING_WORLD", self)
73+
API:RegisterEvent("ZONE_CHANGED_NEW_AREA", self)
74+
75+
-- Deephaul crystal/flag messages are broadcast via BG system chat events.
76+
API:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE", self)
77+
API:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE", self)
78+
API:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL", self)
79+
80+
-- Legacy event (some builds still fire it); harmless if unused.
81+
API:RegisterEvent("WORLD_MAP_UPDATE", self)
82+
end
83+
4884
function mod:Unload()
4985
API:UnregisterAllEvents()
50-
self.loaded = false
5186
end
5287

53-
function mod:AREA_POIS_UPDATED()
54-
if PS_PoiDebug == true then
55-
DumpPOIs()
88+
function mod:WORLD_MAP_UPDATE()
89+
if POIDebug == true then
90+
PVPSound:Debug("POI Debug: " .. tostring(POIDebug))
91+
PVPSound:GetPOIs(mod.zoneId)
5692
end
5793
end
5894

59-
-- Expose helper for slash command dump
60-
function mod:DumpPOIs()
61-
DumpPOIs()
95+
function mod:CHAT_MSG_BG_SYSTEM_ALLIANCE(event, msg)
96+
local m = MsgLower(msg)
97+
if IsCrystalTaken(m) then
98+
AnnounceCrystal("Alliance", "Taken")
99+
elseif IsCrystalDropped(m) then
100+
AnnounceCrystal("Alliance", "Dropped")
101+
elseif IsCrystalReturned(m) then
102+
AnnounceCrystal("Alliance", "Returned")
103+
end
104+
end
105+
106+
function mod:CHAT_MSG_BG_SYSTEM_HORDE(event, msg)
107+
local m = MsgLower(msg)
108+
if IsCrystalTaken(m) then
109+
AnnounceCrystal("Horde", "Taken")
110+
elseif IsCrystalDropped(m) then
111+
AnnounceCrystal("Horde", "Dropped")
112+
elseif IsCrystalReturned(m) then
113+
AnnounceCrystal("Horde", "Returned")
114+
end
62115
end
116+
117+
function mod:CHAT_MSG_BG_SYSTEM_NEUTRAL(event, msg)
118+
-- Some locales/routes send certain objective messages as neutral.
119+
-- We don't have a reliable faction in that case, so ignore for now.
120+
-- If you see crystal events arriving here, capture the chat text and we can expand parsing.
121+
end
122+
123+
function mod:PLAYER_ENTERING_WORLD()
124+
-- timer for fighting
125+
PVPSound:StartFightingTimer()
126+
end
127+
128+
function mod:ZONE_CHANGED_NEW_AREA()
129+
-- timer for fighting
130+
PVPSound:StartFightingTimer()
131+
end
132+
133+
function mod:OnLoad()
134+
mod:Setup()
135+
end
136+
137+
function mod:OnUnload()
138+
mod:Unload()
139+
end

0 commit comments

Comments
 (0)