diff options
6 files changed, 578 insertions, 780 deletions
diff --git a/sql/updates/world/3.3.5/2087_20_20_00_world.sql b/sql/updates/world/3.3.5/2087_20_20_00_world.sql new file mode 100644 index 00000000000..6eaa17f8732 --- /dev/null +++ b/sql/updates/world/3.3.5/2087_20_20_00_world.sql @@ -0,0 +1,50 @@ +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=47670; -- Awaken Gortok +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,1,47670,0,0,31,0,3,26687,0,0,0,0,'','Effect_0 hits Gortok Palehoof'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=47669; -- Awaken Subboss +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,1,47669,0,0,31,0,3,26683,0,0,0,0,'','Effect_0 hits Frenzied Worgen'), +(13,1,47669,0,1,31,0,3,26684,0,0,0,0,'','Effect_0 hits Ravenous Furbolg'), +(13,1,47669,0,2,31,0,3,26685,0,0,0,0,'','Effect_0 hits Massive Jormungar'), +(13,1,47669,0,3,31,0,3,26686,0,0,0,0,'','Effect_0 hits Ferocious Rhino'); + +DELETE FROM `linked_respawn` WHERE `linkedGuid`=126102; +DELETE FROM `creature` WHERE `guid` IN(126091,126092,126093,126094,126256); +DELETE FROM `creature_addon` WHERE `guid` IN(126091,126092,126093,126094,126256); +DELETE FROM `creature_summon_groups` WHERE `summonerId`=26687; -- Gortok Palehoof +INSERT INTO `creature_summon_groups` (`summonerId`,`summonerType`,`groupId`,`entry`,`position_x`,`position_y`,`position_z`,`orientation`,`summonType`,`summonTime`) VALUES +(26687,0,1,26683,262.195,-440.502,104.82 ,3.9968 ,6,6000), +(26687,0,1,26684,262.119,-463.103,104.787,2.04204,6,6000), +(26687,0,1,26685,290.781,-440.816,104.816,3.56047,6,6000), +(26687,0,1,26686,291.549,-462.653,104.824,2.67035,6,6000), +(26687,0,1,22515,238.608,-460.71 ,109.567,1.53589,8,0 ); + +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_palehoof_crazed', +'spell_palehoof_awaken_subboss', +'spell_palehoof_awaken_gortok', +'spell_palehoof_crazed_effect'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(48139,'spell_palehoof_crazed'), +(47669,'spell_palehoof_awaken_subboss'), +(47670,'spell_palehoof_awaken_gortok'), +(48146,'spell_palehoof_crazed_effect'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=48048; + +UPDATE `creature_template` SET `ScriptName`='boss_frenzied_worgen' WHERE `entry`=26683; +UPDATE `creature_template` SET `ScriptName`='boss_ravenous_furbolg' WHERE `entry`=26684; +UPDATE `creature_template` SET `ScriptName`='boss_massive_jormungar' WHERE `entry`=26685; +UPDATE `creature_template` SET `ScriptName`='boss_ferocious_rhino' WHERE `entry`=26686; +UPDATE `creature_template` SET `ScriptName`='' WHERE `entry`=26688; + +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (48261,48256,48140,48137,48105,48136,48133); +INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`) VALUES +(48261, 48261, 59268), +(48256, 48256, 59267), +(48140, 48140, 59273), +(48137, 48137, 59265), +(48105, 48105, 59263), +(48136, 48136, 59272), +(48133, 48133, 59271); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp index 628024ad8a2..b559048d876 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp @@ -15,187 +15,251 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* Script Data Start -SDName: Boss palehoof -SDAuthor: LordVanMartin -SD%Complete: -SDComment: -SDCategory: -Script Data End */ - -#include <algorithm> #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "utgarde_pinnacle.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" enum Spells { - SPELL_ARCING_SMASH = 48260, - SPELL_IMPALE = 48261, - H_SPELL_IMPALE = 59268, - SPELL_WITHERING_ROAR = 48256, - H_SPELL_WITHERING_ROAR = 59267, - SPELL_FREEZE = 16245 + // Palehoof + SPELL_ARCING_SMASH = 48260, + SPELL_IMPALE = 48261, + SPELL_IMPALE_H = 59268, + SPELL_WITHERING_ROAR = 48256, + SPELL_WITHERING_ROAR_H = 59267, + SPELL_FREEZE = 16245, + // Orb - World Trigger + SPELL_ORB_VISUAL = 48044, + SPELL_ORB_CHANNEL = 48048, + SPELL_AWAKEN_SUBBOSS = 47669, + SPELL_AWAKEN_GORTOK = 47670, + // Ravenous Furbolg + SPELL_CHAIN_LIGHTNING = 48140, + SPELL_CHAIN_LIGHTNING_H = 59273, + SPELL_CRAZED = 48139, + SPELL_CRAZED_TAUNT = 48147, + SPELL_TERRIFYING_ROAR = 48144, + // Frenzied Worgen + SPELL_MORTAL_WOUND = 48137, + SPELL_MORTAL_WOUND_H = 59265, + SPELL_ENRAGE_1 = 48138, + SPELL_ENRAGE_2 = 48142, + // Ferocious Rhino + SPELL_GORE = 48130, + SPELL_GORE_2 = 59264, + SPELL_GRIEVOUS_WOUND = 48105, + SPELL_GRIEVOUS_WOUND_H = 59263, + SPELL_STOMP = 48131, + // Massive Jormungar + SPELL_ACID_SPIT = 48132, + SPELL_ACID_SPLATTER = 48136, + SPELL_ACID_SPLATTER_H = 59272, + SPELL_POISON_BREATH = 48133, + SPELL_POISON_BREATH_H = 59271 }; -//Orb spells -enum OrbSpells +enum Events { - SPELL_ORB_VISUAL = 48044, - SPELL_ORB_CHANNEL = 48048 + EVENT_ARCING_SMASH = 1, + EVENT_IMPALE, + EVENT_WITHERING_ROAR, + EVENT_CRAZED, + EVENT_CHAIN_LIGHTNING, + EVENT_TERRIFYING_ROAR, + EVENT_MORTAL_WOUND, + EVENT_MORTAL_WOUND_2, + EVENT_ENRAGE, + EVENT_ENRAGE_2, + EVENT_GORE, + EVENT_GRIEVOUS_WOUND, + EVENT_STOMP, + EVENT_ACID_SPIT, + EVENT_ACID_SPLATTER, + EVENT_POISON_BREATH }; -//not in db -enum Yells +enum Says { - SAY_AGGRO = 0, - SAY_SLAY = 1 - //SAY_DEATH = 2 Missing in database + SAY_AGGRO = 0, + SAY_SLAY = 1, + PALEHOOF_SOUND_DEATH = 13467 }; -enum Creatures +Position const OrbPositions[2] = { - NPC_STASIS_CONTROLLER = 26688 + { 238.6077f, -460.7103f, 112.5671f }, + { 279.26f, -452.1f, 110.0f } }; -Position const moveLocs[] = +enum Misc { - { 261.6f, -449.3f, 109.5f, 0.0f }, - { 263.3f, -454.0f, 109.5f, 0.0f }, - { 291.5f, -450.4f, 109.5f, 0.0f }, - { 291.5f, -454.0f, 109.5f, 0.0f }, - { 310.0f, -453.4f, 109.5f, 0.0f }, - { 238.6f, -460.7f, 109.5f, 0.0f } + ACTION_NEXT_PHASE = 1, + ACTION_START_FIGHT = 2, + ACTION_START_ENCOUNTER = 3, + POSITION_FLY = 0, + POSITION_FINAL = 1, + SUMMON_MINIBOSSES_GROUP = 1 }; -enum Phase +class WormAttackEvent : public BasicEvent { - PHASE_FRENZIED_WORGEN, - PHASE_RAVENOUS_FURLBORG, - PHASE_MASSIVE_JORMUNGAR, - PHASE_FEROCIOUS_RHINO, - PHASE_GORTOK_PALEHOOF, - PHASE_NONE +public: + WormAttackEvent(TempSummon* owner) : BasicEvent(), _owner(owner) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override + { + _owner->SetReactState(REACT_AGGRESSIVE); + _owner->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN); + _owner->SetInCombatWithZone(); + return true; + } + +private: + TempSummon* _owner; }; -enum Misc +class OrbFinalPositionEvent : public BasicEvent { - ACTION_NEXT_PHASE, +public: + OrbFinalPositionEvent(Creature* owner) : BasicEvent(), _owner(owner) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override + { + _owner->CastCustomSpell(SPELL_AWAKEN_SUBBOSS, SPELLVALUE_MAX_TARGETS, 1, _owner); + return true; + } + +private: + Creature* _owner; }; -class boss_palehoof : public CreatureScript +class OrbAirPositionEvent : public BasicEvent { public: - boss_palehoof() : CreatureScript("boss_palehoof") { } + OrbAirPositionEvent(Creature* owner) : BasicEvent(), _owner(owner) { } - struct boss_palehoofAI : public BossAI + bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override { - boss_palehoofAI(Creature* creature) : BossAI(creature, DATA_GORTOK_PALEHOOF) - { - Initialize(); - } + _owner->SetWalk(true); + _owner->GetMotionMaster()->MovePoint(0, OrbPositions[POSITION_FLY]); + return true; + } - void Initialize() - { - /// There is a good reason to store them like this, we are going to shuffle the order. - for (uint32 i = PHASE_FRENZIED_WORGEN; i < PHASE_GORTOK_PALEHOOF; ++i) - Sequence[i] = Phase(i); +private: + Creature* _owner; +}; - /// This ensures a random order and only executes each phase once. - Trinity::Containers::RandomShuffle(Sequence); +class OrbFlyEvent : public BasicEvent +{ +public: + OrbFlyEvent(Creature* owner) : BasicEvent(), _owner(owner) { } - uiArcingSmashTimer = 15000; - uiImpaleTimer = 12000; - uiWhiteringRoarTimer = 10000; + bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override + { + _owner->SetWalk(false); + _owner->GetMotionMaster()->MovePoint(0, OrbPositions[POSITION_FINAL]); + _owner->m_Events.AddEvent(new OrbFinalPositionEvent(_owner), _owner->m_Events.CalculateTime(10000)); + return true; + } - AddCount = 0; +private: + Creature* _owner; +}; - currentPhase = PHASE_NONE; - } +class CombatStartEvent : public BasicEvent +{ +public: + CombatStartEvent(Unit* owner) : BasicEvent(), _owner(owner) { } - uint32 uiArcingSmashTimer; - uint32 uiImpaleTimer; - uint32 uiWhiteringRoarTimer; - Phase currentPhase; - uint8 AddCount; - std::array<Phase, 4> Sequence; + bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) override + { + _owner->GetAI()->DoAction(ACTION_START_FIGHT); + return true; + } - void Reset() override - { - _Reset(); +private: + Unit* _owner; +}; - Initialize(); +class boss_palehoof : public CreatureScript +{ +public: + boss_palehoof() : CreatureScript("boss_palehoof") { } - me->GetMotionMaster()->MoveTargetedHome(); + struct boss_palehoofAI : public BossAI + { + boss_palehoofAI(Creature* creature) : BossAI(creature, DATA_GORTOK_PALEHOOF), _dungeonMode(DUNGEON_MODE(2, 4)) { } - for (uint8 i = DATA_FRENZIED_WORGEN; i <= DATA_FEROCIOUS_RHINO; ++i) - if (Creature* temp = ObjectAccessor::GetCreature(*me, instance->GetGuidData(i))) - if (!temp->IsAlive()) - temp->Respawn(); + void Reset() override + { + _Reset(); + _orb.Clear(); + me->SummonCreatureGroup(SUMMON_MINIBOSSES_GROUP); + _encountersCount = 0; - if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF_SPHERE))) + if (GameObject* go = instance->GetGameObject(DATA_GORTOK_PALEHOOF_SPHERE)) { go->SetGoState(GO_STATE_READY); go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); } } - void EnterCombat(Unit* /*who*/) override + void JustSummoned(Creature* summon) override { - Talk(SAY_AGGRO); + BossAI::JustSummoned(summon); + + if (summon->GetEntry() == NPC_PALEHOOF_ORB) + _orb = summon->GetGUID(); } - void AttackStart(Unit* who) override + void EnterCombat (Unit* /*who*/) override { - if (!who) - return; - - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; + _EnterCombat(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_ARCING_SMASH, Seconds(7)); + events.ScheduleEvent(EVENT_IMPALE, Seconds(11)); + events.ScheduleEvent(EVENT_WITHERING_ROAR, Seconds(12)); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + } - if (me->Attack(who, true)) + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) { - me->AddThreat(who, 0.0f); - me->SetInCombatWith(who); - who->SetInCombatWith(me); - DoStartMovement(who); + case EVENT_ARCING_SMASH: + DoCastVictim(SPELL_ARCING_SMASH); + events.Repeat(Seconds(7)); + break; + case EVENT_IMPALE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_IMPALE); + events.Repeat(Seconds(10), Seconds(15)); + break; + case EVENT_WITHERING_ROAR: + DoCastSelf(SPELL_WITHERING_ROAR); + events.Repeat(Seconds(11)); + break; + default: + break; } } - void UpdateAI(uint32 diff) override + void JustDied(Unit* /*killer*/) override { - if (currentPhase != PHASE_GORTOK_PALEHOOF) - return; - - if (!UpdateVictim()) - return; - - if (uiArcingSmashTimer <= diff) - { - DoCast(me, SPELL_ARCING_SMASH); - uiArcingSmashTimer = urand(13000, 17000); - } else uiArcingSmashTimer -= diff; - - if (uiImpaleTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_IMPALE); - uiImpaleTimer = urand(8000, 12000); - } else uiImpaleTimer -= diff; - - if (uiWhiteringRoarTimer <= diff) - { - DoCast(me, SPELL_WITHERING_ROAR); - uiWhiteringRoarTimer = urand(8000, 12000); - } else uiWhiteringRoarTimer -= diff; - - DoMeleeAttackIfReady(); + events.Reset(); + instance->SetBossState(DATA_GORTOK_PALEHOOF, DONE); + DoPlaySoundToSet(me, PALEHOOF_SOUND_DEATH); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); } - void JustDied(Unit* /*killer*/) override + void EnterEvadeMode(EvadeReason /*why*/) override { - _JustDied(); - //Talk(SAY_DEATH); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + events.Reset(); + summons.DespawnAll(); + _DespawnAtEvade(); } void KilledUnit(Unit* who) override @@ -206,37 +270,45 @@ public: void DoAction(int32 actionId) override { - if (actionId != ACTION_NEXT_PHASE) - return; - - if (currentPhase == PHASE_NONE) + switch (actionId) { - instance->SetBossState(DATA_GORTOK_PALEHOOF, IN_PROGRESS); + case ACTION_NEXT_PHASE: + { + Creature* orb = ObjectAccessor::GetCreature(*me, _orb); + if (!orb) + return; - if (Creature* orb = me->SummonCreature(NPC_STASIS_CONTROLLER, moveLocs[5], TEMPSUMMON_CORPSE_DESPAWN)) - orb->CastSpell(me, SPELL_ORB_VISUAL, true); + _encountersCount++; + if (_encountersCount == _dungeonMode) + orb->CastSpell(orb, SPELL_AWAKEN_GORTOK, true); + else + orb->CastCustomSpell(SPELL_AWAKEN_SUBBOSS, SPELLVALUE_MAX_TARGETS, 1, orb, true); + break; + } + case ACTION_START_FIGHT: + me->RemoveAurasDueToSpell(SPELL_FREEZE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + DoZoneInCombat(); + if (Creature* orb = ObjectAccessor::GetCreature(*me, _orb)) + orb->DespawnOrUnsummon(1000); + break; + case ACTION_START_ENCOUNTER: + if (Creature* orb = ObjectAccessor::GetCreature(*me, _orb)) + { + orb->CastSpell(orb, SPELL_ORB_VISUAL, true); + orb->m_Events.AddEvent(new OrbAirPositionEvent(orb), orb->m_Events.CalculateTime(3000)); + orb->m_Events.AddEvent(new OrbFlyEvent(orb), orb->m_Events.CalculateTime(6000)); + } + break; + default: + break; } - - Phase move = PHASE_NONE; - if (AddCount >= DUNGEON_MODE(2, 4)) - move = PHASE_GORTOK_PALEHOOF; - else - move = Sequence[AddCount++]; - - // send orb to summon spot - if (Creature* orb = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_ORB))) - if (orb->IsAlive()) - orb->GetMotionMaster()->MovePoint(move, moveLocs[move]); - - currentPhase = move; } - void JustReachedHome() override - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NOT_ATTACKABLE_1|UNIT_FLAG_IMMUNE_TO_PC); - me->SetStandState(UNIT_STAND_STATE_STAND); - DoCast(me, SPELL_FREEZE); - } + private: + uint8 _dungeonMode; + uint8 _encountersCount; + ObjectGuid _orb; }; CreatureAI* GetAI(Creature* creature) const override @@ -245,623 +317,395 @@ public: } }; -//ravenous furbolg's spells -enum RavenousSpells -{ - SPELL_CHAIN_LIGHTING = 48140, - H_SPELL_CHAIN_LIGHTING = 59273, - SPELL_CRAZED = 48139, - SPELL_TERRIFYING_ROAR = 48144 -}; - -class npc_ravenous_furbolg : public CreatureScript +struct PalehoofMinionsBossAI : public BossAI { -public: - npc_ravenous_furbolg() : CreatureScript("npc_ravenous_furbolg") { } + PalehoofMinionsBossAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId) { } - CreatureAI* GetAI(Creature* creature) const override + void Reset() override { - return GetInstanceAI<npc_ravenous_furbolgAI>(creature); + me->SetCombatPulseDelay(0); + events.Reset(); + DoCastSelf(SPELL_FREEZE, true); } - struct npc_ravenous_furbolgAI : public ScriptedAI + void EnterCombat(Unit* /*who*/) override { - npc_ravenous_furbolgAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + me->SetCombatPulseDelay(5); + me->setActive(true); + ScheduleTasks(); + } - void Initialize() + void DoAction(int32 actionId) override + { + if (actionId == ACTION_START_FIGHT) { - uiChainLightingTimer = 5000; - uiCrazedTimer = 10000; - uiTerrifyingRoarTimer = 15000; + me->RemoveAurasDueToSpell(SPELL_FREEZE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + DoZoneInCombat(); } + } - uint32 uiChainLightingTimer; - uint32 uiCrazedTimer; - uint32 uiTerrifyingRoarTimer; - - InstanceScript* instance; + void JustDied(Unit* /*killer*/) override + { + if (Creature* palehoof = instance->GetCreature(DATA_GORTOK_PALEHOOF)) + palehoof->AI()->DoAction(ACTION_NEXT_PHASE); + } - void Reset() override - { - Initialize(); + void EnterEvadeMode(EvadeReason why) override + { + if (Creature* palehoof = instance->GetCreature(DATA_GORTOK_PALEHOOF)) + palehoof->AI()->EnterEvadeMode(why); + } +}; - me->GetMotionMaster()->MoveTargetedHome(); +class boss_ravenous_furbolg : public CreatureScript +{ +public: + boss_ravenous_furbolg() : CreatureScript("boss_ravenous_furbolg") { } - if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS) - { - Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF)); - if (palehoof && palehoof->IsAlive()) - palehoof->AI()->Reset(); - } - } + struct boss_ravenous_furbolgAI : public PalehoofMinionsBossAI + { + boss_ravenous_furbolgAI(Creature* creature) : PalehoofMinionsBossAI(creature, DATA_RAVENOUS_FURBOLG) { } - void UpdateAI(uint32 diff) override + void ScheduleTasks() override { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (uiChainLightingTimer <= diff) - { - DoCastVictim(SPELL_CHAIN_LIGHTING); - uiChainLightingTimer = 5000 + rand32() % 5000; - } else uiChainLightingTimer -= diff; - - if (uiCrazedTimer <= diff) - { - DoCast(me, SPELL_CRAZED); - uiCrazedTimer = 8000 + rand32() % 4000; - } else uiCrazedTimer -= diff; - - if (uiTerrifyingRoarTimer <= diff) - { - DoCast(me, SPELL_TERRIFYING_ROAR); - uiTerrifyingRoarTimer = 10000 + rand32() % 10000; - } else uiTerrifyingRoarTimer -= diff; - - DoMeleeAttackIfReady(); + events.ScheduleEvent(EVENT_CRAZED, Seconds(10)); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(12)); + events.ScheduleEvent(EVENT_TERRIFYING_ROAR, Seconds(22)); } - void AttackStart(Unit* who) override + void ExecuteEvent(uint32 eventId) override { - if (!who) - return; - - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; - - if (me->Attack(who, true)) + switch (eventId) { - me->AddThreat(who, 0.0f); - me->SetInCombatWith(who); - who->SetInCombatWith(me); - DoStartMovement(who); + case EVENT_CRAZED: + DoCastSelf(SPELL_CRAZED); + events.Repeat(Seconds(20), Seconds(25)); + break; + case EVENT_CHAIN_LIGHTNING: + DoCastVictim(SPELL_CHAIN_LIGHTNING); + events.Repeat(Seconds(11)); + break; + case EVENT_TERRIFYING_ROAR: + DoCastSelf(SPELL_TERRIFYING_ROAR); + events.Repeat(Seconds(18)); + break; + default: + break; } } - - void JustDied(Unit* /*killer*/) override - { - if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF))) - palehoof->AI()->DoAction(ACTION_NEXT_PHASE); - } - - void JustReachedHome() override - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC); - me->SetStandState(UNIT_STAND_STATE_STAND); - DoCast(me, SPELL_FREEZE); - } }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetUtgardePinnacleAI<boss_ravenous_furbolgAI>(creature); + } }; -//frenzied worgen's spells -enum FrenziedSpells -{ - SPELL_MORTAL_WOUND = 48137, - H_SPELL_MORTAL_WOUND = 59265, - SPELL_ENRAGE_1 = 48138, - SPELL_ENRAGE_2 = 48142 -}; - -class npc_frenzied_worgen : public CreatureScript +class boss_frenzied_worgen : public CreatureScript { public: - npc_frenzied_worgen() : CreatureScript("npc_frenzied_worgen") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_frenzied_worgenAI>(creature); - } + boss_frenzied_worgen() : CreatureScript("boss_frenzied_worgen") { } - struct npc_frenzied_worgenAI : public ScriptedAI + struct boss_frenzied_worgenAI : public PalehoofMinionsBossAI { - npc_frenzied_worgenAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } + boss_frenzied_worgenAI(Creature* creature) : PalehoofMinionsBossAI(creature, DATA_FRENZIED_WORGEN) { } - void Initialize() + void ScheduleTasks() override { - uiMortalWoundTimer = 5000; - uiEnrage1Timer = 15000; - uiEnrage2Timer = 10000; + events.ScheduleEvent(EVENT_MORTAL_WOUND, Seconds(6)); + events.ScheduleEvent(EVENT_ENRAGE, Seconds(16)); + events.ScheduleEvent(EVENT_ENRAGE_2, Minutes(1) + Seconds(30)); } - uint32 uiMortalWoundTimer; - uint32 uiEnrage1Timer; - uint32 uiEnrage2Timer; - - InstanceScript* instance; - - void Reset() override + void ExecuteEvent(uint32 eventId) override { - Initialize(); - - me->GetMotionMaster()->MoveTargetedHome(); - - if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS) + switch (eventId) { - Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF)); - if (palehoof && palehoof->IsAlive()) - palehoof->AI()->Reset(); + case EVENT_MORTAL_WOUND: + DoCastVictim(SPELL_MORTAL_WOUND); + events.Repeat(Seconds(6)); + break; + case EVENT_ENRAGE: + DoCastSelf(SPELL_ENRAGE_1); + events.Repeat(Seconds(25)); + break; + case EVENT_ENRAGE_2: + DoCastSelf(SPELL_ENRAGE_2); + break; + default: + break; } } + }; - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (uiMortalWoundTimer <= diff) - { - DoCastVictim(SPELL_MORTAL_WOUND); - uiMortalWoundTimer = 3000 + rand32() % 4000; - } else uiMortalWoundTimer -= diff; + CreatureAI* GetAI(Creature* creature) const override + { + return GetUtgardePinnacleAI<boss_frenzied_worgenAI>(creature); + } +}; - if (uiEnrage1Timer <= diff) - { - DoCast(me, SPELL_ENRAGE_1); - uiEnrage1Timer = 15000; - } else uiEnrage1Timer -= diff; +class boss_ferocious_rhino : public CreatureScript +{ +public: + boss_ferocious_rhino() : CreatureScript("boss_ferocious_rhino") { } - if (uiEnrage2Timer <= diff) - { - DoCast(me, SPELL_ENRAGE_2); - uiEnrage2Timer = 10000; - } else uiEnrage2Timer -= diff; + struct boss_ferocious_rhinoAI : public PalehoofMinionsBossAI + { + boss_ferocious_rhinoAI(Creature* creature) : PalehoofMinionsBossAI(creature, DATA_FEROCIOUS_RHINO) { } - DoMeleeAttackIfReady(); + void ScheduleTasks() override + { + events.ScheduleEvent(EVENT_GORE, Seconds(10)); + events.ScheduleEvent(EVENT_GRIEVOUS_WOUND, Seconds(12)); + events.ScheduleEvent(EVENT_STOMP, Seconds(5)); } - void AttackStart(Unit* who) override + void ExecuteEvent(uint32 eventId) override { - if (!who) - return; - - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; - - if (me->Attack(who, true)) + switch (eventId) { - me->AddThreat(who, 0.0f); - me->SetInCombatWith(who); - who->SetInCombatWith(me); - DoStartMovement(who); + case EVENT_GORE: + DoCastVictim(SPELL_GORE); + events.Repeat(Seconds(19)); + break; + case EVENT_GRIEVOUS_WOUND: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_GRIEVOUS_WOUND); + events.Repeat(Seconds(18)); + break; + case EVENT_STOMP: + DoCastSelf(SPELL_STOMP); + events.Repeat(Seconds(10), Seconds(15)); + break; + default: + break; } - instance->SetBossState(DATA_GORTOK_PALEHOOF, IN_PROGRESS); - } - - void JustDied(Unit* /*killer*/) override - { - if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF))) - palehoof->AI()->DoAction(ACTION_NEXT_PHASE); - } - - void JustReachedHome() override - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC); - me->SetStandState(UNIT_STAND_STATE_STAND); - DoCast(me, SPELL_FREEZE); } }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetUtgardePinnacleAI<boss_ferocious_rhinoAI>(creature); + } }; -//ferocious rhino's spells -enum FerociousSpells -{ - SPELL_GORE = 48130, - H_SPELL_GORE = 59264, - SPELL_GRIEVOUS_WOUND = 48105, - H_SPELL_GRIEVOUS_WOUND = 59263, - SPELL_STOMP = 48131 -}; - -class npc_ferocious_rhino : public CreatureScript +class boss_massive_jormungar : public CreatureScript { public: - npc_ferocious_rhino() : CreatureScript("npc_ferocious_rhino") { } + boss_massive_jormungar() : CreatureScript("boss_massive_jormungar") { } - CreatureAI* GetAI(Creature* creature) const override + struct boss_massive_jormungarAI : public PalehoofMinionsBossAI { - return GetInstanceAI<npc_ferocious_rhinoAI>(creature); - } + boss_massive_jormungarAI(Creature* creature) : PalehoofMinionsBossAI(creature, DATA_MASSIVE_JORMUNGAR) { } - struct npc_ferocious_rhinoAI : public ScriptedAI - { - npc_ferocious_rhinoAI(Creature* creature) : ScriptedAI(creature) + void ScheduleTasks() override { - Initialize(); - instance = creature->GetInstanceScript(); + events.ScheduleEvent(EVENT_ACID_SPIT, Seconds(6)); + events.ScheduleEvent(EVENT_ACID_SPLATTER, Seconds(16)); + events.ScheduleEvent(EVENT_POISON_BREATH, Seconds(13)); } - void Initialize() + void JustSummoned(Creature* summon) override { - uiStompTimer = 10000; - uiGoreTimer = 15000; - uiGrievousWoundTimer = 20000; - } - - uint32 uiStompTimer; - uint32 uiGoreTimer; - uint32 uiGrievousWoundTimer; - - InstanceScript* instance; - - void Reset() override - { - Initialize(); - - me->GetMotionMaster()->MoveTargetedHome(); - - if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS) + if (summon->GetEntry() == NPC_JORMUNGAR_WORM) { - Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF)); - if (palehoof && palehoof->IsAlive()) - palehoof->AI()->Reset(); + summon->m_Events.AddEvent(new WormAttackEvent(summon->ToTempSummon()), summon->m_Events.CalculateTime(2000)); + summon->GetMotionMaster()->MoveRandom(5.0f); } } - void UpdateAI(uint32 diff) override + void ExecuteEvent(uint32 eventId) override { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (uiStompTimer <= diff) - { - DoCastVictim(SPELL_STOMP); - uiStompTimer = 8000 + rand32() % 4000; - } else uiStompTimer -= diff; - - if (uiGoreTimer <= diff) - { - DoCastVictim(SPELL_GORE); - uiGoreTimer = 13000 + rand32() % 4000; - } else uiGoreTimer -= diff; - - if (uiGrievousWoundTimer <= diff) + switch (eventId) { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_GRIEVOUS_WOUND); - uiGrievousWoundTimer = 18000 + rand32() % 4000; - } else uiGrievousWoundTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void AttackStart(Unit* who) override - { - if (!who) - return; - - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; - - if (me->Attack(who, true)) - { - me->AddThreat(who, 0.0f); - me->SetInCombatWith(who); - who->SetInCombatWith(me); - DoStartMovement(who); + case EVENT_ACID_SPIT: + DoCastVictim(SPELL_ACID_SPIT); + events.Repeat(Seconds(7)); + break; + case EVENT_ACID_SPLATTER: + DoCastSelf(SPELL_ACID_SPLATTER); + events.Repeat(Seconds(16)); + break; + case EVENT_POISON_BREATH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_POISON_BREATH); + events.Repeat(Seconds(14)); + break; + default: + break; } } - void JustDied(Unit* /*killer*/) override - { - if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF))) - palehoof->AI()->DoAction(ACTION_NEXT_PHASE); - } - - void JustReachedHome() override + void EnterEvadeMode(EvadeReason why) override { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC); - me->SetStandState(UNIT_STAND_STATE_STAND); - DoCast(me, SPELL_FREEZE); + summons.DespawnAll(); + PalehoofMinionsBossAI::EnterEvadeMode(why); } }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetUtgardePinnacleAI<boss_massive_jormungarAI>(creature); + } }; -//massive jormungar's spells -enum MassiveSpells -{ - SPELL_ACID_SPIT = 48132, - SPELL_ACID_SPLATTER = 48136, - H_SPELL_ACID_SPLATTER = 59272, - SPELL_POISON_BREATH = 48133, - H_SPELL_POISON_BREATH = 59271 -}; - -enum MassiveAdds -{ - CREATURE_JORMUNGAR_WORM = 27228 -}; - -class npc_massive_jormungar : public CreatureScript +class go_palehoof_sphere : public GameObjectScript { public: - npc_massive_jormungar() : CreatureScript("npc_massive_jormungar") { } + go_palehoof_sphere() : GameObjectScript("go_palehoof_sphere") { } - CreatureAI* GetAI(Creature* creature) const override + bool OnGossipHello(Player* /*player*/, GameObject* go) override { - return GetInstanceAI<npc_massive_jormungarAI>(creature); - } - - struct npc_massive_jormungarAI : public ScriptedAI - { - npc_massive_jormungarAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } - - void Initialize() + if (InstanceScript* instance = go->GetInstanceScript()) { - uiAcidSpitTimer = 3000; - uiAcidSplatterTimer = 12000; - uiPoisonBreathTimer = 10000; + if (Creature* palehoof = instance->GetCreature(DATA_GORTOK_PALEHOOF)) + if (palehoof->IsAlive() && instance->GetBossState(DATA_GORTOK_PALEHOOF) != DONE) + { + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_ACTIVE); + palehoof->AI()->DoAction(ACTION_START_ENCOUNTER); + } } + return true; + } +}; - uint32 uiAcidSpitTimer; - uint32 uiAcidSplatterTimer; - uint32 uiPoisonBreathTimer; - - InstanceScript* instance; +// 48139 - Crazed +class spell_palehoof_crazed : public SpellScriptLoader +{ + public: + spell_palehoof_crazed() : SpellScriptLoader("spell_palehoof_crazed") { } - void Reset() override + class spell_palehoof_crazed_AuraScript : public AuraScript { - Initialize(); + PrepareAuraScript(spell_palehoof_crazed_AuraScript); - me->GetMotionMaster()->MoveTargetedHome(); - - if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF)); - if (palehoof && palehoof->IsAlive()) - palehoof->AI()->Reset(); + GetTarget()->RemoveAurasDueToSpell(SPELL_CRAZED_TAUNT); } - } - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (uiAcidSpitTimer <= diff) + void Register() override { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_ACID_SPIT); - uiAcidSpitTimer = 2000 + rand32() % 2000; - } else uiAcidSpitTimer -= diff; - - if (uiAcidSplatterTimer <= diff) - { - DoCast(me, SPELL_POISON_BREATH); - uiAcidSplatterTimer = 10000 + rand32() % 4000; - } else uiAcidSplatterTimer -= diff; - - if (uiPoisonBreathTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_POISON_BREATH); - uiPoisonBreathTimer = 8000 + rand32() % 4000; - } else uiPoisonBreathTimer -= diff; + OnEffectRemove += AuraEffectRemoveFn(spell_palehoof_crazed_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } + }; - DoMeleeAttackIfReady(); + AuraScript* GetAuraScript() const override + { + return new spell_palehoof_crazed_AuraScript(); } +}; - void AttackStart(Unit* who) override +class spell_palehoof_crazed_effect : public SpellScriptLoader +{ + public: spell_palehoof_crazed_effect() : SpellScriptLoader("spell_palehoof_crazed_effect") { } + + class spell_palehoof_crazed_effect_SpellScript : public SpellScript { - if (!who) - return; + PrepareSpellScript(spell_palehoof_crazed_effect_SpellScript); - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_CRAZED_TAUNT)) + return false; + return true; + } - if (me->Attack(who, true)) + void HandleScriptEffect(SpellEffIndex /* effIndex */) { - me->AddThreat(who, 0.0f); - me->SetInCombatWith(who); - who->SetInCombatWith(me); - DoStartMovement(who); + GetHitUnit()->CastSpell(GetCaster(), SPELL_CRAZED_TAUNT, true); } - } - void JustDied(Unit* /*killer*/) override - { - if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GORTOK_PALEHOOF))) - palehoof->AI()->DoAction(ACTION_NEXT_PHASE); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_palehoof_crazed_effect_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; - void JustReachedHome() override + SpellScript* GetSpellScript() const override { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC); - me->SetStandState(UNIT_STAND_STATE_STAND); - DoCast(me, SPELL_FREEZE); + return new spell_palehoof_crazed_effect_SpellScript(); } - }; - }; -class npc_palehoof_orb : public CreatureScript +// 47669 - Awaken Subbos +class spell_palehoof_awaken_subboss : public SpellScriptLoader { -public: - npc_palehoof_orb() : CreatureScript("npc_palehoof_orb") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<npc_palehoof_orbAI>(creature); - } - - struct npc_palehoof_orbAI : public ScriptedAI - { - npc_palehoof_orbAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } - - void Initialize() - { - currentPhase = PHASE_NONE; - SummonTimer = 5000; - } - - InstanceScript* instance; - uint32 SummonTimer; - Phase currentPhase; - - void Reset() override - { - Initialize(); - //! HACK: Creature's can't have MOVEMENTFLAG_FLYING - me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING); - me->RemoveAurasDueToSpell(SPELL_ORB_VISUAL); - me->SetSpeedRate(MOVE_FLIGHT, 0.5f); - } + public: + spell_palehoof_awaken_subboss() : SpellScriptLoader("spell_palehoof_awaken_subboss") { } - void UpdateAI(uint32 diff) override + class spell_palehoof_awaken_subboss_SpellScript : public SpellScript { - if (currentPhase == PHASE_NONE) - return; + PrepareSpellScript(spell_palehoof_awaken_subboss_SpellScript); - if (SummonTimer <= diff) + bool Validate(SpellInfo const* /*spellInfo*/) override { - uint8 nextBossId = 0; - switch (currentPhase) - { - case PHASE_FRENZIED_WORGEN: - nextBossId = DATA_FRENZIED_WORGEN; - break; - case PHASE_RAVENOUS_FURLBORG: - nextBossId = DATA_RAVENOUS_FURBOLG; - break; - case PHASE_MASSIVE_JORMUNGAR: - nextBossId = DATA_MASSIVE_JORMUNGAR; - break; - case PHASE_FEROCIOUS_RHINO: - nextBossId = DATA_FEROCIOUS_RHINO; - break; - case PHASE_GORTOK_PALEHOOF: - nextBossId = DATA_GORTOK_PALEHOOF; - break; - default: - return; - } - - if (Creature* nextBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(nextBossId))) - { - nextBoss->RemoveAurasDueToSpell(SPELL_FREEZE); - nextBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC); - nextBoss->SetStandState(UNIT_STAND_STATE_STAND); - nextBoss->SetInCombatWithZone(); - } - currentPhase = PHASE_NONE; - - if (nextBossId == DATA_GORTOK_PALEHOOF) - me->DespawnOrUnsummon(); + if (!sSpellMgr->GetSpellInfo(SPELL_ORB_CHANNEL)) + return false; + return true; } - else - SummonTimer -= diff; - } - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - - uint8 nextBossId = 0; - switch (id) + void HandleScript(SpellEffIndex /*effIndex*/) { - case PHASE_FRENZIED_WORGEN: - nextBossId = DATA_FRENZIED_WORGEN; - break; - case PHASE_RAVENOUS_FURLBORG: - nextBossId = DATA_RAVENOUS_FURBOLG; - break; - case PHASE_MASSIVE_JORMUNGAR: - nextBossId = DATA_MASSIVE_JORMUNGAR; - break; - case PHASE_FEROCIOUS_RHINO: - nextBossId = DATA_FEROCIOUS_RHINO; - break; - case PHASE_GORTOK_PALEHOOF: - nextBossId = DATA_GORTOK_PALEHOOF; - break; - default: - return; + Unit* target = GetHitUnit(); + GetCaster()->CastSpell(target, SPELL_ORB_CHANNEL); + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + target->m_Events.AddEvent(new CombatStartEvent(target), target->m_Events.CalculateTime(8500)); } - if (Creature* nextBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(nextBossId))) - DoCast(nextBoss, SPELL_ORB_CHANNEL, false); + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_palehoof_awaken_subboss_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; - currentPhase = Phase(id); - SummonTimer = 5000; + SpellScript* GetSpellScript() const override + { + return new spell_palehoof_awaken_subboss_SpellScript(); } - }; - }; -class go_palehoof_sphere : public GameObjectScript +// 47670 - Awaken Gortok +class spell_palehoof_awaken_gortok : public SpellScriptLoader { public: - go_palehoof_sphere() : GameObjectScript("go_palehoof_sphere") { } + spell_palehoof_awaken_gortok() : SpellScriptLoader("spell_palehoof_awaken_gortok") { } - bool OnGossipHello(Player* /*player*/, GameObject* go) override + class spell_palehoof_awaken_gortok_SpellScript : public SpellScript { - InstanceScript* instance = go->GetInstanceScript(); - if (!instance) - return false; + PrepareSpellScript(spell_palehoof_awaken_gortok_SpellScript); - Creature* palehoof = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_GORTOK_PALEHOOF)); - if (palehoof && palehoof->IsAlive()) + void HandleDummy(SpellEffIndex /*effIndex*/) { - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - go->SetGoState(GO_STATE_ACTIVE); + Unit* target = GetHitUnit(); + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + target->m_Events.AddEvent(new CombatStartEvent(target), target->m_Events.CalculateTime(8000)); + } - palehoof->AI()->DoAction(ACTION_NEXT_PHASE); + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_palehoof_awaken_gortok_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } - return true; - } + }; + SpellScript* GetSpellScript() const override + { + return new spell_palehoof_awaken_gortok_SpellScript(); + } }; void AddSC_boss_palehoof() { new boss_palehoof(); - new npc_ravenous_furbolg(); - new npc_frenzied_worgen(); - new npc_ferocious_rhino(); - new npc_massive_jormungar(); - new npc_palehoof_orb(); + new boss_ravenous_furbolg(); + new boss_frenzied_worgen(); + new boss_ferocious_rhino(); + new boss_massive_jormungar(); new go_palehoof_sphere(); + new spell_palehoof_crazed(); + new spell_palehoof_crazed_effect(); + new spell_palehoof_awaken_subboss(); + new spell_palehoof_awaken_gortok(); } diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp index a31ab6f0e50..e3b49ca46b9 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp @@ -164,7 +164,7 @@ public: _Reset(); Initialize(); me->SetReactState(REACT_PASSIVE); - if (!ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAUF))) + if (!instance->GetCreature(DATA_GRAUF)) me->SummonCreature(NPC_GRAUF, GraufLoc); instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_LODI_DODI_WE_LOVES_THE_SKADI); @@ -242,7 +242,7 @@ public: }) .Schedule(Seconds(2), [this](TaskContext /*context*/) { - if (Creature* grauf = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAUF))) + if (Creature* grauf = instance->GetCreature(DATA_GRAUF)) DoCast(grauf, SPELL_RIDE_GRAUF); }); @@ -347,7 +347,7 @@ public: void JustDied(Unit* /*killer*/) override { - if (Creature* skadi = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SKADI_THE_RUTHLESS))) + if (Creature* skadi = _instance->GetCreature(DATA_SKADI_THE_RUTHLESS)) skadi->AI()->DoAction(ACTION_GAUNTLET_END); me->DespawnOrUnsummon(6000); @@ -412,7 +412,7 @@ public: { me->GetMotionMaster()->MovePath(GRAUF_PATH_LEFT, false); DoCast(SPELL_FREEZING_CLOUD_LEFT_PERIODIC); - if (Creature* skadi = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SKADI_THE_RUTHLESS))) + if (Creature* skadi = _instance->GetCreature(DATA_SKADI_THE_RUTHLESS)) skadi->AI()->DoAction(ACTION_FLAME); }) .Schedule(Seconds(10), [this](TaskContext /*context*/) @@ -431,7 +431,7 @@ public: { me->GetMotionMaster()->MovePath(GRAUF_PATH_RIGHT, false); DoCast(SPELL_FREEZING_CLOUD_RIGHT_PERIODIC); - if (Creature* skadi = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SKADI_THE_RUTHLESS))) + if (Creature* skadi = _instance->GetCreature(DATA_SKADI_THE_RUTHLESS)) skadi->AI()->DoAction(ACTION_FLAME); }) .Schedule(Seconds(10), [this](TaskContext /*context*/) @@ -447,7 +447,7 @@ public: void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override { if (spell->Id == SPELL_LAUNCH_HARPOON) - if (Creature* skadi = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SKADI_THE_RUTHLESS))) + if (Creature* skadi = _instance->GetCreature(DATA_SKADI_THE_RUTHLESS)) skadi->AI()->DoAction(ACTION_HARPOON_HIT); } @@ -488,7 +488,7 @@ struct npc_skadi_trashAI : public ScriptedAI void IsSummonedBy(Unit* /*summoner*/) override { - if (Creature* skadi = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_SKADI_THE_RUTHLESS))) + if (Creature* skadi = _instance->GetCreature(DATA_SKADI_THE_RUTHLESS)) skadi->AI()->JustSummoned(me); } @@ -946,7 +946,7 @@ class at_skadi_gaunlet : public AreaTriggerScript if (InstanceScript* instance = player->GetInstanceScript()) { if (instance->GetBossState(DATA_SKADI_THE_RUTHLESS) == NOT_STARTED) - if (Creature* skadi = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_SKADI_THE_RUTHLESS))) + if (Creature* skadi = instance->GetCreature(DATA_SKADI_THE_RUTHLESS)) { skadi->AI()->DoAction(ACTION_START_ENCOUNTER); return true; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp index 2a0c33694c2..7eff09338fc 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp @@ -188,7 +188,7 @@ class boss_svala : public CreatureScript events.SetPhase(INTRO); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (GameObject* mirror = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_UTGARDE_MIRROR))) + if (GameObject* mirror = instance->GetGameObject(DATA_UTGARDE_MIRROR)) mirror->SetGoState(GO_STATE_READY); if (Creature* arthas = me->SummonCreature(NPC_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN)) @@ -331,7 +331,7 @@ class boss_svala : public CreatureScript break; } case EVENT_INTRO_DESPAWN_ARTHAS: - if (GameObject* mirror = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_UTGARDE_MIRROR))) + if (GameObject* mirror = instance->GetGameObject(DATA_UTGARDE_MIRROR)) mirror->SetGoState(GO_STATE_ACTIVE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp index bc94bda10a1..2afe31455ce 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp @@ -28,7 +28,30 @@ DoorData const doorData[] = { { GO_SKADI_THE_RUTHLESS_DOOR, DATA_SKADI_THE_RUTHLESS, DOOR_TYPE_PASSAGE }, { GO_KING_YMIRON_DOOR, DATA_KING_YMIRON, DOOR_TYPE_PASSAGE }, - { 0, 0, DOOR_TYPE_ROOM } // END + { 0, 0, DOOR_TYPE_ROOM } // END +}; + +ObjectData const creatureData[] = +{ + { NPC_SVALA_SORROWGRAVE, DATA_SVALA_SORROWGRAVE }, + { NPC_GORTOK_PALEHOOF, DATA_GORTOK_PALEHOOF }, + { NPC_SKADI_THE_RUTHLESS, DATA_SKADI_THE_RUTHLESS }, + { NPC_KING_YMIRON, DATA_KING_YMIRON }, + { NPC_FRENZIED_WORGEN, DATA_FRENZIED_WORGEN }, + { NPC_RAVENOUS_FURBOLG, DATA_RAVENOUS_FURBOLG }, + { NPC_MASSIVE_JORMUNGAR, DATA_MASSIVE_JORMUNGAR }, + { NPC_FEROCIOUS_RHINO, DATA_FEROCIOUS_RHINO }, + { NPC_PALEHOOF_ORB, DATA_GORTOK_ORB }, + { NPC_SVALA, DATA_SVALA }, + { NPC_GRAUF, DATA_GRAUF }, + { 0, 0 } // END +}; + +ObjectData const gameObjectData[] = +{ + { GO_UTGARDE_MIRROR, DATA_UTGARDE_MIRROR }, + { GO_GORTOK_PALEHOOF_SPHERE, DATA_GORTOK_PALEHOOF_SPHERE }, + { 0, 0 } //END }; class instance_utgarde_pinnacle : public InstanceMapScript @@ -44,158 +67,37 @@ class instance_utgarde_pinnacle : public InstanceMapScript SetBossNumber(EncounterCount); LoadBossBoundaries(boundaries); LoadDoorData(doorData); + LoadObjectData(creatureData, gameObjectData); } - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) - { - case NPC_SVALA_SORROWGRAVE: - SvalaSorrowgraveGUID = creature->GetGUID(); - break; - case NPC_GORTOK_PALEHOOF: - GortokPalehoofGUID = creature->GetGUID(); - break; - case NPC_SKADI_THE_RUTHLESS: - SkadiTheRuthlessGUID = creature->GetGUID(); - break; - case NPC_KING_YMIRON: - KingYmironGUID = creature->GetGUID(); - break; - case NPC_FRENZIED_WORGEN: - FrenziedWorgenGUID = creature->GetGUID(); - break; - case NPC_RAVENOUS_FURBOLG: - RavenousFurbolgGUID = creature->GetGUID(); - break; - case NPC_MASSIVE_JORMUNGAR: - MassiveJormungarGUID = creature->GetGUID(); - break; - case NPC_FEROCIOUS_RHINO: - FerociousRhinoGUID = creature->GetGUID(); - break; - case NPC_SVALA: - SvalaGUID = creature->GetGUID(); - break; - case NPC_PALEHOOF_ORB: - PalehoofOrbGUID = creature->GetGUID(); - break; - case NPC_GRAUF: - GraufGUID = creature->GetGUID(); - break; - default: - break; - } - } void OnGameObjectCreate(GameObject* go) override { - switch (go->GetEntry()) - { - case GO_UTGARDE_MIRROR: - UtgardeMirrorGUID = go->GetGUID(); - break; - case GO_GORTOK_PALEHOOF_SPHERE: - GortokPalehoofSphereGUID = go->GetGUID(); - if (GetBossState(DATA_GORTOK_PALEHOOF) == DONE) - { - HandleGameObject(ObjectGuid::Empty, true, go); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - } - break; - case GO_SKADI_THE_RUTHLESS_DOOR: - case GO_KING_YMIRON_DOOR: - AddDoor(go, true); - break; - default: - break; - } - } + InstanceScript::OnGameObjectCreate(go); - void OnGameObjectRemove(GameObject* go) override - { - switch (go->GetEntry()) - { - case GO_SKADI_THE_RUTHLESS_DOOR: - case GO_KING_YMIRON_DOOR: - AddDoor(go, false); - break; - default: - break; - } + if (go->GetEntry() == GO_GORTOK_PALEHOOF_SPHERE) + if (GetBossState(DATA_GORTOK_PALEHOOF) == DONE) + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); } void SetGuidData(uint32 type, ObjectGuid data) override { - switch (type) - { - case DATA_SACRIFICED_PLAYER: - SacrificedPlayerGUID = data; - break; - default: - break; - } + if (type == DATA_SACRIFICED_PLAYER) + SacrificedPlayerGUID = data; + + InstanceScript::SetGuidData(type, data); } ObjectGuid GetGuidData(uint32 type) const override { - switch (type) - { - case DATA_SVALA_SORROWGRAVE: - return SvalaSorrowgraveGUID; - case DATA_GORTOK_PALEHOOF: - return GortokPalehoofGUID; - case DATA_SKADI_THE_RUTHLESS: - return SkadiTheRuthlessGUID; - case DATA_KING_YMIRON: - return KingYmironGUID; - case DATA_FRENZIED_WORGEN: - return FrenziedWorgenGUID; - case DATA_RAVENOUS_FURBOLG: - return RavenousFurbolgGUID; - case DATA_MASSIVE_JORMUNGAR: - return MassiveJormungarGUID; - case DATA_FEROCIOUS_RHINO: - return FerociousRhinoGUID; - case DATA_GORTOK_ORB: - return PalehoofOrbGUID; - case DATA_GORTOK_PALEHOOF_SPHERE: - return GortokPalehoofSphereGUID; - case DATA_UTGARDE_MIRROR: - return UtgardeMirrorGUID; - case DATA_SVALA: - return SvalaGUID; - case DATA_SACRIFICED_PLAYER: - return SacrificedPlayerGUID; - case DATA_GRAUF: - return GraufGUID; - default: - break; - } - - return ObjectGuid::Empty; + if (type == DATA_SACRIFICED_PLAYER) + return SacrificedPlayerGUID; + + return InstanceScript::GetGuidData(type); } protected: - ObjectGuid SvalaSorrowgraveGUID; - ObjectGuid GortokPalehoofGUID; - ObjectGuid SkadiTheRuthlessGUID; - ObjectGuid KingYmironGUID; - - ObjectGuid UtgardeMirrorGUID; - ObjectGuid GortokPalehoofSphereGUID; - - ObjectGuid FrenziedWorgenGUID; - ObjectGuid RavenousFurbolgGUID; - ObjectGuid FerociousRhinoGUID; - ObjectGuid MassiveJormungarGUID; - - ObjectGuid PalehoofOrbGUID; - - ObjectGuid SvalaGUID; ObjectGuid SacrificedPlayerGUID; - - ObjectGuid GraufGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h index 40faae2645b..8ac915da4d3 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h @@ -47,6 +47,7 @@ enum DataTypes enum CreatureIds { + // Bosses NPC_SVALA_SORROWGRAVE = 26668, NPC_GORTOK_PALEHOOF = 26687, NPC_SKADI_THE_RUTHLESS = 26693, @@ -60,7 +61,8 @@ enum CreatureIds NPC_RAVENOUS_FURBOLG = 26684, NPC_MASSIVE_JORMUNGAR = 26685, NPC_FEROCIOUS_RHINO = 26686, - NPC_PALEHOOF_ORB = 26688, + NPC_PALEHOOF_ORB = 22515, // World Trigger + NPC_JORMUNGAR_WORM = 27228, // Skadi NPC_GRAUF = 26893, |