bool
FleeingMovementGenerator<T>::_setMoveData(T &owner)
{
    float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z);

    if(i_to_distance_from_caster > 0.0f)
    {
        if((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster)   ||
                // if we reach lower distance
                (i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz > i_last_distance_from_caster) ||
                // if we can't be close
                (i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster)   ||
                // if we reach bigger distance
                (cur_dist_xyz > MAX_QUIET_DISTANCE) ||           // if we are too far
                (i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE) )
            // if we leave 'quiet zone'
        {
            // we are very far or too close, stopping
            i_to_distance_from_caster = 0.0f;
            i_nextCheckTime.Reset( urand(500,1000) );
            return false;
        }
        else
        {
            // now we are running, continue
            i_last_distance_from_caster = cur_dist_xyz;
            return true;
        }
    }

    float cur_dist;
    float angle_to_caster;

    Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);

    if(fright)
    {
        cur_dist = fright->GetDistance(&owner);
        if(cur_dist < cur_dist_xyz)
        {
            i_caster_x = fright->GetPositionX();
            i_caster_y = fright->GetPositionY();
            i_caster_z = fright->GetPositionZ();
            angle_to_caster = fright->GetAngle(&owner);
        }
        else
        {
            cur_dist = cur_dist_xyz;
            angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
        }
    }
    else
    {
        cur_dist = cur_dist_xyz;
        angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
    }

    // if we too close may use 'path-finding' else just stop
    i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3;

    //get angle and 'distance from caster' to run
    float angle;

    if(i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time
    {
        angle = rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * M_PI/3 + rand_norm()*M_PI*2/3;
        i_to_distance_from_caster = MIN_QUIET_DISTANCE;
        i_only_forward = true;
    }
    else if(cur_dist < MIN_QUIET_DISTANCE)
    {
        angle = M_PI/6 + rand_norm()*M_PI*2/3;
        i_to_distance_from_caster = cur_dist*2/3 + rand_norm()*(MIN_QUIET_DISTANCE - cur_dist*2/3);
    }
    else if(cur_dist > MAX_QUIET_DISTANCE)
    {
        angle = rand_norm()*M_PI/3 + M_PI*2/3;
        i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
    }
    else
    {
        angle = rand_norm()*M_PI;
        i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
    }

    int8 sign = rand_norm() > 0.5f ? 1 : -1;
    i_cur_angle = sign*angle + angle_to_caster;

    // current distance
    i_last_distance_from_caster = cur_dist;

    return true;
}
Example #2
1
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (me->getVictim() && me->isAlive())
            {
                if (HealthAbovePct(50))
                {
                    if (Charge_Timer <= diff)
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        {
                            DoCast(target, SPELL_CHARGE);
                            AttackStart(target);
                        }

                        Charge_Timer = 15000 + rand()%15000;
                    } else Charge_Timer -= diff;

                    if (SonicBurst_Timer <= diff)
                    {
                        DoCast(me->getVictim(), SPELL_SONICBURST);
                        SonicBurst_Timer = 8000 + rand()%5000;
                    } else SonicBurst_Timer -= diff;

                    if (Screech_Timer <= diff)
                    {
                        DoCast(me->getVictim(), SPELL_SCREECH);
                        Screech_Timer = 18000 + rand()%8000;
                    } else Screech_Timer -= diff;

                    if (SpawnBats_Timer <= diff)
                    {
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);

                        Creature* Bat = NULL;
                        Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);
                        Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (target && Bat) Bat ->AI()->AttackStart(target);

                        SpawnBats_Timer = 60000;
                    } else SpawnBats_Timer -= diff;
                }
                else
                {
                    if (PhaseTwo)
                    {
                        if (PhaseTwo && ShadowWordPain_Timer <= diff)
                        {
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                            {
                                DoCast(target, SPELL_SHADOW_WORD_PAIN);
                                ShadowWordPain_Timer = 12000 + rand()%6000;
                            }
                        }
                        ShadowWordPain_Timer -=diff;

                        if (MindFlay_Timer <= diff)
                        {
                            DoCast(me->getVictim(), SPELL_MIND_FLAY);
                            MindFlay_Timer = 16000;
                        }
                        MindFlay_Timer -=diff;

                        if (ChainMindFlay_Timer <= diff)
                        {
                            me->InterruptNonMeleeSpells(false);
                            DoCast(me->getVictim(), SPELL_CHAIN_MIND_FLAY);
                            ChainMindFlay_Timer = 15000 + rand()%15000;
                        }
                        ChainMindFlay_Timer -=diff;

                        if (GreaterHeal_Timer <= diff)
                        {
                            me->InterruptNonMeleeSpells(false);
                            DoCast(me, SPELL_GREATERHEAL);
                            GreaterHeal_Timer = 25000 + rand()%10000;
                        }
                        GreaterHeal_Timer -=diff;

                        if (SpawnFlyingBats_Timer <= diff)
                        {
                            Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                            if (!target)
                                return;

                            Creature* FlyingBat = me->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                            if (FlyingBat)
                                FlyingBat->AI()->AttackStart(target);

                            SpawnFlyingBats_Timer = 10000 + rand()%5000;
                        } else SpawnFlyingBats_Timer -=diff;
                    }
                    else
                    {
                        me->SetDisplayId(15219);
                        DoResetThreat();
                        PhaseTwo = true;
                    }
                }

                DoMeleeAttackIfReady();
            }
        }
