diff options
author | joschiwald <joschiwald.trinity@gmail.com> | 2014-09-18 00:38:28 +0200 |
---|---|---|
committer | joschiwald <joschiwald.trinity@gmail.com> | 2014-09-18 00:38:28 +0200 |
commit | 60176157a7cc1da4a1ef25fe61542f86524ae5e6 (patch) | |
tree | 196934cd071addef5c9ab37c4cd2dc3d67193c1e /src | |
parent | b08dcb1d99fe91b7dc1cb3168a34d722f9ea5505 (diff) |
Scripts/Gundrak: cleanup InstanceScript
* converted Gal'Darah and Moorabi to BossAI
* add and correct some texts
* fixed altar activation spell visual
Diffstat (limited to 'src')
-rw-r--r-- | src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp | 62 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Gundrak/boss_eck.cpp | 134 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp | 416 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp | 247 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp | 63 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Gundrak/gundrak.h | 106 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp | 752 |
7 files changed, 787 insertions, 993 deletions
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp index e3daf32212a..f1fececfa7f 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp @@ -24,6 +24,13 @@ #include "gundrak.h" #include "SpellInfo.h" +enum Texts +{ + // Drakkari Elemental + EMOTE_MOJO = 0, + EMOTE_ACTIVATE_ALTAR = 1 +}; + enum Spells { SPELL_EMERGE = 54850, @@ -80,7 +87,7 @@ class boss_drakkari_colossus : public CreatureScript struct boss_drakkari_colossusAI : public BossAI { - boss_drakkari_colossusAI(Creature* creature) : BossAI(creature, DATA_DRAKKARI_COLOSSUS_EVENT) + boss_drakkari_colossusAI(Creature* creature) : BossAI(creature, DATA_DRAKKARI_COLOSSUS) { Initialize(); me->SetReactState(REACT_PASSIVE); @@ -103,41 +110,20 @@ class boss_drakkari_colossus : public CreatureScript me->RemoveAura(SPELL_FREEZE_ANIM); } - //events.Reset(); -> done in _Reset(); events.ScheduleEvent(EVENT_MIGHTY_BLOW, urand(10000, 30000)); Initialize(); - - // Note: This should not be called, but before use SetBossState function we should use BossAI - // in all the bosses of the instance - instance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - me->RemoveAura(SPELL_FREEZE_ANIM); - - // Note: This should not be called, but before use SetBossState function we should use BossAI - // in all the bosses of the instance - instance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, IN_PROGRESS); } void JustDied(Unit* /*killer*/) override { _JustDied(); - - // Note: This should not be called, but before use SetBossState function we should use BossAI - // in all the bosses of the instance - instance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, DONE); - } - - void JustReachedHome() override - { - // Note: This should not be called, but before use SetBossState function we should use BossAI - // in all the bosses of the instance - instance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, FAIL); } void DoAction(int32 action) override @@ -181,13 +167,12 @@ class boss_drakkari_colossus : public CreatureScript if (phase == COLOSSUS_PHASE_NORMAL || phase == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON) { - if (HealthBelowPct( phase == COLOSSUS_PHASE_NORMAL ? 50 : 5)) + if (HealthBelowPct(phase == COLOSSUS_PHASE_NORMAL ? 50 : 5)) { damage = 0; phase = (phase == COLOSSUS_PHASE_NORMAL ? COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON : COLOSSUS_PHASE_SECOND_ELEMENTAL_SUMMON); DoAction(ACTION_FREEZE_COLOSSUS); DoAction(ACTION_SUMMON_ELEMENTAL); - } } } @@ -248,7 +233,7 @@ class boss_drakkari_colossus : public CreatureScript CreatureAI* GetAI(Creature* creature) const override { - return GetInstanceAI<boss_drakkari_colossusAI>(creature); + return GetGundrakAI<boss_drakkari_colossusAI>(creature); } }; @@ -275,10 +260,9 @@ class boss_drakkari_elemental : public CreatureScript void JustDied(Unit* killer) override { - if (killer == me) - return; + Talk(EMOTE_ACTIVATE_ALTAR); - if (Creature* colossus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DRAKKARI_COLOSSUS))) + if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS)) killer->Kill(colossus); } @@ -313,8 +297,9 @@ class boss_drakkari_elemental : public CreatureScript switch (action) { case ACTION_RETURN_TO_COLOSSUS: + Talk(EMOTE_MOJO); DoCast(SPELL_SURGE_VISUAL); - if (Creature* colossus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DRAKKARI_COLOSSUS))) + if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS)) // what if the elemental is more than 80 yards from drakkari colossus ? DoCast(colossus, SPELL_MERGE, true); break; @@ -323,11 +308,11 @@ class boss_drakkari_elemental : public CreatureScript void DamageTaken(Unit* /*attacker*/, uint32& damage) override { - if (HealthBelowPct(50) && instance) + if (HealthBelowPct(50)) { - if (Creature* colossus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DRAKKARI_COLOSSUS))) + if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS)) { - if (colossus->AI()->GetData(DATA_COLOSSUS_PHASE) == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON) + if (colossus->AI()->GetData(DATA_COLOSSUS_PHASE) == COLOSSUS_PHASE_FIRST_ELEMENTAL_SUMMON) { damage = 0; @@ -375,7 +360,7 @@ class boss_drakkari_elemental : public CreatureScript CreatureAI* GetAI(Creature* creature) const override { - return GetInstanceAI<boss_drakkari_elementalAI>(creature); + return GetGundrakAI<boss_drakkari_elementalAI>(creature); } }; @@ -386,7 +371,7 @@ public: CreatureAI* GetAI(Creature* creature) const override { - return GetInstanceAI<npc_living_mojoAI>(creature); + return GetGundrakAI<npc_living_mojoAI>(creature); } struct npc_living_mojoAI : public ScriptedAI @@ -429,7 +414,7 @@ public: if (id == 1) { - if (Creature* colossus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DRAKKARI_COLOSSUS))) + if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS)) { colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS); if (!colossus->AI()->GetData(DATA_INTRO_DONE)) @@ -446,13 +431,11 @@ public: return; // we do this checks to see if the creature is one of the creatures that sorround the boss - if (Creature* colossus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_DRAKKARI_COLOSSUS))) + if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS)) { Position homePosition = me->GetHomePosition(); - Position colossusHomePosition = colossus->GetHomePosition(); - - float distance = homePosition.GetExactDist(colossusHomePosition.GetPositionX(), colossusHomePosition.GetPositionY(), colossusHomePosition.GetPositionZ()); + float distance = homePosition.GetExactDist(&colossus->GetHomePosition()); if (distance < 12.0f) { @@ -484,6 +467,7 @@ public: DoMeleeAttackIfReady(); } + private: InstanceScript* instance; uint32 mojoWaveTimer; diff --git a/src/server/scripts/Northrend/Gundrak/boss_eck.cpp b/src/server/scripts/Northrend/Gundrak/boss_eck.cpp index 9f8cc818958..baf749fec51 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_eck.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_eck.cpp @@ -19,13 +19,18 @@ #include "ScriptedCreature.h" #include "gundrak.h" +enum Texts +{ + EMOTE_SPAWN = 0 +}; + enum Spells { - SPELL_ECK_BERSERK = 55816, //Eck goes berserk, increasing his attack speed by 150% and all damage he deals by 500%. - SPELL_ECK_BITE = 55813, //Eck bites down hard, inflicting 150% of his normal damage to an enemy. - SPELL_ECK_SPIT = 55814, //Eck spits toxic bile at enemies in a cone in front of him, inflicting 2970 Nature damage and draining 220 mana every 1 sec for 3 sec. - SPELL_ECK_SPRING_1 = 55815, //Eck leaps at a distant target. --> Drops aggro and charges a random player. Tank can simply taunt him back. - SPELL_ECK_SPRING_2 = 55837 //Eck leaps at a distant target. + SPELL_ECK_BERSERK = 55816, // Eck goes berserk, increasing his attack speed by 150% and all damage he deals by 500%. + SPELL_ECK_BITE = 55813, // Eck bites down hard, inflicting 150% of his normal damage to an enemy. + SPELL_ECK_SPIT = 55814, // Eck spits toxic bile at enemies in a cone in front of him, inflicting 2970 Nature damage and draining 220 mana every 1 sec for 3 sec. + SPELL_ECK_SPRING_1 = 55815, // Eck leaps at a distant target. --> Drops aggro and charges a random player. Tank can simply taunt him back. + SPELL_ECK_SPRING_2 = 55837 // Eck leaps at a distant target. }; enum Events @@ -38,79 +43,80 @@ enum Events class boss_eck : public CreatureScript { -public: - boss_eck() : CreatureScript("boss_eck") { } + public: + boss_eck() : CreatureScript("boss_eck") { } - struct boss_eckAI : public BossAI - { - boss_eckAI(Creature* creature) : BossAI(creature, DATA_ECK_THE_FEROCIOUS_EVENT) + struct boss_eckAI : public BossAI { - Initialize(); - } + boss_eckAI(Creature* creature) : BossAI(creature, DATA_ECK_THE_FEROCIOUS) + { + Initialize(); + Talk(EMOTE_SPAWN); + } - void Initialize() - { - Berserk = false; - } + void Initialize() + { + _berserk = false; + } - void Reset() override - { - _Reset(); - Initialize(); - } + void Reset() override + { + _Reset(); + Initialize(); + } - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_BITE, 5 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SPIT, 10 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SPRING, 8 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_BERSERK, urand(60 * IN_MILLISECONDS, 90 * IN_MILLISECONDS)); //60-90 secs according to wowwiki - } + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + events.ScheduleEvent(EVENT_BITE, 5 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SPIT, 10 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SPRING, 8 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_BERSERK, urand(60 * IN_MILLISECONDS, 90 * IN_MILLISECONDS)); // 60-90 secs according to wowwiki + } - void DamageTaken(Unit* /*attacker*/, uint32& damage) override - { - if (me->HealthBelowPctDamaged(20, damage) && !Berserk) + void DamageTaken(Unit* /*attacker*/, uint32& damage) override { - events.RescheduleEvent(EVENT_BERSERK, 1000); - Berserk = true; + if (!_berserk && me->HealthBelowPctDamaged(20, damage)) + { + events.RescheduleEvent(EVENT_BERSERK, 1000); + _berserk = true; + } } - } - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) + void ExecuteEvent(uint32 eventId) override { - case EVENT_BITE: - DoCastVictim(SPELL_ECK_BITE); - events.ScheduleEvent(EVENT_BITE, urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS)); - break; - case EVENT_SPIT: - DoCastVictim(SPELL_ECK_SPIT); - events.ScheduleEvent(EVENT_SPIT, urand(6 * IN_MILLISECONDS, 14 * IN_MILLISECONDS)); - break; - case EVENT_SPRING: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 35.0f, true)) - DoCast(target, RAND(SPELL_ECK_SPRING_1, SPELL_ECK_SPRING_2)); - events.ScheduleEvent(EVENT_SPRING, urand(5 * IN_MILLISECONDS, 10 * IN_MILLISECONDS)); - break; - case EVENT_BERSERK: - DoCast(me, SPELL_ECK_BERSERK); - Berserk = true; - break; - default: - break; + switch (eventId) + { + case EVENT_BITE: + DoCastVictim(SPELL_ECK_BITE); + events.ScheduleEvent(EVENT_BITE, urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS)); + break; + case EVENT_SPIT: + DoCastVictim(SPELL_ECK_SPIT); + events.ScheduleEvent(EVENT_SPIT, urand(6 * IN_MILLISECONDS, 14 * IN_MILLISECONDS)); + break; + case EVENT_SPRING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 35.0f, true)) + DoCast(target, RAND(SPELL_ECK_SPRING_1, SPELL_ECK_SPRING_2)); + events.ScheduleEvent(EVENT_SPRING, urand(5 * IN_MILLISECONDS, 10 * IN_MILLISECONDS)); + break; + case EVENT_BERSERK: + DoCast(me, SPELL_ECK_BERSERK); + _berserk = true; + break; + default: + break; + } } - } private: - bool Berserk; - }; + bool _berserk; + }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_eckAI>(creature); - } + CreatureAI* GetAI(Creature* creature) const override + { + return GetGundrakAI<boss_eckAI>(creature); + } }; void AddSC_boss_eck() diff --git a/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp b/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp index 992de8c5402..c9ea3a26f4d 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp @@ -17,281 +17,272 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "gundrak.h" -//Spells +/// @todo: implement stampede + enum Spells { - SPELL_ENRAGE = 55285, - H_SPELL_ENRAGE = 59828, - SPELL_IMPALING_CHARGE = 54956, - H_SPELL_IMPALING_CHARGE = 59827, - SPELL_STOMP = 55292, - H_SPELL_STOMP = 59829, - SPELL_PUNCTURE = 55276, - H_SPELL_PUNCTURE = 59826, - SPELL_STAMPEDE = 55218, - SPELL_WHIRLING_SLASH = 55250, - H_SPELL_WHIRLING_SLASH = 59824, + SPELL_IMPALING_CHARGE = 54956, + SPELL_IMPALING_CHARGE_CONTROL_VEHICLE = 54958, + SPELL_STOMP = 55292, + SPELL_PUNCTURE = 55276, + SPELL_STAMPEDE = 55218, + SPELL_WHIRLING_SLASH = 55250, + SPELL_ENRAGE = 55285, + SPELL_HEARTH_BEAM_VISUAL = 54988, + SPELL_TRANSFORM_RHINO = 55297, + SPELL_TRANSFORM_BACK = 55299 }; -//Yells enum Yells { - SAY_AGGRO = 0, - SAY_SLAY = 1, - SAY_DEATH = 2, - SAY_SUMMON_RHINO = 3, - SAY_TRANSFORM_1 = 4, - SAY_TRANSFORM_2 = 5 + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_DEATH = 2, + SAY_SUMMON_RHINO = 3, + SAY_TRANSFORM_1 = 4, + SAY_TRANSFORM_2 = 5, + EMOTE_IMPALE = 6 }; -enum Displays +enum CombatPhase { - DISPLAY_RHINO = 26265, - DISPLAY_TROLL = 27061 + PHASE_TROLL = 1, + PHASE_RHINO = 2 }; -enum CombatPhase +enum Events { - TROLL, - RHINO + EVENT_IMPALING_CHARGE = 1, + EVENT_STOMP, + EVENT_PUNCTURE, + EVENT_STAMPEDE, + EVENT_WHIRLING_SLASH, + EVENT_ENRAGE, + EVENT_TRANSFORM, + + EVENT_GROUP_TROLL = PHASE_TROLL, + EVENT_GROUP_RHINO = PHASE_RHINO }; enum Misc { - DATA_SHARE_THE_LOVE = 1 + DATA_SHARE_THE_LOVE = 1 }; class boss_gal_darah : public CreatureScript { -public: - boss_gal_darah() : CreatureScript("boss_gal_darah") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_gal_darahAI>(creature); - } + public: + boss_gal_darah() : CreatureScript("boss_gal_darah") { } - struct boss_gal_darahAI : public ScriptedAI - { - boss_gal_darahAI(Creature* creature) : ScriptedAI(creature) + struct boss_gal_darahAI : public BossAI { - Initialize(); - instance = creature->GetInstanceScript(); - } + boss_gal_darahAI(Creature* creature) : BossAI(creature, DATA_GAL_DARAH) + { + Initialize(); + } - void Initialize() - { - uiStampedeTimer = 10 * IN_MILLISECONDS; - uiWhirlingSlashTimer = 21 * IN_MILLISECONDS; - uiPunctureTimer = 10 * IN_MILLISECONDS; - uiEnrageTimer = 15 * IN_MILLISECONDS; - uiImpalingChargeTimer = 21 * IN_MILLISECONDS; - uiStompTimer = 25 * IN_MILLISECONDS; - uiTransformationTimer = 9 * IN_MILLISECONDS; - uiPhaseCounter = 0; - - shareTheLove = 0; - bStartOfTransformation = true; - Phase = TROLL; - } + void Initialize() + { + _phaseCounter = 0; + } - uint32 uiStampedeTimer; - uint32 uiWhirlingSlashTimer; - uint32 uiPunctureTimer; - uint32 uiEnrageTimer; - uint32 uiImpalingChargeTimer; - uint32 uiStompTimer; - uint32 uiTransformationTimer; - GuidList impaledList; - uint8 shareTheLove; + void InitializeAI() override + { + BossAI::InitializeAI(); + DoCastAOE(SPELL_HEARTH_BEAM_VISUAL, true); + } - CombatPhase Phase; + void Reset() override + { + Initialize(); + _Reset(); + impaledPlayers.clear(); + } - uint8 uiPhaseCounter; + void JustReachedHome() override + { + _JustReachedHome(); + DoCastAOE(SPELL_HEARTH_BEAM_VISUAL, true); + } - bool bStartOfTransformation; + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); - InstanceScript* instance; + SetPhase(PHASE_TROLL); + } - void Reset() override - { - Initialize(); + void SetPhase(CombatPhase phase) + { + events.SetPhase(phase); + switch (phase) + { + case PHASE_TROLL: + events.ScheduleEvent(EVENT_STAMPEDE, 10 * IN_MILLISECONDS, 0, PHASE_TROLL); + events.ScheduleEvent(EVENT_WHIRLING_SLASH, 21 * IN_MILLISECONDS, 0, PHASE_TROLL); + break; + case PHASE_RHINO: + events.ScheduleEvent(EVENT_STOMP, 25 * IN_MILLISECONDS, 0, PHASE_RHINO); + events.ScheduleEvent(EVENT_IMPALING_CHARGE, 21 * IN_MILLISECONDS, 0, PHASE_RHINO); + events.ScheduleEvent(EVENT_ENRAGE, 15 * IN_MILLISECONDS, 0, PHASE_RHINO); + events.ScheduleEvent(EVENT_PUNCTURE, 10 * IN_MILLISECONDS, 0, PHASE_RHINO); + break; + } + } - impaledList.clear(); + void SetGUID(ObjectGuid guid, int32 type /*= 0*/) override + { + if (type == DATA_SHARE_THE_LOVE) + { + if (Unit* target = ObjectAccessor::GetUnit(*me, guid)) + Talk(EMOTE_IMPALE, target); + impaledPlayers.insert(guid); + } + } - me->SetDisplayId(DISPLAY_TROLL); + uint32 GetData(uint32 type) const override + { + if (type == DATA_SHARE_THE_LOVE) + return impaledPlayers.size(); - instance->SetData(DATA_GAL_DARAH_EVENT, NOT_STARTED); - } + return 0; + } - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + } - instance->SetData(DATA_GAL_DARAH_EVENT, IN_PROGRESS); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TRANSFORM_BACK) + me->RemoveAurasDueToSpell(SPELL_TRANSFORM_RHINO); + } - switch (Phase) + void ExecuteEvent(uint32 eventId) override { - case TROLL: - if (uiPhaseCounter == 2) - { - if (uiTransformationTimer <= diff) + switch (eventId) + { + case EVENT_IMPALING_CHARGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) + DoCast(target, SPELL_IMPALING_CHARGE); + if (++_phaseCounter >= 2) + events.ScheduleEvent(EVENT_TRANSFORM, 5 * IN_MILLISECONDS); + events.ScheduleEvent(eventId, 31 * IN_MILLISECONDS, 0, PHASE_RHINO); + break; + case EVENT_STOMP: + DoCastAOE(SPELL_STOMP); + events.ScheduleEvent(eventId, 20 * IN_MILLISECONDS, 0, PHASE_RHINO); + break; + case EVENT_PUNCTURE: + DoCastVictim(SPELL_PUNCTURE); + events.ScheduleEvent(eventId, 8 * IN_MILLISECONDS, 0, PHASE_RHINO); + break; + case EVENT_STAMPEDE: + Talk(SAY_SUMMON_RHINO); + DoCast(me, SPELL_STAMPEDE); + events.ScheduleEvent(eventId, 15 * IN_MILLISECONDS, 0, PHASE_TROLL); + break; + case EVENT_WHIRLING_SLASH: + DoCastVictim(SPELL_WHIRLING_SLASH); + if (++_phaseCounter >= 2) + events.ScheduleEvent(EVENT_TRANSFORM, 5 * IN_MILLISECONDS); + events.ScheduleEvent(eventId, 21 * IN_MILLISECONDS, 0, PHASE_TROLL); + break; + case EVENT_ENRAGE: + DoCast(me, SPELL_ENRAGE); + events.ScheduleEvent(eventId, 20 * IN_MILLISECONDS, 0, PHASE_RHINO); + break; + case EVENT_TRANSFORM: + if (events.IsInPhase(PHASE_TROLL)) { - me->SetDisplayId(DISPLAY_RHINO); - Phase = RHINO; - uiPhaseCounter = 0; Talk(SAY_TRANSFORM_1); - uiTransformationTimer = 5*IN_MILLISECONDS; - bStartOfTransformation = true; - me->ClearUnitState(UNIT_STATE_STUNNED|UNIT_STATE_ROOT); - me->SetReactState(REACT_AGGRESSIVE); + DoCast(me, SPELL_TRANSFORM_RHINO); + SetPhase(PHASE_RHINO); } - else + else if (events.IsInPhase(PHASE_RHINO)) { - uiTransformationTimer -= diff; - - if (bStartOfTransformation) - { - bStartOfTransformation = false; - me->AddUnitState(UNIT_STATE_STUNNED|UNIT_STATE_ROOT); - me->SetReactState(REACT_PASSIVE); - } - } - } - else - { - if (uiStampedeTimer <= diff) - { - DoCast(me, SPELL_STAMPEDE); - Talk(SAY_SUMMON_RHINO); - uiStampedeTimer = 15*IN_MILLISECONDS; - } else uiStampedeTimer -= diff; - - if (uiWhirlingSlashTimer <= diff) - { - DoCastVictim(SPELL_WHIRLING_SLASH); - uiWhirlingSlashTimer = 21*IN_MILLISECONDS; - ++uiPhaseCounter; - } else uiWhirlingSlashTimer -= diff; - } - break; - case RHINO: - if (uiPhaseCounter == 2) - { - if (uiTransformationTimer <= diff) - { - me->SetDisplayId(DISPLAY_TROLL); - Phase = TROLL; - uiPhaseCounter = 0; Talk(SAY_TRANSFORM_2); - uiTransformationTimer = 9*IN_MILLISECONDS; - bStartOfTransformation = true; - me->ClearUnitState(UNIT_STATE_STUNNED|UNIT_STATE_ROOT); - me->SetReactState(REACT_AGGRESSIVE); + DoCast(me, SPELL_TRANSFORM_BACK); + SetPhase(PHASE_TROLL); } - else - { - uiTransformationTimer -= diff; - - if (bStartOfTransformation) - { - bStartOfTransformation = false; - me->AddUnitState(UNIT_STATE_STUNNED|UNIT_STATE_ROOT); - me->SetReactState(REACT_PASSIVE); - } - } - } - else - { - if (uiPunctureTimer <= diff) - { - DoCastVictim(SPELL_PUNCTURE); - uiPunctureTimer = 8*IN_MILLISECONDS; - } else uiPunctureTimer -= diff; - - if (uiEnrageTimer <= diff) - { - DoCastVictim(SPELL_ENRAGE); - uiEnrageTimer = 20*IN_MILLISECONDS; - } else uiEnrageTimer -= diff; - - if (uiStompTimer <= diff) - { - DoCastVictim(SPELL_STOMP); - uiStompTimer = 20*IN_MILLISECONDS; - } else uiStompTimer -= diff; - - if (uiImpalingChargeTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - { - DoCast(target, SPELL_IMPALING_CHARGE); - CheckAchievement(target->GetGUID()); - } - uiImpalingChargeTimer = 31*IN_MILLISECONDS; - ++uiPhaseCounter; - } else uiImpalingChargeTimer -= diff; - } - break; + _phaseCounter = 0; + break; + default: + break; + } } - DoMeleeAttackIfReady(); - } + private: + std::set<uint64> impaledPlayers; + uint8 _phaseCounter; + }; - // 5 UNIQUE party members - void CheckAchievement(ObjectGuid guid) + CreatureAI* GetAI(Creature* creature) const override { - bool playerExists = false; - for (GuidList::iterator itr = impaledList.begin(); itr != impaledList.end(); ++itr) - if (guid != *itr) - playerExists = true; - - if (playerExists) - ++shareTheLove; - - impaledList.push_back(guid); + return GetGundrakAI<boss_gal_darahAI>(creature); } +}; - uint32 GetData(uint32 type) const override +// 54956, 59827 - Impaling Charge +class spell_gal_darah_impaling_charge : public SpellScriptLoader +{ + public: + spell_gal_darah_impaling_charge() : SpellScriptLoader("spell_gal_darah_impaling_charge") { } + + class spell_gal_darah_impaling_charge_SpellScript : public SpellScript { - if (type == DATA_SHARE_THE_LOVE) - return shareTheLove; + PrepareSpellScript(spell_gal_darah_impaling_charge_SpellScript); - return 0; - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_IMPALING_CHARGE_CONTROL_VEHICLE)) + return false; + return true; + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); + bool Load() override + { + return GetCaster()->GetVehicleKit() && GetCaster()->GetEntry() == NPC_GAL_DARAH; + } - instance->SetData(DATA_GAL_DARAH_EVENT, DONE); - } + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + Unit* caster = GetCaster(); + target->CastSpell(caster, SPELL_IMPALING_CHARGE_CONTROL_VEHICLE, true); + caster->ToCreature()->AI()->SetGUID(target->GetGUID(), DATA_SHARE_THE_LOVE); + } + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gal_darah_impaling_charge_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_CHARGE); + } + }; - Talk(SAY_SLAY); + SpellScript* GetSpellScript() const override + { + return new spell_gal_darah_impaling_charge_SpellScript(); } - }; - }; class achievement_share_the_love : public AchievementCriteriaScript { public: - achievement_share_the_love() : AchievementCriteriaScript("achievement_share_the_love") - { - } + achievement_share_the_love() : AchievementCriteriaScript("achievement_share_the_love") { } bool OnCheck(Player* /*player*/, Unit* target) override { @@ -309,5 +300,6 @@ class achievement_share_the_love : public AchievementCriteriaScript void AddSC_boss_gal_darah() { new boss_gal_darah(); + new spell_gal_darah_impaling_charge(); new achievement_share_the_love(); } diff --git a/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp b/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp index 255a5ece261..7d7cac5601c 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp @@ -17,170 +17,165 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellInfo.h" #include "gundrak.h" +/// @todo: implement mojo frenzy + enum Spells { - SPELL_DETERMINED_STAB = 55104, - SPELL_GROUND_TREMOR = 55142, - SPELL_NUMBING_SHOUT = 55106, - SPELL_DETERMINED_GORE = 55102, - H_SPELL_DETERMINED_GORE = 59444, - SPELL_QUAKE = 55101, - SPELL_NUMBING_ROAR = 55100, - SPELL_MOJO_FRENZY = 55163, - SPELL_TRANSFORMATION = 55098, //Periodic, The caster transforms into a powerful mammoth, increasing Physical damage done by 25% and granting immunity to Stun effects. + SPELL_DETERMINED_GORE = 55102, + SPELL_DETERMINED_STAB = 55104, + SPELL_GROUND_TREMOR = 55142, + SPELL_NUMBING_SHOUT = 55106, + SPELL_QUAKE = 55101, + SPELL_NUMBING_ROAR = 55100, + SPELL_MOJO_FRENZY = 55163, + SPELL_TRANSFORMATION = 55098, // Periodic, The caster transforms into a powerful mammoth, increasing Physical damage done by 25% and granting immunity to Stun effects. }; enum Says { - SAY_AGGRO = 0, - SAY_SLAY = 1, - SAY_DEATH = 2, - SAY_TRANSFORM = 3, - SAY_QUAKE = 4, - EMOTE_TRANSFORM = 5 + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_DEATH = 2, + SAY_TRANSFORM = 3, + SAY_QUAKE = 4, + EMOTE_BEGIN_TRANSFORM = 5, + EMOTE_TRANSFORMED = 6, + EMOTE_ACTIVATE_ALTAR = 7 +}; + +enum Events +{ + EVENT_GROUND_TREMOR = 1, + EVENT_NUMBLING_SHOUT, + EVENT_DETERMINED_STAB, + EVENT_TRANFORMATION }; enum Misc { - DATA_LESS_RABI = 1 + DATA_LESS_RABI = 1 }; class boss_moorabi : public CreatureScript { -public: - boss_moorabi() : CreatureScript("boss_moorabi") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_moorabiAI>(creature); - } - - struct boss_moorabiAI : public ScriptedAI - { - boss_moorabiAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } - - void Initialize() - { - uiGroundTremorTimer = 18 * IN_MILLISECONDS; - uiNumblingShoutTimer = 10 * IN_MILLISECONDS; - uiDeterminedStabTimer = 20 * IN_MILLISECONDS; - uiTransformationTImer = 12 * IN_MILLISECONDS; - bPhase = false; - } - - InstanceScript* instance; - - bool bPhase; - - uint32 uiNumblingShoutTimer; - uint32 uiGroundTremorTimer; - uint32 uiDeterminedStabTimer; - uint32 uiTransformationTImer; - - void Reset() override - { - Initialize(); - - instance->SetData(DATA_MOORABI_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); - DoCast(me, SPELL_MOJO_FRENZY, true); - - instance->SetData(DATA_MOORABI_EVENT, IN_PROGRESS); - } + public: + boss_moorabi() : CreatureScript("boss_moorabi") { } - void UpdateAI(uint32 uiDiff) override + struct boss_moorabiAI : public BossAI { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (!bPhase && me->HasAura(SPELL_TRANSFORMATION)) + boss_moorabiAI(Creature* creature) : BossAI(creature, DATA_MOORABI) { - bPhase = true; - me->RemoveAura(SPELL_MOJO_FRENZY); + Initialize(); } - if (uiGroundTremorTimer <= uiDiff) + void Initialize() { - Talk(SAY_QUAKE); - if (bPhase) - DoCastVictim(SPELL_QUAKE, true); - else - DoCastVictim(SPELL_GROUND_TREMOR, true); - uiGroundTremorTimer = 10*IN_MILLISECONDS; - } else uiGroundTremorTimer -= uiDiff; - - if (uiNumblingShoutTimer <= uiDiff) + _transformed = false; + } + + void Reset() override { - if (bPhase) - DoCastVictim(SPELL_NUMBING_ROAR, true); - else - DoCastVictim(SPELL_NUMBING_SHOUT, true); - uiNumblingShoutTimer = 10*IN_MILLISECONDS; - } else uiNumblingShoutTimer -=uiDiff; - - if (uiDeterminedStabTimer <= uiDiff) + Initialize(); + _Reset(); + } + + void EnterCombat(Unit* /*who*/) override { - if (bPhase) - DoCastVictim(SPELL_DETERMINED_GORE); - else - DoCastVictim(SPELL_DETERMINED_STAB, true); - uiDeterminedStabTimer = 8*IN_MILLISECONDS; - } else uiDeterminedStabTimer -=uiDiff; - - if (!bPhase && uiTransformationTImer <= uiDiff) + _EnterCombat(); + Talk(SAY_AGGRO); + DoCast(me, SPELL_MOJO_FRENZY, true); + + events.ScheduleEvent(EVENT_GROUND_TREMOR, 18 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_NUMBLING_SHOUT, 10 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_DETERMINED_STAB, 20 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_TRANFORMATION, 12 * IN_MILLISECONDS); + } + + uint32 GetData(uint32 type) const override { - Talk(EMOTE_TRANSFORM); - Talk(SAY_TRANSFORM); - DoCast(me, SPELL_TRANSFORMATION, false); - uiTransformationTImer = 10*IN_MILLISECONDS; - } else uiTransformationTImer -= uiDiff; + if (type == DATA_LESS_RABI) + return _transformed ? 0 : 1; + return 0; + } - DoMeleeAttackIfReady(); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - uint32 GetData(uint32 type) const override - { - if (type == DATA_LESS_RABI) - return bPhase ? 0 : 1; + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + Talk(EMOTE_ACTIVATE_ALTAR); + } - return 0; - } + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_TRANSFORMATION) + { + _transformed = true; + Talk(EMOTE_TRANSFORMED); + events.CancelEvent(EVENT_TRANFORMATION); + me->RemoveAurasDueToSpell(SPELL_MOJO_FRENZY); + } + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_GROUND_TREMOR: + Talk(SAY_QUAKE); + if (_transformed) + DoCastAOE(SPELL_QUAKE); + else + DoCastAOE(SPELL_GROUND_TREMOR); + events.ScheduleEvent(eventId, 10 * IN_MILLISECONDS); + break; + case EVENT_NUMBLING_SHOUT: + if (_transformed) + DoCastAOE(SPELL_NUMBING_ROAR); + else + DoCastAOE(SPELL_NUMBING_SHOUT); + events.ScheduleEvent(eventId, 10 * IN_MILLISECONDS); + break; + case EVENT_DETERMINED_STAB: + if (_transformed) + DoCastVictim(SPELL_DETERMINED_GORE); + else + DoCastVictim(SPELL_DETERMINED_STAB); + events.ScheduleEvent(eventId, 8 * IN_MILLISECONDS); + break; + case EVENT_TRANFORMATION: + Talk(EMOTE_BEGIN_TRANSFORM); + Talk(SAY_TRANSFORM); + DoCast(me, SPELL_TRANSFORMATION); + events.ScheduleEvent(eventId, 10 * IN_MILLISECONDS); + break; + default: + break; + } + } - instance->SetData(DATA_MOORABI_EVENT, DONE); - } + private: + bool _transformed; + }; - void KilledUnit(Unit* victim) override + CreatureAI* GetAI(Creature* creature) const override { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; - - Talk(SAY_SLAY); + return GetGundrakAI<boss_moorabiAI>(creature); } - }; - }; class achievement_less_rabi : public AchievementCriteriaScript { public: - achievement_less_rabi() : AchievementCriteriaScript("achievement_less_rabi") - { - } + achievement_less_rabi() : AchievementCriteriaScript("achievement_less_rabi") { } bool OnCheck(Player* /*player*/, Unit* target) override { diff --git a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp index 6c247b08097..9520736cdb5 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp @@ -24,11 +24,10 @@ enum Spells { SPELL_POISON_NOVA = 55081, - H_SPELL_POISON_NOVA = 59842, SPELL_POWERFULL_BITE = 48287, - H_SPELL_POWERFULL_BITE = 59840, SPELL_VENOM_BOLT = 54970, - H_SPELL_VENOM_BOLT = 59839 + SPELL_SUMMON_SNAKES = 55060, // NYI + SPELL_SUMMON_CONSTRICTORS = 54969 // NYI }; enum Yells @@ -38,7 +37,8 @@ enum Yells SAY_DEATH = 2, SAY_SUMMON_SNAKES = 3, SAY_SUMMON_CONSTRICTORS = 4, - EMOTE_NOVA = 5 + EMOTE_NOVA = 5, + EMOTE_ACTIVATE_ALTAR = 6 }; enum Creatures @@ -50,18 +50,17 @@ enum Creatures enum ConstrictorSpells { SPELL_GRIP_OF_SLAD_RAN = 55093, - SPELL_SNAKE_WRAP = 55126, - SPELL_VENOMOUS_BITE = 54987, - H_SPELL_VENOMOUS_BITE = 58996 + SPELL_SNAKE_WRAP = 55126, // 55099 -> 55126 + SPELL_VENOMOUS_BITE = 54987 }; static Position SpawnLoc[]= { - {1783.81f, 646.637f, 133.948f, 3.71755f}, - {1775.03f, 606.586f, 134.165f, 1.43117f}, - {1717.39f, 630.041f, 129.282f, 5.96903f}, - {1765.66f, 646.542f, 134.02f, 5.11381f}, - {1716.76f, 635.159f, 129.282f, 0.191986f} + {1783.81f, 646.637f, 133.948f, 3.71755f}, + {1775.03f, 606.586f, 134.165f, 1.43117f}, + {1717.39f, 630.041f, 129.282f, 5.96903f}, + {1765.66f, 646.542f, 134.02f, 5.11381f}, + {1716.76f, 635.159f, 129.282f, 0.191986f} }; enum Misc @@ -74,17 +73,11 @@ class boss_slad_ran : public CreatureScript public: boss_slad_ran() : CreatureScript("boss_slad_ran") { } - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_slad_ranAI>(creature); - } - - struct boss_slad_ranAI : public ScriptedAI + struct boss_slad_ranAI : public BossAI { - boss_slad_ranAI(Creature* creature) : ScriptedAI(creature), lSummons(me) + boss_slad_ranAI(Creature* creature) : BossAI(creature, DATA_SLAD_RAN) { Initialize(); - instance = creature->GetInstanceScript(); } void Initialize() @@ -104,25 +97,18 @@ public: uint8 uiPhase; GuidSet lWrappedPlayers; - SummonList lSummons; - - InstanceScript* instance; void Reset() override { Initialize(); + _Reset(); lWrappedPlayers.clear(); - - lSummons.DespawnAll(); - - instance->SetData(DATA_SLAD_RAN_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) override { + _EnterCombat(); Talk(SAY_AGGRO); - - instance->SetData(DATA_SLAD_RAN_EVENT, IN_PROGRESS); } void UpdateAI(uint32 diff) override @@ -181,10 +167,9 @@ public: void JustDied(Unit* /*killer*/) override { + _JustDied(); Talk(SAY_DEATH); - lSummons.DespawnAll(); - - instance->SetData(DATA_SLAD_RAN_EVENT, DONE); + Talk(EMOTE_ACTIVATE_ALTAR); } void KilledUnit(Unit* who) override @@ -193,10 +178,10 @@ public: Talk(SAY_SLAY); } - void JustSummoned(Creature* summoned) override + void JustSummoned(Creature* summon) override { - summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - lSummons.Summon(summoned); + summon->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + summons.Summon(summon); } void SetGUID(ObjectGuid guid, int32 type) override @@ -211,6 +196,10 @@ public: } }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetGundrakAI<boss_slad_ranAI>(creature); + } }; class npc_slad_ran_constrictor : public CreatureScript @@ -310,9 +299,7 @@ public: class achievement_snakes_whyd_it_have_to_be_snakes : public AchievementCriteriaScript { public: - achievement_snakes_whyd_it_have_to_be_snakes() : AchievementCriteriaScript("achievement_snakes_whyd_it_have_to_be_snakes") - { - } + achievement_snakes_whyd_it_have_to_be_snakes() : AchievementCriteriaScript("achievement_snakes_whyd_it_have_to_be_snakes") { } bool OnCheck(Player* player, Unit* target) override { diff --git a/src/server/scripts/Northrend/Gundrak/gundrak.h b/src/server/scripts/Northrend/Gundrak/gundrak.h index fffeca82f39..9963c6caee8 100644 --- a/src/server/scripts/Northrend/Gundrak/gundrak.h +++ b/src/server/scripts/Northrend/Gundrak/gundrak.h @@ -15,59 +15,85 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEF_GUNDRAK_H -#define DEF_GUNDRAK_H +#ifndef GUNDRAK_H_ +#define GUNDRAK_H_ +#define GundrakScriptName "instance_gundrak" #define DataHeader "GD" -enum Data +uint32 const EncounterCount = 5; + +enum DataTypes { - DATA_SLAD_RAN_EVENT, - DATA_MOORABI_EVENT, - DATA_DRAKKARI_COLOSSUS_EVENT, - DATA_GAL_DARAH_EVENT, - DATA_ECK_THE_FEROCIOUS_EVENT + // Encounter Ids // Encounter States // Boss GUIDs + DATA_SLAD_RAN = 0, + DATA_DRAKKARI_COLOSSUS = 1, + DATA_MOORABI = 2, + DATA_GAL_DARAH = 3, + DATA_ECK_THE_FEROCIOUS = 4, + + // Additional Objects + DATA_SLAD_RAN_ALTAR = 5, + DATA_DRAKKARI_COLOSSUS_ALTAR = 6, + DATA_MOORABI_ALTAR = 7, + + DATA_SLAD_RAN_STATUE = 8, + DATA_DRAKKARI_COLOSSUS_STATUE = 9, + DATA_MOORABI_STATUE = 10, + DATA_GAL_DARAH_STATUE = 11, + + DATA_TRAPDOOR = 12, + DATA_COLLISION = 13, + DATA_BRIDGE = 14, + + DATA_STATUE_ACTIVATE = 15, }; -enum Data64 +enum CreatureIds { - DATA_SLAD_RAN_ALTAR, - DATA_MOORABI_ALTAR, - DATA_DRAKKARI_COLOSSUS_ALTAR, - DATA_SLAD_RAN_STATUE, - DATA_MOORABI_STATUE, - DATA_DRAKKARI_COLOSSUS_STATUE, - DATA_DRAKKARI_COLOSSUS, - DATA_STATUE_ACTIVATE + NPC_SLAD_RAN = 29304, + NPC_MOORABI = 29305, + NPC_GAL_DARAH = 29306, + NPC_DRAKKARI_COLOSSUS = 29307, + NPC_RUIN_DWELLER = 29920, + NPC_ECK_THE_FEROCIOUS = 29932, + NPC_ALTAR_TRIGGER = 30298 }; -enum mainCreatures +enum GameObjectIds { - CREATURE_RUIN_DWELLER = 29920, - CREATURE_SLAD_RAN = 29304, - CREATURE_MOORABI = 29305, - CREATURE_GALDARAH = 29306, - CREATURE_DRAKKARICOLOSSUS = 29307, - CREATURE_ECK = 29932 + GO_SLAD_RAN_ALTAR = 192518, + GO_MOORABI_ALTAR = 192519, + GO_DRAKKARI_COLOSSUS_ALTAR = 192520, + GO_SLAD_RAN_STATUE = 192564, + GO_MOORABI_STATUE = 192565, + GO_GAL_DARAH_STATUE = 192566, + GO_DRAKKARI_COLOSSUS_STATUE = 192567, + GO_ECK_THE_FEROCIOUS_DOOR = 192632, + GO_ECK_THE_FEROCIOUS_DOOR_BEHIND = 192569, + GO_GAL_DARAH_DOOR_1 = 193208, + GO_GAL_DARAH_DOOR_2 = 193209, + GO_GAL_DARAH_DOOR_3 = 192568, + GO_TRAPDOOR = 193188, + GO_COLLISION = 192633, }; -enum Gameobjects +enum SpellIds { + SPELL_FIRE_BEAM_MAMMOTH = 57068, + SPELL_FIRE_BEAM_SNAKE = 57071, + SPELL_FIRE_BEAM_ELEMENTAL = 57072 +}; - GO_SLADRAN_ALTAR = 192518, - GO_MOORABI_ALTAR = 192519, - GO_DRAKKARI_COLOSSUS_ALTAR = 192520, - GO_SLADRAN_STATUE = 192564, - GO_MOORABI_STATUE = 192565, - GO_GALDARAH_STATUE = 192566, - GO_DRAKKARI_COLOSSUS_STATUE = 192567, - GO_ECK_THE_FEROCIOUS_DOOR = 192632, - GO_ECK_THE_FEROCIOUS_DOOR_BEHIND = 192569, - GO_GALDARAH_DOOR1 = 193208, - GO_GALDARAH_DOOR2 = 193209, - GO_GALDARAH_DOOR3 = 192568, - GO_BRIDGE = 193188, - GO_COLLISION = 192633 +enum InstanceMisc +{ + TIMER_STATUE_ACTIVATION = 3500 }; -#endif +template<class AI> +inline AI* GetGundrakAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, GundrakScriptName); +} + +#endif // GUNDRAK_H_ diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp index 0fa26a3dee3..31722b06be8 100644 --- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp +++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp @@ -15,550 +15,354 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ScriptMgr.h" #include "InstanceScript.h" -#include "gundrak.h" #include "Player.h" -#include "TemporarySummon.h" +#include "ScriptMgr.h" +#include "WorldSession.h" +#include "gundrak.h" -#define MAX_ENCOUNTER 5 +DoorData const doorData[] = +{ + { GO_GAL_DARAH_DOOR_1, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_GAL_DARAH_DOOR_2, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_GAL_DARAH_DOOR_3, DATA_GAL_DARAH, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_ECK_THE_FEROCIOUS_DOOR, DATA_MOORABI, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_ECK_THE_FEROCIOUS_DOOR_BEHIND, DATA_ECK_THE_FEROCIOUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; -/* GunDrak encounters: -0 - Slad'Ran -1 - Moorabi -2 - Drakkari Colossus -3 - Gal'Darah -4 - Eck the Ferocious -*/ +ObjectData const creatureData[] = +{ + { NPC_DRAKKARI_COLOSSUS, DATA_DRAKKARI_COLOSSUS }, + { 0, 0 } // END +}; + +ObjectData const gameObjectData[] = +{ + { GO_SLAD_RAN_ALTAR, DATA_SLAD_RAN_ALTAR }, + { GO_MOORABI_ALTAR, DATA_MOORABI_ALTAR }, + { GO_DRAKKARI_COLOSSUS_ALTAR, DATA_DRAKKARI_COLOSSUS_ALTAR }, + { GO_SLAD_RAN_STATUE, DATA_SLAD_RAN_STATUE }, + { GO_MOORABI_STATUE, DATA_MOORABI_STATUE }, + { GO_DRAKKARI_COLOSSUS_STATUE, DATA_DRAKKARI_COLOSSUS_STATUE }, + { GO_GAL_DARAH_STATUE, DATA_GAL_DARAH_STATUE }, + { GO_TRAPDOOR, DATA_TRAPDOOR }, + { GO_COLLISION, DATA_COLLISION }, + { 0, 0 } // END +}; Position const EckSpawnPoint = { 1643.877930f, 936.278015f, 107.204948f, 0.668432f }; class instance_gundrak : public InstanceMapScript { -public: - instance_gundrak() : InstanceMapScript("instance_gundrak", 604) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_gundrak_InstanceMapScript(map); - } + public: + instance_gundrak() : InstanceMapScript(GundrakScriptName, 604) { } - struct instance_gundrak_InstanceMapScript : public InstanceScript - { - instance_gundrak_InstanceMapScript(Map* map) : InstanceScript(map) + struct instance_gundrak_InstanceMapScript : public InstanceScript { - SetHeaders(DataHeader); - isHeroic = map->IsHeroic(); - } - - bool isHeroic; - bool spawnSupport; - - uint32 timer; - uint32 phase; - ObjectGuid toActivate; - - ObjectGuid sladRanGUID; - ObjectGuid moorabiGUID; - ObjectGuid drakkariColossusGUID; - ObjectGuid galDarahGUID; - ObjectGuid eckTheFerociousGUID; - - ObjectGuid sladRanAltarGUID; - ObjectGuid moorabiAltarGUID; - ObjectGuid drakkariColossusAltarGUID; - ObjectGuid sladRanStatueGUID; - ObjectGuid moorabiStatueGUID; - ObjectGuid drakkariColossusStatueGUID; - ObjectGuid galDarahStatueGUID; - ObjectGuid eckTheFerociousDoorGUID; - ObjectGuid eckTheFerociousDoorBehindGUID; - ObjectGuid galDarahDoor1GUID; - ObjectGuid galDarahDoor2GUID; - ObjectGuid galDarahDoor3GUID; - ObjectGuid bridgeGUID; - ObjectGuid collisionGUID; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - - GOState sladRanStatueState; - GOState moorabiStatueState; - GOState drakkariColossusStatueState; - GOState galDarahStatueState; - GOState bridgeState; - GOState collisionState; - - GuidSet DwellerGUIDs; - - std::string str_data; - - void Initialize() override - { - spawnSupport = false; - - timer = 0; - phase = 0; - - sladRanStatueState = GO_STATE_ACTIVE; - moorabiStatueState = GO_STATE_ACTIVE; - drakkariColossusStatueState = GO_STATE_ACTIVE; - galDarahStatueState = GO_STATE_READY; - bridgeState = GO_STATE_ACTIVE; - collisionState = GO_STATE_READY; - - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - } - - bool IsEncounterInProgress() const override - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; - - return false; - } + instance_gundrak_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + LoadDoorData(doorData); + LoadObjectData(creatureData, gameObjectData); + + SladRanStatueState = GO_STATE_ACTIVE; + DrakkariColossusStatueState = GO_STATE_ACTIVE; + MoorabiStatueState = GO_STATE_ACTIVE; + } - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) + void OnCreatureCreate(Creature* creature) override { - case CREATURE_SLAD_RAN: - sladRanGUID = creature->GetGUID(); - break; - case CREATURE_MOORABI: - moorabiGUID = creature->GetGUID(); - break; - case CREATURE_GALDARAH: - galDarahGUID = creature->GetGUID(); - break; - case CREATURE_DRAKKARICOLOSSUS: - drakkariColossusGUID = creature->GetGUID(); - break; - case CREATURE_ECK: - eckTheFerociousGUID = creature->GetGUID(); - break; - case CREATURE_RUIN_DWELLER: - if (creature->IsAlive()) - DwellerGUIDs.insert(creature->GetGUID()); - break; + switch (creature->GetEntry()) + { + case NPC_RUIN_DWELLER: + if (creature->IsAlive()) + DwellerGUIDs.insert(creature->GetGUID()); + break; + default: + break; + } + + InstanceScript::OnCreatureCreate(creature); } - } - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) + void OnGameObjectCreate(GameObject* go) override { - case GO_SLADRAN_ALTAR: - sladRanAltarGUID = go->GetGUID(); - // Make sure that they start out as unusuable - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - if (m_auiEncounter[0] == DONE) - { - if (sladRanStatueState == GO_STATE_ACTIVE) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - else + switch (go->GetEntry()) + { + case GO_SLAD_RAN_ALTAR: + if (GetBossState(DATA_SLAD_RAN) == DONE) { - ++phase; - go->SetGoState(GO_STATE_ACTIVE); + if (SladRanStatueState == GO_STATE_ACTIVE) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + else + go->SetGoState(GO_STATE_ACTIVE); } - } - break; - case GO_MOORABI_ALTAR: - moorabiAltarGUID = go->GetGUID(); - // Make sure that they start out as unusuable - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - if (m_auiEncounter[0] == DONE) - { - if (moorabiStatueState == GO_STATE_ACTIVE) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - else + break; + case GO_MOORABI_ALTAR: + if (GetBossState(DATA_MOORABI) == DONE) { - ++phase; - go->SetGoState(GO_STATE_ACTIVE); + if (MoorabiStatueState == GO_STATE_ACTIVE) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + else + go->SetGoState(GO_STATE_ACTIVE); } - } - break; - case GO_DRAKKARI_COLOSSUS_ALTAR: - drakkariColossusAltarGUID = go->GetGUID(); - // Make sure that they start out as unusuable - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - if (m_auiEncounter[0] == DONE) - { - if (drakkariColossusStatueState == GO_STATE_ACTIVE) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - else + break; + case GO_DRAKKARI_COLOSSUS_ALTAR: + if (GetBossState(DATA_DRAKKARI_COLOSSUS) == DONE) { - ++phase; - go->SetGoState(GO_STATE_ACTIVE); + if (DrakkariColossusStatueState == GO_STATE_ACTIVE) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + else + go->SetGoState(GO_STATE_ACTIVE); } - } - break; - case GO_SLADRAN_STATUE: - sladRanStatueGUID = go->GetGUID(); - go->SetGoState(sladRanStatueState); - break; - case GO_MOORABI_STATUE: - moorabiStatueGUID = go->GetGUID(); - go->SetGoState(moorabiStatueState); - break; - case GO_GALDARAH_STATUE: - galDarahStatueGUID = go->GetGUID(); - go->SetGoState(galDarahStatueState); - break; - case GO_DRAKKARI_COLOSSUS_STATUE: - drakkariColossusStatueGUID = go->GetGUID(); - go->SetGoState(drakkariColossusStatueState); - break; - case GO_ECK_THE_FEROCIOUS_DOOR: - eckTheFerociousDoorGUID = go->GetGUID(); - if (isHeroic && m_auiEncounter[1] == DONE) - HandleGameObject(ObjectGuid::Empty, true, go); - break; - case GO_ECK_THE_FEROCIOUS_DOOR_BEHIND: - eckTheFerociousDoorBehindGUID = go->GetGUID(); - if (isHeroic && m_auiEncounter[4] == DONE) - HandleGameObject(ObjectGuid::Empty, true, go); - break; - case GO_GALDARAH_DOOR1: - galDarahDoor1GUID = go->GetGUID(); - if (m_auiEncounter[3] == DONE) - HandleGameObject(ObjectGuid::Empty, true, go); - break; - case GO_GALDARAH_DOOR2: - galDarahDoor2GUID = go->GetGUID(); - if (m_auiEncounter[3] == DONE) - HandleGameObject(ObjectGuid::Empty, true, go); - break; - case GO_BRIDGE: - bridgeGUID = go->GetGUID(); - go->SetGoState(bridgeState); - break; - case GO_COLLISION: - collisionGUID = go->GetGUID(); - go->SetGoState(collisionState); - - // Can't spawn here with SpawnGameObject because go isn't added to world yet... - if (collisionState == GO_STATE_ACTIVE_ALTERNATIVE) - spawnSupport = true; - break; - case GO_GALDARAH_DOOR3: - galDarahDoor3GUID = go->GetGUID(); - if (m_auiEncounter[3] != IN_PROGRESS) - HandleGameObject(galDarahDoor3GUID, true, go); - break; + break; + case GO_SLAD_RAN_STATUE: + go->SetGoState(SladRanStatueState); + break; + case GO_MOORABI_STATUE: + go->SetGoState(MoorabiStatueState); + break; + case GO_GAL_DARAH_STATUE: + go->SetGoState(CheckRequiredBosses(DATA_GAL_DARAH) ? GO_STATE_ACTIVE_ALTERNATIVE : GO_STATE_READY); + break; + case GO_DRAKKARI_COLOSSUS_STATUE: + go->SetGoState(DrakkariColossusStatueState); + break; + case GO_ECK_THE_FEROCIOUS_DOOR: + // Don't store door on non-heroic + if (!instance->IsHeroic()) + return; + break; + case GO_TRAPDOOR: + go->SetGoState(CheckRequiredBosses(DATA_GAL_DARAH) ? GO_STATE_READY : GO_STATE_ACTIVE); + break; + case GO_COLLISION: + go->SetGoState(CheckRequiredBosses(DATA_GAL_DARAH) ? GO_STATE_ACTIVE : GO_STATE_READY); + break; + default: + break; + } + + InstanceScript::OnGameObjectCreate(go); } - } - void OnUnitDeath(Unit* unit) override - { - if (unit->GetEntry() == CREATURE_RUIN_DWELLER) + void OnUnitDeath(Unit* unit) override { - DwellerGUIDs.erase(unit->GetGUID()); + if (unit->GetEntry() == NPC_RUIN_DWELLER) + { + DwellerGUIDs.erase(unit->GetGUID()); - if (DwellerGUIDs.empty()) - unit->SummonCreature(CREATURE_ECK, EckSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300 * IN_MILLISECONDS); + if (DwellerGUIDs.empty()) + unit->SummonCreature(NPC_ECK_THE_FEROCIOUS, EckSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300 * IN_MILLISECONDS); + } } - } - void SetData(uint32 type, uint32 data) override - { - switch (type) + bool SetBossState(uint32 type, EncounterState state) override { - case DATA_SLAD_RAN_EVENT: - m_auiEncounter[0] = data; - if (data == DONE) - { - GameObject* go = instance->GetGameObject(sladRanAltarGUID); - if (go) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - } - break; - case DATA_MOORABI_EVENT: - m_auiEncounter[1] = data; - if (data == DONE) - { - GameObject* go = instance->GetGameObject(moorabiAltarGUID); - if (go) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - if (isHeroic) - HandleGameObject(eckTheFerociousDoorGUID, true); - } - break; - case DATA_DRAKKARI_COLOSSUS_EVENT: - m_auiEncounter[2] = data; - if (data == DONE) + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) { - GameObject* go = instance->GetGameObject(drakkariColossusAltarGUID); - if (go) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + case DATA_SLAD_RAN: + if (state == DONE) + if (GameObject* go = GetGameObject(DATA_SLAD_RAN_ALTAR)) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + case DATA_DRAKKARI_COLOSSUS: + if (state == DONE) + if (GameObject* go = GetGameObject(DATA_DRAKKARI_COLOSSUS_ALTAR)) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + case DATA_MOORABI: + if (state == DONE) + if (GameObject* go = GetGameObject(DATA_MOORABI_ALTAR)) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + default: + break; } - break; - case DATA_GAL_DARAH_EVENT: - m_auiEncounter[3] = data; - if (data == DONE) + + return true; + } + + bool CheckRequiredBosses(uint32 bossId, Player const* player = nullptr) const override + { + if (player && player->GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES)) + return true; + + switch (bossId) { - HandleGameObject(galDarahDoor1GUID, true); - HandleGameObject(galDarahDoor2GUID, true); + case DATA_ECK_THE_FEROCIOUS: + if (!instance->IsHeroic() || GetBossState(DATA_MOORABI) != DONE) + return false; + break; + case DATA_GAL_DARAH: + if (SladRanStatueState != GO_STATE_ACTIVE_ALTERNATIVE + || DrakkariColossusStatueState != GO_STATE_ACTIVE_ALTERNATIVE + || MoorabiStatueState != GO_STATE_ACTIVE_ALTERNATIVE) + return false; + break; + default: + break; } - HandleGameObject(galDarahDoor3GUID, data == IN_PROGRESS ? false : true); - break; - case DATA_ECK_THE_FEROCIOUS_EVENT: - m_auiEncounter[4] = data; - if (isHeroic && data == DONE) - HandleGameObject(eckTheFerociousDoorBehindGUID, true); - break; - } - if (data == DONE) - SaveToDB(); - } + return true; + } - void SetGuidData(uint32 type, ObjectGuid data) override - { - if (type == DATA_STATUE_ACTIVATE) + bool IsBridgeReady() const { - toActivate = data; - timer = 3500; - ++phase; + return SladRanStatueState == GO_STATE_READY && DrakkariColossusStatueState == GO_STATE_READY && MoorabiStatueState == GO_STATE_READY; } - } - uint32 GetData(uint32 type) const override - { - switch (type) + void SetData(uint32 type, uint32 data) override { - case DATA_SLAD_RAN_EVENT: - return m_auiEncounter[0]; - case DATA_MOORABI_EVENT: - return m_auiEncounter[1]; - case DATA_GAL_DARAH_EVENT: - return m_auiEncounter[2]; - case DATA_DRAKKARI_COLOSSUS_EVENT: - return m_auiEncounter[3]; - case DATA_ECK_THE_FEROCIOUS_EVENT: - return m_auiEncounter[4]; + if (type == DATA_STATUE_ACTIVATE) + { + switch (data) + { + case GO_SLAD_RAN_ALTAR: + Events.ScheduleEvent(DATA_SLAD_RAN_STATUE, TIMER_STATUE_ACTIVATION); + break; + case GO_DRAKKARI_COLOSSUS_ALTAR: + Events.ScheduleEvent(DATA_DRAKKARI_COLOSSUS_STATUE, TIMER_STATUE_ACTIVATION); + break; + case GO_MOORABI_ALTAR: + Events.ScheduleEvent(DATA_MOORABI_STATUE, TIMER_STATUE_ACTIVATION); + break; + default: + break; + } + } } - return 0; - } - - ObjectGuid GetGuidData(uint32 type) const override - { - switch (type) + void WriteSaveDataMore(std::ostringstream& data) override { - case DATA_SLAD_RAN_ALTAR: - return sladRanAltarGUID; - case DATA_MOORABI_ALTAR: - return moorabiAltarGUID; - case DATA_DRAKKARI_COLOSSUS_ALTAR: - return drakkariColossusAltarGUID; - case DATA_SLAD_RAN_STATUE: - return sladRanStatueGUID; - case DATA_MOORABI_STATUE: - return moorabiStatueGUID; - case DATA_DRAKKARI_COLOSSUS_STATUE: - return drakkariColossusStatueGUID; - case DATA_DRAKKARI_COLOSSUS: - return drakkariColossusGUID; - case DATA_STATUE_ACTIVATE: - return toActivate; + data << uint32(SladRanStatueState) << ' '; + data << uint32(DrakkariColossusStatueState) << ' '; + data << uint32(MoorabiStatueState) << ' '; } - return ObjectGuid::Empty; - } + void ReadSaveDataMore(std::istringstream& data) override + { + uint32 temp; - std::string GetSaveData() override - { - OUT_SAVE_INST_DATA; + data >> temp; + SladRanStatueState = GOState(temp); - std::ostringstream saveStream; - saveStream << "G D " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' - << m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' ' - << (sladRanStatueGUID ? GetObjState(sladRanStatueGUID) : GO_STATE_ACTIVE) << ' ' << (moorabiStatueGUID ? GetObjState(moorabiStatueGUID) : GO_STATE_ACTIVE) << ' ' - << (drakkariColossusStatueGUID ? GetObjState(drakkariColossusStatueGUID) : GO_STATE_ACTIVE) << ' ' << (galDarahStatueGUID ? GetObjState(galDarahStatueGUID) : GO_STATE_READY) << ' ' - << (bridgeGUID ? GetObjState(bridgeGUID) : GO_STATE_ACTIVE) << ' ' << (collisionGUID ? GetObjState(collisionGUID) : GO_STATE_READY); + data >> temp; + DrakkariColossusStatueState = GOState(temp); - str_data = saveStream.str(); + data >> temp; + MoorabiStatueState = GOState(temp); - OUT_SAVE_INST_DATA_COMPLETE; - return str_data; - } + if (IsBridgeReady()) + Events.ScheduleEvent(DATA_BRIDGE, TIMER_STATUE_ACTIVATION); + } - void Load(const char* in) override - { - if (!in) + void ToggleGameObject(uint32 type, GOState state) { - OUT_LOAD_INST_DATA_FAIL; - return; + if (GameObject* go = GetGameObject(type)) + go->SetGoState(state); + + switch (type) + { + case DATA_SLAD_RAN_STATUE: + SladRanStatueState = state; + break; + case DATA_DRAKKARI_COLOSSUS_STATUE: + DrakkariColossusStatueState = state; + break; + case DATA_MOORABI_STATUE: + MoorabiStatueState = state; + break; + default: + break; + } } - OUT_LOAD_INST_DATA(in); + void Update(uint32 diff) override + { + Events.Update(diff); - char dataHead1, dataHead2; - uint16 data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10; + while (uint32 eventId = Events.ExecuteEvent()) + { + uint32 spellId = 0; + uint32 altarId = 0; + switch (eventId) + { + case DATA_SLAD_RAN_STATUE: + spellId = SPELL_FIRE_BEAM_SNAKE; + altarId = DATA_SLAD_RAN_ALTAR; + break; + case DATA_DRAKKARI_COLOSSUS_STATUE: + spellId = SPELL_FIRE_BEAM_ELEMENTAL; + altarId = DATA_DRAKKARI_COLOSSUS_ALTAR; + break; + case DATA_MOORABI_STATUE: + spellId = SPELL_FIRE_BEAM_MAMMOTH; + altarId = DATA_MOORABI_ALTAR; + break; + case DATA_BRIDGE: + for (uint32 type = DATA_SLAD_RAN_STATUE; type <= DATA_GAL_DARAH_STATUE; ++type) + ToggleGameObject(type, GO_STATE_ACTIVE_ALTERNATIVE); + ToggleGameObject(DATA_TRAPDOOR, GO_STATE_READY); + ToggleGameObject(DATA_COLLISION, GO_STATE_ACTIVE); + SaveToDB(); + return; + default: + return; + } - std::istringstream loadStream(in); - loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 - >> data4 >> data5 >> data6 >> data7 >> data8 >> data9 >> data10; + if (GameObject* altar = GetGameObject(altarId)) + if (Creature* trigger = altar->FindNearestCreature(NPC_ALTAR_TRIGGER, 10.0f)) + trigger->CastSpell((Unit*)nullptr, spellId, true); - if (dataHead1 == 'G' && dataHead2 == 'D') - { - m_auiEncounter[0] = data0; - m_auiEncounter[1] = data1; - m_auiEncounter[2] = data2; - m_auiEncounter[3] = data3; - m_auiEncounter[4] = data4; - sladRanStatueState = GOState(data5); - moorabiStatueState = GOState(data6); - drakkariColossusStatueState = GOState(data7); - galDarahStatueState = GOState(data8); - bridgeState = GOState(data9); - collisionState = GOState(data10); - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - } else OUT_LOAD_INST_DATA_FAIL; - - OUT_LOAD_INST_DATA_COMPLETE; - } + // eventId equals statueId + ToggleGameObject(eventId, GO_STATE_READY); - void Update(uint32 diff) override - { - // Spawn the support for the bridge if necessary - if (spawnSupport) - { - if (GameObject* collision = instance->GetGameObject(collisionGUID)) - collision->SummonGameObject(192743, collision->GetPositionX(), collision->GetPositionY(), collision->GetPositionZ(), collision->GetOrientation(), 0, 0, 0, 0, 0); - spawnSupport = false; - } - - // If there is nothing to activate, then return - if (!toActivate) - return; - - if (timer < diff) - { - timer = 0; - if (toActivate == bridgeGUID) - { - GameObject* bridge = instance->GetGameObject(bridgeGUID); - GameObject* collision = instance->GetGameObject(collisionGUID); - GameObject* sladRanStatue = instance->GetGameObject(sladRanStatueGUID); - GameObject* moorabiStatue = instance->GetGameObject(moorabiStatueGUID); - GameObject* drakkariColossusStatue = instance->GetGameObject(drakkariColossusStatueGUID); - GameObject* galDarahStatue = instance->GetGameObject(galDarahStatueGUID); - - toActivate.Clear(); - - if (bridge && collision && sladRanStatue && moorabiStatue && drakkariColossusStatue && galDarahStatue) - { - bridge->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - collision->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - sladRanStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - moorabiStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - drakkariColossusStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - galDarahStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - - // Add the GO that solidifies the bridge so you can walk on it - spawnSupport = true; - SaveToDB(); - } - } - else - { - uint32 spell = 0; - GameObject* altar = NULL; - if (toActivate == sladRanStatueGUID) - { - spell = 57071; - altar = instance->GetGameObject(sladRanAltarGUID); - } - else if (toActivate == moorabiStatueGUID) - { - spell = 57068; - altar = instance->GetGameObject(moorabiAltarGUID); - } - else if (toActivate == drakkariColossusStatueGUID) - { - spell = 57072; - altar = instance->GetGameObject(drakkariColossusAltarGUID); - } - - // This is a workaround to make the beam cast properly. The caster should be ID 30298 but since the spells - // all are with scripted target for that same ID, it will hit itself. - if (altar) - if (Creature* trigger = altar->SummonCreature(18721, altar->GetPositionX(), altar->GetPositionY(), altar->GetPositionZ() + 3, altar->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 5000)) - { - // Set the trigger model to invisible - trigger->SetDisplayId(11686); - trigger->CastSpell(trigger, spell, false); - } - - if (GameObject* statueGO = instance->GetGameObject(toActivate)) - statueGO->SetGoState(GO_STATE_READY); - - toActivate.Clear(); - - if (phase == 3) - SetGuidData(DATA_STATUE_ACTIVATE, bridgeGUID); - else - SaveToDB(); // Don't save in between last statue and bridge turning in case of crash leading to stuck instance + if (IsBridgeReady()) + Events.ScheduleEvent(DATA_BRIDGE, TIMER_STATUE_ACTIVATION); + + SaveToDB(); } } - else - timer -= diff; - } - GOState GetObjState(ObjectGuid guid) - { - if (GameObject* go = instance->GetGameObject(guid)) - return go->GetGoState(); - return GO_STATE_ACTIVE; - } - }; + protected: + EventMap Events; + GuidSet DwellerGUIDs; + + GOState SladRanStatueState; + GOState DrakkariColossusStatueState; + GOState MoorabiStatueState; + }; + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_gundrak_InstanceMapScript(map); + } }; class go_gundrak_altar : public GameObjectScript { -public: - go_gundrak_altar() : GameObjectScript("go_gundrak_altar") { } - - bool OnGossipHello(Player* /*player*/, GameObject* go) override - { - InstanceScript* instance = go->GetInstanceScript(); - ObjectGuid statueGUID; + public: + go_gundrak_altar() : GameObjectScript("go_gundrak_altar") { } - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - go->SetGoState(GO_STATE_ACTIVE); - - if (instance) + bool OnGossipHello(Player* /*player*/, GameObject* go) override { - switch (go->GetEntry()) - { - case GO_SLADRAN_ALTAR: - statueGUID = instance->GetGuidData(DATA_SLAD_RAN_STATUE); - break; - case GO_MOORABI_ALTAR: - statueGUID = instance->GetGuidData(DATA_MOORABI_STATUE); - break; - case GO_DRAKKARI_COLOSSUS_ALTAR: - statueGUID = instance->GetGuidData(DATA_DRAKKARI_COLOSSUS_STATUE); - break; - } + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_ACTIVE); - if (!instance->GetGuidData(DATA_STATUE_ACTIVATE)) + if (InstanceScript* instance = go->GetInstanceScript()) { - instance->SetGuidData(DATA_STATUE_ACTIVATE, statueGUID); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - go->SetGoState(GO_STATE_ACTIVE); + instance->SetData(DATA_STATUE_ACTIVATE, go->GetEntry()); + return true; } - return true; - } - return false; - } + return false; + } }; void AddSC_instance_gundrak() |