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

Core/BossPrototype: Add :RegisterEngageMob #1872

Merged
merged 14 commits into from
Oct 10, 2024
69 changes: 69 additions & 0 deletions Core/BossPrototype.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ local myLocale = GetLocale()
local hasVoice = BigWigsAPI:HasVoicePack()
local bossUtilityFrame = CreateFrame("Frame")
local petUtilityFrame = CreateFrame("Frame")
local activeNameplateUtilityFrame, inactiveNameplateUtilityFrame = CreateFrame("Frame"), CreateFrame("Frame")
local engagedGUIDs, activeNameplates = {}, {}
local enabledModules, unitTargetScans = {}, {}
local allowedEvents = {}
local difficulty, maxPlayers
Expand Down Expand Up @@ -456,6 +458,11 @@ function boss:Disable(isWipe)
if #enabledModules == 0 then
bossUtilityFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
petUtilityFrame:UnregisterEvent("UNIT_PET")
activeNameplateUtilityFrame:UnregisterEvent("NAME_PLATE_UNIT_ADDED")
inactiveNameplateUtilityFrame:UnregisterEvent("NAME_PLATE_UNIT_REMOVED")
activeNameplateUtilityFrame.nameplateWatcher:Stop()
engagedGUIDs = {}
activeNameplates = {}
unitTargetScans = {}
else
for i = #unitTargetScans, 1, -1 do
Expand Down Expand Up @@ -793,6 +800,64 @@ do
allowedEvents.UNIT_DIED = true
bossUtilityFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
do
local UnitAffectingCombat = UnitAffectingCombat
activeNameplateUtilityFrame:SetScript("OnEvent", function(_, _, unit)
activeNameplates[unit] = true
end)
inactiveNameplateUtilityFrame:SetScript("OnEvent", function(_, _, unit)
activeNameplates[unit] = nil
end)
local nameplateWatcher = activeNameplateUtilityFrame:CreateAnimationGroup()
nameplateWatcher:SetLooping("REPEAT")
local anim = nameplateWatcher:CreateAnimation()
anim:SetDuration(0.5)
activeNameplateUtilityFrame.nameplateWatcher = nameplateWatcher
nameplateWatcher:SetScript("OnLoop", function()
for unit in next, activeNameplates do
local guid = UnitGUID(unit)
local engaged = engagedGUIDs[guid]
if not engaged and UnitAffectingCombat(unit) then
engagedGUIDs[guid] = true
local _, _, _, _, _, id = strsplit("-", guid)
local mobId = tonumber(id)
if mobId then
for i = #enabledModules, 1, -1 do
local self = enabledModules[i]
local m = eventMap[self]["UNIT_ENTERING_COMBAT"]
if m and m[mobId] then
self:Debug("UNIT_ENTERING_COMBAT", guid)
local func = m[mobId]
self[func](self, guid, mobId)
end
end
end
elseif engaged and not UnitAffectingCombat(unit) then
engagedGUIDs[guid] = nil
end
end
end)
--- Register a callback for a unit nameplate entering combat.
-- @param func callback function, passed (guid, mobId)
-- @number ... any number of mob ids
function boss:RegisterEngageMob(func, ...)
if not func then core:Print(format(missingArgument, self.moduleName)) return end
if type(func) ~= "function" and not self[func] then core:Print(format(missingFunction, self.moduleName, func)) return end
if not eventMap[self].UNIT_ENTERING_COMBAT then eventMap[self].UNIT_ENTERING_COMBAT = {} end
for i = 1, select("#", ...) do
eventMap[self]["UNIT_ENTERING_COMBAT"][select(i, ...)] = func
end
activeNameplateUtilityFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
inactiveNameplateUtilityFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
nameplateWatcher:Play()
end
end
--- Checks if a mob is engaged.
-- @param guid a mob to check
-- @return boolean
function boss:IsMobEngaged(guid)
return engagedGUIDs[guid] and true or false
end
end

-------------------------------------------------------------------------------
Expand Down Expand Up @@ -3138,6 +3203,10 @@ do
-- @string guid Anchor to a unit's nameplate by GUID
-- @param[opt] customIconOrText a custom icon (File ID as a number) or text to show text instead
function boss:Nameplate(key, length, guid, customIconOrText)
if not engagedGUIDs[guid] then
-- in rare cases a NPC can start casting before being engaged, make sure this timer isn't overwritten
engagedGUIDs[guid] = true
end
self:SendMessage("BigWigs_StartNameplate", self, guid, key, length, customIconOrText)
end