Example #3
1
 void HandleFlightSequence()
 {
     switch(FlightCount)
     {
     case 0:
         //me->AttackStop();
         error_log("prevent fly phase");
         me->GetMotionMaster()->Clear(false);
         me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
         me->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
         me->StopMoving();
         DoScriptText(YELL_TAKEOFF, me);
         Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
         break;
     case 1:
         error_log("Move to Fly point");
         me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+1, me->GetPositionY(), me->GetPositionZ()+10);
         Timer[EVENT_FLIGHT_SEQUENCE] = 0;
         break;
     case 2: {
         error_log("Summon Vapor case 2");
         Unit *pTarget;
         pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
         if (!pTarget) pTarget = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_PLAYER_GUID) : 0);
         if (pTarget)
         {
             Creature* Vapor = me->SummonCreature(MOB_VAPOR, pTarget->GetPositionX()-5+rand()%10, pTarget->GetPositionY()-5+rand()%10, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
             if (Vapor)
             {
                 Vapor->AI()->AttackStart(pTarget);
                 me->InterruptNonMeleeSpells(false);
                 DoCast(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
                 Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
             }
         }
         else
         {
             EnterEvadeMode();
             return;
         }
         Timer[EVENT_FLIGHT_SEQUENCE] = 10000;
         break;
     }
     case 3: {
         DespawnSummons(MOB_VAPOR_TRAIL);
         error_log("Summon Vapor case3");
         //DoCast(me, SPELL_VAPOR_SELECT); need core support
         Unit *pTarget;
         pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
         if (!pTarget) pTarget = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_PLAYER_GUID) : 0);
         if (pTarget)
         {
             //pTarget->CastSpell(pTarget, SPELL_VAPOR_SUMMON, true); need core support
             Creature* Vapor = me->SummonCreature(MOB_VAPOR, pTarget->GetPositionX()-5+rand()%10, pTarget->GetPositionY()-5+rand()%10, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
             if (Vapor)
             {
                 Vapor->AI()->AttackStart(pTarget);
                 me->InterruptNonMeleeSpells(false);
                 DoCast(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
                 Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
             }
         }
         else
         {
             EnterEvadeMode();
             return;
         }
         Timer[EVENT_FLIGHT_SEQUENCE] = 10000;
         break;
     }
     case 4:
         DespawnSummons(MOB_VAPOR_TRAIL);
         Timer[EVENT_FLIGHT_SEQUENCE] = 1;
         break;
     case 5: {
         Unit *pTarget;
         pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
         if (!pTarget) pTarget = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_PLAYER_GUID) : 0);
         if (pTarget)
         {
             BreathX = pTarget->GetPositionX();
             BreathY = pTarget->GetPositionY();
             float x, y, z;
             pTarget->GetContactPoint(me, x, y, z, 70);
             me->GetMotionMaster()->MovePoint(0, x, y, z+10);
         } else
         {
             EnterEvadeMode();
             return;
         }
         Timer[EVENT_FLIGHT_SEQUENCE] = 0;
         break;
     }
     case 6:
         me->SetOrientation(me->GetAngle(BreathX, BreathY));
         me->StopMoving();
         //DoTextEmote("takes a deep breath.", NULL);
         Timer[EVENT_FLIGHT_SEQUENCE] = 10000;
         break;
     case 7:
         DoCast(me, SPELL_FOG_BREATH, true);
         {
             float x, y, z;
             me->GetPosition(x, y, z);
             x = 2 * BreathX - x;
             y = 2 * BreathY - y;
             me->GetMotionMaster()->MovePoint(0, x, y, z);
         }
         Timer[EVENT_SUMMON_FOG] = 1;
         Timer[EVENT_FLIGHT_SEQUENCE] = 0;
         break;
     case 8:
         me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
         ++BreathCount;
         Timer[EVENT_SUMMON_FOG] = 0;
         Timer[EVENT_FLIGHT_SEQUENCE] = 1;
         if (BreathCount < 3) FlightCount = 4;
         break;
     case 9:
         if (Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0))
         {
             float x, y, z;
             pTarget->GetContactPoint(me, x, y, z);
             me->GetMotionMaster()->MovePoint(0, x, y, z);
         }
         else
         {
             EnterEvadeMode();
             return;
         }
         Timer[EVENT_FLIGHT_SEQUENCE] = 0;
         break;
     case 10:
         me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
         me->StopMoving();
         me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
         EnterPhase(PHASE_GROUND);
         me->AI()->AttackStart(SelectUnit(SELECT_TARGET_TOPAGGRO, 0));
         break;
     default:
         break;
     }
     ++FlightCount;
 }
