TrinityCore
Loading...
Searching...
No Matches
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 "MoveSplineInit.h"
27#include "ObjectAccessor.h"
28#include "PassiveAI.h"
29#include "ScriptedCreature.h"
30#include "ScriptedGossip.h"
31#include "ScriptMgr.h"
32#include "SpellAuraEffects.h"
33#include "SpellHistory.h"
34#include "SpellMgr.h"
35#include "SpellScript.h"
36#include "TemporarySummon.h"
37#include "Transport.h"
38#include "Vehicle.h"
39#include <G3D/Vector3.h>
40
81
114
116{
117 // Applied on friendly transport NPCs
126
127 // Murading Bronzebeard
128 // High Overlord Saurfang
133
134 // Applied on enemy NPCs
137
138 // Gunship Hull
141
142 // Hostile NPCs
147 SPELL_ELITE = 71195,
149
150 // Skybreaker Sorcerer
151 // Kor'kron Battle-Mage
154
155 // Skybreaker Rifleman
156 // Kor'kron Axethrower
157 SPELL_SHOOT = 70162,
162
163 // Skybreaker Mortar Soldier
164 // Kor'kron Rocketeer
169
170 // Skybreaker Marine
171 // Kor'kron Reaver
173
174 // Skybreaker Sergeant
175 // Kor'kron Sergeant
178
179 //
183
184 // Rocket Pack
188
189 // Alliance Gunship Cannon
190 // Horde Gunship Cannon
195
206
215
216Position const SkybreakerAddsSpawnPos = { 15.91131f, 0.0f, 20.4628f, float(M_PI) };
217Position const OrgrimsHammerAddsSpawnPos = { 60.728395f, 0.0f, 38.93467f, float(M_PI) };
218
219// Horde encounter
220Position const SkybreakerTeleportPortal = { 6.666975f, 0.013001f, 20.87888f, 0.0f };
221Position const OrgrimsHammerTeleportExit = { 7.461699f, 0.158853f, 35.72989f, 0.0f };
222
223// Alliance encounter
224Position const OrgrimsHammerTeleportPortal = { 47.550990f, -0.101778f, 37.61111f, 0.0f };
225Position const SkybreakerTeleportExit = { -17.55738f, -0.090421f, 21.18366f, 0.0f };
226
229{
230 { 8.130936f, -0.2699585f, 20.31728f },
231 { 6.380936f, -0.2699585f, 20.31728f },
232 { 3.507703f, 0.02986573f, 20.78463f },
233 { -2.767633f, 3.743143f, 20.37663f },
234 { -4.017633f, 4.493143f, 20.12663f },
235 { -7.242224f, 6.856013f, 20.03468f },
236 { -7.742224f, 8.606013f, 20.78468f },
237 { -7.992224f, 9.856013f, 21.28468f },
238 { -12.24222f, 23.10601f, 21.28468f },
239 { -14.88477f, 25.20844f, 21.59985f },
240};
241
244{
245 { 30.43987f, 0.1475817f, 36.10674f },
246 { 21.36141f, -3.056458f, 35.42970f },
247 { 19.11141f, -3.806458f, 35.42970f },
248 { 19.01736f, -3.299440f, 35.39428f },
249 { 18.6747f, -5.862823f, 35.66611f },
250 { 18.6747f, -7.862823f, 35.66611f },
251 { 18.1747f, -17.36282f, 35.66611f },
252 { 18.1747f, -22.61282f, 35.66611f },
253 { 17.9247f, -24.36282f, 35.41611f },
254 { 17.9247f, -26.61282f, 35.66611f },
255 { 17.9247f, -27.86282f, 35.66611f },
256 { 17.9247f, -29.36282f, 35.66611f },
257 { 15.33203f, -30.42621f, 35.93796f }
258};
259
261{
262 // Freezing the cannons
264
265 // Channeling the portal, refilled with adds that board player's ship
268
269 // Rifleman
274
275 // Additional Rifleman on 25 man
280
281 // Mortar
284
285 // Additional spawns on 25 man
288
289 // Marines
292
293 // Additional spawns on 25 man
296
297 // Sergeants
299
300 // Additional spawns on 25 man
302
305
312
314{
315 { NPC_SKYBREAKER_SORCERER, { -9.479858f, 0.05663967f, 20.77026f, 4.729842f }, 0 },
316
317 { NPC_SKYBREAKER_SORCERER, { 6.385986f, 4.978760f, 20.55417f, 4.694936f }, 0 },
318 { NPC_SKYBREAKER_SORCERER, { 6.579102f, -4.674561f, 20.55060f, 1.553343f }, 0 },
319
320 { NPC_SKYBREAKER_RIFLEMAN, { -29.563900f, -17.95801f, 20.73837f, 4.747295f }, 30 },
321 { NPC_SKYBREAKER_RIFLEMAN, { -18.017210f, -18.82056f, 20.79150f, 4.747295f }, 30 },
322 { NPC_SKYBREAKER_RIFLEMAN, { -9.1193850f, -18.79102f, 20.58887f, 4.712389f }, 30 },
323 { NPC_SKYBREAKER_RIFLEMAN, { -0.3364258f, -18.87183f, 20.56824f, 4.712389f }, 30 },
324
325 { NPC_SKYBREAKER_RIFLEMAN, { -34.705810f, -17.67261f, 20.51523f, 4.729842f }, 30 },
326 { NPC_SKYBREAKER_RIFLEMAN, { -23.562010f, -18.28564f, 20.67859f, 4.729842f }, 30 },
327 { NPC_SKYBREAKER_RIFLEMAN, { -13.602780f, -18.74268f, 20.59622f, 4.712389f }, 30 },
328 { NPC_SKYBREAKER_RIFLEMAN, { -4.3350220f, -18.84619f, 20.58234f, 4.712389f }, 30 },
329
330 { NPC_SKYBREAKER_MORTAR_SOLDIER, { -31.70142f, 18.02783f, 20.77197f, 4.712389f }, 30 },
331 { NPC_SKYBREAKER_MORTAR_SOLDIER, { -9.368652f, 18.75806f, 20.65335f, 4.712389f }, 30 },
332
333 { NPC_SKYBREAKER_MORTAR_SOLDIER, { -20.40851f, 18.40381f, 20.50647f, 4.694936f }, 30 },
334 { NPC_SKYBREAKER_MORTAR_SOLDIER, { 0.1585693f, 18.11523f, 20.41949f, 4.729842f }, 30 },
335
338
341
343
345};
346
348{
349 { NPC_KOR_KRON_BATTLE_MAGE, { 13.58548f, 0.3867192f, 34.99243f, 1.53589f }, 0 },
350
351 { NPC_KOR_KRON_BATTLE_MAGE, { 47.29290f, -4.308941f, 37.55550f, 1.570796f }, 0 },
352 { NPC_KOR_KRON_BATTLE_MAGE, { 47.34621f, 4.032004f, 37.70952f, 4.817109f }, 0 },
353
354 { NPC_KOR_KRON_AXETHROWER, { -12.09280f, 27.65942f, 33.58557f, 1.53589f }, 30 },
355 { NPC_KOR_KRON_AXETHROWER, { -3.170555f, 28.30652f, 34.21082f, 1.53589f }, 30 },
356 { NPC_KOR_KRON_AXETHROWER, { 14.928040f, 26.18018f, 35.47803f, 1.53589f }, 30 },
357 { NPC_KOR_KRON_AXETHROWER, { 24.703310f, 25.36584f, 35.97845f, 1.53589f }, 30 },
358
359 { NPC_KOR_KRON_AXETHROWER, { -16.65302f, 27.59668f, 33.18726f, 1.53589f }, 30 },
360 { NPC_KOR_KRON_AXETHROWER, { -8.084572f, 28.21448f, 33.93805f, 1.53589f }, 30 },
361 { NPC_KOR_KRON_AXETHROWER, { 7.594765f, 27.41968f, 35.00775f, 1.53589f }, 30 },
362 { NPC_KOR_KRON_AXETHROWER, { 20.763390f, 25.58215f, 35.75287f, 1.53589f }, 30 },
363
364 { NPC_KOR_KRON_ROCKETEER, { -11.44849f, -25.71838f, 33.64343f, 1.518436f }, 30 },
365 { NPC_KOR_KRON_ROCKETEER, { 12.30336f, -25.69653f, 35.32373f, 1.518436f }, 30 },
366
367 { NPC_KOR_KRON_ROCKETEER, { -0.05931854f, -25.46399f, 34.50592f, 1.518436f }, 30 },
368 { NPC_KOR_KRON_ROCKETEER, { 27.62149000f, -23.48108f, 36.12708f, 1.518436f }, 30 },
369
372
375
377
379};
380
382{
383public:
388
389 void SetTransport(Transport* transport) { _transport = transport; }
390
392 {
393 _transport = nullptr;
394 for (uint32 i = 0; i < MAX_SLOTS; ++i)
395 _controlledSlots[i].Clear();
396
397 memset(_respawnCooldowns, 0, sizeof(time_t)* MAX_SLOTS);
400 }
401
403 {
404 if (!_transport)
405 return false;
406
407 bool summoned = false;
408 time_t now = GameTime::GetGameTime();
409 for (int32 i = first; i <= last; ++i)
410 {
411 if (_respawnCooldowns[i] > now)
412 continue;
413
414 if (!_controlledSlots[i].IsEmpty())
415 {
417 if (current && current->IsAlive())
418 continue;
419 }
420
422 {
423 _controlledSlots[i] = passenger->GetGUID();
424 _respawnCooldowns[i] = time_t(0);
425 passenger->AI()->SetData(ACTION_SET_SLOT, i);
426 summoned = true;
427 }
428 }
429
430 return summoned;
431 }
432
438
440 {
441 for (int32 i = first; i <= last; ++i)
442 if (!_controlledSlots[i])
443 return true;
444
445 return false;
446 }
447
448private:
450 {
451 Position newPos;
452 float angle = frand(float(-M_PI) * 0.5f, float(M_PI) * 0.5f);
453 newPos.m_positionX = _spawnPoint->GetPositionX() + 2.0f * std::cos(angle);
454 newPos.m_positionY = _spawnPoint->GetPositionY() + 2.0f * std::sin(angle);
457 return newPos;
458 }
459
465};
466
468{
469public:
470 DelayedMovementEvent(Creature* owner, Position const& dest) : _owner(owner), _dest(dest) { }
471
472 bool Execute(uint64, uint32) override
473 {
474 if (!_owner->IsAlive())
475 return true;
476
477 std::function<void(Movement::MoveSplineInit&)> initializer = [dest = _dest](Movement::MoveSplineInit& init)
478 {
479 init.DisableTransportPathTransformations();
480 init.MoveTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), false);
481 };
483
484 return true;
485 }
486
487private:
490};
491
493{
494public:
495 ResetEncounterEvent(Unit* caster, uint32 spellId, ObjectGuid otherTransport) : _caster(caster), _spellId(spellId), _otherTransport(otherTransport) { }
496
497 bool Execute(uint64, uint32) override
498 {
501
503 go->AddObjectToRemoveList();
504
505 return true;
506 }
507
508private:
512};
513
515{
516public:
517 static uint32 const ExperiencedSpells[5];
518 static Milliseconds const ExperiencedTimes[5];
519
520 BattleExperienceEvent(Creature* creature) : _creature(creature), _level(0) { }
521
522 bool Execute(uint64 timer, uint32 /*diff*/) override
523 {
524 if (!_creature->IsAlive())
525 return true;
526
528 ++_level;
529
531 if (_level < (_creature->GetMap()->IsHeroic() ? 4 : 3))
532 {
534 return false;
535 }
536
537 return true;
538 }
539
540private:
543};
544
546Milliseconds const BattleExperienceEvent::ExperiencedTimes[5] = { 100s, 70s, 60s, 90s, 0s };
547
549{
550 gunship_npc_AI(Creature* creature) : ScriptedAI(creature),
551 Instance(creature->GetInstanceScript()), Slot(nullptr), Index(uint32(-1))
552 {
554 me->SetRegenerateHealth(false);
555 }
556
557 void SetData(uint32 type, uint32 data) override
558 {
559 if (type == ACTION_SET_SLOT && data < MAX_SLOTS)
560 {
561 SetSlotInfo(data);
562
564
565 float x, y, z, o;
566 Slot->TargetPosition.GetPosition(x, y, z, o);
567
569 float hx = x, hy = y, hz = z, ho = o;
570 me->GetTransport()->CalculatePassengerPosition(hx, hy, hz, &ho);
571 me->SetHomePosition(hx, hy, hz, ho);
572
573 std::function<void(Movement::MoveSplineInit&)> initializer = [=](Movement::MoveSplineInit& init)
574 {
575 init.DisableTransportPathTransformations();
576 init.MoveTo(x, y, z, false);
577 };
579 }
580 }
581
582 void EnterEvadeMode(EvadeReason /*why*/) override
583 {
584 if (!me->IsAlive() || !me->IsInCombat())
585 return;
586
587 me->CombatStop(true);
590 }
591
592 void JustDied(Unit* /*killer*/) override
593 {
594 if (Slot)
596 captain->AI()->SetData(ACTION_CLEAR_SLOT, Index);
597 }
598
612
613 bool CanAIAttack(Unit const* target) const override
614 {
616 return false;
618 }
619
620protected:
626
628 {
630 {
632 return false;
633 }
634
636 {
637 if (Unit* victim = me->SelectVictim())
638 if (!me->HasSpellFocus() && victim != me->GetVictim())
639 AttackStart(victim);
640
641 return me->GetVictim() != nullptr;
642 }
644 {
646 return false;
647 }
648
649 return true;
650 }
651
662
667};
668
669// 37215 - Orgrim's Hammer
670// 37540 - The Skybreaker
672{
673 public:
674 npc_gunship() : CreatureScript("npc_gunship") { }
675
677 {
678 npc_gunshipAI(Creature* creature) : NullCreatureAI(creature),
679 _teamInInstance(creature->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE)),
680 _summonedFirstMage(false), _died(false)
681 {
682 me->SetRegenerateHealth(false);
683 }
684
685 void DamageTaken(Unit* /*source*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
686 {
687 if (damage >= me->GetHealth())
688 {
689 JustDied(nullptr);
690 damage = me->GetHealth() - 1;
691 return;
692 }
693
695 return;
696
698 return;
699
700 if (!me->HealthBelowPctDamaged(90, damage))
701 return;
702
703 _summonedFirstMage = true;
705 captain->AI()->DoAction(ACTION_SPAWN_MAGE);
706 }
707
708 void JustDied(Unit* /*killer*/) override
709 {
710 if (_died)
711 return;
712
713 _died = true;
714
716 InstanceScript* instance = me->GetInstanceScript();
717 instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, isVictory ? DONE : FAIL);
719 {
720 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature);
721 creature->RemoveAurasDueToSpell(SPELL_CHECK_FOR_PLAYERS);
722 }
723
726
728 std::list<Creature*> creatures;
730 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
731 {
732 Creature* stalker = *itr;
733 stalker->RemoveAllAuras();
734 stalker->CombatStop(true);
735 }
736
737 uint32 explosionSpell = isVictory ? SPELL_EXPLOSION_VICTORY : SPELL_EXPLOSION_WIPE;
738 creatures.clear();
740 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
741 {
742 Creature* hull = *itr;
743 if (hull->GetTransport() != me->GetTransport())
744 continue;
745
746 hull->CastSpell(hull, explosionSpell, TRIGGERED_FULL_MASK);
747 }
748
749 creatures.clear();
751 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
752 {
753 Creature* cannon = *itr;
754 if (isVictory)
755 {
757
759 data << cannon->GetPackGUID();
760 data << uint32(0);
761 cannon->SendMessageToSet(&data, true);
762
763 cannon->RemoveVehicleKit();
764 }
765 else
767 }
768
769 uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD;
770 uint8 textId = isVictory ? SAY_MURADIN_VICTORY : SAY_MURADIN_WIPE;
771 if (_teamInInstance == HORDE)
772 {
773 creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG;
774 textId = isVictory ? SAY_SAURFANG_VICTORY : SAY_SAURFANG_WIPE;
775 }
776
777 if (Creature* creature = me->FindNearestCreature(creatureEntry, 100.0f))
778 creature->AI()->Talk(textId);
779
780 if (isVictory)
781 {
783 otherTransport->EnableMovement(true);
784
786
788 {
790 ship->CastSpell(ship, SPELL_ACHIEVEMENT, TRIGGERED_FULL_MASK);
792 }
793
794 creatures.clear();
799 for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
800 (*itr)->DespawnOrUnsummon(1ms);
801 }
802 else
803 {
807 }
808 }
809
810 void SetGUID(ObjectGuid const& guid, int32 id) override
811 {
812 if (id != ACTION_SHIP_VISITS)
813 return;
814
815 std::map<ObjectGuid, uint32>::iterator itr = _shipVisits.find(guid);
816 if (itr == _shipVisits.end())
817 _shipVisits[guid] = 1;
818 else
819 ++itr->second;
820 }
821
822 uint32 GetData(uint32 id) const override
823 {
824 if (id != ACTION_SHIP_VISITS)
825 return 0;
826
827 uint32 max = 0;
828 for (std::map<ObjectGuid, uint32>::const_iterator itr = _shipVisits.begin(); itr != _shipVisits.end(); ++itr)
829 max = std::max(max, itr->second);
830
831 return max;
832 }
833
834 private:
836 std::map<ObjectGuid, uint32> _shipVisits;
838 bool _died;
839 };
840
841 CreatureAI* GetAI(Creature* creature) const override
842 {
843 if (!creature->GetTransport())
844 return nullptr;
845
846 return GetIcecrownCitadelAI<npc_gunshipAI>(creature);
847 }
848};
849
850// 36939 - High Overlord Saurfang
852{
854 _instance(creature->GetInstanceScript())
855 {
858 me->SetRegenerateHealth(false);
859 me->m_CombatDistance = 70.0f;
861 _axethrowersYellCooldown = time_t(0);
862 _rocketeersYellCooldown = time_t(0);
863 }
864
865 void InitializeAI() override
866 {
868
869 _events.Reset();
871 _axethrowersYellCooldown = time_t(0);
872 _rocketeersYellCooldown = time_t(0);
873 }
874
882
883 void EnterEvadeMode(EvadeReason /*why*/) override
884 {
885 if (!me->IsAlive())
886 return;
887
888 me->CombatStop(true);
891
892 Reset();
893 }
894
895 void DoAction(int32 action) override
896 {
897 if (action == ACTION_ENEMY_GUNSHIP_TALK)
898 {
900 muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS);
901
906
908 // Combat starts now
909 if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f))
911
912 if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f))
913 {
915 orgrimsHammer->CastSpell(orgrimsHammer, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK);
916 }
917
919 }
920 else if (action == ACTION_SPAWN_MAGE)
921 {
922 TimePoint now = GameTime::Now();
923 if (_firstMageCooldown > now)
924 _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast<Milliseconds>(_firstMageCooldown - now));
925 else
927 }
928 else if (action == ACTION_SPAWN_ALL_ADDS)
929 {
933 if (Is25ManRaid())
935 else
936 {
940 }
941 }
942 else if (action == ACTION_EXIT_SHIP)
943 {
944 std::function<void(Movement::MoveSplineInit&)> initializer = [](Movement::MoveSplineInit& init)
945 {
947 init.DisableTransportPathTransformations();
948 init.MovebyPath(path, 0);
949 };
951
952 me->DespawnOrUnsummon(18s);
953 }
954 }
955
956 void SetData(uint32 type, uint32 data) override
957 {
958 if (type == ACTION_CLEAR_SLOT)
959 {
961 if (data == SLOT_FREEZE_MAGE)
963 }
964 }
965
978
979 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
980 {
983
984 if (damage >= me->GetHealth())
985 damage = me->GetHealth() - 1;
986 }
987
988 void UpdateAI(uint32 diff) override
989 {
991 return;
992
993 _events.Update(diff);
994
995 while (uint32 eventId = _events.ExecuteEvent())
996 {
997 switch (eventId)
998 {
999 case EVENT_INTRO_H_1:
1001 break;
1002 case EVENT_INTRO_H_2:
1004 break;
1006 sTransportMgr->CreateTransport(GO_THE_SKYBREAKER_H, 0, me->GetMap());
1007 break;
1008 case EVENT_INTRO_H_3:
1010 break;
1011 case EVENT_INTRO_H_4:
1013 break;
1014 case EVENT_INTRO_H_5:
1016 muradin->AI()->Talk(SAY_MURADIN_INTRO_H);
1017 break;
1018 case EVENT_INTRO_H_6:
1020 break;
1023 {
1026 }
1027 break;
1028 case EVENT_SUMMON_MAGE:
1031 break;
1032 case EVENT_ADDS:
1037 if (Transport* orgrimsHammer = me->GetTransport())
1038 orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000);
1039
1041 skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000);
1042
1045 break;
1048 muradin->AI()->Talk(SAY_MURADIN_BOARD);
1049 break;
1052 {
1054 {
1057 }
1058 }
1060 break;
1061 case EVENT_CHECK_MORTAR:
1063 {
1065 {
1068 }
1069 }
1071 break;
1072 case EVENT_CLEAVE:
1075 break;
1076 default:
1077 break;
1078 }
1079 }
1080
1083 else if (me->isAttackReady())
1084 {
1087 }
1088 }
1089
1090 bool CanAIAttack(Unit const* target) const override
1091 {
1093 return false;
1095 }
1096
1097private:
1104};
1105
1106// 36948 - Muradin Bronzebeard
1108{
1110 _instance(creature->GetInstanceScript())
1111 {
1114 me->SetRegenerateHealth(false);
1115 me->m_CombatDistance = 70.0f;
1117 _riflemanYellCooldown = time_t(0);
1118 _mortarYellCooldown = time_t(0);
1119 }
1120
1121 void InitializeAI() override
1122 {
1124
1125 _events.Reset();
1127 _riflemanYellCooldown = time_t(0);
1128 _mortarYellCooldown = time_t(0);
1129 }
1130
1138
1139 void EnterEvadeMode(EvadeReason /*why*/) override
1140 {
1141 if (!me->IsAlive())
1142 return;
1143
1144 me->CombatStop(true);
1147
1148 Reset();
1149 }
1150
1151 void DoAction(int32 action) override
1152 {
1153 if (action == ACTION_ENEMY_GUNSHIP_TALK)
1154 {
1156 muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS);
1157
1162
1164 // Combat starts now
1165 if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f))
1167
1168 if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f))
1169 {
1171 skybreaker->CastSpell(skybreaker, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK);
1172 }
1173
1175 }
1176 else if (action == ACTION_SPAWN_MAGE)
1177 {
1178 TimePoint now = GameTime::Now();
1179 if (_firstMageCooldown > now)
1180 _events.ScheduleEvent(EVENT_SUMMON_MAGE, std::chrono::duration_cast<Milliseconds>(_firstMageCooldown - now));
1181 else
1183 }
1184 else if (action == ACTION_SPAWN_ALL_ADDS)
1185 {
1189 if (Is25ManRaid())
1191 else
1192 {
1196 }
1197 }
1198 else if (action == ACTION_EXIT_SHIP)
1199 {
1200 std::function<void(Movement::MoveSplineInit&)> initializer = [](Movement::MoveSplineInit& init)
1201 {
1203 init.DisableTransportPathTransformations();
1204 init.MovebyPath(path, 0);
1205 };
1207
1208 me->DespawnOrUnsummon(18s);
1209 }
1210 }
1211
1212 void SetData(uint32 type, uint32 data) override
1213 {
1214 if (type == ACTION_CLEAR_SLOT)
1215 {
1217 if (data == SLOT_FREEZE_MAGE)
1219 }
1220 }
1221
1235
1236 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1237 {
1240
1241 if (damage >= me->GetHealth())
1242 damage = me->GetHealth() - 1;
1243 }
1244
1245 void UpdateAI(uint32 diff) override
1246 {
1248 return;
1249
1250 _events.Update(diff);
1251
1252 while (uint32 eventId = _events.ExecuteEvent())
1253 {
1254 switch (eventId)
1255 {
1256 case EVENT_INTRO_A_1:
1258 break;
1259 case EVENT_INTRO_A_2:
1261 break;
1263 sTransportMgr->CreateTransport(GO_ORGRIMS_HAMMER_A, 0, me->GetMap());
1264 break;
1265 case EVENT_INTRO_A_3:
1267 break;
1268 case EVENT_INTRO_A_4:
1270 break;
1271 case EVENT_INTRO_A_5:
1273 break;
1274 case EVENT_INTRO_A_6:
1276 saurfang->AI()->Talk(SAY_SAURFANG_INTRO_A);
1277 break;
1278 case EVENT_INTRO_A_7:
1280 break;
1283 {
1286 }
1287 break;
1288 case EVENT_SUMMON_MAGE:
1291 break;
1292 case EVENT_ADDS:
1297 if (Transport* skybreaker = me->GetTransport())
1298 skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, nullptr, 21000);
1299
1301 orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, nullptr, 23000);
1302
1305 break;
1308 saurfang->AI()->Talk(SAY_SAURFANG_BOARD);
1309 break;
1312 {
1314 {
1317 }
1318 }
1320 break;
1321 case EVENT_CHECK_MORTAR:
1323 {
1325 {
1328 }
1329 }
1331 break;
1332 case EVENT_CLEAVE:
1335 break;
1336 default:
1337 break;
1338 }
1339 }
1340
1343 else if (me->isAttackReady())
1344 {
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
1366// 37184 - Zafod Boombox
1368{
1369 npc_zafod_boombox(Creature* creature) : gunship_npc_AI(creature) { }
1370
1371 void Reset() override
1372 {
1374 }
1375
1376 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
1377 {
1380 return false;
1381 }
1382
1383 void UpdateAI(uint32 /*diff*/) override
1384 {
1385 UpdateVictim();
1386 }
1387};
1388
1390{
1392 {
1393 me->m_CombatDistance = 80.0f;
1394 _usedDesperateResolve = false;
1395 }
1396
1397 void SetData(uint32 type, uint32 data) override
1398 {
1399 // detach from captain
1400 if (type == ACTION_SET_SLOT)
1401 {
1402 SetSlotInfo(data);
1403
1405
1407
1409 captain->AI()->SetData(ACTION_CLEAR_SLOT, Index);
1410 }
1411 }
1412
1413 void MovementInform(uint32 type, uint32 pointId) override
1414 {
1415 if (type != POINT_MOTION_TYPE)
1416 return;
1417
1418 if (pointId == EVENT_CHARGE_PREPATH && Slot)
1419 {
1421 float x, y, z, o;
1422 otherTransportPos.GetPosition(x, y, z, o);
1423
1424 Transport* myTransport = me->GetTransport();
1425 if (!myTransport)
1426 return;
1427
1429 destTransport->CalculatePassengerPosition(x, y, z, &o);
1430
1431 float angle = frand(0, float(M_PI) * 2.0f);
1432 x += 2.0f * std::cos(angle);
1433 y += 2.0f * std::sin(angle);
1434
1435 me->SetHomePosition(x, y, z, o);
1436 myTransport->CalculatePassengerOffset(x, y, z, &o);
1437 me->SetTransportHomePosition(x, y, z, o);
1438
1443 me->GetSpellHistory()->AddCooldown(BurningPitchId, 0, std::chrono::seconds(3));
1444
1445 std::list<Player*> players;
1448 Cell::VisitWorldObjects(me, searcher, 200.0f);
1449
1450 players.remove_if([this](Player* player)
1451 {
1452 return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true);
1453 });
1454
1455 if (!players.empty())
1456 {
1457 players.sort(Trinity::ObjectDistanceOrderPred(me));
1458 for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
1459 AddThreat(*itr, 1.0f);
1460
1461 AttackStart(players.front());
1462 }
1463
1465 }
1466 }
1467
1468 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
1469 {
1471 return;
1472
1473 if (!me->HealthBelowPctDamaged(25, damage))
1474 return;
1475
1476 _usedDesperateResolve = true;
1478 }
1479
1480 void UpdateAI(uint32 /*diff*/) override
1481 {
1482 if (!SelectVictim())
1483 {
1485 return;
1486 }
1487
1490
1492 }
1493
1494 bool CanAIAttack(Unit const* target) const override
1495 {
1497 uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD;
1499 {
1501 creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG;
1502 }
1503
1504 return target->HasAura(spellId) || target->GetEntry() == creatureEntry;
1505 }
1506
1508 {
1509 std::list<Player*> players;
1512 Cell::VisitWorldObjects(me, searcher,200.0f );
1513
1514 players.remove_if([this](Player* player)
1515 {
1516 return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true);
1517 });
1518
1519 return !players.empty();
1520 }
1521
1522private:
1524};
1525
1526// 36960 - Kor'kron Sergeant
1527// 36961 - Skybreaker Sergeant
1529{
1531
1538
1539 void UpdateAI(uint32 diff) override
1540 {
1541 if (!SelectVictim())
1542 {
1544 return;
1545 }
1546
1547 _events.Update(diff);
1548
1550 return;
1551
1554
1555 while (uint32 eventId = _events.ExecuteEvent())
1556 {
1557 switch (eventId)
1558 {
1559 case EVENT_BLADESTORM:
1562 break;
1566 break;
1567 default:
1568 break;
1569 }
1570 }
1571
1573 }
1574
1575private:
1577};
1578
1579// 36950 - Skybreaker Marine
1580// 36957 - Kor'kron Reaver
1582{
1583 public:
1584 npc_gunship_boarding_add() : CreatureScript("npc_gunship_boarding_add") { }
1585
1586 CreatureAI* GetAI(Creature* creature) const override
1587 {
1588 return GetIcecrownCitadelAI<npc_gunship_boarding_addAI>(creature);
1589 }
1590};
1591
1592// 36968 - Kor'kron Axethrower
1593// 36969 - Skybreaker Rifleman
1595{
1597 {
1598 creature->m_CombatDistance = 200.0f;
1599 }
1600
1601 void AttackStart(Unit* target) override
1602 {
1603 me->Attack(target, false);
1604 }
1605
1606 void MovementInform(uint32 type, uint32 pointId) override
1607 {
1608 gunship_npc_AI::MovementInform(type, pointId);
1609 if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH)
1611 }
1612
1613 void UpdateAI(uint32 /*diff*/) override
1614 {
1615 if (!SelectVictim())
1616 {
1618 return;
1619 }
1620
1622 }
1623};
1624
1625// 36978 - Skybreaker Mortar Soldier
1626// 36982 - Kor'kron Rocketeer
1628{
1630 {
1631 creature->m_CombatDistance = 200.0f;
1632 }
1633
1634 void MovementInform(uint32 type, uint32 pointId) override
1635 {
1636 gunship_npc_AI::MovementInform(type, pointId);
1637 if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH)
1639 }
1640
1641 void UpdateAI(uint32 /*diff*/) override
1642 {
1643 if (!SelectVictim())
1644 return;
1645
1647 return;
1648
1650 if (me->GetSpellHistory()->HasCooldown(spellId))
1651 return;
1652
1653 DoCastAOE(spellId, true);
1654 me->GetSpellHistory()->AddCooldown(spellId, 0, std::chrono::seconds(9));
1655 }
1656};
1657
1658// 37116 - Skybreaker Sorcerer
1659// 37117 - Kor'kron Battle-Mage
1661{
1663 {
1665 }
1666
1667 void EnterEvadeMode(EvadeReason /*why*/) override { }
1668
1669 void MovementInform(uint32 type, uint32 pointId) override
1670 {
1671 if (type != POINT_MOTION_TYPE)
1672 return;
1673
1674 if (pointId == EVENT_CHARGE_PREPATH && Slot)
1675 {
1677 me->SetFacingTo(slots[Index].TargetPosition.GetOrientation());
1678 switch (Index)
1679 {
1680 case SLOT_FREEZE_MAGE:
1682 break;
1683 case SLOT_MAGE_1:
1684 case SLOT_MAGE_2:
1686 break;
1687 default:
1688 break;
1689 }
1690
1692 }
1693 }
1694
1695 void UpdateAI(uint32 /*diff*/) override
1696 {
1697 UpdateVictim();
1698 }
1699
1700 bool CanAIAttack(Unit const* /*target*/) const override
1701 {
1702 return true;
1703 }
1704};
1705
1726// 36838 - Alliance Gunship Cannon
1727// 36839 - Horde Gunship Cannon
1729{
1730 npc_gunship_cannon(Creature* creature) : PassiveAI(creature) { }
1731
1732 void OnCharmed(bool /*isNew*/) override { }
1733
1734 void PassengerBoarded(Unit* /*passenger*/, int8 /*seat*/, bool apply) override
1735 {
1736 if (!apply)
1737 {
1740 }
1741 }
1742};
1743
1744// 68721 - Rocket Pack
1746{
1748
1749 bool Validate(SpellInfo const* /*spellInfo*/) override
1750 {
1752 }
1753
1754 void HandlePeriodic(AuraEffect const* /*aurEff*/)
1755 {
1756 if (!GetTarget()->IsSplineEnabled())
1758 }
1759
1760 void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1761 {
1762 SpellInfo const* damageInfo = sSpellMgr->AssertSpellInfo(SPELL_ROCKET_PACK_DAMAGE);
1764 args.AddSpellBP0(2 * (damageInfo->GetEffect(EFFECT_0).CalcValue() + aurEff->GetTickNumber() * aurEff->GetPeriod()));
1765 GetTarget()->CastSpell(nullptr, SPELL_ROCKET_PACK_DAMAGE, args);
1767 }
1768
1774};
1775
1776// 70348 - Rocket Pack Useable
1778{
1780
1781 bool Load() override
1782 {
1783 return GetOwner()->GetInstanceScript() != nullptr;
1784 }
1785
1786 bool CheckAreaTarget(Unit* target)
1787 {
1789 }
1790
1791 void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1792 {
1793 if (Creature* owner = GetOwner()->ToCreature())
1794 if (Player* target = GetTarget()->ToPlayer())
1795 if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1))
1797 }
1798
1799 void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1800 {
1801 if (Creature* owner = GetOwner()->ToCreature())
1802 if (Player* target = GetTarget()->ToPlayer())
1803 if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1))
1805 }
1806
1813};
1814
1815// 70120 - On Skybreaker Deck
1816// 70121 - On Orgrim's Hammer Deck
1818{
1820
1821public:
1826
1827private:
1828 bool Load() override
1829 {
1830 if (InstanceScript* instance = GetOwner()->GetInstanceScript())
1831 _teamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE);
1832 else
1833 _teamInInstance = 0;
1834 return true;
1835 }
1836
1838 {
1839 return unit->GetTypeId() == TYPEID_PLAYER;
1840 }
1841
1848
1854
1856};
1857
1858// 69470 - Heat Drain
1859// 69487 - Overheat
1875
1876// 69399, 70172 - Cannon Blast
1878{
1880
1881 bool Load() override
1882 {
1883 return GetCaster()->GetTypeId() == TYPEID_UNIT;
1884 }
1885
1887 {
1888 if (GetCaster()->GetPower(POWER_ENERGY) >= 100)
1889 {
1891 if (Vehicle* vehicle = GetCaster()->GetVehicleKit())
1892 if (Unit* passenger = vehicle->GetPassenger(0))
1893 sCreatureTextMgr->SendChat(GetCaster()->ToCreature(), SAY_OVERHEAT, passenger);
1894 }
1895 }
1896
1897 void Register() override
1898 {
1900 }
1901};
1902
1903// 69402, 70175 - Incinerating Blast
1939
1940// 69487 - Overheat
1942{
1944
1945 bool Load() override
1946 {
1947 if (GetAura()->GetType() != UNIT_AURA_TYPE)
1948 return false;
1949 return GetUnitOwner()->IsVehicle();
1950 }
1951
1953 {
1954 if (Vehicle* vehicle = GetUnitOwner()->GetVehicleKit())
1955 {
1956 if (Unit* passenger = vehicle->GetPassenger(0))
1957 {
1958 if (Player* player = passenger->ToPlayer())
1959 {
1960 WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, GetUnitOwner()->GetPackGUID().size() + 1);
1961 data << GetUnitOwner()->GetPackGUID();
1962 data << uint8(value);
1963 player->SendDirectMessage(&data);
1964 }
1965 }
1966 }
1967 }
1968
1969 void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1970 {
1972 }
1973
1974 void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1975 {
1977 }
1978
1984};
1985
1986// 69705 - Below Zero
2004
2005// 70104 - Teleport to Enemy Ship
2007{
2009
2011 {
2012 WorldLocation const* dest = GetHitDest();
2013 Unit* target = GetHitUnit();
2014 if (!dest || !target || !target->GetTransport())
2015 return;
2016
2017 float x, y, z, o;
2018 dest->GetPosition(x, y, z, o);
2019 target->GetTransport()->CalculatePassengerOffset(x, y, z, &o);
2020 target->m_movementInfo.transport.pos.Relocate(x, y, z, o);
2021 }
2022
2027};
2028
2029// 70397, 70403 - Burning Pitch
2031{
2033
2034 void FilterTargets(std::list<WorldObject*>& targets)
2035 {
2036 uint32 team = HORDE;
2037 if (InstanceScript* instance = GetCaster()->GetInstanceScript())
2038 team = instance->GetData(DATA_TEAM_IN_INSTANCE);
2039
2040 targets.remove_if([team](WorldObject* target) -> bool
2041 {
2042 if (Transport* transport = target->GetTransport())
2043 return transport->GetEntry() != uint32(team == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A);
2044 return true;
2045 });
2046
2047 if (!targets.empty())
2048 {
2050 targets.clear();
2051 targets.push_back(target);
2052 }
2053 }
2054
2060
2066};
2067
2068// 71335, 71339 - Burning Pitch
2087
2088// 69678, 70609 - Rocket Artillery
2090{
2092
2093 void SelectRandomTarget(std::list<WorldObject*>& targets)
2094 {
2095 if (!targets.empty())
2096 {
2098 targets.clear();
2099 targets.push_back(target);
2100 }
2101 }
2102
2108
2114};
2115
2116// 69679 - Rocket Artillery
2136
2137// 67335 - Gunship Fall Teleport
2139{
2141
2142 bool Load() override
2143 {
2144 return GetCaster()->GetInstanceScript() != nullptr;
2145 }
2146
2148 {
2149 if (InstanceScript* instance = target->GetInstanceScript())
2150 target = HashMapHolder<Transport>::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE));
2151 }
2152
2153 void RelocateDest(SpellEffIndex /*effIndex*/)
2154 {
2155 if (GetCaster()->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE) == HORDE)
2156 GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 36.0f, 0.0f });
2157 else
2158 GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 21.0f, 0.0f });
2159 }
2160
2166};
2167
2168// 70331 - Check for Players
2170{
2172
2173public:
2178
2179private:
2180 bool Load() override
2181 {
2182 return GetCaster()->GetTypeId() == TYPEID_UNIT;
2183 }
2184
2185 void CountTargets(std::list<WorldObject*>& targets)
2186 {
2187 _playerCount = targets.size();
2188 }
2189
2191 {
2192 if (!_playerCount)
2193 GetCaster()->ToCreature()->AI()->JustDied(nullptr);
2194 }
2195
2197 {
2198 if (GetHitUnit()->GetPositionZ() < GetCaster()->GetPositionZ() - 10.0f)
2200 }
2201
2208
2210};
2211
2212// 72340 - Teleport Players on Victory
2214{
2216
2217 bool Load() override
2218 {
2219 return GetCaster()->GetInstanceScript() != nullptr;
2220 }
2221
2222 void FilterTargets(std::list<WorldObject*>& targets)
2223 {
2225 targets.remove_if([instance](WorldObject* target) -> bool
2226 {
2227 return target->GetTransGUID() != instance->GetGuidData(DATA_ENEMY_GUNSHIP);
2228 });
2229 }
2230
2235};
2236
2237// 71201 - Battle Experience - proc should never happen, handled in script
2239{
2241
2242 bool CheckProc(ProcEventInfo& /*eventInfo*/)
2243 {
2244 return false;
2245 }
2246
2251};
2252
2254{
2255 public:
2256 achievement_im_on_a_boat() : AchievementCriteriaScript("achievement_im_on_a_boat") { }
2257
2258 bool OnCheck(Player* /*source*/, Unit* target) override
2259 {
2260 return target->GetAI() && target->GetAI()->GetData(ACTION_SHIP_VISITS) <= 2;
2261 }
2262};
2263
2265{
2266 // Creatures
2267 new npc_gunship();
2277
2278 // Spells
2296
2297 // Achievements
2299}
@ NPC_ALLIANCE_GUNSHIP_CANNON
@ NPC_HORDE_GUNSHIP_CANNON
#define M_PI
Definition Common.h:72
#define sCreatureTextMgr
@ TEXT_RANGE_NORMAL
uint8_t uint8
Definition Define.h:135
int8_t int8
Definition Define.h:131
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint32_t uint32
Definition Define.h:133
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
Definition Duration.h:36
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#define SIZE_OF_GRIDS
Definition GridDefines.h:38
@ IN_PROGRESS
@ FAIL
@ DONE
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
@ MOTION_PRIORITY_NORMAL
@ POINT_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
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:1128
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_TRIGGER_MISSILE
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ SPELL_EFFECT_TELEPORT_UNITS
@ LANG_ADDON
@ TARGET_UNIT_SRC_AREA_ENTRY
@ TARGET_DEST_NEARBY_ENTRY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TARGET_UNIT_DEST_AREA_ENTRY
@ EVENT_CHARGE_PREPATH
@ TEAM_OTHER
@ ALLIANCE
@ HORDE
@ POWER_ENERGY
@ CHAT_MSG_ADDON
SpellMissInfo
@ SPELL_MISS_NONE
@ AURA_REMOVE_BY_EXPIRE
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_DUMMY
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
@ UNIT_AURA_TYPE
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
@ TRIGGERED_NONE
#define sSpellMgr
Definition SpellMgr.h:738
#define BeforeSpellHitFn(F)
#define SpellObjectTargetSelectFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define SpellCastFn(F)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraCheckProcFn(F)
#define SpellHitFn(F)
#define AuraCheckAreaTargetFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
#define sTransportMgr
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_NPC_FLAG_GOSSIP
@ UNIT_STATE_ROOT
Definition Unit.h:230
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
uint32 const SaurfangExitPathSize
@ SAY_MURADIN_ENTER_ORGRIMMS_HAMMER
G3D::Vector3 const SaurfangExitPath[SaurfangExitPathSize]
SlotInfo const SkybreakerSlotInfo[MAX_SLOTS]
Position const SkybreakerTeleportPortal
Position const OrgrimsHammerTeleportPortal
Position const OrgrimsHammerTeleportExit
@ SPELL_MELEE_TARGETING_ON_SKYBREAKER
@ SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER
@ SPELL_TELEPORT_PLAYERS_ON_RESET_H
@ SPELL_TELEPORT_PLAYERS_ON_RESET_A
@ SPELL_TELEPORT_PLAYERS_ON_VICTORY
@ SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO
SlotInfo const OrgrimsHammerSlotInfo[MAX_SLOTS]
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
uint32 GetTickNumber() const
SpellEffectInfo const & GetSpellEffectInfo() const
int32 GetPeriod() const
void PreventDefaultAction()
AuraObjectType GetType() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
WorldObject * GetOwner() const
HookList< EffectApplyHandler > AfterEffectApply
Aura * GetAura() const
HookList< CheckAreaTargetHandler > DoCheckAreaTarget
Unit * GetTarget() const
HookList< CheckProcHandler > DoCheckProc
HookList< EffectApplyHandler > OnEffectRemove
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:127
@ EVADE_REASON_OTHER
Definition CreatureAI.h:98
virtual void JustDied(Unit *)
Definition CreatureAI.h:130
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void EngagementOver()
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:293
bool _IsTargetAcceptable(Unit const *target) const
bool HasReactState(ReactStates state) const
Definition Creature.h:121
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetRegenerateHealth(bool value)
Definition Creature.h:285
float m_CombatDistance
Definition Creature.h:335
Unit * SelectVictim()
void SetTransportHomePosition(float x, float y, float z, float o)
Definition Creature.h:298
CreatureAI * AI() const
Definition Creature.h:154
bool CanStartAttack(Unit const *u, bool force) const
bool HasSpellFocus(Spell const *focusSpell=nullptr) const override
DelayedMovementEvent(Creature *owner, Position const &dest)
bool Execute(uint64, uint32) override
void Update(uint32 time)
Definition EventMap.h:67
EventId ExecuteEvent()
Definition EventMap.cpp:73
bool IsInPhase(PhaseIndex phase) const
Definition EventMap.h:236
void SetPhase(PhaseIndex phase)
Definition EventMap.cpp:28
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
static T * Find(ObjectGuid guid)
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=nullptr, uint8 param1=0, uint8 param2=0)
void SetZoneMusic(uint32 zoneId, uint32 musicId)
Definition Map.cpp:4764
bool IsHeroic() const
Definition Map.cpp:4256
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:150
static Creature * ToCreature(Object *o)
Definition Object.h:186
PackedGuid const & GetPackGUID() const
Definition Object.h:80
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
std::size_t size() const
Definition ObjectGuid.h:278
void SetTransport(Transport *transport)
bool SlotsNeedRefill(GunshipPassengerSlots first, GunshipPassengerSlots last) const
bool SummonCreatures(GunshipPassengerSlots first, GunshipPassengerSlots last)
void ClearSlot(GunshipPassengerSlots slot)
ObjectGuid _controlledSlots[MAX_SLOTS]
void SendCloseGossip()
PlayerMenu * PlayerTalkClass
Definition Player.h:1969
ResetEncounterEvent(Unit *caster, uint32 spellId, ObjectGuid otherTransport)
bool Execute(uint64, uint32) override
uint32 TriggerSpell
Definition SpellInfo.h:228
int32 CalcValue(WorldObject const *caster=nullptr, int32 const *basePoints=nullptr) const
void AddCooldown(uint32 spellId, uint32 itemId, std::chrono::duration< Type, Period > cooldownDuration)
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:483
HookList< CastHandler > AfterCast
WorldLocation * GetHitDest() const
void SetEffectValue(int32 value)
Unit * GetCaster() const
HookList< HitHandler > AfterHit
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
HookList< ObjectTargetSelectHandler > OnObjectTargetSelect
HookList< CastHandler > OnCast
HookList< EffectHandler > OnEffectLaunchTarget
HookList< BeforeHitHandler > BeforeHit
HookList< EffectHandler > OnEffectLaunch
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
bool IsThreatListEmpty(bool includeOffline=false) const
void CalculatePassengerOffset(float &x, float &y, float &z, float *o=nullptr) const override
This method transforms supplied global coordinates into local offsets.
Definition Transport.h:77
void EnableMovement(bool enabled)
TempSummon * SummonPassenger(uint32 entry, Position const &pos, TempSummonType summonType, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, Unit *summoner=nullptr, uint32 spellId=0, uint32 vehId=0)
Temporarily summons a creature as passenger on this transport.
void CalculatePassengerPosition(float &x, float &y, float &z, float *o=nullptr) const override
This method transforms supplied transport offsets into global coordinates.
Definition Transport.h:71
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
virtual void Reset()
Definition UnitAI.h:145
virtual void InitializeAI()
Definition UnitAI.cpp:36
virtual uint32 GetData(uint32) const
Definition UnitAI.h:155
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
bool DoSpellAttackIfReady(uint32 spell)
Definition UnitAI.cpp:78
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
bool IsVehicle() const
Definition Unit.h:887
bool IsWithinMeleeRange(Unit const *obj) const
Definition Unit.h:844
ThreatManager & GetThreatManager()
Definition Unit.h:1155
void SetControlled(bool apply, UnitState state)
Definition Unit.cpp:11256
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool IsAlive() const
Definition Unit.h:1234
void RemoveNpcFlag(NPCFlags flags)
Definition Unit.h:1098
void RemoveVehicleKit()
Definition Unit.cpp:11808
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
UnitAI * GetAI() const
Definition Unit.h:800
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:5535
uint32 GetHealth() const
Definition Unit.h:913
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool force=false)
Definition Unit.cpp:9421
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13250
void RemoveAllAuras()
Definition Unit.cpp:4157
SpellHistory * GetSpellHistory()
Definition Unit.h:1484
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition Unit.h:918
uint32 GetPower(Powers power) const
Definition Unit.h:934
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:5691
bool isAttackReady(WeaponAttackType type=BASE_ATTACK) const
Definition Unit.h:835
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:598
bool IsInCombat() const
Definition Unit.h:1144
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1783
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
void AddObjectToRemoveList()
Definition Object.cpp:1838
virtual ObjectGuid GetTransGUID() const
Definition Object.cpp:3579
Transport * GetTransport() const
Definition Object.h:564
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
EventProcessor m_Events
Definition Object.h:591
MovementInfo m_movementInfo
Definition Object.h:575
virtual uint32 GetData(uint32) const
Definition ZoneScript.h:55
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
bool OnCheck(Player *, Unit *target) override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
PrepareAuraScript(spell_igb_battle_experience_check)
PrepareSpellScript(spell_igb_below_zero)
void RemovePassengers(SpellMissInfo missInfo)
void FilterTargets(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_igb_burning_pitch_selector)
PrepareSpellScript(spell_igb_burning_pitch)
void HandleDummy(SpellEffIndex effIndex)
PrepareSpellScript(spell_igb_cannon_blast)
PrepareSpellScript(spell_igb_check_for_players)
void CountTargets(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_igb_gunship_fall_teleport)
PrepareSpellScript(spell_igb_incinerating_blast)
PrepareAuraScript(spell_igb_on_gunship_deck)
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
void HandleRemove(AuraEffect const *, AuraEffectHandleModes)
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_igb_overheat)
PrepareAuraScript(spell_igb_periodic_trigger_with_power_cost)
PrepareSpellScript(spell_igb_rocket_artillery_explosion)
void SelectRandomTarget(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_igb_rocket_artillery)
void HandleScript(SpellEffIndex effIndex)
PrepareAuraScript(spell_igb_rocket_pack_useable)
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
void HandleRemove(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_igb_rocket_pack)
void HandlePeriodic(AuraEffect const *)
void HandleRemove(AuraEffect const *aurEff, AuraEffectHandleModes)
void FilterTargets(std::list< WorldObject * > &targets)
PrepareSpellScript(spell_igb_teleport_players_on_victory)
PrepareSpellScript(spell_igb_teleport_to_enemy_ship)
@ DATA_TEAM_IN_INSTANCE
@ SMSG_PLAYER_VEHICLE_DATA
Definition Opcodes.h:1220
@ SMSG_CLIENT_CONTROL_UPDATE
Definition Opcodes.h:374
#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
TimePoint Now()
Current chrono steady_clock time point.
Definition GameTime.cpp:57
time_t GetGameTime()
Definition GameTime.cpp:42
std::vector< Vector3 > PointsArray
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:108
CastSpellExtraArgs & AddSpellBP0(int32 val)
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:180
struct MovementInfo::TransportInfo transport
float m_positionZ
Definition Position.h:58
float m_positionX
Definition Position.h:56
float GetPositionZ() const
Definition Position.h:81
float m_positionY
Definition Position.h:57
float GetOrientation() const
Definition Position.h:82
void SetOrientation(float orientation)
Definition Position.h:74
float GetPositionX() const
Definition Position.h:79
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetPositionY() const
Definition Position.h:80
void RelocateOffset(Position const &offset)
Definition Position.cpp:36
void Relocate(float x, float y)
Definition Position.h:66
void AttackStart(Unit *) override
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
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 =======================================
void AttackStart(Unit *target) override
void MovementInform(uint32 type, uint32 pointId) override
void EnterEvadeMode(EvadeReason) 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