vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[

        SelfCast: Adds self-targeting, either by use of the alt key or automatically
                copyright 2004 by Telo
        
        - If selfcast is enabled, positive spells cast without a friendly target will
          automatically target the player
        - Otherwise, if alt-casting is enabled, holding the alt key when activating a
          button will target the player

]]

--------------------------------------------------------------------------------------------------
-- Localizable strings
--------------------------------------------------------------------------------------------------

SELFCAST_HELP = "help";                         -- must be lowercase; displays help
SELFCAST_STATUS = "status";                     -- must be lowercase; shows status
SELFCAST_ON = "on";                                     -- must be lowercase; for historical reasons, turns self-targeting on
SELFCAST_OFF = "off";                           -- must be lowercase; for historical reasons, turns self-trageting off
SELFCAST_SELFON = "selfon";                     -- must be lowercase; turns self-targeting on
SELFCAST_SELFOFF = "selfoff";           -- must be lowercase; turns self-targeting off
SELFCAST_ALTON = "alton";                       -- must be lowercase; turns alt-casting on
SELFCAST_ALTOFF = "altoff";                     -- must be lowercase; turns alt-casting off

SELFCAST_STATUS_HEADER = "|cffffff00SelfCast status:|r";
SELFCAST_STATUS_SELFON = "SelfCast: |cff00ff00Auto self casting is -ON-.  Beneficial spells will be cast on yourself if you don't have an ally targeted.|r";
SELFCAST_STATUS_SELFOFF = "SelfCast: |cff00ff00Auto self casting is -OFF-.  Beneficial spells must be explicitly targeted.|r";
SELFCAST_STATUS_ALTON = "SelfCast: Alt-casting is on.  Holding Alt while using an action button will target you, if possible.";
SELFCAST_STATUS_ALTOFF = "SelfCast: Alt-casting is off.";

SELFCAST_HELP_TEXT0 = " ";
SELFCAST_HELP_TEXT1 = "|cffffff00SelfCast command help:|r";
SELFCAST_HELP_TEXT2 = "|cff00ff00Use |r|cffffffff/selfcast <command>|r|cff00ff00 or |r|cffffffff/sc <command>|r|cff00ff00 to perform the following commands:|r";
SELFCAST_HELP_TEXT3 = "|cffffffff"..SELFCAST_HELP.."|r|cff00ff00: displays this message.|r";
SELFCAST_HELP_TEXT4 = "|cffffffff"..SELFCAST_STATUS.."|r|cff00ff00: displays status information about the current option settings.|r";
SELFCAST_HELP_TEXT5 = "|cffffffff"..SELFCAST_SELFON.."|r|cff00ff00: turns on auto self casting.  When on, beneficial spells will be cast on yourself if you don't have an ally targeted.|r";
SELFCAST_HELP_TEXT6 = "|cffffffff"..SELFCAST_SELFOFF.."|r|cff00ff00: turns off auto self casting.|r";
SELFCAST_HELP_TEXT7 = "|cffffffff"..SELFCAST_ALTON.."|r|cff00ff00: turns on Alt-casting.  When on, holding Alt while using an action button will target you, if possible.|r";
SELFCAST_HELP_TEXT8 = "|cffffffff"..SELFCAST_ALTOFF.."|r|cff00ff00: turns off Alt-casting.|r";
SELFCAST_HELP_TEXT9 = " ";
SELFCAST_HELP_TEXT10 = "|cff00ff00For example: |r|cffffffff/selfcast selfon|r|cff00ff00 will turn on auto self casting.|r";
SELFCAST_HELP_TEXT11 = " ";
SELFCAST_HELP_TEXT12 = "|cff00ff00Using just |r|cffffffff/selfcast|r|cff00ff00 or |r|cffffffff/sc|r|cff00ff00 without any options will toggle auto-self casting between on and off.";

--------------------------------------------------------------------------------------------------
-- Local variables
--------------------------------------------------------------------------------------------------

