From 25bca7bef31b29d49e169ad957b90a8f03c57f0c Mon Sep 17 00:00:00 2001 From: ForesterDev <11771800+ForesterDev@users.noreply.github.com> Date: Fri, 18 Sep 2020 13:01:58 +0400 Subject: Scripts/ICC: update Gunship Battle scripts to new model (#25438) (cherry picked from commit 2e1a6aefd0e1cb62dfbe63ae3accc312c2afd519) --- .../boss_icecrown_gunship_battle.cpp | 2266 +++++++++----------- 1 file changed, 995 insertions(+), 1271 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 60446964f29..a79a33a6955 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -834,571 +834,536 @@ class npc_gunship : public CreatureScript } }; -class npc_high_overlord_saurfang_igb : public CreatureScript +struct npc_high_overlord_saurfang_igb : public ScriptedAI { - public: - npc_high_overlord_saurfang_igb() : CreatureScript("npc_high_overlord_saurfang_igb") { } + npc_high_overlord_saurfang_igb(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _controller.ResetSlots(HORDE); + _controller.SetTransport(creature->GetTransport()); + me->SetRegenerateHealth(false); + me->m_CombatDistance = 70.0f; + _firstMageCooldown = GameTime::Now() + 60s; + _axethrowersYellCooldown = time_t(0); + _rocketeersYellCooldown = time_t(0); + } + + void InitializeAI() override + { + ScriptedAI::InitializeAI(); + + _events.Reset(); + _firstMageCooldown = GameTime::Now() + 60s; + _axethrowersYellCooldown = time_t(0); + _rocketeersYellCooldown = time_t(0); + } + + void JustEngagedWith(Unit* /*target*/) override + { + _events.SetPhase(PHASE_COMBAT); + DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER, true); + DoCast(me, SPELL_BATTLE_FURY, true); + _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (!me->IsAlive()) + return; + + me->CombatStop(true); + EngagementOver(); + me->GetMotionMaster()->MoveTargetedHome(); + + Reset(); + } - struct npc_high_overlord_saurfang_igbAI : public ScriptedAI + void DoAction(int32 action) override + { + if (action == ACTION_ENEMY_GUNSHIP_TALK) { - npc_high_overlord_saurfang_igbAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) - { - _controller.ResetSlots(HORDE); - _controller.SetTransport(creature->GetTransport()); - me->SetRegenerateHealth(false); - me->m_CombatDistance = 70.0f; - _firstMageCooldown = GameTime::Now() + 60s; - _axethrowersYellCooldown = time_t(0); - _rocketeersYellCooldown = time_t(0); - } + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); - void InitializeAI() override - { - ScriptedAI::InitializeAI(); + Talk(SAY_SAURFANG_INTRO_5); + _events.ScheduleEvent(EVENT_INTRO_H_5, 4s); + _events.ScheduleEvent(EVENT_INTRO_H_6, 11s); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1ms); - _events.Reset(); - _firstMageCooldown = GameTime::Now() + 60s; - _axethrowersYellCooldown = time_t(0); - _rocketeersYellCooldown = time_t(0); - } + _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); + // Combat starts now + if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 1); - void JustEngagedWith(Unit* /*target*/) override + if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) { - _events.SetPhase(PHASE_COMBAT); - DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER, true); - DoCast(me, SPELL_BATTLE_FURY, true); - _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 2); + orgrimsHammer->CastSpell(orgrimsHammer, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); } - void EnterEvadeMode(EvadeReason /*why*/) override + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); + } + else if (action == ACTION_SPAWN_MAGE) + { + TimePoint now = GameTime::Now(); + if (_firstMageCooldown > now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast(_firstMageCooldown - now)); + else + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1ms); + } + else if (action == ACTION_SPAWN_ALL_ADDS) + { + _events.ScheduleEvent(EVENT_ADDS, 12s); + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13s); + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13s); + if (Is25ManRaid()) + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); + else { - if (!me->IsAlive()) - return; + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); + _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); + } + } + else if (action == ACTION_EXIT_SHIP) + { + Movement::PointsArray path(SaurfangExitPath, SaurfangExitPath + SaurfangExitPathSize); + Movement::MoveSplineInit init(me); + init.DisableTransportPathTransformations(); + init.MovebyPath(path, 0); + me->GetMotionMaster()->LaunchMoveSpline(std::move(init), 0, MOTION_PRIORITY_NORMAL, POINT_MOTION_TYPE); - me->CombatStop(true); - EngagementOver(); - me->GetMotionMaster()->MoveTargetedHome(); + me->DespawnOrUnsummon(18s); + } + } - Reset(); - } + void SetData(uint32 type, uint32 data) override + { + if (type == ACTION_CLEAR_SLOT) + { + _controller.ClearSlot(PassengerSlots(data)); + if (data == SLOT_FREEZE_MAGE) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 30s, 33500ms); + } + } - void DoAction(int32 action) override - { - if (action == ACTION_ENEMY_GUNSHIP_TALK) - { - if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) - muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); + bool OnGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override + { + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->GetTransport()->EnableMovement(true); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_1, 5s, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_2, 16s, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_SUMMON_SKYBREAKER, 24600ms, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_3, 29600ms, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_4, 39200ms, 0, PHASE_INTRO); + return false; + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(65, damage) && !me->HasAura(SPELL_TASTE_OF_BLOOD)) + DoCast(me, SPELL_TASTE_OF_BLOOD, true); - Talk(SAY_SAURFANG_INTRO_5); - _events.ScheduleEvent(EVENT_INTRO_H_5, 4s); - _events.ScheduleEvent(EVENT_INTRO_H_6, 11s); - _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1ms); + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } - _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); - // Combat starts now - if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) - _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 1); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return; - if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_H_1: + Talk(SAY_SAURFANG_INTRO_1); + break; + case EVENT_INTRO_H_2: + Talk(SAY_SAURFANG_INTRO_2); + break; + case EVENT_INTRO_SUMMON_SKYBREAKER: + sTransportMgr->CreateTransport(GO_THE_SKYBREAKER_H, UI64LIT(0), me->GetMap()); + break; + case EVENT_INTRO_H_3: + Talk(SAY_SAURFANG_INTRO_3); + break; + case EVENT_INTRO_H_4: + Talk(SAY_SAURFANG_INTRO_4); + break; + case EVENT_INTRO_H_5: + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + muradin->AI()->Talk(SAY_MURADIN_INTRO_H); + break; + case EVENT_INTRO_H_6: + Talk(SAY_SAURFANG_INTRO_6); + break; + case EVENT_KEEP_PLAYER_IN_COMBAT: + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) { - _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 2); - orgrimsHammer->CastSpell(orgrimsHammer, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); + _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 5s, 8s); } - - me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); - } - else if (action == ACTION_SPAWN_MAGE) - { - TimePoint now = GameTime::Now(); - if (_firstMageCooldown > now) - _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast(_firstMageCooldown - now)); - else - _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1ms); - } - else if (action == ACTION_SPAWN_ALL_ADDS) - { - _events.ScheduleEvent(EVENT_ADDS, 12s); - _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13s); - _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13s); - if (Is25ManRaid()) - _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); - else + break; + case EVENT_SUMMON_MAGE: + Talk(SAY_SAURFANG_MAGES); + _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); + break; + case EVENT_ADDS: + Talk(SAY_SAURFANG_ENTER_SKYBREAKER); + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); + _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); + if (Transport* orgrimsHammer = me->GetTransport()) + orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000); + + if (Transport* skybreaker = HashMapHolder::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) + skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000); + + _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6s); + _events.ScheduleEvent(EVENT_ADDS, 1min); + break; + case EVENT_ADDS_BOARD_YELL: + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) + muradin->AI()->Talk(SAY_MURADIN_BOARD); + break; + case EVENT_CHECK_RIFLEMAN: + if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) { - _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); - _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); - _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); + if (_axethrowersYellCooldown < GameTime::GetGameTime()) + { + Talk(SAY_SAURFANG_AXETHROWERS); + _axethrowersYellCooldown = GameTime::GetGameTime() + 5; + } } - } - else if (action == ACTION_EXIT_SHIP) - { - Movement::PointsArray path(SaurfangExitPath, SaurfangExitPath + SaurfangExitPathSize); - Movement::MoveSplineInit init(me); - init.DisableTransportPathTransformations(); - init.MovebyPath(path, 0); - me->GetMotionMaster()->LaunchMoveSpline(std::move(init), 0, MOTION_PRIORITY_NORMAL, POINT_MOTION_TYPE); - - me->DespawnOrUnsummon(18s); - } + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1s); + break; + case EVENT_CHECK_MORTAR: + if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) + { + if (_rocketeersYellCooldown < GameTime::GetGameTime()) + { + Talk(SAY_SAURFANG_ROCKETEERS); + _rocketeersYellCooldown = GameTime::GetGameTime() + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1s); + break; + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); + break; + default: + break; } + } - void SetData(uint32 type, uint32 data) override - { - if (type == ACTION_CLEAR_SLOT) - { - _controller.ClearSlot(PassengerSlots(data)); - if (data == SLOT_FREEZE_MAGE) - _events.ScheduleEvent(EVENT_SUMMON_MAGE, 30s, 33500ms); - } - } + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else if (me->isAttackReady()) + { + DoCastVictim(SPELL_RENDING_THROW); + me->resetAttackTimer(); + } + } - bool OnGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->GetTransport()->EnableMovement(true); - _events.SetPhase(PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_H_1, 5s, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_H_2, 16s, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_SUMMON_SKYBREAKER, 24600ms, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_H_3, 29600ms, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_H_4, 39200ms, 0, PHASE_INTRO); - return false; - } + bool CanAIAttack(Unit const* target) const override + { + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return false; + return target->HasAura(SPELL_ON_ORGRIMS_HAMMER_DECK) || target->GetEntry() == NPC_SKYBREAKER_MARINE || target->GetEntry() == NPC_SKYBREAKER_SERGEANT; + } - void DamageTaken(Unit* /*attacker*/, uint32& damage) override - { - if (me->HealthBelowPctDamaged(65, damage) && !me->HasAura(SPELL_TASTE_OF_BLOOD)) - DoCast(me, SPELL_TASTE_OF_BLOOD, true); +private: + EventMap _events; + PassengerController _controller; + InstanceScript* _instance; + TimePoint _firstMageCooldown; + time_t _axethrowersYellCooldown; + time_t _rocketeersYellCooldown; +}; - if (damage >= me->GetHealth()) - damage = me->GetHealth() - 1; - } +struct npc_muradin_bronzebeard_igb : public ScriptedAI +{ + npc_muradin_bronzebeard_igb(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _controller.ResetSlots(ALLIANCE); + _controller.SetTransport(creature->GetTransport()); + me->SetRegenerateHealth(false); + me->m_CombatDistance = 70.0f; + _firstMageCooldown = GameTime::Now() + 60s; + _riflemanYellCooldown = time_t(0); + _mortarYellCooldown = time_t(0); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) - return; + void InitializeAI() override + { + ScriptedAI::InitializeAI(); - _events.Update(diff); + _events.Reset(); + _firstMageCooldown = GameTime::Now() + 60s; + _riflemanYellCooldown = time_t(0); + _mortarYellCooldown = time_t(0); + } - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_INTRO_H_1: - Talk(SAY_SAURFANG_INTRO_1); - break; - case EVENT_INTRO_H_2: - Talk(SAY_SAURFANG_INTRO_2); - break; - case EVENT_INTRO_SUMMON_SKYBREAKER: - sTransportMgr->CreateTransport(GO_THE_SKYBREAKER_H, UI64LIT(0), me->GetMap()); - break; - case EVENT_INTRO_H_3: - Talk(SAY_SAURFANG_INTRO_3); - break; - case EVENT_INTRO_H_4: - Talk(SAY_SAURFANG_INTRO_4); - break; - case EVENT_INTRO_H_5: - if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) - muradin->AI()->Talk(SAY_MURADIN_INTRO_H); - break; - case EVENT_INTRO_H_6: - Talk(SAY_SAURFANG_INTRO_6); - break; - case EVENT_KEEP_PLAYER_IN_COMBAT: - if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) - { - _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); - _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 5s, 8s); - } - break; - case EVENT_SUMMON_MAGE: - Talk(SAY_SAURFANG_MAGES); - _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); - break; - case EVENT_ADDS: - Talk(SAY_SAURFANG_ENTER_SKYBREAKER); - _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); - _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); - _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); - if (Transport* orgrimsHammer = me->GetTransport()) - orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000); - - if (Transport* skybreaker = HashMapHolder::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) - skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000); - - _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6s); - _events.ScheduleEvent(EVENT_ADDS, 1min); - break; - case EVENT_ADDS_BOARD_YELL: - if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) - muradin->AI()->Talk(SAY_MURADIN_BOARD); - break; - case EVENT_CHECK_RIFLEMAN: - if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) - { - if (_axethrowersYellCooldown < GameTime::GetGameTime()) - { - Talk(SAY_SAURFANG_AXETHROWERS); - _axethrowersYellCooldown = GameTime::GetGameTime() + 5; - } - } - _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1s); - break; - case EVENT_CHECK_MORTAR: - if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) - { - if (_rocketeersYellCooldown < GameTime::GetGameTime()) - { - Talk(SAY_SAURFANG_ROCKETEERS); - _rocketeersYellCooldown = GameTime::GetGameTime() + 5; - } - } - _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1s); - break; - case EVENT_CLEAVE: - DoCastVictim(SPELL_CLEAVE); - _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); - break; - default: - break; - } - } + void JustEngagedWith(Unit* /*target*/) override + { + _events.SetPhase(PHASE_COMBAT); + DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_SKYBREAKER, true); + DoCast(me, SPELL_BATTLE_FURY, true); + _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); + } - if (me->IsWithinMeleeRange(me->GetVictim())) - DoMeleeAttackIfReady(); - else if (me->isAttackReady()) - { - DoCastVictim(SPELL_RENDING_THROW); - me->resetAttackTimer(); - } - } + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (!me->IsAlive()) + return; - bool CanAIAttack(Unit const* target) const override - { - if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) - return false; - return target->HasAura(SPELL_ON_ORGRIMS_HAMMER_DECK) || target->GetEntry() == NPC_SKYBREAKER_MARINE || target->GetEntry() == NPC_SKYBREAKER_SERGEANT; - } + me->CombatStop(true); + EngagementOver(); + me->GetMotionMaster()->MoveTargetedHome(); - private: - EventMap _events; - PassengerController _controller; - InstanceScript* _instance; - TimePoint _firstMageCooldown; - time_t _axethrowersYellCooldown; - time_t _rocketeersYellCooldown; - }; + Reset(); + } - CreatureAI* GetAI(Creature* creature) const override + void DoAction(int32 action) override + { + if (action == ACTION_ENEMY_GUNSHIP_TALK) { - return GetIcecrownCitadelAI(creature); - } -}; + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); -class npc_muradin_bronzebeard_igb : public CreatureScript -{ - public: - npc_muradin_bronzebeard_igb() : CreatureScript("npc_muradin_bronzebeard_igb") { } + Talk(SAY_MURADIN_INTRO_6); + _events.ScheduleEvent(EVENT_INTRO_A_6, 5s); + _events.ScheduleEvent(EVENT_INTRO_A_7, 11s); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1ms); - struct npc_muradin_bronzebeard_igbAI : public ScriptedAI - { - npc_muradin_bronzebeard_igbAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) - { - _controller.ResetSlots(ALLIANCE); - _controller.SetTransport(creature->GetTransport()); - me->SetRegenerateHealth(false); - me->m_CombatDistance = 70.0f; - _firstMageCooldown = GameTime::Now() + 60s; - _riflemanYellCooldown = time_t(0); - _mortarYellCooldown = time_t(0); - } + _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); + // Combat starts now + if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 1); - void InitializeAI() override + if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) { - ScriptedAI::InitializeAI(); - - _events.Reset(); - _firstMageCooldown = GameTime::Now() + 60s; - _riflemanYellCooldown = time_t(0); - _mortarYellCooldown = time_t(0); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 2); + skybreaker->CastSpell(skybreaker, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); } - void JustEngagedWith(Unit* /*target*/) override + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); + } + else if (action == ACTION_SPAWN_MAGE) + { + TimePoint now = GameTime::Now(); + if (_firstMageCooldown > now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast(_firstMageCooldown - now)); + else + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1ms); + } + else if (action == ACTION_SPAWN_ALL_ADDS) + { + _events.ScheduleEvent(EVENT_ADDS, 12s); + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13s); + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13s); + if (Is25ManRaid()) + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); + else { - _events.SetPhase(PHASE_COMBAT); - DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_SKYBREAKER, true); - DoCast(me, SPELL_BATTLE_FURY, true); - _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); + _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); } + } + else if (action == ACTION_EXIT_SHIP) + { + Movement::PointsArray path(MuradinExitPath, MuradinExitPath + MuradinExitPathSize); + Movement::MoveSplineInit init(me); + init.DisableTransportPathTransformations(); + init.MovebyPath(path, 0); + me->GetMotionMaster()->LaunchMoveSpline(std::move(init), 0, MOTION_PRIORITY_NORMAL, POINT_MOTION_TYPE); - void EnterEvadeMode(EvadeReason /*why*/) override - { - if (!me->IsAlive()) - return; + me->DespawnOrUnsummon(18s); + } + } - me->CombatStop(true); - EngagementOver(); - me->GetMotionMaster()->MoveTargetedHome(); + void SetData(uint32 type, uint32 data) override + { + if (type == ACTION_CLEAR_SLOT) + { + _controller.ClearSlot(PassengerSlots(data)); + if (data == SLOT_FREEZE_MAGE) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 30s, 33500ms); + } + } - Reset(); - } + bool OnGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override + { + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + me->GetTransport()->EnableMovement(true); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_1, 5s); + _events.ScheduleEvent(EVENT_INTRO_A_2, 10s, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_SUMMON_ORGRIMS_HAMMER, 28s, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_3, 33s, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_4, 39s, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_5, 45s, 0, PHASE_INTRO); + return false; + } - void DoAction(int32 action) override - { - if (action == ACTION_ENEMY_GUNSHIP_TALK) - { - if (Creature* muradin = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) - muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(65, damage) && me->HasAura(SPELL_TASTE_OF_BLOOD)) + DoCast(me, SPELL_TASTE_OF_BLOOD, true); - Talk(SAY_MURADIN_INTRO_6); - _events.ScheduleEvent(EVENT_INTRO_A_6, 5s); - _events.ScheduleEvent(EVENT_INTRO_A_7, 11s); - _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1ms); + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } - _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); - // Combat starts now - if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) - _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 1); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return; - if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_A_1: + Talk(SAY_MURADIN_INTRO_1); + break; + case EVENT_INTRO_A_2: + Talk(SAY_MURADIN_INTRO_2); + break; + case EVENT_INTRO_SUMMON_ORGRIMS_HAMMER: + sTransportMgr->CreateTransport(GO_ORGRIMS_HAMMER_A, UI64LIT(0), me->GetMap()); + break; + case EVENT_INTRO_A_3: + Talk(SAY_MURADIN_INTRO_3); + break; + case EVENT_INTRO_A_4: + Talk(SAY_MURADIN_INTRO_4); + break; + case EVENT_INTRO_A_5: + Talk(SAY_MURADIN_INTRO_5); + break; + case EVENT_INTRO_A_6: + if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + saurfang->AI()->Talk(SAY_SAURFANG_INTRO_A); + break; + case EVENT_INTRO_A_7: + Talk(SAY_MURADIN_INTRO_7); + break; + case EVENT_KEEP_PLAYER_IN_COMBAT: + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) { - _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 2); - skybreaker->CastSpell(skybreaker, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); + _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 5s, 8s); } - - me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); - } - else if (action == ACTION_SPAWN_MAGE) - { - TimePoint now = GameTime::Now(); - if (_firstMageCooldown > now) - _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast(_firstMageCooldown - now)); - else - _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1ms); - } - else if (action == ACTION_SPAWN_ALL_ADDS) - { - _events.ScheduleEvent(EVENT_ADDS, 12s); - _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13s); - _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13s); - if (Is25ManRaid()) - _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); - else + break; + case EVENT_SUMMON_MAGE: + Talk(SAY_MURADIN_SORCERERS); + _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); + break; + case EVENT_ADDS: + Talk(SAY_MURADIN_ENTER_ORGRIMMS_HAMMER); + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); + _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); + if (Transport* skybreaker = me->GetTransport()) + skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000); + + if (Transport* orgrimsHammer = HashMapHolder::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) + orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000); + + _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6s); + _events.ScheduleEvent(EVENT_ADDS, 1min); + break; + case EVENT_ADDS_BOARD_YELL: + if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) + saurfang->AI()->Talk(SAY_SAURFANG_BOARD); + break; + case EVENT_CHECK_RIFLEMAN: + if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) { - _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); - _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); - _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); + if (_riflemanYellCooldown < GameTime::GetGameTime()) + { + Talk(SAY_MURADIN_RIFLEMAN); + _riflemanYellCooldown = GameTime::GetGameTime() + 5; + } } - } - else if (action == ACTION_EXIT_SHIP) - { - Movement::PointsArray path(MuradinExitPath, MuradinExitPath + MuradinExitPathSize); - Movement::MoveSplineInit init(me); - init.DisableTransportPathTransformations(); - init.MovebyPath(path, 0); - me->GetMotionMaster()->LaunchMoveSpline(std::move(init), 0, MOTION_PRIORITY_NORMAL, POINT_MOTION_TYPE); - - me->DespawnOrUnsummon(18s); - } - } - - void SetData(uint32 type, uint32 data) override - { - if (type == ACTION_CLEAR_SLOT) - { - _controller.ClearSlot(PassengerSlots(data)); - if (data == SLOT_FREEZE_MAGE) - _events.ScheduleEvent(EVENT_SUMMON_MAGE, 30s, 33500ms); - } - } - - bool OnGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - me->GetTransport()->EnableMovement(true); - _events.SetPhase(PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_A_1, 5s); - _events.ScheduleEvent(EVENT_INTRO_A_2, 10s, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_SUMMON_ORGRIMS_HAMMER, 28s, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_A_3, 33s, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_A_4, 39s, 0, PHASE_INTRO); - _events.ScheduleEvent(EVENT_INTRO_A_5, 45s, 0, PHASE_INTRO); - return false; - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage) override - { - if (me->HealthBelowPctDamaged(65, damage) && me->HasAura(SPELL_TASTE_OF_BLOOD)) - DoCast(me, SPELL_TASTE_OF_BLOOD, true); - - if (damage >= me->GetHealth()) - damage = me->GetHealth() - 1; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1s); + break; + case EVENT_CHECK_MORTAR: + if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) { - case EVENT_INTRO_A_1: - Talk(SAY_MURADIN_INTRO_1); - break; - case EVENT_INTRO_A_2: - Talk(SAY_MURADIN_INTRO_2); - break; - case EVENT_INTRO_SUMMON_ORGRIMS_HAMMER: - sTransportMgr->CreateTransport(GO_ORGRIMS_HAMMER_A, UI64LIT(0), me->GetMap()); - break; - case EVENT_INTRO_A_3: - Talk(SAY_MURADIN_INTRO_3); - break; - case EVENT_INTRO_A_4: - Talk(SAY_MURADIN_INTRO_4); - break; - case EVENT_INTRO_A_5: - Talk(SAY_MURADIN_INTRO_5); - break; - case EVENT_INTRO_A_6: - if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) - saurfang->AI()->Talk(SAY_SAURFANG_INTRO_A); - break; - case EVENT_INTRO_A_7: - Talk(SAY_MURADIN_INTRO_7); - break; - case EVENT_KEEP_PLAYER_IN_COMBAT: - if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) - { - _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); - _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 5s, 8s); - } - break; - case EVENT_SUMMON_MAGE: - Talk(SAY_MURADIN_SORCERERS); - _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); - break; - case EVENT_ADDS: - Talk(SAY_MURADIN_ENTER_ORGRIMMS_HAMMER); - _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); - _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); - _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); - if (Transport* skybreaker = me->GetTransport()) - skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000); - - if (Transport* orgrimsHammer = HashMapHolder::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) - orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000); - - _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6s); - _events.ScheduleEvent(EVENT_ADDS, 1min); - break; - case EVENT_ADDS_BOARD_YELL: - if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) - saurfang->AI()->Talk(SAY_SAURFANG_BOARD); - break; - case EVENT_CHECK_RIFLEMAN: - if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) - { - if (_riflemanYellCooldown < GameTime::GetGameTime()) - { - Talk(SAY_MURADIN_RIFLEMAN); - _riflemanYellCooldown = GameTime::GetGameTime() + 5; - } - } - _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1s); - break; - case EVENT_CHECK_MORTAR: - if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) - { - if (_mortarYellCooldown < GameTime::GetGameTime()) - { - Talk(SAY_MURADIN_MORTAR); - _mortarYellCooldown = GameTime::GetGameTime() + 5; - } - } - _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1s); - break; - case EVENT_CLEAVE: - DoCastVictim(SPELL_CLEAVE); - _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); - break; - default: - break; + if (_mortarYellCooldown < GameTime::GetGameTime()) + { + Talk(SAY_MURADIN_MORTAR); + _mortarYellCooldown = GameTime::GetGameTime() + 5; + } } - } - - if (me->IsWithinMeleeRange(me->GetVictim())) - DoMeleeAttackIfReady(); - else if (me->isAttackReady()) - { - DoCastVictim(SPELL_RENDING_THROW); - me->resetAttackTimer(); - } - } - - bool CanAIAttack(Unit const* target) const override - { - if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) - return false; - return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || target->GetEntry() == NPC_KOR_KRON_REAVER || target->GetEntry() == NPC_KOR_KRON_SERGEANT; + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1s); + break; + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_CLEAVE, 2s, 10s); + break; + default: + break; } + } - private: - EventMap _events; - PassengerController _controller; - InstanceScript* _instance; - TimePoint _firstMageCooldown; - time_t _riflemanYellCooldown; - time_t _mortarYellCooldown; - }; - - CreatureAI* GetAI(Creature* creature) const override + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else if (me->isAttackReady()) { - return GetIcecrownCitadelAI(creature); + DoCastVictim(SPELL_RENDING_THROW); + me->resetAttackTimer(); } -}; + } -class npc_zafod_boombox : public CreatureScript -{ - public: - npc_zafod_boombox() : CreatureScript("npc_zafod_boombox") { } + bool CanAIAttack(Unit const* target) const override + { + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return false; + return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || target->GetEntry() == NPC_KOR_KRON_REAVER || target->GetEntry() == NPC_KOR_KRON_SERGEANT; + } - struct npc_zafod_boomboxAI : public gunship_npc_AI - { - npc_zafod_boomboxAI(Creature* creature) : gunship_npc_AI(creature) - { - } +private: + EventMap _events; + PassengerController _controller; + InstanceScript* _instance; + TimePoint _firstMageCooldown; + time_t _riflemanYellCooldown; + time_t _mortarYellCooldown; +}; - void Reset() override - { - me->SetReactState(REACT_PASSIVE); - } +struct npc_zafod_boombox : public gunship_npc_AI +{ + npc_zafod_boombox(Creature* creature) : gunship_npc_AI(creature) { } - bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override - { - player->AddItem(ITEM_GOBLIN_ROCKET_PACK, 1); - CloseGossipMenuFor(player); - return false; - } + void Reset() override + { + me->SetReactState(REACT_PASSIVE); + } - void UpdateAI(uint32 /*diff*/) override - { - UpdateVictim(); - } - }; + bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override + { + player->AddItem(ITEM_GOBLIN_ROCKET_PACK, 1); + CloseGossipMenuFor(player); + return false; + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI(creature); - } + void UpdateAI(uint32 /*diff*/) override + { + UpdateVictim(); + } }; struct npc_gunship_boarding_addAI : public gunship_npc_AI @@ -1538,68 +1503,55 @@ private: bool _usedDesperateResolve; }; -class npc_gunship_boarding_leader : public CreatureScript +struct npc_gunship_boarding_leader : public npc_gunship_boarding_addAI { - public: - npc_gunship_boarding_leader() : CreatureScript("npc_gunship_boarding_leader") { } + npc_gunship_boarding_leader(Creature* creature) : npc_gunship_boarding_addAI(creature) { } + + void JustEngagedWith(Unit* target) override + { + npc_gunship_boarding_addAI::JustEngagedWith(target); + _events.ScheduleEvent(EVENT_BLADESTORM, 13s, 18s); + _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 8s, 10s); + } - struct npc_gunship_boarding_leaderAI : public npc_gunship_boarding_addAI + void UpdateAI(uint32 diff) override + { + if (!SelectVictim()) { - npc_gunship_boarding_leaderAI(Creature* creature) : npc_gunship_boarding_addAI(creature) - { - } + TriggerBurningPitch(); + return; + } - void JustEngagedWith(Unit* target) override - { - npc_gunship_boarding_addAI::JustEngagedWith(target); - _events.ScheduleEvent(EVENT_BLADESTORM, 13s, 18s); - _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 8s, 10s); - } + _events.Update(diff); - void UpdateAI(uint32 diff) override - { - if (!SelectVictim()) - { - TriggerBurningPitch(); - return; - } - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_BLADESTORM)) - return; - - if (!HasAttackablePlayerNearby()) - TriggerBurningPitch(); + if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_BLADESTORM)) + return; - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BLADESTORM: - DoCastAOE(SPELL_BLADESTORM); - _events.ScheduleEvent(EVENT_BLADESTORM, 25s, 30s); - break; - case EVENT_WOUNDING_STRIKE: - DoCastVictim(SPELL_WOUNDING_STRIKE); - _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 9s, 13s); - break; - default: - break; - } - } + if (!HasAttackablePlayerNearby()) + TriggerBurningPitch(); - DoMeleeAttackIfReady(); + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BLADESTORM: + DoCastAOE(SPELL_BLADESTORM); + _events.ScheduleEvent(EVENT_BLADESTORM, 25s, 30s); + break; + case EVENT_WOUNDING_STRIKE: + DoCastVictim(SPELL_WOUNDING_STRIKE); + _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 9s, 13s); + break; + default: + break; } + } - private: - EventMap _events; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI(creature); - } +private: + EventMap _events; }; class npc_gunship_boarding_add : public CreatureScript @@ -1607,152 +1559,118 @@ class npc_gunship_boarding_add : public CreatureScript public: npc_gunship_boarding_add() : CreatureScript("npc_gunship_boarding_add") { } - CreatureAI* GetAI(Creature* creature) const override { return GetIcecrownCitadelAI(creature); } }; -class npc_gunship_gunner : public CreatureScript +struct npc_gunship_gunner : public gunship_npc_AI { - public: - npc_gunship_gunner() : CreatureScript("npc_gunship_gunner") { } - - struct npc_gunship_gunnerAI : public gunship_npc_AI - { - npc_gunship_gunnerAI(Creature* creature) : gunship_npc_AI(creature) - { - creature->m_CombatDistance = 200.0f; - } - - void AttackStart(Unit* target) override - { - me->Attack(target, false); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - gunship_npc_AI::MovementInform(type, pointId); - if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) - me->SetControlled(true, UNIT_STATE_ROOT); - } + npc_gunship_gunner(Creature* creature) : gunship_npc_AI(creature) + { + creature->m_CombatDistance = 200.0f; + } - void UpdateAI(uint32 /*diff*/) override - { - if (!SelectVictim()) - { - TriggerBurningPitch(); - return; - } + void AttackStart(Unit* target) override + { + me->Attack(target, false); + } - DoSpellAttackIfReady(me->GetEntry() == NPC_SKYBREAKER_RIFLEMAN ? SPELL_SHOOT : SPELL_HURL_AXE); - } - }; + void MovementInform(uint32 type, uint32 pointId) override + { + gunship_npc_AI::MovementInform(type, pointId); + if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) + me->SetControlled(true, UNIT_STATE_ROOT); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 /*diff*/) override + { + if (!SelectVictim()) { - return GetIcecrownCitadelAI(creature); + TriggerBurningPitch(); + return; } + + DoSpellAttackIfReady(me->GetEntry() == NPC_SKYBREAKER_RIFLEMAN ? SPELL_SHOOT : SPELL_HURL_AXE); + } }; -class npc_gunship_rocketeer : public CreatureScript +struct npc_gunship_rocketeer : public gunship_npc_AI { - public: - npc_gunship_rocketeer() : CreatureScript("npc_gunship_rocketeer") { } - - struct npc_gunship_rocketeerAI : public gunship_npc_AI - { - npc_gunship_rocketeerAI(Creature* creature) : gunship_npc_AI(creature) - { - creature->m_CombatDistance = 200.0f; - } - - void MovementInform(uint32 type, uint32 pointId) override - { - gunship_npc_AI::MovementInform(type, pointId); - if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) - me->SetControlled(true, UNIT_STATE_ROOT); - } + npc_gunship_rocketeer(Creature* creature) : gunship_npc_AI(creature) + { + creature->m_CombatDistance = 200.0f; + } - void UpdateAI(uint32 /*diff*/) override - { - if (!SelectVictim()) - return; + void MovementInform(uint32 type, uint32 pointId) override + { + gunship_npc_AI::MovementInform(type, pointId); + if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) + me->SetControlled(true, UNIT_STATE_ROOT); + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + void UpdateAI(uint32 /*diff*/) override + { + if (!SelectVictim()) + return; - uint32 spellId = me->GetEntry() == NPC_SKYBREAKER_MORTAR_SOLDIER ? SPELL_ROCKET_ARTILLERY_A : SPELL_ROCKET_ARTILLERY_H; - if (me->GetSpellHistory()->HasCooldown(spellId)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - DoCastAOE(spellId, true); - me->GetSpellHistory()->AddCooldown(spellId, 0, std::chrono::seconds(9)); - } - }; + uint32 spellId = me->GetEntry() == NPC_SKYBREAKER_MORTAR_SOLDIER ? SPELL_ROCKET_ARTILLERY_A : SPELL_ROCKET_ARTILLERY_H; + if (me->GetSpellHistory()->HasCooldown(spellId)) + return; - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI(creature); - } + DoCastAOE(spellId, true); + me->GetSpellHistory()->AddCooldown(spellId, 0, std::chrono::seconds(9)); + } }; -class npc_gunship_mage : public CreatureScript +struct npc_gunship_mage : public gunship_npc_AI { - public: - npc_gunship_mage() : CreatureScript("npc_gunship_mage") { } + npc_gunship_mage(Creature* creature) : gunship_npc_AI(creature) + { + me->SetReactState(REACT_PASSIVE); + } - struct npc_gunship_mageAI : public gunship_npc_AI - { - npc_gunship_mageAI(Creature* creature) : gunship_npc_AI(creature) - { - me->SetReactState(REACT_PASSIVE); - } + void EnterEvadeMode(EvadeReason /*why*/) override { } - void EnterEvadeMode(EvadeReason /*why*/) override { } + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE) + return; - void MovementInform(uint32 type, uint32 pointId) override + if (pointId == EVENT_CHARGE_PREPATH && Slot) + { + SlotInfo const* slots = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SkybreakerSlotInfo : OrgrimsHammerSlotInfo; + me->SetFacingTo(slots[Index].TargetPosition.GetOrientation()); + switch (Index) { - if (type != POINT_MOTION_TYPE) - return; - - if (pointId == EVENT_CHARGE_PREPATH && Slot) - { - SlotInfo const* slots = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SkybreakerSlotInfo : OrgrimsHammerSlotInfo; - me->SetFacingTo(slots[Index].TargetPosition.GetOrientation()); - switch (Index) - { - case SLOT_FREEZE_MAGE: - DoCastAOE(SPELL_BELOW_ZERO); - break; - case SLOT_MAGE_1: - case SLOT_MAGE_2: - DoCastAOE(SPELL_SHADOW_CHANNELING); - break; - default: - break; - } - - me->SetControlled(true, UNIT_STATE_ROOT); - } + case SLOT_FREEZE_MAGE: + DoCastAOE(SPELL_BELOW_ZERO); + break; + case SLOT_MAGE_1: + case SLOT_MAGE_2: + DoCastAOE(SPELL_SHADOW_CHANNELING); + break; + default: + break; } - void UpdateAI(uint32 /*diff*/) override - { - UpdateVictim(); - } + me->SetControlled(true, UNIT_STATE_ROOT); + } + } - bool CanAIAttack(Unit const* /*target*/) const override - { - return true; - } - }; + void UpdateAI(uint32 /*diff*/) override + { + UpdateVictim(); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI(creature); - } + bool CanAIAttack(Unit const* /*target*/) const override + { + return true; + } }; /** @HACK This AI only resets MOVEMENTFLAG_ROOT on the vehicle. @@ -1774,712 +1692,513 @@ Transport Time: 9926 Transport Seat: 255 Fall Time: 824 */ -class npc_gunship_cannon : public CreatureScript -{ - public: - npc_gunship_cannon() : CreatureScript("npc_gunship_cannon") { } - - struct npc_gunship_cannonAI : public PassiveAI - { - npc_gunship_cannonAI(Creature* creature) : PassiveAI(creature) - { - } - void OnCharmed(bool /*isNew*/) override { } +struct npc_gunship_cannon : public PassiveAI +{ + npc_gunship_cannon(Creature* creature) : PassiveAI(creature) { } - void PassengerBoarded(Unit* /*passenger*/, int8 /*seat*/, bool apply) override - { - if (!apply) - { - me->SetControlled(false, UNIT_STATE_ROOT); - me->SetControlled(true, UNIT_STATE_ROOT); - } - } - }; + void OnCharmed(bool /*isNew*/) override { } - CreatureAI* GetAI(Creature* creature) const override + void PassengerBoarded(Unit* /*passenger*/, int8 /*seat*/, bool apply) override + { + if (!apply) { - return GetIcecrownCitadelAI(creature); + me->SetControlled(false, UNIT_STATE_ROOT); + me->SetControlled(true, UNIT_STATE_ROOT); } + } }; -class spell_igb_rocket_pack : public SpellScriptLoader +class spell_igb_rocket_pack : public AuraScript { - public: - spell_igb_rocket_pack() : SpellScriptLoader("spell_igb_rocket_pack") { } - - class spell_igb_rocket_pack_AuraScript : public AuraScript - { - PrepareAuraScript(spell_igb_rocket_pack_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ROCKET_PACK_DAMAGE, SPELL_ROCKET_BURST }) - && !sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE, DIFFICULTY_NONE)->GetEffects().empty(); - } + PrepareAuraScript(spell_igb_rocket_pack); - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - if (!GetTarget()->IsSplineEnabled()) - Remove(AURA_REMOVE_BY_EXPIRE); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ROCKET_PACK_DAMAGE, SPELL_ROCKET_BURST }) + && !sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE, DIFFICULTY_NONE)->GetEffects().empty(); + } - void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - SpellInfo const* damageInfo = sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE, GetCastDifficulty()); - CastSpellExtraArgs args(TRIGGERED_FULL_MASK); - args.CastDifficulty = GetCastDifficulty(); - args.AddSpellBP0(2 * (damageInfo->GetEffect(EFFECT_0).CalcValue() + aurEff->GetTickNumber() * aurEff->GetPeriod())); - GetTarget()->CastSpell(nullptr, SPELL_ROCKET_PACK_DAMAGE, args); - GetTarget()->CastSpell(nullptr, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK); - } + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + if (!GetTarget()->IsSplineEnabled()) + Remove(AURA_REMOVE_BY_EXPIRE); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_rocket_pack_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - OnEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + SpellInfo const* damageInfo = sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE, GetCastDifficulty()); + CastSpellExtraArgs args(TRIGGERED_FULL_MASK); + args.SetCastDifficulty(GetCastDifficulty()); + args.AddSpellBP0(2 * (damageInfo->GetEffect(EFFECT_0).CalcValue() + aurEff->GetTickNumber() * aurEff->GetPeriod())); + GetTarget()->CastSpell(nullptr, SPELL_ROCKET_PACK_DAMAGE, args); + GetTarget()->CastSpell(nullptr, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK); + } - AuraScript* GetAuraScript() const override - { - return new spell_igb_rocket_pack_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_rocket_pack::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + OnEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; -class spell_igb_rocket_pack_useable : public SpellScriptLoader +class spell_igb_rocket_pack_useable : public AuraScript { - public: - spell_igb_rocket_pack_useable() : SpellScriptLoader("spell_igb_rocket_pack_useable") { } - - class spell_igb_rocket_pack_useable_AuraScript : public AuraScript - { - PrepareAuraScript(spell_igb_rocket_pack_useable_AuraScript); + PrepareAuraScript(spell_igb_rocket_pack_useable); - bool Load() override - { - return GetOwner()->GetInstanceScript() != nullptr; - } - - bool CheckAreaTarget(Unit* target) - { - return target->GetTypeId() == TYPEID_PLAYER && GetOwner()->GetInstanceScript()->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE; - } + bool Load() override + { + return GetOwner()->GetInstanceScript() != nullptr; + } - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Creature* owner = GetOwner()->ToCreature()) - if (Player* target = GetTarget()->ToPlayer()) - if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) - sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_ACTIVE, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, SoundKitPlayType::Normal, TEAM_OTHER, false, target); - } + bool CheckAreaTarget(Unit* target) + { + return target->GetTypeId() == TYPEID_PLAYER && GetOwner()->GetInstanceScript()->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE; + } - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Creature* owner = GetOwner()->ToCreature()) - if (Player* target = GetTarget()->ToPlayer()) - if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) - sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_DISABLED, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, SoundKitPlayType::Normal, TEAM_OTHER, false, target); - } + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* owner = GetOwner()->ToCreature()) + if (Player* target = GetTarget()->ToPlayer()) + if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) + sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_ACTIVE, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, SoundKitPlayType::Normal, TEAM_OTHER, false, target); + } - void Register() override - { - DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_rocket_pack_useable_AuraScript::CheckAreaTarget); - AfterEffectApply += AuraEffectApplyFn(spell_igb_rocket_pack_useable_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack_useable_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* owner = GetOwner()->ToCreature()) + if (Player* target = GetTarget()->ToPlayer()) + if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) + sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_DISABLED, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, SoundKitPlayType::Normal, TEAM_OTHER, false, target); + } - AuraScript* GetAuraScript() const override - { - return new spell_igb_rocket_pack_useable_AuraScript(); - } + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_rocket_pack_useable::CheckAreaTarget); + AfterEffectApply += AuraEffectApplyFn(spell_igb_rocket_pack_useable::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack_useable::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; -class spell_igb_on_gunship_deck : public SpellScriptLoader +class spell_igb_on_gunship_deck : public AuraScript { - public: - spell_igb_on_gunship_deck() : SpellScriptLoader("spell_igb_on_gunship_deck") { } - - class spell_igb_on_gunship_deck_AuraScript : public AuraScript - { - PrepareAuraScript(spell_igb_on_gunship_deck_AuraScript); - - public: - spell_igb_on_gunship_deck_AuraScript() - { - _teamInInstance = 0; - } + PrepareAuraScript(spell_igb_on_gunship_deck); - private: - bool Load() override - { - if (InstanceScript* instance = GetOwner()->GetInstanceScript()) - _teamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE); - else - _teamInInstance = 0; - return true; - } +public: + spell_igb_on_gunship_deck() + { + _teamInInstance = 0; + } - bool CheckAreaTarget(Unit* unit) - { - return unit->GetTypeId() == TYPEID_PLAYER; - } +private: + bool Load() override + { + if (InstanceScript* instance = GetOwner()->GetInstanceScript()) + _teamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE); + else + _teamInInstance = 0; + return true; + } - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetSpellInfo()->Id == uint32(_teamInInstance == HORDE ? SPELL_ON_SKYBREAKER_DECK : SPELL_ON_ORGRIMS_HAMMER_DECK)) - if (Creature* gunship = GetOwner()->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f)) - gunship->AI()->SetGUID(GetTarget()->GetGUID(), ACTION_SHIP_VISITS); - } + bool CheckAreaTarget(Unit* unit) + { + return unit->GetTypeId() == TYPEID_PLAYER; + } - void Register() override - { - DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_on_gunship_deck_AuraScript::CheckAreaTarget); - AfterEffectApply += AuraEffectApplyFn(spell_igb_on_gunship_deck_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetSpellInfo()->Id == uint32(_teamInInstance == HORDE ? SPELL_ON_SKYBREAKER_DECK : SPELL_ON_ORGRIMS_HAMMER_DECK)) + if (Creature* gunship = GetOwner()->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f)) + gunship->AI()->SetGUID(GetTarget()->GetGUID(), ACTION_SHIP_VISITS); + } - uint32 _teamInInstance; - }; + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_on_gunship_deck::CheckAreaTarget); + AfterEffectApply += AuraEffectApplyFn(spell_igb_on_gunship_deck::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } - AuraScript* GetAuraScript() const override - { - return new spell_igb_on_gunship_deck_AuraScript(); - } + uint32 _teamInInstance; }; -class spell_igb_periodic_trigger_with_power_cost : public SpellScriptLoader +class spell_igb_periodic_trigger_with_power_cost : public AuraScript { - public: - spell_igb_periodic_trigger_with_power_cost() : SpellScriptLoader("spell_igb_periodic_trigger_with_power_cost") { } + PrepareAuraScript(spell_igb_periodic_trigger_with_power_cost); - class spell_igb_periodic_trigger_with_power_cost_AuraScript : public AuraScript - { - PrepareAuraScript(spell_igb_periodic_trigger_with_power_cost_AuraScript); + void HandlePeriodicTick(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), aurEff->GetSpellEffectInfo().TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)); + } - void HandlePeriodicTick(AuraEffect const* aurEff) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), aurEff->GetSpellEffectInfo().TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_periodic_trigger_with_power_cost::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_periodic_trigger_with_power_cost_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; +class spell_igb_cannon_blast : public SpellScript +{ + PrepareSpellScript(spell_igb_cannon_blast); + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - AuraScript* GetAuraScript() const override + void CheckEnergy() + { + if (GetCaster()->GetPower(POWER_ENERGY) >= 100) { - return new spell_igb_periodic_trigger_with_power_cost_AuraScript(); + GetCaster()->CastSpell(GetCaster(), SPELL_OVERHEAT, TRIGGERED_FULL_MASK); + if (Vehicle* vehicle = GetCaster()->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + sCreatureTextMgr->SendChat(GetCaster()->ToCreature(), SAY_OVERHEAT, passenger); } + } + + void Register() override + { + AfterHit += SpellHitFn(spell_igb_cannon_blast::CheckEnergy); + } }; -class spell_igb_cannon_blast : public SpellScriptLoader +class spell_igb_incinerating_blast : public SpellScript { - public: - spell_igb_cannon_blast() : SpellScriptLoader("spell_igb_cannon_blast") { } + PrepareSpellScript(spell_igb_incinerating_blast); - class spell_igb_cannon_blast_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_cannon_blast_SpellScript); +public: + spell_igb_incinerating_blast() + { + _energyLeft = 0; + } - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_UNIT; - } +private: + void StoreEnergy() + { + _energyLeft = GetCaster()->GetPower(POWER_ENERGY) - 10; + } - void CheckEnergy() - { - if (GetCaster()->GetPower(POWER_ENERGY) >= 100) - { - GetCaster()->CastSpell(GetCaster(), SPELL_OVERHEAT, TRIGGERED_FULL_MASK); - if (Vehicle* vehicle = GetCaster()->GetVehicleKit()) - if (Unit* passenger = vehicle->GetPassenger(0)) - sCreatureTextMgr->SendChat(GetCaster()->ToCreature(), SAY_OVERHEAT, passenger); - } - } - - void Register() override - { - AfterHit += SpellHitFn(spell_igb_cannon_blast_SpellScript::CheckEnergy); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_igb_cannon_blast_SpellScript(); - } -}; - -class spell_igb_incinerating_blast : public SpellScriptLoader -{ - public: - spell_igb_incinerating_blast() : SpellScriptLoader("spell_igb_incinerating_blast") { } - - class spell_igb_incinerating_blast_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_incinerating_blast_SpellScript); - - public: - spell_igb_incinerating_blast_SpellScript() - { - _energyLeft = 0; - } - - private: - void StoreEnergy() - { - _energyLeft = GetCaster()->GetPower(POWER_ENERGY) - 10; - } - - void RemoveEnergy() - { - GetCaster()->SetPower(POWER_ENERGY, 0); - } - - void CalculateDamage(SpellEffIndex /*effIndex*/) - { - SetEffectValue(GetEffectValue() + _energyLeft * _energyLeft * 8); - } + void RemoveEnergy() + { + GetCaster()->SetPower(POWER_ENERGY, 0); + } - void Register() override - { - OnCast += SpellCastFn(spell_igb_incinerating_blast_SpellScript::StoreEnergy); - AfterCast += SpellCastFn(spell_igb_incinerating_blast_SpellScript::RemoveEnergy); - OnEffectLaunchTarget += SpellEffectFn(spell_igb_incinerating_blast_SpellScript::CalculateDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); - } + void CalculateDamage(SpellEffIndex /*effIndex*/) + { + SetEffectValue(GetEffectValue() + _energyLeft * _energyLeft * 8); + } - uint32 _energyLeft; - }; + void Register() override + { + OnCast += SpellCastFn(spell_igb_incinerating_blast::StoreEnergy); + AfterCast += SpellCastFn(spell_igb_incinerating_blast::RemoveEnergy); + OnEffectLaunchTarget += SpellEffectFn(spell_igb_incinerating_blast::CalculateDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + } - SpellScript* GetSpellScript() const override - { - return new spell_igb_incinerating_blast_SpellScript(); - } + uint32 _energyLeft; }; -class spell_igb_overheat : public SpellScriptLoader +class spell_igb_overheat : public AuraScript { - public: - spell_igb_overheat() : SpellScriptLoader("spell_igb_overheat") { } + PrepareAuraScript(spell_igb_overheat); - class spell_igb_overheat_AuraScript : public AuraScript - { - PrepareAuraScript(spell_igb_overheat_AuraScript); - - bool Load() override - { - if (GetAura()->GetType() != UNIT_AURA_TYPE) - return false; - return GetUnitOwner()->IsVehicle(); - } + bool Load() override + { + if (GetAura()->GetType() != UNIT_AURA_TYPE) + return false; + return GetUnitOwner()->IsVehicle(); + } - void SendClientControl(bool value) + void SendClientControl(bool value) + { + if (Vehicle* vehicle = GetUnitOwner()->GetVehicleKit()) + { + if (Unit* passenger = vehicle->GetPassenger(0)) { - if (Vehicle* vehicle = GetUnitOwner()->GetVehicleKit()) + if (Player* player = passenger->ToPlayer()) { - if (Unit* passenger = vehicle->GetPassenger(0)) - { - if (Player* player = passenger->ToPlayer()) - { - WorldPackets::Movement::ControlUpdate data; - data.Guid = GetUnitOwner()->GetGUID(); - data.On = value; - player->SendDirectMessage(data.Write()); - } - } + WorldPackets::Movement::ControlUpdate data; + data.Guid = GetUnitOwner()->GetGUID(); + data.On = value; + player->SendDirectMessage(data.Write()); } } + } + } - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - SendClientControl(false); - } - - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - SendClientControl(true); - } + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + SendClientControl(false); + } - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_igb_overheat_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_igb_overheat_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + SendClientControl(true); + } - AuraScript* GetAuraScript() const override - { - return new spell_igb_overheat_AuraScript(); - } + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_igb_overheat::HandleApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_igb_overheat::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } }; -class spell_igb_below_zero : public SpellScriptLoader +class spell_igb_below_zero : public SpellScript { - public: - spell_igb_below_zero() : SpellScriptLoader("spell_igb_below_zero") { } + PrepareSpellScript(spell_igb_below_zero); - class spell_igb_below_zero_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_below_zero_SpellScript); - - void RemovePassengers(SpellMissInfo missInfo) - { - if (missInfo != SPELL_MISS_NONE) - return; - - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO, TRIGGERED_FULL_MASK); - } + void RemovePassengers(SpellMissInfo missInfo) + { + if (missInfo != SPELL_MISS_NONE) + return; - void Register() override - { - BeforeHit += BeforeSpellHitFn(spell_igb_below_zero_SpellScript::RemovePassengers); - } - }; + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO, TRIGGERED_FULL_MASK); + } - SpellScript* GetSpellScript() const override - { - return new spell_igb_below_zero_SpellScript(); - } + void Register() override + { + BeforeHit += BeforeSpellHitFn(spell_igb_below_zero::RemovePassengers); + } }; -class spell_igb_teleport_to_enemy_ship : public SpellScriptLoader +class spell_igb_teleport_to_enemy_ship : public SpellScript { - public: - spell_igb_teleport_to_enemy_ship() : SpellScriptLoader("spell_igb_teleport_to_enemy_ship") { } + PrepareSpellScript(spell_igb_teleport_to_enemy_ship); - class spell_igb_teleport_to_enemy_ship_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_teleport_to_enemy_ship_SpellScript); - - void RelocateTransportOffset(SpellEffIndex /*effIndex*/) - { - WorldLocation const* dest = GetHitDest(); - Unit* target = GetHitUnit(); - if (!dest || !target || !target->GetTransport()) - return; - - float x, y, z, o; - dest->GetPosition(x, y, z, o); - target->GetTransport()->CalculatePassengerOffset(x, y, z, &o); - target->m_movementInfo.transport.pos.Relocate(x, y, z, o); - } + void RelocateTransportOffset(SpellEffIndex /*effIndex*/) + { + WorldLocation const* dest = GetHitDest(); + Unit* target = GetHitUnit(); + if (!dest || !target || !target->GetTransport()) + return; - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_igb_teleport_to_enemy_ship_SpellScript::RelocateTransportOffset, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); - } - }; + float x, y, z, o; + dest->GetPosition(x, y, z, o); + target->GetTransport()->CalculatePassengerOffset(x, y, z, &o); + target->m_movementInfo.transport.pos.Relocate(x, y, z, o); + } - SpellScript* GetSpellScript() const override - { - return new spell_igb_teleport_to_enemy_ship_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_igb_teleport_to_enemy_ship::RelocateTransportOffset, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } }; -class spell_igb_burning_pitch_selector : public SpellScriptLoader +class spell_igb_burning_pitch_selector : public SpellScript { - public: - spell_igb_burning_pitch_selector() : SpellScriptLoader("spell_igb_burning_pitch_selector") { } + PrepareSpellScript(spell_igb_burning_pitch_selector); - class spell_igb_burning_pitch_selector_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_burning_pitch_selector_SpellScript); - - void FilterTargets(std::list& targets) - { - uint32 team = HORDE; - if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - team = instance->GetData(DATA_TEAM_IN_INSTANCE); - - targets.remove_if([team](WorldObject* target) -> bool - { - if (Transport* transport = target->GetTransport()) - return transport->GetEntry() != uint32(team == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A); - return true; - }); - - if (!targets.empty()) - { - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); - } + void FilterTargets(std::list& targets) + { + uint32 team = HORDE; + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + team = instance->GetData(DATA_TEAM_IN_INSTANCE); - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_burning_pitch_selector_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch_selector_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + targets.remove_if([team](WorldObject* target) -> bool + { + if (Transport* transport = target->GetTransport()) + return transport->GetEntry() != uint32(team == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A); + return true; + }); - SpellScript* GetSpellScript() const override + if (!targets.empty()) { - return new spell_igb_burning_pitch_selector_SpellScript(); + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); } -}; + } -class spell_igb_burning_pitch : public SpellScriptLoader -{ - public: - spell_igb_burning_pitch() : SpellScriptLoader("spell_igb_burning_pitch") { } + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); + } - class spell_igb_burning_pitch_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_burning_pitch_SpellScript); + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_burning_pitch_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch_selector::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - CastSpellExtraArgs args(TRIGGERED_FULL_MASK); - args.AddSpellBP0(8000); - GetCaster()->CastSpell(nullptr, GetEffectValue(), args); - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_BURNING_PITCH, TRIGGERED_FULL_MASK); - } +class spell_igb_burning_pitch : public SpellScript +{ + PrepareSpellScript(spell_igb_burning_pitch); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + CastSpellExtraArgs args(TRIGGERED_FULL_MASK); + args.AddSpellBP0(8000); + GetCaster()->CastSpell(nullptr, GetEffectValue(), args); + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_BURNING_PITCH, TRIGGERED_FULL_MASK); + } - SpellScript* GetSpellScript() const override - { - return new spell_igb_burning_pitch_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; -class spell_igb_rocket_artillery : public SpellScriptLoader +class spell_igb_rocket_artillery : public SpellScript { - public: - spell_igb_rocket_artillery() : SpellScriptLoader("spell_igb_rocket_artillery") { } + PrepareSpellScript(spell_igb_rocket_artillery); - class spell_igb_rocket_artillery_SpellScript : public SpellScript + void SelectRandomTarget(std::list& targets) + { + if (!targets.empty()) { - PrepareSpellScript(spell_igb_rocket_artillery_SpellScript); - - void SelectRandomTarget(std::list& targets) - { - if (!targets.empty()) - { - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } - } - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); - } + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_rocket_artillery_SpellScript::SelectRandomTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_igb_rocket_artillery_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); + } - SpellScript* GetSpellScript() const override - { - return new spell_igb_rocket_artillery_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_rocket_artillery::SelectRandomTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_igb_rocket_artillery::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; -class spell_igb_rocket_artillery_explosion : public SpellScriptLoader +class spell_igb_rocket_artillery_explosion : public SpellScript { - public: - spell_igb_rocket_artillery_explosion() : SpellScriptLoader("spell_igb_rocket_artillery_explosion") { } + PrepareSpellScript(spell_igb_rocket_artillery_explosion); - class spell_igb_rocket_artillery_explosion_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_rocket_artillery_explosion_SpellScript); - - void DamageGunship(SpellEffIndex /*effIndex*/) - { - if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - { - CastSpellExtraArgs args(TRIGGERED_FULL_MASK); - args.AddSpellBP0(5000); - GetCaster()->CastSpell(nullptr, instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_BURNING_PITCH_DAMAGE_A : SPELL_BURNING_PITCH_DAMAGE_H, args); - } - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_igb_rocket_artillery_explosion_SpellScript::DamageGunship, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); - } - }; - - SpellScript* GetSpellScript() const override + void DamageGunship(SpellEffIndex /*effIndex*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { - return new spell_igb_rocket_artillery_explosion_SpellScript(); + CastSpellExtraArgs args(TRIGGERED_FULL_MASK); + args.AddSpellBP0(5000); + GetCaster()->CastSpell(nullptr, instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_BURNING_PITCH_DAMAGE_A : SPELL_BURNING_PITCH_DAMAGE_H, args); } + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_igb_rocket_artillery_explosion::DamageGunship, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); + } }; -class spell_igb_gunship_fall_teleport : public SpellScriptLoader +class spell_igb_gunship_fall_teleport : public SpellScript { - public: - spell_igb_gunship_fall_teleport() : SpellScriptLoader("spell_igb_gunship_fall_teleport") { } - - class spell_igb_gunship_fall_teleport_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_gunship_fall_teleport_SpellScript); - - bool Load() override - { - return GetCaster()->GetInstanceScript() != nullptr; - } + PrepareSpellScript(spell_igb_gunship_fall_teleport); - void SelectTransport(WorldObject*& target) - { - if (InstanceScript* instance = target->GetInstanceScript()) - target = HashMapHolder::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)); - } + bool Load() override + { + return GetCaster()->GetInstanceScript() != nullptr; + } - void RelocateDest(SpellEffIndex /*effIndex*/) - { - if (GetCaster()->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) - GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 36.0f, 0.0f }); - else - GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 21.0f, 0.0f }); - } + void SelectTransport(WorldObject*& target) + { + if (InstanceScript* instance = target->GetInstanceScript()) + target = HashMapHolder::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)); + } - void Register() override - { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_igb_gunship_fall_teleport_SpellScript::SelectTransport, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); - OnEffectLaunch += SpellEffectFn(spell_igb_gunship_fall_teleport_SpellScript::RelocateDest, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); - } - }; + void RelocateDest(SpellEffIndex /*effIndex*/) + { + if (GetCaster()->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 36.0f, 0.0f }); + else + GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 21.0f, 0.0f }); + } - SpellScript* GetSpellScript() const override - { - return new spell_igb_gunship_fall_teleport_SpellScript(); - } + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_igb_gunship_fall_teleport::SelectTransport, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); + OnEffectLaunch += SpellEffectFn(spell_igb_gunship_fall_teleport::RelocateDest, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } }; -class spell_igb_check_for_players : public SpellScriptLoader +class spell_igb_check_for_players : public SpellScript { - public: - spell_igb_check_for_players() : SpellScriptLoader("spell_igb_check_for_players") { } - - class spell_igb_check_for_players_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_check_for_players_SpellScript); + PrepareSpellScript(spell_igb_check_for_players); - public: - spell_igb_check_for_players_SpellScript() - { - _playerCount = 0; - } - - private: - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_UNIT; - } +public: + spell_igb_check_for_players() + { + _playerCount = 0; + } - void CountTargets(std::list& targets) - { - _playerCount = targets.size(); - } +private: + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - void TriggerWipe() - { - if (!_playerCount) - GetCaster()->ToCreature()->AI()->JustDied(nullptr); - } + void CountTargets(std::list& targets) + { + _playerCount = targets.size(); + } - void TeleportPlayer(SpellEffIndex /*effIndex*/) - { - if (GetHitUnit()->GetPositionZ() < GetCaster()->GetPositionZ() - 10.0f) - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GUNSHIP_FALL_TELEPORT, TRIGGERED_FULL_MASK); - } + void TriggerWipe() + { + if (!_playerCount) + GetCaster()->ToCreature()->AI()->JustDied(nullptr); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_check_for_players_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - AfterCast += SpellCastFn(spell_igb_check_for_players_SpellScript::TriggerWipe); - OnEffectHitTarget += SpellEffectFn(spell_igb_check_for_players_SpellScript::TeleportPlayer, EFFECT_0, SPELL_EFFECT_DUMMY); - } + void TeleportPlayer(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()->GetPositionZ() < GetCaster()->GetPositionZ() - 10.0f) + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GUNSHIP_FALL_TELEPORT, TRIGGERED_FULL_MASK); + } - uint32 _playerCount; - }; + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_check_for_players::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + AfterCast += SpellCastFn(spell_igb_check_for_players::TriggerWipe); + OnEffectHitTarget += SpellEffectFn(spell_igb_check_for_players::TeleportPlayer, EFFECT_0, SPELL_EFFECT_DUMMY); + } - SpellScript* GetSpellScript() const override - { - return new spell_igb_check_for_players_SpellScript(); - } + uint32 _playerCount; }; -class spell_igb_teleport_players_on_victory : public SpellScriptLoader +class spell_igb_teleport_players_on_victory : public SpellScript { - public: - spell_igb_teleport_players_on_victory() : SpellScriptLoader("spell_igb_teleport_players_on_victory") { } - - class spell_igb_teleport_players_on_victory_SpellScript : public SpellScript - { - PrepareSpellScript(spell_igb_teleport_players_on_victory_SpellScript); + PrepareSpellScript(spell_igb_teleport_players_on_victory); - bool Load() override - { - return GetCaster()->GetInstanceScript() != nullptr; - } - - void FilterTargets(std::list& targets) - { - InstanceScript* instance = GetCaster()->GetInstanceScript(); - targets.remove_if([instance](WorldObject* target) -> bool - { - return target->GetTransGUID() != instance->GetGuidData(DATA_ENEMY_GUNSHIP); - }); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_teleport_players_on_victory_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); - } - }; + bool Load() override + { + return GetCaster()->GetInstanceScript() != nullptr; + } - SpellScript* GetSpellScript() const override + void FilterTargets(std::list& targets) + { + InstanceScript* instance = GetCaster()->GetInstanceScript(); + targets.remove_if([instance](WorldObject* target) -> bool { - return new spell_igb_teleport_players_on_victory_SpellScript(); - } + return target->GetTransGUID() != instance->GetGuidData(DATA_ENEMY_GUNSHIP); + }); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_teleport_players_on_victory::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); + } }; // 71201 - Battle Experience - proc should never happen, handled in script -class spell_igb_battle_experience_check : public SpellScriptLoader +class spell_igb_battle_experience_check : public AuraScript { -public: - spell_igb_battle_experience_check() : SpellScriptLoader("spell_igb_battle_experience_check") { } + PrepareAuraScript(spell_igb_battle_experience_check); - class spell_igb_battle_experience_check_AuraScript : public AuraScript + bool CheckProc(ProcEventInfo& /*eventInfo*/) { - PrepareAuraScript(spell_igb_battle_experience_check_AuraScript); - - bool CheckProc(ProcEventInfo& /*eventInfo*/) - { - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_igb_battle_experience_check_AuraScript::CheckProc); - } - }; + return false; + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_igb_battle_experience_check_AuraScript(); + DoCheckProc += AuraCheckProcFn(spell_igb_battle_experience_check::CheckProc); } }; @@ -2496,32 +2215,37 @@ class achievement_im_on_a_boat : public AchievementCriteriaScript void AddSC_boss_icecrown_gunship_battle() { + // Creatures new npc_gunship(); - new npc_high_overlord_saurfang_igb(); - new npc_muradin_bronzebeard_igb(); - new npc_zafod_boombox(); - new npc_gunship_boarding_leader(); + RegisterIcecrownCitadelCreatureAI(npc_high_overlord_saurfang_igb); + RegisterIcecrownCitadelCreatureAI(npc_muradin_bronzebeard_igb); + RegisterIcecrownCitadelCreatureAI(npc_zafod_boombox); + RegisterIcecrownCitadelCreatureAI(npc_gunship_boarding_leader); new npc_gunship_boarding_add(); - new npc_gunship_gunner(); - new npc_gunship_rocketeer(); - new npc_gunship_mage(); - new npc_gunship_cannon(); - new spell_igb_rocket_pack(); - new spell_igb_rocket_pack_useable(); - new spell_igb_on_gunship_deck(); - new spell_igb_periodic_trigger_with_power_cost(); - new spell_igb_cannon_blast(); - new spell_igb_incinerating_blast(); - new spell_igb_overheat(); - new spell_igb_below_zero(); - new spell_igb_teleport_to_enemy_ship(); - new spell_igb_burning_pitch_selector(); - new spell_igb_burning_pitch(); - new spell_igb_rocket_artillery(); - new spell_igb_rocket_artillery_explosion(); - new spell_igb_gunship_fall_teleport(); - new spell_igb_check_for_players(); - new spell_igb_teleport_players_on_victory(); - new spell_igb_battle_experience_check(); + RegisterIcecrownCitadelCreatureAI(npc_gunship_gunner); + RegisterIcecrownCitadelCreatureAI(npc_gunship_rocketeer); + RegisterIcecrownCitadelCreatureAI(npc_gunship_mage); + RegisterIcecrownCitadelCreatureAI(npc_gunship_cannon); + + // Spells + RegisterSpellScript(spell_igb_rocket_pack); + RegisterSpellScript(spell_igb_rocket_pack_useable); + RegisterSpellScript(spell_igb_on_gunship_deck); + RegisterSpellScript(spell_igb_periodic_trigger_with_power_cost); + RegisterSpellScript(spell_igb_cannon_blast); + RegisterSpellScript(spell_igb_incinerating_blast); + RegisterSpellScript(spell_igb_overheat); + RegisterSpellScript(spell_igb_below_zero); + RegisterSpellScript(spell_igb_teleport_to_enemy_ship); + RegisterSpellScript(spell_igb_burning_pitch_selector); + RegisterSpellScript(spell_igb_burning_pitch); + RegisterSpellScript(spell_igb_rocket_artillery); + RegisterSpellScript(spell_igb_rocket_artillery_explosion); + RegisterSpellScript(spell_igb_gunship_fall_teleport); + RegisterSpellScript(spell_igb_check_for_players); + RegisterSpellScript(spell_igb_teleport_players_on_victory); + RegisterSpellScript(spell_igb_battle_experience_check); + + // Achievements new achievement_im_on_a_boat(); } -- cgit v1.2.3