void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (DelayTimer && DelayTimer > 5000)
                DelayEventStart();
            else DelayTimer+=diff;

            switch (Phase)
            {
            case PHASE_UNDERGROUND:
                if (ImpaleTimer <= diff)
                {
                    switch (ImpalePhase)
                    {
                    case IMPALE_PHASE_TARGET:
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        {
                            if (Creature* impaleTarget = DoSummonImpaleTarget(target))
                                impaleTarget->CastSpell(impaleTarget, SPELL_IMPALE_SHAKEGROUND, true);
                            ImpaleTimer = 3*IN_MILLISECONDS;
                            ImpalePhase = IMPALE_PHASE_ATTACK;
                        }
                        break;
                    case IMPALE_PHASE_ATTACK:
                        if (Creature* impaleTarget = Unit::GetCreature(*me, ImpaleTarget))
                        {
                            impaleTarget->CastSpell(impaleTarget, SPELL_IMPALE_SPIKE, false);
                            impaleTarget->RemoveAurasDueToSpell(SPELL_IMPALE_SHAKEGROUND);
                        }
                        ImpalePhase = IMPALE_PHASE_DMG;
                        ImpaleTimer = 1*IN_MILLISECONDS;
                        break;
                    case IMPALE_PHASE_DMG:
                        if (Creature* impaleTarget = Unit::GetCreature(*me, ImpaleTarget))
                            me->CastSpell(impaleTarget, DUNGEON_MODE(SPELL_IMPALE_DMG, SPELL_IMPALE_DMG_H), true);
                        ImpalePhase = IMPALE_PHASE_TARGET;
                        ImpaleTimer = 9*IN_MILLISECONDS;
                        break;
                    }
                } else ImpaleTimer -= diff;

                if (!GuardianSummoned)
                {
                    for (uint8 i = 0; i < 2; ++i)
                    {
                        if (Creature* Guardian = me->SummonCreature(CREATURE_GUARDIAN, SpawnPointGuardian[i], TEMPSUMMON_CORPSE_DESPAWN, 0))
                        {
                            Guardian->AddThreat(me->getVictim(), 0.0f);
                            DoZoneInCombat(Guardian);
                        }
                    }
                    GuardianSummoned = true;
                }

                if (!VenomancerSummoned)
                {
                    if (VenomancerTimer <= diff)
                    {
                        if (UndergroundPhase > 1)
                        {
                            for (uint8 i = 0; i < 2; ++i)
                            {
                                if (Creature* Venomancer = me->SummonCreature(CREATURE_VENOMANCER, SpawnPoint[i], TEMPSUMMON_CORPSE_DESPAWN, 0))
                                {
                                    Venomancer->AddThreat(me->getVictim(), 0.0f);
                                    DoZoneInCombat(Venomancer);
                                }
                            }
                            VenomancerSummoned = true;
                        }
                    } else VenomancerTimer -= diff;
                }

                if (!DatterSummoned)
                {
                    if (DatterTimer <= diff)
                    {
                        if (UndergroundPhase > 2)
                        {
                            for (uint8 i = 0; i < 2; ++i)
                            {
                                if (Creature* Datter = me->SummonCreature(CREATURE_DATTER, SpawnPoint[i], TEMPSUMMON_CORPSE_DESPAWN, 0))
                                {
                                    Datter->AddThreat(me->getVictim(), 0.0f);
                                    DoZoneInCombat(Datter);
                                }
                            }
                            DatterSummoned = true;
                        }
                    } else DatterTimer -= diff;

                    if (me->HasAura(SPELL_LEECHING_SWARM))
                        me->RemoveAurasDueToSpell(SPELL_LEECHING_SWARM);
                }

                if (UndergroundTimer <= diff)
                {
                    me->RemoveAura(SPELL_SUBMERGE);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
                    Phase = PHASE_MELEE;
                } else UndergroundTimer -= diff;
                break;

            case PHASE_MELEE:
                if (((UndergroundPhase == 0 && HealthBelowPct(75))
                    || (UndergroundPhase == 1 && HealthBelowPct(50))
                    || (UndergroundPhase == 2 && HealthBelowPct(25)))
                    && !me->HasUnitState(UNIT_STATE_CASTING))
                {
                    GuardianSummoned = false;
                    VenomancerSummoned = false;
                    DatterSummoned = false;

                    UndergroundTimer = 40*IN_MILLISECONDS;
                    VenomancerTimer = 25*IN_MILLISECONDS;
                    DatterTimer = 32*IN_MILLISECONDS;

                    ImpalePhase = 0;
                    ImpaleTimer = 9*IN_MILLISECONDS;

                    DoCast(me, SPELL_SUBMERGE, false);
                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);

                    Phase = PHASE_UNDERGROUND;
                    ++UndergroundPhase;
                }

                if (Channeling == true)
                {
                    for (uint8 i = 0; i < 8; ++i)
                    DoCast(me->getVictim(), SPELL_SUMMON_CARRION_BEETLES, true);
                    Channeling = false;
                }
                else if (CarrionBeetlesTimer <= diff)
                {
                    Channeling = true;
                    DoCastVictim(SPELL_CARRION_BEETLES);
                    CarrionBeetlesTimer = 25*IN_MILLISECONDS;
                } else CarrionBeetlesTimer -= diff;

                if (LeechingSwarmTimer <= diff)
                {
                    DoCast(me, SPELL_LEECHING_SWARM, true);
                    LeechingSwarmTimer = 19*IN_MILLISECONDS;
                } else LeechingSwarmTimer -= diff;

                if (PoundTimer <= diff)
                {
                    if (Unit* target = me->getVictim())
                    {
                        if (Creature* pImpaleTarget = DoSummonImpaleTarget(target))
                            me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_POUND, SPELL_POUND_H), false);
                    }
                    PoundTimer = 16500;
                } else PoundTimer -= diff;

                DoMeleeAttackIfReady();
                break;
            }
        }
