SL = (SL or {}); SL.MeleeStats = (SL.MeleeStats or {}); SL.SpellStats = (SL.SpellStats or {}); SL.Verbose = (SL.Verbose or false); SL.Debug = (SL.Debug or false); SL_MaxShield = 0; SL_ShieldLeft = 0; SL_HasShield = false; SLASH_SHIELDLEFT1 = "/shieldleft"; SLASH_SHIELDLEFT2 = "/sl"; eventlist = { "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS", "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES", "CHAT_MSG_COMBAT_PARTY_HITS", "CHAT_MSG_COMBAT_PARTY_MISSES", "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES", "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE", "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE", "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE", "CHAT_MSG_SPELL_SELF_DAMAGE", "CHAT_MSG_SPELL_PARTY_DAMAGE", "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS", "CHAT_MSG_SPELL_AURA_GONE_SELF", "PLAYER_ENTERING_WORLD", "ADDON_LOADED", "PET_BAR_UPDATE", "LEARNED_SPELL_IN_TAB" } local function ShieldLeft_Debug(msg) if SL.Debug then DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00SL Debug: "..msg); end end local function ShieldLeft_Verbose(msg) if SL.Verbose then DEFAULT_CHAT_FRAME:AddMessage("|cffffff00SL: "..msg); end end local function ShieldLeft_Msg(msg) DEFAULT_CHAT_FRAME:AddMessage("|cffffff00SL: "..msg); end local function ShieldLeft_Error(msg) DEFAULT_CHAT_FRAME:AddMessage("|cffff0000ERROR: " .. msg); UIErrorsFrame:AddMessage("!! " .. msg .. " !!", 1.0, 1.0, 0, 1, 3) end local function RegisterEvents(EventList) if not EventList then ShieldLeft_Error("eventlist is missing") return end for _,aktEvent in EventList do this:RegisterEvent(aktEvent) end end local function UnregisterEvents(EventList) if not EventList then ShieldLeft_Error("eventlist is missing") return end for _,aktEvent in EventList do this:UnregisterEvent(aktEvent) end end local function CheckShieldSpells() ShieldLeft_Verbose(SL_MSG_CHECKINGSPELLS); local i = 1 while true do local spellName, spellRank = GetSpellName(i, BOOKTYPE_SPELL) if not spellName then do break end end if spellName == SL_SHIELD then ShieldLeft_Verbose("found " .. spellName .. '(' .. spellRank .. ')' ) ShieldLeftTooltip:SetSpell(i, BOOKTYPE_SPELL); local _, _, dmg = string.find(ShieldLeftTooltipTextLeft4:GetText(), SL_ABSORBING); ShieldLeft_Debug(ShieldLeftTooltipTextLeft4:GetText()) if ( dmg ) then ShieldLeft_Debug(dmg) if SL_MaxShield < tonumber(dmg) then SL_MaxShield = tonumber(dmg); ShieldLeft_Verbose(SL_MSG_NEWMAXSHIELD .. SL_MaxShield); end end end i = i + 1 end local i = 1 while true do local spellName, spellRank = GetSpellName(i, BOOKTYPE_PET) if not spellName then do break end end if spellName == SL_SHIELD then ShieldLeft_Verbose( spellName .. '(' .. spellRank .. ')' ) ShieldLeftTooltip:SetSpell(i, BOOKTYPE_PET); local _, _, dmg = string.find(ShieldLeftTooltipTextLeft4:GetText(), SL_ABSORBING); if ( dmg ) then if SL_MaxShield < tonumber(dmg) then SL_MaxShield = tonumber(dmg); ShieldLeft_Verbose(SL_MSG_NEWMAXSHIELD .. SL_MaxShield); end end end i = i + 1 end end SlashCmdList["SHIELDLEFT"] = function(msg) if msg == "reset" then -- ShieldLeft_Reset() elseif msg == "info" then ShieldLeft_ShowInfo() elseif msg == "reset" then -- elseif msg == "check" then CheckShieldSpells() elseif msg == "verbose" then SL.Verbose = not SL.Verbose; if SL.Verbose then ShieldLeft_Msg(SL_MSG_VERBOSEON) else ShieldLeft_Msg(SL_MSG_VERBOSEOFF) end elseif msg == "debug" then SL.Debug = not SL.Debug; if SL.Debug then ShieldLeft_Msg(SL_MSG_DEBUGON) else ShieldLeft_Msg(SL_MSG_DEBUGOFF) end else ShieldLeft_Msg(SL_MSG_HELP); end end function ShieldLeft_OnEnter() GameTooltip:SetOwner(this, "ANCHOR_RIGHT"); GameTooltip:SetText(SL_MSG_CLICKTODRAG); end function ShieldLeft_OnLoad() RegisterEvents(eventlist) ShieldLeft_Verbose(SL_MSG_LOADED); end function ShieldLeft_ShowInfo() if SL.Verbose then ShieldLeft_Msg(SL_MSG_VERBOSEON) else ShieldLeft_Msg(SL_MSG_VERBOSEOFF) end ShieldLeft_Msg(SL_MSG_MAXSHIELD .. SL_MaxShield .. "\n"); for aktUnit in SL.MeleeStats do ShieldLeft_Msg(aktUnit .. "(" .. SL.MeleeStats[aktUnit].med .. ")"); end for aktUnit in SL.SpellStats do for aktSpell in SL.SpellStats[aktUnit] do ShieldLeft_Msg(aktUnit .. "'s " .. aktSpell .. "(" .. SL.SpellStats[aktUnit][aktSpell].med .. ")"); end end end function ShieldLeft_Reset() SL.MeleeStats = {}; SL.SpellStats = {}; ShieldLeft_Msg(SL_MSG_STATSRESET); end -- this adds meelee damage to the database function ShieldLeft_AddDamage(unit, dmg) if ( not SL.MeleeStats[unit] ) then SL.MeleeStats[unit] = { ["hits"] = 1, ["dmg"] = dmg, ["med"] = dmg }; ShieldLeft_Verbose(SL_MSG_NEWCRITTER .. unit .. "(" .. dmg .. ")"); else SL.MeleeStats[unit].hits = SL.MeleeStats[unit].hits + 1; SL.MeleeStats[unit].dmg = SL.MeleeStats[unit].dmg + dmg; local oldmed = (SL.MeleeStats[unit].med or 0); SL.MeleeStats[unit].med = ceil(SL.MeleeStats[unit].dmg / SL.MeleeStats[unit].hits); if abs(SL.MeleeStats[unit].med - oldmed) > 0 then ShieldLeft_Verbose(unit .. ": " .. SL.MeleeStats[unit].med); end end end -- this adds spell/ranged damage to the database function ShieldLeft_AddSpellDamage(unit, spell, dmg) if ( not SL.SpellStats[unit] ) then SL.SpellStats[unit] = { [spell] = { ["hits"] = 1, ["dmg"] = dmg, ["med"] = dmg } }; ShieldLeft_Verbose(SL_MSG_NEWCRITTER .. unit); elseif ( not SL.SpellStats[unit][spell] ) then SL.SpellStats[unit][spell] = { ["hits"] = 1, ["dmg"] = dmg, ["med"] = dmg }; ShieldLeft_Verbose(SL_MSG_NEWSPELLFOR .. unit .. ": " .. spell); else SL.SpellStats[unit][spell].hits = SL.SpellStats[unit][spell].hits + 1; SL.SpellStats[unit][spell].dmg = SL.SpellStats[unit][spell].dmg + dmg; local oldmed = (SL.SpellStats[unit][spell].med or 0); SL.SpellStats[unit][spell].med = ceil(SL.SpellStats[unit][spell].dmg / SL.SpellStats[unit][spell].hits); if abs(SL.SpellStats[unit][spell].med - oldmed) > 0 then ShieldLeft_Verbose(unit .. "'s " .. spell .. ": " .. SL.SpellStats[unit][spell].med); end end end -- this subtracts the damagage the shield has absorbed from the "shield left" counter function ShieldLeft_AbsorbShield(unit, spell) if ( not SL_HasShield ) then return; end local recognized; if ( spell ) then if ( SL.SpellStats[unit] and SL.SpellStats[unit][spell] ) then SL_ShieldLeft = SL_ShieldLeft - SL.SpellStats[unit][spell].med; recognized = true; end else if ( SL.MeleeStats[unit] ) then SL_ShieldLeft = SL_ShieldLeft - (SL.MeleeStats[unit].med or 0); recognized = true; end end if ( SL_ShieldLeft < 0 ) then SL_ShieldLeft = 0; end ShieldLeftFrameText:SetText(SL_MSG_SHIELDLEFT .. SL_ShieldLeft .. "|r"); ShieldLeftFrame:SetWidth(ShieldLeftFrameText:GetWidth()+10); ShieldLeftFrame:SetHeight(ShieldLeftFrameText:GetHeight()+15); if ( not recognized ) then ShieldLeftFrame.recognized = nil; ShieldLeftFrame:SetBackdropColor(1, 0, 0, 0.5); elseif ( ShieldLeftFrame.recognized ) then ShieldLeftFrame.recognized = 1; ShieldLeftFrame:SetBackdropColor(0, 0, 1, 0.5); end end function ShieldLeft_OnEvent(event) local _,playerclass = UnitClass("player"); ShieldLeft_Debug("EVENT: " .. event); if event == "PLAYER_ENTERING_WORLD" then this:UnregisterEvent("PLAYER_ENTERING_WORLD") if playerclass == "PRIEST" then ShieldLeft_Debug("adjusting for Priest"); SL_SHIELD = SL_SHIELD_PRIEST; SL_ABSORBING = SL_ABSORBING_PRIEST; SL_YOUGAINSHIELD = SL_YOUGAINSHIELD_PRIEST; SL_YOULOOSESHIELD = SL_YOULOOSESHIELD_PRIEST; elseif playerclass == "WARLOCK" then ShieldLeft_Debug("adjusting for Warlock"); SL_SHIELD = SL_SHIELD_WARLOCK SL_ABSORBING = SL_ABSORBING_WARLOCK SL_YOUGAINSHIELD = SL_YOUGAINSHIELD_WARLOCK; SL_YOULOOSESHIELD = SL_YOULOOSESHIELD_WARLOCK; elseif playerclass == "MAGE" then ShieldLeft_Debug("adjusting for Mage"); SL_SHIELD = SL_SHIELD_MAGE SL_ABSORBING = SL_ABSORBING_MAGE SL_YOUGAINSHIELD = SL_YOUGAINSHIELD_MAGE SL_YOULOOSESHIELD = SL_YOULOOSESHIELD_MAGE else UnregisterEvents(eventlist) return; end CheckShieldSpells() elseif event == "ADDON_LOADED" then this:UnregisterEvent("ADDON_LOADED") local MyAddonDetails = { name = SL_MODNAME, version = SL_VERSION, releaseDate = SL_RELEASEDATE, category = MYADDONS_CATEGORY_COMBAT, author = "VincentGdG", email = "h40izsq02@sneakemail.com", website = "http://wow.g-d-g.de" } local MyAddonHelp = {}; MyAddonHelp[1] = SL_MSG_HELP; if(myAddOnsFrame_Register) then myAddOnsFrame_Register(MyAddonDetails,MyAddonHelp); end elseif event == "PET_BAR_UPDATE" or event == "LEARNED_SPELL_IN_TAB" then CheckShieldSpells(); elseif ( event == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS" or event == "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS" or event == "CHAT_MSG_COMBAT_PARTY_HITS" or event == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES" or event == "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES" or event == "CHAT_MSG_COMBAT_PARTY_MISSES" ) then local _, _, unit, dmg1, dmg2 = string.find(arg1, SL_HITSYOUABSORBED); --ShieldLeft_Debug("MELEE HIT"); if ( unit and dmg1 and dmg2 ) then ShieldLeft_AddDamage(unit, tonumber(dmg1)+tonumber(dmg2)); return; end local _, _, unit, dmg1, dmg2 = string.find(arg1, SL_CRITSYOUABSORBED); if ( unit and dmg1 and dmg2 ) then ShieldLeft_AddDamage(unit, tonumber(dmg1)+tonumber(dmg2)); return; end local _, _, unit, dmg1, dmg2 = string.find(arg1, SL_HITSYOUBLOCKED); if ( unit and dmg1 and dmg2 ) then ShieldLeft_AddDamage(unit, tonumber(dmg1)+tonumber(dmg2)); return; end local _, _, unit, dmg1, dmg2 = string.find(arg1, SL_CRITSYOUBLOCKED); if ( unit and dmg1 and dmg2 ) then ShieldLeft_AddDamage(unit, tonumber(dmg1)+tonumber(dmg2)); return; end local _, _, unit, dmg = string.find(arg1, SL_HITSYOUFOR) if ( unit and dmg ) then ShieldLeft_AddDamage(unit, tonumber(dmg)); return; end local _, _, unit, dmg = string.find(arg1, SL_CRITSYOUFOR); if ( unit and dmg ) then ShieldLeft_AddDamage(unit, tonumber(dmg)); return; end local _, _, unit = string.find(arg1,SL_ABSORBALL); if ( unit ) then ShieldLeft_AbsorbShield(unit); return; end elseif ( event == "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE" or event == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE" or event == "CHAT_MSG_SPELL_PARTY_DAMAGE" or event == "CHAT_MSG_SPELL_SELF_DAMAGE" ) then --ShieldLeft_Debug("RANGED HIT"); local _, _, unit, spell, dmg1, dmg2 = string.find(arg1, SL_RANGED_HITSYOUABSORBED); if ( unit and spell and dmg1 and dmg2 ) then ShieldLeft_AddSpellDamage(unit, spell, tonumber(dmg1)+tonumber(dmg2)); return; end local _, _, unit, spell, dmg1, dmg2 = string.find(arg1, SL_RANGED_CRITSYOUABSORBED); if ( unit and spell and dmg1 and dmg2 ) then ShieldLeft_AddSpellDamage(unit, spell, tonumber(dmg1)+tonumber(dmg2)); return; end local _, _, unit, spell, dmg = string.find(arg1, SL_RANGED_HITSYOU); if ( unit and spell and dmg ) then ShieldLeft_AddSpellDamage(unit, spell, tonumber(dmg)); return; end -- this only seems to be different from the other one in German, for shooting. local _, _, unit, spell, dmg = string.find(arg1, SL_RANGED_HITSYOU2); if ( unit and spell and dmg ) then ShieldLeft_AddSpellDamage(unit, spell, tonumber(dmg)); return; end local _, _, unit, spell, dmg = string.find(arg1, SL_RANGED_CRITSYOU); if ( unit and spell and dmg ) then ShieldLeft_AddSpellDamage(unit, spell, tonumber(dmg)); return; end local _, _, unit, spell = string.find(arg1, SL_RANGED_YOUABSORB); if ( unit and spell ) then ShieldLeft_AbsorbShield(unit, spell); return; end local _, _, spell, dmg = string.find(arg1, SL_YOURHITSYOU); if ( spell and dmg) then ShieldLeft_AddSpellDamage("GenericUnit", spell, tonumber(dmg)); return; end local _, _, spell = string.find(arg1, SL_YOUABSORBYOUR); if ( spell ) then ShieldLeft_AbsorbShield("GenericUnit", spell); return; end elseif ( event == "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE" ) then local _, _, dmg, unit, spell = string.find(arg1, SL_YOUSUFFER); if ( unit and spell and dmg ) then ShieldLeft_AddSpellDamage(unit, spell, tonumber(dmg)); return; end elseif ( event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" or event == "CHAT_MSG_SPELL_AURA_GONE_SELF" ) then if ( arg1 == SL_YOUGAINSHIELD ) then SL_HasShield = true; SL_ShieldLeft = SL_MaxShield; ShieldLeftFrame:Show(); elseif ( arg1 == SL_YOULOOSESHIELD ) then SL_HasShield = false; SL_ShieldLeft = 0; ShieldLeftFrame:Hide(); end return; end end