void JustReachedHome() { if (m_pInstance) { m_pInstance->SetData(TYPE_KILJAEDEN, FAIL); // Reset the corrupt Sunwell aura if (Creature* pKiljaedenController = m_pInstance->GetSingleCreatureFromStorage(NPC_KILJAEDEN_CONTROLLER)) pKiljaedenController->CastSpell(pKiljaedenController, SPELL_ANVEENA_DRAIN, true); // Respawn Anveena if necessary if (Creature* pAnveena = m_pInstance->GetSingleCreatureFromStorage(NPC_ANVEENA)) { if (!pAnveena->isAlive()) pAnveena->Respawn(); } // Despawn Kalec if already summoned if (Creature* pKalec = m_pInstance->GetSingleCreatureFromStorage(NPC_KALECGOS, true)) pKalec->ForcedDespawn(); } // Despawn on wipe m_creature->ForcedDespawn(); }
void JustDidDialogueStep(int32 iEntry) { if (!m_pInstance) return; switch (iEntry) { case NPC_KALECGOS: if (Creature* pKalec = m_pInstance->GetSingleCreatureFromStorage(NPC_KALECGOS)) { pKalec->CastSpell(pKalec, SPELL_KALEC_TELEPORT, true); pKalec->SetLevitate(false); } m_creature->SummonCreature(NPC_CORE_ENTROPIUS, m_creature->GetPositionX(), m_creature->GetPositionY(), 85.0f, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); break; case NPC_BOSS_PORTAL: // ToDo: summon soldiers to the right m_creature->SummonCreature(NPC_BOSS_PORTAL, aOutroLocations[0].m_fX, aOutroLocations[0].m_fY, aOutroLocations[0].m_fZ, aOutroLocations[0].m_fO, TEMPSUMMON_CORPSE_DESPAWN, 0); break; case POINT_SUMMON_SOLDIERS: // ToDo: summon soldiers to the left break; case NPC_VELEN: m_creature->SummonCreature(NPC_VELEN, aOutroLocations[1].m_fX, aOutroLocations[1].m_fY, aOutroLocations[1].m_fZ, aOutroLocations[1].m_fO, TEMPSUMMON_CORPSE_DESPAWN, 0); break; case NPC_LIADRIN: m_creature->SummonCreature(NPC_LIADRIN, aOutroLocations[2].m_fX, aOutroLocations[2].m_fY, aOutroLocations[2].m_fZ, aOutroLocations[2].m_fO, TEMPSUMMON_TIMED_DESPAWN, 4*MINUTE*IN_MILLISECONDS); break; case SPELL_CALL_ENTROPIUS: if (Creature* pVelen = m_pInstance->GetSingleCreatureFromStorage(NPC_VELEN)) pVelen->CastSpell(pVelen, SPELL_CALL_ENTROPIUS, false); // Set point id = 1 for movement event if (Creature* pEntropius = m_creature->GetMap()->GetCreature(m_EntropiusGuid)) { pEntropius->SetWalk(false); pEntropius->GetMotionMaster()->MovePoint(1, m_creature->GetPositionX(), m_creature->GetPositionY(), 35.0f); } break; case POINT_MOVE_LIADRIN: if (Creature* pLiadrin = m_pInstance->GetSingleCreatureFromStorage(NPC_LIADRIN)) pLiadrin->GetMotionMaster()->MovePoint(0, aOutroLocations[4].m_fX, aOutroLocations[4].m_fY, aOutroLocations[4].m_fZ); break; case SPELL_BLAZE_TO_LIGHT: if (Creature* pEntropius = m_creature->GetMap()->GetCreature(m_EntropiusGuid)) { pEntropius->CastSpell(pEntropius, SPELL_BLAZE_TO_LIGHT, true); pEntropius->RemoveAurasDueToSpell(SPELL_ENTROPIUS_BODY); pEntropius->SetWalk(true); pEntropius->GetMotionMaster()->MovePoint(2, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); } break; case POINT_EVENT_EXIT: // Set point id = 1 for the despawn event if (Creature* pVelen = m_pInstance->GetSingleCreatureFromStorage(NPC_VELEN)) pVelen->GetMotionMaster()->MovePoint(1, aOutroLocations[1].m_fX, aOutroLocations[1].m_fY, aOutroLocations[1].m_fZ); break; } }
void JustDidDialogueStep(int32 iEntry) { if (!m_pInstance) return; switch (iEntry) { case PHASE_DARKNESS: case PHASE_ARMAGEDDON: case PHASE_SACRIFICE: if (DoCastSpellIfCan(m_creature, SPELL_SINISTER_REFLECTION, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { DoScriptText(irand(0, 1) ? SAY_REFLECTION_1 : SAY_REFLECTION_2, m_creature); // In the 2nd and 3rd transition kill all drakes if (iEntry == PHASE_ARMAGEDDON || iEntry == PHASE_SACRIFICE) DoCastSpellIfCan(m_creature, SPELL_DESTROY_DRAKES, CAST_TRIGGERED); m_uiPhase = PHASE_TRANSITION; // Darkness of Souls needs the timer reseted m_uiDarknessOfSoulsTimer = iEntry == PHASE_SACRIFICE ? 30000 : 45000; } break; case EVENT_SWITCH_PHASE_2: case EVENT_SWITCH_PHASE_3: case EVENT_SWITCH_PHASE_4: DoCastSpellIfCan(m_creature, SPELL_SHADOW_SPIKE); break; case EVENT_DRAGON_ORB: if (Creature* pKalec = m_pInstance->GetSingleCreatureFromStorage(NPC_KALECGOS)) DoScriptText(irand(0, 1) ? SAY_KALECGOS_ORB_2 : SAY_KALECGOS_ORB_3, pKalec); // no break case SAY_KALECGOS_ORB_1: case SAY_KALECGOS_ORB_4: // ToDo: activate the blue dragon orbs break; case SAY_PHASE_3: m_uiPhase = PHASE_DARKNESS; break; case SAY_PHASE_4: m_uiPhase = PHASE_ARMAGEDDON; break; case SAY_PHASE_5: if (Creature* pAnveena = m_pInstance->GetSingleCreatureFromStorage(NPC_ANVEENA)) { pAnveena->RemoveAurasDueToSpell(SPELL_ANVEENA_PRISON); pAnveena->CastSpell(pAnveena, SPELL_SACRIFICE_ANVEENA, true); pAnveena->ForcedDespawn(3000); } m_uiPhase = PHASE_SACRIFICE; break; } }
void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage, DamageEffectType /*damagetype*/) override { if (uiDamage > m_creature->GetHealth()) { uiDamage = 0; if (m_bIsBanished) return; // banish Sathrovarr and eject the players if (DoCastSpellIfCan(m_creature, SPELL_BANISH, CAST_TRIGGERED) == CAST_OK) m_bIsBanished = true; if (!m_pInstance) return; if (Creature* pKalecgos = m_pInstance->GetSingleCreatureFromStorage(NPC_KALECGOS_DRAGON)) { if (boss_kalecgosAI* pKalecgosAI = dynamic_cast<boss_kalecgosAI*>(pKalecgos->AI())) pKalecgosAI->m_bIsUncorrupted = true; } m_pInstance->DoEjectSpectralPlayers(); } }
void JustSummoned(Creature* pSummoned) override { if (pSummoned->GetEntry() == NPC_VOID_SENTINEL) { // Attack Muru's target if (Creature* pMuru = m_pInstance->GetSingleCreatureFromStorage(NPC_MURU)) { if (Unit* pTarget = pMuru->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { pSummoned->AI()->AttackStart(pTarget); } } } }
void DoStartOutro() { if (!m_pInstance) return; // Bring Sathrovarr in the normal realm and kill him if (Creature* pSathrovarr = m_pInstance->GetSingleCreatureFromStorage(NPC_SATHROVARR)) { // The teleport spell doesn't work right for this, so we need to teleport him manually pSathrovarr->NearTeleportTo(1704.34f, 928.17f, 53.08f, 0); pSathrovarr->DealDamage(pSathrovarr, pSathrovarr->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } if (Creature* pKalec = m_pInstance->GetSingleCreatureFromStorage(NPC_KALECGOS_HUMAN)) pKalec->ForcedDespawn(); EnterEvadeMode(); m_creature->SetFactionTemporary(35, TEMPFACTION_RESTORE_RESPAWN); m_creature->GetMotionMaster()->MoveIdle(); DoScriptText(SAY_GOOD_PLRWIN, m_creature); m_uiExitTimer = 10000; }
void SummonedMovementInform(Creature* pSummoned, uint32 uiType, uint32 uiPointId) { if (uiType != POINT_MOTION_TYPE) return; if (uiPointId == 1) { if (pSummoned->GetEntry() == NPC_CORE_ENTROPIUS) { // Interrupt Velen's casting when entropius has reached the ground if (Creature* pVelen = m_pInstance->GetSingleCreatureFromStorage(NPC_VELEN)) pVelen->InterruptNonMeleeSpells(false); } else if (pSummoned->GetEntry() == NPC_VELEN) { // Cast teleport and despawn Velen, the portal and Kalec; Liadrin will despawn on timer pSummoned->CastSpell(pSummoned, SPELL_TELEPORT_VISUAL, true); pSummoned->ForcedDespawn(1000); // Note: portal should despawn only after all the soldiers have reached this point and "teleported" outside if (Creature* pPortal = m_creature->GetMap()->GetCreature(m_PortalGuid)) pPortal->ForcedDespawn(5000); if (Creature* pKalec = m_pInstance->GetSingleCreatureFromStorage(NPC_KALECGOS)) pKalec->ForcedDespawn(1000); } } else if (uiPointId == 2 && pSummoned->GetEntry() == NPC_CORE_ENTROPIUS) { // When the purified Muru reaches the ground the sunwell ignites and Muru despawns DoCastSpellIfCan(m_creature, SPELL_SUNWELL_IGNITION); if (Creature* pLiadrin = m_pInstance->GetSingleCreatureFromStorage(NPC_LIADRIN)) pLiadrin->SetStandState(UNIT_STAND_STATE_KNEEL); pSummoned->ForcedDespawn(); } }
void JustDied(Unit* pKiller) { if (m_pInstance) { m_pInstance->SetData(TYPE_KILJAEDEN, DONE); // Start the outro if (Creature* pKiljaedenController = m_pInstance->GetSingleCreatureFromStorage(NPC_KILJAEDEN_CONTROLLER)) { if (npc_kiljaeden_controllerAI* pControllerAI = dynamic_cast<npc_kiljaeden_controllerAI*>(pKiljaedenController->AI())) pControllerAI->DoStartOutroDialogue(); } } }
void JustReachedHome() { if (m_pInstance) { m_pInstance->SetData(TYPE_MURU, FAIL); // respawn muru if (Creature* pMuru = m_pInstance->GetSingleCreatureFromStorage(NPC_MURU)) pMuru->Respawn(); } // despawn boss and summons for reset DespawnSummonedCreatures(); m_creature->ForcedDespawn(); }
void UpdateAI(const uint32 uiDiff) override { if (m_uiSentinelTimer) { // Summon the sentinel on a short timer after the portal opens if (m_uiSentinelTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_SENTINEL_SUMMONER) == CAST_OK) m_uiSentinelTimer = 0; } else m_uiSentinelTimer -= uiDiff; } if (m_uiTransformTimer) { if (m_uiTransformTimer <= uiDiff) { // Alternate the visuals ++m_uiTransformCount; DoCastSpellIfCan(m_creature, (m_uiTransformCount % 2) ? SPELL_TRANSFORM_VISUAL_1 : SPELL_TRANSFORM_VISUAL_2, CAST_TRIGGERED); if (m_uiTransformCount < MAX_TRANSFORM_CASTS) m_uiTransformTimer = 1000; else { m_uiTransformTimer = 0; m_uiTransformCount = 0; } // Summon Entropius when reached half of the transition if (m_uiTransformCount == MAX_TRANSFORM_CASTS / 2) { if (Creature* pMuru = m_pInstance->GetSingleCreatureFromStorage(NPC_MURU)) pMuru->CastSpell(pMuru, SPELL_SUMMON_ENTROPIUS, TRIGGERED_NONE); } } else m_uiTransformTimer -= uiDiff; } }
void JustReachedHome() override { if (m_pInstance) { m_pInstance->SetData(TYPE_MURU, FAIL); // respawn muru #if defined (CLASSIC) || defined (TBC) if (Creature* pMuru = m_pInstance->GetSingleCreatureFromStorage(NPC_MURU)) { pMuru->Respawn(); } #endif #if defined (WOTLK) m_creature->SummonCreature(NPC_MURU, afMuruSpawnLoc[0], afMuruSpawnLoc[1], afMuruSpawnLoc[2], afMuruSpawnLoc[3], TEMPSUMMON_DEAD_DESPAWN, 0, true); #endif } // despawn boss and summons for reset #if defined (CLASSIC) || defined (TBC) DespawnSummonedCreatures(); #endif m_creature->ForcedDespawn(); }
void UpdateAI(const uint32 uiDiff) override { if (m_uiMovementTimer) { if (m_uiMovementTimer <= uiDiff) { m_creature->SetLevitate(true); m_creature->GetMotionMaster()->MovePoint(PHASE_GROUND, m_creature->GetPositionX(), m_creature->GetPositionY(), 50.083f, false); m_uiMovementTimer = 0; } else m_uiMovementTimer -= uiDiff; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 0; } } else m_uiBerserkTimer -= uiDiff; } switch (m_uiPhase) { case PHASE_GROUND: if (m_uiCleaveTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CLEAVE) == CAST_OK) m_uiCleaveTimer = urand(2000, 5000); } else m_uiCleaveTimer -= uiDiff; if (m_uiCorrosionTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CORROSION) == CAST_OK) { DoScriptText(SAY_BREATH, m_creature); m_uiCorrosionTimer = 30000; } } else m_uiCorrosionTimer -= uiDiff; if (m_uiGasNovaTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_GAS_NOVA) == CAST_OK) m_uiGasNovaTimer = 23000; } else m_uiGasNovaTimer -= uiDiff; if (m_uiEncapsulateTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_ENCAPSULATE_CHANNEL) == CAST_OK) m_uiEncapsulateTimer = urand(30000, 40000); } } else m_uiEncapsulateTimer -= uiDiff; if (m_uiFlyPhaseTimer < uiDiff) { DoScriptText(SAY_TAKEOFF, m_creature); SetCombatMovement(false); m_creature->SetLevitate(true); m_creature->GetMotionMaster()->MoveIdle(); m_creature->GetMotionMaster()->MovePoint(PHASE_AIR, m_creature->GetPositionX(), m_creature->GetPositionY(), 50.083f, false); m_uiPhase = PHASE_TRANSITION; m_uiSubPhase = SUBPHASE_VAPOR; m_uiDemonicVaporTimer = 1000; m_uiDemonicVaporCount = 0; m_uiFlyPhaseTimer = 60000; } else m_uiFlyPhaseTimer -= uiDiff; DoMeleeAttackIfReady(); break; case PHASE_AIR: switch (m_uiSubPhase) { case SUBPHASE_VAPOR: if (m_uiDemonicVaporTimer < uiDiff) { // After the second Demonic Vapor trial, start the breath phase if (m_uiDemonicVaporCount == 2) { if (!m_pInstance) return; // select the side on which we want to fly m_bIsLeftSide = urand(0, 1) ? true : false; m_uiCorruptionCount = 0; m_uiSubPhase = SUBPHASE_BREATH_PREPARE; if (Creature* pTrigger = m_pInstance->GetSingleCreatureFromStorage(m_bIsLeftSide ? NPC_FLIGHT_TRIGGER_LEFT : NPC_FLIGHT_TRIGGER_RIGHT)) m_creature->GetMotionMaster()->MovePoint(SUBPHASE_VAPOR, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false); } else { if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_VAPOR) == CAST_OK) { ++m_uiDemonicVaporCount; m_uiDemonicVaporTimer = 11000; } } } else m_uiDemonicVaporTimer -= uiDiff; break; case SUBPHASE_BREATH_PREPARE: if (m_uiCorruptionTimer) { if (m_uiCorruptionTimer <= uiDiff) { if (!m_pInstance) return; // Fly to trigger on the same side - choose a random index for the trigger m_uiCorruptionIndex = urand(0, 2); if (Creature* pTrigger = m_creature->GetMap()->GetCreature(m_pInstance->SelectFelmystFlightTrigger(m_bIsLeftSide, m_uiCorruptionIndex))) m_creature->GetMotionMaster()->MovePoint(SUBPHASE_BREATH_PREPARE, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false); m_uiSubPhase = SUBPHASE_BREATH_MOVE; m_uiCorruptionTimer = 0; } else m_uiCorruptionTimer -= uiDiff; } break; case SUBPHASE_BREATH_MOVE: // nothing here; this is handled in MovementInform break; } break; case PHASE_TRANSITION: // nothing here; wait for transition to finish break; } }
void MovementInform(uint32 uiMoveType, uint32 uiPointId) override { if (uiMoveType != POINT_MOTION_TYPE) return; switch (uiPointId) { case PHASE_GROUND: m_creature->SetWalk(false); // ToDo: start WP movement here. Currently disabled because of some MMaps issues // m_creature->GetMotionMaster()->MoveWaypoint(); break; case PHASE_AIR: // switch from ground transition to flight phase m_uiPhase = PHASE_AIR; break; case SUBPHASE_VAPOR: // After the third breath land and resume phase 1 if (m_uiCorruptionCount == 3) { m_uiPhase = PHASE_TRANSITION; float fGroundZ = m_creature->GetMap()->GetHeight(m_creature->GetPhaseMask(), m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); m_creature->GetMotionMaster()->MovePoint(PHASE_TRANSITION, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), fGroundZ, false); return; } // prepare to move to flight trigger ++m_uiCorruptionCount; m_uiCorruptionTimer = 5000; m_uiSubPhase = SUBPHASE_BREATH_PREPARE; break; case SUBPHASE_BREATH_PREPARE: // move across the arena if (!m_pInstance) return; // Fly to the other side, casting the breath. Keep the same trigger index if (Creature* pTrigger = m_creature->GetMap()->GetCreature(m_pInstance->SelectFelmystFlightTrigger(!m_bIsLeftSide, m_uiCorruptionIndex))) { DoScriptText(EMOTE_DEEP_BREATH, m_creature); DoCastSpellIfCan(m_creature, SPELL_SPEED_BURST, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_FOG_CORRUPTION, CAST_TRIGGERED); m_creature->GetMotionMaster()->MovePoint(SUBPHASE_BREATH_MOVE, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false); } break; case SUBPHASE_BREATH_MOVE: if (!m_pInstance) return; // remove speed aura m_creature->RemoveAurasDueToSpell(SPELL_SPEED_BURST); // Get to the flight trigger on the same side of the arena if (Creature* pTrigger = m_pInstance->GetSingleCreatureFromStorage(!m_bIsLeftSide ? NPC_FLIGHT_TRIGGER_LEFT : NPC_FLIGHT_TRIGGER_RIGHT)) m_creature->GetMotionMaster()->MovePoint(SUBPHASE_VAPOR, pTrigger->GetPositionX(), pTrigger->GetPositionY(), pTrigger->GetPositionZ(), false); // switch sides m_bIsLeftSide = !m_bIsLeftSide; break; case PHASE_TRANSITION: // switch back to ground combat from flight transition m_uiPhase = PHASE_GROUND; SetCombatMovement(true); m_creature->SetLevitate(false); DoStartMovement(m_creature->getVictim()); break; } }