Exemple #2
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            switch (uiPhase)
            {
            case PHASE_UNDERGROUND:
                if (uiImpaleTimer <= diff)
                {
                    switch(uiImpalePhase)
                    {
                    case IMPALE_PHASE_TARGET:
                        if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        {
                            if (Creature *pImpaleTarget = DoSummonImpaleTarget(target))
                                pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SHAKEGROUND, true);
                            uiImpaleTimer = 3*IN_MILLISECONDS;
                            uiImpalePhase = IMPALE_PHASE_ATTACK;
                        }
                        break;
                    case IMPALE_PHASE_ATTACK:
                        if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget))
                        {
                            pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SPIKE, false);
                            pImpaleTarget->RemoveAurasDueToSpell(SPELL_IMPALE_SHAKEGROUND);
                        }
                        uiImpalePhase = IMPALE_PHASE_DMG;
                        uiImpaleTimer = 1*IN_MILLISECONDS;
                        break;
                    case IMPALE_PHASE_DMG:
                        if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget))
                            me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_IMPALE_DMG, SPELL_IMPALE_DMG_H), true);
                        uiImpalePhase = IMPALE_PHASE_TARGET;
                        uiImpaleTimer = 9*IN_MILLISECONDS;
                        break;
                    }
                } else uiImpaleTimer -= diff;

                if (!bGuardianSummoned)
                {
                    if (uiGuardianTimer <= diff)
                    {
                        for (uint8 i = 0; i < 2; ++i)
                        {
                            if (Creature *Guardian = me->SummonCreature(CREATURE_GUARDIAN,SpawnPointGuardian[i],TEMPSUMMON_CORPSE_DESPAWN,0))
                            {
                                Guardian->AddThreat(me->getVictim(), 0.0f);
                                DoZoneInCombat(Guardian);
                            }
                        }
                        bGuardianSummoned = true;
                    } else uiGuardianTimer -= diff;
                }

                if (!bVenomancerSummoned)
                {
                    if (uiVenomancerTimer <= diff)
                    {
                        if (uiUndergroundPhase > 1)
                        {
                            for (uint8 i = 0; i < 2; ++i)
                            {
                                if (Creature *Venomancer = me->SummonCreature(CREATURE_VENOMANCER,SpawnPointGuardian[i],TEMPSUMMON_CORPSE_DESPAWN,0))
                                {
                                    Venomancer->AddThreat(me->getVictim(), 0.0f);
                                    DoZoneInCombat(Venomancer);
                                }
                            }
                            bVenomancerSummoned = true;
                        }
                    } else uiVenomancerTimer -= diff;
                }

                if (uiDarterTimer <= diff)
                {
                    if (!uiUndergroundPhase)
                        return;

                    for (uint8 i = 0; i < 2; ++i)
                    {
                        if (Creature *Darter = me->SummonCreature(CREATURE_DARTER,SpawnPoint[i],TEMPSUMMON_CORPSE_DESPAWN,0))
                        {
                            if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                                Darter->AI()->AttackStart(pTarget);
                            DoZoneInCombat(Darter);
                        }
                    }
                    uiDarterTimer = 30*IN_MILLISECONDS / uiUndergroundPhase;
                } else uiDarterTimer -= diff;

                if (uiUndergroundTimer <= diff)
                {
                    if (!uiAddsAlive)
                    {
                        uiPoundTimer = urand(2500, 10000);
                        me->RemoveAura(SPELL_SUBMERGE);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
                        uiPhase = PHASE_MELEE;
                    }
                } else uiUndergroundTimer -= diff;
                break;

            case PHASE_MELEE:
                if (((uiUndergroundPhase == 0 && HealthBelowPct(75))
                    || (uiUndergroundPhase == 1 && HealthBelowPct(50))
                    || (uiUndergroundPhase == 2 && HealthBelowPct(25)))
                    && !me->HasUnitState(UNIT_STAT_CASTING))
                {
                    bGuardianSummoned = false;
                    bVenomancerSummoned = false;

                    uiUndergroundTimer = 40*IN_MILLISECONDS;
                    uiVenomancerTimer = 25*IN_MILLISECONDS;
                    uiGuardianTimer = 5*IN_MILLISECONDS;
                    uiDarterTimer = 10*IN_MILLISECONDS;

                    uiImpalePhase = 0;
                    uiImpaleTimer = 9*IN_MILLISECONDS;

                    DoCast(me, SPELL_SUBMERGE, false);
                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);

                    uiPhase = PHASE_UNDERGROUND;
                    ++uiUndergroundPhase;

                    if (me->HasAura(DUNGEON_MODE(SPELL_LEECHING_SWARM, SPELL_LEECHING_SWARM_H)))
                        me->RemoveAurasDueToSpell(DUNGEON_MODE(SPELL_LEECHING_SWARM, SPELL_LEECHING_SWARM_H));
                }

                if (bChanneling == true)
                {
                    if (uiCarrionBeetlesTimer <= diff)
                    {
                        for (uint8 i = 0; i < 2; ++i)
                            if (Creature* pBeetle = me->SummonCreature(CREATURE_CARRION_BEETLE, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0))
                                if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                                    pBeetle->AI()->AttackStart(pTarget);

                        uiCarrionBeetlesTimer = 2*IN_MILLISECONDS;
                        uiBeetleCounter++;
                    } else uiCarrionBeetlesTimer -= diff;

                    if (uiBeetleCounter == 4)
                    {
                        bChanneling = false;
                        uiBeetleCounter = 0;
                        uiCarrionBeetlesTimer = 60*IN_MILLISECONDS; // handled by leeching swarm
                    }
                }
                else if (uiCarrionBeetlesTimer <= diff)
                {
                    bChanneling = true;
                    DoCastVictim(SPELL_CARRION_BEETLES);
                } else uiCarrionBeetlesTimer -= diff;

                if (uiLeechingSwarmTimer <= diff)
                {
                    if(!me->IsNonMeleeSpellCasted(false))
                    {
                        DoCast(me, DUNGEON_MODE(SPELL_LEECHING_SWARM, SPELL_LEECHING_SWARM_H), true);
                        uiLeechingSwarmTimer = urand(30*IN_MILLISECONDS, 35*IN_MILLISECONDS);
                        uiCarrionBeetlesTimer = 2*IN_MILLISECONDS;
                    }
                } else uiLeechingSwarmTimer -= diff;

                if (uiPoundTimer <= diff)
                {
                    float x, y, z;
                    z = me->GetPositionZ();
                    me->GetNearPoint2D(x, y, -2.5f, me->GetOrientation());

                    // summon the temp target relative to self instead of current victim, should prevent facing issues while casting
                    if (Creature* tempTarget = me->SummonCreature(CREATURE_IMPALE_TARGET, x, y, z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 5000))
                    {
                        me->SetFacingToObject(tempTarget);
                        tempTarget->SetReactState(REACT_PASSIVE);
                        tempTarget->SetDisplayId(DISPLAY_INVISIBLE);
                        tempTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE|UNIT_FLAG_PASSIVE|UNIT_FLAG_NOT_SELECTABLE);
                        me->CastSpell(tempTarget, DUNGEON_MODE(SPELL_POUND, SPELL_POUND_H), false);
                    }
                    uiPoundTimer = urand(17000, 20000);
                } else uiPoundTimer -= diff;

                DoMeleeAttackIfReady();
                break;
            }
        }