All pastes #951430 Raw Edit

Unnamed

public text v1 · immutable
·published 2008-03-21 11:36 UTC
rendered paste body
/* Copyright (C) 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


#include "../sc_defines.h"

#define generic_creature_beta_COOLDOWN   5000

struct MANGOS_DLL_DECL generic_creature_betaAI : public ScriptedAI
{
    generic_creature_betaAI(Creature *c) : ScriptedAI(c) {Reset();}

    uint32 GlobalCooldown;      //This variable acts like the global cooldown that players have (1.5 seconds)
    uint32 BuffTimer;           //This variable keeps track of buffs
    bool InCombat;
    bool IsFeared;              //This variable keeps track of fear asura
    bool IsFlee;                //This variable keeps track of fleeing humanoids
    bool HasFled;              //This variable keeps track of fleeing humanoids make sure only 1 chance
    bool SlowSpell;             //This variable keeps track of auras that increase casting times
	bool CanFlee;				//This variable keeps of creatures that can flee from battle
    bool IsHuman;				//This variable states with creature is human.

   void Reset()
    {
        GlobalCooldown = 0;
        BuffTimer = 0;          //Rebuff as soon as we can
        InCombat = false;
        IsFeared = false;
        IsFlee = false;
        SlowSpell = false;
        HasFled = false;
		CanFlee = false;
        if (m_creature->GetCreatureType() == CREATURE_TYPE_HUMANOID)
            {IsHuman = true;}
        else
            {IsHuman = false;}
        m_creature->RemoveAllAuras();
        m_creature->DeleteThreatList();
        m_creature->CombatStop();
        DoGoHome();
    }

    void AttackStart(Unit *who)
    {
        if (!who)
            return;

        if (who->isTargetableForAttack() && who!= m_creature)
        {
            //Begin melee attack if we are within range
            DoStartMeleeAttack(who);
            InCombat = true;
        }
    }

    void MoveInLineOfSight(Unit *who)
    {
        if (!who || m_creature->getVictim())
            return;
		// detect family member that needs help
		//here need to add check for freindly move in line of sight with fear aura & same familiy
		//then attack what make freindly unit flee.
		if (m_creature->IsFriendlyTo(who) && who->hasUnitState(UNIT_STAT_FLEEING) && m_creature->GetDistanceZ(who) <= 1 && m_creature->IsWithinLOSInMap(who) && !InCombat) 
			{
			float attackRadius = (m_creature->GetAttackDistance(who) /3);
			if (m_creature->IsWithinDistInMap(who, attackRadius))
			{
				Unit* target = NULL;
				target = who->getVictim();
				DoStartMeleeAttack(target);
				if (rand() % 3 == 0)
				{
                who->RemoveSpellsCausingAura(SPELL_AURA_MOD_FEAR);
				}
			}
			}
        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
        {
            float attackRadius = m_creature->GetAttackDistance(who);
            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
            {
                if(who->HasStealthAura())
                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);

                //Begin melee attack if we are within range
                DoStartMeleeAttack(who);

                InCombat = true;
            }
        }
    }

    void UpdateAI(const uint32 diff)
    {
        //Always decrease our global cooldown first
        if (GlobalCooldown > diff)
			{GlobalCooldown -= diff;}
        else 
			{ GlobalCooldown = 0;}

		//Check to see if creature is able to flee from battle or not
		if ((m_creature->GetHealth()*6.66 < m_creature->GetMaxHealth()) && IsHuman)
			{CanFlee = true;}
		else
			{CanFlee = false;}
        
        // other checked need adding for other auras that effect creature spell casting times with possible rank support
        if (m_creature->HasAuraType(SPELL_AURA_HASTE_SPELLS) 
            || m_creature->HasAuraType(SPELL_AURA_MOD_LANGUAGE))
        {
            if (!SlowSpell)
			{GlobalCooldown *= 2;
            SlowSpell = true;}
         else 
			{SlowSpell = false;}
        }
        
        // Check for fear, may need to add other things here like polymorph and others that render creature useless for XX seconds
        if ((m_creature->HasAuraType(SPELL_AURA_MOD_FEAR)) 
            || (m_creature->HasAuraType(SPELL_AURA_MOD_CHARM)) 
            || (m_creature->HasAuraType(SPELL_AURA_MOD_POSSESS))) 
			//set IsFeared = true dissables all spell casting abilities last on int he script
			{IsFeared = true;}
        else 
			{IsFeared = false;}

        // Make humaniod flee for 6-10 seconds, @ 15% HP give 30% chance to flee aslong as not stuned
		if (!HasFled)
		{
        if (!IsFlee && !IsFeared && CanFlee && (!m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) && ((!m_creature->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNDED | UNIT_STAT_ROOT)) || !m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) || (!m_creature->HasAuraType(SPELL_AURA_PREVENTS_FLEEING) )) )
        {
			if (rand() % 3 == 0)
				{
				//Cancel our current spell
				m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
				//This is a semi work around, core needs a Flee_Movement_Gen
				m_creature->CastSpell(m_creature,8225, true); // self cast run away
				IsFeared = true;
				IsFlee = true; 
				HasFled = true;
				}
			else 
				{HasFled = true;} //prevent multi checks to flee
        }
		}

        if (!IsFeared) 
        {        
            //Buff timer (only buff when we are alive and not in combat
            if (!InCombat && m_creature->isAlive())
            {
                if (BuffTimer < diff )
                {
                    //Find a spell that targets friendly and applies an aura (these are generally buffs)
                    SpellEntry const *info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA);

                    if (info && !GlobalCooldown && !m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)  )
                    {
                        //Cast the buff spell
                        DoCastSpell(m_creature, info);

                        //Set our global cooldown
                        GlobalCooldown = generic_creature_beta_COOLDOWN;

                        //Set our timer to 10 minutes before rebuff
                        BuffTimer = 600000;
                    }//Try agian in 30 seconds
                    else BuffTimer = 30000;
                } else BuffTimer -= diff;
            }

            //Return since we have no target
            if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
                return;

            
                //If we are within range melee the target
                if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
                {
                    //Make sure our attack is ready and we arn't currently casting
                    if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false) && !m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)  )
                    {
                        bool Healing = false;
                        SpellEntry const *info = NULL;

                        //Select a healing spell if less than 30% hp
                        if (m_creature->GetHealth()*3.33 < m_creature->GetMaxHealth())
                            info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);

                        //No healing spell available, select a hostile spell
                        if (info) 
                            Healing = true;
                        else 
                            info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE);

                        //50% chance if elite or higher, 20% chance if not, to replace our white hit with a spell
                        if (info && (rand() % (m_creature->GetCreatureInfo()->rank > 1 ? 2 : 5) == 0) && !GlobalCooldown)
                        {
                            //Cast the spell
                            if (Healing)
                                DoCastSpell(m_creature, info);
                            else 
                                DoCastSpell(m_creature->getVictim(), info);

                            //Set our global cooldown
                            GlobalCooldown = generic_creature_beta_COOLDOWN;
                        } else
                        {
                            m_creature->AttackerStateUpdate(m_creature->getVictim());
                        }

                        m_creature->resetAttackTimer();
                    }
                } else 
                {
                    //Only run this code if we arn't already casting
                    if (!m_creature->IsNonMeleeSpellCasted(false) && !m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)  )
                    {
                        bool Healing = false;
                        SpellEntry const *info = NULL;

                        //Select a healing spell if less than 30% hp ONLY 33% of the time
                        if (m_creature->GetHealth()*3.33 < m_creature->GetMaxHealth() && rand() % 3 == 0)
                            info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);

                        //No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
                        if (info) 
                            Healing = true;
                        else 
                            info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, ATTACK_DISTANCE, 0, SELECT_EFFECT_DONTCARE);
                   
                        //Found a spell, check if we arn't on cooldown
                        if (info && !GlobalCooldown)
                        {
                            //If we are currently moving stop us and set the movement generator
                           /* if (!IsSelfRooted)
                            {
                                IsSelfRooted = true;
                            }*/
    
                            //Face target
                            DoFaceTarget(m_creature->getVictim());

                            //Cast spell
                            if (Healing) 
                                DoCastSpell(m_creature,info);
                            else 
                                DoCastSpell(m_creature->getVictim(),info);

                            //Set our global cooldown
                            GlobalCooldown = generic_creature_beta_COOLDOWN;
                            

                        }
                    }
                }
            }
        }
}; 
CreatureAI* GetAI_generic_creature_beta(Creature *_Creature)
{
    return new generic_creature_betaAI (_Creature);
}


void AddSC_generic_creature_beta()
{
    Script *newscript;
    newscript = new Script;
    newscript->Name="generic_creature_beta";
    newscript->GetAI = GetAI_generic_creature_beta;
    m_scripts[nrscripts++] = newscript;
}