Example #4
1
        void HandleFlightSequence()
        {
            switch (uiFlightCount)
            {
            case 0:
                //me->AttackStop();
                me->GetMotionMaster()->Clear(false);
                me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
                me->StopMoving();
                Talk(YELL_TAKEOFF);
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 2000);
                break;
            case 1:
                me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+1, me->GetPositionY(), me->GetPositionZ()+10);
                break;
            case 2:
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
                if (!target)
                    target = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0);

                if (!target)
                {
                    EnterEvadeMode();
                    return;
                }

                Creature* Vapor = me->SummonCreature(MOB_VAPOR, target->GetPositionX()-5+rand()%10, target->GetPositionY()-5+rand()%10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
                if (Vapor)
                {
                    Vapor->AI()->AttackStart(target);
                    me->InterruptNonMeleeSpells(false);
                    DoCast(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
                    Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
                }

                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10000);
                break;
            }
            case 3:
            {
                DespawnSummons(MOB_VAPOR_TRAIL);
                //DoCast(me, SPELL_VAPOR_SELECT); need core support

                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
                if (!target)
                    target = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0);

                if (!target)
                {
                    EnterEvadeMode();
                    return;
                }

                //target->CastSpell(target, SPELL_VAPOR_SUMMON, true); need core support
                Creature* pVapor = me->SummonCreature(MOB_VAPOR, target->GetPositionX()-5+rand()%10, target->GetPositionY()-5+rand()%10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
                if (pVapor)
                {
                    if (pVapor->AI())
                        pVapor->AI()->AttackStart(target);
                    me->InterruptNonMeleeSpells(false);
                    DoCast(pVapor, SPELL_VAPOR_CHANNEL, false); // core bug
                    pVapor->CastSpell(pVapor, SPELL_VAPOR_TRIGGER, true);
                }

                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10000);
                break;
            }
            case 4:
                DespawnSummons(MOB_VAPOR_TRAIL);
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1);
                break;
            case 5:
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true);
                if (!target)
                    target = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0);

                if (!target)
                {
                    EnterEvadeMode();
                    return;
                }

                breathX = target->GetPositionX();
                breathY = target->GetPositionY();
                float x, y, z;
                target->GetContactPoint(me, x, y, z, 70);
                me->GetMotionMaster()->MovePoint(0, x, y, z+10);
                break;
            }
            case 6:
                me->SetOrientation(me->GetAngle(breathX, breathY));
                me->StopMoving();
                //DoTextEmote("takes a deep breath.", NULL);
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 10000);
                break;
            case 7:
            {
                DoCast(me, SPELL_FOG_BREATH, true);
                float x, y, z;
                me->GetPosition(x, y, z);
                x = 2 * breathX - x;
                y = 2 * breathY - y;
                me->GetMotionMaster()->MovePoint(0, x, y, z);
                events.ScheduleEvent(EVENT_SUMMON_FOG, 1);
                break;
            }
            case 8:
                me->CastStop(SPELL_FOG_BREATH);
                me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
                ++uiBreathCount;
                events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1);
                if (uiBreathCount < 3)
                    uiFlightCount = 4;
                break;
            case 9:
                if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                    DoStartMovement(target);
                else
                {
                    EnterEvadeMode();
                    return;
                }
                break;
            case 10:
                me->SetDisableGravity(false);
                me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                EnterPhase(PHASE_GROUND);
                AttackStart(SelectTarget(SELECT_TARGET_TOPAGGRO));
                break;
            }
            ++uiFlightCount;
        }
