vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--
-- 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

Generated by GNU Enscript 1.6.5.90.