void instance_ruins_of_ahnqiraj::DoSortArmyWaves()
{
    CreatureList lCreatureList;

    // Sort the 7 army waves
    // We need to use gridsearcher for this, because coords search is too complicated here
    for (uint8 i = 0; i < MAX_ARMY_WAVES; ++i)
    {
        // Clear all the army waves
        m_sArmyWavesGuids[i].clear();
        lCreatureList.clear();

        if (Creature* pTemp = GetSingleCreatureFromStorage(aArmySortingParameters[i].m_uiEntry))
        {
            GetCreatureListWithEntryInGrid(lCreatureList, pTemp, NPC_QIRAJI_WARRIOR, aArmySortingParameters[i].m_fSearchDist);
            GetCreatureListWithEntryInGrid(lCreatureList, pTemp, NPC_SWARMGUARD_NEEDLER, aArmySortingParameters[i].m_fSearchDist);

            for (CreatureList::const_iterator itr = lCreatureList.begin(); itr != lCreatureList.end(); ++itr)
            {
                if ((*itr)->isAlive())
                    m_sArmyWavesGuids[i].insert((*itr)->GetObjectGuid());
            }

            if (pTemp->isAlive())
                m_sArmyWavesGuids[i].insert(pTemp->GetObjectGuid());
        }
    }

    // send the first wave
    m_uiCurrentArmyWave = 0;
    DoSendNextArmyWave();
}
    Creature *RespawnNearbyBugsAndGetOne()
    {
        CreatureList lUnitList;
        GetCreatureListWithEntryInGrid(lUnitList,m_creature,15316,150.0f);
        GetCreatureListWithEntryInGrid(lUnitList,m_creature,15317,150.0f);

        if (lUnitList.empty())
            return NULL;

        Creature *nearb = NULL;

        for(CreatureList::iterator iter = lUnitList.begin(); iter != lUnitList.end(); ++iter)
        {
            Creature *c = (Creature *)(*iter);
            if (c->isDead())
            {
                c->Respawn();
                c->setFaction(7);
                c->RemoveAllAuras();
            }
            if (c->IsWithinDistInMap(m_creature, ABUSE_BUG_RANGE))
            {
                if (!nearb || !urand(0, 3))
                    nearb = c;
            }
        }
        return nearb;
    }
