-- -- Simple Feign Health - by Brodrick ( aka Kirov ) -- Version 2.0 -- -- Continues to show the player's health and mana values after they've feigned death. -- Also attempts to show party / raid hunters' health and mana after they FD using -- last known valid numbers. -- -- Attempts to keep track of a player's mana regen, as well as mana gains or drains. -- Show accurate health for all FDed hunters in the player's group. -- SimpleFeignHealth_Saved = {}; -- local vars local ValidUnits = {}; --SFH_ValidUnits = ValidUnits; -- for debugging local manaRegen, manaRegenLast, manaRegenStart, player, playerUnit, cacheUnit, cacheMana, cacheHealth, frame, tooltip, statusbar; -- hooked functions local oldUnitHealth = UnitHealth; local oldUnitMana = UnitMana; local oldUnitIsDead = UnitIsDead; -- local references for often used globals local unitManaMax = UnitManaMax; local unitStat = UnitStat; local unitName = UnitName; local getTime = GetTime; local function print( msg ) DEFAULT_CHAT_FRAME:AddMessage( msg ); end -- hack to prevent needless recalculation of the player's mana regen -- which gets around the OnEvent order problem causing mis-matched results. local function clearCache() cacheHealth = nil; cacheMana = nil; this:GetScript("OnUpdate", nil); end -- all grouped units' health -- ------------------------------- local function getHealth(unit) if ( tooltip ) then if ( not cacheUnit or cacheUnit ~= unit ) then if ( not cacheUnit ) then frame:SetScript("OnUpdate", clearCache); end tooltip:SetUnit(unit); cacheUnit = unit; cacheHealth = nil; end if ( not cacheHealth ) then cacheHealth = statusbar:GetValue(); end return cacheHealth; end return 0; end -- player's mana regen -- ------------------------- local function getManaRegen() if ( not cacheMana ) then cacheMana = playerUnit[2]; if ( manaRegenTime ) then if ( manaRegenLast ) then manaRegenTime = manaRegenTime + getTime() - manaRegenLast; manaRegenLast = getTime(); end local base, spirit = unitStat("player", 5); local time = (manaRegenTime - mod(manaRegenTime, 2)); manaRegenTime = manaRegenTime - time; local regen = max(floor((spirit * time / 2 * 0.2) + ( time / 2 * 15 )),0); cacheMana = min( cacheMana + regen, unitManaMax("player") ); playerUnit[2] = cacheMana; manaRegen = manaRegen + regen; end frame:SetScript("OnUpdate",clearCache); end return cacheMana; end -- add hunters to valid list -- ------------------------------- local function checkForHunters() if ( SimpleFeignHealth_Saved["noparty"] ) then return; end local raidNum = GetNumRaidMembers(); local partyNum = GetNumPartyMembers(); if ( raidNum > 0 ) then for i=1, raidNum do local unit = "raid"..i; local _,class = UnitClass(unit); if ( class == "HUNTER" ) then local name = unitName( unit ); if ( not ValidUnits[name] ) then ValidUnits[name] = {unit,oldUnitMana(unit)}; elseif ( name ~= player ) then ValidUnits[name][1] = unit; end end end elseif ( partyNum > 0 ) then for i=1, partyNum do local unit = "party"..i; local _,class = UnitClass(unit); if ( class == "HUNTER" ) then local name = unitName(unit); if ( not ValidUnits[name] ) then ValidUnits[name] = {unit,oldUnitMana(unit)}; elseif ( name ~= player ) then ValidUnits[name][1] = unit; end end end else -- cull all but player from list for k, v in pairs(ValidUnits) do if ( k ~= player ) then v = nil; end end end end -- check for fd -- ------------------ local function checkFeign( unit ) local i, name, texture = 1, unitName(unit); repeat texture = UnitBuff( unit, i ); if ( texture == "Interface\\Icons\\Ability_Rogue_FeignDeath" ) then ValidUnits[name][3] = 1; return 1; end i = i + 1; until not texture; ValidUnits[name][3] = nil; end -- initialization -- -------------------- frame = CreateFrame("frame","SFH_Frame"); frame:RegisterEvent("PLAYER_ENTERING_WORLD"); local function enable() local _,class = UnitClass("player"); if ( class == "HUNTER" ) then frame:RegisterEvent("MIRROR_TIMER_START"); frame:RegisterEvent("MIRROR_TIMER_STOP"); player = unitName("player"); ValidUnits[player] = {"player", oldUnitMana("player")}; playerUnit = ValidUnits[player]; --SFH_PlayerUnit = ValidUnits[player]; -- for debugging end checkForHunters(); frame:RegisterEvent("UNIT_MANA"); frame:RegisterEvent("UNIT_AURA"); frame:RegisterEvent("PARTY_MEMBERS_CHANGED"); if ( not tooltip ) then tooltip = CreateFrame("GameTooltip","SFH_Tooltip",UIParent,"GameTooltipTemplate"); tooltip:SetOwner(tooltip,"ANCHOR_NONE"); statusbar = tooltip:GetChildren(); end end local function disable() ValidUnits = {}; frame:UnregisterEvent("MIRROR_TIMER_START"); frame:UnregisterEvent("MIRROR_TIMER_STOP"); frame:UnregisterEvent("UNIT_MANA"); frame:UnregisterEvent("UNIT_AURA"); frame:UnregisterEvent("PARTY_MEMBERS_CHANGED"); end local function init() print( "SimpleFeignHealh : loaded - /sfh" ); SLASH_SFEIGNHEALTH1 = "/sfh"; SLASH_SFEIGNHEALTH2 = "/simplefeignhealth"; SLASH_SFEIGNHEALTH3 = "/feignhealth"; SlashCmdList["SFEIGNHEALTH"] = SimpleFeignHealth_Console; if ( not SimpleFeignHealth_Saved["disable"] ) then enable(); end end -- event catching -- -------------------- frame:SetScript("OnEvent", function() if ( event == "PLAYER_ENTERING_WORLD" ) then this:UnregisterEvent("PLAYER_ENTERING_WORLD"); init(); elseif ( event == "MIRROR_TIMER_START" ) then if ( arg1 == "FEIGNDEATH" ) then this:RegisterEvent("COMBAT_TEXT_UPDATE"); manaRegenLast = getTime(); manaRegenTime = -4; manaRegen = 0; end elseif ( event == "MIRROR_TIMER_STOP" ) then if ( arg1 == "FEIGNDEATH" ) then this:UnregisterEvent("COMBAT_TEXT_UPDATE"); end elseif ( event == "PARTY_MEMBERS_CHANGED" ) then -- Find hunters in party / raid checkForHunters(); elseif ( event == "COMBAT_TEXT_UPDATE" ) then if ( not playerUnit[3] ) then return; end if ( arg1 == "MANA" ) then playerUnit[2] = max(min(playerUnit[2] + arg2,unitManaMax("player")),0); end else local name = unitName(arg1); if ( event == "UNIT_MANA" ) then if ( ValidUnits[name] ) then local mana = oldUnitMana( arg1 ); if ( mana > 0 ) then -- Keep track of all valid units' mana before FD ValidUnits[name][2] = mana; end end elseif ( event == "UNIT_AURA" ) then if ( ValidUnits[name] ) then checkFeign(arg1); end end end end ); -- console commands -- ---------------------- function SimpleFeignHealth_Console( msg ) if ( string.sub( strlower( msg ), 1, 5 ) == "party" ) then if ( SimpleFeignHealth_Saved["noparty"] ) then SimpleFeignHealth_Saved["noparty"] = nil; checkForHunters(); print( "SimpleFeignHealh : enabled for party hunters" ); else SimpleFeignHealth_Saved["noparty"] = 1; for k, v in ValidUnits do if ( k ~= player ) then ValidUnits[k] = nil; end end print( "SimpleFeignHealh : disabled for party hunters" ); end elseif ( string.sub( strlower( msg ), 1, 2 ) == "on" ) then enable(); SimpleFeignHealth_Saved["disable"] = nil; print( "SimpleFeignHealh : enabled" ); elseif ( string.sub( strlower( msg ), 1, 3 ) == "off" ) then disable(); SimpleFeignHealth_Saved["disable"] = 1; print( "SimpleFeignHealh : disabled" ); elseif ( string.sub( strlower( msg ), 1, 6 ) == "toggle" ) then if ( SimpleFeignHealth_Saved["disable"] ) then SimpleFeignHealth_Saved["disable"] = nil; enable(); print( "SimpleFeignHealh : enabled" ); else SimpleFeignHealth_Saved["disable"] = 1; disable(); print( "SimpleFeignHealh : disabled" ); end else if ( SimpleFeignHealth_Saved["disable"] ) then print( "SimpleFeignHealh : /sfh : currently disabled" ); else print( "SimpleFeignHealh : /sfh : currently enabled" ); end print( "on / off / toggle - enable and disable this mod" ); if ( SimpleFeignHealth_Saved["noparty"] ) then print( "party hunters disabled" ); else print( "party hunters enabled" ); end print( "party - toggle showing heath / mana values for partied hunters" ); end end -- hook functions -- -------------------- function UnitHealth( unit ) local health = oldUnitHealth( unit ); local name = unitName(unit); if ( health == 0 and ValidUnits[name] and (ValidUnits[name][3] or checkFeign(unit)) ) then return getHealth(unit); end return health; end function UnitMana( unit ) local mana = oldUnitMana( unit ); local name = unitName(unit); if ( mana == 0 and ValidUnits[name] and (ValidUnits[name][3] or checkFeign(unit)) ) then if ( player and name == player ) then return getManaRegen(); elseif ( ValidUnits[name][3] ) then return ValidUnits[name][2]; end end return mana; end function UnitIsDead( unit ) local dead = oldUnitIsDead( unit ); local name = unitName(unit); if ( dead and ValidUnits[name] and (ValidUnits[name][3] or checkFeign(unit)) ) then return; end return dead; end