예제 #1
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateCombatState() || !CheckInRoom())
            return;

        events.Update(diff);

        while(uint32 eventId = events.ExecuteEvent())
        {
            switch(eventId)
            {
                case EVENT_CURSE:
                    DoCastAOE(SPELL_CURSE_PLAGUEBRINGER);
                    events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000);
                    return;
                case EVENT_WARRIOR:
                    DoScriptText(SAY_SUMMON, me);
                    SummonUndead(MOB_WARRIOR, HEROIC(2,3));
                    events.ScheduleEvent(EVENT_WARRIOR, 30000);
                    return;
                case EVENT_BLINK:
                    DoCastAOE(SPELL_CRIPPLE, true);
                    DoCastAOE(SPELL_BLINK);
                    DoResetThreat();
                    events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000);
                    return;
                case EVENT_BALCONY:
                    me->SetReactState(REACT_PASSIVE);
                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->AttackStop();
                    me->RemoveAllAuras();
                    me->NearTeleportTo(TELE_X, TELE_Y, TELE_Z, TELE_O);
                    events.Reset();
                    events.ScheduleEvent(EVENT_WAVE, 2000);
                    waveCount = 0;
                    return;
                case EVENT_WAVE:
                    DoScriptText(SAY_SUMMON, me);
                    switch(balconyCount)
                    {
                        case 0: SummonUndead(MOB_CHAMPION, HEROIC(2,4)); break;
                        case 1: SummonUndead(MOB_CHAMPION, HEROIC(1,2));
                                SummonUndead(MOB_GUARDIAN, HEROIC(1,2)); break;
                        case 2: SummonUndead(MOB_GUARDIAN, HEROIC(2,4)); break;
                        default:SummonUndead(MOB_CHAMPION, HEROIC(5,10));
                                SummonUndead(MOB_GUARDIAN, HEROIC(5,10));break;
                    }
                    ++waveCount;
                    events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, 34000);
                    return;
                case EVENT_GROUND:
                {
                    ++balconyCount;
                    float x, y, z, o;
                    me->GetHomePosition(x, y, z, o);
                    me->NearTeleportTo(x, y, z, o);
                    EnterPhaseGround();
                    return;
                }
            }
        }

        if (me->HasReactState(REACT_AGGRESSIVE))
            DoMeleeAttackIfReady();
    }