Beispiel #3
0
bool GOHello_go_altar_of_keepers(Player* pPlayer, GameObject* pGo)
{
    if (!pPlayer || !pGo)
        return false;

    pPlayer->CastSpell(pPlayer, SPELL_USE_ALTAR_VISUAL, true);

    CreatureList lStoneKeepers;
    GetCreatureListWithEntryInGrid(lStoneKeepers, pGo, NPC_STONE_KEEPER, HALL_RADIUS);

    if (!lStoneKeepers.empty())
    {
        for(CreatureList::iterator itr = lStoneKeepers.begin(); itr != lStoneKeepers.end(); ++itr)
        {
            if (*itr && (*itr)->isAlive())
            {
                (*itr)->setFaction(FACTION_TITAN_UNFRIENDLY);
                (*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                (*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                if ((*itr)->AI())
                {
                    (*itr)->RemoveAurasDueToSpell(SPELL_STONED);
                    (*itr)->AI()->AttackStart(pPlayer);
                }
            }
        }
    }
    return false;
}
Beispiel #4
0
    void EnterEvadeMode()
    {
        CreatureList adds;
        GetCreatureListWithEntryInGrid(adds, m_creature, NPC_ADD, 50.0f);
        if (!adds.empty())
            for(CreatureList::iterator iter = adds.begin(); iter != adds.end(); ++iter)
                (*iter)->ForcedDespawn();

        m_creature->GetMotionMaster()->MoveTargetedHome();
    }
Beispiel #5
0
    void DespawnSphere()
    {
        CreatureList assistList;
        GetCreatureListWithEntryInGrid(assistList,m_creature, NPC_ETHEREAL_SPHERE ,150.0f);

        if (assistList.empty())
            return;
        for(CreatureList::iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
            (*iter)->DealDamage((*iter), (*iter)->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
    }
Beispiel #6
0
    void DespawnAdds()
    {
        CreatureList pWorshippers;
        GetCreatureListWithEntryInGrid(pWorshippers, m_creature, NPC_WORSHIPPER, DEFAULT_VISIBILITY_INSTANCE);

        if (!pWorshippers.empty())
            for(CreatureList::iterator itr = pWorshippers.begin(); itr != pWorshippers.end(); ++itr)
            {
                (*itr)->ForcedDespawn();
            }

        CreatureList pFollower;
        GetCreatureListWithEntryInGrid(pFollower, m_creature, NPC_FOLLOWER, DEFAULT_VISIBILITY_INSTANCE);

        if (!pFollower.empty())
            for(CreatureList::iterator iter = pFollower.begin(); iter != pFollower.end(); ++iter)
            {
                (*iter)->ForcedDespawn();
            }
    }
    void DamageTaken(Unit* pDoneBy, uint32& uiDamage, DamageEffectType /*damagetype*/) override
    {
        if (uiDamage > m_creature->GetHealth() || m_creature->GetHealthPercent() < 20.0f)
        {
            if (Player* pPlayer = pDoneBy->GetBeneficiaryPlayer())
            {
                if (pPlayer->GetQuestStatus(QUEST_MISSING_DIPLO_PT16) == QUEST_STATUS_INCOMPLETE)
                    guidPlayer = pPlayer->GetObjectGuid();  // Store the player to give quest credit later
            }

            uiDamage = 0;

            DoScriptText(EMOTE_SURRENDER, m_creature);
            EnterEvadeMode();

            // Make the two sentries flee and despawn
            CreatureList lSentryList;
            GetCreatureListWithEntryInGrid(lSentryList, m_creature, NPC_SENTRY, 40.0f);

            for (CreatureList::const_iterator itr = lSentryList.begin(); itr != lSentryList.end(); ++itr)
            {
                if ((*itr)->isAlive())
                {
                    (*itr)->RemoveAllAurasOnEvade();
                    (*itr)->CombatStop(true);
                    (*itr)->SetWalk(false);
                    (*itr)->GetMotionMaster()->MovePoint(0, fSentryFleePoint[0], fSentryFleePoint[1], fSentryFleePoint[2]);
                    (*itr)->ForcedDespawn(4000);
                }
            }

            // Summon Jaina Proudmoore, Archmage Tervosh and Pained
            for (const auto& lOutroSpawn : lOutroSpawns)
            {
                Creature* pCreature = m_creature->SummonCreature(lOutroSpawn.uiEntry, lOutroSpawn.fX, lOutroSpawn.fY, lOutroSpawn.fZ, lOutroSpawn.fO, TEMPSPAWN_TIMED_DESPAWN, 3 * MINUTE * IN_MILLISECONDS, false, true);
                if (pCreature)
                {
                    pCreature->CastSpell(pCreature, SPELL_TELEPORT_VISUAL, TRIGGERED_NONE);
                    pCreature->GetMotionMaster()->MovePoint(0, lOutroSpawn.fDestX, lOutroSpawn.fDestY, lOutroSpawn.fDestZ);

                    // Exception case for Archmage Tervosh: the outro event is a simple speech with visual spell cast
                    // so it will be handled by a DBScript held by NPC Archmage Tervosh
                    if (pCreature->GetEntry() == NPC_TERVOSH)
                    {
                        // Remove Gossip and Quest Giver flag from now, they will be re-added later to Archmage Tervosh in DBScript
                        pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP);
                        // The DBScript will be done here
                        pCreature->GetMotionMaster()->MoveWaypoint(0);
                    }
                }
            }
        }
    }
Beispiel #8
0
 void ShowMushrooms(bool show = true)
 {
     CreatureList lMushroomsHealthy;
     GetCreatureListWithEntryInGrid(lMushroomsHealthy, m_creature, NPC_HEALTHY_MUSHROOM, 150.0f);
     for(CreatureList::iterator itr1 = lMushroomsHealthy.begin(); itr1 != lMushroomsHealthy.end(); ++itr1)
     {
         if (show)
             (*itr1)->SetVisibility(VISIBILITY_ON);
         else
             (*itr1)->SetVisibility(VISIBILITY_OFF);
     }
     CreatureList lMushroomsPoison;
     GetCreatureListWithEntryInGrid(lMushroomsPoison, m_creature, NPC_POISONOUS_MUSHROOM, 150.0f);
     for(CreatureList::iterator itr2 = lMushroomsPoison.begin(); itr2 != lMushroomsPoison.end(); ++itr2)
     {
         if (show)
             (*itr2)->SetVisibility(VISIBILITY_ON);
         else
             (*itr2)->SetVisibility(VISIBILITY_OFF);
     }
     
 }
Beispiel #9
0
    Creature* SelectRandomCreatureOfEntryInRange(uint32 uiEntry, float fRange)
    {
        CreatureList lCreatureList;
        GetCreatureListWithEntryInGrid(lCreatureList, m_creature, uiEntry, fRange);

        if (lCreatureList.empty())
            return NULL;

        CreatureList::iterator iter = lCreatureList.begin();
        advance(iter, urand(0, lCreatureList.size()-1));

        return *iter;
    }
    // function to cleanup the world states and GO flags
    void DoEncounterCleanup()
    {
        // remove world state
        if (Player* pSummoner = m_creature->GetMap()->GetPlayer(m_summonerGuid))
            pSummoner->SendUpdateWorldState(WORLD_STATE_TETHYR_SHOW, 0);

        // reset all cannons
        GameObjectList lCannonsInRange;
        GetGameObjectListWithEntryInGrid(lCannonsInRange, m_creature, GO_COVE_CANNON, 100.0f);

        for (GameObjectList::const_iterator itr = lCannonsInRange.begin(); itr != lCannonsInRange.end(); ++itr)
            (*itr)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT);

        // despawn all marksmen
        CreatureList lMarksmenInRange;
        GetCreatureListWithEntryInGrid(lMarksmenInRange, m_creature, NPC_THERAMORE_MARKSMAN, 100.0f);

        for (CreatureList::const_iterator itr = lMarksmenInRange.begin(); itr != lMarksmenInRange.end(); ++itr)
            (*itr)->ForcedDespawn(30000);
    }
    void MovementInform(uint32 uiMotionType, uint32 uiPointId) override
    {
        if (uiMotionType == WAYPOINT_MOTION_TYPE)
        {
            // start attacking
            if (uiPointId == 12)
            {
                // make cannons usable
                GameObjectList lCannonsInRange;
                GetGameObjectListWithEntryInGrid(lCannonsInRange, m_creature, GO_COVE_CANNON, 100.0f);

                for (GameObjectList::const_iterator itr = lCannonsInRange.begin(); itr != lCannonsInRange.end(); ++itr)
                    (*itr)->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT);

                // attack all marksmen
                CreatureList lMarksmenInRange;
                GetCreatureListWithEntryInGrid(lMarksmenInRange, m_creature, NPC_THERAMORE_MARKSMAN, 100.0f);

                for (CreatureList::const_iterator itr = lMarksmenInRange.begin(); itr != lMarksmenInRange.end(); ++itr)
                {
                    (*itr)->AI()->AttackStart(m_creature);
                    AttackStart(*itr);
                }
            }
        }
        else if (uiMotionType == POINT_MOTION_TYPE)
        {
            // Spout on cannon point reach
            if (uiPointId)
            {
                if (DoCastSpellIfCan(m_creature, urand(0, 1) ? SPELL_SPOUT_LEFT : SPELL_SPOUT_RIGHT, CAST_INTERRUPT_PREVIOUS) == CAST_OK)
                {
                    // Remove the target focus
                    m_creature->SetTarget(nullptr);
                    m_uiPhase = PHASE_SPOUT;
                }
            }
        }
    }
Beispiel #12
0
void npc_toc_announcerAI::DeleteCreaturesAndRemoveAuras()
{
    CreatureList deleteList;
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_LIGHT_ESSENCE, DEFAULT_VISIBILITY_INSTANCE);
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_DARK_ESSENCE, DEFAULT_VISIBILITY_INSTANCE);
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_CONCENTRATED_LIGHT, DEFAULT_VISIBILITY_INSTANCE);
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_CONCENTRATED_DARKNESS, DEFAULT_VISIBILITY_INSTANCE);
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_MISTRESS_OF_PAIN, DEFAULT_VISIBILITY_INSTANCE);
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_FELFLAME_INFERNAL, DEFAULT_VISIBILITY_INSTANCE);
    // clean up useless corpses
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_GORMOK, DEFAULT_VISIBILITY_INSTANCE);
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_ACIDMAW, DEFAULT_VISIBILITY_INSTANCE);
    GetCreatureListWithEntryInGrid(deleteList, m_creature, NPC_DREADSCALE, DEFAULT_VISIBILITY_INSTANCE);
    for(CreatureList::iterator itr = deleteList.begin(); itr != deleteList.end(); ++itr)
        (*itr)->ForcedDespawn(3500);

    Map::PlayerList const &PlayerList = m_pInstance->instance->GetPlayers();
    if (!PlayerList.isEmpty())
        for (Map::PlayerList::const_iterator iter = PlayerList.begin(); iter != PlayerList.end(); ++iter)
            if (Player* plr = iter->getSource())
                for (uint8 d = 0; d < 12; ++d)
                    plr->RemoveAurasDueToSpell(Dispell[d]);
}
bool QuestAccept_npc_private_hendel(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
{
    if (pQuest->GetQuestId() == QUEST_MISSING_DIPLO_PT16)
    {
        pCreature->SetFactionTemporary(FACTION_HOSTILE, TEMPFACTION_RESTORE_COMBAT_STOP | TEMPFACTION_RESTORE_RESPAWN);
        pCreature->AI()->AttackStart(pPlayer);

        // Find the nearby sentries in order to make them attack
        // The two sentries are linked to Private Hendel in DB to ensure they respawn together
        CreatureList lSentryList;
        GetCreatureListWithEntryInGrid(lSentryList, pCreature, NPC_SENTRY, 40.0f);

        for (CreatureList::const_iterator itr = lSentryList.begin(); itr != lSentryList.end(); ++itr)
        {
            if ((*itr)->isAlive())
            {
                (*itr)->SetFactionTemporary(FACTION_HOSTILE, TEMPFACTION_RESTORE_COMBAT_STOP | TEMPFACTION_RESTORE_RESPAWN);
                (*itr)->AI()->AttackStart(pPlayer);
            }
        }
    }

    return true;
}
Beispiel #14
0
void instance_karazhan::DoPrepareChessEvent()
{
    // Allow all the chess pieces to init start position
    for (GuidList::const_iterator itr = m_lChessPiecesAlliance.begin(); itr != m_lChessPiecesAlliance.end(); ++itr)
    {
        if (Creature* pChessPiece = instance->GetCreature(*itr))
        {
            Creature* pSquare = GetClosestCreatureWithEntry(pChessPiece, NPC_SQUARE_BLACK, 2.0f);
            if (!pSquare)
                pSquare = GetClosestCreatureWithEntry(pChessPiece, NPC_SQUARE_WHITE, 2.0f);
            if (!pSquare)
            {
                script_error_log("Instance Karazhan: ERROR Failed to properly load the Chess square for %s.", pChessPiece->GetGuidStr().c_str());
                return;
            }

            // send event which will prepare the current square
            pChessPiece->AI()->SendAIEvent(AI_EVENT_CUSTOM_B, pSquare, pChessPiece);
        }
    }

    for (GuidList::const_iterator itr = m_lChessPiecesHorde.begin(); itr != m_lChessPiecesHorde.end(); ++itr)
    {
        if (Creature* pChessPiece = instance->GetCreature(*itr))
        {
            Creature* pSquare = GetClosestCreatureWithEntry(pChessPiece, NPC_SQUARE_BLACK, 2.0f);
            if (!pSquare)
                pSquare = GetClosestCreatureWithEntry(pChessPiece, NPC_SQUARE_WHITE, 2.0f);
            if (!pSquare)
            {
                script_error_log("Instance Karazhan: ERROR Failed to properly load the Chess square for %s.", pChessPiece->GetGuidStr().c_str());
                return;
            }

            // send event which will prepare the current square
            pChessPiece->AI()->SendAIEvent(AI_EVENT_CUSTOM_B, pSquare, pChessPiece);
        }
    }

    // add silence debuff
    Map::PlayerList const& players = instance->GetPlayers();
    for (const auto& player : players)
    {
        if (Player* pPlayer = player.getSource())
            pPlayer->CastSpell(pPlayer, SPELL_GAME_IN_SESSION, TRIGGERED_OLD_TRIGGERED);
    }

    m_uiAllianceStalkerCount = 0;
    m_uiHordeStalkerCount = 0;
    m_vHordeStalkers.clear();
    m_vAllianceStalkers.clear();

    // sort stalkers depending on side
    CreatureList lStalkers;
    for (GuidList::const_iterator itr = m_lChessHordeStalkerList.begin(); itr != m_lChessHordeStalkerList.end(); ++itr)
    {
        if (Creature* pTemp = instance->GetCreature(*itr))
            lStalkers.push_back(pTemp);
    }

    if (lStalkers.empty())
    {
        script_error_log("Instance Karazhan: ERROR Failed to properly load the horde side stalkers for the Chess Event.");
        return;
    }

    // get the proper statusBar npc
    Creature* pStatusBar = instance->GetCreature(m_HordeStatusGuid);
    if (!pStatusBar)
        return;

    lStalkers.sort(ObjectDistanceOrder(pStatusBar));
    for (CreatureList::const_iterator itr = lStalkers.begin(); itr != lStalkers.end(); ++itr)
        m_vHordeStalkers.push_back((*itr)->GetObjectGuid());

    lStalkers.clear();
    for (GuidList::const_iterator itr = m_lChessAllianceStalkerList.begin(); itr != m_lChessAllianceStalkerList.end(); ++itr)
    {
        if (Creature* pTemp = instance->GetCreature(*itr))
            lStalkers.push_back(pTemp);
    }

    if (lStalkers.empty())
    {
        script_error_log("Instance Karazhan: ERROR Failed to properly load the alliance side stalkers for the Chess Event.");
        return;
    }

    // get the proper statusBar npc
    pStatusBar = instance->GetCreature(m_AllianceStatusGuid);
    if (!pStatusBar)
        return;

    lStalkers.sort(ObjectDistanceOrder(pStatusBar));
    for (CreatureList::const_iterator itr = lStalkers.begin(); itr != lStalkers.end(); ++itr)
        m_vAllianceStalkers.push_back((*itr)->GetObjectGuid());
}
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // Demoralizing Shout Timer
        if (m_uiDemoralizingShoutTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_DEMORALIZING_SHOUT) == CAST_OK)
                m_uiDemoralizingShoutTimer = urand(15000, 20000);
        }
        else
            m_uiDemoralizingShoutTimer -= uiDiff;

        // Inspire Timer
        if (m_uiInspireTimer < uiDiff)
        {
            Creature* pTarget = nullptr;
            CreatureList pList = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE);
            if (!pList.empty())
            {
                CreatureList::iterator i = pList.begin();
                advance(i, (rand() % pList.size()));
                pTarget = (*i);
            }

            if (!pTarget)
                pTarget = m_creature;

            if (DoCastSpellIfCan(pTarget, SPELL_INSPIRE) == CAST_OK)
                m_uiInspireTimer = 10000;
        }
        else
            m_uiInspireTimer -= uiDiff;

        // Hand of Ragnaros Timer
        if (m_uiKnockdownTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_HAND_OF_RAGNAROS) == CAST_OK)
                m_uiKnockdownTimer = urand(12000, 15000);
        }
        else
            m_uiKnockdownTimer -= uiDiff;

        // Flamespear Timer
        if (m_uiFlamespearTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
            {
                if (DoCastSpellIfCan(pTarget, SPELL_FLAMESPEAR) == CAST_OK)
                    m_uiFlamespearTimer = urand(12000, 16000);
            }
        }
        else
            m_uiFlamespearTimer -= uiDiff;

        // Dark Strike Timer
        if (m_uiDarkstrikeTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DARK_STRIKE) == CAST_OK)
                m_uiDarkstrikeTimer = urand(15000, 18000);
        }
        else
            m_uiDarkstrikeTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Beispiel #16