-- The list of desired self-cast spells
local localSelfCast = { };
-- Druid
localSelfCast["Abolish Poison"] = 1;
localSelfCast["Cure Poison"] = 1;
localSelfCast["Healing Touch"] = 1;
localSelfCast["Innervate"] = 1;
localSelfCast["Mark of the Wild"] = 1;
localSelfCast["Regrowth"] = 1;
localSelfCast["Rejuvenation"] = 1;
localSelfCast["Remove Curse"] = 1;
localSelfCast["Thorns"] = 1;
-- Mage
localSelfCast["Amplify Magic"] = 1;
localSelfCast["Arcane Intellect"] = 1;
localSelfCast["Dampen Magic"] = 1;
localSelfCast["Remove Lesser Curse"] = 1;
-- Paladin
localSelfCast["Cleanse"] = 1;
localSelfCast["Flash of Light"] = 1;
localSelfCast["Holy Light"] = 1;
localSelfCast["Purify"] = 1;
localSelfCast["Lay on Hands"] = 1;
localSelfCast["Blessing of Freedom"] = 1;
localSelfCast["Blessing of Fury"] = 1;
localSelfCast["Blessing of Kings"] = 1;
localSelfCast["Blessing of Light"] = 1;
localSelfCast["Blessing of Might"] = 1;
localSelfCast["Blessing of Protection"] = 1;
localSelfCast["Blessing of Reckoning"] = 1;
localSelfCast["Blessing of Righteousness"] = 1;
localSelfCast["Blessing of Salvation"] = 1;
localSelfCast["Blessing of Sanctuary"] = 1;
localSelfCast["Blessing of Wisdom"] = 1;
-- Priest
localSelfCast["Abolish Disease"] = 1;
localSelfCast["Cure Disease"] = 1;
localSelfCast["Dispel Magic"] = 2;
localSelfCast["Divine Spirit"] = 1;
localSelfCast["Fear Ward"] = 1;
localSelfCast["Flash Heal"] = 1;
localSelfCast["Greater Heal"] = 1;
localSelfCast["Lesser Heal"] = 1;
localSelfCast["Heal"] = 1;
localSelfCast["Power Word: Fortitude"] = 1;
localSelfCast["Power Word: Shield"] = 1;
localSelfCast["Renew"] = 1;
localSelfCast["Shadow Protection"] = 1;
localSelfCast["Power Infusion"] = 1;
-- Shaman
localSelfCast["Chain Heal"] = 1;
localSelfCast["Cure Disease"] = 1;
localSelfCast["Cure Poison"] = 1;
localSelfCast["Healing Wave"] = 1;
localSelfCast["Lesser Healing Wave"] = 1;
localSelfCast["Water Breathing"] = 1;
localSelfCast["Water Walking"] = 1;
-- Warlock
localSelfCast["Detect Greater Invisibility"] = 1;
localSelfCast["Detect Invisibility"] = 1;
localSelfCast["Detect Lesser Invisibility"] = 1;
localSelfCast["Unending Breath"] = 1;
-- First Aid
localSelfCast["Linen Bandage"] = 1;
localSelfCast["Heavy Linen Bandage"] = 1;
localSelfCast["Wool Bandage"] = 1;
localSelfCast["Heavy Wool Bandage"] = 1;
localSelfCast["Silk Bandage"] = 1;
localSelfCast["Heavy Silk Bandage"] = 1;
localSelfCast["Mageweave Bandage"] = 1;
localSelfCast["Heavy Mageweave Bandage"] = 1;
localSelfCast["Anti-Venom"] = 1;
localSelfCast["Strong Anti-Venom"] = 1;
localSelfCast["Runecloth Bandage"] = 1;
localSelfCast["Heavy Runecloth Bandage"] = 1;
-- Miscellaneous
localSelfCast["Crystal Force"] = 1;
localSelfCast["Crystal Restore"] = 1;
localSelfCast["Crystal Spire"] = 1;
localSelfCast["Crystal Ward"] = 1;

-- Function hooks
local lOriginal_UseAction;
local lOriginal_GameTooltip_ClearMoney;

--------------------------------------------------------------------------------------------------
-- Internal functions
--------------------------------------------------------------------------------------------------

local function SelfCast_MoneyToggle()
        if( lOriginal_GameTooltip_ClearMoney ) then
                GameTooltip_ClearMoney = lOriginal_GameTooltip_ClearMoney;
                lOriginal_GameTooltip_ClearMoney = nil;
        else
                lOriginal_GameTooltip_ClearMoney = GameTooltip_ClearMoney;
                GameTooltip_ClearMoney = SelfCast_GameTooltip_ClearMoney;
        end
end

local function SelfCastStatus()
        if( DEFAULT_CHAT_FRAME ) then
                DEFAULT_CHAT_FRAME:AddMessage(SELFCAST_STATUS_HEADER);
                if( SelfCastState ) then
                        if( SelfCastState.AutoSelfCast ) then
                                DEFAULT_CHAT_FRAME:AddMessage(SELFCAST_STATUS_SELFON);
                        else
                                DEFAULT_CHAT_FRAME:AddMessage(SELFCAST_STATUS_SELFOFF);
                        end
                        if( SelfCastState.AltOff ) then
                                DEFAULT_CHAT_FRAME:AddMessage(SELFCAST_STATUS_ALTOFF);
                        else
                                DEFAULT_CHAT_FRAME:AddMessage(SELFCAST_STATUS_ALTON);
                        end
                else
                        DEFAULT_CHAT_FRAME:AddMessage(SELFCAST_STATUS_SELFOFF);
                        DEFAULT_CHAT_FRAME:AddMessage(SELFCAST_STATUS_ALTON);
                end
        end
