All pastes #762706 Raw Edit

Stuff

public cpp v1 · immutable
·published 2007-11-05 21:10 UTC
rendered paste body
#include "../sc_defines.h"struct MANGOS_DLL_DECL npc_generic_creatureAI : public ScriptedAI{    npc_generic_creatureAI(Creature *c) : ScriptedAI(c), spellCasting(new CreatureSpellCasting()), lastAction(getMSTime())    {        EnterEvadeMode();        c->LoadSpellInfo();        spellCasting->spellBook = c->m_creatureSpellBook;    }    //float attackReach;    CreatureSpellCasting *spellCasting;    uint64 lastAction;    uint32 runawayTimer;    float chanceToWin; // Float cause use attackrange for the moment, who sound good but wrong manner to take it    void EnterEvadeMode()    {        /*** SpellSystem ***/        //For selecting spell case        //attackReach = 3.0f; //m_creature->GetFloatValue(UNIT_FIELD_COMBATREACH) ? m_creature->GetFloatValue(UNIT_FIELD_COMBATREACH) : 1.5f;        runawayTimer = 2000;        spellCasting->reset(true);        lastAction = getMSTime()+30000;        //m_creature->RemoveAllAuras();        m_creature->DeleteThreatList();        m_creature->CombatStop();        chanceToWin = 100.0f;        DoGoHome();    }    void JustDie()    {        if( AICheckFriendTarget() ) // a healer should never ne target by a healer so, else case should be good        {                Unit* friendTarget = m_creature->GetUnit((*m_creature), m_creature->GetUInt64Value(UNIT_FIELD_TARGET));                friendTarget->m_hasHealer = false;        }        }    void DamageTaken(Unit *done_by, uint32 &damage)    {        // Make a helper Attack the Persone is attacking him, so next tick he will be a attacker.        if( !m_creature->getVictim() && AIHPPercent(m_creature) < irand(80,99) )        {           m_creature->clearUnitState(UNIT_STAT_FOLLOW);           m_creature->SetUInt64Value(UNIT_FIELD_TARGET,0);           MoveInLineOfSight(done_by);        }    }    void AttackStart(Unit *attacker)    {        if( !attacker )            return;        // AICheckFriendTarget() should not appear here, Must be Checked to be sure she never needed here.        if( AICheckFriendTarget() && AIHPPercent(attacker) > AIHPPercent(m_creature)+20 )        {            m_creature->AddThreat(attacker, 0.0f); //target can come from threat, should put at better place            return;        }        if( attacker->isTargetableForAttack() /*&& attacker!= m_creature, That should not happen*/ )        {            if ( m_creature->Attack(attacker) )            {                m_creature->AddThreat(attacker, 0.0f); //target can come from threat, should put at better place                m_creature->resetAttackTimer();                if (attacker->GetTypeId() == TYPEID_PLAYER)                    m_creature->SetLootRecipient((Player*)attacker);                return;            }        }    }    void MoveInLineOfSight(Unit *who)    {        if( !m_creature->IsWithinLOSInMap(who) || m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE )             return;        if( !m_creature->GetUInt64Value(UNIT_FIELD_TARGET) )        {            //MoveInLineOfSight Normal            if( m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature) )            {                float attackRadius = m_creature->GetAttackDistance(who);                if( m_creature->IsWithinDistInMap(who, attackRadius) )                {                    chanceToWin = attackRadius;                    // TODO:  my Stock CombatPoint < is Stock Combat Point                    // Is target got too stronger, Search Friend Closer If No One, Cast a fear Spell on her, or similar                    // If she walk near ally they will do what they have to do.                    // If friend around they will catch him if possible                                                            if( who->HasStealthAura() )                        who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);                    AttackStart(who);                    if(m_creature->m_creatureSpellBook)                        AIMotionTarget(who,FOLLOW_RANGE_CASTER);                    else                        AIMotionTarget(who,FOLLOW_RANGE_MELEE);                    // Should be Aggro Rate from Config in place 1                    if( who->GetTypeId() == TYPEID_PLAYER && attackRadius/ 1 <= irand(5,8) )                    {                        m_creature->CastSpell( (Unit*)m_creature, CREATURE_SPELL_RUNAWAY, true );                        if(m_creature->getVictim()->GetTypeId() == TYPEID_PLAYER)                            m_creature->getVictim()->SetUInt64Value(UNIT_FIELD_TARGET,0);                        runawayTimer = 5000;                    }                    return;                }                return;            }            //MoveInLineOfSight Friendly            if( m_creature->IsWithinDistInMap(who,RANGE_ASSIST ) && m_creature->IsFriendlyTo(who) && ( !who->m_hasHealer || !irand(0,20) ) ) //!irand(0,20) , can be used for Strongnest Adjustement, less Chance more easy            {                //TODO: test with IsInCombat() + Take target from AttackerList                Unit *victimTarget = who->getVictim();                if( who->getVictim() )                {                       if( m_creature->IsHostileTo(victimTarget) )                    {                        if( spellCasting->spellBook && spellCasting->spellBook->hasHealing() && AIManaPercent(m_creature) > 10 )                        {                            m_creature->SetUInt64Value( UNIT_FIELD_TARGET, who->GetGUID() );                            who->m_hasHealer = true;                            AIMotionTarget(who,(rand_norm()*3.0f)+1.0f);//Not sure i love that here... to be continued                            AISelectSpell( spellCasting );                        }                        else                        {                            AttackStart( victimTarget );                            AIMotionTarget(who,(rand_norm()*3.0f)+1.0f);//Not sure i love that here... to be continued                        }                    }                }                else if(spellCasting->spellBook && AIHPPercent(who) < 100 ) //Target is IDLE Around we Heal Of Buff if we can                    AISelectSpell( spellCasting, who );            }        }        //That has fucking too much check, must found the fastes way to dynamic heal...         //We are probaly doing something, event if, we try do something on a dynamic target        if( m_creature->IsWithinDistInMap(who, RANGE_DYNAMIC_ASSIST ) && m_creature->IsFriendlyTo(who) )        {            if( who->getVictim() && m_creature->IsFriendlyTo(who->getVictim()))                return;            else if( AIHPPercent(who) < 100 && spellCasting->spellBook                      && spellCasting->spellBook->hasHealing()                      && AIManaPercent(m_creature) > 10 && !irand(0,10))            {                    if( spellCasting->spellIndex > -1 )                {                        if( !spellCasting->reached ) //We cancel Current spell Only if not allready into casting Timer                        spellCasting->reset();                    else                        return;                }                AISelectSpell( spellCasting, who );                return;            }        }        //TODO:Dynamic cast on Enemy should not be needed ... but will test to see result.    }    void UpdateAI(const uint32 diff)    {        if( m_creature->isDead() )            return;                //run Away Spell, Causing a Like fear But no Speed Mod and No Visual Status        //Spell Work First Time: 4 Seconde, Second Time: 2 Seconde, After won't work until a Laps of Time ;)        //So pretty neet for what i need here :)        if( m_creature->getVictim() && runawayTimer > -1 )         {            if( runawayTimer / 5000 == 1 )            {                ++runaway;                m_creature->CastSpell( (Unit*)m_creature, CREATURE_SPELL_TAP_FRIEND, true );                return;            }            else if( !m_creature->HasAura(CREATURE_SPELL_RUNAWAY,0) )            {                //Check if we can use Original Caster Value in place Hack into Aura Update For fear.                m_creature->CastSpell( (Unit*)m_creature, CREATURE_SPELL_RUNAWAY, true );                if(m_creature->getVictim()->GetTypeId() == TYPEID_PLAYER)                    m_creature->getVictim()->SetUInt64Value(UNIT_FIELD_TARGET,0);                return;            }        }        //Will need a runaway Timer or Something....                //TODO: OVERIDE spellCasting->range, Check if Target is Melee range from US, if so , then Run away or follow about same range        // me->AttacPower() - him->armor() < him->AttackPower() - me-Armor(), try stick away by little push MV                //Spell Casting        if(spellCasting->spellIndex > -1)        {                Unit *target = m_creature->GetUnit( (*m_creature),m_creature->GetUInt64Value(UNIT_FIELD_TARGET) );            Unit *spellTarget = NULL;            if( spellCasting->targetGUID != m_creature->GetGUID() )                spellTarget = m_creature->GetUnit((*m_creature),spellCasting->targetGUID );            else               spellTarget = ((Unit*)m_creature);            bool dynamicTarget = false;            if(spellCasting->targetGUID != m_creature->GetGUID() && spellCasting->targetGUID != m_creature->GetUInt64Value(UNIT_FIELD_TARGET))                dynamicTarget = true;                        if(spellTarget)            {                if( !spellCasting->reached )                {                    if(dynamicTarget)                    {                        if( m_creature->IsWithinDistInMap(spellTarget, spellCasting->range) )                            spellCasting->reached = true;                        else                        {                            spellCasting->reset();                            return;                        }                      }                    else                    {                        if( spellTarget->GetGUID() == m_creature->GetGUID() || m_creature->IsWithinDistInMap(spellTarget, spellCasting->range) )                            spellCasting->reached = true;                        else                        {                            spellCasting->runningTimer += diff;                            if(spellCasting->runningTimer > irand(1000*CREATURE_WAIT_REACH_RATE,2000*CREATURE_WAIT_REACH_RATE) )                            {                                //need Speed To reach target, so we cancel Current Spell and try Speed Up.                                //DoDoSay("Too Long To Reach Target, IsStopped:%u ",m_creature->IsStopped());                                spellCasting->runningTimer = 0;                                spellCasting->reset();                                if( m_creature->m_creatureSpellBook->hasSpeed() )                                    AISelectSpell(spellCasting, NULL, SELECTSPELL_SPEED);                                //Else If CreatureSpeed < TargetSpeed , Chance To Return Home.                            }                            //return;                        }                    }                      //if( !spellCasting->reached && m_creature->IsStopped() ) // Hack                        //AIMotionTarget(target,1.0f);                 }                if( spellCasting->reached )                {                    if(!spellCasting->started)                    {                        if(!m_creature->IsStopped() && spellCasting->spellBook->info[spellCasting->spellIndex].isDelayed)                            m_creature->StopMoving();                        AICast(spellCasting);                        lastAction = getMSTime();                        return;                    }                    //Spell Finish                    else if( m_creature->m_currentSpells[CURRENT_CHANNELED_SPELL] )                     {                        if( !m_creature->HasSpellChannelActiveTimer() )                        {                            //if(!dynamicTarget && target && target->isAlive() && m_creature->hasUnitState(UNIT_STAT_FOLLOW))                                //AIMotionTarget(target, spellCasting->range/2);                            spellCasting->reset();                        }                        return;                    }                    else                    {                        spellCasting->reset();                        //if(!dynamicTarget && target && target->isAlive() && m_creature->hasUnitState(UNIT_STAT_FOLLOW))                            //AIMotionTarget(target);                        return;                    }                }            }            else if(dynamicTarget)      //Bad dynamicTarget Target             {                if(!spellCasting->reached)                    spellCasting->reset();            }            else                        //Bad Target            {                if(!spellCasting->reached)                    spellCasting->reset(true);            }            //return;        }        //Must fix Oder so creature can Strike when Running at Target waiting Spell To reach.        if( !AICheckFriendTarget() && m_creature->SelectHostilTarget() && AICheckVictimTarget() && m_creature->isAttackReady() && m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE) )        {            if(m_creature->getVictim()->HasSpellChannelActiveTimer() && m_creature->m_creatureSpellBook->hasInterrupt())            {                AISelectSpell( spellCasting,  m_creature->getVictim(), SELECTSPELL_INTERRUPT);                return;            }            //Add a Chance To win and Go to Friend.                        m_creature->AttackerStateUpdate(m_creature->getVictim());            m_creature->resetAttackTimer();            lastAction = getMSTime();        }        //Choses a Spell To Cast        if( spellCasting->spellIndex < 0 && m_creature->GetUInt64Value(UNIT_FIELD_TARGET) )            AISelectSpell( spellCasting );        //Wait Time Reset Action Selected        if(lastAction+irand(5000*CREATURE_WAIT_RATE,7000*CREATURE_WAIT_RATE) < getMSTime() )        {            if( spellCasting->spellIndex > -1 )            {                if( !spellCasting->reached )                    spellCasting->reset();                else                    return;            }            if( AICheckFriendTarget() )            {                Unit* friendTarget = m_creature->GetUnit((*m_creature), m_creature->GetUInt64Value(UNIT_FIELD_TARGET));                if( friendTarget && friendTarget->getVictim() )                {                    AISelectSpell(spellCasting,friendTarget->getVictim());                }                else if(friendTarget && AIHPPercent(friendTarget) > irand(90,99))                {                    friendTarget->m_hasHealer = false;                    m_creature->SelectHostilTarget();                         }            }            else                m_creature->SelectHostilTarget();            lastAction = getMSTime();        }    }};CreatureAI* GetAI_npc_generic_creature(Creature *_Creature){    return new npc_generic_creatureAI (_Creature);}void AddSC_npc_generic_creature(){    Script *newscript;    newscript = new Script;    newscript->Name="generic_creature";    newscript->GetAI = GetAI_npc_generic_creature;    m_scripts[nrscripts++] = newscript;}