0
    void UpdateAI(const uint32 uiDiff)
    {
        //Return since we have no target
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiPhase == 1 || m_uiPhase == 2)
        {
            // tank out of range
            if (m_creature->GetDistance2d(m_creature->getVictim()) > m_creature->GetAttackDistance(m_creature->getVictim()))
            {
                if (m_uiRange_Timer <= uiDiff)
                {
                    DoCast(m_creature, SPELL_FROST_BREATH);
                    m_uiRange_Timer = 10000;
                }m_uiRange_Timer -= uiDiff;
            }else m_uiRange_Timer = 10000;
            
            //Pull
            if (m_uiPullTimer < uiDiff)
            {
                PullAll();
                m_uiPullTimer = 15000;
            }
            else m_uiPullTimer -= uiDiff;

            //Smash
            if (m_uiSmashTimer < uiDiff)
            {
                DoCast(m_creature, SPELL_SMASH);
                m_uiSmashTimer = 17000;
            }
            else m_uiSmashTimer -= uiDiff;

            //Cleave
            if (m_uiCleaveTimer < uiDiff)
            {
                DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE);
                m_uiCleaveTimer = urand(5000, 8000);
            }
            else m_uiCleaveTimer -= uiDiff;
            
            if (m_uiPhase == 1 && m_creature->GetHealthPercent() <= 50.0f)
            {
                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                m_creature->RemoveAllAuras();
                m_creature->CastSpell(m_creature, SPELL_ICE_BLOCK, true);
                SpawnAdds();
                m_uiPhase = 2;
                return;
            }
        }
        else if (m_uiPhase == 2)
        {
            if (m_uiAddCheck_Timer <= uiDiff)
            {
                CreatureList adds;
                GetCreatureListWithEntryInGrid(adds, m_creature, NPC_ADD, 5.0f);
                if (!adds.empty())
                {
                    adds.clear();
                    GetCreatureListWithEntryInGrid(adds, m_creature, NPC_ADD, 45.0f);
                    for(CreatureList::iterator iter = adds.begin(); iter != adds.end(); ++iter)
                    {
                        if (!(*iter)->isAlive())
                            continue;
                        (*iter)->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
                        m_creature->CastSpell(*iter, SPELL_LINK, true);
                        m_creature->CastSpell(m_creature, SPELL_DMG, true);
                    }
                    m_uiPhase = 3;
                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    m_creature->RemoveAllAuras();
                    PullAll();
                    m_uiPullTimer = 15000;
                    m_uiSmashTimer = 17000;
                    m_uiCleaveTimer = urand(5000, 8000);
                    m_uiRange_Timer = 10000;
                    return;
                }
                m_uiAddCheck_Timer = 2000;
            }else m_uiAddCheck_Timer -= uiDiff;
            
            if (m_uiBlizzard_Timer <= uiDiff)
            {
                if (Unit* target = m_creature->SelectAttackingPlayer(ATTACKING_TARGET_RANDOM, 0))
                    DoCast(target,SPELL_BLIZZARD);
                m_uiBlizzard_Timer = 10000;
            }else m_uiBlizzard_Timer -= uiDiff;
            
            //we dont wanna melee
            return;
        }
        
        DoMeleeAttackIfReady();
    }
    void UpdateAI(const uint32 uiDiff) override
    {
        bool bHasYelled = false;
        CreatureList lTechniciansList;

        if (m_uiIntroTimer)
        {
            if (m_uiIntroTimer <= uiDiff)
            {
                switch (m_uiIntroPhase)
                {
                    case 0:
                        // Summon Lord Victor Nefarius in front of the Throne
                        m_creature->SummonCreature(NPC_LORD_VICTOR_NEFARIUS, aNefariusSpawnLoc[0], aNefariusSpawnLoc[1], aNefariusSpawnLoc[2], aNefariusSpawnLoc[3], TEMPSPAWN_TIMED_DESPAWN, 25000);

                        // Search for the Blackwing Technicians tormeting Vaelastrasz to make them flee to the next room above the stairs
                        GetCreatureListWithEntryInGrid(lTechniciansList, m_creature, NPC_BLACKWING_TECHNICIAN, 40.0f);
                        for (CreatureList::const_iterator itr = lTechniciansList.begin(); itr != lTechniciansList.end(); ++itr)
                        {
                            // Ignore Blackwing Technicians on upper floors and dead ones
                            if (!((*itr)->isAlive()) || (*itr)->GetPositionZ() > m_creature->GetPositionZ() + 1)
                                continue;

                            // Each fleeing part and despawn is handled in DB, we only need to make them run
                            (*itr)->SetWalk(false);

                            // The technicians will behave differently depending on they are on the right or left side of
                            // Vaelastrasz. We compare their X position to Vaelastrasz X position to sort them out
                            if ((*itr)->GetPositionX() > m_creature->GetPositionX())
                            {
                                // Left side
                                if (!bHasYelled)
                                {
                                    DoScriptText(SAY_TECHNICIAN_RUN, (*itr));
                                    bHasYelled = true;
                                }
                                (*itr)->GetMotionMaster()->MoveWaypoint(0);
                            }
                            else
                                // Right side
                                (*itr)->GetMotionMaster()->MoveWaypoint(1);
                        }
                        m_uiIntroTimer = 1000;
                        break;
                    case 1:
                        if (Creature* pNefarius = m_creature->GetMap()->GetCreature(m_nefariusGuid))
                        {
                            pNefarius->CastSpell(m_creature, SPELL_NEFARIUS_CORRUPTION, TRIGGERED_OLD_TRIGGERED);
                            DoScriptText(SAY_NEFARIUS_CORRUPT_1, pNefarius);
                        }
                        m_uiIntroTimer = 16000;
                        break;
                    case 2:
                        if (Creature* pNefarius = m_creature->GetMap()->GetCreature(m_nefariusGuid))
                            DoScriptText(SAY_NEFARIUS_CORRUPT_2, pNefarius);

                        // Set npc flags now
                        m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
                        m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
                        m_uiIntroTimer = 6000;
                        break;
                    case 3:
                        if (Creature* pNefarius = m_creature->GetMap()->GetCreature(m_nefariusGuid))
                            pNefarius->CastSpell(m_creature, SPELL_RED_LIGHTNING, TRIGGERED_NONE);
                        m_uiIntroTimer = 0;
                        break;
                }
                ++m_uiIntroPhase;
            }
            else
                m_uiIntroTimer -= uiDiff;
        }

        // Speech
        if (m_uiSpeechTimer)
        {
            if (m_uiSpeechTimer <= uiDiff)
            {
                switch (m_uiSpeechNum)
                {
                    case 0:
                        // 16 seconds till next line
                        DoScriptText(SAY_LINE_2, m_creature);
                        m_uiSpeechTimer = 16000;
                        ++m_uiSpeechNum;
                        break;
                    case 1:
                        // This one is actually 16 seconds but we only go to 10 seconds because he starts attacking after he says "I must fight this!"
                        DoScriptText(SAY_LINE_3, m_creature);
                        m_uiSpeechTimer = 10000;
                        ++m_uiSpeechNum;
                        break;
                    case 2:
                        m_creature->SetFactionTemporary(FACTION_HOSTILE, TEMPFACTION_RESTORE_RESPAWN);

                        if (m_playerGuid)
                        {
                            if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid))
                                AttackStart(pPlayer);
                        }
                        m_uiSpeechTimer = 0;
                        break;
                }
            }
            else
                m_uiSpeechTimer -= uiDiff;
        }

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

        // Yell if hp lower than 15%
        if (m_creature->GetHealthPercent() < 15.0f && !m_bHasYelled)
        {
            DoScriptText(SAY_HALFLIFE, m_creature);
            m_bHasYelled = true;
        }

        // Cleave Timer
        if (m_uiCleaveTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK)
                m_uiCleaveTimer = 15000;
        }
        else
            m_uiCleaveTimer -= uiDiff;

        // Flame Breath Timer
        if (m_uiFlameBreathTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FLAME_BREATH) == CAST_OK)
                m_uiFlameBreathTimer = urand(4000, 8000);
        }
        else
            m_uiFlameBreathTimer -= uiDiff;

        // Burning Adrenaline Caster Timer
        if (m_uiBurningAdrenalineCasterTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_BURNING_ADRENALINE, SELECT_FLAG_PLAYER | SELECT_FLAG_POWER_MANA))
            {
                pTarget->CastSpell(pTarget, SPELL_BURNING_ADRENALINE, TRIGGERED_OLD_TRIGGERED, nullptr, nullptr, m_creature->GetObjectGuid());
                m_uiBurningAdrenalineCasterTimer = 15000;
            }
        }
        else
            m_uiBurningAdrenalineCasterTimer -= uiDiff;

        // Burning Adrenaline Tank Timer
        if (m_uiBurningAdrenalineTankTimer < uiDiff)
        {
            // have the victim cast the spell on himself otherwise the third effect aura will be applied
            // to Vael instead of the player
            m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_BURNING_ADRENALINE_TANK, TRIGGERED_OLD_TRIGGERED, nullptr, nullptr, m_creature->GetObjectGuid());

            m_uiBurningAdrenalineTankTimer = 45000;
        }
        else
            m_uiBurningAdrenalineTankTimer -= uiDiff;

        // Fire Nova Timer
        if (m_uiFireNovaTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_FIRE_NOVA) == CAST_OK)
                m_uiFireNovaTimer = 5000;
        }
        else
            m_uiFireNovaTimer -= uiDiff;

        // Tail Sweep Timer
        if (m_uiTailSweepTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_TAIL_SWEEP) == CAST_OK)
                m_uiTailSweepTimer = 20000;
        }
        else
            m_uiTailSweepTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiHealTimer < uiDiff)
        {
            if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f))
            {
                if (DoCastSpellIfCan(pTarget, SPELL_FLASH_HEAL) == CAST_OK)
                    m_uiHealTimer = urand(15000, 20000);
            }
        }
        else
            m_uiHealTimer -= uiDiff;

        if (m_uiRenewTimer < uiDiff)
        {
            if (Unit* pTarget = DoSelectLowestHpFriendly(50.0f))
            {
                if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_RENEW : SPELL_RENEW_H) == CAST_OK)
                    m_uiRenewTimer = urand(5000, 10000);
            }
        }
        else
            m_uiRenewTimer -= uiDiff;

        if (m_uiShieldTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_SHIELD : SPELL_SHIELD_H) == CAST_OK)
                m_uiShieldTimer = urand(30000, 35000);
        }
        else
            m_uiShieldTimer -= uiDiff;

        if (m_uiDispelTimer < uiDiff)
        {
            Unit* pTarget = nullptr;
            CreatureList lTempList = DoFindFriendlyCC(50.0f);

            if (!lTempList.empty())
                pTarget = *(lTempList.begin());
            else
                pTarget = DoSelectLowestHpFriendly(50.0f);

            if (pTarget)
            {
                if (DoCastSpellIfCan(pTarget, SPELL_DISPEL_MAGIC) == CAST_OK)
                    m_uiDispelTimer = urand(12000, 15000);
            }
        }
        else
            m_uiDispelTimer -= uiDiff;

        // Use the Medallion if CC - only on heroic. Not sure how many times they are allowed to use it.
        if (!m_bIsRegularMode && m_uiMedallionTimer)
        {
            if (m_creature->isFrozen() || m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT))
            {
                if (m_uiMedallionTimer <= uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_MEDALLION, CAST_TRIGGERED) == CAST_OK)
                        m_uiMedallionTimer = 0;
                }
                else
                    m_uiMedallionTimer -= uiDiff;
            }
        }

        if (m_uiSWPainTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, nullptr, SELECT_FLAG_PLAYER))
            {
                if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_SHADOW_WORD_PAIN : SPELL_SHADOW_WORD_PAIN_H) == CAST_OK)
                    m_uiSWPainTimer = 10000;
            }
        }
        else
            m_uiSWPainTimer -= uiDiff;

        if (m_uiScreamTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_SCREAM) == CAST_OK)
                m_uiScreamTimer = urand(15000, 20000);
        }
        else
            m_uiScreamTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
    bool UpdateCompanionAI(const uint32 uiDiff)
    {
        if (m_uiGoblinDragonGunTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_GOBLIN_DRAGON_GUN : SPELL_GOBLIN_DRAGON_GUN_H) == CAST_OK)
                m_uiGoblinDragonGunTimer = urand(10000, 20000);
        }
        else
            m_uiGoblinDragonGunTimer -= uiDiff;

        if (m_uiRocketLaunchTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, nullptr, SELECT_FLAG_PLAYER))
            {
                if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_ROCKET_LAUNCH : SPELL_ROCKET_LAUNCH_H) == CAST_OK)
                    m_uiRocketLaunchTimer = 9000;
            }
        }
        else
            m_uiRocketLaunchTimer -= uiDiff;

        if (m_uiFelIronBombTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, nullptr, SELECT_FLAG_PLAYER))
            {
                if (DoCastSpellIfCan(pTarget, m_bIsRegularMode ? SPELL_FEL_IRON_BOMB : SPELL_FEL_IRON_BOMB_H) == CAST_OK)
                    m_uiFelIronBombTimer = 15000;
            }
        }
        else
            m_uiFelIronBombTimer -= uiDiff;

        if (m_uiRecombobulateTimer < uiDiff)
        {
            // Note: this should be casted only on Polyformed targets
            Unit* pTarget = nullptr;
            CreatureList lTempList = DoFindFriendlyCC(50.0f);

            if (!lTempList.empty())
                pTarget = *(lTempList.begin());
            else
                pTarget = DoSelectLowestHpFriendly(50.0f);

            if (pTarget)
            {
                if (DoCastSpellIfCan(pTarget, SPELL_RECOMBOBULATE) == CAST_OK)
                    m_uiRecombobulateTimer = 2000;
            }
        }
        else
            m_uiRecombobulateTimer -= uiDiff;

        if (m_uiHighExplosiveSheepTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_HIGH_EXPLOSIVE_SHEEP) == CAST_OK)
                m_uiHighExplosiveSheepTimer = 65000;
        }
        else
            m_uiHighExplosiveSheepTimer -= uiDiff;

        return true;
    }