Expand Down
69 changes: 69 additions & 0 deletions Core/BossPrototype_Classic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ local myLocale = GetLocale()
local hasVoice = BigWigsAPI:HasVoicePack()
local bossUtilityFrame = CreateFrame("Frame")
local petUtilityFrame = CreateFrame("Frame")
local activeNameplateUtilityFrame, inactiveNameplateUtilityFrame = CreateFrame("Frame"), CreateFrame("Frame")
local engagedGUIDs, activeNameplates = {}, {}
local enabledModules, unitTargetScans = {}, {}
local allowedEvents = {}
local difficulty, maxPlayers
Expand Down Expand Up @@ -528,6 +530,11 @@ function boss:Disable(isWipe)
if #enabledModules == 0 then
bossUtilityFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
petUtilityFrame:UnregisterEvent("UNIT_PET")
activeNameplateUtilityFrame:UnregisterEvent("NAME_PLATE_UNIT_ADDED")
inactiveNameplateUtilityFrame:UnregisterEvent("NAME_PLATE_UNIT_REMOVED")
activeNameplateUtilityFrame.nameplateWatcher:Stop()
engagedGUIDs = {}
activeNameplates = {}
unitTargetScans = {}
else
for i = #unitTargetScans, 1, -1 do
Expand Down Expand Up @@ -866,6 +873,64 @@ do
allowedEvents.UNIT_DIED = true
bossUtilityFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
do
local UnitAffectingCombat = UnitAffectingCombat
activeNameplateUtilityFrame:SetScript("OnEvent", function(_, _, unit)
activeNameplates[unit] = true
end)
inactiveNameplateUtilityFrame:SetScript("OnEvent", function(_, _, unit)
activeNameplates[unit] = nil
end)
local nameplateWatcher = activeNameplateUtilityFrame:CreateAnimationGroup()
nameplateWatcher:SetLooping("REPEAT")
local anim = nameplateWatcher:CreateAnimation()
anim:SetDuration(0.5)
activeNameplateUtilityFrame.nameplateWatcher = nameplateWatcher
nameplateWatcher:SetScript("OnLoop", function()
for unit in next, activeNameplates do
local guid = UnitGUID(unit)
local engaged = engagedGUIDs[guid]
if not engaged and UnitAffectingCombat(unit) then
engagedGUIDs[guid] = true
local _, _, _, _, _, id = strsplit("-", guid)
local mobId = tonumber(id)
if mobId then
for i = #enabledModules, 1, -1 do
local self = enabledModules[i]
local m = eventMap[self]["UNIT_ENTERING_COMBAT"]
if m and m[mobId] then
self:Debug("UNIT_ENTERING_COMBAT", guid)
local func = m[mobId]
self[func](self, guid, mobId)
end
end
end
elseif engaged and not UnitAffectingCombat(unit) then
engagedGUIDs[guid] = nil
end
end
end)
--- Register a callback for a unit nameplate entering combat.
-- @param func callback function, passed (guid, mobId)
-- @number ... any number of mob ids
function boss:RegisterEngageMob(func, ...)
if not func then core:Print(format(missingArgument, self.moduleName)) return end
if type(func) ~= "function" and not self[func] then core:Print(format(missingFunction, self.moduleName, func)) return end
if not eventMap[self].UNIT_ENTERING_COMBAT then eventMap[self].UNIT_ENTERING_COMBAT = {} end
for i = 1, select("#", ...) do
eventMap[self]["UNIT_ENTERING_COMBAT"][select(i, ...)] = func
end
activeNameplateUtilityFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
inactiveNameplateUtilityFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
nameplateWatcher:Play()
end
end
--- Checks if a mob is engaged.
-- @param guid a mob to check
-- @return boolean
function boss:IsMobEngaged(guid)
return engagedGUIDs[guid] and true or false
end
end

-------------------------------------------------------------------------------
Expand Down Expand Up @@ -3132,6 +3197,10 @@ do
-- @string guid Anchor to a unit's nameplate by GUID
-- @param[opt] customIconOrText a custom icon (File ID as a number) or text to show text instead
function boss:Nameplate(key, length, guid, customIconOrText)
if not engagedGUIDs[guid] then
-- in rare cases a NPC can start casting before being engaged, make sure this timer isn't overwritten
engagedGUIDs[guid] = true
end
self:SendMessage("BigWigs_StartNameplate", self, guid, key, length, customIconOrText)
end

Expand Down
10 changes: 9 additions & 1 deletion gen_option_values.lua
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ local function parseLua(file)
local options, option_keys, option_key_used, bitflag_used = {}, {}, {}, {}
local options_block_start = 0
local special_options = {}
local methods, registered_methods, unit_died_methods = {Win=true,Disable=true}, {}, {}
local methods, registered_methods, unit_died_methods, mob_engaged_methods = {Win=true,Disable=true}, {}, {}, {}
local event_callbacks = {}
local current_func = nil
local args_keys = standard_args_keys
Expand Down Expand Up @@ -807,6 +807,12 @@ local function parseLua(file)
registered_methods[callback] = n
unit_died_methods[callback] = true
end
event = line:match(":MobEngaged%(\"(.-)\"%s*,.*")
if event then
callback = event
registered_methods[callback] = n
mob_engaged_methods[callback] = true
end

--- Set spellId replacement values.
-- Record the function that was declared and use the callback map that was
Expand All @@ -822,6 +828,8 @@ local function parseLua(file)
args_keys = {}
elseif unit_died_methods[name] then
args_keys = unit_died_args_keys
elseif mob_engaged_methods[name] then
args_keys = {}
else
args_keys = standard_args_keys
end
Expand Down