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; }
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; }
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(); }
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); }
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); } } } } }
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; }
void MoveInLineOfSight(Unit* pWho) override { if (HasEscortState(STATE_ESCORT_ESCORTING) && pWho->GetEntry() == NPC_REETHE && lCreatureList.empty()) lCreatureList.push_back((Creature*)pWho); npc_escortAI::MoveInLineOfSight(pWho); }
CreatureList<PrivateKey> StorageReal::getPrivateKeyList(Monitor& monitor) { if (!check_interface(monitor)) return CreatureList<PrivateKey>(); CreatureList<PrivateKey> res = creator.createCreatureList<PrivateKey>(); Iterator i; SIMPLE_CALL( (i=iface->iterator(session,error)) ); for (; i.inrange(); ++i) { eprovider::Error error; TheKey thekey = iface->item(session,i,error); if (thekey.category() == kcPrivateKey) { PrivateKey toadd = creator.createPrivateKey(thekey,NotCritical(monitor)); if (toadd) res.push_back( toadd ); } } return res; }
void JustSummoned(Creature* pSummoned) override { lCreatureList.push_back(pSummoned); pSummoned->setFaction(FACTION_GENERIC_FRIENDLY); if (pSummoned->GetEntry() == NPC_CALDWELL) pSummoned->GetMotionMaster()->MovePoint(0, m_afMoveTo[0], m_afMoveTo[1], m_afMoveTo[2]); else { if (Creature* pCaldwell = GetCreature(NPC_CALDWELL)) { // will this conversion work without compile warning/error? size_t iSize = lCreatureList.size(); pSummoned->GetMotionMaster()->MoveFollow(pCaldwell, 0.5f, (M_PI / 2) * (int)iSize); } } }
Creature* instance_uldaman::GetClosestDwarfNotInCombat(Creature* pSearcher) { CreatureList lTemp; for (GuidList::const_iterator itr = m_lWardens.begin(); itr != m_lWardens.end(); ++itr) { Creature* pTemp = instance->GetCreature(*itr); if (pTemp && pTemp->isAlive() && !pTemp->getVictim()) lTemp.push_back(pTemp); } if (lTemp.empty()) return nullptr; lTemp.sort(ObjectDistanceOrder(pSearcher)); return lTemp.front(); }
void PrepareSummonPlaces() { CreatureList lSummonList; m_pInstance->GetGothSummonPointCreatures(lSummonList, true); if (lSummonList.empty()) return; // Trainees and Rider uint8 index = 0; uint8 uiTraineeCount = 3; lSummonList.sort(ObjectDistanceOrder(m_creature)); for (auto& itr : lSummonList) { if (itr) { if (uiTraineeCount == 0) break; if (index == 1) m_lRiderSummonPosGuids.push_back(itr->GetObjectGuid()); else { m_lTraineeSummonPosGuids.push_back(itr->GetObjectGuid()); --uiTraineeCount; } index++; } } // DeathKnights uint8 uiDeathKnightCount = 2; lSummonList.sort(ObjectDistanceOrderReversed(m_creature)); for (auto& itr : lSummonList) { if (itr) { if (uiDeathKnightCount == 0) break; m_lDeathKnightSummonPosGuids.push_back(itr->GetObjectGuid()); --uiDeathKnightCount; } } }
// 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); }
Creature* GetCreature(uint32 uiCreatureEntry) { if (!lCreatureList.empty()) { for (auto& itr : lCreatureList) { if (itr->GetEntry() == uiCreatureEntry && itr->isAlive()) return itr; } } return nullptr; }
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; } } } }
void Reset() override { m_uiGlobalTimer = 5000; if (HasEscortState(STATE_ESCORT_PAUSED) && m_uiPhase == PHASE_FIGHT) m_uiPhase = PHASE_COMPLETE; if (!HasEscortState(STATE_ESCORT_ESCORTING)) { lCreatureList.clear(); m_uiPhase = 0; m_uiPhaseCounter = 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; }
void DoStartAttackMe() { if (!lCreatureList.empty()) { for (auto& itr : lCreatureList) { if (itr->GetEntry() == NPC_REETHE) continue; if (itr->isAlive()) { itr->setFaction(FACTION_THER_HOSTILE); itr->AI()->AttackStart(m_creature); } } } }
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 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); } }
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; };
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(); }
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; switch (m_uiPhase) { case PHASE_FAKE_DEATH: if (m_uiResurrectTimer < uiDiff) { if (!m_pInstance) return; if (m_pInstance->GetData(TYPE_THEKAL) != SPECIAL || m_pInstance->GetData(TYPE_ZATH) != SPECIAL) { DoCastSpellIfCan(m_creature, SPELL_RESURRECT); m_pInstance->SetData(TYPE_LORKHAN, IN_PROGRESS); } m_uiPhase = PHASE_WAITING; } else m_uiResurrectTimer -= uiDiff; // no break needed here case PHASE_WAITING: return; case PHASE_NORMAL: if (m_uiDispelTimer < uiDiff) { CreatureList pList = DoFindFriendlyCC(30.0f); Creature* dispelTarget = nullptr; if (!pList.empty()) for (auto& itr : pList) { dispelTarget = itr; break; } if (!dispelTarget && (m_creature->isInRoots() || m_creature->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED))) dispelTarget = m_creature; if (dispelTarget && (DoCastSpellIfCan(dispelTarget, SPELL_DISPEL_MAGIC) == CAST_OK)) m_uiDispelTimer = urand(15000, 20000); } else m_uiDispelTimer -= uiDiff; // Lightning_Shield_Timer if (m_uiLightningShieldTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_LIGHTNING_SHIELD) == CAST_OK) m_uiLightningShieldTimer = 61000; } else m_uiLightningShieldTimer -= uiDiff; // Casting Greatheal to Thekal or Zath if they are in meele range. // TODO - why this range check? if (m_uiGreatHealTimer < uiDiff) { if (m_pInstance) { Creature* pThekal = m_pInstance->GetSingleCreatureFromStorage(NPC_THEKAL); Creature* pZath = m_pInstance->GetSingleCreatureFromStorage(NPC_ZATH); switch (urand(0, 1)) { case 0: if (pThekal && m_creature->IsWithinDistInMap(pThekal, 3 * ATTACK_DISTANCE)) DoCastSpellIfCan(pThekal, SPELL_GREAT_HEAL); break; case 1: if (pZath && m_creature->IsWithinDistInMap(pZath, 3 * ATTACK_DISTANCE)) DoCastSpellIfCan(pZath, SPELL_GREAT_HEAL); break; } } m_uiGreatHealTimer = urand(15000, 20000); } else m_uiGreatHealTimer -= uiDiff; // Disarm_Timer if (m_uiDisarmTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_DISARM) == CAST_OK) m_uiDisarmTimer = urand(15000, 25000); } else m_uiDisarmTimer -= uiDiff; break; } 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; }
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 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); } }
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()); }