TrinityCore
boss_icecrown_gunship_battle.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "icecrown_citadel.h"
19#include "CellImpl.h"
20#include "Containers.h"
21#include "CreatureTextMgr.h"
22#include "GridNotifiersImpl.h"
23#include "InstanceScript.h"
24#include "Map.h"
25#include "MotionMaster.h"
26#include "MovementPackets.h"
27#include "MoveSplineInit.h"
28#include "ObjectAccessor.h"
29#include "PassiveAI.h"
30#include "ScriptedCreature.h"
31#include "ScriptedGossip.h"
32#include "ScriptMgr.h"
33#include "SpellAuraEffects.h"
34#include "SpellHistory.h"
35#include "SpellMgr.h"
36#include "SpellScript.h"
37#include "TemporarySummon.h"
38#include "Transport.h"
39#include "Vehicle.h"
40#include <G3D/Vector3.h>
41
43{
44 // High Overlord Saurfang
59
60 // Muradin Bronzebeard
76
79
80 SAY_OVERHEAT = 0
81};
82
84{
85 // High Overlord Saurfang
93
94 // Muradin Bronzebeard
103
111
115
117{
118 // Applied on friendly transport NPCs
127
128 // Murading Bronzebeard
129 // High Overlord Saurfang
134
135 // Applied on enemy NPCs
138
139 // Gunship Hull
142
143 // Hostile NPCs
148 SPELL_ELITE = 71195,
150
151 // Skybreaker Sorcerer
152 // Kor'kron Battle-Mage
155
156 // Skybreaker Rifleman
157 // Kor'kron Axethrower
158 SPELL_SHOOT = 70162,
163
164 // Skybreaker Mortar Soldier
165 // Kor'kron Rocketeer
170
171 // Skybreaker Marine
172 // Kor'kron Reaver
174
175 // Skybreaker Sergeant
176 // Kor'kron Sergeant
179
180 //
184
185 // Rocket Pack
189
190 // Alliance Gunship Cannon
191 // Horde Gunship Cannon
196
198{
201
204
205 MUSIC_ENCOUNTER = 17289
207
209{
216
217Position const SkybreakerAddsSpawnPos = { 15.91131f, 0.0f, 20.4628f, float(M_PI) };
218Position const OrgrimsHammerAddsSpawnPos = { 60.728395f, 0.0f, 38.93467f, float(M_PI) };
219
220// Horde encounter
221Position const SkybreakerTeleportPortal = { 6.666975f, 0.013001f, 20.87888f, 0.0f };
222Position const OrgrimsHammerTeleportExit = { 7.461699f, 0.158853f, 35.72989f, 0.0f };
223
224// Alliance encounter
225Position const OrgrimsHammerTeleportPortal = { 47.550990f, -0.101778f, 37.61111f, 0.0f };
226Position const SkybreakerTeleportExit = { -17.55738f, -0.090421f, 21.18366f, 0.0f };
227
230{
231 { 8.130936f, -0.2699585f, 20.31728f },
232 { 6.380936f, -0.2699585f, 20.31728f },
233 { 3.507703f, 0.02986573f, 20.78463f },
234 { -2.767633f, 3.743143f, 20.37663f },
235 { -4.017633f, 4.493143f, 20.12663f },
236 { -7.242224f, 6.856013f, 20.03468f },
237 { -7.742224f, 8.606013f, 20.78468f },
238 { -7.992224f, 9.856013f, 21.28468f },
239 { -12.24222f, 23.10601f, 21.28468f },
240 { -14.88477f, 25.20844f, 21.59985f },
241};
242
245{
246 { 30.43987f, 0.1475817f, 36.10674f },
247 { 21.36141f, -3.056458f, 35.42970f },
248 { 19.11141f, -3.806458f, 35.42970f },
249 { 19.01736f, -3.299440f, 35.39428f },
250 { 18.6747f, -5.862823f, 35.66611f },
251 { 18.6747f, -7.862823f, 35.66611f },
252 { 18.1747f, -17.36282f, 35.66611f },
253 { 18.1747f, -22.61282f, 35.66611f },
254 { 17.9247f, -24.36282f, 35.41611f },
255 { 17.9247f, -26.61282f, 35.66611f },
256 { 17.9247f, -27.86282f, 35.66611f },
257 { 17.9247f, -29.36282f, 35.66611f },
258 { 15.33203f, -30.42621f, 35.93796f }
259};
260
262{
263 // Freezing the cannons
265
266 // Channeling the portal, refilled with adds that board player's ship
269
270 // Rifleman
275
276 // Additional Rifleman on 25 man
281
282 // Mortar
285
286 // Additional spawns on 25 man
289
290 // Marines
293
294 // Additional spawns on 25 man
297
298 // Sergeants
300
301 // Additional spawns on 25 man
303
306
308{
312};
313
315{
316 { NPC_SKYBREAKER_SORCERER, { -9.479858f, 0.05663967f, 20.77026f, 4.729842f }, 0 },
317
318 { NPC_SKYBREAKER_SORCERER, { 6.385986f, 4.978760f, 20.55417f, 4.694936f }, 0 },
319 { NPC_SKYBREAKER_SORCERER, { 6.579102f, -4.674561f, 20.55060f, 1.553343f }, 0 },
320
321 { NPC_SKYBREAKER_RIFLEMAN, { -29.563900f, -17.95801f, 20.73837f, 4.747295f }, 30 },
322 { NPC_SKYBREAKER_RIFLEMAN, { -18.017210f, -18.82056f, 20.79150f, 4.747295f }, 30 },
323 { NPC_SKYBREAKER_RIFLEMAN, { -9.1193850f, -18.79102f, 20.58887f, 4.712389f }, 30 },
324 { NPC_SKYBREAKER_RIFLEMAN, { -0.3364258f, -18.87183f, 20.56824f, 4.712389f }, 30 },
325
326 { NPC_SKYBREAKER_RIFLEMAN, { -34.705810f, -17.67261f, 20.51523f, 4.729842f }, 30 },
327 { NPC_SKYBREAKER_RIFLEMAN, { -23.562010f, -18.28564f, 20.67859f, 4.729842f }, 30 },
328 { NPC_SKYBREAKER_RIFLEMAN, { -13.602780f, -18.74268f, 20.59622f, 4.712389f }, 30 },
329 { NPC_SKYBREAKER_RIFLEMAN, { -4.3350220f, -18.84619f, 20.58234f, 4.712389f }, 30 },
330
331 { NPC_SKYBREAKER_MORTAR_SOLDIER, { -31.70142f, 18.02783f, 20.77197f, 4.712389f }, 30 },
332 { NPC_SKYBREAKER_MORTAR_SOLDIER, { -9.368652f, 18.75806f, 20.65335f, 4.712389f }, 30 },
333
334 { NPC_SKYBREAKER_MORTAR_SOLDIER, { -20.40851f, 18.40381f, 20.50647f, 4.694936f }, 30 },
335 { NPC_SKYBREAKER_MORTAR_SOLDIER, { 0.1585693f, 18.11523f, 20.41949f, 4.729842f }, 30 },
336
339
342
344
346};
347
349{
350 { NPC_KOR_KRON_BATTLE_MAGE, { 13.58548f, 0.3867192f, 34.99243f, 1.53589f }, 0 },
351
352 { NPC_KOR_KRON_BATTLE_MAGE, { 47.29290f, -4.308941f, 37.55550f, 1.570796f }, 0 },
353 { NPC_KOR_KRON_BATTLE_MAGE, { 47.34621f, 4.032004f, 37.70952f, 4.817109f }, 0 },
354
355 { NPC_KOR_KRON_AXETHROWER, { -12.09280f, 27.65942f, 33.58557f, 1.53589f }, 30 },
356 { NPC_KOR_KRON_AXETHROWER, { -3.170555f, 28.30652f, 34.21082f, 1.53589f }, 30 },
357 { NPC_KOR_KRON_AXETHROWER, { 14.928040f, 26.18018f, 35.47803f, 1.53589f }, 30 },
358 { NPC_KOR_KRON_AXETHROWER, { 24.703310f, 25.36584f, 35.97845f, 1.53589f }, 30 },
359
360 { NPC_KOR_KRON_AXETHROWER, { -16.65302f, 27.59668f, 33.18726f, 1.53589f }, 30 },
361 { NPC_KOR_KRON_AXETHROWER, { -8.084572f, 28.21448f, 33.93805f, 1.53589f }, 30 },
362 { NPC_KOR_KRON_AXETHROWER, { 7.594765f, 27.41968f, 35.00775f, 1.53589f }, 30 },
363 { NPC_KOR_KRON_AXETHROWER, { 20.763390f, 25.58215f, 35.75287f, 1.53589f }, 30 },
364
365 { NPC_KOR_KRON_ROCKETEER, { -11.44849f, -25.71838f, 33.64343f, 1.518436f }, 30 },
366 { NPC_KOR_KRON_ROCKETEER, { 12.30336f, -25.69653f, 35.32373f, 1.518436f }, 30 },
367
368 { NPC_KOR_KRON_ROCKETEER, { -0.05931854f, -25.46399f, 34.50592f, 1.518436f }, 30 },
369 { NPC_KOR_KRON_ROCKETEER, { 27.62149000f, -23.48108f, 36.12708f, 1.518436f }, 30 },
370
373
376
378
380};
381
383{
384public:
386 {
388 }
389
390 void SetTransport(Transport* transport) { _transport = transport; }
391
393 {
394 _transport = nullptr;
395 for (uint32 i = 0; i < MAX_SLOTS; ++i)
396 _controlledSlots[i].Clear();
397
398 memset(_respawnCooldowns, 0, sizeof(time_t)* MAX_SLOTS);
401 }
402
404 {
405 if (!_transport)
406 return false;
407
408 bool summoned = false;
409 time_t now = GameTime::GetGameTime();
410 for (int32 i = first; i <= last; ++i)
411 {
412 if (_respawnCooldowns[i] > now)
413 continue;
414
415 if (!_controlledSlots[i].IsEmpty())
416 {
418 if (current && current->IsAlive())
419 continue;
420 }
421
423 {
424 _controlledSlots[i] = passenger->GetGUID();
425 _respawnCooldowns[i] = time_t(0);
426 passenger->AI()->SetData(ACTION_SET_SLOT, i);
427 summoned = true;
428 }
429 }
430
431 return summoned;
432 }
433
435 {
436 _controlledSlots[slot].Clear();
438 }
439
441 {
442 for (int32 i = first; i <= last; ++i)
443 if (!_controlledSlots[i])
444 return true;
445
446 return false;
447 }
448
449private:
451 {
452 Position newPos;
453 float angle = frand(float(-M_PI) * 0.5f, float(M_PI) * 0.5f);
454 newPos.m_positionX = _spawnPoint->GetPositionX() + 2.0f * std::cos(angle);
455 newPos.m_positionY = _spawnPoint->GetPositionY() + 2.0f * std::sin(angle);
458 return newPos;
459 }
460
466};
467
469{
470public:
471 DelayedMovementEvent(Creature* owner, Position const& dest) : _owner(owner), _dest(dest) { }
472
473 bool Execute(uint64, uint32) override
474 {
475 if (!_owner->IsAlive())
476 return true;
477
478 std::function<void(Movement::MoveSplineInit&)> initializer = [dest = _dest](Movement::MoveSplineInit& init)
479 {
480 init.DisableTransportPathTransformations();
481 init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), false);
482 };
484
485 return true;
486 }
487
488private:
491};
492
494{
495public:
496 ResetEncounterEvent(Unit* caster, uint32 spellId, ObjectGuid transport, ObjectGuid otherTransport) : _caster(caster), _spellId(spellId),
497 _transport(transport), _otherTransport(otherTransport) { }
498
499 bool Execute(uint64, uint32) override
500 {
502
504 go->AddObjectToRemoveList();
505
507 go->AddObjectToRemoveList();
508
509 return true;
510 }
511
512private:
517};
518
520{
521public:
522 static uint32 const ExperiencedSpells[5];
524
525 BattleExperienceEvent(Creature* creature) : _creature(creature), _level(0) { }
526
527 bool Execute(uint64 timer, uint32 /*diff*/) override
528 {
529 if (!_creature->IsAlive())
530 return true;
531
533 ++_level;
534
536 if (_level < (_creature->GetMap()->IsHeroic() ? 4 : 3))
537 {
539 return false;
540 }
541
542 return true;
543 }
544
545private:
548};
549
551Milliseconds const BattleExperienceEvent::ExperiencedTimes[5] = { 100s, 70s, 60s, 90s, 0s };
552
554{
555 gunship_npc_AI(Creature* creature) : ScriptedAI(creature),
556 Instance(creature->GetInstanceScript()), Slot(nullptr), Index(uint32(-1))
557 {
559 me->SetRegenerateHealth(false);
560 }
561
562 void SetData(uint32 type, uint32 data) override
563 {
564 if (type == ACTION_SET_SLOT && data < MAX_SLOTS)
565 {
566 SetSlotInfo(data);
567
569
570 float x, y, z, o;
571 Slot->TargetPosition.GetPosition(x, y, z, o);
572
574 float hx = x, hy = y, hz = z, ho = o;
575 me->GetTransport()->CalculatePassengerPosition(hx, hy, hz, &ho);
576 me->SetHomePosition(hx, hy, hz, ho);
577
578 std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
579 {
580 init.DisableTransportPathTransformations();
581 init.MoveTo(x, y, z, false);
582 };
584 }
585 }
586
587 void EnterEvadeMode(EvadeReason /*why*/) override
588 {
589 if (!me->IsAlive() || !me->IsInCombat())
590 return;
591
592 me->CombatStop(true);
595 }
596
597 void JustDied(Unit* /*killer*/) override
598 {
599 if (Slot)
601 captain->AI()->SetData(ACTION_CLEAR_SLOT, Index);
602 }
603
604 void MovementInform(uint32 type, uint32 pointId) override
605 {
606 if (type != POINT_MOTION_TYPE)
607 return;
608
609 if (pointId == EVENT_CHARGE_PREPATH && Slot)
610 {
615 }
616 }
617
618 bool CanAIAttack(Unit const* target) const override
619 {
621 return false;
623 }
624
625protected:
626 void SetSlotInfo(uint32 index)
627 {
628 Index = index;
630 }
631
633 {
635 {
637 return false;
638 }
639
641 {
642 if (Unit* victim = me->SelectVictim())
643 if (!me->HasSpellFocus() && victim != me->GetVictim())
644 AttackStart(victim);
645
646 return me->GetVictim() != nullptr;
647 }
649 {
651 return false;
652 }
653
654 return true;
655 }
656
658 {
662 {
664 me->GetSpellHistory()->AddCooldown(BurningPitchId, 0, std::chrono::milliseconds(urand(3000, 4000)));
665 }
666 }
667
672};
673
675{
676 public:
677 npc_gunship() : CreatureScript("npc_gunship") { }
678
680 {
681 npc_gunshipAI(Creature* creature) : NullCreatureAI(creature),
682 _teamInInstance(creature->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE)),
683 _summonedFirstMage(false), _died(false)
684 {
685 me->SetRegenerateHealth(false);
686 }
687
688 void DamageTaken(Unit* /*source*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
689 {
690 if (damage >= me->GetHealth())
691 {
692 JustDied(nullptr);
693 damage = me->GetHealth() - 1;
694 return;
695 }
696
698 return;
699
701 return;
702
703 if (!me->HealthBelowPctDamaged(90, damage))
704 return;
705
706 _summonedFirstMage = true;
708 captain->AI()->DoAction(ACTION_SPAWN_MAGE);
709 }
710
711 void JustDied(Unit* /*killer*/) override
712 {
713 if (_died)
714 return;
715
716 _died = true;
717
718 InstanceScript* instance = me->GetInstanceScript();
719 bool isVictory = me->GetTransport()->GetTransportGUID() == instance->GetGuidData(DATA_ENEMY_GUNSHIP);
720 instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, isVictory ? DONE : FAIL);
722 {
723 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature);
724 creature->RemoveAurasDueToSpell(SPELL_CHECK_FOR_PLAYERS);
725 }
726
729
731 std::list<Creature*> creatures;
733 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
734 {
735 Creature* stalker = *itr;
736 stalker->RemoveAllAuras();
737 stalker->CombatStop(true);
738 }
739
740 uint32 explosionSpell = isVictory ? SPELL_EXPLOSION_VICTORY : SPELL_EXPLOSION_WIPE;
741 creatures.clear();
743 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
744 {
745 Creature* hull = *itr;
746 if (hull->GetTransport() != me->GetTransport())
747 continue;
748
749 hull->CastSpell(hull, explosionSpell, TRIGGERED_FULL_MASK);
750 }
751
752 creatures.clear();
754 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
755 {
756 Creature* cannon = *itr;
757 if (isVictory)
758 {
760 cannon->RemoveVehicleKit();
761 }
762 else
764 }
765
766 uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD;
767 uint8 textId = isVictory ? SAY_MURADIN_VICTORY : SAY_MURADIN_WIPE;
768 if (_teamInInstance == HORDE)
769 {
770 creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG;
771 textId = isVictory ? SAY_SAURFANG_VICTORY : SAY_SAURFANG_WIPE;
772 }
773
774 if (Creature* creature = me->FindNearestCreature(creatureEntry, 100.0f))
775 creature->AI()->Talk(textId);
776
777 if (isVictory)
778 {
780 otherTransport->EnableMovement(true);
781
782 if (Transport* transport = dynamic_cast<Transport*>(me->GetTransport()))
783 transport->EnableMovement(true);
784
786 {
788 ship->CastSpell(ship, SPELL_ACHIEVEMENT, TRIGGERED_FULL_MASK);
790 }
791
792 creatures.clear();
797 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
798 (*itr)->DespawnOrUnsummon(1ms);
799 }
800 else
801 {
804 instance->GetGuidData(DATA_ENEMY_GUNSHIP)), 8s);
805 }
806 }
807
808 void SetGUID(ObjectGuid const& guid, int32 id) override
809 {
810 if (id != ACTION_SHIP_VISITS)
811 return;
812
813 std::map<ObjectGuid, uint32>::iterator itr = _shipVisits.find(guid);
814 if (itr == _shipVisits.end())
815 _shipVisits[guid] = 1;
816 else
817 ++itr->second;
818 }
819
820 uint32 GetData(uint32 id) const override
821 {
822 if (id != ACTION_SHIP_VISITS)
823 return 0;
824
825 uint32 max = 0;
826 for (std::map<ObjectGuid, uint32>::const_iterator itr = _shipVisits.begin(); itr != _shipVisits.end(); ++itr)
827 max = std::max(max, itr->second);
828
829 return max;
830 }
831
832 private:
834 std::map<ObjectGuid, uint32> _shipVisits;
836 bool _died;
837 };
838
839 CreatureAI* GetAI(Creature* creature) const override
840 {
841 if (!creature->GetTransport())
842 return nullptr;
843
844 return GetIcecrownCitadelAI<npc_gunshipAI>(creature);
845 }
846};
847
849{
851 _instance(creature->GetInstanceScript())
852 {
854 _controller.SetTransport(dynamic_cast<Transport*>(creature->GetTransport()));
855 me->SetRegenerateHealth(false);
856 me->m_CombatDistance = 70.0f;
858 _axethrowersYellCooldown = time_t(0);
859 _rocketeersYellCooldown = time_t(0);
860 }
861
862 void InitializeAI() override
863 {
865
866 _events.Reset();
868 _axethrowersYellCooldown = time_t(0);
869 _rocketeersYellCooldown = time_t(0);
870 }
871
872 void JustEngagedWith(Unit* /*target*/) override
873 {
878 }
879
880 void EnterEvadeMode(EvadeReason /*why*/) override
881 {
882 if (!me->IsAlive())
883 return;
884
885 me->CombatStop(true);
888
889 Reset();
890 }
891
892 void DoAction(int32 action) override
893 {
894 if (action == ACTION_ENEMY_GUNSHIP_TALK)
895 {
897 muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS);
898
903
905 // Combat starts now
906 if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f))
908
909 if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f))
910 {
912 orgrimsHammer->CastSpell(orgrimsHammer, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK);
913 }
914
916 }
917 else if (action == ACTION_SPAWN_MAGE)
918 {
919 TimePoint now = GameTime::Now();
920 if (_firstMageCooldown > now)
921 _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast<Milliseconds>(_firstMageCooldown - now));
922 else
924 }
925 else if (action == ACTION_SPAWN_ALL_ADDS)
926 {
930 if (Is25ManRaid())
932 else
933 {
937 }
938 }
939 else if (action == ACTION_EXIT_SHIP)
940 {
941 std::function<void(Movement::MoveSplineInit&)> initializer = [](Movement::MoveSplineInit& init)
942 {
944 init.DisableTransportPathTransformations();
945 init.MovebyPath(path, 0);
946 };
948
949 me->DespawnOrUnsummon(18s);
950 }
951 }
952
953 void SetData(uint32 type, uint32 data) override
954 {
955 if (type == ACTION_CLEAR_SLOT)
956 {
958 if (data == SLOT_FREEZE_MAGE)
960 }
961 }
962
963 bool OnGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override
964 {
966 if (Transport* transport = dynamic_cast<Transport*>(me->GetTransport()))
967 transport->EnableMovement(true);
974 return false;
975 }
976
977 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
978 {
981
982 if (damage >= me->GetHealth())
983 damage = me->GetHealth() - 1;
984 }
985
986 void UpdateAI(uint32 diff) override
987 {
989 return;
990
991 _events.Update(diff);
992
993 while (uint32 eventId = _events.ExecuteEvent())
994 {
995 switch (eventId)
996 {
997 case EVENT_INTRO_H_1:
999 break;
1000 case EVENT_INTRO_H_2:
1002 break;
1004 sTransportMgr->CreateTransport(GO_THE_SKYBREAKER_H, me->GetMap());
1005 break;
1006 case EVENT_INTRO_H_3:
1008 break;
1009 case EVENT_INTRO_H_4:
1011 break;
1012 case EVENT_INTRO_H_5:
1014 muradin->AI()->Talk(SAY_MURADIN_INTRO_H);
1015 break;
1016 case EVENT_INTRO_H_6:
1018 break;
1021 {
1024 }
1025 break;
1026 case EVENT_SUMMON_MAGE:
1029 break;
1030 case EVENT_ADDS:
1035 if (Transport* orgrimsHammer = dynamic_cast<Transport*>(me->GetTransport()))
1036 orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21s);
1037
1039 skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23s);
1040
1043 break;
1046 muradin->AI()->Talk(SAY_MURADIN_BOARD);
1047 break;
1050 {
1052 {
1055 }
1056 }
1058 break;
1059 case EVENT_CHECK_MORTAR:
1061 {
1063 {
1066 }
1067 }
1069 break;
1070 case EVENT_CLEAVE:
1073 break;
1074 default:
1075 break;
1076 }
1077 }
1078
1080 {
1081 if (me->isAttackReady())
1082 {
1085 }
1086 }
1087 }
1088
1089 bool CanAIAttack(Unit const* target) const override
1090 {
1092 return false;
1094 }
1095
1096private:
1103};
1104
1106{
1108 _instance(creature->GetInstanceScript())
1109 {
1111 _controller.SetTransport(dynamic_cast<Transport*>(creature->GetTransport()));
1112 me->SetRegenerateHealth(false);
1113 me->m_CombatDistance = 70.0f;
1115 _riflemanYellCooldown = time_t(0);
1116 _mortarYellCooldown = time_t(0);
1117 }
1118
1119 void InitializeAI() override
1120 {
1122
1123 _events.Reset();
1125 _riflemanYellCooldown = time_t(0);
1126 _mortarYellCooldown = time_t(0);
1127 }
1128
1129 void JustEngagedWith(Unit* /*target*/) override
1130 {
1133 DoCast(me, SPELL_BATTLE_FURY, true);
1135 }
1136
1137 void EnterEvadeMode(EvadeReason /*why*/) override
1138 {
1139 if (!me->IsAlive())
1140 return;
1141
1142 me->CombatStop(true);
1145
1146 Reset();
1147 }
1148
1149 void DoAction(int32 action) override
1150 {
1151 if (action == ACTION_ENEMY_GUNSHIP_TALK)
1152 {
1154 muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS);
1155
1160
1162 // Combat starts now
1163 if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f))
1165
1166 if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f))
1167 {
1169 skybreaker->CastSpell(skybreaker, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK);
1170 }
1171
1173 }
1174 else if (action == ACTION_SPAWN_MAGE)
1175 {
1176 TimePoint now = GameTime::Now();
1177 if (_firstMageCooldown > now)
1178 _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast<Milliseconds>(_firstMageCooldown - now));
1179 else
1181 }
1182 else if (action == ACTION_SPAWN_ALL_ADDS)
1183 {
1187 if (Is25ManRaid())
1189 else
1190 {
1194 }
1195 }
1196 else if (action == ACTION_EXIT_SHIP)
1197 {
1198 std::function<void(Movement::MoveSplineInit&)> initializer = [](Movement::MoveSplineInit& init)
1199 {
1201 init.DisableTransportPathTransformations();
1202 init.MovebyPath(path, 0);
1203 };
1205
1206 me->DespawnOrUnsummon(18s);
1207 }
1208 }
1209
1210 void SetData(uint32 type, uint32 data) override
1211 {
1212 if (type == ACTION_CLEAR_SLOT)
1213 {
1215 if (data == SLOT_FREEZE_MAGE)
1217 }
1218 }
1219
1220 bool OnGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) override
1221 {
1223 if (Transport* transport = dynamic_cast<Transport*>(me->GetTransport()))
1224 transport->EnableMovement(true);
1232 return false;
1233 }
1234
1235 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1236 {
1239
1240 if (damage >= me->GetHealth())
1241 damage = me->GetHealth() - 1;
1242 }
1243
1244 void UpdateAI(uint32 diff) override
1245 {
1247 return;
1248
1249 _events.Update(diff);
1250
1251 while (uint32 eventId = _events.ExecuteEvent())
1252 {
1253 switch (eventId)
1254 {
1255 case EVENT_INTRO_A_1:
1257 break;
1258 case EVENT_INTRO_A_2:
1260 break;
1262 sTransportMgr->CreateTransport(GO_ORGRIMS_HAMMER_A, me->GetMap());
1263 break;
1264 case EVENT_INTRO_A_3:
1266 break;
1267 case EVENT_INTRO_A_4:
1269 break;
1270 case EVENT_INTRO_A_5:
1272 break;
1273 case EVENT_INTRO_A_6:
1275 saurfang->AI()->Talk(SAY_SAURFANG_INTRO_A);
1276 break;
1277 case EVENT_INTRO_A_7:
1279 break;
1282 {
1285 }
1286 break;
1287 case EVENT_SUMMON_MAGE:
1290 break;
1291 case EVENT_ADDS:
1296 if (Transport* skybreaker = dynamic_cast<Transport*>(me->GetTransport()))
1297 skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21s);
1298
1300 orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23s);
1301
1304 break;
1307 saurfang->AI()->Talk(SAY_SAURFANG_BOARD);
1308 break;
1311 {
1313 {
1316 }
1317 }
1319 break;
1320 case EVENT_CHECK_MORTAR:
1322 {
1324 {
1327 }
1328 }
1330 break;
1331 case EVENT_CLEAVE:
1334 break;
1335 default:
1336 break;
1337 }
1338 }
1339
1341 {
1342 if (me->isAttackReady())
1343 {
1346 }
1347 }
1348 }
1349
1350 bool CanAIAttack(Unit const* target) const override
1351 {
1353 return false;
1354 return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || target->GetEntry() == NPC_KOR_KRON_REAVER || target->GetEntry() == NPC_KOR_KRON_SERGEANT;
1355 }
1356
1357private:
1364};
1365
1367{
1368 npc_zafod_boombox(Creature* creature) : gunship_npc_AI(creature) { }
1369
1370 void Reset() override
1371 {
1373 }
1374
1375 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
1376 {
1378 CloseGossipMenuFor(player);
1379 return false;
1380 }
1381
1382 void UpdateAI(uint32 /*diff*/) override
1383 {
1384 UpdateVictim();
1385 }
1386};
1387
1389{
1391 {
1392 me->m_CombatDistance = 80.0f;
1393 _usedDesperateResolve = false;
1394 }
1395
1396 void SetData(uint32 type, uint32 data) override
1397 {
1398 // detach from captain
1399 if (type == ACTION_SET_SLOT)
1400 {
1401 SetSlotInfo(data);
1402
1404
1406
1408 captain->AI()->SetData(ACTION_CLEAR_SLOT, Index);
1409 }
1410 }
1411
1412 void MovementInform(uint32 type, uint32 pointId) override
1413 {
1414 if (type != POINT_MOTION_TYPE)
1415 return;
1416
1417 if (pointId == EVENT_CHARGE_PREPATH && Slot)
1418 {
1420 float x, y, z, o;
1421 otherTransportPos.GetPosition(x, y, z, o);
1422
1423 TransportBase* myTransport = me->GetTransport();
1424 if (!myTransport)
1425 return;
1426
1428 destTransport->CalculatePassengerPosition(x, y, z, &o);
1429
1430 float angle = frand(0, float(M_PI) * 2.0f);
1431 x += 2.0f * std::cos(angle);
1432 y += 2.0f * std::sin(angle);
1433
1434 me->SetHomePosition(x, y, z, o);
1435 myTransport->CalculatePassengerOffset(x, y, z, &o);
1436 me->SetTransportHomePosition(x, y, z, o);
1437
1442 me->GetSpellHistory()->AddCooldown(BurningPitchId, 0, std::chrono::seconds(3));
1443
1444 std::list<Player*> players;
1447 Cell::VisitWorldObjects(me, searcher, 200.0f);
1448
1449 players.remove_if([this](Player* player)
1450 {
1451 return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true);
1452 });
1453
1454 if (!players.empty())
1455 {
1456 players.sort(Trinity::ObjectDistanceOrderPred(me));
1457 for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
1458 AddThreat(*itr, 1.0f);
1459
1460 AttackStart(players.front());
1461 }
1462
1464 }
1465 }
1466
1467 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1468 {
1470 return;
1471
1472 if (!me->HealthBelowPctDamaged(25, damage))
1473 return;
1474
1475 _usedDesperateResolve = true;
1477 }
1478
1479 void UpdateAI(uint32 /*diff*/) override
1480 {
1481 if (!SelectVictim())
1482 {
1484 return;
1485 }
1486
1489 }
1490
1491 bool CanAIAttack(Unit const* target) const override
1492 {
1494 uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD;
1496 {
1498 creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG;
1499 }
1500
1501 return target->HasAura(spellId) || target->GetEntry() == creatureEntry;
1502 }
1503
1505 {
1506 std::list<Player*> players;
1509 Cell::VisitWorldObjects(me, searcher,200.0f );
1510
1511 players.remove_if([this](Player* player)
1512 {
1513 return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true);
1514 });
1515
1516 return !players.empty();
1517 }
1518
1519private:
1521};
1522
1524{
1526
1527 void JustEngagedWith(Unit* target) override
1528 {
1532 }
1533
1534 void UpdateAI(uint32 diff) override
1535 {
1536 if (!SelectVictim())
1537 {
1539 return;
1540 }
1541
1542 _events.Update(diff);
1543
1545 return;
1546
1549
1550 while (uint32 eventId = _events.ExecuteEvent())
1551 {
1552 switch (eventId)
1553 {
1554 case EVENT_BLADESTORM:
1557 break;
1561 break;
1562 default:
1563 break;
1564 }
1565 }
1566 }
1567
1568private:
1570};
1571
1573{
1574 public:
1575 npc_gunship_boarding_add() : CreatureScript("npc_gunship_boarding_add") { }
1576
1577 CreatureAI* GetAI(Creature* creature) const override
1578 {
1579 return GetIcecrownCitadelAI<npc_gunship_boarding_addAI>(creature);
1580 }
1581};
1582
1584{
1586 {
1587 creature->m_CombatDistance = 200.0f;
1588 }
1589
1590 void AttackStart(Unit* target) override
1591 {
1592 me->Attack(target, false);
1593 }
1594
1595 void MovementInform(uint32 type, uint32 pointId) override
1596 {
1597 gunship_npc_AI::MovementInform(type, pointId);
1598 if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH)
1600 }
1601
1602 void UpdateAI(uint32 /*diff*/) override
1603 {
1604 if (!SelectVictim())
1605 {
1607 return;
1608 }
1609
1611 }
1612};
1613
1615{
1617 {
1618 creature->m_CombatDistance = 200.0f;
1619 }
1620
1621 void MovementInform(uint32 type, uint32 pointId) override
1622 {
1623 gunship_npc_AI::MovementInform(type, pointId);
1624 if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH)
1626 }
1627
1628 void UpdateAI(uint32 /*diff*/) override
1629 {
1630 if (!SelectVictim())
1631 return;
1632
1634 return;
1635
1637 if (me->GetSpellHistory()->HasCooldown(spellId))
1638 return;
1639
1640 DoCastAOE(spellId, true);
1641 me->GetSpellHistory()->AddCooldown(spellId, 0, std::chrono::seconds(9));
1642 }
1643};
1644
1646{
1648 {
1650 }
1651
1652 void EnterEvadeMode(EvadeReason /*why*/) override { }
1653
1654 void MovementInform(uint32 type, uint32 pointId) override
1655 {
1656 if (type != POINT_MOTION_TYPE)
1657 return;
1658
1659 if (pointId == EVENT_CHARGE_PREPATH && Slot)
1660 {
1662 me->SetFacingTo(slots[Index].TargetPosition.GetOrientation());
1663 switch (Index)
1664 {
1665 case SLOT_FREEZE_MAGE:
1667 break;
1668 case SLOT_MAGE_1:
1669 case SLOT_MAGE_2:
1671 break;
1672 default:
1673 break;
1674 }
1675
1677 }
1678 }
1679
1680 void UpdateAI(uint32 /*diff*/) override
1681 {
1682 UpdateVictim();
1683 }
1684
1685 bool CanAIAttack(Unit const* /*target*/) const override
1686 {
1687 return true;
1688 }
1689};
1690
1712{
1713 npc_gunship_cannon(Creature* creature) : PassiveAI(creature) { }
1714
1715 void OnCharmed(bool /*isNew*/) override { }
1716
1717 void PassengerBoarded(Unit* /*passenger*/, int8 /*seat*/, bool apply) override
1718 {
1719 if (!apply)
1720 {
1723 }
1724 }
1725};
1726
1727// 68721 - Rocket Pack
1729{
1730 bool Validate(SpellInfo const* /*spellInfo*/) override
1731 {
1734 }
1735
1736 void HandlePeriodic(AuraEffect const* /*aurEff*/)
1737 {
1738 if (!GetTarget()->IsSplineEnabled())
1740 }
1741
1742 void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1743 {
1744 SpellInfo const* damageInfo = sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE, GetCastDifficulty());
1747 args.AddSpellBP0(2 * (damageInfo->GetEffect(EFFECT_0).CalcValue() + aurEff->GetTickNumber() * aurEff->GetPeriod()));
1748 GetTarget()->CastSpell(nullptr, SPELL_ROCKET_PACK_DAMAGE, args);
1750 }
1751
1752 void Register() override
1753 {
1756 }
1757};
1758
1759// 70348 - Rocket Pack Useable
1761{
1762 bool Load() override
1763 {
1764 return GetOwner()->GetInstanceScript() != nullptr;
1765 }
1766
1767 bool CheckAreaTarget(Unit* target)
1768 {
1770 }
1771
1772 void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1773 {
1774 if (Creature* owner = GetOwner()->ToCreature())
1775 if (Player* target = GetTarget()->ToPlayer())
1776 if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1))
1778 }
1779
1780 void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1781 {
1782 if (Creature* owner = GetOwner()->ToCreature())
1783 if (Player* target = GetTarget()->ToPlayer())
1784 if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1))
1786 }
1787
1788 void Register() override
1789 {
1793 }
1794};
1795
1796// 70120 - On Skybreaker Deck
1797// 70121 - On Orgrim's Hammer Deck
1799{
1800public:
1802 {
1803 _teamInInstance = 0;
1804 }
1805
1806private:
1807 bool Load() override
1808 {
1809 if (InstanceScript* instance = GetOwner()->GetInstanceScript())
1810 _teamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE);
1811 else
1812 _teamInInstance = 0;
1813 return true;
1814 }
1815
1817 {
1818 return unit->GetTypeId() == TYPEID_PLAYER;
1819 }
1820
1821 void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1822 {
1824 if (Creature* gunship = GetOwner()->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f))
1825 gunship->AI()->SetGUID(GetTarget()->GetGUID(), ACTION_SHIP_VISITS);
1826 }
1827
1828 void Register() override
1829 {
1832 }
1833
1835};
1836
1837// 69470 - Heat Drain
1838// 69487 - Overheat
1840{
1841 void HandlePeriodicTick(AuraEffect const* aurEff)
1842 {
1845 }
1846
1847 void Register() override
1848 {
1850 }
1851};
1852
1853// 69399, 70172 - Cannon Blast
1855{
1856 bool Load() override
1857 {
1858 return GetCaster()->GetTypeId() == TYPEID_UNIT;
1859 }
1860
1862 {
1863 if (GetCaster()->GetPower(POWER_ENERGY) >= 100)
1864 {
1866 if (Vehicle* vehicle = GetCaster()->GetVehicleKit())
1867 if (Unit* passenger = vehicle->GetPassenger(0))
1868 sCreatureTextMgr->SendChat(GetCaster()->ToCreature(), SAY_OVERHEAT, passenger);
1869 }
1870 }
1871
1872 void Register() override
1873 {
1875 }
1876};
1877
1878// 69402, 70175 - Incinerating Blast
1880{
1882 {
1884 }
1885
1887 {
1889 }
1890
1891 void CalculateDamage(Unit const* /*victim*/, int32& /*damage*/, int32& flatMod, float& /*pctMod*/) const
1892 {
1893 flatMod += _energyLeft * _energyLeft * 8;
1894 }
1895
1896 void Register() override
1897 {
1901 }
1902
1904};
1905
1906// 69487 - Overheat
1908{
1909 bool Load() override
1910 {
1911 if (GetAura()->GetType() != UNIT_AURA_TYPE)
1912 return false;
1913 return GetUnitOwner()->IsVehicle();
1914 }
1915
1916 void SendClientControl(bool value)
1917 {
1918 if (Vehicle* vehicle = GetUnitOwner()->GetVehicleKit())
1919 {
1920 if (Unit* passenger = vehicle->GetPassenger(0))
1921 {
1922 if (Player* player = passenger->ToPlayer())
1923 {
1925 data.Guid = GetUnitOwner()->GetGUID();
1926 data.On = value;
1927 player->SendDirectMessage(data.Write());
1928 }
1929 }
1930 }
1931 }
1932
1933 void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1934 {
1935 SendClientControl(false);
1936 }
1937
1938 void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1939 {
1940 SendClientControl(true);
1941 }
1942
1943 void Register() override
1944 {
1947 }
1948};
1949
1950// 69705 - Below Zero
1952{
1954 {
1955 if (missInfo != SPELL_MISS_NONE)
1956 return;
1957
1959 }
1960
1961 void Register() override
1962 {
1964 }
1965};
1966
1967// 70104 - Teleport to Enemy Ship
1969{
1971 {
1972 WorldLocation const* dest = GetHitDest();
1973 Unit* target = GetHitUnit();
1974 if (!dest || !target || !target->GetTransport())
1975 return;
1976
1977 float x, y, z, o;
1978 dest->GetPosition(x, y, z, o);
1979 target->GetTransport()->CalculatePassengerOffset(x, y, z, &o);
1980 target->m_movementInfo.transport.pos.Relocate(x, y, z, o);
1981 }
1982
1983 void Register() override
1984 {
1986 }
1987};
1988
1989// 70397, 70403 - Burning Pitch
1991{
1992 void FilterTargets(std::list<WorldObject*>& targets)
1993 {
1994 uint32 team = HORDE;
1995 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
1996 team = instance->GetData(DATA_TEAM_IN_INSTANCE);
1997
1998 targets.remove_if([team](WorldObject* target) -> bool
1999 {
2000 if (Transport* transport = dynamic_cast<Transport*>(target->GetTransport()))
2001 return transport->GetEntry() != uint32(team == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A);
2002 return true;
2003 });
2004
2005 if (!targets.empty())
2006 {
2008 targets.clear();
2009 targets.push_back(target);
2010 }
2011 }
2012
2014 {
2015 PreventHitDefaultEffect(effIndex);
2017 }
2018
2019 void Register() override
2020 {
2023 }
2024};
2025
2026// 71335, 71339 - Burning Pitch
2028{
2030 {
2031 PreventHitDefaultEffect(effIndex);
2033 args.AddSpellBP0(8000);
2034 GetCaster()->CastSpell(nullptr, GetEffectValue(), args);
2036 }
2037
2038 void Register() override
2039 {
2041 }
2042};
2043
2044// 69678, 70609 - Rocket Artillery
2046{
2047 void SelectRandomTarget(std::list<WorldObject*>& targets)
2048 {
2049 if (!targets.empty())
2050 {
2052 targets.clear();
2053 targets.push_back(target);
2054 }
2055 }
2056
2058 {
2059 PreventHitDefaultEffect(effIndex);
2061 }
2062
2063 void Register() override
2064 {
2067 }
2068};
2069
2070// 69679 - Rocket Artillery
2072{
2073 void DamageGunship(SpellEffIndex /*effIndex*/)
2074 {
2075 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
2076 {
2078 args.AddSpellBP0(5000);
2080 }
2081 }
2082
2083 void Register() override
2084 {
2086 }
2087};
2088
2089// 67335 - Gunship Fall Teleport
2091{
2092 bool Load() override
2093 {
2094 return GetCaster()->GetInstanceScript() != nullptr;
2095 }
2096
2098 {
2099 if (InstanceScript* instance = target->GetInstanceScript())
2100 target = ObjectAccessor::GetTransport(*GetCaster(), instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE));
2101 }
2102
2103 void RelocateDest(SpellEffIndex /*effIndex*/)
2104 {
2105 if (GetCaster()->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE) == HORDE)
2106 GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 36.0f, 0.0f });
2107 else
2108 GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 21.0f, 0.0f });
2109 }
2110
2111 void Register() override
2112 {
2115 }
2116};
2117
2118// 70331 - Check for Players
2120{
2121public:
2123 {
2124 _playerCount = 0;
2125 }
2126
2127private:
2128 bool Load() override
2129 {
2130 return GetCaster()->GetTypeId() == TYPEID_UNIT;
2131 }
2132
2133 void CountTargets(std::list<WorldObject*>& targets)
2134 {
2135 _playerCount = targets.size();
2136 }
2137
2139 {
2140 if (!_playerCount)
2141 GetCaster()->ToCreature()->AI()->JustDied(nullptr);
2142 }
2143
2145 {
2146 if (GetHitUnit()->GetPositionZ() < GetCaster()->GetPositionZ() - 10.0f)
2148 }
2149
2150 void Register() override
2151 {
2155 }
2156
2158};
2159
2160// 72340 - Teleport Players on Victory
2162{
2163 bool Load() override
2164 {
2165 return GetCaster()->GetInstanceScript() != nullptr;
2166 }
2167
2168 void FilterTargets(std::list<WorldObject*>& targets)
2169 {
2171 targets.remove_if([instance](WorldObject* target) -> bool
2172 {
2173 return target->GetTransGUID() != instance->GetGuidData(DATA_ENEMY_GUNSHIP);
2174 });
2175 }
2176
2177 void Register() override
2178 {
2180 }
2181};
2182
2183// 71201 - Battle Experience - proc should never happen, handled in script
2185{
2186 bool CheckProc(ProcEventInfo& /*eventInfo*/)
2187 {
2188 return false;
2189 }
2190
2191 void Register() override
2192 {
2194 }
2195};
2196
2198{
2199 public:
2200 achievement_im_on_a_boat() : AchievementCriteriaScript("achievement_im_on_a_boat") { }
2201
2202 bool OnCheck(Player* /*source*/, Unit* target) override
2203 {
2204 return target->GetAI() && target->GetAI()->GetData(ACTION_SHIP_VISITS) <= 2;
2205 }
2206};
2207
2209{
2210 // Creatures
2211 new npc_gunship();
2221
2222 // Spells
2240
2241 // Achievements
2243}
Texts
@ NPC_ALLIANCE_GUNSHIP_CANNON
@ NPC_HORDE_GUNSHIP_CANNON
#define M_PI
Definition: Common.h:115
#define sCreatureTextMgr
@ TEXT_RANGE_NORMAL
uint8_t uint8
Definition: Define.h:144
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
uint32_t uint32
Definition: Define.h:142
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
Definition: Duration.h:41
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
#define SIZE_OF_GRIDS
Definition: GridDefines.h:40
@ IN_PROGRESS
@ FAIL
@ DONE
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ MOTION_PRIORITY_NORMAL
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
Definition: ObjectDefines.h:68
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
Spells
Definition: PlayerAI.cpp:32
float frand(float min, float max)
Definition: Random.cpp:55
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
void CloseGossipMenuFor(Player *player)
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_1
Definition: SharedDefines.h:31
@ EFFECT_0
Definition: SharedDefines.h:30
@ LANG_ADDON
SpellMissInfo
@ SPELL_MISS_NONE
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_DEST_NEARBY_ENTRY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TARGET_UNIT_DEST_AREA_ENTRY
@ EVENT_CHARGE_PREPATH
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_TRIGGER_MISSILE
@ SPELL_EFFECT_TELEPORT_UNITS
@ TEAM_OTHER
@ ALLIANCE
@ HORDE
@ POWER_ENERGY
@ CHAT_MSG_ADDON
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_EXPIRE
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ UNIT_AURA_TYPE
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore power and reagent cost.
Definition: SpellDefines.h:249
@ TRIGGERED_NONE
Not triggered.
Definition: SpellDefines.h:246
#define sSpellMgr
Definition: SpellMgr.h:849
#define BeforeSpellHitFn(F)
Definition: SpellScript.h:847
#define SpellObjectTargetSelectFn(F, I, N)
Definition: SpellScript.h:869
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
#define AuraEffectPeriodicFn(F, I, N)
Definition: SpellScript.h:2046
#define SpellCalcDamageFn(F)
Definition: SpellScript.h:879
#define SpellCastFn(F)
Definition: SpellScript.h:825
#define AuraEffectApplyFn(F, I, N, M)
Definition: SpellScript.h:2029
#define AuraCheckProcFn(F)
Definition: SpellScript.h:2130
#define SpellHitFn(F)
Definition: SpellScript.h:854
#define AuraCheckAreaTargetFn(F)
Definition: SpellScript.h:2008
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:2040
#define sTransportMgr
Definition: TransportMgr.h:183
EvadeReason
Definition: UnitAICommon.h:30
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ UNIT_NPC_FLAG_GOSSIP
Definition: UnitDefines.h:297
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_STATE_ROOT
Definition: Unit.h:265
@ UNIT_STATE_CASTING
Definition: Unit.h:270
MiscData
uint32 const SaurfangExitPathSize
@ SPELL_FRIENDLY_BOSS_DAMAGE_MOD
@ SPELL_EJECT_ALL_PASSENGERS_WIPE
@ SPELL_AWARD_REPUTATION_BOSS_KILL
@ SPELL_MELEE_TARGETING_ON_SKYBREAKER
@ SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER
@ SPELL_LOCK_PLAYERS_AND_TAP_CHEST
@ SPELL_TELEPORT_PLAYERS_ON_RESET_H
@ SPELL_TELEPORT_PLAYERS_ON_RESET_A
@ SPELL_TELEPORT_PLAYERS_ON_VICTORY
@ SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO
G3D::Vector3 const SaurfangExitPath[SaurfangExitPathSize]
SlotInfo const SkybreakerSlotInfo[MAX_SLOTS]
Position const SkybreakerTeleportPortal
Position const OrgrimsHammerTeleportPortal
Position const OrgrimsHammerTeleportExit
SlotInfo const OrgrimsHammerSlotInfo[MAX_SLOTS]
@ SAY_ZAFOD_ROCKET_PACK_ACTIVE
@ SAY_SAURFANG_ENTER_SKYBREAKER
@ SAY_MURADIN_ENTER_ORGRIMMS_HAMMER
@ SAY_ZAFOD_ROCKET_PACK_DISABLED
Position const SkybreakerAddsSpawnPos
Position const OrgrimsHammerAddsSpawnPos
G3D::Vector3 const MuradinExitPath[MuradinExitPathSize]
void AddSC_boss_icecrown_gunship_battle()
uint32 const MuradinExitPathSize
Position const SkybreakerTeleportExit
@ EVENT_INTRO_SUMMON_ORGRIMS_HAMMER
@ EVENT_INTRO_SUMMON_SKYBREAKER
uint32 GetTickNumber() const
SpellEffectInfo const & GetSpellEffectInfo() const
int32 GetPeriod() const
void PreventDefaultAction()
AuraObjectType GetType() const
HookList< EffectApplyHandler > AfterEffectRemove
Definition: SpellScript.h:2039
HookList< EffectPeriodicHandler > OnEffectPeriodic
Definition: SpellScript.h:2045
SpellInfo const * GetSpellInfo() const
WorldObject * GetOwner() const
HookList< EffectApplyHandler > AfterEffectApply
Definition: SpellScript.h:2028
Aura * GetAura() const
HookList< CheckAreaTargetHandler > DoCheckAreaTarget
Definition: SpellScript.h:2007
Unit * GetTarget() const
Difficulty GetCastDifficulty() const
HookList< CheckProcHandler > DoCheckProc
Definition: SpellScript.h:2129
HookList< EffectApplyHandler > OnEffectRemove
Definition: SpellScript.h:2035
void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Unit * GetUnitOwner() const
bool Execute(uint64 timer, uint32) override
static uint32 const ExperiencedSpells[5]
static Milliseconds const ExperiencedTimes[5]
virtual void JustEngagedWith(Unit *)
Definition: CreatureAI.h:99
virtual void JustDied(Unit *)
Definition: CreatureAI.h:105
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void EngagementOver()
Definition: CreatureAI.cpp:287
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:371
bool _IsTargetAcceptable(Unit const *target) const
Definition: Creature.cpp:2639
bool HasReactState(ReactStates state) const
Definition: Creature.h:162
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
void SetRegenerateHealth(bool value)
Definition: Creature.h:358
float m_CombatDistance
Definition: Creature.h:412
Unit * SelectVictim()
Definition: Creature.cpp:1211
void SetTransportHomePosition(float x, float y, float z, float o)
Definition: Creature.h:376
CreatureAI * AI() const
Definition: Creature.h:214
bool CanStartAttack(Unit const *u, bool force) const
Definition: Creature.cpp:2099
bool HasSpellFocus(Spell const *focusSpell=nullptr) const override
Definition: Creature.cpp:3481
DelayedMovementEvent(Creature *owner, Position const &dest)
bool Execute(uint64, uint32) override
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void Reset()
Definition: EventMap.cpp:21
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
void AddEventAtOffset(BasicEvent *event, Milliseconds offset)
Milliseconds CalculateTime(Milliseconds t_offset) const
virtual bool SetBossState(uint32 id, EncounterState state)
void DoCastSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
virtual ObjectGuid GetGuidData(uint32 type) const override
EncounterState GetBossState(uint32 id) const
void SendEncounterUnit(EncounterFrameType type, Unit const *unit, Optional< int32 > param1={}, Optional< int32 > param2={})
void SetZoneMusic(uint32 zoneId, uint32 musicId)
Definition: Map.cpp:3913
bool IsHeroic() const
Definition: Map.cpp:3282
void LaunchMoveSpline(std::function< void(Movement::MoveSplineInit &init)> &&initializer, uint32 id=0, MovementGeneratorPriority priority=MOTION_PRIORITY_NORMAL, MovementGeneratorType type=EFFECT_MOTION_TYPE)
void MoveTargetedHome()
void Clear()
Definition: ObjectGuid.h:286
static Creature * ToCreature(Object *o)
Definition: Object.h:219
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
void SetTransport(Transport *transport)
bool SummonCreatures(PassengerSlots first, PassengerSlots last)
bool SlotsNeedRefill(PassengerSlots first, PassengerSlots last) const
void ClearSlot(PassengerSlots slot)
ObjectGuid _controlledSlots[MAX_SLOTS]
ResetEncounterEvent(Unit *caster, uint32 spellId, ObjectGuid transport, ObjectGuid otherTransport)
bool Execute(uint64, uint32) override
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
Definition: SpellInfo.cpp:495
uint32 TriggerSpell
Definition: SpellInfo.h:237
void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration)
Definition: SpellHistory.h:108
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0) const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition: SpellInfo.h:577
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
Definition: SpellScript.h:173
HookList< DamageAndHealingCalcHandler > CalcDamage
Definition: SpellScript.h:878
HookList< CastHandler > AfterCast
Definition: SpellScript.h:824
WorldLocation * GetHitDest() const
Unit * GetCaster() const
HookList< HitHandler > AfterHit
Definition: SpellScript.h:852
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:839
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< ObjectTargetSelectHandler > OnObjectTargetSelect
Definition: SpellScript.h:868
HookList< CastHandler > OnCast
Definition: SpellScript.h:822
HookList< BeforeHitHandler > BeforeHit
Definition: SpellScript.h:846
HookList< EffectHandler > OnEffectLaunch
Definition: SpellScript.h:837
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
bool IsThreatListEmpty(bool includeOffline=false) const
virtual ObjectGuid GetTransportGUID() const =0
virtual void CalculatePassengerPosition(float &x, float &y, float &z, float *o=nullptr) const =0
This method transforms supplied transport offsets into global coordinates.
virtual void CalculatePassengerOffset(float &x, float &y, float &z, float *o=nullptr) const =0
This method transforms supplied global coordinates into local offsets.
TempSummon * SummonPassenger(uint32 entry, Position const &pos, TempSummonType summonType, SummonPropertiesEntry const *properties=nullptr, Milliseconds duration=0ms, Unit *summoner=nullptr, uint32 spellId=0, uint32 vehId=0)
Temporarily summons a creature as passenger on this transport.
Definition: Transport.cpp:409
bool DoSpellAttackIfReady(uint32 spellId)
Definition: UnitAI.cpp:61
virtual void Reset()
Definition: UnitAI.h:63
virtual void InitializeAI()
Definition: UnitAI.cpp:43
virtual uint32 GetData(uint32) const
Definition: UnitAI.h:73
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
bool IsVehicle() const
Definition: Unit.h:743
bool IsWithinMeleeRange(Unit const *obj) const
Definition: Unit.h:699
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition: Unit.cpp:5827
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:10911
void SetPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:9419
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsAlive() const
Definition: Unit.h:1164
void RemoveNpcFlag(NPCFlags flags)
Definition: Unit.h:983
UnitAI * GetAI() const
Definition: Unit.h:660
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:5670
uint64 GetHealth() const
Definition: Unit.h:776
Unit * GetVictim() const
Definition: Unit.h:715
int32 GetPower(Powers power) const
Definition: Unit.cpp:9401
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
void RemoveAllAuras()
Definition: Unit.cpp:4242
SpellHistory * GetSpellHistory()
Definition: Unit.h:1457
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition: Unit.h:781
void RemoveVehicleKit(bool onRemoveFromWorld=false)
Definition: Unit.cpp:11459
bool isAttackReady(WeaponAttackType type=BASE_ATTACK) const
Definition: Unit.h:690
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:630
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
bool IsInCombat() const
Definition: Unit.h:1043
Map * GetMap() const
Definition: Object.h:624
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
TransportBase * GetTransport() const
Definition: Object.h:750
virtual ObjectGuid GetTransGUID() const
Definition: Object.cpp:3748
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
EventProcessor m_Events
Definition: Object.h:777
MovementInfo m_movementInfo
Definition: Object.h:761
WorldPacket const * Write() override
virtual uint32 GetData(uint32) const
Definition: ZoneScript.h:91
bool OnCheck(Player *, Unit *target) override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
void RemovePassengers(SpellMissInfo missInfo)
void FilterTargets(std::list< WorldObject * > &targets)
void HandleDummy(SpellEffIndex effIndex)
void CountTargets(std::list< WorldObject * > &targets)
void CalculateDamage(Unit const *, int32 &, int32 &flatMod, float &) const
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
void HandleRemove(AuraEffect const *, AuraEffectHandleModes)
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
void SelectRandomTarget(std::list< WorldObject * > &targets)
void HandleScript(SpellEffIndex effIndex)
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
void HandleRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
void HandlePeriodic(AuraEffect const *)
void HandleRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
void FilterTargets(std::list< WorldObject * > &targets)
@ DATA_TEAM_IN_INSTANCE
#define RegisterIcecrownCitadelCreatureAI(ai_name)
@ AREA_ICECROWN_CITADEL
@ GO_THE_SKYBREAKER_A
@ GO_THE_SKYBREAKER_H
@ GO_ORGRIMS_HAMMER_A
@ GO_ORGRIMS_HAMMER_H
@ ACTION_ENEMY_GUNSHIP_TALK
@ ACTION_EXIT_SHIP
@ DATA_ICECROWN_GUNSHIP_BATTLE
@ DATA_ENEMY_GUNSHIP
@ NPC_TELEPORT_PORTAL
@ NPC_SKYBREAKER_SORCERER
@ NPC_ORGRIMS_HAMMER
@ NPC_IGB_MURADIN_BRONZEBEARD
@ NPC_SKYBREAKER_MARINE
@ NPC_KOR_KRON_ROCKETEER
@ NPC_SKYBREAKER_MORTAR_SOLDIER
@ NPC_TELEPORT_EXIT
@ NPC_KOR_KRON_BATTLE_MAGE
@ NPC_KOR_KRON_REAVER
@ NPC_MARTYR_STALKER_IGB_SAURFANG
@ NPC_KOR_KRON_AXETHROWER
@ NPC_KOR_KRON_SERGEANT
@ NPC_IGB_HIGH_OVERLORD_SAURFANG
@ NPC_SKYBREAKER_RIFLEMAN
@ NPC_SKYBREAKER_SERGEANT
@ NPC_GUNSHIP_HULL
@ NPC_THE_SKYBREAKER
void apply(T *val)
Definition: ByteConverter.h:41
TimePoint Now()
Current chrono steady_clock time point.
Definition: GameTime.cpp:59
time_t GetGameTime()
Definition: GameTime.cpp:44
std::vector< Vector3 > PointsArray
TC_GAME_API Transport * GetTransport(WorldObject const &u, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
CastSpellExtraArgs & SetCastDifficulty(Difficulty castDifficulty)
Definition: SpellDefines.h:472
CastSpellExtraArgs & AddSpellBP0(int32 val)
Definition: SpellDefines.h:475
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:191
struct MovementInfo::TransportInfo transport
constexpr void SetOrientation(float orientation)
Definition: Position.h:71
constexpr float GetPositionX() const
Definition: Position.h:76
float m_positionZ
Definition: Position.h:55
constexpr float GetPositionY() const
Definition: Position.h:77
float m_positionX
Definition: Position.h:53
float m_positionY
Definition: Position.h:54
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr void Relocate(float x, float y)
Definition: Position.h:63
void RelocateOffset(Position const &offset)
Definition: Position.cpp:34
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
bool Is25ManRaid() const
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
gunship_npc_AI(Creature *creature)
void MovementInform(uint32 type, uint32 pointId) override
void EnterEvadeMode(EvadeReason) override
bool CanAIAttack(Unit const *target) const override
void SetData(uint32 type, uint32 data) override
void JustDied(Unit *) override
void SetSlotInfo(uint32 index)
uint32 GetData(uint32 id) const override
std::map< ObjectGuid, uint32 > _shipVisits
void SetGUID(ObjectGuid const &guid, int32 id) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void SetData(uint32 type, uint32 data) override
bool CanAIAttack(Unit const *target) const override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void MovementInform(uint32 type, uint32 pointId) override
void JustEngagedWith(Unit *target) override
void PassengerBoarded(Unit *, int8, bool apply) override
== Fields =======================================
npc_gunship_cannon(Creature *creature)
npc_gunship_gunner(Creature *creature)
void AttackStart(Unit *target) override
== Triggered Actions Requested ==================
void MovementInform(uint32 type, uint32 pointId) override
npc_gunship_mage(Creature *creature)
void EnterEvadeMode(EvadeReason) override
void UpdateAI(uint32) override
bool CanAIAttack(Unit const *) const override
void MovementInform(uint32 type, uint32 pointId) override
void MovementInform(uint32 type, uint32 pointId) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void SetData(uint32 type, uint32 data) override
bool CanAIAttack(Unit const *target) const override
bool OnGossipSelect(Player *, uint32, uint32) override
bool OnGossipSelect(Player *, uint32, uint32) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
bool CanAIAttack(Unit const *target) const override
void SetData(uint32 type, uint32 data) override
bool OnGossipSelect(Player *player, uint32, uint32) override
npc_zafod_boombox(Creature *creature)