diff options
Diffstat (limited to 'src/server/scripts')
53 files changed, 3910 insertions, 368 deletions
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp index d74c075b05a..0a8a4a88191 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp @@ -244,22 +244,22 @@ public: std::list<HostileReference*> threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) { - Unit* pUnit; + Unit* unit; if ((*i) && (*i)->getSource()) { - pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit) + unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit) { //Cast affliction - DoCast(pUnit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, + DoCast(unit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN), true); //Chromatic mutation if target is effected by all afflictions - if (pUnit->HasAura(SPELL_BROODAF_BLUE) - && pUnit->HasAura(SPELL_BROODAF_BLACK) - && pUnit->HasAura(SPELL_BROODAF_RED) - && pUnit->HasAura(SPELL_BROODAF_BRONZE) - && pUnit->HasAura(SPELL_BROODAF_GREEN)) + if (unit->HasAura(SPELL_BROODAF_BLUE) + && unit->HasAura(SPELL_BROODAF_BLACK) + && unit->HasAura(SPELL_BROODAF_RED) + && unit->HasAura(SPELL_BROODAF_BRONZE) + && unit->HasAura(SPELL_BROODAF_GREEN)) { //pTarget->RemoveAllAuras(); //DoCast(target, SPELL_CHROMATIC_MUT_1); @@ -269,8 +269,8 @@ public: //So instead we instant kill our target //WORKAROUND - if (pUnit->GetTypeId() == TYPEID_PLAYER) - pUnit->CastSpell(pUnit, 5, false); + if (unit->GetTypeId() == TYPEID_PLAYER) + unit->CastSpell(unit, 5, false); } } } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp index 596dfa9c25f..e804d2b2b61 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp @@ -141,8 +141,8 @@ public: { if (Phase == 2) { - if (Unit* pUnit = Unit::GetUnit(*me, Attumen)) - DoScriptText(SAY_MIDNIGHT_KILL, pUnit); + if (Unit* unit = Unit::GetUnit(*me, Attumen)) + DoScriptText(SAY_MIDNIGHT_KILL, unit); } } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp index 04981669681..98e40acc4e1 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp @@ -359,9 +359,9 @@ struct boss_moroes_guestAI : public ScriptedAI uint64 TempGUID = GuestGUID[rand()%4]; if (TempGUID) { - Unit* pUnit = Unit::GetUnit((*me), TempGUID); - if (pUnit && pUnit->isAlive()) - return pUnit; + Unit* unit = Unit::GetUnit((*me), TempGUID); + if (unit && unit->isAlive()) + return unit; } return me; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp index 51085504f99..e13ef8f62e1 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp @@ -424,10 +424,10 @@ public: for (uint32 i = 0; i < 4; ++i) { - if (Creature* pUnit = me->SummonCreature(CREATURE_WATER_ELEMENTAL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000)) + if (Creature* unit = me->SummonCreature(CREATURE_WATER_ELEMENTAL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000)) { - pUnit->Attack(me->getVictim(), true); - pUnit->setFaction(me->getFaction()); + unit->Attack(me->getVictim(), true); + unit->setFaction(me->getFaction()); } } @@ -438,10 +438,10 @@ public: { for (uint32 i = 0; i < 5; ++i) { - if (Creature* pUnit = me->SummonCreature(CREATURE_SHADOW_OF_ARAN, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) + if (Creature* unit = me->SummonCreature(CREATURE_SHADOW_OF_ARAN, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000)) { - pUnit->Attack(me->getVictim(), true); - pUnit->setFaction(me->getFaction()); + unit->Attack(me->getVictim(), true); + unit->setFaction(me->getFaction()); } } @@ -464,11 +464,11 @@ public: if (!FlameWreathTarget[i]) continue; - Unit* pUnit = Unit::GetUnit(*me, FlameWreathTarget[i]); - if (pUnit && !pUnit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3)) + Unit* unit = Unit::GetUnit(*me, FlameWreathTarget[i]); + if (unit && !unit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3)) { - pUnit->CastSpell(pUnit, 20476, true, 0, 0, me->GetGUID()); - pUnit->CastSpell(pUnit, 11027, true); + unit->CastSpell(unit, 20476, true, 0, 0, me->GetGUID()); + unit->CastSpell(unit, 11027, true); FlameWreathTarget[i] = 0; } } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index b3f06bdf2c7..6802d1817a3 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -193,11 +193,11 @@ public: std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i != m_threatlist.end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && pUnit->isAlive()) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && unit->isAlive()) { - float threat = me->getThreatManager().getThreat(pUnit); - SummonedUnit->AddThreat(pUnit, threat); + float threat = me->getThreatManager().getThreat(unit); + SummonedUnit->AddThreat(unit, threat); } } } @@ -211,9 +211,9 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) - pUnit->CastSpell(pUnit, SPELL_TELEPORT_CENTER, true); + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) + unit->CastSpell(unit, SPELL_TELEPORT_CENTER, true); } DoCast(me, SPELL_TELEPORT_CENTER, true); } @@ -223,10 +223,10 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) // Knockback into the air - pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, me->GetGUID()); + unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_DOT, true, 0, 0, me->GetGUID()); } } @@ -235,17 +235,17 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { // Also needs an exception in spell system. - pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, me->GetGUID()); + unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, me->GetGUID()); // Use packet hack WorldPacket data(12); data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); - data.append(pUnit->GetPackGUID()); + data.append(unit->GetPackGUID()); data << uint32(0); - pUnit->SendMessageToSet(&data, true); + unit->SendMessageToSet(&data, true); } } } @@ -255,17 +255,17 @@ public: std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { - pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY); - pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT); + unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY); + unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT); WorldPacket data(12); data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); - data.append(pUnit->GetPackGUID()); + data.append(unit->GetPackGUID()); data << uint32(0); - pUnit->SendMessageToSet(&data, true); + unit->SendMessageToSet(&data, true); } } } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index f54883daf56..ae7d7aba9f1 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -527,12 +527,12 @@ public: { DoCast(me, SPELL_VANISH); - Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0); + Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0); DoResetThreat(); - if (pUnit) - me->AddThreat(pUnit, 1000.0f); + if (unit) + me->AddThreat(unit, 1000.0f); InVanish = true; Vanish_Timer = 30000; @@ -644,24 +644,24 @@ public: if (Seed_of_Corruption_Timer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_SEED_OF_CORRUPTION); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_SEED_OF_CORRUPTION); Seed_of_Corruption_Timer = 10000; } else Seed_of_Corruption_Timer -= diff; if (Curse_of_Agony_Timer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_CURSE_OF_AGONY); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_CURSE_OF_AGONY); Curse_of_Agony_Timer = 13000; } else Curse_of_Agony_Timer -= diff; if (Fear_Timer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_FEAR); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_FEAR); Fear_Timer = 10000; } else Fear_Timer -= diff; @@ -806,8 +806,8 @@ public: if (Blizzard_Timer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_BLIZZARD); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_BLIZZARD); Blizzard_Timer = 8000; } else Blizzard_Timer -= diff; @@ -937,8 +937,8 @@ public: //if nobody is in melee range than try to use Intercept if (!InMeleeRange) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_INTERCEPT_STUN); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_INTERCEPT_STUN); } Intercept_Stun_Timer = 10000; @@ -1168,8 +1168,8 @@ public: if (Purge_Timer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_PURGE); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_PURGE); Purge_Timer = 15000; } else Purge_Timer -= diff; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp index 8b68330717f..35269bb296d 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp @@ -103,15 +103,15 @@ public: //for (uint8 i = 0; i < CRYSTALS_NUMBER; ++i) for (std::list<uint64>::const_iterator itr = Crystals.begin(); itr != Crystals.end(); ++itr) { - //Unit* pUnit = Unit::GetUnit(*me, FelCrystals[i]); - Unit* pUnit = Unit::GetUnit(*me, *itr); - if (pUnit) + //Unit* unit = Unit::GetUnit(*me, FelCrystals[i]); + Unit* unit = Unit::GetUnit(*me, *itr); + if (unit) { - if (!pUnit->isAlive()) - CAST_CRE(pUnit)->Respawn(); // Let the core handle setting death state, etc. + if (!unit->isAlive()) + CAST_CRE(unit)->Respawn(); // Let the core handle setting death state, etc. // Only need to set unselectable flag. You can't attack unselectable units so non_attackable flag is not necessary here. - pUnit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + unit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index e255cc52871..9a3913cb7dd 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -478,8 +478,8 @@ public: { me->setFaction(FACTION_HOSTILE); - if (Unit* pUnit = Unit::GetUnit(*me, m_uiDuelerGUID)) - AttackStart(pUnit); + if (Unit* unit = Unit::GetUnit(*me, m_uiDuelerGUID)) + AttackStart(unit); } else m_uiDuelTimer -= uiDiff; diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index f321e75caac..9296bd09bbc 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -569,9 +569,9 @@ public: std::list<HostileReference*>::const_iterator itr; for (itr = caster->getThreatManager().getThreatList().begin(); itr != caster->getThreatManager().getThreatList().end(); ++itr) { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit && pUnit->isAlive() && pUnit != caster) - me->AddThreat(pUnit, caster->getThreatManager().getThreat(pUnit)); + Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (unit && unit->isAlive() && unit != caster) + me->AddThreat(unit, caster->getThreatManager().getThreat(unit)); } } } diff --git a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp index 71b5a42a6b2..2f8d333735f 100644 --- a/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp +++ b/src/server/scripts/EasternKingdoms/Stratholme/stratholme.cpp @@ -53,9 +53,9 @@ public: if (pInstance->GetData(TYPE_BARON_RUN) != NOT_STARTED) return false; - if (Group* pGroup = player->GetGroup()) + if (Group* group = player->GetGroup()) { - for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pGroupie = itr->getSource(); if (!pGroupie) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index 8f15878f888..df20eab39de 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -760,11 +760,11 @@ public: { for (std::list<HostileReference*>::const_iterator itr = me->getThreatManager().getThreatList().begin(); itr != me->getThreatManager().getThreatList().end(); ++itr) { - if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) { - if (pUnit->GetPositionZ() > me->GetPositionZ()+5) + if (unit->GetPositionZ() > me->GetPositionZ()+5) { - me->getThreatManager().modifyThreatPercent(pUnit, -100); + me->getThreatManager().modifyThreatPercent(unit, -100); } } } diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 47704b42d5a..e81d4975378 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -994,9 +994,9 @@ public: std::list<HostileReference*>::iterator itr; for (itr = me->getThreatManager().getThreatList().begin(); itr != me->getThreatManager().getThreatList().end(); ++itr) { - Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (pUnit) - pPortal->AddThreat(pUnit, 1.0f); + Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()); + if (unit) + pPortal->AddThreat(unit, 1.0f); } } FelfirePortalTimer = 20000; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index 7f7a85b881f..6135c076920 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -160,23 +160,23 @@ class boss_mandokir : public CreatureScript { if (WatchTarget) //If someone is watched and If the Position of the watched target is different from the one stored, or are attacking, mandokir will charge him { - Unit* pUnit = Unit::GetUnit(*me, WatchTarget); + Unit* unit = Unit::GetUnit(*me, WatchTarget); - if (pUnit && ( - targetX != pUnit->GetPositionX() || - targetY != pUnit->GetPositionY() || - targetZ != pUnit->GetPositionZ() || - pUnit->isInCombat())) + if (unit && ( + targetX != unit->GetPositionX() || + targetY != unit->GetPositionY() || + targetZ != unit->GetPositionZ() || + unit->isInCombat())) { - if (me->IsWithinMeleeRange(pUnit)) + if (me->IsWithinMeleeRange(unit)) { - DoCast(pUnit, 24316); + DoCast(unit, 24316); } else { - DoCast(pUnit, SPELL_CHARGE); - //me->SendMonsterMove(pUnit->GetPositionX(), pUnit->GetPositionY(), pUnit->GetPositionZ(), 0, true, 1); - AttackStart(pUnit); + DoCast(unit, SPELL_CHARGE); + //me->SendMonsterMove(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 0, true, 1); + AttackStart(unit); } } } @@ -198,12 +198,12 @@ class boss_mandokir : public CreatureScript if ((Watch_Timer < 1000) && endWatch) //1 sec before the debuf expire, store the target position { - Unit* pUnit = Unit::GetUnit(*me, WatchTarget); - if (pUnit) + Unit* unit = Unit::GetUnit(*me, WatchTarget); + if (unit) { - targetX = pUnit->GetPositionX(); - targetY = pUnit->GetPositionY(); - targetZ = pUnit->GetPositionZ(); + targetX = unit->GetPositionX(); + targetY = unit->GetPositionY(); + targetZ = unit->GetPositionZ(); } endWatch = false; } @@ -232,8 +232,8 @@ class boss_mandokir : public CreatureScript std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { - Unit* pUnit = Unit::GetUnit(*me, (*i)->getUnitGuid()); - if (pUnit && me->IsWithinMeleeRange(pUnit)) + Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); + if (unit && me->IsWithinMeleeRange(unit)) ++TargetInRange; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index a7e5f51da98..da316cb91c7 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -358,9 +358,9 @@ public: std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); for (; itr != m_threatlist.end(); ++itr) { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit && pUnit->isAlive()) - targets.push_back(pUnit); + Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (unit && unit->isAlive()) + targets.push_back(unit); } if (targets.empty()) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index 0754e4a1554..385e86e5069 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -714,9 +714,9 @@ void hyjalAI::DeSpawnVeins() return; if (Faction == 1) { - Creature* pUnit=Unit::GetCreature((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); - if (!pUnit)return; - hyjalAI* ai = CAST_AI(hyjalAI, pUnit->AI()); + Creature* unit=Unit::GetCreature((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE)); + if (!unit)return; + hyjalAI* ai = CAST_AI(hyjalAI, unit->AI()); if (!ai)return; for (uint8 i = 0; i<7; ++i) { @@ -725,9 +725,9 @@ void hyjalAI::DeSpawnVeins() } } else if (Faction) { - Creature* pUnit=Unit::GetCreature((*me), pInstance->GetData64(DATA_THRALL)); - if (!pUnit)return; - hyjalAI* ai = CAST_AI(hyjalAI, pUnit->AI()); + Creature* unit=Unit::GetCreature((*me), pInstance->GetData64(DATA_THRALL)); + if (!unit)return; + hyjalAI* ai = CAST_AI(hyjalAI, unit->AI()); if (!ai)return; for (uint8 i = 7; i<14; ++i) { @@ -853,8 +853,8 @@ void hyjalAI::UpdateAI(const uint32 diff) { if (BossGUID[i]) { - Unit* pUnit = Unit::GetUnit((*me), BossGUID[i]); - if (pUnit && (!pUnit->isAlive())) + Unit* unit = Unit::GetUnit((*me), BossGUID[i]); + if (unit && (!unit->isAlive())) { if (BossGUID[i] == BossGUID[0]) { @@ -1080,37 +1080,37 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls { uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(GHOUL, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) + Creature* unit = me->SummonCreature(GHOUL, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (unit) { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); + CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + unit->setActive(true); } } for (uint8 i = 0; i < 3; ++i)//summon 3 abominations { uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(ABOMINATION, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) + Creature* unit = me->SummonCreature(ABOMINATION, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (unit) { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); + CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + unit->setActive(true); } } for (uint8 i = 0; i < 5; ++i)//summon 5 gargoyles { - Creature* pUnit = me->SummonCreature(GARGOYLE, AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) + Creature* unit = me->SummonCreature(GARGOYLE, AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (unit) { - pUnit->SetHomePosition(AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3]); - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); + unit->SetHomePosition(AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3]); + CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + unit->setActive(true); } } break; @@ -1120,38 +1120,38 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) for (uint8 i = 0; i < 26; ++i)//summon infernals { - Creature* pUnit = me->SummonCreature(GIANT_INFERNAL, InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) + Creature* unit = me->SummonCreature(GIANT_INFERNAL, InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (unit) { - pUnit->SetHomePosition(InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3]); - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); + unit->SetHomePosition(InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3]); + CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + unit->setActive(true); } } for (uint8 i = 0; i < 25; ++i)//summon 25 ghouls { uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(GHOUL, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) + Creature* unit = me->SummonCreature(GHOUL, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (unit) { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); + CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + unit->setActive(true); } } for (uint8 i = 0; i < 5; ++i)//summon 5 abominations { uint8 r = rand()%4; - Creature* pUnit = me->SummonCreature(ABOMINATION, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); - if (pUnit) + Creature* unit = me->SummonCreature(ABOMINATION, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); + if (unit) { - CAST_AI(hyjal_trashAI, pUnit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, pUnit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, pUnit->AI())->OverrunType = i; - pUnit->setActive(true); + CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; + CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + unit->setActive(true); } } break; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index fcb7126cb6a..e3d57414b94 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -191,12 +191,12 @@ public: Creature* creature = instance->GetCreature(Azgalor); if (creature) { - Creature* pUnit = creature->SummonCreature(21987, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); + Creature* unit = creature->SummonCreature(21987, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); Map* pMap = creature->GetMap(); - if (pMap->IsDungeon() && pUnit) + if (pMap->IsDungeon() && unit) { - pUnit->SetVisible(false); + unit->SetVisible(false); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (PlayerList.isEmpty()) return; @@ -206,7 +206,7 @@ public: if (i->getSource()) { WorldPacket data(SMSG_MESSAGECHAT, 200); - pUnit->BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, YELL_EFFORTS, 0, YELL_EFFORTS_NAME, i->getSource()->GetGUID()); + unit->BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, YELL_EFFORTS, 0, YELL_EFFORTS_NAME, i->getSource()->GetGUID()); i->getSource()->GetSession()->SendPacket(&data); WorldPacket data2(SMSG_PLAY_SOUND, 4); diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp index c73843b7a8c..7244d78e83d 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp @@ -576,11 +576,11 @@ public: while (i != Stomach_Map.end()) { //Check for valid player - Unit* pUnit = Unit::GetUnit(*me, i->first); + Unit* unit = Unit::GetUnit(*me, i->first); //Only units out of stomach - if (pUnit && i->second == false) - temp.push_back(pUnit); + if (unit && i->second == false) + temp.push_back(unit); ++i; } @@ -724,19 +724,19 @@ public: while (i != Stomach_Map.end()) { //Check for valid player - Unit* pUnit = Unit::GetUnit(*me, i->first); + Unit* unit = Unit::GetUnit(*me, i->first); //Only move units in stomach - if (pUnit && i->second == true) + if (unit && i->second == true) { //Teleport each player out - DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); + DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them - DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); + DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff - pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); + unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } @@ -755,25 +755,25 @@ public: while (i != Stomach_Map.end()) { //Check for valid player - Unit* pUnit = Unit::GetUnit(*me, i->first); + Unit* unit = Unit::GetUnit(*me, i->first); //Only apply to units in stomach - if (pUnit && i->second == true) + if (unit && i->second == true) { //Cast digestive acid on them - DoCast(pUnit, SPELL_DIGESTIVE_ACID, true); + DoCast(unit, SPELL_DIGESTIVE_ACID, true); //Check if player should be kicked from stomach - if (pUnit->IsWithinDist3d(&KickPos, 15.0f)) + if (unit->IsWithinDist3d(&KickPos, 15.0f)) { //Teleport each player out - DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); + DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them - DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); + DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff - pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); + unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } @@ -805,11 +805,11 @@ public: if (StomachEnterVisTimer <= diff) { //Check for valid player - Unit* pUnit = Unit::GetUnit(*me, StomachEnterTarget); + Unit* unit = Unit::GetUnit(*me, StomachEnterTarget); - if (pUnit) + if (unit) { - DoTeleportPlayer(pUnit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O); + DoTeleportPlayer(unit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O); } StomachEnterTarget = 0; diff --git a/src/server/scripts/Kalimdor/boss_azuregos.cpp b/src/server/scripts/Kalimdor/boss_azuregos.cpp index 8bfefade07e..6bbc29dcc56 100644 --- a/src/server/scripts/Kalimdor/boss_azuregos.cpp +++ b/src/server/scripts/Kalimdor/boss_azuregos.cpp @@ -87,10 +87,10 @@ public: std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { - DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, pUnit->GetOrientation()); + DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+3, unit->GetOrientation()); } } diff --git a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp index 0c01e5dcc27..e79ab78f46b 100644 --- a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp @@ -535,8 +535,8 @@ public: SetCombatMovement(true); if (me->isInCombat()) - if (Unit* pUnit = me->getVictim()) - me->GetMotionMaster()->MoveChase(pUnit); + if (Unit* unit = me->getVictim()) + me->GetMotionMaster()->MoveChase(unit); } void MoveToDock() @@ -823,6 +823,36 @@ class spell_energize_aoe : public SpellScriptLoader } }; +/*###### +## go_blackhoof_cage +######*/ + +enum PrisonersOfTheGrimTotems +{ + NPC_THERAMORE_PRISONER = 23720, + SAY_FREE = 0, +}; + +class go_blackhoof_cage : public GameObjectScript +{ +public: + go_blackhoof_cage() : GameObjectScript("go_blackhoof_cage") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (Creature* prisoner = go->FindNearestCreature(NPC_THERAMORE_PRISONER, 1.0f)) + { + go->UseDoorOrButton(); + if (player) + player->KilledMonsterCredit(NPC_THERAMORE_PRISONER, 0); + + prisoner->AI()->Talk(SAY_FREE); // We also emote cry here (handled in creature_text.emote) + prisoner->ForcedDespawn(6000); + } + return true; + } +}; + void AddSC_dustwallow_marsh() { new mobs_risen_husk_spirit(); @@ -836,4 +866,5 @@ void AddSC_dustwallow_marsh() new spell_ooze_zap(); new spell_ooze_zap_channel_end(); new spell_energize_aoe(); + new go_blackhoof_cage(); } diff --git a/src/server/scripts/Kalimdor/mulgore.cpp b/src/server/scripts/Kalimdor/mulgore.cpp index 6b7197292dd..947c5236e14 100644 --- a/src/server/scripts/Kalimdor/mulgore.cpp +++ b/src/server/scripts/Kalimdor/mulgore.cpp @@ -160,9 +160,9 @@ public: switch (uiEventPhase) { case 1: - if (Unit* pUnit = Unit::GetUnit(*me, uiPlayerGUID)) + if (Unit* unit = Unit::GetUnit(*me, uiPlayerGUID)) { - if (GameObject* pGo = pUnit->GetGameObject(SPELL_LUNCH)) + if (GameObject* pGo = unit->GetGameObject(SPELL_LUNCH)) { m_bIsMovingToLunch = true; me->GetMotionMaster()->MovePoint(POINT_ID, pGo->GetPositionX(), pGo->GetPositionY(), pGo->GetPositionZ()); @@ -174,8 +174,8 @@ public: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USESTANDING); break; case 3: - if (Player* pUnit = Unit::GetPlayer(*me, uiPlayerGUID)) - pUnit->TalkedToCreature(me->GetEntry(), me->GetGUID()); + if (Player* unit = Unit::GetPlayer(*me, uiPlayerGUID)) + unit->TalkedToCreature(me->GetEntry(), me->GetGUID()); me->UpdateEntry(NPC_KYLE_FRIENDLY); break; diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 3e1f500ebce..63e714d17aa 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -173,6 +173,7 @@ set(scripts_STAT_SRCS Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp Northrend/IcecrownCitadel/boss_sindragosa.cpp + Northrend/IcecrownCitadel/boss_the_lich_king.cpp Northrend/zuldrak.cpp Northrend/icecrown.cpp Northrend/Gundrak/boss_slad_ran.cpp diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp index 6dc0d0365a0..acbe54d0acd 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp @@ -223,8 +223,8 @@ public: uint64 uiGrandChampionBoss1 = 0; if (Creature* pBoss = Unit::GetCreature(*me, uiVehicle1GUID)) if (Vehicle* pVehicle = pBoss->GetVehicleKit()) - if (Unit* pUnit = pVehicle->GetPassenger(0)) - uiGrandChampionBoss1 = pUnit->GetGUID(); + if (Unit* unit = pVehicle->GetPassenger(0)) + uiGrandChampionBoss1 = unit->GetGUID(); if (pInstance) { pInstance->SetData64(DATA_GRAND_CHAMPION_VEHICLE_1, uiVehicle1GUID); @@ -239,8 +239,8 @@ public: uint64 uiGrandChampionBoss2 = 0; if (Creature* pBoss = Unit::GetCreature(*me, uiVehicle2GUID)) if (Vehicle* pVehicle = pBoss->GetVehicleKit()) - if (Unit* pUnit = pVehicle->GetPassenger(0)) - uiGrandChampionBoss2 = pUnit->GetGUID(); + if (Unit* unit = pVehicle->GetPassenger(0)) + uiGrandChampionBoss2 = unit->GetGUID(); if (pInstance) { pInstance->SetData64(DATA_GRAND_CHAMPION_VEHICLE_2, uiVehicle2GUID); @@ -255,8 +255,8 @@ public: uint64 uiGrandChampionBoss3 = 0; if (Creature* pBoss = Unit::GetCreature(*me, uiVehicle3GUID)) if (Vehicle* pVehicle = pBoss->GetVehicleKit()) - if (Unit* pUnit = pVehicle->GetPassenger(0)) - uiGrandChampionBoss3 = pUnit->GetGUID(); + if (Unit* unit = pVehicle->GetPassenger(0)) + uiGrandChampionBoss3 = unit->GetGUID(); if (pInstance) { pInstance->SetData64(DATA_GRAND_CHAMPION_VEHICLE_3, uiVehicle3GUID); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index 013f2cd6e98..ff342db5503 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -292,14 +292,14 @@ struct boss_faction_championsAI : public ScriptedAI std::list<HostileReference*> const& tList = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = tList.begin(); itr != tList.end(); ++itr) { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit && me->getThreatManager().getThreat(pUnit)) + Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (unit && me->getThreatManager().getThreat(unit)) { - if (pUnit->GetTypeId()==TYPEID_PLAYER) + if (unit->GetTypeId()==TYPEID_PLAYER) { - float threat = CalculateThreat(me->GetDistance2d(pUnit), (float)pUnit->GetArmor(), pUnit->GetHealth()); - me->getThreatManager().modifyThreatPercent(pUnit, -100); - me->AddThreat(pUnit, 1000000.0f * threat); + float threat = CalculateThreat(me->GetDistance2d(unit), (float)unit->GetArmor(), unit->GetHealth()); + me->getThreatManager().modifyThreatPercent(unit, -100); + me->AddThreat(unit, 1000000.0f * threat); } } } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h index 8381ead167d..6237d7d57b0 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -114,8 +114,8 @@ struct boss_horAI : ScriptedAI me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_AGGRESSIVE); - if (Unit* pUnit = me->SelectNearestTarget()) - AttackStart(pUnit); + if (Unit* unit = me->SelectNearestTarget()) + AttackStart(unit); DoZoneInCombat(); break; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index b19042b3669..a52965f925f 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -193,9 +193,9 @@ class boss_lord_marrowgar : public CreatureScript case EVENT_BONE_STORM_MOVE: { events.ScheduleEvent(EVENT_BONE_STORM_MOVE, _boneStormDuration/3); - Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 1); + Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)); if (!unit) - unit = SelectTarget(SELECT_TARGET_RANDOM, 0); + unit = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); if (unit) me->GetMotionMaster()->MovePoint(POINT_TARGET_BONESTORM_PLAYER, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ()); break; @@ -564,14 +564,14 @@ class spell_marrowgar_bone_storm : public SpellScriptLoader { PrepareSpellScript(spell_marrowgar_bone_storm_SpellScript); - void RecalculateDamage(SpellEffIndex /*effIndex*/) + void RecalculateDamage() { - SetHitDamage(int32(GetHitDamage() / sqrtf(logf(GetHitUnit()->GetExactDist2d(GetCaster()))))); + SetHitDamage(int32(GetHitDamage() / std::max(sqrtf(GetHitUnit()->GetExactDist2d(GetCaster())), 1.0f))); } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_marrowgar_bone_storm_SpellScript::RecalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnHit += SpellHitFn(spell_marrowgar_bone_storm_SpellScript::RecalculateDamage); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 72b5f8f918c..a6e3e78c96a 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -525,7 +525,7 @@ class boss_professor_putricide : public CreatureScript EnterEvadeMode(); break; case EVENT_FESTERGUT_GOO: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) DoCast(target, SPELL_MALLABLE_GOO_H, true); // triggered, to skip LoS check events.ScheduleEvent(EVENT_FESTERGUT_GOO, urand(15000, 20000), 0, PHASE_FESTERGUT); break; @@ -534,7 +534,7 @@ class boss_professor_putricide : public CreatureScript EnterEvadeMode(); break; case EVENT_ROTFACE_VILE_GAS: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) DoCast(target, SPELL_VILE_GAS_H, true); // triggered, to skip LoS check events.ScheduleEvent(EVENT_ROTFACE_VILE_GAS, urand(15000, 20000), 0, PHASE_ROTFACE); break; @@ -601,7 +601,7 @@ class boss_professor_putricide : public CreatureScript events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, urand(35000, 40000)); break; case EVENT_UNBOUND_PLAGUE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) { me->CastCustomSpell(SPELL_UNBOUND_PLAGUE, SPELLVALUE_BASE_POINT0, 775, target); DoCast(target, SPELL_UNBOUND_PLAGUE_SEARCHER); @@ -1341,18 +1341,18 @@ class spell_putricide_mutated_transformation : public SpellScriptLoader if (!summon || !summon->IsVehicle()) return; - caster->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_NAME, true); summon->CastSpell(summon, SPELL_ABOMINATION_VEHICLE_POWER_DRAIN, true); summon->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_DAMAGE, true); + caster->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_NAME, true); - caster->EnterVehicle(summon, 0); + caster->EnterVehicle(summon, 0); // VEHICLE_SPELL_RIDE_HARDCODED is used according to sniff, this is ok summon->SetCreatorGUID(caster->GetGUID()); putricide->AI()->JustSummoned(summon); } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_putricide_mutated_transformation_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); + OnEffectHit += SpellEffectFn(spell_putricide_mutated_transformation_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp new file mode 100644 index 00000000000..85ab188f336 --- /dev/null +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -0,0 +1,3243 @@ +/* + * Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Spell.h" +#include "Vehicle.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "icecrown_citadel.h" + +enum Texts +{ + // The Lich King + SAY_LK_INTRO_1 = 0, + SAY_LK_INTRO_2 = 1, + SAY_LK_INTRO_3 = 2, + SAY_LK_REMORSELESS_WINTER = 4, + SAY_LK_QUAKE = 5, + SAY_LK_SUMMON_VALKYR = 6, + SAY_LK_HARVEST_SOUL = 7, + SAY_LK_FROSTMOURNE_ESCAPE = 8, // not said on heroic + SAY_LK_FROSTMOURNE_KILL = 9, // not said on heroic + SAY_LK_KILL = 10, + SAY_LK_BERSERK = 11, + EMOTE_DEFILE_WARNING = 12, + EMOTE_NECROTIC_PLAGUE_WARNING = 13, + SAY_LK_OUTRO_1 = 14, + SAY_LK_OUTRO_2 = 15, + SAY_LK_OUTRO_3 = 16, + SAY_LK_OUTRO_4 = 17, + SAY_LK_OUTRO_5 = 18, + SAY_LK_OUTRO_6 = 19, + SAY_LK_OUTRO_7 = 20, + SAY_LK_OUTRO_8 = 21, + + // Highlord Tirion Fordring + SAY_TIRION_INTRO_1 = 0, + SAY_TIRION_INTRO_2 = 1, + SAY_TIRION_OUTRO_1 = 2, + SAY_TIRION_OUTRO_2 = 3, + + // Terenas Menethil (outro) + SAY_TERENAS_OUTRO_1 = 0, + SAY_TERENAS_OUTRO_2 = 1, + + // Terenas Menethil (Frostmourne) + SAY_TERENAS_INTRO_1 = 0, + SAY_TERENAS_INTRO_2 = 1, + SAY_TERENAS_INTRO_3 = 2, +}; + +enum Spells +{ + // The Lich King + SPELL_PLAGUE_AVOIDANCE = 72846, // raging spirits also get it + SPELL_EMOTE_SIT_NO_SHEATH = 73220, + SPELL_BOSS_HITTIN_YA = 73878, + SPELL_EMOTE_SHOUT_NO_SHEATH = 73213, + SPELL_ICE_LOCK = 71614, + + // Phase 1 + SPELL_SUMMON_SHAMBLING_HORROR = 70372, + SPELL_RISEN_WITCH_DOCTOR_SPAWN = 69639, + SPELL_SUMMON_DRUDGE_GHOULS = 70358, + SPELL_INFEST = 70541, + SPELL_NECROTIC_PLAGUE = 70337, + SPELL_NECROTIC_PLAGUE_JUMP = 70338, + SPELL_PLAGUE_SIPHON = 74074, + SPELL_SHADOW_TRAP = 73539, + SPELL_SHADOW_TRAP_AURA = 73525, + SPELL_SHADOW_TRAP_KNOCKBACK = 73529, + + // Phase Transition + SPELL_REMORSELESS_WINTER_1 = 68981, + SPELL_REMORSELESS_WINTER_2 = 72259, + SPELL_PAIN_AND_SUFFERING = 72133, + SPELL_SUMMON_ICE_SPHERE = 69104, + SPELL_ICE_SPHERE = 69090, + SPELL_ICE_BURST_TARGET_SEARCH = 69109, + SPELL_ICE_PULSE = 69091, + SPELL_ICE_BURST = 69108, + SPELL_RAGING_SPIRIT = 69200, + SPELL_RAGING_SPIRIT_VISUAL = 69197, + SPELL_RAGING_SPIRIT_VISUAL_CLONE = 69198, + SPELL_SOUL_SHRIEK = 69242, + SPELL_QUAKE = 72262, + + // Phase 2 + SPELL_DEFILE = 72762, + SPELL_DEFILE_AURA = 72743, + SPELL_DEFILE_GROW = 72756, + SPELL_SUMMON_VALKYR = 69037, + SPELL_SUMMON_VALKYR_PERIODIC = 74361, + SPELL_HARVEST_SOUL_VALKYR = 68985, // Val'kyr Shadowguard vehicle aura + SPELL_SOUL_REAPER = 69409, + SPELL_SOUL_REAPER_BUFF = 69410, + SPELL_WINGS_OF_THE_DAMNED = 74352, + SPELL_VALKYR_TARGET_SEARCH = 69030, + SPELL_CHARGE = 74399, // cast on selected target + SPELL_VALKYR_CARRY = 74445, // removes unselectable flag + SPELL_LIFE_SIPHON = 73488, + SPELL_LIFE_SIPHON_HEAL = 73489, + SPELL_EJECT_ALL_PASSENGERS = 68576, + + // Phase 3 + SPELL_VILE_SPIRITS = 70498, + SPELL_VILE_SPIRIT_MOVE_SEARCH = 70501, + SPELL_VILE_SPIRIT_DAMAGE_SEARCH = 70502, + SPELL_SPIRIT_BURST = 70503, + SPELL_HARVEST_SOUL = 68980, + SPELL_HARVEST_SOULS = 73654, // Heroic version, weird because it has all 4 difficulties just like above spell + SPELL_HARVEST_SOUL_VEHICLE = 68984, + SPELL_HARVEST_SOUL_VISUAL = 71372, + SPELL_HARVEST_SOUL_TELEPORT = 72546, + SPELL_HARVEST_SOULS_TELEPORT = 73655, + SPELL_HARVEST_SOUL_TELEPORT_BACK = 72597, + SPELL_IN_FROSTMOURNE_ROOM = 74276, + SPELL_KILL_FROSTMOURNE_PLAYERS = 75127, + SPELL_HARVESTED_SOUL = 72679, + SPELL_TRIGGER_VILE_SPIRIT_HEROIC = 73582, + + // Frostmourne + SPELL_LIGHTS_FAVOR = 69382, + SPELL_RESTORE_SOUL = 72595, + SPELL_RESTORE_SOULS = 73650, // Heroic + SPELL_DARK_HUNGER = 69383, // Passive proc healing + SPELL_DESTROY_SOUL = 74086, // Used when Terenas Menethil dies + SPELL_SOUL_RIP = 69397, // Deals increasing damage + SPELL_SOUL_RIP_DAMAGE = 69398, + SPELL_TERENAS_LOSES_INSIDE = 72572, + SPELL_SUMMON_SPIRIT_BOMB_1 = 73581, // (Heroic) + SPELL_SUMMON_SPIRIT_BOMB_2 = 74299, // (Heroic) + SPELL_EXPLOSION = 73576, // Spirit Bomb (Heroic) + + // Outro + SPELL_FURY_OF_FROSTMOURNE = 72350, + SPELL_FURY_OF_FROSTMOURNE_NO_REZ = 72351, + SPELL_EMOTE_QUESTION_NO_SHEATH = 73330, + SPELL_RAISE_DEAD = 71769, + SPELL_LIGHTS_BLESSING = 71797, + SPELL_JUMP = 71809, + SPELL_JUMP_TRIGGERED = 71811, + SPELL_JUMP_2 = 72431, + SPELL_SUMMON_BROKEN_FROSTMOURNE = 74081, // visual + SPELL_SUMMON_BROKEN_FROSTMOURNE_2 = 72406, // animation + SPELL_SUMMON_BROKEN_FROSTMOURNE_3 = 73017, // real summon + SPELL_BROKEN_FROSTMOURNE = 72398, + SPELL_BROKEN_FROSTMOURNE_KNOCK = 72405, + SPELL_SOUL_BARRAGE = 72305, + SPELL_SUMMON_TERENAS = 72420, + SPELL_MASS_RESURRECTION = 72429, + SPELL_MASS_RESURRECTION_REAL = 72423, + SPELL_PLAY_MOVIE = 73159, + + // Shambling Horror + SPELL_SHOCKWAVE = 72149, + SPELL_ENRAGE = 72143, + SPELL_FRENZY = 28747, +}; + +#define NECROTIC_PLAGUE_LK RAID_MODE<uint32>(70337, 73912, 73913, 73914) +#define NECROTIC_PLAGUE_PLR RAID_MODE<uint32>(70338, 73785, 73786, 73787) +#define REMORSELESS_WINTER_1 RAID_MODE<uint32>(68981, 74270, 74271, 74272) +#define REMORSELESS_WINTER_2 RAID_MODE<uint32>(72259, 74273, 74274, 74275) +#define SUMMON_VALKYR RAID_MODE<uint32>(69037, 74361, 69037, 74361) +#define HARVEST_SOUL RAID_MODE<uint32>(68980, 74325, 74296, 74297) + +enum Events +{ + // The Lich King + // intro events + EVENT_INTRO_MOVE_1 = 1, + EVENT_INTRO_MOVE_2 = 2, + EVENT_INTRO_MOVE_3 = 3, + EVENT_INTRO_TALK_1 = 4, + EVENT_EMOTE_CAST_SHOUT = 5, + EVENT_INTRO_EMOTE_1 = 6, + EVENT_INTRO_CHARGE = 7, + EVENT_INTRO_CAST_FREEZE = 8, + EVENT_FINISH_INTRO = 9, + + // combat events + EVENT_SUMMON_SHAMBLING_HORROR = 10, + EVENT_SUMMON_DRUDGE_GHOUL = 11, + EVENT_INFEST = 12, + EVENT_NECROTIC_PLAGUE = 13, + EVENT_SHADOW_TRAP = 14, // heroic only + EVENT_SOUL_REAPER = 15, + EVENT_DEFILE = 16, + EVENT_HARVEST_SOUL = 17, // normal mode only + EVENT_PAIN_AND_SUFFERING = 18, + EVENT_SUMMON_ICE_SPHERE = 19, + EVENT_SUMMON_RAGING_SPIRIT = 20, + EVENT_QUAKE = 21, + EVENT_SUMMON_VALKYR = 22, + EVENT_GRAB_PLAYER = 23, + EVENT_MOVE_TO_DROP_POS = 24, + EVENT_LIFE_SIPHON = 25, // heroic only + EVENT_START_ATTACK = 26, + EVENT_QUAKE_2 = 27, + EVENT_VILE_SPIRITS = 28, + EVENT_HARVEST_SOULS = 29, // heroic only + EVENT_WICKED_SPIRITS = 30, + EVENT_SOUL_RIP = 31, + EVENT_DESTROY_SOUL = 32, + EVENT_FROSTMOURNE_TALK_1 = 33, + EVENT_FROSTMOURNE_TALK_2 = 34, + EVENT_FROSTMOURNE_TALK_3 = 35, + EVENT_TELEPORT_BACK = 36, + EVENT_FROSTMOURNE_HEROIC = 37, + EVENT_OUTRO_TALK_1 = 38, + EVENT_OUTRO_TALK_2 = 39, + EVENT_OUTRO_EMOTE_TALK = 40, + EVENT_OUTRO_TALK_3 = 41, + EVENT_OUTRO_MOVE_CENTER = 42, + EVENT_OUTRO_TALK_4 = 43, + EVENT_OUTRO_RAISE_DEAD = 44, + EVENT_OUTRO_TALK_5 = 45, + EVENT_OUTRO_BLESS = 46, + EVENT_OUTRO_REMOVE_ICE = 47, + EVENT_OUTRO_MOVE_1 = 48, + EVENT_OUTRO_JUMP = 49, + EVENT_OUTRO_TALK_6 = 50, + EVENT_OUTRO_KNOCK_BACK = 51, + EVENT_OUTRO_SOUL_BARRAGE = 52, + EVENT_OUTRO_SUMMON_TERENAS = 53, + EVENT_OUTRO_TERENAS_TALK_1 = 54, + EVENT_OUTRO_TERENAS_TALK_2 = 55, + EVENT_OUTRO_TALK_7 = 56, + EVENT_OUTRO_TALK_8 = 57, + EVENT_BERSERK = 58, + + // Shambling Horror + EVENT_SHOCKWAVE = 59, + EVENT_ENRAGE = 60, + + // Raging Spirit + EVENT_SOUL_SHRIEK = 61, + + // Strangulate Vehicle (Harvest Soul) + EVENT_TELEPORT = 62, + EVENT_MOVE_TO_LICH_KING = 63, + EVENT_DESPAWN_SELF = 64, +}; + +enum EventGroups +{ + EVENT_GROUP_BERSERK = 1, + EVENT_GROUP_VILE_SPIRITS = 2, +}; + +enum Phases +{ + PHASE_INTRO = 1, + PHASE_ONE = 2, + PHASE_TWO = 3, + PHASE_THREE = 4, + PHASE_TRANSITION = 5, + PHASE_FROSTMOURNE = 6, // only set on heroic mode when all players are sent into frostmourne + PHASE_OUTRO = 7, + + PHASE_MASK_INTRO = 1 << PHASE_INTRO, + PHASE_MASK_ONE = 1 << PHASE_ONE, + PHASE_MASK_TWO = 1 << PHASE_TWO, + PHASE_MASK_THREE = 1 << PHASE_THREE, + PHASE_MASK_TRANSITION = 1 << PHASE_TRANSITION, + PHASE_MASK_NO_CAST_CHECK = (1 << PHASE_TRANSITION) | (1 << PHASE_FROSTMOURNE) | (1 << PHASE_OUTRO), + PHASE_MASK_FROSTMOURNE = 1 << PHASE_FROSTMOURNE, + PHASE_MASK_OUTRO = 1 << PHASE_OUTRO, + PHASE_MASK_NO_VICTIM = (1 << PHASE_INTRO) | (1 << PHASE_OUTRO) | (1 << PHASE_FROSTMOURNE), +}; + +#define PHASE_TWO_THREE (events.GetPhaseMask() & PHASE_MASK_TWO ? PHASE_TWO : PHASE_THREE) + +Position const CenterPosition = {503.6282f, -2124.655f, 840.8569f, 0.0f}; +Position const TirionIntro = {489.2970f, -2124.840f, 840.8569f, 0.0f}; +Position const TirionCharge = {482.9019f, -2124.479f, 840.8570f, 0.0f}; +Position const LichKingIntro[3] = +{ + {432.0851f, -2123.673f, 864.6582f, 0.0f}, + {457.8351f, -2123.423f, 841.1582f, 0.0f}, + {465.0730f, -2123.470f, 840.8569f, 0.0f}, +}; +Position const OutroPosition1 = {493.6286f, -2124.569f, 840.8569f, 0.0f}; +Position const OutroFlying = {508.9897f, -2124.561f, 845.3565f, 0.0f}; +Position const TerenasSpawn = {495.5542f, -2517.012f, 1050.000f, 4.6993f}; +Position const TerenasSpawnHeroic = {495.7080f, -2523.760f, 1050.000f, 0.0f}; +Position const SpiritWardenSpawn = {495.3406f, -2529.983f, 1050.000f, 1.5592f}; + +enum MovePoints +{ + POINT_CENTER_1 = 1, + POINT_CENTER_2 = 2, + POINT_TIRION_INTRO = 3, + POINT_LK_INTRO_1 = 4, + POINT_LK_INTRO_2 = 5, + POINT_LK_INTRO_3 = 6, + POINT_TIRION_CHARGE = 7, + POINT_DROP_PLAYER = 8, + POINT_LK_OUTRO_1 = 9, + POINT_TIRION_OUTRO_1 = 10, + POINT_OUTRO_JUMP = 11, + POINT_LK_OUTRO_2 = 12, + POINT_GROUND = 13, + POINT_CHARGE = 1003, // globally used number for charge spell effects +}; + +enum EncounterActions +{ + ACTION_START_ENCOUNTER = 0, + ACTION_CONTINUE_INTRO = 1, + ACTION_START_ATTACK = 2, + ACTION_OUTRO = 3, + ACTION_PLAY_MUSIC = 4, + ACTION_BREAK_FROSTMOURNE = 5, + ACTION_SUMMON_TERENAS = 6, + ACTION_FINISH_OUTRO = 7, + ACTION_TELEPORT_BACK = 8, +}; + +enum MiscData +{ + LIGHT_SNOWSTORM = 2490, + LIGHT_SOULSTORM = 2508, + + MUSIC_FROZEN_THRONE = 17457, + MUSIC_SPECIAL = 17458, // Summon Shambling Horror, Remorseless Winter, Quake, Summon Val'kyr Periodic, Harvest Soul, Vile Spirits + MUSIC_FURY_OF_FROSTMOURNE = 17459, + MUSIC_FINAL = 17460, // Raise Dead, Light's Blessing + + SOUND_PAIN = 17360, // separate sound, not attached to any text + + EQUIP_ASHBRINGER_GLOWING = 50442, + EQUIP_BROKEN_FROSTMOURNE = 50840, + + MOVIE_FALL_OF_THE_LICH_KING = 16, +}; + +#define DATA_PLAGUE_STACK 70337 +#define DATA_VILE 45814622 + +class NecroticPlagueTargetCheck : public std::unary_function<Unit*, bool> +{ + public: + NecroticPlagueTargetCheck(Unit const* obj, uint32 notAura1 = 0, uint32 notAura2 = 0) + : _sourceObj(obj), _notAura1(notAura1), _notAura2(notAura2) + { + } + + bool operator()(Unit* unit) const + { + if (!unit || unit == _sourceObj || !unit->isTargetableForAttack() || unit->isTotem() || unit->HasAura(SPELL_PLAGUE_AVOIDANCE)) + return false; + if ((_notAura1 && unit->HasAura(_notAura1)) || (_notAura2 && unit->HasAura(_notAura2))) + return false; + return true; + } + + private: + Unit const* _sourceObj; + uint32 _notAura1; + uint32 _notAura2; +}; + +class HeightDifferenceCheck +{ + public: + HeightDifferenceCheck(GameObject* go, float diff, bool reverse) + : _baseObject(go), _difference(diff), _reverse(reverse) + { + } + + bool operator()(Unit* unit) const + { + return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse; + } + + private: + GameObject* _baseObject; + float _difference; + bool _reverse; +}; + +class FrozenThroneResetWorker +{ + public: + FrozenThroneResetWorker() { } + + bool operator()(GameObject* go) + { + switch (go->GetEntry()) + { + case GO_ARTHAS_PLATFORM: + go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING); + break; + case GO_DOODAD_ICECROWN_THRONEFROSTYWIND01: + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01: + go->SetGoState(GO_STATE_READY); + break; + case GO_DOODAD_ICESHARD_STANDING02: + case GO_DOODAD_ICESHARD_STANDING01: + case GO_DOODAD_ICESHARD_STANDING03: + case GO_DOODAD_ICESHARD_STANDING04: + go->ResetDoorOrButton(); + break; + default: + break; + } + + return false; + } +}; + +class StartMovementEvent : public BasicEvent +{ + public: + StartMovementEvent(Creature* summoner, Creature* owner) + : _summoner(summoner), _owner(owner) + { + } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) + { + _owner->SetReactState(REACT_AGGRESSIVE); + if (Unit* target = _summoner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(_summoner))) + _owner->AI()->AttackStart(target); + return true; + } + + private: + Creature* _summoner; + Creature* _owner; +}; + +class VileSpiritActivateEvent : public BasicEvent +{ + public: + explicit VileSpiritActivateEvent(Creature* owner) + : _owner(owner) + { + } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) + { + _owner->SetReactState(REACT_AGGRESSIVE); + _owner->CastSpell(_owner, SPELL_VILE_SPIRIT_MOVE_SEARCH, true); + _owner->CastSpell((Unit*)NULL, SPELL_VILE_SPIRIT_DAMAGE_SEARCH, true); + return true; + } + + private: + Creature* _owner; +}; + +class boss_the_lich_king : public CreatureScript +{ + public: + boss_the_lich_king() : CreatureScript("boss_the_lich_king") { } + + struct boss_the_lich_kingAI : public BossAI + { + boss_the_lich_kingAI(Creature* creature) : BossAI(creature, DATA_THE_LICH_KING) + { + } + + void Reset() + { + _Reset(); + me->SetReactState(REACT_PASSIVE); + events.SetPhase(PHASE_INTRO); + _necroticPlagueStack = 0; + _vileSpiritExplosions = 0; + SetEquipmentSlots(true); + } + + void JustDied(Unit* /*killer*/) + { + _JustDied(); + DoCastAOE(SPELL_PLAY_MOVIE, false); + me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03); + float x, y, z; + me->GetPosition(x, y, z); + // use larger distance for vmap height search than in most other cases + float ground_Z = me->GetMap()->GetHeight(x, y, z, true, MAX_FALL_DISTANCE); + if (fabs(ground_Z - z) < 0.1f) + return; + + me->GetMotionMaster()->MoveFall(ground_Z); + } + + void EnterCombat(Unit* target) + { + if (!instance->CheckRequiredBosses(DATA_THE_LICH_KING, target->ToPlayer())) + { + EnterEvadeMode(); + instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); + return; + } + + me->setActive(true); + DoZoneInCombat(); + + events.SetPhase(PHASE_ONE); + events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 20000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 10000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_INFEST, 5000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, urand(30000, 33000), 0, PHASE_ONE); + events.ScheduleEvent(EVENT_BERSERK, 900000, EVENT_GROUP_BERSERK); + if (IsHeroic()) + events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE); + } + + void JustReachedHome() + { + _JustReachedHome(); + instance->SetBossState(DATA_THE_LICH_KING, NOT_STARTED); + + // Reset The Frozen Throne gameobjects + FrozenThroneResetWorker reset; + Trinity::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset); + me->VisitNearbyGridObject(333.0f, worker); + + // Reset any light override + SendLightOverride(0, 5000); + } + + bool CanAIAttack(Unit const* target) const + { + // The Lich King must not select targets in frostmourne room if he killed everyone outside + return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM); + } + + void EnterEvadeMode() + { + instance->SetBossState(DATA_THE_LICH_KING, FAIL); + BossAI::EnterEvadeMode(); + if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + tirion->AI()->EnterEvadeMode(); + DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS); + summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK); + } + + void KilledUnit(Unit* victim) + { + if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode() && !(events.GetPhaseMask() & PHASE_MASK_OUTRO)) + Talk(SAY_LK_KILL); + } + + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_START_ENCOUNTER: + instance->SetBossState(DATA_THE_LICH_KING, IN_PROGRESS); + Talk(SAY_LK_INTRO_1); + SendMusicToPlayers(MUSIC_FROZEN_THRONE); + // schedule talks + me->SetStandState(UNIT_STAND_STATE_STAND); + events.ScheduleEvent(EVENT_INTRO_MOVE_1, 4000); + break; + case ACTION_START_ATTACK: + events.ScheduleEvent(EVENT_START_ATTACK, 5000); + break; + case ACTION_PLAY_MUSIC: + SendMusicToPlayers(MUSIC_FINAL); + break; + case ACTION_RESTORE_LIGHT: + SendLightOverride(0, 5000); + break; + case ACTION_BREAK_FROSTMOURNE: + DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE); + DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE_2); + SetEquipmentSlots(false, EQUIP_BROKEN_FROSTMOURNE); + events.ScheduleEvent(EVENT_OUTRO_TALK_6, 2500, 0, PHASE_OUTRO); + break; + case ACTION_FINISH_OUTRO: + events.ScheduleEvent(EVENT_OUTRO_TALK_7, 7000, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_TALK_8, 17000, 0, PHASE_OUTRO); + break; + case ACTION_TELEPORT_BACK: + summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK); + if (!IsHeroic()) + Talk(SAY_LK_FROSTMOURNE_ESCAPE); + else + DoCastAOE(SPELL_TRIGGER_VILE_SPIRIT_HEROIC); + break; + default: + break; + } + } + + uint32 GetData(uint32 type) + { + switch (type) + { + case DATA_PLAGUE_STACK: + return _necroticPlagueStack; + case DATA_VILE: + return _vileSpiritExplosions; + default: + break; + } + + return 0; + } + + void SetData(uint32 type, uint32 value) + { + switch (type) + { + case DATA_PLAGUE_STACK: + _necroticPlagueStack = std::max(value, _necroticPlagueStack); + break; + case DATA_VILE: + _vileSpiritExplosions += value; + break; + default: + break; + } + } + + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) + { + if (events.GetPhaseMask() & PHASE_MASK_ONE && !HealthAbovePct(70)) + { + events.SetPhase(PHASE_TRANSITION); + me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition); + return; + } + + if (events.GetPhaseMask() & PHASE_MASK_TWO && !HealthAbovePct(40)) + { + events.SetPhase(PHASE_TRANSITION); + me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition); + return; + } + + if (events.GetPhaseMask() & PHASE_MASK_THREE && !HealthAbovePct(10)) + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + events.Reset(); + events.SetPhase(PHASE_OUTRO); + summons.DespawnAll(); + SendMusicToPlayers(MUSIC_FURY_OF_FROSTMOURNE); + DoCastAOE(SPELL_FURY_OF_FROSTMOURNE); + me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); + events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 17600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 27600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_TALK_2, 34600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_TALK_3, 43600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 54600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 58600, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_MOVE_CENTER, 69600, 0, PHASE_OUTRO); + // stop here. rest will get scheduled from MovementInform + return; + } + } + + void JustSummoned(Creature* summon) + { + switch (summon->GetEntry()) + { + case NPC_SHAMBLING_HORROR: + case NPC_DRUDGE_GHOUL: + summon->CastSpell(summon, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true); + summon->SetReactState(REACT_PASSIVE); + summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + summon->m_Events.AddEvent(new StartMovementEvent(me, summon), summon->m_Events.CalculateTime(5000)); + break; + case NPC_ICE_SPHERE: + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + { + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_ICE_SPHERE, false); + summon->CastSpell(summon, SPELL_ICE_BURST_TARGET_SEARCH, false); + summon->CastSpell(target, SPELL_ICE_PULSE, false); + summon->ClearUnitState(UNIT_STAT_CASTING); + summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f); + } + else + summon->DespawnOrUnsummon(); + break; + } + case NPC_DEFILE: + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_DEFILE_AURA, false); + break; + case NPC_VALKYR_SHADOWGUARD: + summon->CastSpell(summon, SPELL_WINGS_OF_THE_DAMNED, true); + summon->CastSpell(summon, SPELL_VALKYR_TARGET_SEARCH, true); + break; + case NPC_FROSTMOURNE_TRIGGER: + { + summons.Summon(summon); + summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true); + + SendLightOverride(LIGHT_SOULSTORM, 10000); + SendWeather(WEATHER_STATE_BLACKSNOW); + + events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5000, 0, PHASE_OUTRO); + return; + } + case NPC_VILE_SPIRIT: + { + summons.Summon(summon); + if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE) + { + TeleportSpirit(summon); + return; + } + + summon->SetReactState(REACT_PASSIVE); + summon->SetSpeed(MOVE_FLIGHT, 0.5f); + summon->GetMotionMaster()->MoveRandom(10.0f); + summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000)); + return; + } + case NPC_STRANGULATE_VEHICLE: + summons.Summon(summon); + return; + default: + break; + } + + BossAI::JustSummoned(summon); + } + + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) + { + switch (summon->GetEntry()) + { + case NPC_SHAMBLING_HORROR: + case NPC_DRUDGE_GHOUL: + case NPC_ICE_SPHERE: + case NPC_VALKYR_SHADOWGUARD: + case NPC_RAGING_SPIRIT: + case NPC_VILE_SPIRIT: + case NPC_WICKED_SPIRIT: + summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN); + break; + default: + break; + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + if (spell->Id == SPELL_HARVESTED_SOUL && me->isInCombat() && !IsHeroic()) + Talk(SAY_LK_FROSTMOURNE_KILL); + } + + void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) + { + if (spell->Id == REMORSELESS_WINTER_1 || spell->Id == REMORSELESS_WINTER_2) + { + SendLightOverride(LIGHT_SNOWSTORM, 5000); + SendWeather(WEATHER_STATE_LIGHT_SNOW); + } + } + + void MovementInform(uint32 type, uint32 pointId) + { + if (type != POINT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_LK_INTRO_1: + // schedule for next update cycle, current update must finalize movement + events.ScheduleEvent(EVENT_INTRO_MOVE_2, 1, 0, PHASE_INTRO); + break; + case POINT_LK_INTRO_2: + events.ScheduleEvent(EVENT_INTRO_MOVE_3, 1, 0, PHASE_INTRO); + break; + case POINT_LK_INTRO_3: + if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + tirion->AI()->DoAction(ACTION_CONTINUE_INTRO); + events.ScheduleEvent(EVENT_INTRO_TALK_1, 9000, 0, PHASE_INTRO); + break; + case POINT_CENTER_1: + me->SetFacing(0.0f); + Talk(SAY_LK_REMORSELESS_WINTER); + SendMusicToPlayers(MUSIC_SPECIAL); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + DoCast(me, SPELL_REMORSELESS_WINTER_1); + events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions + events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 4000, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 3000, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_SUMMON_VALKYR, 78000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_INFEST, 70000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_DEFILE, 97000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_SOUL_REAPER, 94000, 0, PHASE_TWO); + break; + case POINT_CENTER_2: + me->SetFacing(0.0f); + Talk(SAY_LK_REMORSELESS_WINTER); + SendMusicToPlayers(MUSIC_SPECIAL); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + DoCast(me, SPELL_REMORSELESS_WINTER_2); + summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD); + events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions + events.ScheduleEvent(EVENT_QUAKE_2, 62500, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 6000, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8000, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 5000, 0, PHASE_TRANSITION); + events.ScheduleEvent(EVENT_DEFILE, 95500, 0, PHASE_THREE); + events.ScheduleEvent(EVENT_SOUL_REAPER, 99500, 0, PHASE_THREE); + events.ScheduleEvent(EVENT_VILE_SPIRITS, 79500, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE); + events.ScheduleEvent(IsHeroic() ? EVENT_HARVEST_SOULS : EVENT_HARVEST_SOUL, 73500, 0, PHASE_THREE); + break; + case POINT_LK_OUTRO_1: + events.ScheduleEvent(EVENT_OUTRO_TALK_4, 1, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_RAISE_DEAD, 1000, 0, PHASE_OUTRO); + events.ScheduleEvent(EVENT_OUTRO_TALK_5, 29000, 0, PHASE_OUTRO); + break; + case POINT_LK_OUTRO_2: + if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + tirion->AI()->Talk(SAY_TIRION_OUTRO_2); + if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f)) + frostmourne->AI()->DoAction(ACTION_SUMMON_TERENAS); + break; + default: + break; + } + } + + void UpdateAI(uint32 const diff) + { + // check phase first to prevent updating victim and entering evade mode when not wanted + if (!(events.GetPhaseMask() & PHASE_MASK_NO_VICTIM)) + if (!UpdateVictim()) + return; + + events.Update(diff); + + // during Remorseless Winter phases The Lich King is channeling a spell, but we must continue casting other spells + if (me->HasUnitState(UNIT_STAT_CASTING) && !(events.GetPhaseMask() & PHASE_MASK_NO_CAST_CHECK)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_MOVE_1: + me->SetSheath(SHEATH_STATE_MELEE); + me->RemoveAurasDueToSpell(SPELL_EMOTE_SIT_NO_SHEATH); + me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); + me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_1, LichKingIntro[0]); + break; + case EVENT_INTRO_MOVE_2: + me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_2, LichKingIntro[1]); + break; + case EVENT_INTRO_MOVE_3: + me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_3, LichKingIntro[2]); + break; + case EVENT_INTRO_TALK_1: + Talk(SAY_LK_INTRO_2); + // for some reason blizz sends 2 emotes in row here so (we handle one in Talk) + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NOSHEATHE); + events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 7000, 0, PHASE_INTRO); + events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 13000, 0, PHASE_INTRO); + events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 18000, 0, PHASE_INTRO); + events.ScheduleEvent(EVENT_INTRO_CAST_FREEZE, 31000, 0, PHASE_INTRO); + break; + case EVENT_EMOTE_CAST_SHOUT: + DoCast(me, SPELL_EMOTE_SHOUT_NO_SHEATH, false); + break; + case EVENT_INTRO_EMOTE_1: + me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NOSHEATHE); + break; + case EVENT_INTRO_CAST_FREEZE: + Talk(SAY_LK_INTRO_3); + DoCastAOE(SPELL_ICE_LOCK, false); + events.ScheduleEvent(EVENT_FINISH_INTRO, 1000, 0, PHASE_INTRO); + break; + case EVENT_FINISH_INTRO: + me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->SetReactState(REACT_AGGRESSIVE); + events.SetPhase(PHASE_ONE); + break; + case EVENT_SUMMON_SHAMBLING_HORROR: + DoCast(me, SPELL_SUMMON_SHAMBLING_HORROR); + SendMusicToPlayers(MUSIC_SPECIAL); + events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 60000, 0, PHASE_ONE); + break; + case EVENT_SUMMON_DRUDGE_GHOUL: + DoCast(me, SPELL_SUMMON_DRUDGE_GHOULS); + events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 30000, 0, PHASE_ONE); + break; + case EVENT_INFEST: + DoCast(me, SPELL_INFEST); + events.ScheduleEvent(EVENT_INFEST, urand(21000, 24000), 0, (events.GetPhaseMask() & PHASE_MASK_ONE) ? PHASE_ONE : PHASE_TWO); + break; + case EVENT_NECROTIC_PLAGUE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, NecroticPlagueTargetCheck(me, NECROTIC_PLAGUE_LK, NECROTIC_PLAGUE_PLR))) + { + Talk(EMOTE_NECROTIC_PLAGUE_WARNING, target->GetGUID()); + DoCast(target, SPELL_NECROTIC_PLAGUE); + } + events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, urand(30000, 33000), 0, PHASE_ONE); + break; + case EVENT_SHADOW_TRAP: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + DoCast(target, SPELL_SHADOW_TRAP); + events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500, 0, PHASE_ONE); + break; + case EVENT_SOUL_REAPER: + DoCastVictim(SPELL_SOUL_REAPER); + events.ScheduleEvent(EVENT_SOUL_REAPER, urand(33000, 35000), 0, PHASE_TWO_THREE); + break; + case EVENT_DEFILE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_HARVEST_SOUL_VALKYR)) + { + Talk(EMOTE_DEFILE_WARNING); + DoCast(target, SPELL_DEFILE); + } + events.ScheduleEvent(EVENT_DEFILE, urand(32000, 35000), 0, PHASE_TWO_THREE); + break; + case EVENT_HARVEST_SOUL: + Talk(SAY_LK_HARVEST_SOUL); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, SpellTargetSelector(me, SPELL_HARVEST_SOUL))) + DoCast(target, SPELL_HARVEST_SOUL); + events.ScheduleEvent(EVENT_HARVEST_SOUL, 75000, 0, PHASE_THREE); + break; + case EVENT_PAIN_AND_SUFFERING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + me->CastSpell(target, SPELL_PAIN_AND_SUFFERING, TRIGGERED_NONE); + events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, urand(1500, 4000), 0, PHASE_TRANSITION); + break; + case EVENT_SUMMON_ICE_SPHERE: + DoCastAOE(SPELL_SUMMON_ICE_SPHERE); + events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, urand(7500, 8500), 0, PHASE_TRANSITION); + break; + case EVENT_SUMMON_RAGING_SPIRIT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE); + events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, urand(22000, 23000), 0, PHASE_TRANSITION); + break; + case EVENT_QUAKE: + events.SetPhase(PHASE_TWO); + me->ClearUnitState(UNIT_STAT_CASTING); // clear state to ensure check in DoCastAOE passes + DoCastAOE(SPELL_QUAKE); + SendMusicToPlayers(MUSIC_SPECIAL); + Talk(SAY_LK_QUAKE); + break; + case EVENT_QUAKE_2: + events.SetPhase(PHASE_THREE); + me->ClearUnitState(UNIT_STAT_CASTING); // clear state to ensure check in DoCastAOE passes + DoCastAOE(SPELL_QUAKE); + SendMusicToPlayers(MUSIC_SPECIAL); + Talk(SAY_LK_QUAKE); + break; + case EVENT_SUMMON_VALKYR: + SendMusicToPlayers(MUSIC_SPECIAL); + Talk(SAY_LK_SUMMON_VALKYR); + DoCastAOE(SUMMON_VALKYR); + events.ScheduleEvent(EVENT_SUMMON_VALKYR, urand(45000, 50000), 0, PHASE_TWO); + break; + case EVENT_START_ATTACK: + me->SetReactState(REACT_AGGRESSIVE); + if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE) + events.SetPhase(PHASE_THREE); + break; + case EVENT_VILE_SPIRITS: + SendMusicToPlayers(MUSIC_SPECIAL); + DoCastAOE(SPELL_VILE_SPIRITS); + events.ScheduleEvent(EVENT_VILE_SPIRITS, urand(35000, 40000), EVENT_GROUP_VILE_SPIRITS, PHASE_THREE); + break; + case EVENT_WICKED_SPIRITS: + DoCastAOE(SPELL_VILE_SPIRITS); + events.ScheduleEvent(EVENT_WICKED_SPIRITS, urand(35000, 40000), 0, PHASE_FROSTMOURNE); + break; + case EVENT_HARVEST_SOULS: + Talk(SAY_LK_HARVEST_SOUL); + DoCastAOE(SPELL_HARVEST_SOULS); + events.ScheduleEvent(EVENT_HARVEST_SOULS, urand(100000, 110000), 0, PHASE_THREE); + events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading) + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + events.ScheduleEvent(EVENT_WICKED_SPIRITS, events.GetNextEventTime(EVENT_VILE_SPIRITS) - events.GetTimer(), 0, PHASE_FROSTMOURNE); + events.DelayEvents(50000, EVENT_GROUP_VILE_SPIRITS); + events.RescheduleEvent(EVENT_DEFILE, 50000, 0, PHASE_THREE); + events.RescheduleEvent(EVENT_SOUL_REAPER, urand(57000, 62000), 0, PHASE_THREE); + events.ScheduleEvent(EVENT_START_ATTACK, 49000); + events.ScheduleEvent(EVENT_FROSTMOURNE_HEROIC, 6500); + break; + case EVENT_FROSTMOURNE_HEROIC: + if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, NULL, 50000)) + { + terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO); + std::list<Creature*> triggers; + GetCreatureListWithEntryInGrid(triggers, terenas, NPC_WORLD_TRIGGER_INFINITE_AOI, 100.0f); + if (!triggers.empty()) + { + triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true)); + Unit* spawner = triggers.front(); + spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly + spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players + } + + for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i) + { + Creature* summon = ObjectAccessor::GetCreature(*me, *i); + if (summon && summon->GetEntry() == NPC_VILE_SPIRIT) + TeleportSpirit(summon); + } + } + break; + case EVENT_OUTRO_TALK_1: + Talk(SAY_LK_OUTRO_1); + DoCastAOE(SPELL_FURY_OF_FROSTMOURNE_NO_REZ, true); + break; + case EVENT_OUTRO_TALK_2: + Talk(SAY_LK_OUTRO_2); + DoCastAOE(SPELL_EMOTE_QUESTION_NO_SHEATH); + break; + case EVENT_OUTRO_EMOTE_TALK: + me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NOSHEATHE); + break; + case EVENT_OUTRO_TALK_3: + if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + me->SetFacing(0.0f, tirion); + Talk(SAY_LK_OUTRO_3); + break; + case EVENT_OUTRO_MOVE_CENTER: + me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_1, CenterPosition); + break; + case EVENT_OUTRO_TALK_4: + me->SetFacing(0.01745329f); + Talk(SAY_LK_OUTRO_4); + break; + case EVENT_OUTRO_RAISE_DEAD: + DoCastAOE(SPELL_RAISE_DEAD); + me->ClearUnitState(UNIT_STAT_CASTING); + SendMusicToPlayers(MUSIC_FINAL); + break; + case EVENT_OUTRO_TALK_5: + Talk(SAY_LK_OUTRO_5); + if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + tirion->AI()->DoAction(ACTION_OUTRO); + break; + case EVENT_OUTRO_TALK_6: + Talk(SAY_LK_OUTRO_6); + if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + tirion->SetFacing(0.0f, me); + me->ClearUnitState(UNIT_STAT_CASTING); + DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE_3); + SetEquipmentSlots(false, EQUIP_UNEQUIP); + break; + case EVENT_OUTRO_SOUL_BARRAGE: + DoCastAOE(SPELL_SOUL_BARRAGE); + sCreatureTextMgr->SendSound(me, SOUND_PAIN, CHAT_MSG_MONSTER_YELL, 0, TEXT_RANGE_NORMAL, TEAM_OTHER, false); + // set flight + me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03); + me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_2, OutroFlying); + break; + case EVENT_OUTRO_TALK_7: + Talk(SAY_LK_OUTRO_7); + break; + case EVENT_OUTRO_TALK_8: + Talk(SAY_LK_OUTRO_8); + break; + case EVENT_BERSERK: + Talk(SAY_LK_BERSERK); + DoCast(me, SPELL_BERSERK2); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + + void TeleportSpirit(Creature* summon) + { + float dist = me->GetObjectSize() + (15.0f - me->GetObjectSize()) * float(rand_norm()); + float angle = float(rand_norm()) * float(2.0f * M_PI); + Position dest = TerenasSpawnHeroic; + me->MovePosition(dest, dist, angle); + dest.m_positionZ += 15.0f; + summon->UpdateEntry(NPC_WICKED_SPIRIT); + summon->SetReactState(REACT_PASSIVE); + summon->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation()); + summon->SetSpeed(MOVE_FLIGHT, 0.5f); + summon->m_Events.KillAllEvents(true); + summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(1000)); + } + + void SendMusicToPlayers(uint32 musicId) const + { + WorldPacket data(SMSG_PLAY_MUSIC, 4); + data << uint32(musicId); + SendPacketToPlayers(&data); + } + + void SendLightOverride(uint32 overrideId, uint32 fadeInTime) const + { + WorldPacket data(SMSG_OVERRIDE_LIGHT, 12); + data << uint32(2488); // Light.dbc entry (map default) + data << uint32(overrideId); // Light.dbc entry (override) + data << uint32(fadeInTime); + SendPacketToPlayers(&data); + } + + void SendWeather(WeatherState weather) const + { + WorldPacket data(SMSG_WEATHER, 9); + data << uint32(weather); + data << float(0.5f); + data << uint8(0); + SendPacketToPlayers(&data); + } + + // Send packet to all players in The Frozen Throne + void SendPacketToPlayers(WorldPacket const* data) const + { + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + if (!players.isEmpty()) + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->getSource()) + if (player->GetAreaId() == AREA_THE_FROZEN_THRONE) + player->GetSession()->SendPacket(data); + } + + uint32 _necroticPlagueStack; + uint32 _vileSpiritExplosions; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<boss_the_lich_kingAI>(creature); + } +}; + +class npc_tirion_fordring_tft : public CreatureScript +{ + public: + npc_tirion_fordring_tft() : CreatureScript("npc_tirion_fordring_tft") { } + + struct npc_tirion_fordringAI : public ScriptedAI + { + npc_tirion_fordringAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + void Reset() + { + _events.Reset(); + if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE) + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + switch (id) + { + case POINT_TIRION_INTRO: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); + if (Creature* theLichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + theLichKing->AI()->DoAction(ACTION_START_ENCOUNTER); + break; + case POINT_TIRION_OUTRO_1: + _events.ScheduleEvent(EVENT_OUTRO_JUMP, 1, 0, PHASE_OUTRO); + break; + } + } + + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_CONTINUE_INTRO: + Talk(SAY_TIRION_INTRO_1); + _events.ScheduleEvent(EVENT_INTRO_TALK_1, 34000, 0, PHASE_INTRO); + break; + case ACTION_OUTRO: + _events.SetPhase(PHASE_OUTRO); + _events.ScheduleEvent(EVENT_OUTRO_TALK_1, 7000, 0, PHASE_OUTRO); + _events.ScheduleEvent(EVENT_OUTRO_BLESS, 18000, 0, PHASE_OUTRO); + _events.ScheduleEvent(EVENT_OUTRO_REMOVE_ICE, 23000, 0, PHASE_OUTRO); + _events.ScheduleEvent(EVENT_OUTRO_MOVE_1, 25000, 0, PHASE_OUTRO); + break; + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + if (spell->Id == SPELL_ICE_LOCK) + me->SetFacing(3.085098f); + else if (spell->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK) + SetEquipmentSlots(true); // remove glow on ashbringer + } + + void sGossipSelect(Player* player, uint32 sender, uint32 action) + { + if (me->GetCreatureInfo()->GossipMenuId == sender && !action) + { + _events.SetPhase(PHASE_INTRO); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); + me->GetMotionMaster()->MovePoint(POINT_TIRION_INTRO, TirionIntro); + } + } + + void JustReachedHome() + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + + if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE) + return; + + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim() && !(_events.GetPhaseMask() & (PHASE_MASK_INTRO | PHASE_MASK_OUTRO))) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_TALK_1: + Talk(SAY_TIRION_INTRO_2); + _events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 2000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_CHARGE, 5000, 0, PHASE_INTRO); + break; + case EVENT_INTRO_EMOTE_1: + me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NOSHEATHE); + break; + case EVENT_INTRO_CHARGE: + me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); + me->GetMotionMaster()->MovePoint(POINT_TIRION_CHARGE, TirionCharge); + break; + case EVENT_OUTRO_TALK_1: + Talk(SAY_TIRION_OUTRO_1); + break; + case EVENT_OUTRO_BLESS: + DoCast(me, SPELL_LIGHTS_BLESSING); + break; + case EVENT_OUTRO_REMOVE_ICE: + me->RemoveAurasDueToSpell(SPELL_ICE_LOCK); + SetEquipmentSlots(false, EQUIP_ASHBRINGER_GLOWING); + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + { + me->SetFacing(0.0f, lichKing); + lichKing->AI()->DoAction(ACTION_PLAY_MUSIC); + } + break; + case EVENT_OUTRO_MOVE_1: + me->GetMotionMaster()->MovePoint(POINT_TIRION_OUTRO_1, OutroPosition1); + break; + case EVENT_OUTRO_JUMP: + DoCastAOE(SPELL_JUMP); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_tirion_fordringAI>(creature); + } +}; + +class npc_shambling_horror_icc : public CreatureScript +{ + public: + npc_shambling_horror_icc() : CreatureScript("npc_shambling_horror_icc") { } + + struct npc_shambling_horror_iccAI : public ScriptedAI + { + npc_shambling_horror_iccAI(Creature* creature) : ScriptedAI(creature) + { + _frenzied = false; + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_SHOCKWAVE, urand(20000, 25000)); + _events.ScheduleEvent(EVENT_ENRAGE, urand(11000, 14000)); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (IsHeroic() && me->HealthBelowPctDamaged(20, damage)) + { + _frenzied = true; + DoCast(me, SPELL_FRENZY, true); + } + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SHOCKWAVE: + DoCast(me, SPELL_SHOCKWAVE); + _events.ScheduleEvent(EVENT_SHOCKWAVE, urand(20000, 25000)); + break; + case EVENT_ENRAGE: + DoCast(me, SPELL_ENRAGE); + _events.ScheduleEvent(EVENT_ENRAGE, urand(20000, 25000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + bool _frenzied; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_shambling_horror_iccAI>(creature); + } +}; + +class npc_raging_spirit : public CreatureScript +{ + public: + npc_raging_spirit() : CreatureScript("npc_raging_spirit") { } + + struct npc_raging_spiritAI : public ScriptedAI + { + npc_raging_spiritAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_SOUL_SHRIEK, urand(12000, 15000)); + DoCast(me, SPELL_PLAGUE_AVOIDANCE, true); + DoCast(me, SPELL_RAGING_SPIRIT_VISUAL, true); + if (TempSummon* summon = me->ToTempSummon()) + if (Unit* summoner = summon->GetSummoner()) + summoner->CastSpell(me, SPELL_RAGING_SPIRIT_VISUAL_CLONE, true); + DoCast(me, SPELL_BOSS_HITTIN_YA, true); + } + + void IsSummonedBy(Unit* summoner) + { + // player is the spellcaster so register summon manually + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + lichKing->AI()->JustSummoned(me); + } + + void JustDied(Unit* killer) + { + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + lichKing->AI()->SummonedCreatureDespawn(me); + if (TempSummon* summon = me->ToTempSummon()) + summon->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN); + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SOUL_SHRIEK: + DoCastAOE(SPELL_SOUL_SHRIEK); + _events.ScheduleEvent(EVENT_SOUL_SHRIEK, urand(12000, 15000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_raging_spiritAI>(creature); + } +}; + +class npc_valkyr_shadowguard : public CreatureScript +{ + public: + npc_valkyr_shadowguard() : CreatureScript("npc_valkyr_shadowguard") { } + + struct npc_valkyr_shadowguardAI : public ScriptedAI + { + npc_valkyr_shadowguardAI(Creature* creature) : ScriptedAI(creature), + _grabbedPlayer(0), _instance(creature->GetInstanceScript()) + { + } + + void Reset() + { + _events.Reset(); + me->SetReactState(REACT_PASSIVE); + me->SetSpeed(MOVE_FLIGHT, 0.642857f, true); + } + + void IsSummonedBy(Unit* /*summoner*/) + { + _events.Reset(); + _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2500); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (!IsHeroic()) + return; + + if (!me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE)) + return; + + if (me->HealthBelowPctDamaged(50, damage)) + { + _events.Reset(); + DoCastAOE(SPELL_EJECT_ALL_PASSENGERS); + me->GetMotionMaster()->MoveTargetedHome(); + me->ClearUnitState(UNIT_STAT_EVADE); + } + } + + void JustReachedHome() + { + // schedule siphon life event (heroic only) + DoZoneInCombat(); + _events.Reset(); + _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2000); + } + + void AttackStart(Unit* /*target*/) + { + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + switch (id) + { + case POINT_DROP_PLAYER: + DoCastAOE(SPELL_EJECT_ALL_PASSENGERS); + me->DespawnOrUnsummon(1000); + break; + case POINT_CHARGE: + if (Player* target = ObjectAccessor::GetPlayer(*me, _grabbedPlayer)) + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (GameObject* platform = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_ARTHAS_PLATFORM))) + { + std::list<Creature*> triggers; + GetCreatureListWithEntryInGrid(triggers, me, NPC_WORLD_TRIGGER, 150.0f); + triggers.remove_if(HeightDifferenceCheck(platform, 5.0f, true)); + if (triggers.empty()) + return; + + triggers.sort(Trinity::ObjectDistanceOrderPred(me)); + DoCast(target, SPELL_VALKYR_CARRY); + _dropPoint.Relocate(triggers.front()); + _events.ScheduleEvent(EVENT_MOVE_TO_DROP_POS, 1500); + + } + } + else + me->DespawnOrUnsummon(); + break; + default: + break; + } + } + + void SetGUID(uint64 guid, int32 /* = 0*/) + { + _grabbedPlayer = guid; + _events.Reset(); + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_GRAB_PLAYER: + DoCastAOE(SPELL_VALKYR_TARGET_SEARCH); + _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2000); + break; + case EVENT_MOVE_TO_DROP_POS: + me->GetMotionMaster()->MovePoint(POINT_DROP_PLAYER, _dropPoint); + break; + case EVENT_LIFE_SIPHON: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_LIFE_SIPHON); + _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2500); + break; + default: + break; + } + } + + // no melee attacks + } + + private: + EventMap _events; + Position _dropPoint; + uint64 _grabbedPlayer; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_valkyr_shadowguardAI>(creature); + } +}; + +class npc_strangulate_vehicle : public CreatureScript +{ + public: + npc_strangulate_vehicle() : CreatureScript("npc_strangulate_vehicle") { } + + struct npc_strangulate_vehicleAI : public ScriptedAI + { + npc_strangulate_vehicleAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + void IsSummonedBy(Unit* summoner) + { + me->SetFacing(0.0f, summoner); + DoCast(summoner, SPELL_HARVEST_SOUL_VEHICLE); + _events.Reset(); + _events.ScheduleEvent(EVENT_MOVE_TO_LICH_KING, 2000); + _events.ScheduleEvent(EVENT_TELEPORT, 6000); + + // this will let us easily access all creatures of this entry on heroic mode when its time to teleport back + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + lichKing->AI()->JustSummoned(me); + } + + void DoAction(int32 const action) + { + if (action != ACTION_TELEPORT_BACK) + return; + + if (TempSummon* summ = me->ToTempSummon()) + if (Unit* summoner = summ->GetSummoner()) + DoCast(summoner, SPELL_HARVEST_SOUL_TELEPORT_BACK); + + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + lichKing->AI()->SummonedCreatureDespawn(me); + } + + void UpdateAI(uint32 const diff) + { + UpdateVictim(); + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_TELEPORT: + me->GetMotionMaster()->MoveIdle(MOTION_SLOT_ACTIVE); + if (TempSummon* summ = me->ToTempSummon()) + { + if (Unit* summoner = summ->GetSummoner()) + { + summoner->CastSpell((Unit*)NULL, SPELL_HARVEST_SOUL_VISUAL, true); + summoner->ExitVehicle(summoner); + if (!IsHeroic()) + summoner->CastSpell(summoner, SPELL_HARVEST_SOUL_TELEPORT, true); + else + { + summoner->CastSpell(summoner, SPELL_HARVEST_SOULS_TELEPORT, true); + summoner->RemoveAurasDueToSpell(HARVEST_SOUL, 0, 0, AURA_REMOVE_BY_EXPIRE); + } + } + } + + _events.ScheduleEvent(EVENT_DESPAWN_SELF, 65000); + break; + case EVENT_MOVE_TO_LICH_KING: + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + { + if (me->GetExactDist(lichKing) > 10.0f) + { + Position pos; + lichKing->GetNearPosition(pos, float(rand_norm()) * 5.0f + 7.5f, lichKing->GetAngle(me)); + me->GetMotionMaster()->MovePoint(0, pos); + } + } + break; + case EVENT_DESPAWN_SELF: + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + lichKing->AI()->SummonedCreatureDespawn(me); + me->DespawnOrUnsummon(1); + break; + default: + break; + } + } + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_strangulate_vehicleAI>(creature); + } +}; + +class npc_terenas_menethil : public CreatureScript +{ + public: + npc_terenas_menethil() : CreatureScript("npc_terenas_menethil") { } + + struct npc_terenas_menethilAI : public ScriptedAI + { + npc_terenas_menethilAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + bool CanAIAttack(Unit const* target) const + { + return target->GetEntry() != NPC_THE_LICH_KING; + } + + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_FROSTMOURNE_INTRO: + me->setActive(true); + if (!IsHeroic()) + me->SetHealth(me->GetMaxHealth() / 2); + DoCast(me, SPELL_LIGHTS_FAVOR); + _events.Reset(); + _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_1, 2000, PHASE_FROSTMOURNE); + _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_2, 11000, PHASE_FROSTMOURNE); + if (!IsHeroic()) + { + _events.ScheduleEvent(EVENT_DESTROY_SOUL, 60000, PHASE_FROSTMOURNE); + _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_3, 25000); + } + break; + case ACTION_TELEPORT_BACK: + me->CastSpell((Unit*)NULL, SPELL_RESTORE_SOUL, TRIGGERED_NONE); + me->DespawnOrUnsummon(3000); + break; + default: + break; + } + } + + void EnterEvadeMode() + { + // no running back home + if (!me->isAlive()) + return; + + me->DeleteThreatList(); + me->CombatStop(false); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (damage >= me->GetHealth()) + { + damage = me->GetHealth() - 1; + if (!me->HasAura(SPELL_TERENAS_LOSES_INSIDE) && !IsHeroic()) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(SPELL_TERENAS_LOSES_INSIDE); + _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000); + if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f)) + { + warden->CastSpell((Unit*)NULL, SPELL_DESTROY_SOUL, TRIGGERED_NONE); + warden->DespawnOrUnsummon(2000); + } + + me->DespawnOrUnsummon(2000); + } + } + } + + void IsSummonedBy(Unit* /*summoner*/) + { + _events.Reset(); + _events.SetPhase(PHASE_OUTRO); + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + me->SetFacing(0.0f, lichKing); + + _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_1, 2000, 0, PHASE_OUTRO); + _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_2, 14000, 0, PHASE_OUTRO); + } + + void UpdateAI(uint32 const diff) + { + UpdateVictim(); + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FROSTMOURNE_TALK_1: + Talk(SAY_TERENAS_INTRO_1); + if (IsHeroic()) + DoCastAOE(SPELL_RESTORE_SOULS); + break; + case EVENT_FROSTMOURNE_TALK_2: + Talk(SAY_TERENAS_INTRO_2); + break; + case EVENT_FROSTMOURNE_TALK_3: + Talk(SAY_TERENAS_INTRO_3); + break; + case EVENT_OUTRO_TERENAS_TALK_1: + Talk(SAY_TERENAS_OUTRO_1); + break; + case EVENT_OUTRO_TERENAS_TALK_2: + Talk(SAY_TERENAS_OUTRO_2); + DoCastAOE(SPELL_MASS_RESURRECTION); + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + { + lichKing->AI()->DoAction(ACTION_FINISH_OUTRO); + lichKing->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); + if (Creature* tirion = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + tirion->AI()->AttackStart(lichKing); + } + break; + case EVENT_DESTROY_SOUL: + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f)) + warden->CastSpell((Unit*)NULL, SPELL_DESTROY_SOUL, TRIGGERED_NONE); + DoCast(SPELL_TERENAS_LOSES_INSIDE); + _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1000); + break; + case EVENT_TELEPORT_BACK: + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING))) + lichKing->AI()->DoAction(ACTION_TELEPORT_BACK); + break; + default: + break; + } + } + + // fighting Spirit Warden + if (me->isInCombat()) + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_terenas_menethilAI>(creature); + } +}; + +class npc_spirit_warden : public CreatureScript +{ + public: + npc_spirit_warden() : CreatureScript("npc_spirit_warden") { } + + struct npc_spirit_wardenAI : public ScriptedAI + { + npc_spirit_wardenAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_SOUL_RIP, urand(12000, 15000)); + DoCast(SPELL_DARK_HUNGER); + } + + void JustDied(Unit* /*killer*/) + { + if (Creature* terenas = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_TERENAS_MENETHIL))) + terenas->AI()->DoAction(ACTION_TELEPORT_BACK); + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SOUL_RIP: + DoCastVictim(SPELL_SOUL_RIP); + _events.ScheduleEvent(EVENT_SOUL_RIP, urand(23000, 27000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_spirit_wardenAI>(creature); + } +}; + +class npc_spirit_bomb : public CreatureScript +{ + public: + npc_spirit_bomb() : CreatureScript("npc_spirit_bomb") { } + + struct npc_spirit_bombAI : public CreatureAI + { + npc_spirit_bombAI(Creature* creature) : CreatureAI(creature) + { + } + + void IsSummonedBy(Unit* summoner) + { + float destX, destY, destZ; + me->GetPosition(destX, destY); + destZ = 1055.0f; // approximation, gets more precise later + me->UpdateGroundPositionZ(destX, destY, destZ); + me->GetMotionMaster()->MovePoint(POINT_GROUND, destX, destY, destZ); + } + + void MovementInform(uint32 type, uint32 point) + { + if (type != POINT_MOTION_TYPE || point != POINT_GROUND) + return; + + me->RemoveAllAuras(); + DoCastAOE(SPELL_EXPLOSION); + me->DespawnOrUnsummon(1000); + } + + void AttackStart(Unit* /*victim*/) + { + } + + void UpdateAI(uint32 const diff) + { + UpdateVictim(); + // no melee attacks + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_spirit_bombAI>(creature); + } +}; + +class npc_broken_frostmourne : public CreatureScript +{ + public: + npc_broken_frostmourne() : CreatureScript("npc_broken_frostmourne") { } + + struct npc_broken_frostmourneAI : public CreatureAI + { + npc_broken_frostmourneAI(Creature* creature) : CreatureAI(creature) + { + } + + void Reset() + { + _events.Reset(); + } + + void IsSummonedBy(Unit* summoner) + { + _events.SetPhase(PHASE_OUTRO); + _events.ScheduleEvent(EVENT_OUTRO_KNOCK_BACK, 3000, 0, PHASE_OUTRO); + } + + void DoAction(int32 const action) + { + if (action == ACTION_SUMMON_TERENAS) + _events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6000, 0, PHASE_OUTRO); + } + + void UpdateAI(uint32 const diff) + { + UpdateVictim(); + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_OUTRO_KNOCK_BACK: + DoCastAOE(SPELL_BROKEN_FROSTMOURNE_KNOCK); + break; + case EVENT_OUTRO_SUMMON_TERENAS: + DoCastAOE(SPELL_SUMMON_TERENAS); + break; + default: + break; + } + } + + // no melee attacks + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_broken_frostmourneAI>(creature); + } +}; + +class spell_the_lich_king_infest : public SpellScriptLoader +{ + public: + spell_the_lich_king_infest() : SpellScriptLoader("spell_the_lich_king_infest") { } + + class spell_the_lich_king_infest_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_infest_AuraScript); + + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + if (GetUnitOwner()->HealthAbovePct(90)) + { + PreventDefaultAction(); + Remove(AURA_REMOVE_BY_ENEMY_SPELL); + } + } + + void OnUpdate(AuraEffect* aurEff) + { + // multiply, starting from 2nd tick + if (aurEff->GetTickNumber() == 1) + return; + + aurEff->SetAmount(int32(aurEff->GetAmount() * 1.15f)); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_infest_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_the_lich_king_infest_AuraScript::OnUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_infest_AuraScript(); + } +}; + +class spell_the_lich_king_necrotic_plague : public SpellScriptLoader +{ + public: + spell_the_lich_king_necrotic_plague() : SpellScriptLoader("spell_the_lich_king_necrotic_plague") { } + + class spell_the_lich_king_necrotic_plague_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_necrotic_plague_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_NECROTIC_PLAGUE_JUMP)) + return false; + return true; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* newCaster = GetTarget(); + switch (GetTargetApplication()->GetRemoveMode()) + { + case AURA_REMOVE_BY_ENEMY_SPELL: + case AURA_REMOVE_BY_EXPIRE: + case AURA_REMOVE_BY_DEATH: + break; + default: + return; + } + + CustomSpellValues values; + //values.AddSpellMod(SPELLVALUE_AURA_STACK, 2); + values.AddSpellMod(SPELLVALUE_MAX_TARGETS, 1); + GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID()); + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_necrotic_plague_AuraScript(); + } +}; + +class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader +{ + public: + spell_the_lich_king_necrotic_plague_jump() : SpellScriptLoader("spell_the_lich_king_necrotic_plague_jump") { } + + class spell_the_lich_king_necrotic_plague_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_necrotic_plague_SpellScript); + + bool Load() + { + _hadAura = false; + return true; + } + + void SelectTarget(std::list<Unit*>& targets) + { + targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster())); + if (targets.size() < 2) + return; + + targets.resize(1); + } + + void CheckAura() + { + if (GetHitUnit()->HasAura(GetSpellInfo()->Id)) + _hadAura = true; + } + + void AddMissingStack() + { + if (!_hadAura && GetSpellValue()->EffectBasePoints[EFFECT_1] != AURA_REMOVE_BY_ENEMY_SPELL) + GetHitAura()->ModStackAmount(1); + } + + void Register() + { + BeforeHit += SpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::CheckAura); + OnHit += SpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::AddMissingStack); + } + + bool _hadAura; + }; + + class spell_the_lich_king_necrotic_plague_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_necrotic_plague_AuraScript); + + bool Load() + { + _lastAmount = 0; + return true; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + caster->GetAI()->SetData(DATA_PLAGUE_STACK, GetStackAmount()); + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + _lastAmount = aurEff->GetAmount(); + switch (GetTargetApplication()->GetRemoveMode()) + { + case AURA_REMOVE_BY_EXPIRE: + case AURA_REMOVE_BY_DEATH: + break; + default: + return; + } + + CustomSpellValues values; + values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount()); + GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID()); + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true); + } + + void OnDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + _lastAmount = aurEff->GetAmount(); + } + + void AfterDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + // this means the stack increased so don't process as if dispelled + if (aurEff->GetAmount() > _lastAmount) + return; + + CustomSpellValues values; + values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount()); + values.AddSpellMod(SPELLVALUE_BASE_POINT1, AURA_REMOVE_BY_ENEMY_SPELL); // add as marker (spell has no effect 1) + GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID()); + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true); + + Remove(AURA_REMOVE_BY_ENEMY_SPELL); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_the_lich_king_necrotic_plague_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY); + AfterEffectApply += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::AfterDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY); + } + + int32 _lastAmount; + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_necrotic_plague_SpellScript(); + } + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_necrotic_plague_AuraScript(); + } +}; + +class spell_the_lich_king_shadow_trap_visual : public SpellScriptLoader +{ + public: + spell_the_lich_king_shadow_trap_visual() : SpellScriptLoader("spell_the_lich_king_shadow_trap_visual") { } + + class spell_the_lich_king_shadow_trap_visual_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_shadow_trap_visual_AuraScript); + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode) + { + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) + GetTarget()->CastSpell(GetTarget(), SPELL_SHADOW_TRAP_AURA, TRIGGERED_NONE); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_shadow_trap_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_shadow_trap_visual_AuraScript(); + } +}; + +class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader +{ + public: + spell_the_lich_king_shadow_trap_periodic() : SpellScriptLoader("spell_the_lich_king_shadow_trap_periodic") { } + + class spell_the_lich_king_shadow_trap_periodic_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_shadow_trap_periodic_SpellScript); + + void CheckTargetCount(std::list<Unit*>& targets) + { + if (targets.empty()) + return; + + GetCaster()->CastSpell((Unit*)NULL, SPELL_SHADOW_TRAP_KNOCKBACK, true); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_shadow_trap_periodic_SpellScript(); + } +}; + +class spell_the_lich_king_quake : public SpellScriptLoader +{ + public: + spell_the_lich_king_quake() : SpellScriptLoader("spell_the_lich_king_quake") { } + + class spell_the_lich_king_quake_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_quake_SpellScript); + + bool Load() + { + return GetCaster()->GetInstanceScript() != NULL; + } + + void FilterTargets(std::list<Unit*>& unitList) + { + if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_ARTHAS_PLATFORM))) + unitList.remove_if(HeightDifferenceCheck(platform, 5.0f, false)); + } + + void HandleSendEvent(SpellEffIndex /*effIndex*/) + { + if (GetCaster()->IsAIEnabled) + GetCaster()->GetAI()->DoAction(ACTION_START_ATTACK); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHit += SpellEffectFn(spell_the_lich_king_quake_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_quake_SpellScript(); + } +}; + +class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader +{ + public: + spell_the_lich_king_ice_burst_target_search() : SpellScriptLoader("spell_the_lich_king_ice_burst_target_search") { } + + class spell_the_lich_king_ice_burst_target_search_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_ice_burst_target_search_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BURST)) + return false; + return true; + } + + void CheckTargetCount(std::list<Unit*>& unitList) + { + if (unitList.empty()) + return; + + // if there is at least one affected target cast the explosion + GetCaster()->CastSpell(GetCaster(), SPELL_ICE_BURST, true); + if (GetCaster()->GetTypeId() == TYPEID_UNIT) + GetCaster()->ToCreature()->DespawnOrUnsummon(500); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_ice_burst_target_search_SpellScript(); + } +}; + +class spell_the_lich_king_raging_spirit : public SpellScriptLoader +{ + public: + spell_the_lich_king_raging_spirit() : SpellScriptLoader("spell_the_lich_king_raging_spirit") { } + + class spell_the_lich_king_raging_spirit_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_raging_spirit_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_LIFE_SIPHON_HEAL)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_raging_spirit_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_raging_spirit_SpellScript(); + } +}; + +class ExactDistanceCheck +{ + public: + ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {} + + bool operator()(Unit* unit) + { + return _source->GetExactDist2d(unit) > _dist; + } + + private: + Unit* _source; + float _dist; +}; + +class spell_the_lich_king_defile : public SpellScriptLoader +{ + public: + spell_the_lich_king_defile() : SpellScriptLoader("spell_the_lich_king_defile") { } + + class spell_the_lich_king_defile_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_defile_SpellScript); + + void CorrectRange(std::list<Unit*>& targets) + { + targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X))); + } + + void ChangeDamageAndGrow() + { + SetHitDamage(int32(GetHitDamage() * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X))); + // HACK: target player should cast this spell on defile + // however with current aura handling auras cast by different units + // cannot stack on the same aura object increasing the stack count + GetCaster()->CastSpell(GetCaster(), SPELL_DEFILE_GROW, true); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnHit += SpellHitFn(spell_the_lich_king_defile_SpellScript::ChangeDamageAndGrow); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_defile_SpellScript(); + } +}; + +class spell_the_lich_king_summon_into_air : public SpellScriptLoader +{ + public: + spell_the_lich_king_summon_into_air() : SpellScriptLoader("spell_the_lich_king_summon_into_air") { } + + class spell_the_lich_king_summon_into_air_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_summon_into_air_SpellScript); + + void ModDestHeight(SpellEffIndex effIndex) + { + static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f}; + WorldLocation* dest = const_cast<WorldLocation*>(GetTargetDest()); + dest->RelocateOffset(offset); + // spirit bombs get higher + if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB) + dest->RelocateOffset(offset); + } + + void Register() + { + OnEffectLaunch += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_summon_into_air_SpellScript(); + } +}; + +class spell_the_lich_king_soul_reaper : public SpellScriptLoader +{ + public: + spell_the_lich_king_soul_reaper() : SpellScriptLoader("spell_the_lich_king_soul_reaper") { } + + class spell_the_lich_king_soul_reaper_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_soul_reaper_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_SOUL_REAPER_BUFF)) + return false; + return true; + } + + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + if (Unit* caster = GetCaster()) + GetTarget()->CastSpell(caster, SPELL_SOUL_REAPER_BUFF, true); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_reaper_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_soul_reaper_AuraScript(); + } +}; + +class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader +{ + public: + spell_the_lich_king_valkyr_target_search() : SpellScriptLoader("spell_the_lich_king_valkyr_target_search") { } + + class spell_the_lich_king_valkyr_target_search_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_valkyr_target_search_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BURST)) + return false; + return true; + } + + bool Load() + { + _target = NULL; + return true; + } + + void SelectTarget(std::list<Unit*>& unitList) + { + if (unitList.empty()) + return; + + unitList.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id)); + if (unitList.empty()) + return; + + _target = SelectRandomContainerElement(unitList); + unitList.clear(); + unitList.push_back(_target); + GetCaster()->GetAI()->SetGUID(_target->GetGUID()); + } + + void ReplaceTarget(std::list<Unit*>& unitList) + { + unitList.clear(); + if (_target) + unitList.push_back(_target); + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), SPELL_CHARGE, true); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_valkyr_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + + Unit* _target; + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_valkyr_target_search_SpellScript(); + } +}; + +class spell_the_lich_king_eject_all_passengers : public SpellScriptLoader +{ + public: + spell_the_lich_king_eject_all_passengers() : SpellScriptLoader("spell_the_lich_king_eject_all_passengers") { } + + class spell_the_lich_king_eject_all_passengers_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_eject_all_passengers_SpellScript); + + bool Load() + { + return GetCaster()->IsVehicle(); + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->GetVehicleKit()->RemoveAllPassengers(); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_eject_all_passengers_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_eject_all_passengers_SpellScript(); + } +}; + +class spell_the_lich_king_cast_back_to_caster : public SpellScriptLoader +{ + public: + spell_the_lich_king_cast_back_to_caster() : SpellScriptLoader("spell_the_lich_king_cast_back_to_caster") { } + + class spell_the_lich_king_cast_back_to_caster_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_cast_back_to_caster_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_cast_back_to_caster_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_cast_back_to_caster_SpellScript(); + } +}; + +class spell_the_lich_king_life_siphon : public SpellScriptLoader +{ + public: + spell_the_lich_king_life_siphon() : SpellScriptLoader("spell_the_lich_king_life_siphon") { } + + class spell_the_lich_king_life_siphon_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_life_siphon_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_LIFE_SIPHON_HEAL)) + return false; + return true; + } + + void TriggerHeal() + { + GetHitUnit()->CastCustomSpell(SPELL_LIFE_SIPHON_HEAL, SPELLVALUE_BASE_POINT0, GetHitDamage() * 10, GetCaster(), true); + } + + void Register() + { + AfterHit += SpellHitFn(spell_the_lich_king_life_siphon_SpellScript::TriggerHeal); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_life_siphon_SpellScript(); + } +}; + +class spell_the_lich_king_vile_spirits : public SpellScriptLoader +{ + public: + spell_the_lich_king_vile_spirits() : SpellScriptLoader("spell_the_lich_king_vile_spirits") { } + + class spell_the_lich_king_vile_spirits_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_vile_spirits_AuraScript); + + bool Load() + { + _is25Man = GetUnitOwner()->GetMap()->Is25ManRaid(); + return true; + } + + void OnPeriodic(AuraEffect const* aurEff) + { + if (_is25Man || ((aurEff->GetTickNumber() - 1) % 5)) + GetTarget()->CastSpell((Unit*)NULL, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, NULL, aurEff, GetCasterGUID()); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_vile_spirits_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + + bool _is25Man; + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_vile_spirits_AuraScript(); + } +}; + +class spell_the_lich_king_vile_spirits_visual : public SpellScriptLoader +{ + public: + spell_the_lich_king_vile_spirits_visual() : SpellScriptLoader("spell_the_lich_king_vile_spirits_visual") { } + + class spell_the_lich_king_vile_spirits_visual_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_vile_spirits_visual_SpellScript); + + void ModDestHeight(SpellEffIndex /*effIndex*/) + { + Position offset = {0.0f, 0.0f, 15.0f, 0.0f}; + const_cast<WorldLocation*>(GetTargetDest())->RelocateOffset(offset); + } + + void Register() + { + OnEffectLaunch += SpellEffectFn(spell_the_lich_king_vile_spirits_visual_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_vile_spirits_visual_SpellScript(); + } +}; + +class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoader +{ + public: + spell_the_lich_king_vile_spirit_move_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_move_target_search") { } + + class spell_the_lich_king_vile_spirit_move_target_search_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_vile_spirit_move_target_search_SpellScript); + + bool Load() + { + _target = NULL; + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void SelectTarget(std::list<Unit*>& targets) + { + if (targets.empty()) + return; + + _target = SelectRandomContainerElement(targets); + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + // for this spell, all units are in target map, however it should select one to attack + if (GetHitUnit() != _target) + return; + + GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit()); + GetCaster()->AddThreat(GetHitUnit(), 100000.0f); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + + Unit* _target; + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_vile_spirit_move_target_search_SpellScript(); + } +}; + +class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptLoader +{ + public: + spell_the_lich_king_vile_spirit_damage_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_damage_target_search") { } + + class spell_the_lich_king_vile_spirit_damage_target_search_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void CheckTargetCount(std::list<Unit*>& targets) + { + if (targets.empty()) + return; + + // this spell has SPELL_AURA_BLOCK_SPELL_FAMILY so every next cast of this + // searcher spell will be blocked + if (TempSummon* summon = GetCaster()->ToTempSummon()) + if (Unit* summoner = summon->GetSummoner()) + summoner->GetAI()->SetData(DATA_VILE, 1); + GetCaster()->CastSpell((Unit*)NULL, SPELL_SPIRIT_BURST, true); + GetCaster()->ToCreature()->DespawnOrUnsummon(3000); + GetCaster()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + + Unit* _target; + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_vile_spirit_damage_target_search_SpellScript(); + } +}; + +class spell_the_lich_king_harvest_soul : public SpellScriptLoader +{ + public: + spell_the_lich_king_harvest_soul() : SpellScriptLoader("spell_the_lich_king_harvest_soul") { } + + class spell_the_lich_king_harvest_soul_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_harvest_soul_AuraScript); + + bool Load() + { + return GetOwner()->GetInstanceScript() != NULL; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // m_originalCaster to allow stacking from different casters, meh + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH) + GetTarget()->CastSpell((Unit*)NULL, SPELL_HARVESTED_SOUL, true, NULL, NULL, GetTarget()->GetInstanceScript()->GetData64(DATA_THE_LICH_KING)); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_harvest_soul_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_harvest_soul_AuraScript(); + } +}; + +class spell_the_lich_king_lights_favor : public SpellScriptLoader +{ + public: + spell_the_lich_king_lights_favor() : SpellScriptLoader("spell_the_lich_king_lights_favor") { } + + class spell_the_lich_king_lights_favor_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_lights_favor_AuraScript); + + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + if (Unit* caster = GetCaster()) + if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1)) + effect->RecalculateAmount(caster); + } + + void CalculateBonus(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + canBeRecalculated = true; + amount = 0; + if (Unit* caster = GetCaster()) + amount = int32(caster->GetHealthPct()); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_lights_favor_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_the_lich_king_lights_favor_AuraScript::CalculateBonus, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_lights_favor_AuraScript(); + } +}; + +class spell_the_lich_king_soul_rip : public SpellScriptLoader +{ + public: + spell_the_lich_king_soul_rip() : SpellScriptLoader("spell_the_lich_king_soul_rip") { } + + class spell_the_lich_king_soul_rip_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_soul_rip_AuraScript); + + void OnPeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + // shouldn't be needed, this is channeled + if (Unit* caster = GetCaster()) + caster->CastCustomSpell(SPELL_SOUL_RIP_DAMAGE, SPELLVALUE_BASE_POINT0, 5000 * aurEff->GetTickNumber(), GetTarget(), true, NULL, aurEff, GetCasterGUID()); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_rip_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_soul_rip_AuraScript(); + } +}; + +class spell_the_lich_king_restore_soul : public SpellScriptLoader +{ + public: + spell_the_lich_king_restore_soul() : SpellScriptLoader("spell_the_lich_king_restore_soul") { } + + class spell_the_lich_king_restore_soul_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_restore_soul_SpellScript); + + bool Load() + { + _instance = GetCaster()->GetInstanceScript(); + return _instance != NULL; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Creature* lichKing = ObjectAccessor::GetCreature(*GetCaster(), _instance->GetData64(DATA_THE_LICH_KING))) + lichKing->AI()->DoAction(ACTION_TELEPORT_BACK); + if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f)) + spawner->RemoveAllAuras(); + } + + void RemoveAura() + { + if (Unit* target = GetHitUnit()) + target->RemoveAurasDueToSpell(target->GetMap()->IsHeroic() ? SPELL_HARVEST_SOULS_TELEPORT : SPELL_HARVEST_SOUL_TELEPORT); + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_the_lich_king_restore_soul_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + BeforeHit += SpellHitFn(spell_the_lich_king_restore_soul_SpellScript::RemoveAura); + } + + InstanceScript* _instance; + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_restore_soul_SpellScript(); + } +}; + +class spell_the_lich_king_in_frostmourne_room : public SpellScriptLoader +{ + public: + spell_the_lich_king_in_frostmourne_room() : SpellScriptLoader("spell_the_lich_king_in_frostmourne_room") { } + + class spell_the_lich_king_in_frostmourne_room_AuraScript : public AuraScript + { + PrepareAuraScript(spell_the_lich_king_in_frostmourne_room_AuraScript); + + bool Load() + { + return GetOwner()->GetInstanceScript() != NULL; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + // m_originalCaster to allow stacking from different casters, meh + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH) + GetTarget()->CastSpell((Unit*)NULL, SPELL_HARVESTED_SOUL, true, NULL, NULL, GetTarget()->GetInstanceScript()->GetData64(DATA_THE_LICH_KING)); + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_in_frostmourne_room_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_the_lich_king_in_frostmourne_room_AuraScript(); + } +}; + +class spell_the_lich_king_summon_spirit_bomb : public SpellScriptLoader +{ + public: + spell_the_lich_king_summon_spirit_bomb() : SpellScriptLoader("spell_the_lich_king_summon_spirit_bomb") { } + + class spell_the_lich_king_summon_spirit_bomb_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_summon_spirit_bomb_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell((Unit*)NULL, uint32(GetEffectValue()), true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_summon_spirit_bomb_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_summon_spirit_bomb_SpellScript(); + } +}; + +class spell_the_lich_king_trigger_vile_spirit : public SpellScriptLoader +{ + public: + spell_the_lich_king_trigger_vile_spirit() : SpellScriptLoader("spell_the_lich_king_trigger_vile_spirit") { } + + class spell_the_lich_king_trigger_vile_spirit_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_trigger_vile_spirit_SpellScript); + + void TeleportOutside() + { + Creature* target = GetHitCreature(); + if (!target) + return; + + Position dest; + Position offset; + TerenasSpawnHeroic.GetPositionOffsetTo(*target, offset); + GetCaster()->GetPosition(&dest); + dest.RelocateOffset(offset); + target->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation()); + } + + void Register() + { + OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::TeleportOutside); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_trigger_vile_spirit_SpellScript(); + } +}; + +class spell_the_lich_king_jump : public SpellScriptLoader +{ + public: + spell_the_lich_king_jump() : SpellScriptLoader("spell_the_lich_king_jump") { } + + class spell_the_lich_king_jump_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_jump_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->RemoveAurasDueToSpell(SPELL_RAISE_DEAD); + GetHitUnit()->CastSpell((Unit*)NULL, SPELL_JUMP_2, true); + if (Creature* creature = GetHitCreature()) + creature->AI()->DoAction(ACTION_BREAK_FROSTMOURNE); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_jump_SpellScript(); + } +}; + +class spell_the_lich_king_jump_remove_aura : public SpellScriptLoader +{ + public: + spell_the_lich_king_jump_remove_aura() : SpellScriptLoader("spell_the_lich_king_jump_remove_aura") { } + + class spell_the_lich_king_jump_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_jump_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->RemoveAurasDueToSpell(uint32(GetEffectValue())); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_jump_SpellScript(); + } +}; + +class spell_the_lich_king_play_movie : public SpellScriptLoader +{ + public: + spell_the_lich_king_play_movie() : SpellScriptLoader("spell_the_lich_king_play_movie") { } + + class spell_the_lich_king_play_movie_SpellScript : public SpellScript + { + PrepareSpellScript(spell_the_lich_king_play_movie_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sMovieStore.LookupEntry(MOVIE_FALL_OF_THE_LICH_KING)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* player = GetHitPlayer()) + player->SendMovieStart(MOVIE_FALL_OF_THE_LICH_KING); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_play_movie_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_the_lich_king_play_movie_SpellScript(); + } +}; + +class achievement_been_waiting_long_time : public AchievementCriteriaScript +{ + public: + achievement_been_waiting_long_time() : AchievementCriteriaScript("achievement_been_waiting_long_time") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + if (!target) + return false; + + return target->GetAI()->GetData(DATA_PLAGUE_STACK) >= 30; + } +}; + +class achievement_neck_deep_in_vile : public AchievementCriteriaScript +{ + public: + achievement_neck_deep_in_vile() : AchievementCriteriaScript("achievement_neck_deep_in_vile") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + if (!target) + return false; + + return !target->GetAI()->GetData(DATA_VILE); + } +}; + +void AddSC_boss_the_lich_king() +{ + new boss_the_lich_king(); + new npc_tirion_fordring_tft(); + new npc_shambling_horror_icc(); + new npc_raging_spirit(); + new npc_valkyr_shadowguard(); + new npc_strangulate_vehicle(); + new npc_terenas_menethil(); + new npc_spirit_warden(); + new npc_spirit_bomb(); + new npc_broken_frostmourne(); + new spell_the_lich_king_infest(); + new spell_the_lich_king_necrotic_plague(); + new spell_the_lich_king_necrotic_plague_jump(); + new spell_the_lich_king_shadow_trap_visual(); + new spell_the_lich_king_shadow_trap_periodic(); + new spell_the_lich_king_quake(); + new spell_the_lich_king_ice_burst_target_search(); + new spell_the_lich_king_raging_spirit(); + new spell_the_lich_king_defile(); + new spell_the_lich_king_summon_into_air(); + new spell_the_lich_king_soul_reaper(); + new spell_the_lich_king_valkyr_target_search(); + new spell_the_lich_king_eject_all_passengers(); + new spell_the_lich_king_cast_back_to_caster(); + new spell_the_lich_king_life_siphon(); + new spell_the_lich_king_vile_spirits(); + new spell_the_lich_king_vile_spirits_visual(); + new spell_the_lich_king_vile_spirit_move_target_search(); + new spell_the_lich_king_vile_spirit_damage_target_search(); + new spell_the_lich_king_harvest_soul(); + new spell_the_lich_king_lights_favor(); + new spell_the_lich_king_soul_rip(); + new spell_the_lich_king_restore_soul(); + new spell_the_lich_king_in_frostmourne_room(); + new spell_the_lich_king_summon_spirit_bomb(); + new spell_the_lich_king_trigger_vile_spirit(); + new spell_the_lich_king_jump(); + new spell_the_lich_king_jump_remove_aura(); + new spell_trigger_spell_from_caster("spell_the_lich_king_mass_resurrection", SPELL_MASS_RESURRECTION_REAL); + new spell_the_lich_king_play_movie(); + new achievement_been_waiting_long_time(); + new achievement_neck_deep_in_vile(); +} diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 26b2546fc50..ece966fcda5 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -28,22 +28,30 @@ uint32 const EncounterCount = 13; uint32 const WeeklyNPCs = 9; uint32 const MaxHeroicAttempts = 50; +// Defined in boss_valithria_dreamwalker.cpp extern Position const ValithriaSpawnPos; // Defined in boss_sindragosa.cpp extern Position const SindragosaSpawnPos; +// Defined in boss_the_lich_king.cpp +extern Position const TerenasSpawn; +extern Position const TerenasSpawnHeroic; +extern Position const SpiritWardenSpawn; // Shared spells used by more than one script enum SharedSpells { - SPELL_BERSERK = 26662, - SPELL_BERSERK2 = 47008, + SPELL_BERSERK = 26662, + SPELL_BERSERK2 = 47008, // Deathbound Ward - SPELL_STONEFORM = 70733, + SPELL_STONEFORM = 70733, // Residue Rendezvous - SPELL_ORANGE_BLIGHT_RESIDUE = 72144, - SPELL_GREEN_BLIGHT_RESIDUE = 72145, + SPELL_ORANGE_BLIGHT_RESIDUE = 72144, + SPELL_GREEN_BLIGHT_RESIDUE = 72145, + + // The Lich King + SPELL_FROSTMOURNE_TELEPORT_VISUAL = 73078, }; enum TeleporterSpells @@ -99,6 +107,9 @@ enum DataTypes DATA_CAPTAIN_RUPERT = 34, DATA_VALITHRIA_TRIGGER = 35, DATA_VALITHRIA_LICH_KING = 36, + DATA_HIGHLORD_TIRION_FORDRING = 37, + DATA_ARTHAS_PLATFORM = 38, + DATA_TERENAS_MENETHIL = 39, }; enum CreaturesIds @@ -247,7 +258,23 @@ enum CreaturesIds // The Lich King NPC_THE_LICH_KING = 36597, + NPC_HIGHLORD_TIRION_FORDRING_LK = 38995, + NPC_TERENAS_MENETHIL_FROSTMOURNE = 36823, + NPC_SPIRIT_WARDEN = 36824, + NPC_TERENAS_MENETHIL_FROSTMOURNE_H = 39217, + NPC_SHAMBLING_HORROR = 37698, + NPC_DRUDGE_GHOUL = 37695, + NPC_ICE_SPHERE = 36633, + NPC_RAGING_SPIRIT = 36701, + NPC_DEFILE = 38757, + NPC_VALKYR_SHADOWGUARD = 36609, + NPC_VILE_SPIRIT = 37799, + NPC_WICKED_SPIRIT = 39190, + NPC_STRANGULATE_VEHICLE = 36598, NPC_WORLD_TRIGGER = 22515, + NPC_WORLD_TRIGGER_INFINITE_AOI = 36171, + NPC_SPIRIT_BOMB = 39189, + NPC_FROSTMOURNE_TRIGGER = 38584, }; enum GameObjectsIds @@ -312,6 +339,20 @@ enum GameObjectsIds GO_ICE_WALL = 202396, GO_ICE_BLOCK = 201722, GO_SIGIL_OF_THE_FROSTWING = 202181, + + // The Lich King + GO_ARTHAS_PLATFORM = 202161, + GO_ARTHAS_PRECIPICE = 202078, + GO_DOODAD_ICECROWN_THRONEFROSTYWIND01 = 202188, + GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01 = 202189, + GO_DOODAD_ICESHARD_STANDING02 = 202141, + GO_DOODAD_ICESHARD_STANDING01 = 202142, + GO_DOODAD_ICESHARD_STANDING03 = 202143, + GO_DOODAD_ICESHARD_STANDING04 = 202144, + GO_DOODAD_ICECROWN_SNOWEDGEWARNING01 = 202190, + GO_FROZEN_LAVAMAN = 202436, + GO_LAVAMAN_PILLARS_CHAINED = 202437, + GO_LAVAMAN_PILLARS_UNCHAINED = 202438, }; enum AchievementCriteriaIds @@ -351,9 +392,6 @@ enum AchievementCriteriaIds enum SharedActions { - // Coldflame Traps - ACTION_STOP_TRAPS = -377440, - // Festergut ACTION_FESTERGUT_COMBAT = -366260, ACTION_FESTERGUT_GAS = -366261, @@ -374,6 +412,10 @@ enum SharedActions // Sindragosa ACTION_START_FROSTWYRM = -368530, ACTION_TRIGGER_ASPHYXIATION = -368531, + + // The Lich King + ACTION_RESTORE_LIGHT = -72262, + ACTION_FROSTMOURNE_INTRO = -36823, }; enum WeekliesICC @@ -399,6 +441,11 @@ enum WorldStatesICC WORLDSTATE_ATTEMPTS_MAX = 4942, }; +enum AreaIds +{ + AREA_THE_FROZEN_THRONE = 4859, +}; + class spell_trigger_spell_from_caster : public SpellScriptLoader { public: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index d38af614bc0..90078e44d10 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -23,6 +23,20 @@ #include "PoolMgr.h" #include "icecrown_citadel.h" +enum EventIds +{ + EVENT_QUAKE = 23437, + EVENT_SECOND_REMORSELESS_WINTER = 23507, + EVENT_TELEPORT_TO_FROSMOURNE = 23617, +}; + +enum TimedEvents +{ + EVENT_UPDATE_EXECUTION_TIME = 1, + EVENT_QUAKE_SHATTER = 2, + EVENT_REBUILD_PLATFORM = 3, +}; + DoorData const doorData[] = { {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N }, @@ -116,6 +130,13 @@ class instance_icecrown_citadel : public InstanceMapScript SpinestalkerGUID = 0; RimefangGUID = 0; TheLichKingGUID = 0; + HighlordTirionFordringGUID = 0; + TerenasMenethilGUID = 0; + ArthasPlatformGUID = 0; + ArthasPrecipiceGUID = 0; + FrozenThroneEdgeGUID = 0; + FrozenThroneWindGUID = 0; + FrozenThroneWarningGUID = 0; FrostwyrmCount = 0; SpinestalkerTrashCount = 0; RimefangTrashCount = 0; @@ -125,7 +146,6 @@ class instance_icecrown_citadel : public InstanceMapScript IsOrbWhispererEligible = true; ColdflameJetsState = NOT_STARTED; BloodQuickeningState = NOT_STARTED; - BloodQuickeningTimer = 0; BloodQuickeningMinutes = 0; } @@ -269,6 +289,13 @@ class instance_icecrown_citadel : public InstanceMapScript case NPC_THE_LICH_KING: TheLichKingGUID = creature->GetGUID(); break; + case NPC_HIGHLORD_TIRION_FORDRING_LK: + HighlordTirionFordringGUID = creature->GetGUID(); + break; + case NPC_TERENAS_MENETHIL_FROSTMOURNE: + case NPC_TERENAS_MENETHIL_FROSTMOURNE_H: + TerenasMenethilGUID = creature->GetGUID(); + break; default: break; } @@ -424,6 +451,40 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_DRINK_ME: PutricideTableGUID = go->GetGUID(); break; + case GO_ARTHAS_PLATFORM: + // this enables movement at The Frozen Throne, when printed this value is 0.000000f + // however, when represented as integer client will accept only this value + go->SetUInt32Value(GAMEOBJECT_PARENTROTATION, 5535469); + ArthasPlatformGUID = go->GetGUID(); + break; + case GO_ARTHAS_PRECIPICE: + go->SetUInt32Value(GAMEOBJECT_PARENTROTATION, 4178312); + ArthasPrecipiceGUID = go->GetGUID(); + break; + case GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01: + FrozenThroneEdgeGUID = go->GetGUID(); + break; + case GO_DOODAD_ICECROWN_THRONEFROSTYWIND01: + FrozenThroneWindGUID = go->GetGUID(); + break; + case GO_DOODAD_ICECROWN_SNOWEDGEWARNING01: + FrozenThroneWarningGUID = go->GetGUID(); + break; + case GO_FROZEN_LAVAMAN: + FrozenBolvarGUID = go->GetGUID(); + if (GetBossState(DATA_THE_LICH_KING) == DONE) + go->SetRespawnTime(7 * DAY); + break; + case GO_LAVAMAN_PILLARS_CHAINED: + PillarsChainedGUID = go->GetGUID(); + if (GetBossState(DATA_THE_LICH_KING) == DONE) + go->SetRespawnTime(7 * DAY); + break; + case GO_LAVAMAN_PILLARS_UNCHAINED: + PillarsUnchainedGUID = go->GetGUID(); + if (GetBossState(DATA_THE_LICH_KING) == DONE) + go->SetRespawnTime(7 * DAY); + break; default: break; } @@ -541,6 +602,12 @@ class instance_icecrown_citadel : public InstanceMapScript return RimefangGUID; case DATA_THE_LICH_KING: return TheLichKingGUID; + case DATA_HIGHLORD_TIRION_FORDRING: + return HighlordTirionFordringGUID; + case DATA_ARTHAS_PLATFORM: + return ArthasPlatformGUID; + case DATA_TERENAS_MENETHIL: + return TerenasMenethilGUID; default: break; } @@ -661,6 +728,14 @@ class instance_icecrown_citadel : public InstanceMapScript } break; case DATA_THE_LICH_KING: + { + // set the platform as active object to dramatically increase visibility range + // note: "active" gameobjects do not block grid unloading + if (GameObject* precipice = instance->GetGameObject(ArthasPrecipiceGUID)) + precipice->setActive(state == IN_PROGRESS); + if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID)) + platform->setActive(state == IN_PROGRESS); + if (instance->IsHeroic()) { if (state == FAIL && HeroicAttempts) @@ -672,7 +747,18 @@ class instance_icecrown_citadel : public InstanceMapScript theLichKing->DespawnOrUnsummon(); } } + + if (state == DONE) + { + if (GameObject* bolvar = instance->GetGameObject(FrozenBolvarGUID)) + bolvar->SetRespawnTime(7 * DAY); + if (GameObject* pillars = instance->GetGameObject(PillarsChainedGUID)) + pillars->SetRespawnTime(7 * DAY); + if (GameObject* pillars = instance->GetGameObject(PillarsUnchainedGUID)) + pillars->SetRespawnTime(7 * DAY); + } break; + } default: break; } @@ -798,13 +884,13 @@ class instance_icecrown_citadel : public InstanceMapScript switch (data) { case IN_PROGRESS: - BloodQuickeningTimer = 60000; + Events.ScheduleEvent(EVENT_UPDATE_EXECUTION_TIME, 60000); BloodQuickeningMinutes = 30; DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); DoUpdateWorldState(WORLDSTATE_EXECUTION_TIME, BloodQuickeningMinutes); break; case DONE: - BloodQuickeningTimer = 0; + Events.CancelEvent(EVENT_UPDATE_EXECUTION_TIME); BloodQuickeningMinutes = 0; DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); break; @@ -1050,32 +1136,103 @@ class instance_icecrown_citadel : public InstanceMapScript void Update(uint32 diff) { - if (BloodQuickeningState == IN_PROGRESS) + if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS) + return; + + Events.Update(diff); + + while (uint32 eventId = Events.ExecuteEvent()) { - if (BloodQuickeningTimer <= diff) + switch (eventId) { - --BloodQuickeningMinutes; - BloodQuickeningTimer = 60000; - if (BloodQuickeningMinutes) + case EVENT_UPDATE_EXECUTION_TIME: { - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); - DoUpdateWorldState(WORLDSTATE_EXECUTION_TIME, BloodQuickeningMinutes); + --BloodQuickeningMinutes; + if (BloodQuickeningMinutes) + { + Events.ScheduleEvent(EVENT_UPDATE_EXECUTION_TIME, 60000); + DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); + DoUpdateWorldState(WORLDSTATE_EXECUTION_TIME, BloodQuickeningMinutes); + } + else + { + BloodQuickeningState = DONE; + DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); + if (Creature* bq = instance->GetCreature(BloodQueenLanaThelGUID)) + bq->AI()->DoAction(ACTION_KILL_MINCHAR); + } + SaveToDB(); + break; } - else + case EVENT_QUAKE_SHATTER: { - BloodQuickeningState = DONE; - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); - if (Creature* bq = instance->GetCreature(BloodQueenLanaThelGUID)) - bq->AI()->DoAction(ACTION_KILL_MINCHAR); + if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID)) + platform->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); + if (GameObject* edge = instance->GetGameObject(FrozenThroneEdgeGUID)) + edge->SetGoState(GO_STATE_ACTIVE); + if (GameObject* wind = instance->GetGameObject(FrozenThroneWindGUID)) + wind->SetGoState(GO_STATE_READY); + if (GameObject* warning = instance->GetGameObject(FrozenThroneWarningGUID)) + warning->SetGoState(GO_STATE_READY); + if (Creature* theLichKing = instance->GetCreature(TheLichKingGUID)) + theLichKing->AI()->DoAction(ACTION_RESTORE_LIGHT); + break; } - SaveToDB(); + case EVENT_REBUILD_PLATFORM: + if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID)) + platform->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING); + if (GameObject* edge = instance->GetGameObject(FrozenThroneEdgeGUID)) + edge->SetGoState(GO_STATE_READY); + if (GameObject* wind = instance->GetGameObject(FrozenThroneWindGUID)) + wind->SetGoState(GO_STATE_ACTIVE); + break; + default: + break; } - else - BloodQuickeningTimer -= diff; + } + } + + void ProcessEvent(WorldObject* /*source*/, uint32 eventId) + { + switch (eventId) + { + case EVENT_QUAKE: + if (GameObject* warning = instance->GetGameObject(FrozenThroneWarningGUID)) + warning->SetGoState(GO_STATE_ACTIVE); + Events.ScheduleEvent(EVENT_QUAKE_SHATTER, 5000); + break; + case EVENT_SECOND_REMORSELESS_WINTER: + if (GameObject* platform = instance->GetGameObject(ArthasPlatformGUID)) + { + platform->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED); + Events.ScheduleEvent(EVENT_REBUILD_PLATFORM, 1500); + } + break; + case EVENT_TELEPORT_TO_FROSMOURNE: // Harvest Soul (normal mode) + if (Creature* terenas = instance->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE, TerenasSpawn, NULL, 63000)) + { + terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO); + std::list<Creature*> triggers; + GetCreatureListWithEntryInGrid(triggers, terenas, NPC_WORLD_TRIGGER_INFINITE_AOI, 100.0f); + if (!triggers.empty()) + { + triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, false)); + Unit* visual = triggers.front(); + visual->CastSpell(visual, SPELL_FROSTMOURNE_TELEPORT_VISUAL, true); + } + + if (Creature* warden = instance->SummonCreature(NPC_SPIRIT_WARDEN, SpiritWardenSpawn, NULL, 63000)) + { + terenas->AI()->AttackStart(warden); + warden->AddThreat(terenas, 300000.0f); + } + } + break; } } protected: + EventMap Events; uint64 LadyDeathwisperElevatorGUID; uint64 DeathbringerSaurfangGUID; uint64 DeathbringerSaurfangDoorGUID; @@ -1105,8 +1262,17 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 SpinestalkerGUID; uint64 RimefangGUID; uint64 TheLichKingGUID; + uint64 HighlordTirionFordringGUID; + uint64 TerenasMenethilGUID; + uint64 ArthasPlatformGUID; + uint64 ArthasPrecipiceGUID; + uint64 FrozenThroneEdgeGUID; + uint64 FrozenThroneWindGUID; + uint64 FrozenThroneWarningGUID; + uint64 FrozenBolvarGUID; + uint64 PillarsChainedGUID; + uint64 PillarsUnchainedGUID; uint32 TeamInInstance; - uint32 BloodQuickeningTimer; uint32 ColdflameJetsState; uint32 FrostwyrmCount; uint32 SpinestalkerTrashCount; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp index 22aaa74a174..16c258af756 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp @@ -276,8 +276,8 @@ public: if (timeBombTimer <= uiDiff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(pUnit, SPELL_TIME_BOMB); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(unit, SPELL_TIME_BOMB); timeBombTimer = urand(20000, 25000); } else timeBombTimer -= uiDiff; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp index 9272aa03c41..50f866ea920 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp @@ -541,9 +541,6 @@ class boss_flame_leviathan : public CreatureScript //! I also removed the spellInfo check void DoBatteringRamIfReady() { - if (me->HasUnitState(UNIT_STAT_CASTING)) - return; - if (me->isAttackReady()) { Unit* target = ObjectAccessor::GetUnit(*me, _pursueTarget); @@ -1229,7 +1226,7 @@ public: //bool OnGossipSelect(Player* player, Creature* creature, uint32 uiSender, uint32 uiAction) //{ // player->PlayerTalkClass->ClearMenus(); - // switch (uiAction) + // switch(uiAction) // { // case GOSSIP_ACTION_INFO_DEF+1: // if (player) @@ -1660,10 +1657,25 @@ class spell_pursue : public SpellScriptLoader void FilterTargets(std::list<Unit*>& targets) { - targets.remove_if (FlameLeviathanPursuedTargetSelector(GetCaster())); + targets.remove_if(FlameLeviathanPursuedTargetSelector(GetCaster())); if (targets.empty()) + { if (Creature* caster = GetCaster()->ToCreature()) caster->AI()->EnterEvadeMode(); + } + else + { + //! In the end, only one target should be selected + _target = SelectRandomContainerElement(targets); + FilterTargetsSubsequently(targets); + } + } + + void FilterTargetsSubsequently(std::list<Unit*>& targets) + { + ASSERT(_target); + targets.clear(); + targets.push_back(_target); } void HandleScript(SpellEffIndex /*eff*/) @@ -1687,8 +1699,11 @@ class spell_pursue : public SpellScriptLoader void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); OnEffectHitTarget += SpellEffectFn(spell_pursue_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA); } + + Unit* _target; }; SpellScript* GetSpellScript() const diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp index 761eed86382..33f265419e6 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp @@ -381,17 +381,19 @@ class boss_freya : public CreatureScript } } - if (Elder[0]->isAlive()) + if (Elder[0] && Elder[0]->isAlive()) { Elder[0]->CastSpell(me, SPELL_BRIGHTLEAF_ESSENCE, true); events.ScheduleEvent(EVENT_UNSTABLE_ENERGY, urand(10000, 20000)); } - if (Elder[1]->isAlive()) + + if (Elder[1] && Elder[1]->isAlive()) { Elder[1]->CastSpell(me, SPELL_STONEBARK_ESSENCE, true); events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(10000, 20000)); } - if (Elder[2]->isAlive()) + + if (Elder[2] && Elder[2]->isAlive()) { Elder[2]->CastSpell(me, SPELL_IRONBRANCH_ESSENCE, true); events.ScheduleEvent(EVENT_STRENGTHENED_IRON_ROOTS, urand(10000, 20000)); diff --git a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp index 1e17103d23d..7ba12847750 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp @@ -168,6 +168,9 @@ class achievement_defenseless : public AchievementCriteriaScript bool OnCheck(Player* /*player*/, Unit* target) { + if(!target) + return false; + InstanceScript* instance = target->GetInstanceScript(); if (!instance) return false; diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp index 318876d79e7..b02ea4bfc48 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp @@ -137,8 +137,8 @@ public: if (SpellVoidShiftTimer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_VOID_SHIFT); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_VOID_SHIFT); SpellVoidShiftTimer = 20000; } else SpellVoidShiftTimer -=diff; diff --git a/src/server/scripts/Northrend/borean_tundra.cpp b/src/server/scripts/Northrend/borean_tundra.cpp index c0fbbae1980..a0d64e38d49 100644 --- a/src/server/scripts/Northrend/borean_tundra.cpp +++ b/src/server/scripts/Northrend/borean_tundra.cpp @@ -1706,12 +1706,12 @@ public: { } - void SpellHit(Unit* pUnit, const SpellInfo* pSpell) + void SpellHit(Unit* unit, const SpellInfo* pSpell) { - if (pSpell->Id == SPELL_NEURAL_NEEDLE && pUnit->GetTypeId() == TYPEID_PLAYER) + if (pSpell->Id == SPELL_NEURAL_NEEDLE && unit->GetTypeId() == TYPEID_PLAYER) { ++uiPhase; - CasterGUID = pUnit->GetGUID(); + CasterGUID = unit->GetGUID(); } } diff --git a/src/server/scripts/Northrend/grizzly_hills.cpp b/src/server/scripts/Northrend/grizzly_hills.cpp index 80d1bf4b3c3..6ed452857aa 100644 --- a/src/server/scripts/Northrend/grizzly_hills.cpp +++ b/src/server/scripts/Northrend/grizzly_hills.cpp @@ -481,6 +481,7 @@ public: } m_uiPhase = 0; } + DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Northrend/icecrown.cpp b/src/server/scripts/Northrend/icecrown.cpp index c84228b99a4..27054b5755a 100644 --- a/src/server/scripts/Northrend/icecrown.cpp +++ b/src/server/scripts/Northrend/icecrown.cpp @@ -399,7 +399,7 @@ public: struct npc_vereth_the_cunningAI : public ScriptedAI { - npc_vereth_the_cunningAI(Creature* pCreature) : ScriptedAI(pCreature) {} + npc_vereth_the_cunningAI(Creature* creature) : ScriptedAI(creature) {} void MoveInLineOfSight(Unit* who) { diff --git a/src/server/scripts/Northrend/zuldrak.cpp b/src/server/scripts/Northrend/zuldrak.cpp index bf742a4602f..193c699f930 100644 --- a/src/server/scripts/Northrend/zuldrak.cpp +++ b/src/server/scripts/Northrend/zuldrak.cpp @@ -839,12 +839,12 @@ public: std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { - if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) { - if (pUnit->GetPositionZ() <= 286.276f) + if (unit->GetPositionZ() <= 286.276f) { me->getThreatManager().resetAllAggro(); - me->AddThreat(pUnit, 5.0f); + me->AddThreat(unit, 5.0f); break; } EnterEvadeMode(); @@ -961,12 +961,12 @@ public: std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { - if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) { - if (pUnit->GetPositionZ() <= 286.276f) + if (unit->GetPositionZ() <= 286.276f) { me->getThreatManager().resetAllAggro(); - me->AddThreat(pUnit, 5.0f); + me->AddThreat(unit, 5.0f); break; } EnterEvadeMode(); @@ -1083,7 +1083,7 @@ public: } - void EnterCombat(Unit* pUnit) + void EnterCombat(Unit* unit) { if (!SummonList.empty()) for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr) @@ -1091,7 +1091,7 @@ public: if (Creature* pTemp = Unit::GetCreature(*me, *itr)) { pTemp->m_CombatDistance = 100.0f; // ugly hack? we are not in a instance sorry. :( - pTemp->AI()->AttackStart(pUnit); + pTemp->AI()->AttackStart(unit); } } } @@ -1106,12 +1106,12 @@ public: std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) { - if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) { - if (pUnit->GetPositionZ() <= 286.276f) + if (unit->GetPositionZ() <= 286.276f) { me->getThreatManager().resetAllAggro(); - me->AddThreat(pUnit, 5.0f); + me->AddThreat(unit, 5.0f); break; } EnterEvadeMode(); diff --git a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp index 66ef35f7400..21ecab02293 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_bloodboil.cpp @@ -185,14 +185,14 @@ public: void RevertThreatOnTarget(uint64 guid) { - Unit* pUnit = NULL; - pUnit = Unit::GetUnit((*me), guid); - if (pUnit) + Unit* unit = NULL; + unit = Unit::GetUnit((*me), guid); + if (unit) { - if (DoGetThreat(pUnit)) - DoModifyThreatPercent(pUnit, -100); + if (DoGetThreat(unit)) + DoModifyThreatPercent(unit, -100); if (TargetThreat) - me->AddThreat(pUnit, TargetThreat); + me->AddThreat(unit, TargetThreat); } } diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 612065d5ee6..d602b4d2aac 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -1474,9 +1474,9 @@ public: std::vector<Unit*> eliteList; for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit && pUnit->GetEntry() == ILLIDARI_ELITE) - eliteList.push_back(pUnit); + Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (unit && unit->GetEntry() == ILLIDARI_ELITE) + eliteList.push_back(unit); } for (std::vector<Unit*>::const_iterator itr = eliteList.begin(); itr != eliteList.end(); ++itr) (*itr)->setDeathState(JUST_DIED); diff --git a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp index 4d79098689c..62e33f0913b 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp @@ -165,12 +165,12 @@ public: float Z = TeleportPoint[random].z; for (uint8 i = 0; i < 3; ++i) { - Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 1); + if (unit && unit->isAlive() && (unit->GetTypeId() == TYPEID_PLAYER)) { - TargetGUID[i] = pUnit->GetGUID(); - pUnit->CastSpell(pUnit, SPELL_TELEPORT_VISUAL, true); - DoTeleportPlayer(pUnit, X, Y, Z, pUnit->GetOrientation()); + TargetGUID[i] = unit->GetGUID(); + unit->CastSpell(unit, SPELL_TELEPORT_VISUAL, true); + DoTeleportPlayer(unit, X, Y, Z, unit->GetOrientation()); } } } @@ -247,12 +247,12 @@ public: { for (uint8 i = 0; i < 3; ++i) { - Unit* pUnit = NULL; + Unit* unit = NULL; if (TargetGUID[i]) { - pUnit = Unit::GetUnit((*me), TargetGUID[i]); - if (pUnit) - pUnit->CastSpell(pUnit, SPELL_ATTRACTION, true); + unit = Unit::GetUnit((*me), TargetGUID[i]); + if (unit) + unit->CastSpell(unit, SPELL_ATTRACTION, true); TargetGUID[i] = 0; } } diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index 746ad9aa7ff..c3bb4ee3d2b 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -216,12 +216,12 @@ public: std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); for (; itr != m_threatlist.end(); ++itr) { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit) + Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (unit) { - DoModifyThreatPercent(pUnit, -100); - float threat = target->getThreatManager().getThreat(pUnit); - me->AddThreat(pUnit, threat); // This makes it so that the unit has the same amount of threat in Reliquary's threatlist as in the target creature's (One of the Essences). + DoModifyThreatPercent(unit, -100); + float threat = target->getThreatManager().getThreat(unit); + me->AddThreat(unit, threat); // This makes it so that the unit has the same amount of threat in Reliquary's threatlist as in the target creature's (One of the Essences). } } } @@ -438,9 +438,9 @@ public: std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); for (; itr != m_threatlist.end(); ++itr) { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER)) // Only alive players - targets.push_back(pUnit); + Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (unit && unit->isAlive() && (unit->GetTypeId() == TYPEID_PLAYER)) // Only alive players + targets.push_back(unit); } if (targets.empty()) return; // No targets added for some reason. No point continuing. diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp index 04646fb10bc..cced0207ca1 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -821,14 +821,14 @@ public: { bool Yelled = false; for (std::list<uint64>::const_iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) - if (Creature* pUnit = Unit::GetCreature(*me, *itr)) + if (Creature* unit = Unit::GetCreature(*me, *itr)) { if (!Yelled) { - DoScriptText(SAY_BROKEN_FREE_01, pUnit); + DoScriptText(SAY_BROKEN_FREE_01, unit); Yelled = true; } - pUnit->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + unit->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); } } ++EndingTalkCount; @@ -838,9 +838,9 @@ public: if (!BrokenList.empty()) { for (std::list<uint64>::const_iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) - if (Creature* pUnit = Unit::GetCreature(*me, *itr)) + if (Creature* unit = Unit::GetCreature(*me, *itr)) // This is the incorrect spell, but can't seem to find the right one. - pUnit->CastSpell(pUnit, 39656, true); + unit->CastSpell(unit, 39656, true); } ++EndingTalkCount; SoulRetrieveTimer = 5000; @@ -849,8 +849,8 @@ public: if (!BrokenList.empty()) { for (std::list<uint64>::const_iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) - if (Creature* pUnit = Unit::GetCreature((*me), *itr)) - pUnit->MonsterYell(SAY_BROKEN_FREE_02, LANG_UNIVERSAL, 0); + if (Creature* unit = Unit::GetCreature((*me), *itr)) + unit->MonsterYell(SAY_BROKEN_FREE_02, LANG_UNIVERSAL, 0); } SoulRetrieveTimer = 0; break; diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index 4b235906505..6785f7e4e9e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -177,13 +177,13 @@ public: std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && me->IsWithinMeleeRange(pUnit)) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && me->IsWithinMeleeRange(unit)) { - if (pUnit->GetHealth() > health) + if (unit->GetHealth() > health) { - health = pUnit->GetHealth(); - target = pUnit; + health = unit->GetHealth(); + target = unit; } } } diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index 0d3301ec29b..53e5fae888e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -173,9 +173,9 @@ public: std::list<Unit*> targets; for (; itr != m_threatlist.end(); ++itr) { - Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); - if (pUnit && pUnit->isAlive()) - targets.push_back(pUnit); + Unit* unit = Unit::GetUnit((*me), (*itr)->getUnitGuid()); + if (unit && unit->isAlive()) + targets.push_back(unit); } targets.sort(Trinity::ObjectDistanceOrderPred(me)); Unit* target = targets.front(); @@ -322,11 +322,11 @@ public: std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); for (i = m_threatlist.begin(); i != m_threatlist.end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && pUnit->isAlive()) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && unit->isAlive()) { - float threat = DoGetThreat(pUnit); - Blossom->AddThreat(pUnit, threat); + float threat = DoGetThreat(unit); + Blossom->AddThreat(unit, threat); } } } @@ -389,9 +389,9 @@ public: Done = true; if (AggroTargetGUID) { - Unit* pUnit = Unit::GetUnit((*me), AggroTargetGUID); - if (pUnit) - AttackStart(pUnit); + Unit* unit = Unit::GetUnit((*me), AggroTargetGUID); + if (unit) + AttackStart(unit); DoZoneInCombat(); } diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index 7d698559197..71ee7d06f32 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -419,10 +419,10 @@ struct boss_illidari_councilAI : public ScriptedAI { for (uint8 i = 0; i < 4; ++i) { - if (Unit* pUnit = Unit::GetUnit(*me, Council[i])) - if (pUnit != me && pUnit->getVictim()) + if (Unit* unit = Unit::GetUnit(*me, Council[i])) + if (unit != me && unit->getVictim()) { - AttackStart(pUnit->getVictim()); + AttackStart(unit->getVictim()); return; } } @@ -437,11 +437,11 @@ struct boss_illidari_councilAI : public ScriptedAI damage /= 4; for (uint8 i = 0; i < 4; ++i) { - if (Creature* pUnit = Unit::GetCreature(*me, Council[i])) - if (pUnit != me && damage < pUnit->GetHealth()) + if (Creature* unit = Unit::GetCreature(*me, Council[i])) + if (unit != me && damage < unit->GetHealth()) { - pUnit->ModifyHealth(-int32(damage)); - pUnit->LowerPlayerDamageReq(damage); + unit->ModifyHealth(-int32(damage)); + unit->LowerPlayerDamageReq(damage); } } } @@ -504,15 +504,15 @@ public: Unit* SelectCouncilMember() { - Unit* pUnit = me; + Unit* unit = me; uint32 member = 0; // He chooses Lady Malande most often if (rand()%10 == 0) // But there is a chance he picks someone else. member = urand(1, 3); if (member != 2) // No need to create another pointer to us using Unit::GetUnit - pUnit = Unit::GetUnit((*me), Council[member]); - return pUnit; + unit = Unit::GetUnit((*me), Council[member]); + return unit; } void CastAuraOnCouncil() @@ -525,9 +525,9 @@ public: } for (uint8 i = 0; i < 4; ++i) { - Unit* pUnit = Unit::GetUnit((*me), Council[i]); - if (pUnit) - pUnit->CastSpell(pUnit, spellid, true, 0, 0, me->GetGUID()); + Unit* unit = Unit::GetUnit((*me), Council[i]); + if (unit) + unit->CastSpell(unit, spellid, true, 0, 0, me->GetGUID()); } } @@ -538,12 +538,12 @@ public: if (BlessingTimer <= diff) { - if (Unit* pUnit = SelectCouncilMember()) + if (Unit* unit = SelectCouncilMember()) { switch (urand(0, 1)) { - case 0: DoCast(pUnit, SPELL_BLESS_SPELLWARD); break; - case 1: DoCast(pUnit, SPELL_BLESS_PROTECTION); break; + case 0: DoCast(unit, SPELL_BLESS_SPELLWARD); break; + case 1: DoCast(unit, SPELL_BLESS_PROTECTION); break; } } BlessingTimer = 60000; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp index 6564972fd46..141e5d1c277 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp @@ -707,15 +707,15 @@ public: if (Heal_Timer <= diff) { // It can be cast on any of the mobs - Unit* pUnit = NULL; + Unit* unit = NULL; - while (pUnit == NULL || !pUnit->isAlive()) + while (unit == NULL || !unit->isAlive()) { - pUnit = selectAdvisorUnit(); + unit = selectAdvisorUnit(); } - if (pUnit && pUnit->isAlive()) - DoCast(pUnit, SPELL_HEAL); + if (unit && unit->isAlive()) + DoCast(unit, SPELL_HEAL); Heal_Timer = 60000; } else Heal_Timer -= diff; @@ -724,26 +724,26 @@ public: Unit* selectAdvisorUnit() { - Unit* pUnit = NULL; + Unit* unit = NULL; if (pInstance) { switch (rand()%4) { case 0: - pUnit = Unit::GetUnit((*me), pInstance->GetData64(DATA_KARATHRESS)); + unit = Unit::GetUnit((*me), pInstance->GetData64(DATA_KARATHRESS)); break; case 1: - pUnit = Unit::GetUnit((*me), pInstance->GetData64(DATA_SHARKKIS)); + unit = Unit::GetUnit((*me), pInstance->GetData64(DATA_SHARKKIS)); break; case 2: - pUnit = Unit::GetUnit((*me), pInstance->GetData64(DATA_TIDALVESS)); + unit = Unit::GetUnit((*me), pInstance->GetData64(DATA_TIDALVESS)); break; case 3: - pUnit = me; + unit = me; break; } - } else pUnit = me; - return pUnit; + } else unit = me; + return unit; } }; }; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index f3da63af38b..e1b3ab1308f 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -96,9 +96,9 @@ public: } void JustDied(Unit* /*victim*/) { - Unit* pUnit = Unit::GetUnit((*me), victimGUID); - if (pUnit && pUnit->HasAura(SPELL_INSIDIOUS_WHISPER)) - pUnit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER); + Unit* unit = Unit::GetUnit((*me), victimGUID); + if (unit && unit->HasAura(SPELL_INSIDIOUS_WHISPER)) + unit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER); } void DamageTaken(Unit* done_by, uint32 &damage) @@ -353,13 +353,13 @@ public: { if (InnderDemon[i] > 0) { - Creature* pUnit = Unit::GetCreature((*me), InnderDemon[i]); - if (pUnit && pUnit->isAlive()) + Creature* unit = Unit::GetCreature((*me), InnderDemon[i]); + if (unit && unit->isAlive()) { - Unit* unit_target = Unit::GetUnit(*pUnit, CAST_AI(mob_inner_demon::mob_inner_demonAI, pUnit->AI())->victimGUID); + Unit* unit_target = Unit::GetUnit(*unit, CAST_AI(mob_inner_demon::mob_inner_demonAI, unit->AI())->victimGUID); if (unit_target && unit_target->isAlive()) { - pUnit->CastSpell(unit_target, SPELL_CONSUMING_MADNESS, true); + unit->CastSpell(unit_target, SPELL_CONSUMING_MADNESS, true); DoModifyThreatPercent(unit_target, -100); } } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 2692d6f12da..12da67f94b5 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -770,8 +770,8 @@ class boss_kaelthas : public CreatureScript if (FlameStrike_Timer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_FLAME_STRIKE); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_FLAME_STRIKE); FlameStrike_Timer = 30000; } @@ -784,7 +784,7 @@ class boss_kaelthas : public CreatureScript for (uint32 i = 0; i < 3; ++i) { sLog->outDebug(LOG_FILTER_TSCR, "SD2: Kael'Thas mind control not supported."); - //DoCast(pUnit, SPELL_MIND_CONTROL); + //DoCast(unit, SPELL_MIND_CONTROL); } MindControl_Timer = 60000; @@ -892,11 +892,11 @@ class boss_kaelthas : public CreatureScript // 1) Kael'thas will portal the whole raid right into his body for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); - if (pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER)) + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + if (unit && (unit->GetTypeId() == TYPEID_PLAYER)) { //Use work around packet to prevent player from being dropped from combat - DoTeleportPlayer(pUnit, afGravityPos[0], afGravityPos[1], afGravityPos[2], pUnit->GetOrientation()); + DoTeleportPlayer(unit, afGravityPos[0], afGravityPos[1], afGravityPos[2], unit->GetOrientation()); } } @@ -913,20 +913,20 @@ class boss_kaelthas : public CreatureScript // 2) At that point he will put a Gravity Lapse debuff on everyone for (i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i) { - if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid())) { - DoCast(pUnit, SPELL_KNOCKBACK, true); + DoCast(unit, SPELL_KNOCKBACK, true); //Gravity lapse - needs an exception in Spell system to work - pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE, true, 0, 0, me->GetGUID()); - pUnit->CastSpell(pUnit, SPELL_GRAVITY_LAPSE_AURA, true, 0, 0, me->GetGUID()); + unit->CastSpell(unit, SPELL_GRAVITY_LAPSE, true, 0, 0, me->GetGUID()); + unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_AURA, true, 0, 0, me->GetGUID()); //Using packet workaround WorldPacket data(12); data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); - data.append(pUnit->GetPackGUID()); + data.append(unit->GetPackGUID()); data << uint32(0); - pUnit->SendMessageToSet(&data, true); + unit->SendMessageToSet(&data, true); } } GravityLapse_Timer = 10000; @@ -946,14 +946,14 @@ class boss_kaelthas : public CreatureScript //Remove flight for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i) { - if (Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid())) { //Using packet workaround WorldPacket data(12); data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); - data.append(pUnit->GetPackGUID()); + data.append(unit->GetPackGUID()); data << uint32(0); - pUnit->SendMessageToSet(&data, true); + unit->SendMessageToSet(&data, true); } } @@ -982,8 +982,8 @@ class boss_kaelthas : public CreatureScript //NetherBeam_Timer if (NetherBeam_Timer <= diff) { - if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(pUnit, SPELL_NETHER_BEAM); + if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(unit, SPELL_NETHER_BEAM); NetherBeam_Timer = 4000; } @@ -1286,12 +1286,12 @@ class boss_grand_astromancer_capernian : public CreatureScript std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = m_threatlist.begin(); i!= m_threatlist.end(); ++i) { - Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid()); + Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid()); //if in melee range - if (pUnit && pUnit->IsWithinDistInMap(me, 5)) + if (unit && unit->IsWithinDistInMap(me, 5)) { InMeleeRange = true; - target = pUnit; + target = unit; break; } } diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp index 5b2350369f0..2ae0cce2ba2 100644 --- a/src/server/scripts/Outland/netherstorm.cpp +++ b/src/server/scripts/Outland/netherstorm.cpp @@ -809,10 +809,10 @@ public: for (std::list<HostileReference*>::const_iterator itr = AggroList.begin(); itr != AggroList.end(); ++itr) { - if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) { - if (pUnit->GetCreateMana() > 0) - UnitsWithMana.push_back(pUnit); + if (unit->GetCreateMana() > 0) + UnitsWithMana.push_back(unit); } } if (!UnitsWithMana.empty()) diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp index b16166ed904..327964e7b1e 100644 --- a/src/server/scripts/Outland/shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/shadowmoon_valley.cpp @@ -129,9 +129,9 @@ public: { if (bCanEat && !bIsEating) { - if (Unit* pUnit = Unit::GetUnit(*me, uiPlayerGUID)) + if (Unit* unit = Unit::GetUnit(*me, uiPlayerGUID)) { - if (GameObject* pGo = pUnit->FindNearestGameObject(GO_CARCASS, 10)) + if (GameObject* pGo = unit->FindNearestGameObject(GO_CARCASS, 10)) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) me->GetMotionMaster()->MovementExpired(); diff --git a/src/server/scripts/Outland/terokkar_forest.cpp b/src/server/scripts/Outland/terokkar_forest.cpp index ab3cd88ce3a..2dec7ab191d 100644 --- a/src/server/scripts/Outland/terokkar_forest.cpp +++ b/src/server/scripts/Outland/terokkar_forest.cpp @@ -95,9 +95,9 @@ public: if (done_by->GetTypeId() == TYPEID_PLAYER) if (me->HealthBelowPctDamaged(30, damage)) { - if (Group* pGroup = CAST_PLR(done_by)->GetGroup()) + if (Group* group = CAST_PLR(done_by)->GetGroup()) { - for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pGroupie = itr->getSource(); if (pGroupie && diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 30eb1538010..17849027dd4 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -295,6 +295,38 @@ class spell_dru_starfall_aoe : public SpellScriptLoader } }; +// 40121 - Swift Flight Form (Passive) +class spell_dru_swift_flight_passive : public SpellScriptLoader +{ + public: + spell_dru_swift_flight_passive() : SpellScriptLoader("spell_dru_swift_flight_passive") { } + + class spell_dru_swift_flight_passive_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_swift_flight_passive_AuraScript); + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) + { + Unit* caster = GetCaster(); + if (!caster || !caster->ToPlayer()) + return; + + if (caster->ToPlayer()->Has310Flyer(false)) + amount = 310; + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_swift_flight_passive_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_swift_flight_passive_AuraScript(); + } +}; + void AddSC_druid_spell_scripts() { new spell_dru_glyph_of_starfire(); @@ -303,4 +335,5 @@ void AddSC_druid_spell_scripts() new spell_dru_savage_defense(); new spell_dru_t10_restoration_4p_bonus(); new spell_dru_starfall_aoe(); + new spell_dru_swift_flight_passive(); } |