Beispiel #20
0
void npc_toc_announcerAI::UpdateAI(const uint32 /*diff*/)
{
    // custom event step handling
    if (SpellTimer* stepTimer = m_TimerMgr->GetState(TIMER_PHASE_HANDLING))
    {
        uint32 cooldown = 0;
        ++encounterStage;

        switch(currentEncounter)
        {
            case TYPE_BEASTS:
            {
                switch(encounterStage)
                {
                    case 1:
                        DoScriptText(SAY_STAGE_0_01, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 22000;
                        break;
                    case 2:
                        DoScriptText(SAY_STAGE_0_02, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 4000;
                        break;
                    case 3:
                        SummonToCBoss(NPC_GORMOK, 0, 100);
                        cooldown = 1000;
                        break;
                    case 4:
                        if (encounterCreature)
                            encounterCreature->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap());
                        cooldown = 5000;
                        break;
                    case 5:
                        if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI)
                            DoScriptText(SAY_STAGE_0_03a, m_pInstance->GetCreature(NPC_WRYNN));
                        else
                            DoScriptText(SAY_STAGE_0_03h, m_pInstance->GetCreature(NPC_GARROSH));
                        cooldown = isHeroic ? 174000 : REALLY_BIG_COOLDOWN;
                        break;
                    case 6:
                        SummonToCBoss(NPC_DREADSCALE, NULL, 5100);
                        DoScriptText(SAY_STAGE_0_04, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 6000;
                        break;
                    case 7:
                        if (encounterCreature)
                            encounterCreature->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap());
                        cooldown = 4000;
                        break;
                    case 8:
                    {
                        Player* randPlr = m_pInstance->GetRandomPlayerInMap();
                        if (!randPlr)
                            break;

                        encounterCreature2 = DoSpawnTocBoss(NPC_ACIDMAW, randPlr->GetPosition(), 0);
                        if (!encounterCreature2)
                            break;

                        encounterCreature2->CastSpell(encounterCreature2, SPELL_EMERGE_ACIDMAW, false);
                        cooldown = isHeroic ? 170000 + stepTimer->GetCustomValue() : REALLY_BIG_COOLDOWN;
                        break;
                    }
                    case 9:
                        SummonToCBoss(NPC_ICEHOWL, NULL, 3100);
                        DoScriptText(SAY_STAGE_0_05, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 4000;
                    case 10:
                        if (encounterCreature)
                            encounterCreature->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap());
                        cooldown = isHeroic ? 176000 + stepTimer->GetCustomValue() : REALLY_BIG_COOLDOWN;
                        break;
                    case 11:
                        if (encounterCreature)
                            encounterCreature->GetTimerMgr()->AddSpellToQueue(SPELL_BERSERK_NB);
                        cooldown = REALLY_BIG_COOLDOWN;
                        break;
                    case 51: // outro
                        DoScriptText(SAY_STAGE_0_06, m_pInstance->GetCreature(NPC_TIRION));
                        break;
                }
                break;
            }
            case TYPE_JARAXXUS:
            {
                switch(encounterStage)
                {
                    case 1:
                    {
                        encounterCreature2 = m_pInstance->GetCreature(NPC_JARAXXUS);
                        if (encounterCreature2 && m_pInstance->GetData(TYPE_JARAXXUS) == FAIL)
                        {
                            encounterCreature2->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
                            encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
                            encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
                            ((ScriptedAI*)encounterCreature2->AI())->EnableAttack(true);
                            DoScriptText(SAY_STAGE_1_AGGRO, encounterCreature2);
                            encounterCreature2->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap());
                            m_pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS);
                            cooldown = REALLY_BIG_COOLDOWN;
                        }
                        else
                        {
                            DoScriptText(SAY_STAGE_1_01, m_pInstance->GetCreature(NPC_TIRION));
                            SummonToCBoss(NPC_FIZZLEBANG);
                            cooldown = 2000;
                        }
                        break;
                    }
                    case 2:
                    {
                        if (!encounterCreature)
                            break;

                        encounterCreature->AddSplineFlag(SPLINEFLAG_WALKMODE);
                        encounterCreature->GetMotionMaster()->MovePoint(POINT_MOVE, SpawnLoc[LOC_FIZZLE_END], false);

                        uint32 timeToPoint = uint32(encounterCreature->GetPosition().GetDistance2d(SpawnLoc[LOC_FIZZLE_END])/0.0025f);

                        m_TimerMgr->Cooldown(TIMER_DOOR_HANDLER, timeToPoint);
                        cooldown = timeToPoint + 1000;
                        break;
                    }
                    case 3:
                        DoScriptText(SAY_STAGE_1_02, encounterCreature);
                        cooldown = 11000;
                        break;
                    case 4:
                    {
                        DoScriptText(SAY_STAGE_1_03, encounterCreature);
                        Coords sumPos = SpawnLoc[LOC_CENTER];
                        encounterCreature->SummonCreature(NPC_WILFRED_PORTAL_GROUND, sumPos, 1.5f*M_PI_F, TEMPSUMMON_TIMED_DESPAWN, 8000);
                        cooldown = 2000;
                        break;
                    }
                    case 5:
                    {
                        Coords sumPos = SpawnLoc[LOC_CENTER];
                        sumPos.z += 5.f;
                        if (!(encounterCreature2 = encounterCreature->SummonCreature(NPC_TRIGGER, sumPos, 1.5f*M_PI_F, TEMPSUMMON_TIMED_DESPAWN, 6000)))
                            break;

                        encounterCreature2->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.f);
                        encounterCreature2->CastSpell(encounterCreature2, SPELL_WILFRED_PORTAL, false);
                        cooldown = 3500;
                        break;
                    }
                    case 6:
                        DoScriptText(SAY_STAGE_1_04, encounterCreature);
                        if (!(encounterCreature2 = DoSpawnTocBoss(NPC_JARAXXUS, encounterCreature2->GetPosition(), encounterCreature->GetOrientation())))
                            break;

                        cooldown = 500;
                        break;
                    case 7:
                        encounterCreature2->GetMotionMaster()->MovePoint(0, SpawnLoc[LOC_JAROXXUS_END]);
                        cooldown = 2300;
                        break;
                    case 8:
                        encounterCreature2->SetFacingToObject(encounterCreature);
                        encounterCreature2->SetSummonPoint(encounterCreature->GetPositionX(), encounterCreature->GetPositionY(), encounterCreature->GetPositionZ(), encounterCreature->GetOrientation());
                        ((ScriptedAI*)encounterCreature2->AI())->SetCombatMovement(false);
                        cooldown = 8500;
                        break;
                    case 9:
                        DoScriptText(SAY_STAGE_1_05, encounterCreature2);
                        cooldown = 7000;
                        break;
                    case 10:
                        DoScriptText(SAY_STAGE_1_06, encounterCreature);
                        cooldown = 800;
                        break;
                    case 11:
                        encounterCreature2->CastSpell(encounterCreature, SPELL_FEL_LIGHTNING_IK, false);
                        cooldown = 2000;
                        break;
                    case 12:
                        DoScriptText(SAY_STAGE_1_07, m_pInstance->GetCreature(NPC_TIRION));
                        ((ScriptedAI*)encounterCreature2->AI())->SetCombatMovement(true);
                        cooldown = 5000;
                        break;
                    case 13:
                        encounterCreature2->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
                        encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                        encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
                        encounterCreature2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
                        ((ScriptedAI*)encounterCreature2->AI())->EnableAttack(true);
                        m_pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS);
                        DoScriptText(SAY_STAGE_1_AGGRO, encounterCreature2);
                        encounterCreature2->AI()->AttackStart(m_pInstance->GetRandomPlayerInMap());
                        cooldown = REALLY_BIG_COOLDOWN;
                        break;
                    case 51: //outro
                        DoScriptText(SAY_STAGE_1_08, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 15000;
                        break;
                    case 52:
                        DoScriptText(SAY_STAGE_1_09, m_pInstance->GetCreature(NPC_GARROSH));
                        cooldown = 10000;
                        break;
                    case 53:
                        DoScriptText(SAY_STAGE_1_10, m_pInstance->GetCreature(NPC_WRYNN));
                        cooldown = 7000;
                        break;
                    case 54:
                        DoScriptText(SAY_STAGE_1_11, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 5000;
                        break;
                    case 55:
                        break;
                }
                break;
            }
            case TYPE_CRUSADERS:
            {
                switch(encounterStage)
                {
                    case 1:
                        DoScriptText(SAY_STAGE_2_01, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 9000;
                        break;
                    case 2:
                        if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI)
                            DoScriptText(SAY_STAGE_2_02h, m_pInstance->GetCreature(NPC_GARROSH));
                        else
                            DoScriptText(SAY_STAGE_2_02a, m_pInstance->GetCreature(NPC_WRYNN));
                        cooldown = 17000;
                        break;
                    case 3:
                        DoScriptText(SAY_STAGE_2_03, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 5000;
                        break;
                    case 4:
                    {
                        uint32 spawnMask = 0;
                        if (!(spawnMask = m_pInstance->GetData(TYPE_CHAMPION_SPAWN_MASK)))
                        {
                            typedef std::list<uint8> ChampionList;
                            ChampionList healerList, dpsList, finalList;

                            for(uint8 i = 0; i < CHAMPION_COUNT; ++i)
                            {
                                if (i == CHAMPION_R_DRUID  || i == CHAMPION_H_PALADIN || i == CHAMPION_R_SHAMAN || i == CHAMPION_D_PRIEST)
                                    healerList.push_back(i);
                                else
                                    dpsList.push_back(i);
                            }

                            for(uint8 h = 0; h < 2; ++h)
                            {
                                uint8 neededCount = h ? (is10Man ? 2 : 3) : (is10Man ? 4 : 7);
                                ChampionList& refList = h ? healerList : dpsList;
                                for (uint8 i = 0; i < neededCount; ++i)
                                {
                                    ChampionList::iterator itr = refList.begin();
                                    std::advance(itr, urand(0, refList.size()-1));
                                    finalList.push_back(*itr);
                                    refList.erase(itr);
                                }
                            }

                            for(ChampionList::iterator itr = finalList.begin(); itr != finalList.end(); ++itr)
                                spawnMask |= (1 << *itr);

                            m_pInstance->SetData(TYPE_CHAMPION_SPAWN_MASK, spawnMask);
                        }
                        encounterCreature = NULL;
                        encounterCreature2 = NULL;
                        AddNonCastTimer(TIMER_CUSTOM, 500, 2000);
                        cooldown = REALLY_BIG_COOLDOWN;
                        break;
                    }
                    case 5:
                    {
                        uint32 textId, npcId, faction;
                        if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI)
                        {
                            textId = SAY_STAGE_2_04h;
                            npcId = NPC_GARROSH;
                            faction = FACTION_HORDE;
                        }
                        else
                        {
                            textId = SAY_STAGE_2_04a;
                            npcId = NPC_WRYNN;
                            faction = FACTION_ALLIANCE;
                        }

                        DoScriptText(textId, m_pInstance->GetCreature(npcId));
                        CreatureList ChampionList;
                        for(uint8 i = 0; i < CHAMPION_COUNT; ++i)
                            GetCreatureListWithEntryInGrid(ChampionList, m_creature, FChampIDs[i][faction], DEFAULT_VISIBILITY_INSTANCE);

                        stepTimer->SetValue(TIMER_VALUE_CUSTOM, 0);

                        for(CreatureList::iterator itr = ChampionList.begin(); itr != ChampionList.end(); ++itr)
                        {
                            Creature* champ = *itr;
                            if (!champ)
                                continue;

                            champ->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                            ((ScriptedAI*)champ->AI())->EnableAttack(true);
                        }

                        cooldown = REALLY_BIG_COOLDOWN;
                        break;
                    }
                    case 51: // outro
                        DoScriptText(SAY_STAGE_2_06, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 5000;
                        break;
                    case 52:
                    {
                        uint32 chestId = 0;
                        m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_CHAMPIONS);
                        if (getMSTimeDiff(stepTimer->GetCustomValue(), getMSTime() < 73000)) // kill under 60 seconds
                            m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_CHAMPIONS_MINUTE);

                        switch(m_dDifficulty)
                        {
                            case RAID_DIFFICULTY_10MAN_NORMAL: chestId = GO_CRUSADERS_CACHE_10; break;
                            case RAID_DIFFICULTY_25MAN_NORMAL: chestId = GO_CRUSADERS_CACHE_25; break;
                            case RAID_DIFFICULTY_10MAN_HEROIC: chestId = GO_CRUSADERS_CACHE_10_H; break;
                            case RAID_DIFFICULTY_25MAN_HEROIC: chestId = GO_CRUSADERS_CACHE_25_H; break;
                            default: break;
                        }
                        if (chestId)
                            m_creature->SummonGameobject(chestId, SpawnLoc[LOC_CENTER], M_PI_F*1.5f, 604800);
                        break;
                    }
                }
                break;
            }
            case TYPE_VALKIRIES:
            {
                switch(encounterStage)
                {
                    case 1:
                        DoScriptText(SAY_STAGE_3_01, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 12000;
                        break;
                    case 2:
                        SummonToCBoss(NPC_LIGHTBANE, NPC_DARKBANE);
                        for(uint8 i = 0; i < 4; ++i)
                            DoSpawnTocBoss(i/2 ? NPC_LIGHT_ESSENCE : NPC_DARK_ESSENCE, SpawnLoc[LOC_D_ESSENCE_1+i], 0);

                        cooldown = 2000;
                        break;
                    case 3:
                    {
                        if (!encounterCreature || !encounterCreature2)
                            break;

                        DoScriptText(SAY_STAGE_3_02, m_pInstance->GetCreature(NPC_TIRION));

                        uint32 travelTime[2];
                        for(uint8 second = 0; second < 2; ++second)
                        {
                            Creature* crt = second ? encounterCreature2 : encounterCreature;
                            ((ScriptedAI*)crt->AI())->EnableAttack(false);

                            PointPath path;
                            path.resize(3);
                            path.set(0, crt->GetPosition());
                            path.set(1, second ? SpawnLoc[LOC_D_VALKYR_1] : SpawnLoc[LOC_L_VALKYR_1]);
                            path.set(2, second ? SpawnLoc[LOC_D_VALKYR_2] : SpawnLoc[LOC_L_VALKYR_2]);
                            //path.set(3, second ? SpawnLoc[LOC_D_VALKYR_3] : SpawnLoc[LOC_L_VALKYR_3]);

                            travelTime[second] = path.GetTotalLength()/(crt->GetSpeed(MOVE_RUN)*0.001f);

                            crt->GetMotionMaster()->Clear(false, true);
                            crt->ChargeMonsterMove(path, SPLINETYPE_FACINGANGLE, crt->GetSplineFlags(), travelTime[second], M_PI_F*1.5f);
                        }
                        cooldown = (travelTime[0] > travelTime[1] ? travelTime[0] : travelTime[1]) + 5000;
                        break;
                    }
                    case 4:
                    {
                        for(uint8 second = 0; second < 2; ++second)
                        {
                            Creature* crt = second ? encounterCreature2 : encounterCreature;
                            ((ScriptedAI*)crt->AI())->EnableAttack(true);
                            crt->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                        }
                        cooldown = REALLY_BIG_COOLDOWN;
                        break;
                    }
                    case 51: // outro
                        if (m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI)
                            DoScriptText(SAY_STAGE_3_03a, m_pInstance->GetCreature(NPC_WRYNN));
                        else
                            DoScriptText(SAY_STAGE_3_03h, m_pInstance->GetCreature(NPC_GARROSH));
                        cooldown = 5000;
                        break;
                    case 52:
                        break;
                }
                break;
            }
            case TYPE_LICH_KING:
            {
                switch(encounterStage)
                {
                    case 1:
                        DoScriptText(SAY_STAGE_4_01, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 19000;
                        break;
                    case 2:
                        encounterCreature = DoSpawnTocBoss(NPC_LICH_KING, SpawnLoc[LOC_BACKDOOR], M_PI_F*1.5f);
                        encounterCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.1f);
                        encounterCreature->SetVisibility(VISIBILITY_OFF);
                        m_pInstance->SetData(TYPE_LICH_KING, IN_PROGRESS);
                        cooldown = 500;
                        break;
                    case 3:
                        DoScriptText(SAY_STAGE_4_02, encounterCreature);
                        cooldown = 7000;
                        break;
                    case 4:
                        if (!(encounterCreature2 = DoSpawnTocBoss(NPC_TRIGGER, SpawnLoc[LOC_LICH_KING_S], M_PI_F*1.5f, false)))
                            break;

                        encounterCreature2->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.8f);
                        encounterCreature2->CastSpell(encounterCreature2, SPELL_LK_GATE, false);
                        cooldown = 4000;
                        break;
                    case 5:
                        encounterCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.f);
                        m_pInstance->instance->CreatureRelocation(encounterCreature, SpawnLoc[LOC_LICH_KING_S], M_PI_F*1.5f);
                        cooldown = 500;
                        break;
                    case 6:
                    {
                        PointPath path;
                        path.resize(2);
                        path.set(0, SpawnLoc[LOC_LICH_KING_S]);
                        path.set(1, SpawnLoc[LOC_LICH_KING_E]);

                        encounterCreature->GetMotionMaster()->Clear(false, true);
                        encounterCreature->GetMotionMaster()->MoveIdle();
                        encounterCreature->ChargeMonsterMove(path, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, path.GetTotalLength()/0.0025f);
                        cooldown = 3000;
                        break;
                    }
                    case 7:
                        DoScriptText(SAY_STAGE_4_03, m_pInstance->GetCreature(NPC_TIRION));
                        cooldown = 8000;
                        break;
                    case 8:
                        DoScriptText(SAY_STAGE_4_04, encounterCreature);
                        encounterCreature->HandleEmote(EMOTE_ONESHOT_LAUGH);
                        cooldown = 13000;
                        break;
                    case 9:
                        encounterCreature->HandleEmote(EMOTE_ONESHOT_EXCLAMATION);
                        cooldown = 3000;
                        break;
                    case 10:
                        encounterCreature->HandleEmote(EMOTE_ONESHOT_KNEEL);
                        cooldown = 1000;
                        break;
                    case 11:
                        encounterCreature->CastSpell(encounterCreature, SPELL_LK_NOVA, false);
                        cooldown = 500;
                        break;
                    case 12:
                    {
                        encounterCreature->SetVisibility(VISIBILITY_OFF);
                        m_pInstance->instance->CreatureRelocation(encounterCreature, SpawnLoc[LOC_BACKDOOR], M_PI_F*1.5f);
                        encounterCreature->SendMonsterMove(SpawnLoc[LOC_BACKDOOR].x, SpawnLoc[LOC_BACKDOOR].y, SpawnLoc[LOC_BACKDOOR].z, SPLINETYPE_NORMAL, encounterCreature->GetSplineFlags(), 1);

                        Map::PlayerList const &PlayerList = m_pInstance->instance->GetPlayers();
                        if (!PlayerList.isEmpty())
                            for (Map::PlayerList::const_iterator iter = PlayerList.begin(); iter != PlayerList.end(); ++iter)
                                if (Player* plr = iter->getSource())
                                    plr->KnockBackFrom(plr, 2, 25);

                        if (GameObject* pFloor = m_pInstance->GetGameObject(GO_ARGENT_COLISEUM_FLOOR))
                        {
                            pFloor->TakenDamage(100, m_creature);
                            pFloor->TakenDamage(100, m_creature);
                        }
                        cooldown = 2000;
                        break;
                    }
                    case 13:
                        DoScriptText(SAY_STAGE_4_05, encounterCreature);
                        cooldown = 10000;
                        break;
                    case 14:
                    {
                        m_pInstance->SetData(TYPE_LICH_KING, DONE);
                        encounterCreature->ForcedDespawn();
                        if (GameObject* pFloor = m_pInstance->GetGameObject(GO_ARGENT_COLISEUM_FLOOR))
                            pFloor->Rebuild(m_creature);
                        break;
                    }
                }
                break;
            }
            case TYPE_ANUBARAK:
            {
                switch(encounterStage)
                {
                    case 51:
                        if (!(encounterCreature = DoSpawnTocBoss(NPC_OUTRO_TIRION, SpawnLoc[LOC_O_TIRION_S], 0)))
                            break;
                        if (!(encounterCreature2 = DoSpawnTocBoss(NPC_OUTRO_ARGENT_MAGE, SpawnLoc[LOC_O_MAGE_S], 0)))
                            break;

                        encounterCreature->GetMotionMaster()->MovePoint(0, SpawnLoc[LOC_O_TIRION_E], false);
                        encounterCreature2->GetMotionMaster()->MovePoint(0, SpawnLoc[LOC_O_MAGE_E], false);
                        cooldown = 10000;
                        break;
                    case 52:
                        DoScriptText(SAY_STAGE_4_06, encounterCreature);
                        cooldown = 15000;
                        break;
                    case 53:
                        if (!isHeroic || m_pInstance->GetData(TYPE_COUNTER) >= 50)
                            break;

                        DoScriptText(SAY_STAGE_4_07, encounterCreature);
                        cooldown = 5000;
                        break;
                    case 54:
                    {
                        uint32 chestId = 0;
                        uint32 attempts = m_pInstance->GetData(TYPE_COUNTER);
                        if (isInRange(1, attempts, 24))
                            chestId = is10Man ? GO_TRIBUTE_CHEST_10H_1 : GO_TRIBUTE_CHEST_25H_1;
                        else if (isInRange(25, attempts, 44))
                            chestId = is10Man ? GO_TRIBUTE_CHEST_10H_25 : GO_TRIBUTE_CHEST_25H_25;
                        else if (isInRange(45, attempts, 49))
                            chestId = is10Man ? GO_TRIBUTE_CHEST_10H_45 : GO_TRIBUTE_CHEST_25H_45;
                        else if (attempts == 50)
                            chestId = is10Man ? GO_TRIBUTE_CHEST_10H_50 : GO_TRIBUTE_CHEST_25H_50;
                        if (chestId)
                            m_creature->SummonGameobject(chestId, SpawnLoc[LOC_UNDERGROUND], 0, 604800);

                        break;
                    }
                }
                break;
            }
            default:
                break;
        }

        cat_log("toc_announcer: Phase updating: Handling current encounter %u in encounter stage %u and setting cooldown to %u", currentEncounter, encounterStage, cooldown);

        if (cooldown)
            stepTimer->Cooldown(cooldown);
        else
            Reset();
    }

    // open and closes doors
    if (SpellTimer* doorTimer = m_TimerMgr->GetState(TIMER_DOOR_HANDLER))
    {
        uint64 doorGuid = m_pInstance->GetData64(GO_MAIN_GATE_DOOR);
        if (!doorTimer->GetCustomValue())
        {
            m_pInstance->OpenDoor(doorGuid);
            doorTimer->SetValue(TIMER_VALUE_CUSTOM, true);
        }
        else
        {
            m_pInstance->CloseDoor(doorGuid);
            doorTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true);
        }
    }

    // runaway of announcer
    if (SpellTimer* runawayTimer = m_TimerMgr->GetState(TIMER_RUNAWAY))
    {
        if (GameObject* go = m_pInstance->GetGameObject(GO_GATE_EAST))
        {
            Coords coord = go->GetPosition();
            m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
            m_creature->SetSpeedRate(MOVE_RUN, 1.2f, true);
            m_creature->GetMotionMaster()->MovePoint(POINT_MOVE, coord.x, coord.y, coord.z, false);
        }
        runawayTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true);
    }

    // handling of custom timer in the event
    if (SpellTimer* customTimer = m_TimerMgr->GetState(TIMER_CUSTOM))
    {
        if (currentEncounter == TYPE_CRUSADERS)
        {
            uint32 timerCustom = customTimer->GetCustomValue();
            uint32 spawnMask = m_pInstance->GetData(TYPE_CHAMPION_SPAWN_MASK);
            uint8 faction = m_pInstance->GetInstanceSide() == INSTANCE_SIDE_ALI ? FACTION_HORDE : FACTION_ALLIANCE;

            const Coords Spawn1 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_SPAWN_1] : SpawnLoc[LOC_FCH_H_SPAWN_1];
            const Coords Spawn2 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_SPAWN_2] : SpawnLoc[LOC_FCH_H_SPAWN_2];
            const Coords Jump1 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_JUMP_1] : SpawnLoc[LOC_FCH_H_JUMP_1];
            const Coords Jump2 = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_JUMP_2] : SpawnLoc[LOC_FCH_H_JUMP_2];
            Coords Location = faction == FACTION_ALLIANCE ? SpawnLoc[LOC_FCH_A_MOVE] : SpawnLoc[LOC_FCH_H_MOVE];

            if (encounterCreature2)
            {
                int32 champOrder = customValue-2;
                int32 x_coef = champOrder%2 ? 1 : -1;
                int32 y_coef = champOrder/2 - (is10Man ? 1 : 2);
                if (faction == FACTION_HORDE)
                {
                    x_coef *= -1;
                    y_coef *= -1;
                }
                Location.x += x_coef*2.5f;
                Location.y += y_coef*5.f;

                PointPath path;
                path.resize(2);
                //path.set(0, champOrder%2 ? Jump2 : Jump1);
                path.set(0, encounterCreature2->GetPosition());
                path.set(1, Location);

                uint32 travelTime = path.GetTotalLength()/0.0025f;
                encounterCreature2->GetMotionMaster()->Clear(false, true);
                encounterCreature2->ChargeMonsterMove(path, SPLINETYPE_FACINGANGLE, SPLINEFLAG_WALKMODE,
                travelTime, faction == FACTION_ALLIANCE ? M_PI_F : 0);
                encounterCreature2 = NULL;

                // if is last one set phase handler to travelTime
                if (timerCustom == CHAMPION_COUNT && !encounterCreature)
                {
                    customTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true);
                    m_TimerMgr->Cooldown(TIMER_PHASE_HANDLING, travelTime);
                    return;
                }
            }
            if (encounterCreature)
            {
                uint32 champOrder = customValue-1;
                const Coords& jump = champOrder%2 ? Jump2 : Jump1;
                encounterCreature->GetMotionMaster()->Clear(false, true);
                encounterCreature->GetMotionMaster()->MoveIdle();
                encounterCreature->TrajMonsterMove(jump.x, jump.y, jump.z, false, 80, 1000);
                encounterCreature2 = encounterCreature;
                encounterCreature = NULL;
            }
            for(uint8 i = timerCustom; i < CHAMPION_COUNT; ++i)
            {
                customTimer->SetValue(TIMER_VALUE_CUSTOM, i+1);
                if (spawnMask & (1 << i))
                {
                    const Coords& spawn = customValue%2 ? Spawn2 : Spawn1;
                    encounterCreature = DoSpawnTocBoss(FChampIDs[i][faction], spawn, 0);
                    ((ScriptedAI*)encounterCreature->AI())->EnableAttack(false);
                    break;
                }
            }
            ++customValue;
        }
        else
            customTimer->SetValue(TIMER_VALUE_DELETE_AT_FINISH, true);
    }
}
Beispiel #21
0
bool EffectDummyCreature_spell_anchor(Unit* /*pCaster*/, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget, ObjectGuid /*originalCasterGuid*/)
{
    if (uiEffIndex != EFFECT_INDEX_0 || pCreatureTarget->GetEntry() != NPC_SUB_BOSS_TRIGGER)
        return true;

    instance_naxxramas* pInstance = (instance_naxxramas*)pCreatureTarget->GetInstanceData();

    if (!pInstance)
        return true;

    switch (uiSpellId)
    {
        case SPELL_A_TO_ANCHOR_1:                           // trigger mobs at high right side
        case SPELL_B_TO_ANCHOR_1:
        case SPELL_C_TO_ANCHOR_1:
        {
            if (Creature* pAnchor2 = pInstance->GetClosestAnchorForGoth(pCreatureTarget, false))
            {
                uint32 uiTriggered = SPELL_A_TO_ANCHOR_2;

                if (uiSpellId == SPELL_B_TO_ANCHOR_1)
                    uiTriggered = SPELL_B_TO_ANCHOR_2;
                else if (uiSpellId == SPELL_C_TO_ANCHOR_1)
                    uiTriggered = SPELL_C_TO_ANCHOR_2;

                pCreatureTarget->CastSpell(pAnchor2, uiTriggered, TRIGGERED_OLD_TRIGGERED);
            }

            return true;
        }
        case SPELL_A_TO_ANCHOR_2:                           // trigger mobs at high left side
        case SPELL_B_TO_ANCHOR_2:
        case SPELL_C_TO_ANCHOR_2:
        {
            CreatureList lTargets;
            pInstance->GetGothSummonPointCreatures(lTargets, false);

            if (!lTargets.empty())
            {
                CreatureList::iterator itr = lTargets.begin();
                uint32 uiPosition = urand(0, lTargets.size() - 1);
                advance(itr, uiPosition);

                if (Creature* pTarget = (*itr))
                {
                    uint32 uiTriggered = SPELL_A_TO_SKULL;

                    if (uiSpellId == SPELL_B_TO_ANCHOR_2)
                        uiTriggered = SPELL_B_TO_SKULL;
                    else if (uiSpellId == SPELL_C_TO_ANCHOR_2)
                        uiTriggered = SPELL_C_TO_SKULL;

                    pCreatureTarget->CastSpell(pTarget, uiTriggered, TRIGGERED_OLD_TRIGGERED);
                }
            }
            return true;
        }
        case SPELL_A_TO_SKULL:                              // final destination trigger mob
        case SPELL_B_TO_SKULL:
        case SPELL_C_TO_SKULL:
        {
            if (Creature* pGoth = pInstance->GetSingleCreatureFromStorage(NPC_GOTHIK))
            {
                uint32 uiNpcEntry = NPC_SPECT_TRAINEE;

                if (uiSpellId == SPELL_B_TO_SKULL)
                    uiNpcEntry = NPC_SPECT_DEATH_KNIGHT;
                else if (uiSpellId == SPELL_C_TO_SKULL)
                    uiNpcEntry = NPC_SPECT_RIDER;

                pGoth->SummonCreature(uiNpcEntry, pCreatureTarget->GetPositionX(), pCreatureTarget->GetPositionY(), pCreatureTarget->GetPositionZ(), pCreatureTarget->GetOrientation(), TEMPSPAWN_DEAD_DESPAWN, 0);

                if (uiNpcEntry == NPC_SPECT_RIDER)
                    pGoth->SummonCreature(NPC_SPECT_HORSE, pCreatureTarget->GetPositionX(), pCreatureTarget->GetPositionY(), pCreatureTarget->GetPositionZ(), pCreatureTarget->GetOrientation(), TEMPSPAWN_DEAD_DESPAWN, 0);
            }
            return true;
        }
    }

    return true;
};