end

function SelfCast(msg)
        if( msg ) then
                local command = string.lower(msg);
                if( command == "" ) then
                        if( SelfCastState.AutoSelfCast ) then
                                SelfCastState.AutoSelfCast = nil;
                        else
                                SelfCastState.AutoSelfCast = 1;
                        end
                        SelfCastStatus();
                elseif( command == SELFCAST_HELP ) then
                        local index = 0;
                        local value = getglobal("SELFCAST_HELP_TEXT"..index);
                        while( value ) do
                                DEFAULT_CHAT_FRAME:AddMessage(value);
                                index = index + 1;
                                value = getglobal("SELFCAST_HELP_TEXT"..index);
                        end
                elseif( command == SELFCAST_STATUS ) then
                        SelfCastStatus();
                elseif( command == SELFCAST_SELFON or command == SELFCAST_ON ) then
                        SelfCastState.AutoSelfCast = 1;
                        SelfCastStatus();
                elseif( command == SELFCAST_SELFOFF or command == SELFCAST_OFF ) then
                        SelfCastState.AutoSelfCast = nil;
                        SelfCastStatus();
                elseif( command == SELFCAST_ALTON ) then
                        SelfCastState.AltOff = nil;
                        SelfCastStatus();
                elseif( command == SELFCAST_ALTOFF ) then
                        SelfCastState.AltOff = 1;
                        SelfCastStatus();
                end
        end
end

--------------------------------------------------------------------------------------------------
-- OnFoo functions
--------------------------------------------------------------------------------------------------

function SelfCast_OnLoad()
        -- Register our slash command
        SLASH_SELFCAST1 = "/selfcast";
        SLASH_SELFCAST2 = "/sc";
        SlashCmdList["SELFCAST"] = function(msg)
                SelfCast(msg);
        end

        -- Hook UseAction
        lOriginal_UseAction = UseAction;
        UseAction = SelfCast_UseAction;
        
        this:RegisterEvent("VARIABLES_LOADED");

        if( DEFAULT_CHAT_FRAME ) then
                DEFAULT_CHAT_FRAME:AddMessage("Telo's SelfCast AddOn loaded");
        end
        UIErrorsFrame:AddMessage("Telo's SelfCast AddOn loaded", 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME);
end

function SelfCast_OnEvent()
        if( event == "VARIABLES_LOADED" ) then
                if( not SelfCastState ) then
                        SelfCastState = { };
                end
                if( AutoSelfCast ) then
                        SelfCastState.AutoSelfCast = 1;
                end
                SelfCastStatus();
        end
end

function SelfCast_UseAction(id, type, self)
        local fSelfCast;
        local fSelfCastable;

        if( not SelfCastState.AltOff and IsAltKeyDown() ) then
                fSelfCast = 1;
        elseif( SelfCastState.AutoSelfCast ) then
                -- protect money frame while we set hidden tooltip
                SelfCast_MoneyToggle();
                SelfCastTooltip:SetOwner(UIParent, "ANCHOR_NONE");
                SelfCastTooltip:SetAction(id);
                SelfCast_MoneyToggle();
                
                local name = getglobal("SelfCastTooltipTextLeft1"):GetText();
                if( name and localSelfCast[name] ) then
                        -- This spell is self-castable
                        fSelfCastable = 1;
                        
                        if( not UnitExists("target") or UnitCanAttack("player", "target") or
                                (not UnitIsPVP("target") and (not UnitPlayerControlled("target") or UnitLevel("target") == 1)) ) then
                                fSelfCast = 1;
                        end
                        
                        -- Don't self-cast certain spells if you have any target at all
                        if( localSelfCast[name] == 2 and UnitExists("target") ) then
                                fSelfCast = nil;
                        end
                end
        end
        
        if( fSelfCast ) then
                lOriginal_UseAction(id, type, 1);
        else
                lOriginal_UseAction(id, type, self);
        end
        
        if( fSelfCast or fSelfCastable ) then
                if( SpellIsTargeting() ) then
                        SpellTargetUnit("player");
                end
                if( SpellIsTargeting() ) then
                        TargetUnit("player");
                end
        end
end

--------------------------------------------------------------------------------------------------
-- Hooked functions
--------------------------------------------------------------------------------------------------

function SelfCast_GameTooltip_ClearMoney()
        -- Intentionally empty; don't clear money while we use hidden tooltips
end