Example #5
1
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        if (m_creature->getVictim() && m_creature->isAlive())
        {
            if (PoisonVolley_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_POISONVOLLEY);
                PoisonVolley_Timer = 10000 + rand()%10000;
            } else PoisonVolley_Timer -= diff;

            if (!PhaseTwo && Aspect_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_ASPECT_OF_MARLI);
                Aspect_Timer = 13000 + rand()%5000;
            } else Aspect_Timer -= diff;

            if (!Spawned && SpawnStartSpiders_Timer < diff)
            {
                DoScriptText(SAY_SPIDER_SPAWN, m_creature);

                Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if (!target)
                    return;

                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if (Spider)
                    Spider->AI()->AttackStart(target);
                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if (Spider)
                    Spider->AI()->AttackStart(target);
                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if (Spider)
                    Spider->AI()->AttackStart(target);
                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if (Spider)
                    Spider->AI()->AttackStart(target);

                Spawned = true;
            } else SpawnStartSpiders_Timer -= diff;

            if (SpawnSpider_Timer < diff)
            {
                Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if (!target)
                    return;

                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if (Spider)
                    Spider->AI()->AttackStart(target);
                SpawnSpider_Timer = 12000 + rand()%5000;
            } else SpawnSpider_Timer -= diff;

            if (!PhaseTwo && Transform_Timer < diff)
            {
                DoScriptText(SAY_TRANSFORM, m_creature);
                DoCast(m_creature,SPELL_SPIDER_FORM);
                const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
                m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
                m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
                m_creature->UpdateDamagePhysical(BASE_ATTACK);
                DoCast(m_creature->getVictim(),SPELL_ENVOLWINGWEB);

                if (DoGetThreat(m_creature->getVictim()))
                    DoModifyThreatPercent(m_creature->getVictim(),-100);

                PhaseTwo = true;
                Transform_Timer = 35000 + rand()%25000;
            } else Transform_Timer -= diff;

            if (PhaseTwo)
            {
                if (Charge_Timer < diff)
                {
                    Unit* target = NULL;
                    int i = 0 ;
                    while (i < 3)                           // max 3 tries to get a random target with power_mana
                    {
                        ++i;                                //not aggro leader
                        target = SelectUnit(SELECT_TARGET_RANDOM,1);
                        if (target)
                            if (target->getPowerType() == POWER_MANA)
                                i=3;
                    }
                    if (target)
                    {
                        DoCast(target, SPELL_CHARGE);
                        //m_creature->GetMap()->CreatureRelocation(m_creature, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
                        //m_creature->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true,1);
                        AttackStart(target);
                    }

                    Charge_Timer = 8000;
                } else Charge_Timer -= diff;

                if (TransformBack_Timer < diff)
                {
                    m_creature->SetDisplayId(15220);
                    const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
                    m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1)));
                    m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1)));
                    m_creature->UpdateDamagePhysical(BASE_ATTACK);

                    PhaseTwo = false;
                    TransformBack_Timer = 25000 + rand()%15000;
                } else TransformBack_Timer -= diff;

            }

            DoMeleeAttackIfReady();
        }
    }