예제 #2
0
    void UpdateAI(const uint32 diff)
    {
        if (!phase)
            return;

        events.Update(diff);

        if (phase != PHASE_BIRTH && !UpdateCombatState() || !CheckInRoom())
            return;

        if (CanTheHundredClub)
        {
            if (CheckFrostResistTimer <= diff)
            {
                CheckPlayersFrostResist();
                CheckFrostResistTimer = (rand() % 5 + 5) * 1000;
            } else CheckFrostResistTimer -= diff;
        }

        if (phase == PHASE_GROUND)
        {
            while (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                    case EVENT_BERSERK:
                        DoScriptText(EMOTE_ENRAGE, me);
                        DoCast(me, SPELL_BERSERK);
                        return;
                    case EVENT_CLEAVE:
                        DoCast(me->getVictim(), SPELL_CLEAVE);
                        events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND);
                        return;
                    case EVENT_TAIL:
                        DoCastAOE(SPELL_TAIL_SWEEP);
                        events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND);
                        return;
                    case EVENT_DRAIN:
                        DoCastAOE(SPELL_LIFE_DRAIN);
                        events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND);
                        return;
                    case EVENT_BLIZZARD:
                    {
                        //DoCastAOE(SPELL_SUMMON_BLIZZARD);
                        if (Creature *pSummon = DoSummon(MOB_BLIZZARD, me, 0.0f, urand(25000,30000), TEMPSUMMON_TIMED_DESPAWN))
                            pSummon->GetMotionMaster()->MoveRandom(40);
                        events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20000,7000), 0, PHASE_GROUND);
                        break;
                    }
                    case EVENT_FLIGHT:
                        phase = PHASE_FLIGHT;
                        events.SetPhase(PHASE_FLIGHT);
                        me->SetReactState(REACT_PASSIVE);
                        me->AttackStop();
                        float x, y, z, o;
                        me->GetHomePosition(x, y, z, o);
                        me->GetMotionMaster()->MovePoint(1, x, y, z);
                        return;
                }
            }

            DoMeleeAttackIfReady();
        }
        else
        {
            if (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                    case EVENT_LIFTOFF:
                        me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
                        me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
                        me->SendMovementFlagUpdate();
                        events.ScheduleEvent(EVENT_ICEBOLT, 1500);
                        iceboltCount = RAID_MODE(2,3);
                        return;
                    case EVENT_ICEBOLT:
                    {
                        std::vector<Unit*> targets;
                        std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
                        for (; i != me->getThreatManager().getThreatList().end(); ++i)
                            if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT))
                                targets.push_back((*i)->getTarget());

                        if (targets.empty())
                            iceboltCount = 0;
                        else
                        {
                            std::vector<Unit*>::const_iterator itr = targets.begin();
                            advance(itr, rand()%targets.size());
                            iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0));
                            DoCast(*itr, SPELL_ICEBOLT);
                            --iceboltCount;
                        }

                        if (iceboltCount)
                            events.ScheduleEvent(EVENT_ICEBOLT, 1000);
                        else
                            events.ScheduleEvent(EVENT_BREATH, 1000);
                        return;
                    }
                    case EVENT_BREATH:
                    {
                        DoScriptText(EMOTE_BREATH, me);
                        DoCastAOE(SPELL_FROST_MISSILE);
                        events.ScheduleEvent(EVENT_EXPLOSION, 8000);
                        return;
                    }
                    case EVENT_EXPLOSION:
                        CastExplosion();
                        ClearIceBlock();
                        events.ScheduleEvent(EVENT_LAND, 3000);
                        return;
                    case EVENT_LAND:
                        me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                        me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
                        me->SendMovementFlagUpdate();
                        events.ScheduleEvent(EVENT_GROUND, 1500);
                        return;
                    case EVENT_GROUND:
                        EnterPhaseGround();
                        return;
                    case EVENT_BIRTH:
                        me->SetVisibility(VISIBILITY_ON);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                        me->SetReactState(REACT_AGGRESSIVE);
                        return;
                }
            }//if (uint32 eventId = events.ExecuteEvent())
        }//if (phase == PHASE_GROUND)
    }
