Modified Ajantis Shadow Beacon, uses Skull/X/Square marks instead of the defaults.
-- master frame
local sb = CreateFrame("Frame")
local markClearFrame = CreateFrame("Frame")
-- constants
local SPELLS = { [64465] = true, }
local NAMES = { ["Marked Immortal Guardian"] = true, }
-- variables
local lastIconIndex = 9
-- mobs tracking
local guids = { }
local ignoreGuids = { }
-- loop and timer control
local nextCheckTime = nil
local lastBeaconBatchTime = nil
-- mark clearing control
local markToClear = 8
local nextMarkCheckTime = nil
-- Main mark clearing loop.
local function ClearAllMarksLoop()
if nextMarkCheckTime ~= nil then
local curTime = GetTime()
local abort = nil
if curTime >= nextMarkCheckTime then
if markToClear == 6 then
markToClear = 0
abort = true
end
SetRaidTarget("player", markToClear)
if abort then
nextMarkCheckTime = nil
markToClear = 8
markClearFrame:SetScript("OnUpdate", nil)
else
markToClear = markToClear + 1
if markToClear == 6 then
nextMarkCheckTime = curTime + 0.5
else
nextMarkCheckTime = curTime + 0.2
end
end
end
end
end
-- Starts the mark clearing loop.
function ClearAllMarks()
markToClear = 8
nextMarkCheckTime = GetTime()
markClearFrame:SetScript("OnUpdate", ClearAllMarksLoop)
end
-- Gets the next icon index to mark a mob with.
local function GetNextAvailableIcon()
if lastIconIndex == 6 then
lastIconIndex = 9
end
lastIconIndex = lastIconIndex - 1
return lastIconIndex
end
-- Marks the supplied unit.
local function MarkUnit(unit)
if UnitExists(unit) then
local guid = UnitGUID(unit)
SetRaidTarget(unit, GetNextAvailableIcon())
ignoreGuids[guid] = true
end
end
-- Checks to see if we want to mark this unitId, by
-- checking to see if it's a known GUID from the
-- combat log, if it's name matches something in our
-- list of markable mobs, or if it has the Shadow
-- Beacon buff. Returns true if we are interested
-- in the mob, nil otherwise.
local function IsMobOfInterest(unitId)
local rc
if UnitExists(unitId) then
local name = UnitName(unitId)
local guid = UnitGUID(unitId)
if not ignoreGuids[guid] then
if guids[guid] then
rc = true
elseif NAMES[name] then
rc = true
else
for spellId, _ in pairs(SPELLS) do
local spellName = GetSpellInfo(spellId)
if spellName then
if UnitBuff(unitId, spellName) then
rc = true
break
end
end
end
end
end
end
return rc
end
-- Checks the supplied unitId to see if it matches the
-- supplied GUID. If it does, this function ensures
-- that mob has one of the acceptable Shadow Beacon
-- marks. If the mob doesn't yet have an allowed
-- mark, it marks it up with the next usable mark.
-- Returns true if the mob matched the GUID and has
-- a mark, nil otherwise.
local function MarkMobByUnitIfGUID(unitId, guid)
local rc
if UnitExists(unitId) then
if UnitGUID(unitId) == guid then
local curIcon = GetRaidTargetIndex(unitId) or 0
-- only mark up if it doesn't already
-- have one of the five marks we use
if curIcon < 6 or curIcon > 8 then
MarkUnit(unitId)
end
rc = true
end
end
return rc
end
-- Scans all available targets to see if any of them match
-- the supplied GUID. If that mob is found, this function
-- ensures it is marked with one of the acceptable Shadow
-- Beacon marks. Returns true if the mob was found and
-- is (or was caused to be) marked, nil otherwise.
local function MarkMobByGUIDFromRaidTargets(guid)
local rc
for i = 1, 40 do
local unitId = "raid"..i.."target"
if MarkMobByUnitIfGUID(unitId, guid) then
rc = true
break
end
end
return rc
end
-- Attempts to mark up the mob with the supplied GUID, and
-- if it can't be found, the GUID is put in a list to be
-- scanned on a 100ms timer so it will be marked ASAP.
local function RecordMobByGUID(guid)
if not MarkMobByGUIDFromRaidTargets(guid) then
guids[guid] = true
end
end
-- Detect Yogg-Saron casting Shadow Beacon and find out which mob he cast it on.
local function HandleCombatLog(timeStamp, event, sourceGuid, sourceName, sourceFlags, destGuid, destName, destFlags, spellId)
if event == "SPELL_AURA_APPLIED" or event == "SPELL_AURA_REFRESH" then
if SPELLS[spellId] then
-- Activate the mouseover timer.
nextCheckTime = GetTime()
-- If this is a new round of Beacons, tell the player
-- to start going nuts with the mouseovers.
if lastBeaconBatchTime == nil then
lastBeaconBatchTime = GetTime()
UIErrorsFrame:AddMessage("Shadow Beacon cast - start mousing over the elephants!")
PlaySoundFile(("Interface\\AddOns\\AjantisShadowBeacon\\aoogah.ogg"))
end
-- Record this mob as one of interest.
RecordMobByGUID(destGuid)
end
end
end
-- Forgets we ever did anything.
local function Reset(removeIgnored)
guids = { }
nextCheckTime = nil
lastIconIndex = 9
lastBeaconBatchTime = nil
ClearAllMarks()
ignoreGuids = { }
end
-- The timer loop for marking mobs that weren't being
-- targeted by someone at the time the Beacon was cast.
-- It tracks mouseovers until all mobs that are known
-- to be of interest are marked up.
sb:SetScript("OnUpdate", function(f, event, ...)
local curTime = GetTime()
-- Reset everything if the last 'batch' of Shadow Beacons sent out was long enough ago.
if lastBeaconBatchTime ~= nil and curTime - lastBeaconBatchTime >= 31 then
Reset()
else
-- Main mouseover loop to check the current mouseover unit
-- to see if it's in need of a mark.
if nextCheckTime ~= nil and curTime >= nextCheckTime then
if IsMobOfInterest("mouseover") then
local curGuid = UnitGUID("mouseover")
local curIcon = GetRaidTargetIndex("mouseover") or 0
-- Only mark up if it doesn't already
-- have one of the five marks we use.
if curIcon < 6 or curIcon > 8 then
MarkUnit("mouseover")
end
-- Done marking this mob, forget about it now.
guids[curGuid] = nil
end
nextCheckTime = curTime + 0.15
end
end
end)
-- Hook into and handle the various events.
sb:SetScript("OnEvent", function(f, event, ...)
if event == "COMBAT_LOG_EVENT_UNFILTERED" then
HandleCombatLog(...)
elseif event == "PLAYER_REGEN_DISABLED" then
Reset(true)
elseif event == "ZONE_CHANGED_NEW_AREA" then
Reset(true)
elseif event == "ZONE_CHANGED" then
Reset(true)
end
end)
sb:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
sb:RegisterEvent("PLAYER_REGEN_DISABLED")
sb:RegisterEvent("ZONE_CHANGED_NEW_AREA")
sb:RegisterEvent("ZONE_CHANGED")


Recent Comments