Example #6
1
    void UpdateAI(const uint32 diff)
    {
        //Check if we have a target
        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
            return;

        //No instance
        if (!pInst)
            return;

        switch (pInst->GetData(DATA_CTHUN_PHASE))
        {
        case 0:
        {
            //BeamTimer
            if (BeamTimer < diff)
            {
                //SPELL_GREEN_BEAM
                Unit* target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if (target)
                {
                    m_creature->InterruptNonMeleeSpells(false);
                    DoCast(target,SPELL_GREEN_BEAM);

                    //Correctly update our target
                    m_creature->SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());
                }

                //Beam every 3 seconds
                BeamTimer = 3000;
            } else BeamTimer -= diff;

            //ClawTentacleTimer
            if (ClawTentacleTimer < diff)
            {
                Unit* target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if (target)
                {
                    Creature* Spawned = NULL;

                    //Spawn claw tentacle on the random target
                    Spawned = (Creature*)m_creature->SummonCreature(MOB_CLAW_TENTACLE,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,500);

                    if (Spawned)
                        Spawned->AI()->AttackStart(target);
                }

                //One claw tentacle every 12.5 seconds
                ClawTentacleTimer = 12500;
            } else ClawTentacleTimer -= diff;

            //EyeTentacleTimer
            if (EyeTentacleTimer < diff)
            {
                //Spawn the 8 Eye Tentacles in the corret spots
                SpawnEyeTentacle(0, 20);                //south
                SpawnEyeTentacle(10, 10);               //south west
                SpawnEyeTentacle(20, 0);                //west
                SpawnEyeTentacle(10, -10);              //north west

                SpawnEyeTentacle(0, -20);               //north
                SpawnEyeTentacle(-10, -10);             //north east
                SpawnEyeTentacle(-20, 0);               // east
                SpawnEyeTentacle(-10, 10);              // south east

                //No point actually putting a timer here since
                //These shouldn't trigger agian until after phase shifts
                EyeTentacleTimer = 45000;
            } else EyeTentacleTimer -= diff;

            //PhaseTimer
            if (PhaseTimer < diff)
            {
                //Switch to Dark Beam
                pInst->SetData(DATA_CTHUN_PHASE, 1);

                m_creature->InterruptNonMeleeSpells(false);

                //Select random target for dark beam to start on
                Unit* target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM,0);

                if (target)
                {
                    //Correctly update our target
                    m_creature->SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());

                    //Face our target
                    DarkGlareAngle = m_creature->GetAngle(target);
                    DarkGlareTickTimer = 1000;
                    DarkGlareTick = 0;
                    ClockWise = rand()%2;
                }

                //Add red coloration to C'thun
                DoCast(m_creature,SPELL_RED_COLORATION);

                //Freeze animation
                m_creature->setEmoteState(53);

                //Darkbeam for 35 seconds
                PhaseTimer = 35000;
            } else PhaseTimer -= diff;

        }
        break;
        case 1:
        {
            //EyeTentacleTimer
            if (DarkGlareTick < 35)
                if (DarkGlareTickTimer < diff)
                {
                    //Remove any target
                    m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);

                    //Set angle and cast
                    if (ClockWise)
                        m_creature->SetOrientation(DarkGlareAngle + ((float)DarkGlareTick*PI/35));
                    else m_creature->SetOrientation(DarkGlareAngle - ((float)DarkGlareTick*PI/35));

                    m_creature->StopMoving();

                    //Actual dark glare cast, maybe something missing here?
                    m_creature->CastSpell(m_creature, SPELL_DARK_GLARE, false);

                    //Increase tick
                    DarkGlareTick++;

                    //1 second per tick
                    DarkGlareTickTimer = 1000;
                } else DarkGlareTickTimer -= diff;

            //PhaseTimer
            if (PhaseTimer < diff)
            {
                //Switch to Eye Beam
                pInst->SetData(DATA_CTHUN_PHASE, 0);

                BeamTimer = 3000;
                EyeTentacleTimer = 45000;               //Always spawns 5 seconds before Dark Beam
                ClawTentacleTimer = 12500;              //4 per Eye beam phase (unsure if they spawn durring Dark beam)

                m_creature->InterruptNonMeleeSpells(false);

                //Remove Red coloration from c'thun
                m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION);

                //Freeze animation
                m_creature->setEmoteState(0);
                m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);

                //Eye Beam for 50 seconds
                PhaseTimer = 50000;
            } else PhaseTimer -= diff;
        }
        break;

        //Transition phase
        case 2:
        {
            //Remove any target
            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
            m_creature->SetHealth(0);
        }

        //Dead phase
        case 5:
        {
            m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false);
        }
        }
    }
        void UpdateAI(const uint32 uiDiff)
        {
            if (m_bTargetDied || !UpdateVictim())
                return;

            if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
            {
                if (!target->isAlive())
                {
                    if (m_pInstance)
                    {
                        Unit* gormok = ObjectAccessor::GetCreature(*me, m_pInstance->GetData64(NPC_GORMOK));
                        if (gormok && gormok->isAlive())
                        {
                            SetCombatMovement(false);
                            m_bTargetDied = true;
                            me->GetMotionMaster()->MoveJump(gormok->GetPositionX(), gormok->GetPositionY(), gormok->GetPositionZ(), 15.0f, 15.0f);
                        }
                        else if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        {
                            m_uiTargetGUID = target->GetGUID();
                            me->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 15.0f, 15.0f);
                        }
                    }
                }
            }

            if (m_uiFireBombTimer < uiDiff)
            {
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                    DoCast(target, SPELL_FIRE_BOMB);
                m_uiFireBombTimer = 20000;
            }
            else m_uiFireBombTimer -= uiDiff;

            if (m_uiBatterTimer < uiDiff)
            {
                if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
                    DoCast(target, SPELL_BATTER);
                m_uiBatterTimer = 10000;
            }
            else m_uiBatterTimer -= uiDiff;

            if (m_uiHeadCrackTimer < uiDiff)
            {
                if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
                    DoCast(target, SPELL_HEAD_CRACK);
                m_uiHeadCrackTimer = 35000;
            }
            else m_uiHeadCrackTimer -= uiDiff;

            DoMeleeAttackIfReady();
        }
    void SpellCast(float val)
    {
        if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget())
        {
            float comulativeperc = 0;
            Unit* target = NULL;
            for(int i=0; i<nrspells; i++)
            {
                spells[i].casttime--;

                if (m_spellcheck[i])
                {
                    spells[i].casttime = spells[i].cooldown;
                    target = _unit->GetAIInterface()->GetNextTarget();
                    switch(spells[i].targettype)
                    {
                    case TARGET_SELF:
                    case TARGET_VARIOUS:
                        _unit->CastSpell(_unit, spells[i].info, spells[i].instant);
                        break;
                    case TARGET_ATTACKING:
                        _unit->CastSpell(target, spells[i].info, spells[i].instant);
                        break;
                    case TARGET_DESTINATION:
                        _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant);
                        break;
                    }

                    if (spells[i].speech != "")
                    {
                        _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str());
                        _unit->PlaySoundToSet(spells[i].soundid);
                    }

                    m_spellcheck[i] = false;
                    return;
                }

                if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime)
                {
                    _unit->setAttackTimer(spells[i].attackstoptimer, false);
                    m_spellcheck[i] = true;
                }
                comulativeperc += spells[i].perctrigger;
            }
        }
    }
    void SpellCast(float val)
    {
        if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->getNextTarget())
        {
            float comulativeperc = 0;
            Unit* target = NULL;
            for(int i = 0; i < nrspells; i++)
            {
                if(!spells[i].perctrigger) continue;

                if(m_spellcheck[i])
                {
                    target = _unit->GetAIInterface()->getNextTarget();
                    switch(spells[i].targettype)
                    {
                        target = _unit->GetAIInterface()->getNextTarget();
                    case TARGET_SELF:
                    case TARGET_VARIOUS:
                        _unit->CastSpell(_unit, spells[i].info, spells[i].instant);
                    case TARGET_ATTACKING:
                        _unit->CastSpell(target, spells[i].info, spells[i].instant);
                        break;
                    case TARGET_DESTINATION:
                        _unit->CastSpellAoF(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), spells[i].info, spells[i].instant);
                        break;
                    }
                    m_spellcheck[i] = false;
                    return;
                }

                if(val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger))
                {
                    _unit->setAttackTimer(spells[i].attackstoptimer, false);
                    m_spellcheck[i] = true;
                }
                comulativeperc += spells[i].perctrigger;
            }
        }
    }
        void UpdateAI(const uint32 uiDiff)
        {
            if (!UpdateVictim())
                return;

            switch (m_uiStage)
            {
            case 0:
                if (m_uiFerociousButtTimer <= uiDiff)
                {
                    DoCastVictim(RAID_MODE(SPELL_FEROCIOUS_BUTT_10_N, SPELL_FEROCIOUS_BUTT_25_N, SPELL_FEROCIOUS_BUTT_10_H, SPELL_FEROCIOUS_BUTT_25_H));
                    m_uiFerociousButtTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
                } else m_uiFerociousButtTimer -= uiDiff;

                if (m_uiArticBreathTimer <= uiDiff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        DoCast(target, RAID_MODE(SPELL_ARCTIC_BREATH_10_N, SPELL_ARCTIC_BREATH_25_N, SPELL_ARCTIC_BREATH_10_H, SPELL_ARCTIC_BREATH_25_H));
                    m_uiArticBreathTimer = urand(25*IN_MILLISECONDS, 40*IN_MILLISECONDS);
                } else m_uiArticBreathTimer -= uiDiff;

                if (m_uiWhirlTimer <= uiDiff)
                {
                    DoCastAOE(RAID_MODE(SPELL_WHIRL_10_N, SPELL_WHIRL_25_N, SPELL_WHIRL_10_H, SPELL_WHIRL_25_H));
                    m_uiWhirlTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
                } else m_uiWhirlTimer -= uiDiff;

                if (m_uiMassiveCrashTimer <= uiDiff)
                {
                    me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 10.0f, 20.0f); // 1: Middle of the room
                    m_uiStage = 7; //Invalid (Do nothing more than move)
                    m_uiMassiveCrashTimer = 30*IN_MILLISECONDS;
                } else m_uiMassiveCrashTimer -= uiDiff;

                DoMeleeAttackIfReady();
                break;
            case 1:
                DoCastAOE(RAID_MODE(SPELL_MASSIVE_CRASH_10_N, SPELL_MASSIVE_CRASH_25_N, SPELL_MASSIVE_CRASH_10_H, SPELL_MASSIVE_CRASH_25_H));
                m_uiStage = 2;
                break;
            case 2:
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
                {
                    m_uiTrampleTargetGUID = target->GetGUID();
                    me->SetTarget(m_uiTrampleTargetGUID);
                    DoScriptText(SAY_TRAMPLE_STARE, me, target);
                    m_bTrampleCasted = false;
                    SetCombatMovement(false);
                    me->GetMotionMaster()->MoveIdle();
                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    m_uiTrampleTimer = 4*IN_MILLISECONDS;
                    m_uiStage = 3;
                } else m_uiStage = 6;
                break;
            case 3:
                if (m_uiTrampleTimer <= uiDiff)
                {
                    if (Unit* target = Unit::GetPlayer(*me, m_uiTrampleTargetGUID))
                    {
                        m_bTrampleCasted = false;
                        m_bMovementStarted = true;
                        m_fTrampleTargetX = target->GetPositionX();
                        m_fTrampleTargetY = target->GetPositionY();
                        m_fTrampleTargetZ = target->GetPositionZ();
                        me->GetMotionMaster()->MoveJump(2*me->GetPositionX()-m_fTrampleTargetX,
                                                        2*me->GetPositionY()-m_fTrampleTargetY,
                                                        me->GetPositionZ(),
                                                        10.0f, 20.0f); // 2: Hop Backwards
                        m_uiStage = 7; //Invalid (Do nothing more than move)
                    } else m_uiStage = 6;
                } else m_uiTrampleTimer -= uiDiff;
                break;
            case 4:
                DoScriptText(SAY_TRAMPLE_START, me);
                me->GetMotionMaster()->MoveCharge(m_fTrampleTargetX, m_fTrampleTargetY, m_fTrampleTargetZ+2, 42, 1);
                me->SetTarget(0);
                m_uiStage = 5;
                break;
            case 5:
                if (m_bMovementFinish)
                {
                    if (m_uiTrampleTimer <= uiDiff) DoCastAOE(SPELL_TRAMPLE);
                    m_bMovementFinish = false;
                    m_uiStage = 6;
                    return;
                }
                if (m_uiTrampleTimer <= uiDiff)
                {
                    Map::PlayerList const &lPlayers = me->GetMap()->GetPlayers();
                    for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
                    {
                        if (Unit* player = itr->getSource())
                            if (player->isAlive() && player->IsWithinDistInMap(me, 6.0f))
                            {
                                DoCastAOE(SPELL_TRAMPLE);
                                m_uiTrampleTimer = IN_MILLISECONDS;
                                break;
                            }
                    }
                } else m_uiTrampleTimer -= uiDiff;
                break;
            case 6:
                if (!m_bTrampleCasted)
                {
                    DoCast(me, SPELL_STAGGERED_DAZE);
                    DoScriptText(SAY_TRAMPLE_FAIL, me);
                }
                m_bMovementStarted = false;
                me->GetMotionMaster()->MovementExpired();
                me->GetMotionMaster()->MoveChase(me->getVictim());
                SetCombatMovement(true);
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                m_uiStage = 0;
                break;
            }
        }
    void UpdateAI(const uint32 diff)
    {
        //Return since we have no target
        if (!UpdateVictim())
            return;

        //MortalWound_Timer
        if (MortalWound_Timer <= diff)
        {
            DoCast(me->getVictim(),SPELL_MORTAL_WOUND);
            MortalWound_Timer = 10000 + rand()%10000;
        } else MortalWound_Timer -= diff;

        //Summon 1-3 Spawns of Fankriss at random time.
        if (SpawnSpawns_Timer <= diff)
        {
            switch (rand()%3)
            {
            case 0:
                SummonSpawn(SelectUnit(SELECT_TARGET_RANDOM, 0));
                break;
            case 1:
                SummonSpawn(SelectUnit(SELECT_TARGET_RANDOM, 0));
                SummonSpawn(SelectUnit(SELECT_TARGET_RANDOM, 0));
                break;
            case 2:
                SummonSpawn(SelectUnit(SELECT_TARGET_RANDOM, 0));
                SummonSpawn(SelectUnit(SELECT_TARGET_RANDOM, 0));
                SummonSpawn(SelectUnit(SELECT_TARGET_RANDOM, 0));
                break;
            }
            SpawnSpawns_Timer = 30000 + rand()%30000;
        } else SpawnSpawns_Timer -= diff;

        // Teleporting Random Target to one of the three tunnels and spawn 4 hatchlings near the gamer.
        //We will only telport if fankriss has more than 3% of hp so teleported gamers can always loot.
        if (me->GetHealth()*100 / me->GetMaxHealth() > 3)
        {
            if (SpawnHatchlings_Timer <= diff)
            {
                Unit *pTarget = NULL;
                pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
                {
                    DoCast(pTarget, SPELL_ROOT);

                    if (DoGetThreat(pTarget))
                        DoModifyThreatPercent(pTarget, -100);

                    switch (rand()%3)
                    {
                    case 0:
                        DoTeleportPlayer(pTarget, -8106.0142f, 1289.2900f,-74.419533f, 5.112f);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-3, pTarget->GetPositionY()-3, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-3, pTarget->GetPositionY()+3, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-5, pTarget->GetPositionY()-5, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-5, pTarget->GetPositionY()+5, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        break;
                    case 1:
                        DoTeleportPlayer(pTarget, -7990.135354f, 1155.1907f,-78.849319f, 2.608f);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-3, pTarget->GetPositionY()-3, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-3, pTarget->GetPositionY()+3, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-5, pTarget->GetPositionY()-5, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-5, pTarget->GetPositionY()+5, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        break;
                    case 2:
                        DoTeleportPlayer(pTarget,-8159.7753f, 1127.9064f,-76.868660f, 0.675f);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-3, pTarget->GetPositionY()-3, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-3, pTarget->GetPositionY()+3, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-5, pTarget->GetPositionY()-5, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        Hatchling = me->SummonCreature(15962, pTarget->GetPositionX()-5, pTarget->GetPositionY()+5, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (Hatchling)
                            ((CreatureAI*)Hatchling->AI())->AttackStart(pTarget);
                        break;
                    }
                }
                SpawnHatchlings_Timer = 45000 + rand()%15000;
            } else SpawnHatchlings_Timer -= diff;
        }

        DoMeleeAttackIfReady();
    }