예제 #3
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateCombatState())
            return;

        events.Update(diff);

        if (Phase == 1)
        {
            while(uint32 eventId = events.GetEvent())
            {
                switch (eventId)
                {
                    case EVENT_WASTE:
                        DoSummon(NPC_WASTE, Pos[RAND(0,3,6,9)]);
                        events.RepeatEvent(urand(2000,5000));
                        break;
                    case EVENT_ABOMIN:
                        if (nAbomination < 8)
                        {
                            DoSummon(NPC_ABOMINATION, Pos[RAND(1,4,7,10)]);
                            nAbomination++;
                            events.RepeatEvent(20000);
                        }
                        else
                            events.PopEvent();
                        break;
                    case EVENT_WEAVER:
                        if (nWeaver < 8)
                        {
                            DoSummon(NPC_WEAVER, Pos[RAND(0,3,6,9)]);
                            nWeaver++;
                            events.RepeatEvent(25000);
                        }
                        else
                            events.PopEvent();
                        break;
                    case EVENT_TRIGGER:
                        if (GameObject *pKTTrigger = m_creature->GetMap()->GetGameObject(KTTriggerGUID))    
                            pKTTrigger->SetPhaseMask(2, true);
                        events.PopEvent();
                        break;
                    case EVENT_PHASE:
                        events.Reset();
                        DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
                        spawns.DespawnAll();
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
                        me->CastStop();

                        DoStartMovement(me->getVictim());
                        events.ScheduleEvent(EVENT_BOLT, urand(5000,10000));
                        events.ScheduleEvent(EVENT_NOVA, 15000);
                        events.ScheduleEvent(EVENT_DETONATE, urand(30000,40000));
                        events.ScheduleEvent(EVENT_FISSURE, urand(10000,30000));
                        events.ScheduleEvent(EVENT_BLAST, urand(60000,120000));
                        if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
                            events.ScheduleEvent(EVENT_CHAIN, urand(30000,60000));
                        Phase = 2;
                        break;
                    default:
                        events.PopEvent();
                        break;
                }
            }
        }
        else
        {
            //start phase 3 when we are 45% health
            if (Phase != 3)
            {
                if (HealthBelowPct(45))
                {
                    Phase = 3 ;
                    DoScriptText(SAY_REQUEST_AID, m_creature);
                    //here Lich King should respond to KelThuzad but I don't know which Creature to make talk
                    //so for now just make Kelthuzad says it.
                    DoScriptText(SAY_ANSWER_REQUEST, m_creature);

                    for (uint8 i = 0; i <= 3; ++i)
                    {
                        if (GameObject *pPortal = m_creature->GetMap()->GetGameObject(PortalsGUID[i]))
                        {
                            if (pPortal->getLootState() == GO_READY)
                                pPortal->UseDoorOrButton();
                        }
                    }
                }
            }
            else if (nGuardiansOfIcecrownCount < RAID_MODE(2,4))
            {
                if (uiGuardiansOfIcecrownTimer <= diff)
                {
                    // TODO : Add missing text
                    if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8,11)]))
                        pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
                    ++nGuardiansOfIcecrownCount;
                    uiGuardiansOfIcecrownTimer = 5000;
                }
                else uiGuardiansOfIcecrownTimer -= diff;
            }

            if (me->hasUnitState(UNIT_STAT_CASTING))
                return;

            if (uint32 eventId = events.GetEvent())
            {
                switch (eventId)
                {
                    case EVENT_BOLT:
                        DoCastVictim(RAID_MODE(SPELL_FROST_BOLT,H_SPELL_FROST_BOLT));
                        events.RepeatEvent(urand(5000,10000));
                        break;
                    case EVENT_NOVA:
                        DoCastAOE(RAID_MODE(SPELL_FROST_BOLT_AOE,H_SPELL_FROST_BOLT_AOE));
                        events.RepeatEvent(urand(15000,30000));
                        break;
                    case EVENT_CHAIN:
                    {
                        uint32 count = urand(1,3);
                        for (uint8 i = 1; i <= count; i++)
                        {
                            Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true);
                            if (pTarget && !pTarget->isCharmed() && (chained.find(pTarget->GetGUID()) == chained.end()))
                            {
                                DoCast(pTarget, SPELL_CHAINS_OF_KELTHUZAD);
                                float scale = pTarget->GetFloatValue(OBJECT_FIELD_SCALE_X);
                                chained.insert(std::make_pair(pTarget->GetGUID(), scale));
                                pTarget->SetFloatValue(OBJECT_FIELD_SCALE_X, scale * 2);
                                events.ScheduleEvent(EVENT_CHAINED_SPELL, 2000); //core has 2000ms to set unit flag charm
                            }
                        }
                        if (!chained.empty())
                            DoScriptText(RAND(SAY_CHAIN_1,SAY_CHAIN_2), me);
                        events.RepeatEvent(urand(100000,180000));
                        break;
                    }
                    case EVENT_CHAINED_SPELL:
                    {
                        std::map<uint64, float>::iterator itr;
                        for (itr = chained.begin(); itr != chained.end();)
                        {
                            if (Unit* player = Unit::GetPlayer((*itr).first))
                            {
                                if (!player->isCharmed())
                                {
                                    player->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
                                    std::map<uint64, float>::iterator next = itr;
                                    ++next;
                                    chained.erase(itr);
                                    itr = next;
                                    continue;
                                }

                                if (Unit *pTarget = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, NotCharmedTargetSelector()))
                                {
                                    switch(player->getClass())
                                    {
                                        case CLASS_DRUID:
                                            if (urand(0,1))
                                                player->CastSpell(pTarget, SPELL_MOONFIRE, false);
                                            else
                                                player->CastSpell(m_creature, SPELL_LIFEBLOOM, false);
                                            break;
                                        case CLASS_HUNTER:
                                            player->CastSpell(pTarget, RAND(SPELL_MULTI_SHOT, SPELL_VOLLEY), false);
                                            break;
                                        case CLASS_MAGE:
                                            player->CastSpell(pTarget, RAND(SPELL_FROST_FIREBOLT, SPELL_ARCANE_MISSILES), false);
                                            break;
                                        case CLASS_WARLOCK:
                                            player->CastSpell(pTarget, RAND(SPELL_CURSE_OF_AGONY, SPELL_SHADOW_BOLT), true);
                                            break;
                                        case CLASS_WARRIOR:
                                            player->CastSpell(pTarget, RAND(SPELL_BLADESTORM, SPELL_CLEAVE), false);
                                            break;
                                        case CLASS_PALADIN:
                                            if (urand(0,1))
                                                player->CastSpell(pTarget, SPELL_HAMMER_OF_JUSTICE, false);
                                            else
                                                player->CastSpell(m_creature, SPELL_HOLY_SHOCK, false);
                                            break;
                                        case CLASS_PRIEST:
                                            if (urand(0,1))
                                                player->CastSpell(pTarget, SPELL_VAMPIRIC_TOUCH, false);
                                            else
                                                player->CastSpell(m_creature, SPELL_RENEW, false);
                                            break;
                                        case CLASS_SHAMAN:
                                            if (urand(0,1))
                                                player->CastSpell(pTarget, SPELL_EARTH_SHOCK, false);
                                            else
                                                player->CastSpell(m_creature, SPELL_HEALING_WAVE, false);
                                            break;
                                        case CLASS_ROGUE:
                                            player->CastSpell(pTarget, RAND(SPELL_HEMORRHAGE, SPELL_MUTILATE), false);
                                            break;
                                        case CLASS_DEATH_KNIGHT:
                                            if (urand(0,1))
                                                player->CastSpell(pTarget, SPELL_PLAGUE_STRIKE, true);
                                            else
                                                player->CastSpell(pTarget, SPELL_HOWLING_BLAST, true);
                                            break;
                                    }
                                }
                            }
                            itr++;
                        }

                        if (chained.empty())
                            events.PopEvent();
                        else
                            events.RepeatEvent(5000);

                        break;
                    }
                    case EVENT_DETONATE:
                    {
                        std::vector<Unit*> unitList;
                        std::list<HostileReference*> *threatList = &me->getThreatManager().getThreatList();
                        for (std::list<HostileReference*>::const_iterator itr = threatList->begin(); itr != threatList->end(); ++itr)
                        {
                            if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER
                                && (*itr)->getTarget()->getPowerType() == POWER_MANA
                                && (*itr)->getTarget()->GetPower(POWER_MANA))
                                unitList.push_back((*itr)->getTarget());
                        }

                        if (!unitList.empty())
                        {
                            std::vector<Unit*>::iterator itr = unitList.begin();
                            advance(itr, rand()%unitList.size());
                            DoCast(*itr, SPELL_MANA_DETONATION);
                            DoScriptText(RAND(SAY_SPECIAL_1,SAY_SPECIAL_2,SAY_SPECIAL_3), me);
                        }

                        events.RepeatEvent(urand(20000,50000));
                        break;
                    }
                    case EVENT_FISSURE:
                        if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
                            DoCast(pTarget, SPELL_SHADOW_FISURE);
                        events.RepeatEvent(urand(10000,45000));
                        break;
                    case EVENT_BLAST:
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1,0), 0, true))
                            DoCast(pTarget, SPELL_FROST_BLAST);
                        if (rand()%2)
                            DoScriptText(SAY_FROST_BLAST, m_creature);
                        events.RepeatEvent(urand(30000,90000));
                        break;
                    default:
                        events.PopEvent();
                        break;
                }
            }

            DoMeleeAttackIfReady();
        }
    }
