void JustReachedHome() override { if (m_pInstance) { if (m_pInstance->GetData(TYPE_FACTION_CHAMPIONS) != FAIL) m_pInstance->SetData(TYPE_FACTION_CHAMPIONS, FAIL); } }
void Aggro(Unit* /*pWho*/) override { DoScriptText(SAY_AGGRO, m_creature); DoCastSpellIfCan(m_creature, SPELL_SURGE_OF_LIGHT); if (m_pInstance && m_pInstance->GetData(TYPE_TWIN_VALKYR) != IN_PROGRESS) m_pInstance->SetData(TYPE_TWIN_VALKYR, IN_PROGRESS); }
void JustDied(Unit* /*pKiller*/) override { DoScriptText(SAY_DEATH, m_creature); if (m_pInstance && m_pInstance->GetData(TYPE_TWIN_VALKYR) != DONE) m_pInstance->SetData(TYPE_TWIN_VALKYR, DONE); DoCastSpellIfCan(m_creature, SPELL_CLEAR_VALKYR_ESSENCE, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_CLEAR_VALKYR_TOUCH, CAST_TRIGGERED); }
void Aggro(Unit* pWho) override { if (m_pInstance) { if (m_pInstance->GetData(TYPE_FACTION_CHAMPIONS) != IN_PROGRESS) { m_pInstance->SetData(TYPE_FACTION_CHAMPIONS, IN_PROGRESS); m_pInstance->DoSetCrusadersInCombat(pWho); } } }
void EnterEvadeMode() override { if (m_pInstance && m_pInstance->GetData(TYPE_TWIN_VALKYR) != FAIL) m_pInstance->SetData(TYPE_TWIN_VALKYR, FAIL); DoCastSpellIfCan(m_creature, SPELL_CLEAR_VALKYR_ESSENCE, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_CLEAR_VALKYR_TOUCH, CAST_TRIGGERED); // cleanup handled by creature linking m_creature->ForcedDespawn(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiTwinSpikeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_TWIN_SPIKE_DARK) == CAST_OK) m_uiTwinSpikeTimer = 10000; } else m_uiTwinSpikeTimer -= uiDiff; // heroic abilities if (m_pInstance && m_pInstance->IsHeroicDifficulty()) { if (m_uiTouchTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_DARK_TOUCH) == CAST_OK) m_uiTouchTimer = 20000; } else m_uiTouchTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void JustSummoned(Creature* pSummoned) override { switch (pSummoned->GetEntry()) { case NPC_GORMOK: m_uiPhase = PHASE_GORMOK; break; case NPC_DREADSCALE: m_uiPhase = PHASE_WORMS; break; case NPC_ICEHOWL: m_uiPhase = PHASE_ICEHOWL; break; case NPC_ACIDMAW: // Cast emerge and delayed set in combat? pSummoned->SetInCombatWithZone(); m_aSummonedBossGuid[3] = pSummoned->GetObjectGuid(); return; } m_aSummonedBossGuid[m_uiPhase] = pSummoned->GetObjectGuid(); pSummoned->SetWalk(false); pSummoned->GetMotionMaster()->MovePoint(m_uiPhase, aMovePositions[m_uiPhase][0], aMovePositions[m_uiPhase][1], aMovePositions[m_uiPhase][2], false); // Next beasts are summoned only for heroic modes if (m_creature->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_HEROIC || m_creature->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC) m_uiNextBeastTimer = 150 * IN_MILLISECONDS; // 2 min 30 m_uiAttackDelayTimer = 10000; if (m_pInstance) m_pInstance->DoOpenMainGate(10000); }
void JustDied(Unit* /*pKiller*/) override { DoScriptText(SAY_DEATH, m_creature); if (m_pInstance) m_pInstance->SetData(TYPE_ANUBARAK, DONE); }
void KilledUnit(Unit* pVictim) override { if (!m_pInstance) return; Creature* pSpeaker = m_pInstance->GetSingleCreatureFromStorage(m_pInstance->GetPlayerTeam() == ALLIANCE ? NPC_GARROSH : NPC_VARIAN); if (!pSpeaker) return; switch (urand(0, 3)) { case 0: DoScriptText(m_pInstance->GetPlayerTeam() == ALLIANCE ? SAY_GARROSH_PVP_A_SLAY_1 : SAY_VARIAN_PVP_H_SLAY_1, pSpeaker); break; case 1: DoScriptText(m_pInstance->GetPlayerTeam() == ALLIANCE ? SAY_GARROSH_PVP_A_SLAY_2 : SAY_VARIAN_PVP_H_SLAY_2, pSpeaker); break; case 2: DoScriptText(m_pInstance->GetPlayerTeam() == ALLIANCE ? SAY_GARROSH_PVP_A_SLAY_3 : SAY_VARIAN_PVP_H_SLAY_3, pSpeaker); break; case 3: DoScriptText(m_pInstance->GetPlayerTeam() == ALLIANCE ? SAY_GARROSH_PVP_A_SLAY_4 : SAY_VARIAN_PVP_H_SLAY_4, pSpeaker); break; } }
// Only for Dreadscale and Icehowl void DoSummonNextBeast(uint32 uiBeastEntry) { if (uiBeastEntry == NPC_DREADSCALE) { if (Creature* pTirion = m_pInstance->GetSingleCreatureFromStorage(NPC_TIRION_A)) DoScriptText(SAY_TIRION_BEAST_2, pTirion); m_creature->SummonCreature(NPC_DREADSCALE, aSpawnPositions[2][0], aSpawnPositions[2][1], aSpawnPositions[2][2], aSpawnPositions[2][3], TEMPSUMMON_DEAD_DESPAWN, 0); } else { if (Creature* pTirion = m_pInstance->GetSingleCreatureFromStorage(NPC_TIRION_A)) DoScriptText(SAY_TIRION_BEAST_3, pTirion); m_creature->SummonCreature(NPC_ICEHOWL, aSpawnPositions[4][0], aSpawnPositions[4][1], aSpawnPositions[4][2], aSpawnPositions[4][3], TEMPSUMMON_DEAD_DESPAWN, 0); } }
void SummonedCreatureJustDied(Creature* pSummoned) override { if (!m_pInstance) return; switch (pSummoned->GetEntry()) { case NPC_GORMOK: if (m_uiPhase == PHASE_GORMOK) DoSummonNextBeast(NPC_DREADSCALE); break; case NPC_DREADSCALE: case NPC_ACIDMAW: if (m_bFirstWormDied && m_uiPhase == PHASE_WORMS) { DoSummonNextBeast(NPC_ICEHOWL); // cast achiev spell if timer is still running if (m_uiWormAchievTimer) { m_creature->CastSpell(m_creature, SPELL_JORMUNGAR_ACHIEV_CREDIT, TRIGGERED_OLD_TRIGGERED); m_uiWormAchievTimer = 0; } } else { m_bFirstWormDied = true; // jormungar brother enrages if (Creature* pWorm = m_pInstance->GetSingleCreatureFromStorage(pSummoned->GetEntry() == NPC_ACIDMAW ? NPC_DREADSCALE : NPC_ACIDMAW)) { pWorm->CastSpell(pWorm, SPELL_JORMUNGAR_ENRAGE, TRIGGERED_OLD_TRIGGERED); DoScriptText(EMOTE_JORMUNGAR_ENRAGE, pWorm); m_uiWormAchievTimer = 10000; } } break; case NPC_ICEHOWL: m_pInstance->SetData(TYPE_NORTHREND_BEASTS, DONE); m_creature->ForcedDespawn(); break; } }
void Aggro(Unit* /*pWho*/) override { // trigger the controller combat if (m_pInstance) { if (Creature* pStalker = m_pInstance->GetSingleCreatureFromStorage(NPC_BEASTS_COMBAT_STALKER)) pStalker->SetInCombatWithZone(); } }
void EnterEvadeMode() override { if (m_pInstance) m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL); for (uint8 i = 0; i < 4; ++i) { if (Creature* pBoss = m_creature->GetMap()->GetCreature(m_aSummonedBossGuid[i])) pBoss->ForcedDespawn(); } m_creature->ForcedDespawn(); }
void Reset() override { // get the list of summoned stalkers and move to a randome one if (m_pInstance) m_pInstance->GetStalkersGUIDVector(m_vStalkersGuids); if (m_vStalkersGuids.empty()) return; m_creature->SetWalk(false); if (Creature* pStalker = m_creature->GetMap()->GetCreature(m_vStalkersGuids[urand(0, m_vStalkersGuids.size() - 1)])) m_creature->GetMotionMaster()->MovePoint(1, pStalker->GetPositionX(), pStalker->GetPositionY(), pStalker->GetPositionZ()); }
void Reset() override { DoCastSpellIfCan(m_creature, SPELL_VALKYR_TWINS_HITTING_YA); m_uiTwinSpikeTimer = 7000; m_uiTouchTimer = 10000; m_uiSpecialAbilityTimer = 45000; m_uiSummonTimer = 25000; m_uiBerserkTimer = 8 * MINUTE * IN_MILLISECONDS; // always start with light twin pact m_bIsLightTwin = true; m_bIsVortex = false; if (m_pInstance && m_pInstance->IsHeroicDifficulty()) m_uiBerserkTimer = 6 * MINUTE * IN_MILLISECONDS; }
void Aggro(Unit* /*pWho*/) override { DoScriptText(SAY_AGGRO, m_creature); // Summon the spheres on random points for (uint8 i = 0; i < MAX_FROSTSPHERES; ++i) { if (Creature* pTemp = m_creature->SummonCreature(NPC_FROSTSPHERE, aFrostSphereSpawnPositions[i][0], aFrostSphereSpawnPositions[i][1], aFrostSphereSpawnPositions[i][2], 0, TEMPSUMMON_DEAD_DESPAWN, 0)) m_vSpheresGuidVector[i] = pTemp->GetObjectGuid(); } // It's not clear if these should be spawned by DB or summoned for (uint8 i = 0; i < MAX_BURROWS; ++i) m_creature->SummonCreature(NPC_BURROW, aBurrowSpawnPositions[i][0], aBurrowSpawnPositions[i][1], aBurrowSpawnPositions[i][2], aBurrowSpawnPositions[i][3], TEMPSUMMON_DEAD_DESPAWN, 0); if (m_pInstance) m_pInstance->SetData(TYPE_ANUBARAK, IN_PROGRESS); }
// function that handles the special ability for both twins bool DoCastSpecialAbility() { if (!m_pInstance) return false; // choose the caster; it always alternates Unit* pCaster = NULL; uint32 uiSpell = 0; uint32 uiShieldSpell = 0; if (m_bIsLightTwin) pCaster = m_creature; else { Creature* pEydis = m_pInstance->GetSingleCreatureFromStorage(NPC_EYDIS); if (!pEydis) return false; pCaster = pEydis; } if (!pCaster) return false; // select and cast ability if (m_bIsVortex) { uiSpell = m_bIsLightTwin ? SPELL_LIGHT_VORTEX : SPELL_DARK_VORTEX; pCaster->CastSpell(pCaster, uiSpell, TRIGGERED_NONE); DoScriptText(m_bIsLightTwin ? SAY_TO_WHITE : SAY_TO_BLACK, pCaster); } else { uiSpell = m_bIsLightTwin ? SPELL_TWINS_PACT_LIGHT : SPELL_TWINS_PACT_DARK; uiShieldSpell = m_bIsLightTwin ? SPELL_SHIELD_OF_LIGHTS : SPELL_SHIELD_OF_DARKNESS; pCaster->CastSpell(pCaster, uiSpell, TRIGGERED_NONE); pCaster->CastSpell(pCaster, uiShieldSpell, TRIGGERED_OLD_TRIGGERED); DoScriptText(SAY_COLORSWITCH, pCaster); } m_bIsVortex = urand(0, 1) ? true : false; m_bIsLightTwin = !m_bIsLightTwin; return true; }
void SpellHit(Unit* /*pCaster*/, const SpellEntry* pSpell) override { if (pSpell->Id == SPELL_SUBMERGE) { m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Extra check here, because AnubArak must be submerged by default if (m_Phase != PHASE_SUBMERGING) return; m_Phase = PHASE_UNDERGROUND; // Refresh spheres only on normal difficulty if (m_pInstance && !m_pInstance->IsHeroicDifficulty()) DoRefreshSpheres(); DoCastSpellIfCan(m_creature, SPELL_CLEAR_ALL_DEBUFFS, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_SUMMON_SPIKES, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_SUMMON_SCARAB, CAST_TRIGGERED); } }
void UpdateAI(const uint32 uiDiff) override { if (m_uiNextBeastTimer) { if (m_uiNextBeastTimer <= uiDiff) { if (m_uiPhase == PHASE_GORMOK) DoSummonNextBeast(NPC_DREADSCALE); else if (m_uiPhase == PHASE_WORMS) DoSummonNextBeast(NPC_ICEHOWL); m_uiNextBeastTimer = 0; } else m_uiNextBeastTimer -= uiDiff; } if (m_uiAttackDelayTimer) { if (m_uiAttackDelayTimer <= uiDiff) { // for worm phase, summon brother on aggro if (m_uiPhase == PHASE_WORMS) { m_creature->SummonCreature(NPC_ACIDMAW, aSpawnPositions[3][0], aSpawnPositions[3][1], aSpawnPositions[3][2], aSpawnPositions[3][3], TEMPSUMMON_DEAD_DESPAWN, 0); m_uiWormPhaseTimer = 45000; } // start combat if (Creature* pBeast = m_creature->GetMap()->GetCreature(m_aSummonedBossGuid[m_uiPhase])) { pBeast->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); // first boss doesn't automatically attack if (pBeast->GetEntry() != NPC_GORMOK) pBeast->SetInCombatWithZone(); } m_uiAttackDelayTimer = 0; } else m_uiAttackDelayTimer -= uiDiff; } if (m_uiBerserkTimer) { if (m_uiBerserkTimer < uiDiff) { for (uint8 i = 0; i < 4; ++i) { Creature* pBoss = m_creature->GetMap()->GetCreature(m_aSummonedBossGuid[i]); if (pBoss && pBoss->isAlive()) pBoss->CastSpell(pBoss, SPELL_BERSERK, TRIGGERED_OLD_TRIGGERED); } } else m_uiBerserkTimer -= uiDiff; } // jormungars phase switch control if (m_uiWormPhaseTimer) { if (m_uiWormPhaseTimer <= uiDiff) { if (!m_pInstance) return; ++m_uiWormPhaseStage; switch (m_uiWormPhaseStage) { // submerge worms case 1: if (Creature* pWorm = m_pInstance->GetSingleCreatureFromStorage(NPC_ACIDMAW)) { if (pWorm->isAlive()) SendAIEvent(AI_EVENT_CUSTOM_A, m_creature, pWorm); } if (Creature* pWorm = m_pInstance->GetSingleCreatureFromStorage(NPC_DREADSCALE)) { if (pWorm->isAlive()) SendAIEvent(AI_EVENT_CUSTOM_A, m_creature, pWorm); } m_uiWormPhaseTimer = 4000; break; // change places case 2: float fX, fY, fZ; if (Creature* pWorm = m_pInstance->GetSingleCreatureFromStorage(NPC_ACIDMAW)) { if (pWorm->isAlive()) { m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 45.0f, fX, fY, fZ); pWorm->MonsterMoveWithSpeed(fX, fY, fZ, 7.7f); } } if (Creature* pWorm = m_pInstance->GetSingleCreatureFromStorage(NPC_DREADSCALE)) { if (pWorm->isAlive()) { m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 45.0f, fX, fY, fZ); pWorm->MonsterMoveWithSpeed(fX, fY, fZ, 7.7f); } } m_uiWormPhaseTimer = 6000; break; // emerge and change phase case 3: if (Creature* pWorm = m_pInstance->GetSingleCreatureFromStorage(NPC_ACIDMAW)) { if (pWorm->isAlive()) SendAIEvent(AI_EVENT_CUSTOM_B, m_creature, pWorm); } if (Creature* pWorm = m_pInstance->GetSingleCreatureFromStorage(NPC_DREADSCALE)) { if (pWorm->isAlive()) SendAIEvent(AI_EVENT_CUSTOM_B, m_creature, pWorm); } m_uiWormPhaseStage = 0; m_uiWormPhaseTimer = 45000; break; } } else m_uiWormPhaseTimer -= uiDiff; } // jormungars achiev timer if (m_uiWormAchievTimer) { if (m_uiWormAchievTimer <= uiDiff) m_uiWormAchievTimer = 0; else m_uiWormAchievTimer -= uiDiff; } m_creature->SelectHostileTarget(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // special ability spell if (m_uiSpecialAbilityTimer < uiDiff) { if (DoCastSpecialAbility()) m_uiSpecialAbilityTimer = 45000; } else m_uiSpecialAbilityTimer -= uiDiff; if (m_uiSummonTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_LIGHT_BULLET_SUMMON_TRIGGER, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_DARK_BULLET_SUMMON_TRIGGER, CAST_TRIGGERED); m_uiSummonTimer = 30000; } else m_uiSummonTimer -= uiDiff; // berserk spell if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { // handle berserk for both twins if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { if (m_pInstance) { if (Creature* pEydis = m_pInstance->GetSingleCreatureFromStorage(NPC_EYDIS)) { pEydis->CastSpell(pEydis, SPELL_BERSERK, TRIGGERED_OLD_TRIGGERED); DoScriptText(SAY_BERSERK, pEydis); } } DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 0; } } else m_uiBerserkTimer -= uiDiff; } if (m_uiTwinSpikeTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_TWIN_SPIKE_LIGHT) == CAST_OK) m_uiTwinSpikeTimer = 10000; } else m_uiTwinSpikeTimer -= uiDiff; // heroic abilities if (m_pInstance && m_pInstance->IsHeroicDifficulty()) { if (m_uiTouchTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_LIGHT_TOUCH) == CAST_OK) m_uiTouchTimer = 20000; } else m_uiTouchTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_bIsFuriousCharge) { if (m_uiFuriosChargeTimer < uiDiff) { switch (m_uiFuriousChargeStage) { case 0: // pick a target if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, uint32(0), SELECT_FLAG_PLAYER | SELECT_FLAG_IN_LOS)) { DoScriptText(EMOTE_MASSIVE_CRASH, m_creature, pTarget); m_creature->SummonCreature(NPC_FURIOUS_CHARGE_STALKER, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 35000); } // apply surge of adrenaline if (m_pInstance && !m_pInstance->IsHeroicDifficulty()) DoApplySurgeOfAdrenaline(); m_uiFuriosChargeTimer = 1000; break; case 1: // roar at target if (Creature* pTarget = m_creature->GetMap()->GetCreature(m_chargeStalkerGuid)) DoCastSpellIfCan(pTarget, SPELL_ROAR); m_uiFuriosChargeTimer = 2000; break; case 2: // jump back and prepare to charge if (Creature* pTarget = m_creature->GetMap()->GetCreature(m_chargeStalkerGuid)) DoCastSpellIfCan(pTarget, SPELL_JUMP_BACK); m_uiFuriosChargeTimer = 2000; break; case 3: // charge to the target m_creature->SetSpeedRate(MOVE_RUN, m_fSpeedRate * 4); if (Creature* pTarget = m_creature->GetMap()->GetCreature(m_chargeStalkerGuid)) m_creature->GetMotionMaster()->MovePoint(POINT_ID_CHARGE_END, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ()); m_uiFuriosChargeTimer = 99999; break; } ++m_uiFuriousChargeStage; } else m_uiFuriosChargeTimer -= uiDiff; // no other actions during charge return; } if (m_uiMassiveCrashTimer < uiDiff) { SetCombatMovement(false); m_creature->InterruptNonMeleeSpells(false); m_creature->GetMotionMaster()->Clear(); m_creature->GetMotionMaster()->MoveJump(aSpawnPositions[0][0], aSpawnPositions[0][1], aSpawnPositions[1][2], 2 * m_creature->GetSpeed(MOVE_RUN), 10.0f, POINT_ID_CHARGE_BEGIN); m_bIsFuriousCharge = true; m_uiFuriousChargeStage = 0; m_uiFuriosChargeTimer = 99999; m_uiMassiveCrashTimer = urand(40000, 45000); } else m_uiMassiveCrashTimer -= uiDiff; if (m_uiWhirlTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_WHIRL) == CAST_OK) m_uiWhirlTimer = urand(15000, 20000); } else m_uiWhirlTimer -= uiDiff; if (m_uiArticBreathTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_ARCTIC_BREATH) == CAST_OK) m_uiArticBreathTimer = urand(25000, 30000); } else m_uiArticBreathTimer -= uiDiff; if (m_uiFerociousButtTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FEROCIOUS_BUTT) == CAST_OK) m_uiFerociousButtTimer = 15000; } else m_uiFerociousButtTimer -= uiDiff; DoMeleeAttackIfReady(); }
void Aggro(Unit* /*pWho*/) override { if (m_pInstance) m_pInstance->SetData(TYPE_NORTHREND_BEASTS, IN_PROGRESS); }
void JustReachedHome() override { if (m_pInstance) m_pInstance->SetData(TYPE_ANUBARAK, FAIL); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; // Call specific virtual function if (!UpdateCrusaderAI(uiDiff)) return; if (m_uiAbilityTimer < uiDiff) { uint8 uiIndex = urand(0, m_uiMaxAbilities - 1); uint32 uiMinHealth = m_pAbilityArray[uiIndex].m_uiMinHealth; uint8 uiTargetType = m_pAbilityArray[uiIndex].m_uiTargetType; SelectFlags spellSelectFlag = m_pAbilityArray[uiIndex].m_selectFlag; // check timers and health condition // only cast spells that have timers expired // also check for health percentage for self cast spells if (m_uiSpellTimer[uiIndex] || (uiTargetType == TARGET_TYPE_SELF && uiMinHealth && m_creature->GetHealthPercent() > uiMinHealth)) { m_uiAbilityTimer = 2000; return; } else { uint32 uiSpellId = m_pAbilityArray[uiIndex].m_uiSpellId; // special case for heroism / bloodlust if (uiSpellId == SPELL_HEROISM && m_pInstance && m_pInstance->GetPlayerTeam() == ALLIANCE) uiSpellId = SPELL_BLOODLUST; if (CanUseSpecialAbility(uiSpellId, uiTargetType, spellSelectFlag, uiMinHealth)) { m_uiSpellTimer[uiIndex] = m_pAbilityArray[uiIndex].m_uiCooldown; m_uiAbilityTimer = urand(2000, 6000); } else m_uiAbilityTimer = 2000; } } else m_uiAbilityTimer -= uiDiff; // spell cooldown for (uint8 i = 0; i < m_uiMaxAbilities; ++i) { if (m_uiSpellTimer[i]) { if (m_uiSpellTimer[i] <= uiDiff) m_uiSpellTimer[i] = 0; else m_uiSpellTimer[i] -= uiDiff; } } // Change target if (m_uiResetThreatTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1)) { DoResetThreat(); AttackStart(pTarget); m_uiResetThreatTimer = urand(5000, 15000); } } else m_uiResetThreatTimer -= uiDiff; // CC check for PVP trinket if (m_uiIsCCTimer < uiDiff) { if (m_creature->isFrozen() || m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT)) { // Pvp trinket only in heroic mode if (m_pInstance && m_pInstance->IsHeroicDifficulty() && !m_uiTrinketCooldownTimer) { if (DoCastSpellIfCan(m_creature, SPELL_PVP_TRINKET, CAST_TRIGGERED) == CAST_OK) m_uiTrinketCooldownTimer = 120000; } SendAIEventAround(AI_EVENT_GOT_CCED, NULL, 0, CRUSADER_AIEVENT_THROW_RADIUS); SendAIEvent(AI_EVENT_GOT_CCED, NULL, m_creature); m_uiIsCCTimer = 5000; } else m_uiIsCCTimer = 2000; } else m_uiIsCCTimer -= uiDiff; // trinket cooldown if (m_uiTrinketCooldownTimer) { if (m_uiTrinketCooldownTimer <= uiDiff) m_uiTrinketCooldownTimer = 0; else m_uiTrinketCooldownTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 uiDiff) override { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; switch (m_Phase) { case PHASE_GROUND: // Switch to underground phase on timer if (m_PhaseSwitchTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_SUBMERGE) == CAST_OK) { DoScriptText(SAY_SUBMERGE, m_creature); DoScriptText(EMOTE_BURROW, m_creature); m_PhaseSwitchTimer = 63000; m_Phase = PHASE_SUBMERGING; return; } } else m_PhaseSwitchTimer -= uiDiff; // Switch to phase 3 when below 30% if (m_creature->GetHealthPercent() <= 30.0f) { if (DoCastSpellIfCan(m_creature, SPELL_LEECHING_SWARM) == CAST_OK) { DoScriptText(SAY_LEECHING_SWARM, m_creature); DoScriptText(EMOTE_LEECHING_SWARM, m_creature); m_Phase = PHASE_LEECHING_SWARM; } } // No break - the spells are used in both phase 1 and 3 case PHASE_LEECHING_SWARM: if (m_uiFreezingSlashTimer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_FREEZING_SLASH) == CAST_OK) m_uiFreezingSlashTimer = 20000; } else m_uiFreezingSlashTimer -= uiDiff; if (m_uiPenetratingColdTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_PENETRATING_COLD) == CAST_OK) m_uiPenetratingColdTimer = 15000; } else m_uiPenetratingColdTimer -= uiDiff; // The Borrowers are summoned in Ground phase only on normal mode or during Ground and Swarm phase on heroic mode if (m_Phase == PHASE_GROUND || (m_pInstance && m_pInstance->IsHeroicDifficulty())) { if (m_uiBurrowerSummonTimer < uiDiff) { // The number of targets is handled in core, based on difficulty if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_NERUBIAN_BURROWER) == CAST_OK) m_uiBurrowerSummonTimer = 45000; } else m_uiBurrowerSummonTimer -= uiDiff; } DoMeleeAttackIfReady(); break; case PHASE_UNDERGROUND: // Underground phase is finished if (m_PhaseSwitchTimer < uiDiff) { DoCastSpellIfCan(m_creature, SPELL_EMERGE, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_TELEPORT_TO_SPIKE, CAST_TRIGGERED); DoScriptText(EMOTE_EMERGE, m_creature); DoDespawnPursuingSpikes(); m_creature->RemoveAurasDueToSpell(SPELL_SUBMERGE); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Refresh spheres only on normal difficulty if (m_pInstance && !m_pInstance->IsHeroicDifficulty()) DoRefreshSpheres(); m_PhaseSwitchTimer = 80000; m_Phase = PHASE_GROUND; } else m_PhaseSwitchTimer -= uiDiff; break; case PHASE_SUBMERGING: // Do nothing, but continue berserk timer break; } if (m_uiBerserkTimer) { if (m_uiBerserkTimer <= uiDiff) { if (m_Phase != PHASE_UNDERGROUND) { if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK) { DoScriptText(SAY_BERSERK, m_creature); m_uiBerserkTimer = 0; } } } else m_uiBerserkTimer -= uiDiff; } }