void JustReachedHome() override { if (!m_pInstance) return; if (m_bEventFinished) { if (m_pInstance->GetData(TYPE_ALGALON) == DONE) { // complete the achiev and start outro dialogue DoCastSpellIfCan(m_creature, SPELL_KILL_CREDIT, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_SUPERMASSIVE_FAIL, CAST_TRIGGERED); StartNextDialogueText(NPC_ALGALON); } else StartNextDialogueText(SAY_DESPAWN_1); } else m_pInstance->SetData(TYPE_ALGALON, FAIL); // despawn everything for (GuidList::const_iterator itr = m_lSummonedGuids.begin(); itr != m_lSummonedGuids.end(); ++itr) { if (Creature* pSummoned = m_creature->GetMap()->GetCreature(*itr)) pSummoned->ForcedDespawn(); } }
void JustDidDialogueStep(int32 iEntry) override { if (!m_pInstance) return; switch (iEntry) { case NPC_SIF: DoCastSpellIfCan(m_creature, SPELL_SHEAT_OF_LIGHTNING, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT); if (Creature* pSif = m_creature->SummonCreature(NPC_SIF, afSifSpawnLoc[0], afSifSpawnLoc[1], afSifSpawnLoc[2], afSifSpawnLoc[3], TEMPSUMMON_CORPSE_DESPAWN, 0)) DoScriptText(SAY_SIF_BEGIN, pSif); break; case SPELL_TOUCH_OF_DOMINION: if (Creature* pSif = m_pInstance->GetSingleCreatureFromStorage(NPC_SIF)) pSif->CastSpell(m_creature, SPELL_TOUCH_OF_DOMINION, false); break; case PHASE_SOLO: m_creature->GetMotionMaster()->MoveJump(afArenaCenterLoc[0], afArenaCenterLoc[1], afArenaCenterLoc[2], 45.55969f, 5.0f, 1); break; case SPELL_STORMHAMMER_OUTRO: DoScriptText(SAY_DEFEATED, m_creature); break; case SAY_OUTRO_HARD_1: DoCastSpellIfCan(m_creature, SPELL_STORMHAMMER_OUTRO); break; case SPELL_TELEPORT: case SPELL_THORIM_CREDIT: if (DoCastSpellIfCan(m_creature, SPELL_TELEPORT) == CAST_OK) m_creature->ForcedDespawn(2000); // despawn Sif if not despawned by accident if (Creature* pSif = m_pInstance->GetSingleCreatureFromStorage(NPC_SIF)) pSif->ForcedDespawn(); break; } }
// Function that will drain elders after aggro void DoDrainElders() { if (!m_pInstance) return; if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_BRIGHTLEAF)) { if (pElder->isAlive()) { pElder->CastSpell(pElder, SPELL_DRAINED_OF_POWER, true); pElder->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_IRONBRACH)) { if (pElder->isAlive()) { pElder->CastSpell(pElder, SPELL_DRAINED_OF_POWER, true); pElder->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_STONEBARK)) { if (pElder->isAlive()) { pElder->CastSpell(pElder, SPELL_DRAINED_OF_POWER, true); pElder->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } }
void JustReachedHome() override { if (m_pInstance) { m_pInstance->SetData(TYPE_FREYA, FAIL); // reset elders if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_BRIGHTLEAF)) { if (pElder->isAlive()) { pElder->AI()->EnterEvadeMode(); pElder->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_IRONBRACH)) { if (pElder->isAlive()) { pElder->AI()->EnterEvadeMode(); pElder->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_STONEBARK)) { if (pElder->isAlive()) { pElder->AI()->EnterEvadeMode(); pElder->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } } }
void ReceiveAIEvent(AIEventType eventType, Unit* /*pSender*/, Unit* pInvoker, uint32 /*uiMiscValue*/) override { // inform about the harpoon repair event if (eventType == AI_EVENT_CUSTOM_A) { DoMoveEngineersToHarpoon(); m_uiRepairHarpoonTimer = 20000; } // inform about a harpoon being shot if (eventType == AI_EVENT_CUSTOM_B) { ++m_uiHarpoonsUsed; // start grounded phase if (m_uiHarpoonsUsed == m_uiMaxHarpoons) { // use upgraded speed rate for FlyOrLand. This isn't supported by DB but it's confirmed to happen on retail uint32 uiSpeedRate = m_creature->GetSpeedRate(MOVE_RUN); m_creature->SetWalk(false); m_creature->SetSpeedRate(MOVE_RUN, SPEED_RATE_RAZORSCALE); m_creature->GetMotionMaster()->MoveFlyOrLand(1, afRazorscaleGroundPos[0], afRazorscaleGroundPos[1], afRazorscaleGroundPos[2], false); m_creature->SetSpeedRate(MOVE_RUN, uiSpeedRate); m_uiPhase = PHASE_TRANSITION; m_uiShackleTimer = 5000; // move the trappers around float fX, fY, fZ; uint8 uiIndex = 5; if (m_pInstance) { if (Creature* pController = m_pInstance->GetSingleCreatureFromStorage(NPC_RAZORSCALE_CONTROLLER)) { for (GuidList::const_iterator itr = m_lTrappersGuids.begin(); itr != m_lTrappersGuids.end(); ++itr) { if (Creature* pTrapper = m_creature->GetMap()->GetCreature(*itr)) { pController->GetNearPoint(pController, fX, fY, fZ, 0, 50.0f, M_PI_F / 4 * uiIndex); pTrapper->SetWalk(false); uiSpeedRate = pTrapper->GetSpeedRate(MOVE_RUN); pTrapper->SetSpeedRate(MOVE_RUN, SPEED_RATE_HELPERS); pTrapper->GetMotionMaster()->MovePoint(1, fX, fY, fZ); pTrapper->SetSpeedRate(MOVE_RUN, uiSpeedRate); ++uiIndex; } } } // yell that Razor is grounded if (Creature* pCommander = m_pInstance->GetSingleCreatureFromStorage(NPC_EXPEDITION_COMMANDER)) DoScriptText(SAY_GROUNDED, pCommander); } } } }
void Aggro(Unit* /*pWho*/) override { if (m_pInstance) { m_pInstance->SetData(TYPE_XT002, IN_PROGRESS); m_pInstance->SetData(TYPE_XT002_HARD, NOT_STARTED); } DoScriptText(SAY_AGGRO, m_creature); }
void Aggro(Unit* /*pWho*/) override { if (m_pInstance) { m_pInstance->SetData(TYPE_RAZORSCALE, IN_PROGRESS); // load engineers and harpoon data m_pInstance->GetEngineersGuids(m_lEngineersGuids); m_pInstance->GetTrappersGuids(m_lTrappersGuids); m_pInstance->GetHarpoonsGuids(m_vHarpoonsGuids); } }
// check for all elders alive void FetchElders() { if (!m_pInstance) return; uint8 uiEldersAlive = 0; if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_BRIGHTLEAF)) { if (pElder->isAlive()) { pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_BRIGHTLEAF_ESSENCE_CHANNEL : SPELL_BRIGHTLEAF_ESSENCE_CHANNEL_H, false, NULL, NULL, m_creature->GetObjectGuid()); pElder->CastSpell(pElder, SPELL_FULL_HEAL, true); m_uiUnstableEnergyTimer = 25000; ++uiEldersAlive; } } if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_IRONBRACH)) { if (pElder->isAlive()) { pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_IRONBRANCH_ESSENCE_CHANNEL : SPELL_IRONBRANCH_ESSENCE_CHANNEL_H, false, NULL, NULL, m_creature->GetObjectGuid()); pElder->CastSpell(pElder, SPELL_FULL_HEAL, true); m_uiIronRootsTimer = 60000; ++uiEldersAlive; } } if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_STONEBARK)) { if (pElder->isAlive()) { pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_STONEBARK_ESSEMCE_CHANNEL : SPELL_STONEBARK_ESSEMCE_CHANNEL_H, false, NULL, NULL, m_creature->GetObjectGuid()); pElder->CastSpell(pElder, SPELL_FULL_HEAL, true); m_uiGroundTremorTimer = 10000; ++uiEldersAlive; } } // store the info about the elders alive m_pInstance->SetData(TYPE_FREYA_HARD, uiEldersAlive); if (uiEldersAlive) { DoScriptText(SAY_AGGRO_HARD, m_creature); m_uiDrainEldersTimer = 5000; } else DoScriptText(SAY_AGGRO, m_creature); }
void MoveInLineOfSight(Unit* pWho) override { // spawn the arena npcs only when players are close to Thorim in order to avoid the possible bugs if (!m_bArenaSpawned && pWho->GetTypeId() == TYPEID_PLAYER && pWho->IsAlive() && !((Player*)pWho)->isGameMaster() && m_creature->IsWithinDistInMap(pWho, DEFAULT_VISIBILITY_INSTANCE)) { if (m_pInstance && m_pInstance->GetData(TYPE_THORIM) != DONE) m_pInstance->DoSpawnThorimNpcs((Player*)pWho); m_bArenaSpawned = true; } ScriptedAI::MoveInLineOfSight(pWho); }
void Aggro(Unit* /*pWho*/) override { if (m_pInstance) { m_pInstance->SetData(TYPE_HODIR, IN_PROGRESS); m_pInstance->SetData(TYPE_HODIR_HARD, DONE); } DoScriptText(SAY_AGGRO, m_creature); DoCastSpellIfCan(m_creature, SPELL_BITTING_COLD, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_ICICLE_AURA, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT); DoCastSpellIfCan(m_creature, SPELL_SHATTER_CHEST, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT); }
void Aggro(Unit* /*pWho*/) override { if (m_pInstance) { m_pInstance->SetData(TYPE_THORIM, IN_PROGRESS); m_pInstance->SetData(TYPE_THORIM_HARD, NOT_STARTED); m_pInstance->GetThunderOrbsGuids(m_lUpperOrbsGuids); m_pInstance->GetThorimBunniesGuids(m_lUpperBunniesGuids, true); m_pInstance->GetThorimBunniesGuids(m_lLowerBunniesGuids, false); } StartNextDialogueText(SAY_AGGRO_1); }
void SpellHit(Unit* /*pCaster*/, const SpellEntry* pSpell) override { // hard mode is failed; despawn Sif if (pSpell->Id == SPELL_TOUCH_OF_DOMINION_AURA && m_pInstance) { m_pInstance->SetData(TYPE_THORIM_HARD, FAIL); if (Creature* pSif = m_pInstance->GetSingleCreatureFromStorage(NPC_SIF)) { DoScriptText(SAY_SIF_DESPAWN, pSif); pSif->ForcedDespawn(5000); } } }
void SpellHit(Unit* /*pCaster*/, const SpellEntry* pSpell) override { // start runic smash event if (pSpell->Id == SPELL_RUNIC_SMASH_L && m_pInstance) { m_lCurrentSmashBunnies.clear(); m_pInstance->GetSmashTargetsGuids(m_lCurrentSmashBunnies, true); m_bSmashActive = true; } else if (pSpell->Id == SPELL_RUNIC_SMASH_R && m_pInstance) { m_lCurrentSmashBunnies.clear(); m_pInstance->GetSmashTargetsGuids(m_lCurrentSmashBunnies, false); m_bSmashActive = true; } }
void DamageTaken(Unit* pDoneBy, uint32& uiDamage) override { if (pDoneBy->GetEntry() == NPC_FREYA) return; if (uiDamage >= m_creature->GetHealth()) { uiDamage = 0; if (m_bIsFakeDeath) return; if (m_pInstance) { if (Creature* pFreya = m_pInstance->GetSingleCreatureFromStorage(NPC_FREYA)) SendAIEvent(AI_EVENT_CUSTOM_B, m_creature, pFreya); } DoCastSpellIfCan(m_creature, SPELL_CLEAR_DEBUFFS, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_FEIGN_DEATH, CAST_TRIGGERED); m_creature->SetHealth(1); m_creature->ClearComboPointHolders(); m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false); m_creature->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->ClearAllReactives(); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveIdle(); m_creature->SetStandState(UNIT_STAND_STATE_DEAD); DoScriptText(EMOTE_REGEN_ALLIES, m_creature); m_bIsFakeDeath = true; } }
void Aggro(Unit* /*pWho*/) override { if (m_pInstance) m_pInstance->SetData(TYPE_KOLOGARN, IN_PROGRESS); DoScriptText(SAY_AGGRO, m_creature); }
// function to return a random player from the arena Unit* GetRandomArenaPlayer() { if (!m_pInstance) return NULL; Creature* pTrigger = m_pInstance->GetSingleCreatureFromStorage(NPC_THORIM_COMBAT_TRIGGER); if (!pTrigger) return NULL; std::vector<Unit*> suitableTargets; ThreatList const& threatList = m_creature->GetThreatManager().getThreatList(); for (ThreatList::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) { if (Unit* pTarget = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid())) { if (pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->IsWithinDistInMap(pTrigger, 50.0f) && pTarget->IsWithinLOSInMap(pTrigger)) suitableTargets.push_back(pTarget); } } // if no player in the arena was found trigger berserk automatically if (suitableTargets.empty()) { m_uiBerserkTimer = 1000; m_uiStormHammerTimer = 60000; return NULL; } else return suitableTargets[urand(0, suitableTargets.size() - 1)]; }
void JustDied(Unit* /*pKiller*/) override { if (m_pInstance) m_pInstance->SetData(TYPE_XT002, DONE); DoScriptText(SAY_DEATH, m_creature); }
void UpdateAI(const uint32 /*uiDiff*/) override { // Flash Freeze npcs should be always be summoned if (!m_creature->IsTemporarySummon()) return; // do the freezing on the first update tick if (!m_bFreezeInit) { // Flash Freeze npc will always stun or kill the summoner if (m_creature->GetEntry() == NPC_FLASH_FREEZE_NPC) { if (DoCastSpellIfCan(m_creature, SPELL_FLASH_FREEZE_AURA_NPC) == CAST_OK) DoCastSpellIfCan(m_creature, SPELL_FLASH_FREEZE_INITIAL, CAST_TRIGGERED); } else if (m_creature->GetEntry() == NPC_FLASH_FREEZE) { if (Unit* pSummoner = m_creature->GetMap()->GetUnit(((TemporarySummon*)m_creature)->GetSummonerGuid())) { // kill frozen players if (pSummoner->HasAura(SPELL_FREEZE)) DoCastSpellIfCan(pSummoner, SPELL_FLASH_FREEZE_KILL); else DoCastSpellIfCan(m_creature, SPELL_FLASH_FREEZE_AURA); if (pSummoner->GetTypeId() == TYPEID_PLAYER && m_pInstance) m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_CHEESE_FREEZE, false); } } m_bFreezeInit = true; } }
void JustReachedHome() override { if (m_pInstance) m_pInstance->SetData(TYPE_RAZORSCALE, FAIL); m_creature->GetMotionMaster()->MoveRandomAroundPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 10.0f); }
void JustDidDialogueStep(int32 iEntry) override { if (!m_pInstance) { script_error_log("Instance Ulduar: ERROR Failed to load instance data for this instace."); return; } switch (iEntry) { case NPC_EXPEDITION_ENGINEER: { if (Creature* pEngineer = GetClosestCreatureWithEntry(m_creature, NPC_EXPEDITION_ENGINEER, 15.0f)) DoScriptText(SAY_INTRO_1, pEngineer); GuidList m_lDefenderGuids; m_pInstance->GetDefenderGuids(m_lDefenderGuids); // move the defenders into attack position for (GuidList::const_iterator itr = m_lDefenderGuids.begin(); itr != m_lDefenderGuids.end(); ++itr) { if (Creature* pDefender = m_creature->GetMap()->GetCreature(*itr)) { pDefender->CastSpell(pDefender, SPELL_THREAT, TRIGGERED_OLD_TRIGGERED); pDefender->SetWalk(false); pDefender->GetMotionMaster()->MoveWaypoint(); } } break; } case NPC_RAZORSCALE: if (Creature* pRazorscale = m_pInstance->GetSingleCreatureFromStorage(NPC_RAZORSCALE)) { if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid)) pRazorscale->AI()->AttackStart(pPlayer); } break; case NPC_EXPEDITION_DEFENDER: if (Creature* pEngineer = GetClosestCreatureWithEntry(m_creature, NPC_EXPEDITION_ENGINEER, 15.0f)) DoScriptText(SAY_INTRO_3, pEngineer); // inform Razorscale about the start of the harpoon event if (Creature* pRazorscale = m_pInstance->GetSingleCreatureFromStorage(NPC_RAZORSCALE)) m_creature->AI()->SendAIEvent(AI_EVENT_CUSTOM_A, m_creature, pRazorscale); break; } }
void SpellHitTarget(Unit* pTarget, SpellEntry const* pSpellEntry) override { if (pSpellEntry->Id == SPELL_LIGHTNING_CHARGE_DAMAGE && pTarget->GetTypeId() == TYPEID_PLAYER) { if (m_pInstance) m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_LIGHTNING, false); } }
void JustDied(Unit* /*pKiller*/) override { if (m_pInstance) m_pInstance->SetData(TYPE_IGNIS, DONE); DoCastSpellIfCan(m_creature, SPELL_KILL_ALL_CONSTRUCTS, CAST_TRIGGERED); DoScriptText(SAY_DEATH, m_creature); }
void JustDied(Unit* /*pKiller*/) override { // notify XT that hard mode is enabled if (m_pInstance) { if (Creature* pDeconstructor = m_pInstance->GetSingleCreatureFromStorage(NPC_XT002)) SendAIEvent(AI_EVENT_CUSTOM_B, m_creature, pDeconstructor); } }
void Aggro(Unit* /*pWho*/) override { if (m_pInstance) { // start the counter at the first aggro if (m_pInstance->GetData(TYPE_ALGALON) == SPECIAL) { m_pInstance->DoUpdateWorldState(WORLD_STATE_TIMER, 1); m_pInstance->SetData(TYPE_ALGALON_TIMER, 60); } m_pInstance->SetData(TYPE_ALGALON, IN_PROGRESS); } DoCastSpellIfCan(m_creature, SPELL_SUPERMASSIVE_FAIL, CAST_TRIGGERED); // Note: it's not clear wether these texts should be yelled on every aggro StartNextDialogueText(SAY_AGGRO); }
void JustDied(Unit* /*pKiller*/) override { if (m_pInstance) m_pInstance->SetData(TYPE_KOLOGARN, DONE); DoScriptText(SAY_DEATH, m_creature); DoCastSpellIfCan(m_creature, SPELL_INSTAKILL_KOLOGARN_ARM, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_INSTAKILL_KOLOGARN_ARM, CAST_TRIGGERED); }
void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage) override { // switch to phase 2 as soon as it's hit by any damage if (m_uiPhase == PHASE_ARENA && uiDamage > 0) { StartNextDialogueText(SAY_JUMP); m_uiPhase = PHASE_TRANSITION; // prepare the hard mode if necessary if (m_pInstance && m_pInstance->GetData(TYPE_THORIM_HARD) != FAIL) { if (Creature* pSif = m_pInstance->GetSingleCreatureFromStorage(NPC_SIF)) pSif->InterruptNonMeleeSpells(false); m_pInstance->SetData(TYPE_THORIM_HARD, DONE); } return; } // handle outro if (uiDamage >= m_creature->GetHealth()) { uiDamage = 0; if (!m_bEventFinished) { if (m_pInstance) { m_pInstance->SetData(TYPE_THORIM, DONE); // start a different outro version for hard mode if (m_pInstance->GetData(TYPE_THORIM_HARD) == DONE) StartNextDialogueText(SPELL_STORMHAMMER_OUTRO); else StartNextDialogueText(SAY_DEFEATED); } m_creature->CastSpell(m_creature, SPELL_THORIM_CREDIT, true); m_creature->setFaction(FACTION_ID_FRIENDLY); m_bEventFinished = true; EnterEvadeMode(); } } }
void JustSummoned(Creature* pSummoned) override { if (pSummoned->GetEntry() == NPC_RUBBLE && m_pInstance) { if (Creature* pKologarn = m_pInstance->GetSingleCreatureFromStorage(NPC_KOLOGARN)) SendAIEvent(AI_EVENT_CUSTOM_A, m_creature, pKologarn); pSummoned->SetInCombatWithZone(); } }
void JustReachedHome() override { if (m_pInstance) m_pInstance->SetData(TYPE_KOLOGARN, FAIL); // kill both hands - will be respawned m_creature->RemoveAllAuras(); DoCastSpellIfCan(m_creature, SPELL_INSTAKILL_KOLOGARN_ARM, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_INSTAKILL_KOLOGARN_ARM, CAST_TRIGGERED); }
void JustReachedHome() override { if (m_pInstance) { m_pInstance->SetData(TYPE_XT002, FAIL); // mount the Heart back at the right seat after wipe or respawn (respawn handled in DB) m_uiMountTimer = 1000; } }
void ReceiveAIEvent(AIEventType eventType, Unit* /*pSender*/, Unit* pInvoker, uint32 /*uiMiscValue*/) override { // count the summoned Rubble if (eventType == AI_EVENT_CUSTOM_A && pInvoker->GetEntry() == NPC_RUBBLE_STALKER) { ++m_uiRubbleCount; if (m_uiRubbleCount == MAX_ACHIEV_RUBBLE && m_pInstance) m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_RUBBLE, true); } }