예제 #4
0
    void UpdateAI(const uint32 diff)
    {
        if (!CanStartEvent)//boss is invisible, don't attack
        {
            if (CheckCanStart())
            {
                if (Submerged)
                {
                    me->SetVisibility(VISIBILITY_ON);
                    Submerged = false;
                    WaitTimer2 = 500;
                }
                if (!Submerged && WaitTimer2 <= diff)//wait 500ms before emerge anim
                {
                    me->RemoveAllAuras();
                    me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
                    DoCast(me, SPELL_EMERGE, false);
                    WaitTimer2 = 60000;//never reached
                    WaitTimer = 3000;
                } else WaitTimer2 -= diff;

                if (WaitTimer <= diff)//wait 3secs for emerge anim, then attack
                {
                    WaitTimer = 3000;
                    CanStartEvent=true;//fresh fished from pool
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                } else WaitTimer -= diff;
            }
            return;
        }

        if (me->getThreatManager().getThreatList().empty())//check if should evade
        {
            if (me->isInCombat())
                EnterEvadeMode();
            return;
        }
        if (!Submerged)
        {
            if (PhaseTimer <= diff)
            {
                me->InterruptNonMeleeSpells(false);
                DoCast(me, SPELL_SUBMERGE);
                PhaseTimer = 60000;//60secs submerged
                Submerged = true;
            } else PhaseTimer-=diff;

            if (SpoutTimer <= diff)
            {
                me->MonsterTextEmote(EMOTE_SPOUT,0,true);
                me->SetReactState(REACT_PASSIVE);
                me->GetMotionMaster()->MoveRotate(20000, rand()%2 ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
                SpoutTimer = 45000;
                WhirlTimer = 20000;//whirl directly after spout
                RotTimer = 20000;
                return;
            } else SpoutTimer -= diff;

            //Whirl directly after a Spout and at random times
            if (WhirlTimer <= diff)
            {
                WhirlTimer = 18000;
                DoCast(me, SPELL_WHIRL);
            } else WhirlTimer -= diff;

            if (CheckTimer <= diff)//check if there are players in melee range
            {
                InRange = false;
                Map* pMap = me->GetMap();
                Map::PlayerList const &PlayerList = pMap->GetPlayers();
                if (!PlayerList.isEmpty())
                {
                    for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    {
                        if (me->IsWithinMeleeRange(i->getSource()))
                            InRange = true;
                    }
                }
                CheckTimer = 2000;
            } else CheckTimer -= diff;

            if (RotTimer)
            {
                Map* pMap = me->GetMap();
                if (pMap->IsDungeon())
                {
                    Map::PlayerList const &PlayerList = pMap->GetPlayers();
                    for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    {
                        if (i->getSource() && i->getSource()->isAlive() && me->HasInArc((double)diff/20000*(double)M_PI*2,i->getSource()) && me->IsWithinDist(i->getSource(), SPOUT_DIST) && !i->getSource()->IsInWater())
                            DoCast(i->getSource(), SPELL_SPOUT, true);//only knock back palyers in arc, in 100yards, not in water
                    }
                }

                if (SpoutAnimTimer <= diff)
                {
                    DoCast(me, SPELL_SPOUT_ANIM, true);
                    SpoutAnimTimer = 1000;
                } else SpoutAnimTimer -= diff;

                if (RotTimer <= diff)
                {
                    RotTimer = 0;
                } else RotTimer -= diff;
                return;
            }

            if (GeyserTimer <= diff)
            {
                Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1);
                if (!pTarget && me->getVictim())
                    pTarget = me->getVictim();
                if (pTarget)
                    DoCast(pTarget, SPELL_GEYSER, true);
                GeyserTimer = rand()%5000 + 15000;
            } else GeyserTimer -= diff;

            if (!InRange)//if on players in melee range cast Waterbolt
            {
                if (WaterboltTimer <= diff)
                {
                    Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
                    if (!pTarget && me->getVictim())
                        pTarget = me->getVictim();
                    if (pTarget)
                        DoCast(pTarget, SPELL_WATERBOLT, true);
                    WaterboltTimer = 3000;
                } else WaterboltTimer -= diff;
            }

            if (!UpdateCombatState())
                return;

            DoMeleeAttackIfReady();

        }else//submerged
        {
            if (PhaseTimer <= diff)
            {
                Submerged = false;
                me->InterruptNonMeleeSpells(false);//shouldn't be any
                me->RemoveAllAuras();
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
                me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
                DoCast(me, SPELL_EMERGE, true);
                Spawned = false;
                SpoutTimer = 3000; // directly cast Spout after emerging!
                PhaseTimer = 120000;
                return;
            } else PhaseTimer-=diff;

            if (me->getThreatManager().getThreatList().empty())//check if should evade
            {
                EnterEvadeMode();
                return;
            }
            if (!me->isInCombat())
                DoZoneInCombat();

            if (!Spawned)
            {
                me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
                //spawn adds
                for (uint8 i = 0; i < 9; ++i)
                {
                    Creature* Summoned;
                    if (i < 6)
                        Summoned = me->SummonCreature(MOB_COILFANG_AMBUSHER,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
                    else Summoned = me->SummonCreature(MOB_COILFANG_GUARDIAN,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);

                    if (Summoned)
                        Summons.Summon(Summoned);
                }
                Spawned = true;
            }
        }
    }
예제 #5
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateCombatState())
            return;

        events.Update(diff);

        if (Phase == 1)
        {
            while(uint32 eventId = events.GetEvent())
            {
                switch(eventId)
                {
                    case EVENT_WASTE:
                        DoSummon(NPC_WASTE, Pos[RAND(0,3,6,9)]);
                        events.RepeatEvent(5000);
                        break;
                    case EVENT_ABOMIN:
                        DoSummon(NPC_ABOMINATION, Pos[RAND(1,4,7,10)]);
                        events.RepeatEvent(25000);
                        break;
                    case EVENT_WEAVER:
                        DoSummon(NPC_WEAVER, Pos[RAND(0,3,6,9)]);
                        events.RepeatEvent(20000);
                        break;
                    case EVENT_PHASE:
                        events.Reset();
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                        me->SetReactState(REACT_AGGRESSIVE);
                        events.ScheduleEvent(EVENT_BOLT, urand(1000,10000));
                        events.ScheduleEvent(EVENT_NOVA, urand(10000,15000));
                        events.ScheduleEvent(EVENT_DETONATE, 20000);
                        events.ScheduleEvent(EVENT_FISSURE, 25000);
                        events.ScheduleEvent(EVENT_BLAST, urand(30000,60000));
                        if (HeroicMode)
                            events.ScheduleEvent(EVENT_CHAIN, urand(30000,60000));
                        Phase = 2;
                        return;
                    default:
                        events.PopEvent();
                        break;
                }
            }
        }
        else
        {
            //start phase 3 when we are 40% health
            if (Phase != 3)
            {
                if (HealthBelowPct(40))
                {
                    Phase = 3 ;
                    DoScriptText(SAY_REQUEST_AID, m_creature);
                    //here Lich King should respond to KelThuzad but I don't know which Creature to make talk
                    //so for now just make Kelthuzad says it.
                    DoScriptText(SAY_ANSWER_REQUEST, m_creature);
                }
            }
            else if (GuardiansOfIcecrown_Count < HEROIC(2,5))
            {
                if (GuardiansOfIcecrown_Timer <= diff)
                {
                    DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8)]);
                    ++GuardiansOfIcecrown_Count;
                    GuardiansOfIcecrown_Timer = 5000;
                }
                else GuardiansOfIcecrown_Timer -= diff;
            }

            if (me->hasUnitState(UNIT_STAT_CASTING))
                return;

            if (uint32 eventId = events.GetEvent())
            {
                switch(eventId)
                {
                    case EVENT_BOLT:
                        DoCastVictim(HEROIC(SPELL_FROST_BOLT,H_SPELL_FROST_BOLT));
                        events.RepeatEvent(urand(1000,10000));
                        return;
                    case EVENT_NOVA:
                        DoCastAOE(HEROIC(SPELL_FROST_BOLT_AOE,H_SPELL_FROST_BOLT_AOE));
                        events.RepeatEvent(urand(10000,20000));
                        return;
                    case EVENT_CHAIN:
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true))
                            DoCast(pTarget, SPELL_CHAINS_OF_KELTHUZAD);
                        DoScriptText(RAND(SAY_CHAIN_1,SAY_CHAIN_2), me);
                        events.RepeatEvent(urand(30000,60000));
                        return;
                    case EVENT_DETONATE:
                    {
                        std::vector<Unit*> unitList;
                        std::list<HostilReference*> *threatList = &me->getThreatManager().getThreatList();
                        for (std::list<HostilReference*>::const_iterator itr = threatList->begin(); itr != threatList->end(); ++itr)
                        {
                            if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER
                                && (*itr)->getTarget()->getPowerType() == POWER_MANA
                                && (*itr)->getTarget()->GetPower(POWER_MANA))
                                unitList.push_back((*itr)->getTarget());
                        }

                        if (!unitList.empty())
                        {
                            std::vector<Unit*>::iterator itr = unitList.begin();
                            advance(itr, rand()%unitList.size());
                            DoCast(*itr, SPELL_MANA_DETONATION);
                            DoScriptText(RAND(SAY_SPECIAL_1,SAY_SPECIAL_2,SAY_SPECIAL_3), me);
                        }

                        events.RepeatEvent(20000);
                        return;
                    }
                    case EVENT_FISSURE:
                        if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
                            DoCast(pTarget, SPELL_SHADOW_FISURE);
                        events.RepeatEvent(25000);
                        return;
                    case EVENT_BLAST:
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
                            DoCast(pTarget, SPELL_FROST_BLAST);
                        if (rand()%2)
                            DoScriptText(SAY_FROST_BLAST, m_creature);
                        events.RepeatEvent(urand(30000,60000));
                        return;
                    default:
                        events.PopEvent();
                        return;
                }
            }

            DoMeleeAttackIfReady();
        }
    }
