void instance_zulaman::DoTimeRunSay(RunEventSteps uiData) { switch (uiData) { case RUN_START: DoOrSimulateScriptTextForThisInstance(SAY_INST_BEGIN, NPC_MALACRASS); break; case RUN_FAIL: DoOrSimulateScriptTextForThisInstance(urand(0, 1) ? SAY_INST_SACRIF1 : SAY_INST_SACRIF2, NPC_MALACRASS); break; case RUN_DONE: DoOrSimulateScriptTextForThisInstance(SAY_INST_COMPLETE, NPC_MALACRASS); break; case RUN_PROGRESS: // This function is on progress called before the data is set to the array switch (GetKilledPreBosses() + 1) { case 1: DoOrSimulateScriptTextForThisInstance(SAY_INST_PROGRESS_1, NPC_MALACRASS); break; case 2: DoOrSimulateScriptTextForThisInstance(SAY_INST_PROGRESS_2, NPC_MALACRASS); break; case 3: DoOrSimulateScriptTextForThisInstance(SAY_INST_PROGRESS_3, NPC_MALACRASS); break; } break; case RUN_FAIL_SOON: switch (GetKilledPreBosses()) { case 0: DoOrSimulateScriptTextForThisInstance(SAY_INST_WARN_1, NPC_MALACRASS); break; case 1: DoOrSimulateScriptTextForThisInstance(SAY_INST_WARN_2, NPC_MALACRASS); break; case 2: DoOrSimulateScriptTextForThisInstance(SAY_INST_WARN_3, NPC_MALACRASS); break; case 3: DoOrSimulateScriptTextForThisInstance(SAY_INST_WARN_4, NPC_MALACRASS); break; } break; } }
void instance_naxxramas::DoTaunt() { if (m_auiEncounter[TYPE_KELTHUZAD] != DONE) { uint8 uiWingsCleared = 0; if (m_auiEncounter[TYPE_MAEXXNA] == DONE) ++uiWingsCleared; if (m_auiEncounter[TYPE_LOATHEB] == DONE) ++uiWingsCleared; if (m_auiEncounter[TYPE_FOUR_HORSEMEN] == DONE) ++uiWingsCleared; if (m_auiEncounter[TYPE_THADDIUS] == DONE) ++uiWingsCleared; switch(uiWingsCleared) { case 1: DoOrSimulateScriptTextForThisInstance(SAY_KELTHUZAD_TAUNT1, NPC_KELTHUZAD); break; case 2: DoOrSimulateScriptTextForThisInstance(SAY_KELTHUZAD_TAUNT2, NPC_KELTHUZAD); break; case 3: DoOrSimulateScriptTextForThisInstance(SAY_KELTHUZAD_TAUNT3, NPC_KELTHUZAD); break; case 4: DoOrSimulateScriptTextForThisInstance(SAY_KELTHUZAD_TAUNT4, NPC_KELTHUZAD); break; } } }
void instance_sunwell_plateau::Update(uint32 uiDiff) { DialogueUpdate(uiDiff); if (m_uiKalecRespawnTimer) { if (m_uiKalecRespawnTimer <= uiDiff) { if (Creature* pKalecDragon = GetSingleCreatureFromStorage(NPC_KALECGOS_DRAGON)) pKalecDragon->Respawn(); if (Creature* pKalecHuman = GetSingleCreatureFromStorage(NPC_KALECGOS_HUMAN)) pKalecHuman->Respawn(); m_uiKalecRespawnTimer = 0; } else m_uiKalecRespawnTimer -= uiDiff; } // Muru berserk timer; needs to be done here because it involves two distinct creatures if (m_auiEncounter[TYPE_MURU] == IN_PROGRESS) { if (m_uiMuruBerserkTimer < uiDiff) { if (Creature* pEntrpius = GetSingleCreatureFromStorage(NPC_ENTROPIUS, true)) pEntrpius->CastSpell(pEntrpius, SPELL_MURU_BERSERK, true); else if (Creature* pMuru = GetSingleCreatureFromStorage(NPC_MURU)) pMuru->CastSpell(pMuru, SPELL_MURU_BERSERK, true); m_uiMuruBerserkTimer = 10 * MINUTE * IN_MILLISECONDS; } else m_uiMuruBerserkTimer -= uiDiff; } if (m_auiEncounter[TYPE_KILJAEDEN] == NOT_STARTED || m_auiEncounter[TYPE_KILJAEDEN] == FAIL) { if (m_uiKiljaedenYellTimer < uiDiff) { switch (urand(0, 4)) { case 0: DoOrSimulateScriptTextForThisInstance(SAY_ORDER_1, NPC_KILJAEDEN_CONTROLLER); break; case 1: DoOrSimulateScriptTextForThisInstance(SAY_ORDER_2, NPC_KILJAEDEN_CONTROLLER); break; case 2: DoOrSimulateScriptTextForThisInstance(SAY_ORDER_3, NPC_KILJAEDEN_CONTROLLER); break; case 3: DoOrSimulateScriptTextForThisInstance(SAY_ORDER_4, NPC_KILJAEDEN_CONTROLLER); break; case 4: DoOrSimulateScriptTextForThisInstance(SAY_ORDER_5, NPC_KILJAEDEN_CONTROLLER); break; } m_uiKiljaedenYellTimer = 90000; } else m_uiKiljaedenYellTimer -= uiDiff; } }
void instance_zulgurub::DoYellAtTriggerIfCan(uint32 uiTriggerId) { if (uiTriggerId == AREATRIGGER_ENTER && !m_bHasIntroYelled) { DoOrSimulateScriptTextForThisInstance(SAY_HAKKAR_PROTECT, NPC_HAKKAR); m_bHasIntroYelled = true; } else if (uiTriggerId == AREATRIGGER_ALTAR && !m_bHasAltarYelled) { DoOrSimulateScriptTextForThisInstance(SAY_MINION_DESTROY, NPC_HAKKAR); m_bHasAltarYelled = true; } }
void instance_stratholme::ThazudinAcolyteJustDied(Creature* pCreature) { for (uint8 i = 0; i < MAX_ZIGGURATS; ++i) { if (m_zigguratStorage[i].m_lZigguratAcolyteGuid.empty()) continue; // nothing to do anymore for this ziggurat m_zigguratStorage[i].m_lZigguratAcolyteGuid.remove(pCreature->GetObjectGuid()); if (m_zigguratStorage[i].m_lZigguratAcolyteGuid.empty()) { // A random zone yell after one is cleared int32 aAnnounceSay[MAX_ZIGGURATS] = {SAY_ANNOUNCE_ZIGGURAT_1, SAY_ANNOUNCE_ZIGGURAT_2, SAY_ANNOUNCE_ZIGGURAT_3}; DoOrSimulateScriptTextForThisInstance(aAnnounceSay[i], NPC_THUZADIN_ACOLYTE); // Kill Crystal if (Creature* pCrystal = instance->GetCreature(m_zigguratStorage[i].m_crystalGuid)) pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); switch (i) { case 0: SetData(TYPE_BARONESS, SPECIAL); break; case 1: SetData(TYPE_NERUB, SPECIAL); break; case 2: SetData(TYPE_PALLID, SPECIAL); break; } } } }
void instance_ulduar::JustDidDialogueStep(int32 iEntry) { switch (iEntry) { case SAY_PRE_LEVIATHAN_1: case SAY_PRE_LEVIATHAN_2: case SAY_PRE_LEVIATHAN_3: DoOrSimulateScriptTextForThisInstance(iEntry, NPC_BRONZEBEARD_RADIO); break; case NPC_LEVIATHAN: // move the leviathan in the arena if (Creature* pLeviathan = GetSingleCreatureFromStorage(NPC_LEVIATHAN)) { // the boss has increased speed for this move; handled as custom float fSpeedRate = pLeviathan->GetSpeedRate(MOVE_RUN); pLeviathan->SetWalk(false); pLeviathan->SetSpeedRate(MOVE_RUN, 5); pLeviathan->GetMotionMaster()->MovePoint(1, afLeviathanMovePos[0], afLeviathanMovePos[1], afLeviathanMovePos[2]); pLeviathan->SetSpeedRate(MOVE_RUN, fSpeedRate); // modify respawn / home position to the center of arena pLeviathan->SetRespawnCoord(afLeviathanMovePos[0], afLeviathanMovePos[1], afLeviathanMovePos[2], afLeviathanMovePos[3]); } // Note: starting 4.x this gate is a GO 33 and it's destroyed at this point DoUseDoorOrButton(GO_LEVIATHAN_GATE); break; } }
// Function that spawns next scourge wave void instance_culling_of_stratholme::DoSpawnNextScourgeWave() { Creature* pSummoner = GetSingleCreatureFromStorage(NPC_ARTHAS); if (!pSummoner) return; DoOrSimulateScriptTextForThisInstance(m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_iYellId, NPC_LORDAERON_CRIER); for (uint8 i = 0; i < MAX_SCOURGE_TYPE_PER_WAVE; ++i) { // get the mob entry uint32 uiEntry = GetRandomMobOfType(uiScourgeWaveDef[m_uiScourgeWaveCount - 1][i]); if (!uiEntry) continue; float fX, fY, fZ, fO; fO = m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fO; // bosses get exact location if (uiScourgeWaveDef[m_uiScourgeWaveCount - 1][i] == SCOURGE_TYPE_BOSS || uiScourgeWaveDef[m_uiScourgeWaveCount - 1][i] == SCOURGE_TYPE_ACOLYTES) { fX = m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fX; fY = m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fY; fZ = m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fZ; } // random position around point else pSummoner->GetRandomPoint(m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fX, m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fY, m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fZ, 5.0f, fX, fY, fZ); // special requirement for acolytes - spawn a pack of 4 if (uiScourgeWaveDef[m_uiScourgeWaveCount - 1][i] == SCOURGE_TYPE_ACOLYTES) { for (uint8 j = 0; j < 4; ++j) { pSummoner->GetRandomPoint(m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fX, m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fY, m_aScourgeWavesLocs[m_uiCurrentUndeadPos].m_fZ, 5.0f, fX, fY, fZ); pSummoner->SummonCreature(uiEntry, fX, fY, fZ, fO, TEMPSUMMON_DEAD_DESPAWN, 0); } } // spawn the selected mob else pSummoner->SummonCreature(uiEntry, fX, fY, fZ, fO, TEMPSUMMON_DEAD_DESPAWN, 0); } // start infinite curruptor event on the first wave if (m_uiScourgeWaveCount == 1 && !instance->IsRegularDifficulty() && GetData(TYPE_INFINITE_CORRUPTER) != DONE) SetData(TYPE_INFINITE_CORRUPTER, IN_PROGRESS); // get a random position that is different from the previous one for the next round uint8 uiCurrentPos = urand(POS_FESTIVAL_LANE, POS_ELDERS_SQUARE); while (uiCurrentPos == m_uiCurrentUndeadPos) uiCurrentPos = urand(POS_FESTIVAL_LANE, POS_ELDERS_SQUARE); m_uiCurrentUndeadPos = uiCurrentPos; }
void instance_ruins_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) { switch (uiType) { case TYPE_KURINNAXX: if (uiData == DONE) { DoSapwnAndorovIfCan(); // Yell after kurinnaxx DoOrSimulateScriptTextForThisInstance(SAY_OSSIRIAN_INTRO, NPC_OSSIRIAN); } m_auiEncounter[uiType] = uiData; break; case TYPE_RAJAXX: m_auiEncounter[uiType] = uiData; if (uiData == IN_PROGRESS) { DoSortArmyWaves(); } if (uiData == DONE) { if (Creature* pAndorov = GetSingleCreatureFromStorage(NPC_GENERAL_ANDOROV)) { if (pAndorov->IsAlive()) { pAndorov->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } } } break; case TYPE_MOAM: case TYPE_BURU: case TYPE_AYAMISS: case TYPE_OSSIRIAN: m_auiEncounter[uiType] = uiData; break; } if (uiData == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5]; m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
bool instance_stratholme::StartSlaugtherSquare() { if (m_auiEncounter[TYPE_BARONESS] == SPECIAL && m_auiEncounter[TYPE_NERUB] == SPECIAL && m_auiEncounter[TYPE_PALLID] == SPECIAL) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RIVENDARE, NPC_BARON); DoUseDoorOrButton(GO_PORT_GAUNTLET); DoUseDoorOrButton(GO_PORT_SLAUGTHER); debug_log("SD2: Instance Stratholme: Open slaugther square."); return true; } return false; }
void instance_magtheridons_lair::Update(uint32 uiDiff) { // Prepare to release Magtheridon if (m_uiCageBreakTimer) { if (m_uiCageBreakTimer <= uiDiff) { switch (m_uiCageBreakStage) { case 0: if (Creature* pMagtheridon = GetSingleCreatureFromStorage(NPC_MAGTHERIDON)) { if (pMagtheridon->isAlive()) { DoScriptText(EMOTE_NEARLY_FREE, pMagtheridon); m_uiCageBreakTimer = MINUTE * IN_MILLISECONDS; } } break; case 1: SetData(TYPE_MAGTHERIDON_EVENT, IN_PROGRESS); m_uiCageBreakTimer = 0; break; } ++m_uiCageBreakStage; } else m_uiCageBreakTimer -= uiDiff; } // no yell if event is in progress or finished if (m_auiEncounter[TYPE_CHANNELER_EVENT] == IN_PROGRESS || m_auiEncounter[TYPE_MAGTHERIDON_EVENT] == DONE) return; if (m_uiRandYellTimer < uiDiff) { DoOrSimulateScriptTextForThisInstance(aRandomTaunt[urand(0, 5)], NPC_MAGTHERIDON); m_uiRandYellTimer = 90000; } else m_uiRandYellTimer -= uiDiff; }
void instance_shattered_halls::Update(uint32 uiDiff) { if (m_auiEncounter[TYPE_EXECUTION] != IN_PROGRESS) return; if (m_uiExecutionTimer < uiDiff) { switch (m_uiExecutionStage) { case 0: // Kill the officer if (Creature* pSoldier = GetSingleCreatureFromStorage(m_uiTeam == ALLIANCE ? NPC_OFFICER_ALLIANCE : NPC_OFFICER_HORDE)) pSoldier->DealDamage(pSoldier, pSoldier->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); // Make Kargath yell DoOrSimulateScriptTextForThisInstance(m_uiTeam == ALLIANCE ? SAY_KARGATH_EXECUTE_ALLY : SAY_KARGATH_EXECUTE_HORDE, NPC_KARGATH_BLADEFIST); // Set timer for the next execution DoCastGroupDebuff(SPELL_KARGATH_EXECUTIONER_2); m_uiExecutionTimer = 10 * MINUTE * IN_MILLISECONDS; break; case 1: if (Creature* pSoldier = GetSingleCreatureFromStorage(m_uiTeam == ALLIANCE ? NPC_SOLDIER_ALLIANCE_2 : NPC_SOLDIER_HORDE_2)) pSoldier->DealDamage(pSoldier, pSoldier->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); DoCastGroupDebuff(SPELL_KARGATH_EXECUTIONER_3); m_uiExecutionTimer = 15 * MINUTE * IN_MILLISECONDS; break; case 2: if (Creature* pSoldier = GetSingleCreatureFromStorage(m_uiTeam == ALLIANCE ? NPC_SOLDIER_ALLIANCE_3 : NPC_SOLDIER_HORDE_3)) pSoldier->DealDamage(pSoldier, pSoldier->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); SetData(TYPE_EXECUTION, FAIL); m_uiExecutionTimer = 0; break; } ++m_uiExecutionStage; } else m_uiExecutionTimer -= uiDiff; }
void instance_ruins_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) { switch (uiType) { case TYPE_KURINNAXX: if (uiData == DONE) { DoSapwnAndorovIfCan(); // Yell after kurinnaxx DoOrSimulateScriptTextForThisInstance(SAY_OSSIRIAN_INTRO, NPC_OSSIRIAN); } m_auiEncounter[uiType] = uiData; break; case TYPE_RAJAXX: case TYPE_MOAM: case TYPE_BURU: case TYPE_AYAMISS: case TYPE_OSSIRIAN: m_auiEncounter[uiType] = uiData; break; } if (uiData == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5]; m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void instance_naxxramas::OnCreatureDeath(Creature* pCreature) { if (pCreature->GetEntry() == NPC_MR_BIGGLESWORTH && m_auiEncounter[TYPE_KELTHUZAD] != DONE) DoOrSimulateScriptTextForThisInstance(SAY_KELTHUZAD_CAT_DIED, NPC_KELTHUZAD); }
void instance_culling_of_stratholme::Update(uint32 uiDiff) { // 25min Run - decrease time, update worldstate every ~20s // as the time is always saved by m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME], there is no need for an extra timer if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]) { if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] <= uiDiff) SetData(TYPE_INFINITE_CORRUPTER, FAIL); else { m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] -= uiDiff; if (m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] / IN_MILLISECONDS % 20 == 0) SetData(TYPE_INFINITE_CORRUPTER_TIME, m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME]); } // This part is needed for a small "hurry up guys" note, TODO, verify 20min if (m_auiEncounter[TYPE_INFINITE_CORRUPTER] == IN_PROGRESS && m_auiEncounter[TYPE_INFINITE_CORRUPTER_TIME] <= 24 * MINUTE * IN_MILLISECONDS) SetData(TYPE_INFINITE_CORRUPTER, SPECIAL); } // Small Timer, to remove Grain-Crate WorldState and Spawn Second Chromie if (m_uiRemoveCrateStateTimer) { if (m_uiRemoveCrateStateTimer <= uiDiff) { if (Player* pPlayer = GetPlayerInMap()) DoSpawnChromieIfNeeded(pPlayer); DoUpdateWorldState(WORLD_STATE_CRATES, 0); DoChromieWhisper(WHISPER_CHROMIE_CRATES); m_uiRemoveCrateStateTimer = 0; } else m_uiRemoveCrateStateTimer -= uiDiff; } // Respawn Arthas after some time if (m_uiArthasRespawnTimer) { if (m_uiArthasRespawnTimer <= uiDiff) { if (Player* pPlayer = GetPlayerInMap()) DoSpawnArthasIfNeeded(pPlayer); m_uiArthasRespawnTimer = 0; } else m_uiArthasRespawnTimer -= uiDiff; } // Handle undead waves if (m_uiScourgeWaveTimer) { if (m_uiScourgeWaveTimer <= uiDiff) { if (GetData(TYPE_SALRAMM_EVENT) == DONE) { DoOrSimulateScriptTextForThisInstance(SAY_MEET_TOWN_HALL, NPC_ARTHAS); DoUpdateWorldState(WORLD_STATE_WAVE, 0); // Remove WaveCounter // despawn and respawn Arthas in the new location if (Creature* pArthas = GetSingleCreatureFromStorage(NPC_ARTHAS)) pArthas->ForcedDespawn(); if (Player* pPlayer = GetPlayerInMap()) DoSpawnArthasIfNeeded(pPlayer); } else { ++m_uiScourgeWaveCount; DoUpdateWorldState(WORLD_STATE_WAVE, m_uiScourgeWaveCount); DoSpawnNextScourgeWave(); } m_uiScourgeWaveTimer = 0; } else m_uiScourgeWaveTimer -= uiDiff; } }
void instance_ruins_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) { switch(uiType) { case TYPE_KURINNAXX: if (uiData == DONE) { DoSapwnAndorovIfCan(); // Yell after kurinnaxx if (m_auiEncounter[uiType] != DONE) DoOrSimulateScriptTextForThisInstance(YELL_OSSIRIAN_BREACHED, NPC_OSSIRIAN); } m_auiEncounter[uiType] = uiData; break; case TYPE_RAJAXX: m_auiEncounter[uiType] = uiData; if (uiData == IN_PROGRESS) { m_hasResetRajaxx = false; DoSortArmyWaves(); } if (uiData == DONE) { Map::PlayerList const &PlayerList = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { if (itr->getSource() && itr->getSource()->IsInWorld()) itr->getSource()->SetCombatTimer(0); } if (Creature* pAndorov = GetSingleCreatureFromStorage(NPC_GENERAL_ANDOROV)) { if (pAndorov->isAlive() && m_auiEncounter[TYPE_ANDOROV] != FAIL) { #if AQ_PATCH >= 10 pAndorov->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); #else pAndorov->ForcedDespawn(); #endif Map::PlayerList const& lPlayers = this->instance->GetPlayers(); if (!lPlayers.isEmpty()) for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) { if (Player* pPlayer = itr->getSource()) pPlayer->RewardReputation(609, 150); } } } } break; case TYPE_MOAM: case TYPE_BURU: case TYPE_AYAMISS: case TYPE_OSSIRIAN: case TYPE_ANDOROV: m_auiEncounter[uiType] = uiData; break; } if (uiData == DONE || (uiType == TYPE_RAJAXX && uiData == IN_PROGRESS) || (uiType == TYPE_ANDOROV && uiData == FAIL)) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6]; m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void instance_culling_of_stratholme::SetData(uint32 uiType, uint32 uiData) { switch (uiType) { case TYPE_GRAIN_EVENT: m_auiEncounter[uiType] = uiData; if (uiData == SPECIAL) DoUpdateWorldState(WORLD_STATE_CRATES, 1); else if (uiData == IN_PROGRESS) { // safety check if (m_uiGrainCrateCount >= MAX_GRAIN_CRATES) return; ++m_uiGrainCrateCount; DoUpdateWorldState(WORLD_STATE_CRATES_COUNT, m_uiGrainCrateCount); if (m_uiGrainCrateCount == MAX_GRAIN_CRATES) { m_uiRemoveCrateStateTimer = 20000; SetData(TYPE_GRAIN_EVENT, DONE); } } break; case TYPE_ARTHAS_INTRO_EVENT: m_auiEncounter[uiType] = uiData; if (uiData == DONE) { m_uiScourgeWaveCount = 0; m_uiScourgeWaveTimer = 1000; DoUpdateZombieResidents(); SetData(TYPE_MEATHOOK_EVENT, IN_PROGRESS); } break; case TYPE_MEATHOOK_EVENT: m_auiEncounter[uiType] = uiData; if (uiData == DONE) { m_uiScourgeWaveTimer = 20000; SetData(TYPE_SALRAMM_EVENT, IN_PROGRESS); } break; case TYPE_SALRAMM_EVENT: m_auiEncounter[uiType] = uiData; if (uiData == DONE) m_uiScourgeWaveTimer = 5000; break; case TYPE_ARTHAS_TOWNHALL_EVENT: m_auiEncounter[uiType] = uiData; if (uiData == DONE) { // despawn arthas and spawn him in the next point if (Creature* pArthas = GetSingleCreatureFromStorage(NPC_ARTHAS)) pArthas->ForcedDespawn(); if (Player* pPlayer = GetPlayerInMap()) DoSpawnArthasIfNeeded(pPlayer); } break; case TYPE_EPOCH_EVENT: m_auiEncounter[uiType] = uiData; break; case TYPE_ARTHAS_ESCORT_EVENT: // use fail in order to respawn Arthas if (uiData == FAIL) { m_uiArthasRespawnTimer = 10000; // despawn the bosses if Arthas dies in order to avoid exploits if (Creature* pEpoch = GetSingleCreatureFromStorage(NPC_LORD_EPOCH, true)) pEpoch->ForcedDespawn(); if (Creature* pMalganis = GetSingleCreatureFromStorage(NPC_MALGANIS, true)) pMalganis->ForcedDespawn(); } else m_auiEncounter[uiType] = uiData; break; case TYPE_MALGANIS_EVENT: m_auiEncounter[uiType] = uiData; if (uiData == DONE) { DoUseDoorOrButton(GO_CITY_ENTRANCE_GATE); DoToggleGameObjectFlags(instance->IsRegularDifficulty() ? GO_DARK_RUNED_CHEST : GO_DARK_RUNED_CHEST_H, GO_FLAG_NO_INTERACT, false); DoRespawnGameObject(instance->IsRegularDifficulty() ? GO_DARK_RUNED_CHEST : GO_DARK_RUNED_CHEST_H, 30 * MINUTE); if (Player* pPlayer = GetPlayerInMap()) DoSpawnChromieIfNeeded(pPlayer); } break; case TYPE_INFINITE_CORRUPTER_TIME: m_auiEncounter[uiType] = uiData; if (!uiData) { DoUpdateWorldState(WORLD_STATE_TIME, 0); // Remove Timer DoUpdateWorldState(WORLD_STATE_TIME_COUNTER, 0); } else DoUpdateWorldState(WORLD_STATE_TIME_COUNTER, uiData / (MINUTE * IN_MILLISECONDS)); break; case TYPE_INFINITE_CORRUPTER: m_auiEncounter[uiType] = uiData; switch (uiData) { case IN_PROGRESS: if (!GetData(TYPE_INFINITE_CORRUPTER_TIME)) { SetData(TYPE_INFINITE_CORRUPTER_TIME, MINUTE * 25 * IN_MILLISECONDS); DoUpdateWorldState(WORLD_STATE_TIME, 1); DoChromieWhisper(WHISPER_CHROMIE_GUARDIAN); // spawn the corruptor for the first time if (Creature* pArthas = GetSingleCreatureFromStorage(NPC_ARTHAS)) DoSpawnCorruptorIfNeeded(pArthas); } break; case DONE: // event completed - epilog handled by dbscript SetData(TYPE_INFINITE_CORRUPTER_TIME, 0); break; case SPECIAL: DoChromieWhisper(WHISPER_CHROMIE_HURRY); break; case FAIL: // event failed - despawn the corruptor SetData(TYPE_INFINITE_CORRUPTER_TIME, 0); if (Creature* pCorrupter = GetSingleCreatureFromStorage(NPC_INFINITE_CORRUPTER)) { DoOrSimulateScriptTextForThisInstance(SAY_CORRUPTOR_DESPAWN, NPC_INFINITE_CORRUPTER); if (pCorrupter->isAlive()) pCorrupter->ForcedDespawn(); } break; } break; } if (uiData == DONE || uiType == TYPE_INFINITE_CORRUPTER_TIME) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8] << " " << m_auiEncounter[9]; m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void instance_stratholme::Update(uint32 uiDiff) { if (m_uiBarthilasRunTimer) { if (m_uiBarthilasRunTimer <= uiDiff) { Creature* pBarthilas = GetSingleCreatureFromStorage(NPC_BARTHILAS); if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) pBarthilas->NearTeleportTo(aStratholmeLocation[1].m_fX, aStratholmeLocation[1].m_fY, aStratholmeLocation[1].m_fZ, aStratholmeLocation[1].m_fO); SetData(TYPE_BARTHILAS_RUN, DONE); m_uiBarthilasRunTimer = 0; } else m_uiBarthilasRunTimer -= uiDiff; } // Timer to summon Aurius into the Slaughter House once Baron is engaged if (m_uiAuriusSummonTimer) { if (m_uiAuriusSummonTimer <= uiDiff) { SetData(TYPE_AURIUS, IN_PROGRESS); m_uiAuriusSummonTimer = 0; } else m_uiAuriusSummonTimer -= uiDiff; } // Check changes for Baron ultimatum timer only if Baron is not already in combat if (m_uiBaronRunTimer && GetData(TYPE_BARON) != IN_PROGRESS) { if (m_uiYellCounter == 0 && m_uiBaronRunTimer <= 10 * MINUTE * IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_10_MIN, NPC_BARON); ++m_uiYellCounter; } else if (m_uiYellCounter == 1 && m_uiBaronRunTimer <= 5 * MINUTE * IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_5_MIN, NPC_BARON); ++m_uiYellCounter; } // Used to create a delay of 10s between Baron speech and Ysida's answer else if (m_uiYellCounter == 2 && m_uiBaronRunTimer <= (5 * MINUTE - 10) * IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(YSIDA_SAY_RUN_5_MIN, NPC_YSIDA); ++m_uiYellCounter; } if (m_uiBaronRunTimer <= uiDiff) { if (GetData(TYPE_BARON_RUN) != FAIL) { SetData(TYPE_BARON_RUN, FAIL); // Open the cage and let Ysida face her doom if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA)) { pYsida->GetMotionMaster()->MovePoint(0, aStratholmeLocation[8].m_fX, aStratholmeLocation[8].m_fY, aStratholmeLocation[8].m_fZ, aStratholmeLocation[8].m_fO); DoUseDoorOrButton(GO_YSIDA_CAGE); } DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_FAIL, NPC_BARON); m_uiBaronRunTimer = 8000; // We reset the timer so the speech of Ysida is not said at the same time than the Baron's one } else { // Baron ultimatum failed: let the Baron kill her if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA)) if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) pBaron->CastSpell(pYsida, SPELL_BARON_SOUL_DRAIN, true); DoOrSimulateScriptTextForThisInstance(YSIDA_SAY_RUN_FAIL, NPC_YSIDA); m_uiBaronRunTimer = 0; // event done for good, no more speech debug_log("SD2: Instance Stratholme: Baron run event reached end. Event has state %u.", GetData(TYPE_BARON_RUN)); } } else m_uiBaronRunTimer -= uiDiff; } if (m_uiMindlessSummonTimer) { if (m_uiMindlessCount < 30) { if (m_uiMindlessSummonTimer <= uiDiff) { if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { // Summon mindless skeletons and move them to random point in the center of the square if (Creature* pTemp = pBaron->SummonCreature(NPC_MINDLESS_UNDEAD, aStratholmeLocation[4].m_fX, aStratholmeLocation[4].m_fY, aStratholmeLocation[4].m_fZ, aStratholmeLocation[4].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) { float fX, fY, fZ; pBaron->GetRandomPoint(aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ, 20.0f, fX, fY, fZ); pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ); m_luiUndeadGUIDs.push_back(pTemp->GetObjectGuid()); ++m_uiMindlessCount; } } m_uiMindlessSummonTimer = 400; } else m_uiMindlessSummonTimer -= uiDiff; } else m_uiMindlessSummonTimer = 0; } if (m_uiSlaugtherSquareTimer) { if (m_uiSlaugtherSquareTimer <= uiDiff) { // Call next Abomnations for (GuidSet::const_iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end(); ++itr) { Creature* pAbom = instance->GetCreature(*itr); // Skip killed and already walking Abomnations if (!pAbom || !pAbom->isAlive() || pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) continue; // Let Move to somewhere in the middle if (!pAbom->isInCombat()) { if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_PORT_SLAUGTHER)) { float fX, fY, fZ; pAbom->GetRandomPoint(pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ(), 10.0f, fX, fY, fZ); pAbom->GetMotionMaster()->MovePoint(0, fX, fY, fZ); } } break; } // TODO - how fast are they called? m_uiSlaugtherSquareTimer = urand(15000, 30000); } else m_uiSlaugtherSquareTimer -= uiDiff; } }
void instance_blackwing_lair::Update(uint32 uiDiff) { // Scepter of the Shifting Sand epic quest line if (m_uiScepterEpicTimer) { if (m_uiScepterEpicTimer <= uiDiff) { switch (m_uiScepterQuestStep) { case 0: // On quest acceptance DoOrSimulateScriptTextForThisInstance(YELL_REDSHARD_TAUNT_1, NPC_LORD_VICTOR_NEFARIUS); m_uiScepterEpicTimer = 2 * HOUR * IN_MILLISECONDS; break; case 1: // 2 hours time mark switch (urand(0, 1)) { case 0: DoOrSimulateScriptTextForThisInstance(YELL_REDSHARD_TAUNT_2, NPC_LORD_VICTOR_NEFARIUS); DoOrSimulateScriptTextForThisInstance(EMOTE_REDSHARD_TAUNT_1, NPC_LORD_VICTOR_NEFARIUS); break; case 1: DoOrSimulateScriptTextForThisInstance(YELL_REDSHARD_TAUNT_3, NPC_LORD_VICTOR_NEFARIUS); break; } m_uiScepterEpicTimer = 2 * HOUR * IN_MILLISECONDS; break; case 2: // 1 hour left switch (urand(0, 1)) { case 0: DoOrSimulateScriptTextForThisInstance(YELL_REDSHARD_TAUNT_4, NPC_LORD_VICTOR_NEFARIUS); break; case 1: DoOrSimulateScriptTextForThisInstance(YELL_REDSHARD_TAUNT_5, NPC_LORD_VICTOR_NEFARIUS); break; } m_uiScepterEpicTimer = 30 * MINUTE * IN_MILLISECONDS; break; case 3: // 30 min left DoOrSimulateScriptTextForThisInstance(YELL_REDSHARD_TAUNT_6, NPC_LORD_VICTOR_NEFARIUS); m_uiScepterEpicTimer = 30 * MINUTE * IN_MILLISECONDS; break; case 4: // Failure SetData(TYPE_QUEST_SCEPTER, FAIL); if (GetData(TYPE_NEFARIAN) == NOT_STARTED) { DoOrSimulateScriptTextForThisInstance(EMOTE_REDSHARD_TAUNT_2, NPC_LORD_VICTOR_NEFARIUS); DoOrSimulateScriptTextForThisInstance(YELL_REDSHARD_TAUNT_7, NPC_LORD_VICTOR_NEFARIUS); } default: // Something weird happened: stop timer and fail the event m_uiScepterEpicTimer = 0; SetData(TYPE_QUEST_SCEPTER, FAIL); break; } m_uiScepterQuestStep++; } else m_uiScepterEpicTimer -= uiDiff; } // Reset Razorgore in case of wipe if (m_uiResetTimer) { if (m_uiResetTimer <= uiDiff) { // Respawn Razorgore if (Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE)) { if (!pRazorgore->isAlive()) pRazorgore->Respawn(); } // Respawn the Dragon Eggs for (GuidList::const_iterator itr = m_lDragonEggsGuids.begin(); itr != m_lDragonEggsGuids.end(); ++itr) { if (GameObject* pEgg = instance->GetGameObject(*itr)) { if (!pEgg->isSpawned()) pEgg->Respawn(); } } m_uiResetTimer = 0; } else m_uiResetTimer -= uiDiff; } if (GetData(TYPE_RAZORGORE) != IN_PROGRESS) return; if (m_uiDefenseTimer < uiDiff) { // Randomize generators std::random_shuffle(m_vGeneratorGuids.begin(), m_vGeneratorGuids.end()); // Spawn the defenders for (uint8 i = 0; i < MAX_EGGS_DEFENDERS; ++i) { Creature* pGenerator = instance->GetCreature(m_vGeneratorGuids[i]); if (!pGenerator) continue; // Defenders are spawned randomly, 4 at a time // There can be up to 12 Dragonspawns spawned and 40 Orcs (either mage or legionnaire) // If one of the cap is reached, only the remaining type of NPC is spawned until the second cap is also reached uint32 uiSpellId = 0; // Hold the spell summoning the NPC defender for that generator uint8 uiMaxRange = (m_uiDragonspawnCount < MAX_DRAGONSPAWN ? 3 : 1); // If all dragonspawns are already spawned, don't roll for them below switch (urand(0, uiMaxRange)) { case 0: if (m_uiBlackwingDefCount < MAX_BLACKWING_DEFENDER) uiSpellId = SPELL_SUMMON_LEGIONNAIRE; break; case 1: if (m_uiBlackwingDefCount < MAX_BLACKWING_DEFENDER) uiSpellId = SPELL_SUMMON_MAGE; break; case 2: case 3: uiSpellId = SPELL_SUMMON_DRAGONSPAWN; break; } if (uiSpellId != 0) pGenerator->CastSpell(pGenerator, uiSpellId, TRIGGERED_NONE); } m_uiDefenseTimer = 15000; } else m_uiDefenseTimer -= uiDiff; }
void instance_stratholme::SetData(uint32 uiType, uint32 uiData) { // TODO: Remove the hard-coded indexes from array accessing switch (uiType) { case TYPE_BARON_RUN: switch (uiData) { case IN_PROGRESS: if (m_auiEncounter[uiType] == IN_PROGRESS || m_auiEncounter[uiType] == FAIL) break; // Baron ultimatum starts: summon Ysida in the cage if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_START, NPC_BARON); if (Creature* pYsida = pBaron->SummonCreature(NPC_YSIDA, aStratholmeLocation[7].m_fX, aStratholmeLocation[7].m_fY, aStratholmeLocation[7].m_fZ, aStratholmeLocation[7].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0)) pYsida->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); } m_uiBaronRunTimer = 45 * MINUTE * IN_MILLISECONDS; debug_log("SD2: Instance Stratholme: Baron run in progress."); break; case FAIL: // may add code to remove aura from players, but in theory the time should be up already and removed. break; case DONE: m_uiBaronRunTimer = 0; break; } m_auiEncounter[uiType] = uiData; break; case TYPE_BARONESS: case TYPE_NERUB: case TYPE_PALLID: m_auiEncounter[uiType] = uiData; if (uiData == DONE) { DoSortZiggurats(); DoUseDoorOrButton(m_zigguratStorage[uiType - TYPE_BARONESS].m_doorGuid); } if (uiData == SPECIAL) StartSlaugtherSquare(); break; case TYPE_RAMSTEIN: if (uiData == SPECIAL) { if (m_auiEncounter[uiType] != SPECIAL && m_auiEncounter[uiType] != DONE) { m_uiSlaugtherSquareTimer = 20000; // TODO - unknown, also possible that this is not the very correct place.. DoUseDoorOrButton(GO_PORT_GAUNTLET); } uint32 uiCount = m_sAbomnationGUID.size(); for (GuidSet::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end();) { if (Creature* pAbom = instance->GetCreature(*itr)) { ++itr; if (!pAbom->isAlive()) --uiCount; } else { // Remove obsolete guid from set and decrement count m_sAbomnationGUID.erase(itr++); --uiCount; } } if (!uiCount) { // Open the Slaughterhouse door and set a timer to close it after 10 sec to let some time to Ramstein to move out DoOpenSlaughterhouseDoor(true); m_uiSlaughterDoorTimer = 10000; // No more handlng of Abomnations m_uiSlaugtherSquareTimer = 0; if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { DoScriptText(SAY_ANNOUNCE_RAMSTEIN, pBaron); if (Creature* pRamstein = pBaron->SummonCreature(NPC_RAMSTEIN, aStratholmeLocation[2].m_fX, aStratholmeLocation[2].m_fY, aStratholmeLocation[2].m_fZ, aStratholmeLocation[2].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0)) pRamstein->GetMotionMaster()->MovePoint(0, aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ); debug_log("SD2: Instance Stratholme - Slaugther event: Ramstein spawned."); } } else debug_log("SD2: Instance Stratholme - Slaugther event: %u Abomnation left to kill.", uiCount); } // After fail aggroing Ramstein means wipe on Ramstein, so close door again if (uiData == IN_PROGRESS && m_auiEncounter[uiType] == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); if (uiData == DONE) { // Open side gate and start summoning skeletons DoUseDoorOrButton(GO_PORT_SLAUGHTER_GATE); // Close the Slaughterhouse door in case it was open again after a wipe on Ramstein DoOpenSlaughterhouseDoor(false); // use this timer as a bool just to start summoning m_uiMindlessSummonTimer = 500; m_uiMindlessCount = 0; m_luiUndeadGUIDs.clear(); // Summon 5 guards if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { for (uint8 i = 0; i < 5; ++i) { float fX, fY, fZ; pBaron->GetRandomPoint(aStratholmeLocation[6].m_fX, aStratholmeLocation[6].m_fY, aStratholmeLocation[6].m_fZ, 5.0f, fX, fY, fZ); if (Creature* pTemp = pBaron->SummonCreature(NPC_BLACK_GUARD, aStratholmeLocation[6].m_fX, aStratholmeLocation[6].m_fY, aStratholmeLocation[6].m_fZ, aStratholmeLocation[6].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0)) m_luiGuardGUIDs.push_back(pTemp->GetObjectGuid()); } debug_log("SD2: Instance Stratholme - Slaugther event: Summoned 5 guards."); } } // Open Door again and stop Abomnation if (uiData == FAIL && m_auiEncounter[uiType] != FAIL) { DoUseDoorOrButton(GO_PORT_GAUNTLET); m_uiSlaugtherSquareTimer = 0; // Let already moving Abomnations stop for (auto itr : m_sAbomnationGUID) { Creature* pAbom = instance->GetCreature(itr); if (pAbom && pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) pAbom->GetMotionMaster()->MovementExpired(); } } m_auiEncounter[uiType] = uiData; break; case TYPE_BARON: if (uiData == IN_PROGRESS) { // Close Slaughterhouse door if needed if (m_auiEncounter[uiType] == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); // If Aurius was given the medaillon wait 5s before summoning him if (GetData(TYPE_AURIUS) == DONE) m_uiAuriusSummonTimer = 5000; } else if (uiData == DONE) { // Players successfully engaged Baron within the time-limit of his ultimatum // Note: UpdateAI() prevents TYPE_BARON_RUN to be marked as FAILED if the // Baron is already engaged (in progress) when the ultimatum timer expires if (m_auiEncounter[TYPE_BARON_RUN] == IN_PROGRESS) { SetData(TYPE_BARON_RUN, DONE); Map::PlayerList const& players = instance->GetPlayers(); for (const auto& player : players) { if (Player* pPlayer = player.getSource()) { if (pPlayer->HasAura(SPELL_BARON_ULTIMATUM)) pPlayer->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM); if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE) pPlayer->KilledMonsterCredit(NPC_YSIDA); // Argent Dawn reputation reward pPlayer->CastSpell(pPlayer, SPELL_YSIDA_FREED, TRIGGERED_OLD_TRIGGERED); } } // Open cage, finish rescue event if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA)) { DoScriptText(SAY_EPILOGUE, pYsida); DoUseDoorOrButton(GO_YSIDA_CAGE); pYsida->GetMotionMaster()->MovePoint(0, aStratholmeLocation[8].m_fX, aStratholmeLocation[8].m_fY, aStratholmeLocation[8].m_fZ); pYsida->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); } } // If Aurius was spawned to help fight the Baron if (GetData(TYPE_AURIUS) == DONE) { // Baron killed and Aurius is alive: give him his NPC Flags back, so players can complete the quest and fake his death if (Creature* pAurius = GetSingleCreatureFromStorage(NPC_AURIUS)) { if (pAurius->isAlive()) { DoScriptText(SAY_AURIUS_DEATH, pAurius); pAurius->StopMoving(); pAurius->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); pAurius->InterruptNonMeleeSpells(true); pAurius->SetHealth(1); pAurius->GetMotionMaster()->MovementExpired(); pAurius->GetMotionMaster()->MoveIdle(); pAurius->RemoveAllAurasOnDeath(); pAurius->SetStandState(UNIT_STAND_STATE_DEAD); } } } // Open Slaughterhouse door again DoUseDoorOrButton(GO_PORT_GAUNTLET); } else if (uiData == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); m_auiEncounter[uiType] = uiData; break; case TYPE_BARTHILAS_RUN: if (uiData == IN_PROGRESS) { Creature* pBarthilas = GetSingleCreatureFromStorage(NPC_BARTHILAS); if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) { DoScriptText(SAY_WARN_BARON, pBarthilas); pBarthilas->SetWalk(false); pBarthilas->GetMotionMaster()->MovePoint(0, aStratholmeLocation[0].m_fX, aStratholmeLocation[0].m_fY, aStratholmeLocation[0].m_fZ); m_uiBarthilasRunTimer = 8000; } } m_auiEncounter[uiType] = uiData; break; case TYPE_BLACK_GUARDS: // Prevent double action if (m_auiEncounter[uiType] == uiData) return; // Restart after failure, close Gauntlet if (uiData == IN_PROGRESS && m_auiEncounter[uiType] == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); // Wipe case - open gauntlet if (uiData == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); if (uiData == DONE) { if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) DoScriptText(SAY_UNDEAD_DEFEAT, pBaron); DoOpenSlaughterhouseDoor(true); DoUseDoorOrButton(GO_ZIGGURAT_DOOR_5); } m_auiEncounter[uiType] = uiData; // No need to save anything here, so return return; case TYPE_POSTMASTER: m_auiEncounter[uiType] = uiData; if (uiData == IN_PROGRESS) { ++m_uiPostboxesUsed; // After the second post box prepare to spawn the Post Master if (m_uiPostboxesUsed == 2) SetData(TYPE_POSTMASTER, SPECIAL); } // No need to save anything here, so return return; case TYPE_TRUE_MASTERS: m_auiEncounter[uiType] = uiData; if (uiData == SPECIAL) { ++m_uiSilverHandKilled; // When the 5th paladin is killed set data to DONE in order to give the quest credit for the last paladin if (m_uiSilverHandKilled == MAX_SILVERHAND) SetData(TYPE_TRUE_MASTERS, DONE); } // No need to save anything here, so return return; case TYPE_AURIUS: // Prevent further players to complete the quest in that instance or autocomplete the follow-up quest. the flag will be set back if event is succeed if (uiData == DONE) { if (Creature* pAurius = GetSingleCreatureFromStorage(NPC_AURIUS)) pAurius->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); } m_auiEncounter[uiType] = uiData; break; } if (uiData == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6] << " " << m_auiEncounter[7]; m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void instance_stratholme::Update(uint32 uiDiff) { if (m_uiBarthilasRunTimer) { if (m_uiBarthilasRunTimer <= uiDiff) { Creature* pBarthilas = GetSingleCreatureFromStorage(NPC_BARTHILAS); if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) pBarthilas->NearTeleportTo(aStratholmeLocation[1].m_fX, aStratholmeLocation[1].m_fY, aStratholmeLocation[1].m_fZ, aStratholmeLocation[1].m_fO); SetData(TYPE_BARTHILAS_RUN, DONE); m_uiBarthilasRunTimer = 0; } else m_uiBarthilasRunTimer -= uiDiff; } if (m_uiBaronRunTimer) { if (m_uiYellCounter == 0 && m_uiBaronRunTimer <= 10*MINUTE*IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_10_MIN, NPC_BARON); ++m_uiYellCounter; } else if (m_uiYellCounter == 1 && m_uiBaronRunTimer <= 5*MINUTE*IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_5_MIN, NPC_BARON); ++m_uiYellCounter; } if (m_uiBaronRunTimer <= uiDiff) { SetData(TYPE_BARON_RUN, FAIL); DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_FAIL, NPC_BARON); m_uiBaronRunTimer = 0; debug_log("SD2: Instance Stratholme: Baron run event reached end. Event has state %u.", GetData(TYPE_BARON_RUN)); } else m_uiBaronRunTimer -= uiDiff; } if (m_uiMindlessSummonTimer) { if (m_uiMindlessCount < 30) { if (m_uiMindlessSummonTimer <= uiDiff) { if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { // Summon mindless skeletons and move them to random point in the center of the square if (Creature* pTemp = pBaron->SummonCreature(NPC_MINDLESS_UNDEAD, aStratholmeLocation[4].m_fX, aStratholmeLocation[4].m_fY, aStratholmeLocation[4].m_fZ, aStratholmeLocation[4].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) { float fX, fY, fZ; pBaron->GetRandomPoint(aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ, 20.0f, fX, fY, fZ); pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ); m_luiUndeadGUIDs.push_back(pTemp->GetObjectGuid()); ++m_uiMindlessCount; } } m_uiMindlessSummonTimer = 400; } else m_uiMindlessSummonTimer -= uiDiff; } else m_uiMindlessSummonTimer = 0; } if (m_uiSlaugtherSquareTimer) { if (m_uiSlaugtherSquareTimer <= uiDiff) { // Call next Abomnations for (GuidSet::const_iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end(); ++itr) { Creature* pAbom = instance->GetCreature(*itr); // Skip killed and already walking Abomnations if (!pAbom || !pAbom->isAlive() || pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) continue; // Let Move to somewhere in the middle if (!pAbom->isInCombat()) { if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_PORT_SLAUGTHER)) { float fX, fY, fZ; pAbom->GetRandomPoint(pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ(), 10.0f, fX, fY, fZ); pAbom->GetMotionMaster()->MovePoint(0, fX, fY, fZ); } } break; } // TODO - how fast are they called? m_uiSlaugtherSquareTimer = urand(15000, 30000); } else m_uiSlaugtherSquareTimer -= uiDiff; } }
void instance_stratholme::Update(uint32 uiDiff) { // Loop over the two Gate traps, each one has up to three timers (trap reset, gate opening delay, critters spawning delay) for (uint8 i = 0; i < 2; i++) { // Check that the trap is not on cooldown, if so check if player/pet is in range if (m_uiGateTrapTimers[i][0]) { m_uiGateTrapTimers[i][0] -= uiDiff; if (m_uiGateTrapTimers[i][0] <= uiDiff) { debug_log("SD2: Instance Stratholme - Rat Trap reseted %u.", i); m_uiGateTrapTimers[i][0] = 0; } } else { Map::PlayerList const& players = instance->GetPlayers(); for (const auto& player : players) { if (Player* pPlayer = player.getSource()) { if (!pPlayer->isGameMaster() && pPlayer->IsWithinDist2d(aGateTrap[i].m_fX, aGateTrap[i].m_fY, 5.5f)) DoGateTrap(i); Pet* pet = pPlayer->GetPet(); if (!pPlayer->isGameMaster() && pet && pet->IsWithinDist2d(aGateTrap[i].m_fX, aGateTrap[i].m_fY, 5.5f)) DoGateTrap(i); } } } // Timer to reopen the gates if (m_uiGateTrapTimers[i][1]) { if (m_uiGateTrapTimers[i][1] <= uiDiff) { DoUseDoorOrButton(aGates[2 * i]); DoUseDoorOrButton(aGates[2 * i + 1]); m_uiGateTrapTimers[i][1] = 0; } else m_uiGateTrapTimers[i][1] -= uiDiff; } // Delay timer to spawn the plagued critters once the gate are closing if (m_uiGateTrapTimers[i][2]) { if (m_uiGateTrapTimers[i][2] <= uiDiff) { if (Player* pPlayer = GetPlayerInMap()) DoSpawnPlaguedCritters(i, pPlayer); m_uiGateTrapTimers[i][2] = 0; } else m_uiGateTrapTimers[i][2] -= uiDiff; } } // Timer to send the Black Guard Sentries out of the Slaughterhouse before Baron Rivendare if (m_uiBlackGuardsTimer) { if (m_uiBlackGuardsTimer <= uiDiff) { // Open the Slaughterhouse door and set a timer to close it after 10 sec to let some time to the 5 Black Guards to move out DoOpenSlaughterhouseDoor(true); m_uiSlaughterDoorTimer = 10000; for (GuidList::const_iterator itr = m_luiGuardGUIDs.begin(); itr != m_luiGuardGUIDs.end(); ++itr) { Creature* pGuard = instance->GetCreature(*itr); if (pGuard && pGuard->isAlive() && !pGuard->isInCombat()) { float fX, fY, fZ; pGuard->GetRandomPoint(aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ, 10.0f, fX, fY, fZ); pGuard->GetMotionMaster()->MovePoint(0, fX, fY, fZ); } } m_uiBlackGuardsTimer = 0; } else m_uiBlackGuardsTimer -= uiDiff; } // Timer to close the gate of the Slaughterhouse before Baron Rivendare after Ramstein/Black Guards moved out if (m_uiSlaughterDoorTimer) { if (m_uiSlaughterDoorTimer <= uiDiff) { DoOpenSlaughterhouseDoor(false); m_uiSlaughterDoorTimer = 0; } else m_uiSlaughterDoorTimer -= uiDiff; } // Timer to teleport Barthilas if (m_uiBarthilasRunTimer) { if (m_uiBarthilasRunTimer <= uiDiff) { Creature* pBarthilas = GetSingleCreatureFromStorage(NPC_BARTHILAS); if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) pBarthilas->NearTeleportTo(aStratholmeLocation[1].m_fX, aStratholmeLocation[1].m_fY, aStratholmeLocation[1].m_fZ, aStratholmeLocation[1].m_fO); SetData(TYPE_BARTHILAS_RUN, DONE); m_uiBarthilasRunTimer = 0; } else m_uiBarthilasRunTimer -= uiDiff; } // Timer to summon Aurius into the Slaughter House once Baron is engaged if (m_uiAuriusSummonTimer) { if (m_uiAuriusSummonTimer <= uiDiff) { // Teleport Aurius from the Chapel and spawn it in the Slaughter House to engage Baron Creature* pAurius = GetSingleCreatureFromStorage(NPC_AURIUS); if (pAurius && pAurius->isAlive() && !pAurius->isInCombat()) { if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { float fX, fY, fZ; pBaron->GetRandomPoint(pBaron->GetPositionX(), pBaron->GetPositionY(), pBaron->GetPositionZ(), 4.0f, fX, fY, fZ); pAurius->NearTeleportTo(fX, fY, fZ, pAurius->GetOrientation()); pAurius->SetRespawnCoord(fX, fY, fZ, pAurius->GetOrientation()); DoScriptText(SAY_AURIUS_AGGRO, pAurius); pAurius->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); pAurius->AI()->AttackStart(pBaron); } } m_uiAuriusSummonTimer = 0; } else m_uiAuriusSummonTimer -= uiDiff; } // Check changes for Baron ultimatum timer only if Baron is not already in combat if (m_uiBaronRunTimer && GetData(TYPE_BARON) != IN_PROGRESS) { if (m_uiYellCounter == 0 && m_uiBaronRunTimer <= 10 * MINUTE * IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_10_MIN, NPC_BARON); ++m_uiYellCounter; } else if (m_uiYellCounter == 1 && m_uiBaronRunTimer <= 5 * MINUTE * IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_5_MIN, NPC_BARON); ++m_uiYellCounter; } // Used to create a delay of 10s between Baron speech and Ysida's answer else if (m_uiYellCounter == 2 && m_uiBaronRunTimer <= (5 * MINUTE - 10) * IN_MILLISECONDS) { DoOrSimulateScriptTextForThisInstance(SAY_YSIDA_RUN_5_MIN, NPC_YSIDA); ++m_uiYellCounter; } if (m_uiBaronRunTimer <= uiDiff) { if (GetData(TYPE_BARON_RUN) != FAIL) { SetData(TYPE_BARON_RUN, FAIL); // Open the cage and let Ysida face her doom if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA)) { pYsida->GetMotionMaster()->MovePoint(0, aStratholmeLocation[8].m_fX, aStratholmeLocation[8].m_fY, aStratholmeLocation[8].m_fZ); DoUseDoorOrButton(GO_YSIDA_CAGE); } DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_FAIL, NPC_BARON); m_uiBaronRunTimer = 8000; // We reset the timer so the speech of Ysida is not said at the same time than the Baron's one } else { // Baron ultimatum failed: let the Baron kill her if (Creature* pYsida = GetSingleCreatureFromStorage(NPC_YSIDA)) { if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) pBaron->CastSpell(pYsida, SPELL_BARON_SOUL_DRAIN, TRIGGERED_NONE); } DoOrSimulateScriptTextForThisInstance(SAY_YSIDA_RUN_FAIL, NPC_YSIDA); m_uiBaronRunTimer = 0; // event done for good, no more speech debug_log("SD2: Instance Stratholme: Baron run event reached end. Event has state %u.", GetData(TYPE_BARON_RUN)); } } else m_uiBaronRunTimer -= uiDiff; } if (m_uiMindlessSummonTimer) { if (m_uiMindlessCount < 30) { if (m_uiMindlessSummonTimer <= uiDiff) { if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { // Summon mindless skeletons and move them to random point in the center of the square if (Creature* pTemp = pBaron->SummonCreature(NPC_MINDLESS_UNDEAD, aStratholmeLocation[4].m_fX, aStratholmeLocation[4].m_fY, aStratholmeLocation[4].m_fZ, aStratholmeLocation[4].m_fO, TEMPSPAWN_DEAD_DESPAWN, 0)) { float fX, fY, fZ; pBaron->GetRandomPoint(aStratholmeLocation[5].m_fX, aStratholmeLocation[5].m_fY, aStratholmeLocation[5].m_fZ, 20.0f, fX, fY, fZ); pTemp->SetWalk(false); pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ); m_luiUndeadGUIDs.push_back(pTemp->GetObjectGuid()); ++m_uiMindlessCount; } } m_uiMindlessSummonTimer = 400; } else m_uiMindlessSummonTimer -= uiDiff; } else m_uiMindlessSummonTimer = 0; } if (m_uiSlaugtherSquareTimer) { if (m_uiSlaugtherSquareTimer <= uiDiff) { // Call next Abomnations for (auto itr : m_sAbomnationGUID) { Creature* pAbom = instance->GetCreature(itr); // Skip killed and already walking Abomnations if (!pAbom || !pAbom->isAlive() || pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) continue; // Let Move to somewhere in the middle if (!pAbom->isInCombat()) { if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_PORT_SLAUGTHER)) { float fX, fY, fZ; pAbom->GetRandomPoint(pDoor->GetPositionX(), pDoor->GetPositionY(), pDoor->GetPositionZ(), 10.0f, fX, fY, fZ); pAbom->GetMotionMaster()->MovePoint(0, fX, fY, fZ); } } break; } // TODO - how fast are they called? m_uiSlaugtherSquareTimer = urand(30000, 45000); } else m_uiSlaugtherSquareTimer -= uiDiff; } }
void instance_stratholme::SetData(uint32 uiType, uint32 uiData) { // TODO: Remove the hard-coded indexes from array accessing switch(uiType) { case TYPE_BARON_RUN: switch(uiData) { case IN_PROGRESS: if (m_auiEncounter[uiType] == IN_PROGRESS || m_auiEncounter[uiType] == FAIL) break; DoOrSimulateScriptTextForThisInstance(SAY_ANNOUNCE_RUN_START, NPC_BARON); m_uiBaronRunTimer = 45*MINUTE*IN_MILLISECONDS; debug_log("SD2: Instance Stratholme: Baron run in progress."); break; case FAIL: //may add code to remove aura from players, but in theory the time should be up already and removed. break; case DONE: m_uiBaronRunTimer = 0; break; } m_auiEncounter[uiType] = uiData; break; case TYPE_BARONESS: case TYPE_NERUB: case TYPE_PALLID: m_auiEncounter[uiType] = uiData; if (uiData == DONE) { DoSortZiggurats(); DoUseDoorOrButton(m_zigguratStorage[uiType - TYPE_BARONESS].m_doorGuid); } if (uiData == SPECIAL) StartSlaugtherSquare(); break; case TYPE_RAMSTEIN: if (uiData == SPECIAL) { if (m_auiEncounter[uiType] != SPECIAL && m_auiEncounter[uiType] != DONE) { m_uiSlaugtherSquareTimer = 20000; // TODO - unknown, also possible that this is not the very correct place.. DoUseDoorOrButton(GO_PORT_GAUNTLET); } uint32 uiCount = m_sAbomnationGUID.size(); for(GuidSet::iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end();) { if (Creature* pAbom = instance->GetCreature(*itr)) { ++itr; if (!pAbom->isAlive()) --uiCount; } else { // Remove obsolete guid from set and decrement count m_sAbomnationGUID.erase(itr++); --uiCount; } } if (!uiCount) { // Old Comment: a bit itchy, it should close GO_ZIGGURAT_DOOR_4 door after 10 secs, but it doesn't. skipping it for now. // However looks like that this door is no more closed DoUseDoorOrButton(GO_ZIGGURAT_DOOR_4); // No more handlng of Abomnations m_uiSlaugtherSquareTimer = 0; if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { DoScriptText(SAY_ANNOUNCE_RAMSTEIN, pBaron); if (Creature* pRamstein = pBaron->SummonCreature(NPC_RAMSTEIN, aStratholmeLocation[2].m_fX, aStratholmeLocation[2].m_fY, aStratholmeLocation[2].m_fZ, aStratholmeLocation[2].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) pRamstein->GetMotionMaster()->MovePoint(0, aStratholmeLocation[3].m_fX, aStratholmeLocation[3].m_fY, aStratholmeLocation[3].m_fZ); debug_log("SD2: Instance Stratholme - Slaugther event: Ramstein spawned."); } } else debug_log("SD2: Instance Stratholme - Slaugther event: %u Abomnation left to kill.", uiCount); } // After fail aggroing Ramstein means wipe on Ramstein, so close door again if (uiData == IN_PROGRESS && m_auiEncounter[uiType] == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); if (uiData == DONE) { // Open side gate and start summoning skeletons DoUseDoorOrButton(GO_PORT_SLAUGHTER_GATE); // use this timer as a bool just to start summoning m_uiMindlessSummonTimer = 500; m_uiMindlessCount = 0; m_luiUndeadGUIDs.clear(); // Summon 5 guards if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) { for(uint8 i = 0; i < 5; ++i) { float fX, fY, fZ; pBaron->GetRandomPoint(aStratholmeLocation[6].m_fX, aStratholmeLocation[6].m_fY, aStratholmeLocation[6].m_fZ, 5.0f, fX, fY, fZ); if (Creature* pTemp = pBaron->SummonCreature(NPC_BLACK_GUARD, aStratholmeLocation[6].m_fX, aStratholmeLocation[6].m_fY, aStratholmeLocation[6].m_fZ, aStratholmeLocation[6].m_fO, TEMPSUMMON_DEAD_DESPAWN, 0)) m_luiGuardGUIDs.push_back(pTemp->GetObjectGuid()); } debug_log("SD2: Instance Stratholme - Slaugther event: Summoned 5 guards."); } } // Open Door again and stop Abomnation if (uiData == FAIL && m_auiEncounter[uiType] != FAIL) { DoUseDoorOrButton(GO_PORT_GAUNTLET); m_uiSlaugtherSquareTimer = 0; // Let already moving Abomnations stop for (GuidSet::const_iterator itr = m_sAbomnationGUID.begin(); itr != m_sAbomnationGUID.end(); ++itr) { Creature* pAbom = instance->GetCreature(*itr); if (pAbom && pAbom->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) pAbom->GetMotionMaster()->MovementExpired(); } } m_auiEncounter[uiType] = uiData; break; case TYPE_BARON: if (uiData == IN_PROGRESS) { // Reached the Baron within time-limit if (m_auiEncounter[TYPE_BARON_RUN] == IN_PROGRESS) SetData(TYPE_BARON_RUN, DONE); // Close Slaughterhouse door if needed if (m_auiEncounter[5] == FAIL) // TODO DoUseDoorOrButton(GO_PORT_GAUNTLET); } if (uiData == DONE) { if (m_auiEncounter[TYPE_BARON_RUN] == DONE) { Map::PlayerList const& players = instance->GetPlayers(); for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* pPlayer = itr->getSource()) { if (pPlayer->HasAura(SPELL_BARON_ULTIMATUM)) pPlayer->RemoveAurasDueToSpell(SPELL_BARON_ULTIMATUM); if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE) pPlayer->AreaExploredOrEventHappens(QUEST_DEAD_MAN_PLEA); } } // Open cage and finish rescue event if (Creature* pYsidaT = GetSingleCreatureFromStorage(NPC_YSIDA_TRIGGER)) { if (Creature* pYsida = pYsidaT->SummonCreature(NPC_YSIDA, pYsidaT->GetPositionX(), pYsidaT->GetPositionY(), pYsidaT->GetPositionZ(), pYsidaT->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 1800000)) { DoScriptText(SAY_EPILOGUE, pYsida); pYsida->GetMotionMaster()->MovePoint(0, aStratholmeLocation[7].m_fX, aStratholmeLocation[7].m_fY, aStratholmeLocation[7].m_fZ); } DoUseDoorOrButton(GO_YSIDA_CAGE); } } // Open Slaughterhouse door again DoUseDoorOrButton(GO_PORT_GAUNTLET); } if (uiData == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); m_auiEncounter[5] = uiData; // TODO break; case TYPE_BARTHILAS_RUN: if (uiData == IN_PROGRESS) { Creature* pBarthilas = GetSingleCreatureFromStorage(NPC_BARTHILAS); if (pBarthilas && pBarthilas->isAlive() && !pBarthilas->isInCombat()) { DoScriptText(SAY_WARN_BARON, pBarthilas); pBarthilas->SetWalk(false); pBarthilas->GetMotionMaster()->MovePoint(0, aStratholmeLocation[0].m_fX, aStratholmeLocation[0].m_fY, aStratholmeLocation[0].m_fZ); m_uiBarthilasRunTimer = 8000; } } m_auiEncounter[6] = uiData; // TODO break; case TYPE_BLACK_GUARDS: // Prevent double action if (m_auiEncounter[7] == uiData) // TODO return; // Restart after failure, close Gauntlet if (uiData == IN_PROGRESS && m_auiEncounter[7] == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); // Wipe case - open gauntlet if (uiData == FAIL) DoUseDoorOrButton(GO_PORT_GAUNTLET); if (uiData == DONE) { if (Creature* pBaron = GetSingleCreatureFromStorage(NPC_BARON)) DoScriptText(SAY_UNDEAD_DEFEAT, pBaron); DoUseDoorOrButton(GO_ZIGGURAT_DOOR_5); } m_auiEncounter[7] = uiData; // TODO // No need to save anything here, so return return; case TYPE_SH_AELMAR: m_bIsSilverHandDead[0] = (uiData) ? true : false; break; case TYPE_SH_CATHELA: m_bIsSilverHandDead[1] = (uiData) ? true : false; break; case TYPE_SH_GREGOR: m_bIsSilverHandDead[2] = (uiData) ? true : false; break; case TYPE_SH_NEMAS: m_bIsSilverHandDead[3] = (uiData) ? true : false; break; case TYPE_SH_VICAR: m_bIsSilverHandDead[4] = (uiData) ? true : false; break; } if (uiData == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6]; m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void instance_sunken_temple::SetData(uint32 uiType, uint32 uiData) { switch (uiType) { case TYPE_ATALARION: if (uiData == SPECIAL) DoSpawnAtalarionIfCan(); m_auiEncounter[uiType] = uiData; break; case TYPE_PROTECTORS: if (uiData == DONE) { --m_uiProtectorsRemaining; if (!m_uiProtectorsRemaining) { m_auiEncounter[uiType] = uiData; DoUseDoorOrButton(GO_JAMMALAN_BARRIER); // Intro yell DoOrSimulateScriptTextForThisInstance(SAY_JAMMALAN_INTRO, NPC_JAMMALAN); } } break; case TYPE_JAMMALAN: if (uiData == DONE) { if (Creature* pEranikus = GetSingleCreatureFromStorage(NPC_SHADE_OF_ERANIKUS)) pEranikus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER); } m_auiEncounter[uiType] = uiData; break; case TYPE_AVATAR: if (uiData == SPECIAL) { ++m_uiFlameCounter; Creature* pShade = GetSingleCreatureFromStorage(NPC_SHADE_OF_HAKKAR); if (!pShade) return; switch (m_uiFlameCounter) { // Yells on each flame // TODO It might be possible that these yells should be ordered randomly, however this is the seen state case 1: DoScriptText(SAY_AVATAR_BRAZIER_1, pShade); break; case 2: DoScriptText(SAY_AVATAR_BRAZIER_2, pShade); break; case 3: DoScriptText(SAY_AVATAR_BRAZIER_3, pShade); break; // Summon the avatar of all flames are used case MAX_FLAMES: DoScriptText(SAY_AVATAR_BRAZIER_4, pShade); pShade->CastSpell(pShade, SPELL_SUMMON_AVATAR, TRIGGERED_OLD_TRIGGERED); m_uiAvatarSummonTimer = 0; m_uiSupressorTimer = 0; break; } // Summon the suppressors only after the flames are doused // Summon timer is confusing random; timers were: 13, 39 and 52 secs; if (m_uiFlameCounter != MAX_FLAMES) m_uiSupressorTimer = urand(15000, 45000); return; } // Prevent double processing if (m_auiEncounter[uiType] == uiData) return; if (uiData == IN_PROGRESS) { m_uiSupressorTimer = 0; DoUpdateFlamesFlags(false); // Summon timer; use a small delay m_uiAvatarSummonTimer = 3000; m_bIsFirstHakkarWave = true; // Summon the shade Player* pPlayer = GetPlayerInMap(); if (!pPlayer) return; if (Creature* pShade = pPlayer->SummonCreature(NPC_SHADE_OF_HAKKAR, aSunkenTempleLocation[1].m_fX, aSunkenTempleLocation[1].m_fY, aSunkenTempleLocation[1].m_fZ, aSunkenTempleLocation[1].m_fO, TEMPSPAWN_MANUAL_DESPAWN, 0)) { m_npcEntryGuidStore[NPC_SHADE_OF_HAKKAR] = pShade->GetObjectGuid(); pShade->SetRespawnDelay(DAY); } // Respawn circles for (GuidVector::const_iterator itr = m_vuiCircleGUIDs.begin(); itr != m_vuiCircleGUIDs.end(); ++itr) DoRespawnGameObject(*itr, 30 * MINUTE); } else if (uiData == FAIL) { // In case of wipe during the summoning ritual the shade is despawned // The trash mobs stay in place, they are not despawned; the avatar is not sure if it's despawned or not but most likely he'll stay in place // Despawn the shade and the avatar if needed -- TODO, avatar really? if (Creature* pShade = GetSingleCreatureFromStorage(NPC_SHADE_OF_HAKKAR)) pShade->ForcedDespawn(); // Reset flames DoUpdateFlamesFlags(true); } // Use combat doors DoUseDoorOrButton(GO_HAKKAR_DOOR_1); DoUseDoorOrButton(GO_HAKKAR_DOOR_2); m_auiEncounter[uiType] = uiData; break; } if (uiData == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4]; m_strInstData = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }