-- -- AggroAlert -- v1.5 -- By Sathanas of Khadgar -- -- Creates a movable frame that will display the target's target (if any), and allow for -- visible warning on player gaining aggro. -- -- To move the AggroAlert bubble, use Shift+Left Button and drag it to a new position. -- -- Clicking on the AggroAlert bubble will target the unit named in the bubble -- -- v1.5 Changes: -- -- Updated TOC for 1.7 patch. -- Added an option in the /agg warning command to disable all text warnings. -- -- -- v1.4 Changes: -- -- Removed buggy call command. Seeing a pattern here? -- Background of the AggroAlert bubble is now a healthbar for the named unit in the bubble. -- -- -- v1.3 Changes: -- -- Ditched the buggy spell alert that was in 1.3 beta. It sucked. -- Added Healer Mode, the bubble will display "- Tank" or "- Idle" when targetting an ally, showing -- whether their target is currently aggrod on them (i.e. the ally is tanking) or not. -- Also added the new command "/agg call" which turns on automatic announcment of targets target changes -- in the appropriate channel. When your target changes targets (i.e. the main tank loses aggro) -- AggroAlert will broadcast a message to the channel, example "Target Change! Onyxia is now engaged on SomeDumbGuy!", -- this alert disables itself when you change targets or exit combat, and must be turned on individually each -- time with "/agg call", this is done mainly since this is a very situational feature. -- -- -- v1.2 Changes: -- -- Slash commands have changed, use "/agg mode" to toggle modes, and "/agg warning" to toggle between -- the original smaller warning, and a new gigantic one. -- Hopefully fixed all the errors caused by stun/sap/poly etc -- -- -- v1.1 Changes: -- -- AggroAlert now uses the slash command /aggroalert or /agg to toggle between 2 modes: -- DPS Mode will alert you visibly on screen when the targetted unit targets onto you (You pulled aggro) -- Tank Mode will alert you when the targeted unit CEASES targetting on you (Someone else pulled aggro) -- -- local aggroWarningCount = 0; local PlayerName = UnitName("player"); AggroAlertMode = {}; AggroAlertWarning = {}; function AggroAlert_OnLoad() this:RegisterEvent("PLAYER_TARGET_CHANGED"); this:RegisterEvent("UNIT_COMBAT"); this:RegisterEvent("PLAYER_REGEN_DISABLED"); this:RegisterEvent("PLAYER_REGEN_ENABLED"); this:RegisterEvent("VARIABLES_LOADED"); end function AggroAlert_Command(cmd) if (cmd) then if (cmd == "mode") then if (AggroAlertMode[PlayerName] == 0) then -- DPS Mode AggroAlertMode[PlayerName] = 1; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert is now operating in Tank Mode",1,0,0); elseif (AggroAlertMode[PlayerName] == 1) then -- Tank Mode AggroAlertMode[PlayerName] = 2; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert is now operating in Healer Mode",1,0,0); elseif (AggroAlertMode[PlayerName] == 2) then AggroAlertMode[PlayerName] = 0; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert is now operating in DPS Mode",1,0,0); end elseif (cmd == "warning") then if (AggroAlertWarning[PlayerName] == 0) then -- Little Warning AggroAlertWarning[PlayerName] = 1; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert Warning style set to Giganto Mode",1,0,0); elseif (AggroAlertWarning[PlayerName] == 1) then -- Big Warning AggroAlertWarning[PlayerName] = 2; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert Warning text disabled",1,0,0); elseif (AggroAlertWarning[PlayerName] == 2) then -- Warning Off AggroAlertWarning[PlayerName] = 0; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert Warning style set to Small Mode",1,0,0); end else DEFAULT_CHAT_FRAME:AddMessage("Valid AggroAlert commands are:",1,0,0); DEFAULT_CHAT_FRAME:AddMessage("/agg mode - Toggle operating mode between DPS ,Tank, and Healer modes.",1,0,0); DEFAULT_CHAT_FRAME:AddMessage("/agg warning - Toggle between small, large, and no warning text.",1,0,0); end end end function AggroAlert_OnEvent(event) if( event == "PLAYER_TARGET_CHANGED" or event == "UNIT_COMBAT" or event == "PLAYER_REGEN_DISABLED") then AggroAlert_Go(); end if (event == "PLAYER_REGEN_ENABLED") then aggroWarningCount = 0; AggroAlert_Call = 0; CallTime = 0; AggroAlert_Go(); end if (event == "VARIABLES_LOADED") then if (AggroAlertMode == nil) then AggroAlertMode = {}; end if (AggroAlertWarning == nil) then AggroAlertWarning = {}; end if (AggroAlertMode[PlayerName] == nil) then AggroAlertMode[PlayerName] = {}; AggroAlertMode[PlayerName] = 0; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert is setting initial mode..."); end if (AggroAlertWarning[PlayerName] == nil) then AggroAlertWarning[PlayerName] = {}; AggroAlertWarning[PlayerName] = 0; DEFAULT_CHAT_FRAME:AddMessage("AggroAlert is setting initial warning style..."); end SLASH_AGGROALERT1 = "/aggroalert"; SLASH_AGGROALERT2 = "/agg"; SlashCmdList["AGGROALERT"] = AggroAlert_Command; end end function AggroAlert_Go() if (UnitName("target")) then -- Player has something targetted if (UnitIsCorpse("target")) then AggroAlert(); elseif (UnitIsDead("target")) then AggroAlert(); else AggroAlert("Idle"); end if (UnitAffectingCombat("target")) then -- Target is in an active combat situation if (UnitIsDead("targettarget") or UnitIsCorpse("targettarget")) then -- Im thinking targetting something that is targetting a corpse or dead thing is causing crashes -- Hence this safety check. If it is, we do nothing and hide the bubble. AggroAlert(); else if (UnitName("targettarget")) then -- Stupid mobs dont have targets when they are trapped/polyd/sapped/stunned, check for this if (AggroAlertMode[PlayerName] == 0) then -- DPS Mode if (UnitName("targettarget") == UnitName("player")) then -- Its coming right for us! AggroAlert("*** YOU ***",0,1); if (aggroWarningCount == 0) then if (AggroAlertWarning[PlayerName] == 0) then UIErrorsFrame:AddMessage(UnitName("target").." has changed targets to you!",1,0,0,1,3); elseif (AggroAlertWarning[PlayerName] == 1) then AggroAlertFadingFrame_Show(UnitName("target").." has changed targets to you!"); elseif (AggroAlertWarning[PlayerName] == 2) then -- Warning disabled, left in for future additions that may require this condition end aggroWarningCount = 1; end else -- Whew it isnt fighting us AggroAlert(UnitName("targettarget"),1,0); aggroWarningCount = 0; end elseif (AggroAlertMode[PlayerName] == 1) then -- Tank mode if (UnitName("targettarget") == UnitName("player")) then -- Its coming right for us! (A good thing, im tanking it) AggroAlert("*** YOU ***",1,0); aggroWarningCount = 0; else -- Some dumb hunter pulled aggro AggroAlert(UnitName("targettarget"),0,1); if (aggroWarningCount == 0) then if (AggroAlertWarning[PlayerName] == 0) then UIErrorsFrame:AddMessage("You have lost aggro to "..UnitName("targettarget").."!",1,0,0,1,3); elseif (AggroAlertWarning[PlayerName] == 1) then AggroAlertFadingFrame_Show("You have lost aggro to "..UnitName("targettarget").."!"); elseif (AggroAlertWarning[PlayerName] == 2) then -- Warning disabled, left in for future additions that may require this condition end aggroWarningCount = 1; end end elseif (AggroAlertMode[PlayerName] == 2) then -- Healer Mode if (UnitIsPlayer("target")) then if (UnitIsFriend("player", "target")) then if (UnitIsUnit("target", "targettargettarget")) then -- The target and the targets target target (whew) are the same AggroAlert(UnitName("targettarget").." - Tank",1,0); if (aggroWarningCount == 0) then if (AggroAlertWarning[PlayerName] == 0) then UIErrorsFrame:AddMessage(UnitName("target").." is now tanking "..UnitName("targettarget"),1,0,0,1,3); elseif (AggroAlertWarning[PlayerName] == 1) then AggroAlertFadingFrame_Show(UnitName("target").." is now tanking "..UnitName("targettarget")); elseif (AggroAlertWarning[PlayerName] == 2) then -- Warning disabled, left in for future additions that may require this condition end aggroWarningCount = 1; end else -- Lazy warrior isnt tanking anything! AggroAlert(UnitName("targettarget").." - Idle",1,0); aggroWarningCount = 0; end else if (UnitName("targettarget") == UnitName("player")) then -- Its coming right for us! AggroAlert("*** YOU ***",0,1); if (aggroWarningCount == 0) then if (AggroAlertWarning[PlayerName] == 0) then UIErrorsFrame:AddMessage(UnitName("target").." has changed targets to you!",1,0,0,1,3); elseif (AggroAlertWarning[PlayerName] == 1) then AggroAlertFadingFrame_Show(UnitName("target").." has changed targets to you!"); elseif (AggroAlertWarning[PlayerName] == 2) then -- Warning disabled, left in for future additions that may require this condition end aggroWarningCount = 1; end else -- Whew it isnt fighting us AggroAlert(UnitName("targettarget"),1,0); aggroWarningCount = 0; end end else if (UnitName("targettarget") == UnitName("player")) then -- Its coming right for us! AggroAlert("*** YOU ***",0,1); if (aggroWarningCount == 0) then if (AggroAlertWarning[PlayerName] == 0) then UIErrorsFrame:AddMessage(UnitName("target").." has changed targets to you!",1,0,0,1,3); elseif (AggroAlertWarning[PlayerName] == 1) then AggroAlertFadingFrame_Show(UnitName("target").." has changed targets to you!"); elseif (AggroAlertWarning[PlayerName] == 2) then -- Warning disabled, left in for future additions that may require this condition end aggroWarningCount = 1; end else -- Whew it isnt fighting us AggroAlert(UnitName("targettarget"),1,0); aggroWarningCount = 0; end end end end end end else -- Player has nothing targetted AggroAlert(); end end function AggroAlert(text, swords, skull) AggroAlert_Skull:Hide(); AggroAlert_Swords:Hide(); AggroAlert_Bubble:Hide(); AggroAlert_Frame:Show(); AggroAlert_Text:Show(); if (text == nil) then AggroAlert_Skull:Hide(); AggroAlert_Swords:Hide(); AggroAlert_Bubble:Hide(); AggroAlert_Frame:Hide(); AggroAlert_Text:Hide(); else AggroAlert_Text:SetText(text); AggroAlert_Frame:SetWidth(AggroAlert_Text:GetWidth() + 30); AggroAlert_Bar:SetWidth(AggroAlert_Frame:GetWidth() - 6); if (UnitIsFriend("targettarget","player") or UnitInParty("targettarget") or UnitInRaid("targettarget")) then AggroAlert_Bar:SetAlpha(.5); elseif (UnitIsUnit("targettarget","player")) then AggroAlert_Bar:SetAlpha(.6); else AggroAlert_Bar:SetAlpha(.4); end if (UnitHealthMax("targettarget") > 100) then local thingy = UnitHealth("targettarget") / UnitHealthMax("targettarget"); thingy = thingy * 100; AggroAlert_Bar:SetValue(thingy); else AggroAlert_Bar:SetValue(UnitHealth("targettarget")); end if (swords == 1) then AggroAlert_Bubble:Show(); AggroAlert_Swords:Show(); end if (skull == 1) then AggroAlert_Bubble:Show(); AggroAlert_Skull:Show(); end end end function AggroAlert_TargetUnit() AssistUnit("target"); aggroWarningCount = 0; end -- -- Fade in/out frame stuff -- Ripped/modified from FadingFrame from Blizzard -- function AggroAlertFadingFrame_OnLoad() AggroAlert_BigWarning:Hide(); end function AggroAlertFadingFrame_Show(message) AggroAlertstartTime = GetTime(); if (message) then AggroAlert_BigWarning_Text:SetText(message); end AggroAlert_BigWarning:Show(); end function AggroAlertFadingFrame_OnUpdate() local elapsed = GetTime() - AggroAlertstartTime; local fadeInTime = 0.2; if ( elapsed < fadeInTime ) then local alpha = (elapsed / fadeInTime); AggroAlert_BigWarning:SetAlpha(alpha); return; end local holdTime = 2.5; if ( elapsed < (fadeInTime + holdTime) ) then AggroAlert_BigWarning:SetAlpha(1.0); return; end local fadeOutTime = 2; if ( elapsed < (fadeInTime + holdTime + fadeOutTime) ) then local alpha = 1.0 - ((elapsed - holdTime - fadeInTime) / fadeOutTime); AggroAlert_BigWarning:SetAlpha(alpha); return; end AggroAlert_BigWarning:Hide(); end