예제 #6
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateCombatState() || !CheckInRoom())
            return;

        events.Update(diff);

        if (!thirtyPercentReached && HealthBelowPct(30) && phaseTwo)
        {
            thirtyPercentReached = true;
            if (instance)
                instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
        }

        if (me->hasUnitState(UNIT_STAT_CASTING))
            return;

        while (uint32 eventId = events.ExecuteEvent())
        {
            switch(eventId)
            {
                case EVENT_SUMMON:
                    if (waves[waveCount].entry)
                    {
                        if ((waves[waveCount].mode == 2) && (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL))
                           DoGothikSummon(waves[waveCount].entry);
                        else if ((waves[waveCount].mode == 0) && (getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL))
                            DoGothikSummon(waves[waveCount].entry);
                        else if (waves[waveCount].mode == 1)
                            DoGothikSummon(waves[waveCount].entry);

                        // if group is not splitted, open gate and merge both sides at ~ 2 minutes (wave 11)
                        if (waveCount == 11)
                        {
                            if (!CheckGroupSplitted())
                            {
                                if (instance)
                                    instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
                                summons.DoAction(0, 0);
                                summons.DoZoneInCombat();
                                mergedSides = true;
                            }
                        }

                        if (waves[waveCount].mode == 1)
                            events.ScheduleEvent(EVENT_SUMMON,waves[waveCount].time);
                        else if ((waves[waveCount].mode == 2) && (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL))
                            events.ScheduleEvent(EVENT_SUMMON,waves[waveCount].time);
                        else if ((waves[waveCount].mode == 0) && (getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL))
                            events.ScheduleEvent(EVENT_SUMMON,waves[waveCount].time);
                        else
                            events.ScheduleEvent(EVENT_SUMMON, 0);

                        ++waveCount;
                    }
                    else
                    {
                        phaseTwo = true;
                        DoScriptText(SAY_TELEPORT, me);
                        DoTeleportTo(PosGroundLiveSide);
                        me->SetReactState(REACT_AGGRESSIVE);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
                        summons.DoAction(0, 0);
                        summons.DoZoneInCombat();
                        events.ScheduleEvent(EVENT_BOLT, 1000);
                        events.ScheduleEvent(EVENT_HARVEST, urand(3000,15000));
                        events.ScheduleEvent(EVENT_TELEPORT, 20000);
                    }
                    break;
                case EVENT_BOLT:
                    DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT));
                    events.ScheduleEvent(EVENT_BOLT, 1000);
                    break;
                case EVENT_HARVEST:
                    DoCast(me->getVictim(), SPELL_HARVEST_SOUL, true);
                    events.ScheduleEvent(EVENT_HARVEST, urand(20000,25000));
                    break;
                case EVENT_TELEPORT:
                    if (!thirtyPercentReached)
                    {
                        me->AttackStop();
                        if (IN_LIVE_SIDE(me))
                        {
                            DoTeleportTo(PosGroundDeadSide);
                        }
                        else
                        {
                            DoTeleportTo(PosGroundLiveSide);
                        }

                        me->getThreatManager().resetAggro(NotOnSameSide(me));
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0))
                        {
                            me->getThreatManager().addThreat(pTarget, 100.0f);
                            AttackStart(pTarget);
                        }

                        events.ScheduleEvent(EVENT_TELEPORT, 20000);
                    }
                    break;
            }
        }

        DoMeleeAttackIfReady();
    }