diff options
author | Supabad <none@none> | 2010-10-11 01:17:16 +0200 |
---|---|---|
committer | Supabad <none@none> | 2010-10-11 01:17:16 +0200 |
commit | 8f9660fa0744ba9e821cae42c5b42b697bbe9911 (patch) | |
tree | c0a181649e9d62f30853cba964cc4b2f62a9515d | |
parent | 40e3ca43664244d0151e6916c48208f9310e13a4 (diff) |
Scripts/Ulduar: Boss Razorscale
- Update Boss Razorscale thanks to PrinceCreed
- harpoon event needs work
- apply trinity coding standard to patch
- change minor typo in Boss Ignis Thanks to Lopin
--HG--
branch : trunk
-rw-r--r-- | sql/scripts/world_script_texts.sql | 12 | ||||
-rw-r--r-- | sql/scripts/world_scripts_full.sql | 6 | ||||
-rw-r--r-- | sql/updates/10208_world_script_name.sql | 8 | ||||
-rw-r--r-- | sql/updates/10208_world_script_texts.sql | 16 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp | 919 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp | 105 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h | 3 |
8 files changed, 807 insertions, 264 deletions
diff --git a/sql/scripts/world_script_texts.sql b/sql/scripts/world_script_texts.sql index 7eb2b741ebd..f2f05f73ffa 100644 --- a/sql/scripts/world_script_texts.sql +++ b/sql/scripts/world_script_texts.sql @@ -2523,8 +2523,16 @@ INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1` (33350,-1603259,'Combat matrix enhanced. Behold wonderous rapidity!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15630,1,0,0,'Mimiron SAY_YS_HELP'), -- Razorscale encounter - (33210,-1603260,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15647,1,0,0,'Exp. Commander SAY_INTRO'), - (33210,-1603261,'',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15648,1,0,0,'Exp. Commander SAY_GROUND'), + + (33186,-1603268, 'Razorscale grounded permanently!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,2,0,0, 'EMOTE_PERMA'), + (33186,-1603267, 'Razorscale takes a deep breath...', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,2,0,0, 'EMOTE_BREATH'), + (33287,-1603266, 'Harpoon Turret is ready for use!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,2,0,0, 'EMOTE_HARPOON'), + (33287,-1603265, 'Fires out! Let''s rebuild those turrets!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_TURRETS'), + (33287,-1603264, 'Ready to move out, keep those dwarves off of our backs!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_AGGRO_3'), + (33287,-1603263, 'Be on the lookout! Mole machines will be surfacing soon with those nasty Iron dwarves aboard!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_AGGRO_2'), + (33287,-1603262, 'Give us a moment to prepare to build the turrets.', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_AGGRO_1'), + (33210,-1603260, 'Welcome, champions! All of our attempts at grounding her have failed. We could use a hand in bring her down with these harpoon guns.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15647,0,0,0,'Exp. Commander SAY_INTRO'), + (33210,-1603261, 'Move! Quickly! She won''t remain grounded for long.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15648,1,0,0,'Exp. Commander SAY_GROUND'), -- Thorim (33413,-1603270,'Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,15733,1,0,0,'Thorim SAY_AGGRO_1'), diff --git a/sql/scripts/world_scripts_full.sql b/sql/scripts/world_scripts_full.sql index 49be107aaa5..5b2cf232c50 100644 --- a/sql/scripts/world_scripts_full.sql +++ b/sql/scripts/world_scripts_full.sql @@ -1493,6 +1493,12 @@ UPDATE `creature_template` SET `ScriptName`='boss_ignis' WHERE `entry`=33118; UPDATE `creature_template` SET `ScriptName`='npc_iron_construct' WHERE `entry`=33121; UPDATE `creature_template` SET `ScriptName`='npc_scorch_ground' WHERE `entry`=33221; UPDATE `creature_template` SET `ScriptName`='boss_razorscale' WHERE `entry`=33186; +UPDATE `creature_template` SET `ScriptName`='npc_devouring_flame' WHERE `entry`=34188; +UPDATE `creature_template` SET `ScriptName`='npc_mole_machine_trigger' WHERE `entry`=33245; +UPDATE `creature_template` SET `ScriptName`='npc_expedition_commander' WHERE `entry`=33210; +UPDATE `creature_template` SET `ScriptName`='npc_darkrune_guardian' WHERE `entry`=33388; +UPDATE `creature_template` SET `ScriptName`='npc_darkrune_sentinel' WHERE `entry`=33846; +UPDATE `creature_template` SET `ScriptName`='npc_darkrune_watcher' WHERE `entry`=33453; UPDATE `creature_template` SET `ScriptName`='boss_xt002' WHERE `entry`=33293; UPDATE `creature_template` SET `ScriptName`='mob_xt002_heart' WHERE `entry`=33329; UPDATE `creature_template` SET `ScriptName`='mob_scrapbot' WHERE `entry`=33343; diff --git a/sql/updates/10208_world_script_name.sql b/sql/updates/10208_world_script_name.sql new file mode 100644 index 00000000000..7487de2d439 --- /dev/null +++ b/sql/updates/10208_world_script_name.sql @@ -0,0 +1,8 @@ +-- Razorscale +UPDATE `creature_template` SET `ScriptName` = 'boss_razorscale' WHERE `entry`=33186; +UPDATE `creature_template` SET `ScriptName` = 'npc_devouring_flame' WHERE `entry`=34188; +UPDATE `creature_template` SET `ScriptName` = 'npc_mole_machine_trigger' WHERE `entry`=33245; +UPDATE `creature_template` SET `ScriptName` = 'npc_expedition_commander' WHERE `entry`=33210; +UPDATE `creature_template` SET `ScriptName` = 'npc_darkrune_guardian' WHERE `entry`=33388; +UPDATE `creature_template` SET `ScriptName` = 'npc_darkrune_sentinel' WHERE `entry`=33846; +UPDATE `creature_template` SET `ScriptName` = 'npc_darkrune_watcher' WHERE `entry`=33453; diff --git a/sql/updates/10208_world_script_texts.sql b/sql/updates/10208_world_script_texts.sql new file mode 100644 index 00000000000..83041d0dbe7 --- /dev/null +++ b/sql/updates/10208_world_script_texts.sql @@ -0,0 +1,16 @@ +DELETE FROM `script_texts` WHERE `entry` IN (-1603268,-1603267,-1603266); +INSERT INTO `script_texts` (`npc_entry`, `entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`) VALUES +(33186, -1603268, 'Razorscale grounded permanently!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,2,0,0, 'EMOTE_PERMA'), +(33186, -1603267, 'Razorscale takes a deep breath...', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,2,0,0, 'EMOTE_BREATH'), +(33287, -1603266, 'Harpoon Turret is ready for use!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,2,0,0, 'EMOTE_HARPOON'); + +DELETE FROM `script_texts` WHERE `entry` IN (-1603265,-1603264,-1603263,-1603262); +INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +(33287, -1603265, 'Fires out! Let''s rebuild those turrets!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_TURRETS'), +(33287, -1603264, 'Ready to move out, keep those dwarves off of our backs!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_AGGRO_3'), +(33287, -1603263, 'Be on the lookout! Mole machines will be surfacing soon with those nasty Iron dwarves aboard!', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_AGGRO_2'), +(33287, -1603262, 'Give us a moment to prepare to build the turrets.', NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,0, 'SAY_AGGRO_1'); + +-- Razorscale emotes +UPDATE `script_texts` SET `content_default` = "Welcome, champions! All of our attempts at grounding her have failed. We could use a hand in bring her down with these harpoon guns.", `type`=0 WHERE `entry`=-1603260; +UPDATE `script_texts` SET `content_default` = "Move! Quickly! She won't remain grounded for long.", `type`=1 WHERE `entry`=-1603261; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp index e9c09d03b21..a51f72e6964 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp @@ -133,7 +133,7 @@ public: std::vector<Creature*> triggers; bool Shattered; - uint32 SlagPotGUID; + uint64 SlagPotGUID; uint32 EncounterTime; uint32 ConstructTimer; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp index c4de6b47d22..da17b613336 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp @@ -15,36 +15,141 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +//TODO: Harpoon event is automated needs to be checked + /* ScriptData -SDName: razorscale -SDAuthor: MaXiMiUS -SD%Complete: 65 +SDName: Razorscale +SDAuthor: PrinceCreed +SD%Complete: 100 EndScriptData */ #include "ScriptPCH.h" #include "ulduar.h" -//not in db -#define SAY_AGGRO -2000000 -#define SAY_KILL -2000001 -#define SAY_PHASE_2_TRANS -2000002 -#define SAY_PHASE_3_TRANS -2000003 -#define EMOTE_BREATH -2000004 +enum Says +{ + SAY_GREET = -1603260, + SAY_GROUND_PHASE = -1603261, + SAY_AGGRO_1 = -1603262, + SAY_AGGRO_2 = -1603263, + SAY_AGGRO_3 = -1603264, + SAY_TURRETS = -1603265, + EMOTE_HARPOON = -1603266, + EMOTE_BREATH = -1603267, + EMOTE_PERMA = -1603268, +}; + +#define GOSSIP_ITEM_1 "Activate Harpoones!" enum Spells { - SPELL_FLAMEBUFFET = 64016, - SPELL_FIREBALL = 62796, + SPELL_FLAMEBUFFET = 64016, + SPELL_FIREBALL = 62796, + SPELL_FLAME_GROUND = 64709, + SPELL_WINGBUFFET = 62666, + SPELL_FLAMEBREATH = 63317, + SPELL_FUSEARMOR = 64771, + SPELL_DEVOURING_FLAME = 63236, + SPELL_HARPOON = 54933, + SPELL_FLAMED = 62696, + SPELL_STUN = 9032, + SPELL_BERSERK = 47008 +}; + +const Position PosHarpoon[4] = +{ +{594.317f, -136.953f, 391.517f, 4.544f}, +{577.449f, -136.953f, 391.517f, 4.877f}, +{607.726f, -146.857f, 391.517f, 4.041f}, +{561.449f, -146.857f, 391.517f, 5.426f} +}; + +const Position PosEngSpawn = {591.951f, -95.968f, 391.517f, 0}; + +const Position PosEngRepair[4] = +{ +{590.442f, -130.550f, 391.517f, 4.789f}, +{574.850f, -133.687f, 391.517f, 4.252f}, +{606.567f, -143.369f, 391.517f, 4.434f}, +{560.609f, -142.967f, 391.517f, 5.074f} +}; - SPELL_WINGBUFFET = 62666, - SPELL_FLAMEBREATH = 63317, - SPELL_FUSEARMOR = 64771, - SPELL_DEVOURINGFLAME = 63014 +const Position PosDefSpawn[4] = +{ +{600.75f, -104.850f, 391.517f, 0}, +{596.38f, -110.262f, 391.517f, 0}, +{566.47f, -103.633f, 391.517f, 0}, +{570.41f, -108.791f, 391.517f, 0} }; +const Position PosDefCombat[4] = +{ +{614.975f, -155.138f, 391.517f, 4.154f}, +{609.814f, -204.968f, 391.517f, 5.385f}, +{563.531f, -201.557f, 391.517f, 4.108f}, +{560.231f, -153.677f, 391.517f, 5.403f} +}; + +const Position RazorFlight = {588.050f, -251.191f, 470.536f, 1.605f}; +const Position RazorGround = {586.966f, -175.534f, 391.517f, 1.692f}; + enum Mobs { - NPC_DARK_RUNE_SENTINEL = 33846 + RAZORSCALE = 33186,// ?? why not use instance? + NPC_DARK_RUNE_GUARDIAN = 33388, + NPC_DARK_RUNE_SENTINEL = 33846, + NPC_DARK_RUNE_WATCHER = 33453, + MOLE_MACHINE_TRIGGER = 33245, + NPC_COMMANDER = 33210, + NPC_ENGINEER = 33287, + NPC_DEFENDER = 33816, + NPC_HARPOON = 33184, + GOB_MOLE_MACHINE = 194316 +}; + +enum DarkRuneSpells +{ + // Dark Rune Watcher + SPELL_CHAIN_LIGHTNING = 64758, + SPELL_LIGHTNING_BOLT = 63809, + + // Dark Rune Guardian + SPELL_STORMSTRIKE = 64757, + + // Dark Rune Sentinel + SPELL_BATTLE_SHOUT = 46763, + SPELL_HEROIC_STRIKE = 45026, + SPELL_WHIRLWIND = 63807, +}; + +#define ACHIEVEMENT_QUICK_SHAVE RAID_MODE(2919, 2921) + +#define ACTION_EVENT_START 1 +#define ACTION_GROUND_PHASE 2 + +enum Phases +{ + PHASE_NULL, + PHASE_PERMAGROUND, + PHASE_GROUND, + PHASE_FLIGHT +}; + +enum Events +{ + EVENT_NONE, + EVENT_BERSERK, + EVENT_BREATH, + EVENT_BUFFET, + EVENT_HARPOON, + EVENT_FIREBALL, + EVENT_FLIGHT, + EVENT_DEVOURING, + EVENT_FLAME, + EVENT_LAND, + EVENT_GROUND, + EVENT_FUSE, + EVENT_SUMMON }; class boss_razorscale : public CreatureScript @@ -59,59 +164,58 @@ public: struct boss_razorscaleAI : public BossAI { - boss_razorscaleAI(Creature *pCreature) : BossAI(pCreature, TYPE_RAZORSCALE) {} + boss_razorscaleAI(Creature *pCreature) : BossAI(pCreature, TYPE_RAZORSCALE), phase(PHASE_NULL) + { + // Do not let Razorscale be affected by Battle Shout buff + me->ApplySpellImmune(0, IMMUNITY_ID, (SPELL_BATTLE_SHOUT), true); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); + me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip + } - uint8 Phase; + Phases phase; - uint32 FlameBreathTimer; - uint32 FuseArmorTimer; - uint32 DevouringFlameTimer; - uint32 FlameBuffetTimer; - uint32 SummonAddsTimer; - uint32 WingBuffetTimer; - uint32 FireballTimer; - //uint32 StunTimer; - //uint32 CastSpellsTimer; + uint32 EnrageTimer; + uint32 FlyCount; - bool InitialSpawn; - bool IsFlying; + Creature* Harpoon[4]; + bool PermaGround; + bool Enraged; void Reset() { - Phase = 1; - - FlyPhase(Phase, 0); - - FlameBreathTimer = 20000; - DevouringFlameTimer = 2000; - FuseArmorTimer = 15000; - FlameBuffetTimer = 3000; - SummonAddsTimer = 45000; - WingBuffetTimer = 17000; - FireballTimer = 18000; - //StunTimer = 30000; - //CastSpellsTimer = 0; - - InitialSpawn = true; - IsFlying = true; - - me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - me->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); + _Reset(); + me->SetFlying(true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_PASSIVE); + PermaGround = false; } void EnterCombat(Unit* /*who*/) { - DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); + _EnterCombat(); + for (uint8 n = 0; n < RAID_MODE(2,4); ++n) + Harpoon[n] = me->SummonCreature(NPC_HARPOON, PosHarpoon[n], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 0); + me->SetSpeed(MOVE_FLIGHT, 3.0f, true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_PASSIVE); + phase = PHASE_GROUND; + events.SetPhase(PHASE_GROUND); + FlyCount = 0; + EnrageTimer = 15*60*1000; // Enrage in 15 min + Enraged = false; + events.ScheduleEvent(EVENT_FLIGHT, 0, 0, PHASE_GROUND); } void JustDied(Unit* /*Killer*/) { - } + _JustDied(); - void KilledUnit(Unit * /*victim*/) - { - DoScriptText(SAY_KILL, me); + if (instance) + { + // A Quick Shave + if (FlyCount <= 2) + instance->DoCompleteAchievement(ACHIEVEMENT_QUICK_SHAVE); + } } void UpdateAI(const uint32 diff) @@ -119,209 +223,594 @@ public: if (!UpdateVictim()) return; - if (me->GetPositionY() > -60 || me->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles. - { - me->RemoveAllAuras(); - me->DeleteThreatList(); - me->CombatStop(false); - me->GetMotionMaster()->MoveTargetedHome(); - } - - // Victim is not controlled by a player (should never happen) if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()) me->Kill(me->getVictim()); - if (HealthBelowPct(99) && Phase == 1) // TODO: Only land (exit Phase 1) if brought down with harpoon guns! This is important! + events.Update(diff); + + if (HealthBelowPct(50) && !PermaGround) + EnterPermaGround(); + + if (EnrageTimer <= diff && !Enraged) { - Phase = 2; - DoScriptText(SAY_PHASE_2_TRANS, me); // Audio: "Move quickly! She won't remain grounded for long!" + DoCast(me, SPELL_BERSERK); + Enraged = true; } + else EnrageTimer -= diff; - if (HealthBelowPct(33) && Phase == 2) // Health under 33%, Razorscale can't fly anymore. + if (phase == PHASE_GROUND) { - Phase = 3; - DoScriptText(SAY_PHASE_3_TRANS, me); // "Razorscale lands permanently!" - // TODO: Cast Devouring Flame on all harpoon guns simultaneously, briefly after Phase 3 starts (lasts until the harpoon guns are destroyed) + while (uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) + { + case EVENT_FLIGHT: + phase = PHASE_FLIGHT; + events.SetPhase(PHASE_FLIGHT); + me->SetFlying(true); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->RemoveAllAuras(); + me->GetMotionMaster()->MovePoint(0,RazorFlight); + events.ScheduleEvent(EVENT_FIREBALL, 7000, 0, PHASE_FLIGHT); + events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT); + events.ScheduleEvent(EVENT_SUMMON, 5000, 0, PHASE_FLIGHT); + events.ScheduleEvent(EVENT_GROUND, 75000, 0, PHASE_FLIGHT); + ++FlyCount; + return; + case EVENT_LAND: + me->SetFlying(false); + me->NearTeleportTo(586.966f, -175.534f, 391.517f, 1.692f); + DoCast(me, SPELL_STUN, true); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (Creature *pCommander = me->GetCreature(*me, instance->GetData64(DATA_EXP_COMMANDER))) + pCommander->AI()->DoAction(ACTION_GROUND_PHASE); + events.ScheduleEvent(EVENT_HARPOON, 0, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_BREATH, 30000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_BUFFET, 33000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_FLIGHT, 35000, 0, PHASE_GROUND); + return; + case EVENT_HARPOON: + for (uint8 n = 0; n < RAID_MODE(2,4); ++n) + if (Harpoon[n]) + Harpoon[n]->CastSpell(me, SPELL_HARPOON, true); + events.ScheduleEvent(EVENT_HARPOON, 1500, 0, PHASE_GROUND); + return; + case EVENT_BREATH: + me->MonsterTextEmote(EMOTE_BREATH, 0, true); + DoCastAOE(SPELL_FLAMEBREATH); + events.CancelEvent(EVENT_HARPOON); + events.CancelEvent(EVENT_BREATH); + return; + case EVENT_BUFFET: + DoCastAOE(SPELL_WINGBUFFET); + for (uint8 n = 0; n < RAID_MODE(2,4); ++n) + if (Harpoon[n]) + Harpoon[n]->CastSpell(Harpoon[n], SPELL_FLAMED, true); + events.CancelEvent(EVENT_BUFFET); + return; + } + } } + if (phase == PHASE_PERMAGROUND) + { + while (uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) + { + case EVENT_FLAME: + DoCastAOE(SPELL_FLAMEBUFFET); + events.ScheduleEvent(EVENT_FLAME, 10000, 0, PHASE_PERMAGROUND); + return; + case EVENT_BREATH: + me->MonsterTextEmote(EMOTE_BREATH, 0, true); + DoCastVictim(SPELL_FLAMEBREATH); + events.ScheduleEvent(EVENT_BREATH, 20000, 0, PHASE_PERMAGROUND); + return; + case EVENT_FIREBALL: + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) + DoCast(pTarget, SPELL_FIREBALL); + events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND); + return; + case EVENT_DEVOURING: + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) + DoCast(pTarget, SPELL_DEVOURING_FLAME); + events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_PERMAGROUND); + return; + case EVENT_BUFFET: + DoCastAOE(SPELL_WINGBUFFET); + events.CancelEvent(EVENT_BUFFET); + return; + case EVENT_FUSE: + DoCastVictim(SPELL_FUSEARMOR); + events.ScheduleEvent(EVENT_FUSE, 10000, 0, PHASE_PERMAGROUND); + return; + } + } - /* - if (Phase == 2 && CastSpellsTimer > 0) // 5 seconds of spell casting, after stun breaks, during Phase 2 + DoMeleeAttackIfReady(); + } + else { - if (CastSpellsTimer <= diff) // 5 seconds are up - Phase = 1; // Return to phase 1 - else - CastSpellsTimer -= diff; - }*/ + if (uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) + { + case EVENT_GROUND: + phase = PHASE_GROUND; + events.SetPhase(PHASE_GROUND); + if (Harpoon[0]) + Harpoon[0]->MonsterTextEmote(EMOTE_HARPOON, 0, true); + me->GetMotionMaster()->MovePoint(0,RazorGround); + events.ScheduleEvent(EVENT_LAND, 5500, 0, PHASE_GROUND); + return; + case EVENT_FIREBALL: + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) + DoCast(pTarget, SPELL_FIREBALL); + events.ScheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_FLIGHT); + return; + case EVENT_DEVOURING: + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) + DoCast(pTarget, SPELL_DEVOURING_FLAME); + events.ScheduleEvent(EVENT_DEVOURING, 10000, 0, PHASE_FLIGHT); + return; + case EVENT_SUMMON: + SummonAdds(); + events.ScheduleEvent(EVENT_SUMMON, 45000, 0, PHASE_FLIGHT); + return; + } + } + } + } + + void EnterPermaGround() + { + me->MonsterTextEmote(EMOTE_PERMA, 0, true); + phase = PHASE_PERMAGROUND; + events.SetPhase(PHASE_PERMAGROUND); + me->SetFlying(false); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveAurasDueToSpell(SPELL_STUN); + me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + PermaGround = true; + DoCastAOE(SPELL_FLAMEBREATH); + events.ScheduleEvent(EVENT_FLAME, 15000, 0, PHASE_PERMAGROUND); + events.RescheduleEvent(EVENT_DEVOURING, 15000, 0, PHASE_PERMAGROUND); + events.RescheduleEvent(EVENT_BREATH, 20000, 0, PHASE_PERMAGROUND); + events.RescheduleEvent(EVENT_FIREBALL, 3000, 0, PHASE_PERMAGROUND); + events.RescheduleEvent(EVENT_DEVOURING, 6000, 0, PHASE_PERMAGROUND); + events.RescheduleEvent(EVENT_BUFFET, 2500, 0, PHASE_PERMAGROUND); + events.RescheduleEvent(EVENT_FUSE, 5000, 0, PHASE_PERMAGROUND); + } - FlyPhase(Phase, diff); + void SummonAdds() + { + // Adds will come in waves from mole machines. One mole can spawn a Dark Rune Watcher + // with 1-2 Guardians, or a lone Sentinel. Up to 4 mole machines can spawn adds at any given time. + uint8 random = urand(1,4); + for (uint8 i = 0; i < random; ++i) + { + float x = irand(540.0f, 640.0f); // Safe range is between 500 and 650 + float y = irand(-230.0f, -195.0f); // Safe range is between -235 and -145 + float z = 391.5f; // Ground level + me->SummonCreature(MOLE_MACHINE_TRIGGER, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 10000); + } + } - if (Phase >= 2) // Ground Phase (Phase 3 = permanent ground phase) + void DoAction(const int32 action) + { + switch(action) { - if (FuseArmorTimer <= diff) - { - DoCastVictim(SPELL_FUSEARMOR); - FuseArmorTimer = 10000; - } else FuseArmorTimer -= diff; + case ACTION_EVENT_START: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + DoZoneInCombat(); + break; + } + } + }; - if (WingBuffetTimer <= diff) - { - DoCast(SPELL_WINGBUFFET); - WingBuffetTimer = urand(7000,14000); - } else WingBuffetTimer -= diff; +}; - if (FireballTimer <= diff) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) - { - me->SetInFront(pTarget); - DoCast(pTarget, SPELL_FIREBALL); - } +/*==================================================================================== +====================================================================================*/ - FireballTimer = 18000; - } else FireballTimer -= diff; +class npc_expedition_commander : public CreatureScript +{ +public: + npc_expedition_commander() : CreatureScript("npc_expedition_commander") { } - if (FlameBreathTimer <= diff) - { - DoScriptText(EMOTE_BREATH, me); // TODO: "Razorscale takes a deep breath..." - DoCastVictim(SPELL_FLAMEBREATH); - FlameBreathTimer = 15000; - WingBuffetTimer = 0; - } else FlameBreathTimer -= diff; + bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction) + { + pPlayer->PlayerTalkClass->ClearMenus(); + InstanceScript* pInstance = pCreature->GetInstanceScript(); + switch(uiAction) + { + case GOSSIP_ACTION_INFO_DEF: + if (pPlayer) + pPlayer->CLOSE_GOSSIP_MENU(); + CAST_AI(npc_expedition_commanderAI, (pCreature->AI()))->uiPhase = 1; + break; + } + return true; + } - if (Phase == 3) + bool OnGossipHello(Player* pPlayer, Creature* pCreature) + { + InstanceScript* pInstance = pCreature->GetInstanceScript(); + if (pInstance && pInstance->GetBossState(TYPE_RAZORSCALE) == NOT_STARTED && pPlayer) + { + pPlayer->PrepareGossipMenu(pCreature); + + pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT,GOSSIP_ITEM_1,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF); + pPlayer->SEND_GOSSIP_MENU(13853, pCreature->GetGUID()); + } + else pPlayer->SEND_GOSSIP_MENU(13910, pCreature->GetGUID()); + + return true; + } + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_expedition_commanderAI (pCreature); + } + + struct npc_expedition_commanderAI : public ScriptedAI + { + npc_expedition_commanderAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me) + { + pInstance = pCreature->GetInstanceScript(); + greet = false; + } + + InstanceScript* pInstance; + SummonList summons; + + bool greet; + uint32 uiTimer; + uint8 uiPhase; + Creature* engineer[4]; + Creature* defender[4]; + + void Reset() + { + uiTimer = 0; + uiPhase = 0; + greet = false; + } + + void MoveInLineOfSight(Unit *who) + { + if (!greet && me->IsWithinDistInMap(who, 10.0f) && who->GetTypeId() == TYPEID_PLAYER) + { + DoScriptText(SAY_GREET, me); + greet = true; + } + } + + void JustSummoned(Creature *summon) + { + summons.Summon(summon); + } + + void DoAction(const int32 action) + { + switch(action) + { + case ACTION_GROUND_PHASE: + DoScriptText(SAY_GROUND_PHASE, me); + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + ScriptedAI::UpdateAI(uiDiff); + if (uiTimer <= uiDiff) + { + switch(uiPhase) { - if (FlameBuffetTimer <= diff) - { - DoScriptText(EMOTE_BREATH, me); - std::list<Unit*> pTargets; - SelectTargetList(pTargets, RAID_MODE(3,9), SELECT_TARGET_RANDOM, 100, true); - uint8 i = 0; - for (std::list<Unit*>::const_iterator itr = pTargets.begin(); itr != pTargets.end();) + case 1: + pInstance->SetBossState(TYPE_RAZORSCALE, IN_PROGRESS); + summons.DespawnAll(); + uiTimer = 1000; + uiPhase = 2; + break; + case 2: + for (uint8 n = 0; n < RAID_MODE(2,4); ++n) + { + engineer[n] = me->SummonCreature(NPC_ENGINEER, PosEngSpawn, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + engineer[n]->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); + engineer[n]->SetSpeed(MOVE_RUN, 0.5f); + engineer[n]->SetHomePosition(PosEngRepair[n]); + engineer[n]->GetMotionMaster()->MoveTargetedHome(); + } + engineer[0]->MonsterYell(SAY_AGGRO_3, LANG_UNIVERSAL, 0); + uiPhase = 3; + uiTimer = 14000; + break; + case 3: + for (uint8 n = 0; n < 4; ++n) { - if (me->HasInArc(M_PI, *itr)) - { - DoCast(*itr, SPELL_FLAMEBUFFET, true); - ++i; - } - if (++itr == pTargets.end() || i == RAID_MODE(3,9)) - { - AttackStart(*--itr); // seems to attack targets randomly during perma-ground phase.. - break; - } + defender[n] = me->SummonCreature(NPC_DEFENDER, PosDefSpawn[n], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + defender[n] ->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); + defender[n] ->SetHomePosition(PosDefCombat[n]); + defender[n] ->GetMotionMaster()->MoveTargetedHome(); } - FlameBuffetTimer = 25000; - } else FlameBuffetTimer -= diff; + uiPhase = 4; + break; + case 4: + for (uint8 n = 0; n < RAID_MODE(2,4); ++n) + engineer[n]->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USESTANDING); + for (uint8 n = 0; n < 4; ++n) + defender[n]->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); + me->MonsterYell(SAY_AGGRO_2, LANG_UNIVERSAL, 0); + uiTimer = 16000; + uiPhase = 5; + break; + case 5: + if (Creature *pRazorscale = me->GetCreature(*me, pInstance->GetData64(TYPE_RAZORSCALE))) + pRazorscale->AI()->DoAction(ACTION_EVENT_START); + engineer[0]->MonsterYell(SAY_AGGRO_1, LANG_UNIVERSAL, 0); + uiPhase = 6; + break; } - - DoMeleeAttackIfReady(); } - else if (Phase == 1) //Flying Phase - { - if (InitialSpawn) - SummonAdds(); + else uiTimer -= uiDiff; + } + }; - InitialSpawn = false; +}; - if (FireballTimer <= diff) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) - { - me->SetInFront(pTarget); - DoCast(pTarget, SPELL_FIREBALL); - } - FireballTimer = 18000; - } else FireballTimer -= diff; +class npc_mole_machine_trigger : public CreatureScript +{ +public: + npc_mole_machine_trigger() : CreatureScript("npc_mole_machine_trigger") { } - if (DevouringFlameTimer <= diff) - { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) - { - me->SetInFront(pTarget); - DoCast(pTarget, SPELL_DEVOURINGFLAME); - } + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_mole_machine_triggerAI (pCreature); + } + + struct npc_mole_machine_triggerAI : public Scripted_NoMovementAI + { + npc_mole_machine_triggerAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); + me->SetVisibility(VISIBILITY_OFF); + } - DevouringFlameTimer = 10000; - } else DevouringFlameTimer -= diff; + GameObject* MoleMachine; + uint32 SummonTimer; - if (SummonAddsTimer <= diff) - SummonAdds(); - else SummonAddsTimer -= diff; - } + void Reset() + { + if (MoleMachine = me->SummonGameObject(GOB_MOLE_MACHINE,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),urand(0,6),0,0,0,0,300)) + MoleMachine->SetGoState(GO_STATE_ACTIVE); + SummonTimer = 6000; } - void SummonAdds() + void UpdateAI(const uint32 uiDiff) { - // TODO: Adds will come in waves from mole machines. One mole can spawn a Dark Rune Watcher - // with 1-2 Guardians, or a lone Sentinel. Up to 4 mole machines can spawn adds at any given time. - uint8 random = urand(1,4); - for (uint8 i = 0; i < random; ++i) + if (!UpdateVictim()) + return; + + if (SummonTimer <= uiDiff) { - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) + float x = me->GetPositionX(); + float y = me->GetPositionY(); + float z = me->GetPositionZ(); + + // One mole can spawn a Dark Rune Watcher with 1-2 Guardians, or a lone Sentinel + if (!(rand()%2)) { - float x = std::max(500.0f, std::min(650.0f, pTarget->GetPositionX() + irand(-20,20))); // Safe range is between 500 and 650 - float y = std::max(-235.0f, std::min(-145.0f, pTarget->GetPositionY() + irand(-20,20))); // Safe range is between -235 and -145 - float z = me->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT); // Ground level - // TODO: Spawn drillers, then spawn adds 5 seconds later - if (Creature *pAdd = me->SummonCreature(NPC_DARK_RUNE_SENTINEL, x, y, z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000)) - pAdd->AI()->AttackStart(pTarget); + me->SummonCreature(NPC_DARK_RUNE_WATCHER, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000); + uint8 random = urand(1,2); + for (uint8 i = 0; i < random; ++i) + me->SummonCreature(NPC_DARK_RUNE_GUARDIAN, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000); } + else me->SummonCreature(NPC_DARK_RUNE_SENTINEL, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000); + + SummonTimer = 15000; } - SummonAddsTimer = 45000; + else SummonTimer -= uiDiff; } - void FlyPhase(uint8 Phase, const uint32 /*diff*/) + void JustSummoned(Creature *summon) { - const float x = 587.54f; - const float y = -174.92f; - const float GroundLevel = me->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT); - const float FlightHeight = GroundLevel + 4.0f; // TODO: Fly out of range of attacks (442 is sufficient height for this), minus ~(10*number of harpoon gun chains attached to Razorscale) + summon->AI()->DoZoneInCombat(); + } + }; - if (Phase == 1) // Always flying during Phase 1 - IsFlying = true; +}; - me->SetFlying(IsFlying); - me->SendMovementFlagUpdate(); - me->SetSpeed(MOVE_WALK, IsFlying ? 7.0f : 2.5f, IsFlying); - if (Phase == 1) // Flying Phase +class npc_devouring_flame : public CreatureScript +{ +public: + npc_devouring_flame() : CreatureScript("npc_devouring_flame") { } + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_devouring_flameAI (pCreature); + } + + struct npc_devouring_flameAI : public Scripted_NoMovementAI + { + npc_devouring_flameAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); + me->SetDisplayId(11686); + } + + void Reset() + { + DoCast(me, SPELL_FLAME_GROUND); + } + }; + +}; + + +class npc_darkrune_watcher : public CreatureScript +{ +public: + npc_darkrune_watcher() : CreatureScript("npc_darkrune_watcher") { } + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_darkrune_watcherAI (pCreature); + } + + struct npc_darkrune_watcherAI : public ScriptedAI + { + npc_darkrune_watcherAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceScript(); + } + + InstanceScript *pInstance; + + uint32 ChainTimer; + uint32 LightTimer; + + void Reset() + { + ChainTimer = urand(10000, 15000); + LightTimer = urand(1000, 3000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (ChainTimer <= uiDiff) { - if (me->GetPositionZ() > FlightHeight) // Correct height, stop moving - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - else // Incorrect height - { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - me->GetMotionMaster()->MovePoint(0, x, y, FlightHeight + 0.5f); // Fly to slightly above (x, y, FlightHeight) - } + DoCastVictim(SPELL_CHAIN_LIGHTNING); + ChainTimer = urand(10000, 15000); } - else // Ground Phases + else ChainTimer -= uiDiff; + + if (LightTimer <= uiDiff) + { + DoCastVictim(SPELL_LIGHTNING_BOLT); + LightTimer = urand(5000, 7000); + } + else LightTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + }; + +}; + + +class npc_darkrune_guardian : public CreatureScript +{ +public: + npc_darkrune_guardian() : CreatureScript("npc_darkrune_guardian") { } + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_darkrune_guardianAI (pCreature); + } + + struct npc_darkrune_guardianAI : public ScriptedAI + { + npc_darkrune_guardianAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceScript(); + } + + InstanceScript *pInstance; + + uint32 StormTimer; + + void Reset() + { + StormTimer = urand(3000, 6000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (StormTimer <= uiDiff) + { + DoCastVictim(SPELL_STORMSTRIKE); + StormTimer = urand(4000, 8000); + } + else StormTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + }; + +}; + + +class npc_darkrune_sentinel : public CreatureScript +{ +public: + npc_darkrune_sentinel() : CreatureScript("npc_darkrune_sentinel") { } + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_darkrune_sentinelAI (pCreature); + } + + struct npc_darkrune_sentinelAI : public ScriptedAI + { + npc_darkrune_sentinelAI(Creature *pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceScript(); + } + + InstanceScript *pInstance; + + uint32 HeroicTimer; + uint32 WhirlTimer; + uint32 ShoutTimer; + + void Reset() + { + HeroicTimer = urand(4000, 8000); + WhirlTimer = urand(20000, 25000); + ShoutTimer = urand(15000, 30000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (HeroicTimer <= uiDiff) + { + DoCastVictim(SPELL_HEROIC_STRIKE); + HeroicTimer = urand(4000, 6000); + } + else HeroicTimer -= uiDiff; + + if (WhirlTimer <= uiDiff) { - const float CurrentGroundLevel = me->GetBaseMap()->GetHeight(me->GetPositionX(), me->GetPositionY(), MAX_HEIGHT); - //if (StunTimer == 30000) // Only fly around if not stunned. - //{ - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - if (IsFlying && me->GetPositionZ() > CurrentGroundLevel) // Fly towards the ground - me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), CurrentGroundLevel); - // TODO: Swoop up just before landing - else - IsFlying = false; // Landed, no longer flying - //} - - //if (!IsFlying &&Phase == 2 && CastSpellsTimer == 0 && StunTimer >= diff) // No longer flying, non-permanent ground phase, and not casting spells - //{ - // TODO: Add stun here. 30 second stun after Razorscale is grounded by harpoon guns - //StunTimer -= diff; - //} - //else if (StunTimer != 30000 && (StunTimer < 0 || Phase == 3)) // Stun is active, and needs to end. Note: Stun breaks instantly if Phase 3 starts - //{ - // TODO: Remove stun here. - //DoCast(SPELL_WINGBUFFET); // "Used in the beginning of the phase." - //WingBuffetTimer = urand(7000,14000); - //StunTimer = 30000; // Reinitialize the stun timer - //if (Phase == 2) // Non-permanent ground phase - // CastSpellsTimer = 5000; // Five seconds of casting before returning to Phase 1 - //} + DoCastVictim(SPELL_WHIRLWIND); + WhirlTimer = urand(20000, 25000); } + else WhirlTimer -= uiDiff; + + if (ShoutTimer <= uiDiff) + { + DoCast(me, SPELL_BATTLE_SHOUT); + ShoutTimer = urand(30000, 40000); + } + else ShoutTimer -= uiDiff; + + DoMeleeAttackIfReady(); } }; @@ -331,4 +820,10 @@ public: void AddSC_boss_razorscale() { new boss_razorscale(); -} + new npc_expedition_commander(); + new npc_mole_machine_trigger(); + new npc_devouring_flame(); + new npc_darkrune_watcher(); + new npc_darkrune_guardian(); + new npc_darkrune_sentinel(); +}
\ No newline at end of file diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp index af70b828f23..3b78ce16ec4 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp @@ -53,6 +53,7 @@ public: uint64 uiLeviathanGUID; uint64 uiIgnisGUID; uint64 uiRazorscaleGUID; + uint64 uiExpCommanderGUID; uint64 uiXT002GUID; uint64 uiAssemblyGUIDs[3]; uint64 uiKologarnGUID; @@ -77,6 +78,7 @@ public: SetBossNumber(MAX_ENCOUNTER); uiIgnisGUID = 0; uiRazorscaleGUID = 0; + uiExpCommanderGUID = 0; uiXT002GUID = 0; uiKologarnGUID = 0; uiAuriayaGUID = 0; @@ -123,6 +125,9 @@ public: case NPC_RAZORSCALE: uiRazorscaleGUID = pCreature->GetGUID(); break; + case NPC_EXPEDITION_COMMANDER: + uiExpCommanderGUID = pCreature->GetGUID(); + return; case NPC_XT002: uiXT002GUID = pCreature->GetGUID(); break; @@ -227,57 +232,57 @@ public: } bool SetBossState(uint32 type, EncounterState state) - { - if (!InstanceScript::SetBossState(type, state)) - return false; + { + if (!InstanceScript::SetBossState(type, state)) + return false; - switch (type) + switch (type) + { + case TYPE_LEVIATHAN: + if (state == IN_PROGRESS) { - case TYPE_LEVIATHAN: - if (state == IN_PROGRESS) - { - for (uint8 uiI = 0; uiI < 7; ++uiI) - HandleGameObject(uiLeviathanDoor[uiI],false); - } - else - { - for (uint8 uiI = 0; uiI < 7; ++uiI) - HandleGameObject(uiLeviathanDoor[uiI],true); - } - break; - case TYPE_IGNIS: - case TYPE_RAZORSCALE: - case TYPE_XT002: - case TYPE_ASSEMBLY: - case TYPE_AURIAYA: - case TYPE_MIMIRON: - case TYPE_VEZAX: - case TYPE_YOGGSARON: - break; - case TYPE_KOLOGARN: - if (state == DONE) - if (GameObject* pGO = instance->GetGameObject(uiKologarnChestGUID)) - pGO->SetRespawnTime(pGO->GetRespawnDelay()); - break; - case TYPE_HODIR: - if (state == DONE) - if (GameObject* pGO = instance->GetGameObject(uiHodirChestGUID)) - pGO->SetRespawnTime(pGO->GetRespawnDelay()); - break; - case TYPE_THORIM: - if (state == DONE) - if (GameObject* pGO = instance->GetGameObject(uiThorimChestGUID)) - pGO->SetRespawnTime(pGO->GetRespawnDelay()); - break; - case TYPE_FREYA: - if (state == DONE) - if (GameObject* pGO = instance->GetGameObject(uiFreyaChestGUID)) - pGO->SetRespawnTime(pGO->GetRespawnDelay()); - break; - } - - return true; - } + for (uint8 uiI = 0; uiI < 7; ++uiI) + HandleGameObject(uiLeviathanDoor[uiI],false); + } + else + { + for (uint8 uiI = 0; uiI < 7; ++uiI) + HandleGameObject(uiLeviathanDoor[uiI],true); + } + break; + case TYPE_IGNIS: + case TYPE_RAZORSCALE: + case TYPE_XT002: + case TYPE_ASSEMBLY: + case TYPE_AURIAYA: + case TYPE_MIMIRON: + case TYPE_VEZAX: + case TYPE_YOGGSARON: + break; + case TYPE_KOLOGARN: + if (state == DONE) + if (GameObject* pGO = instance->GetGameObject(uiKologarnChestGUID)) + pGO->SetRespawnTime(pGO->GetRespawnDelay()); + break; + case TYPE_HODIR: + if (state == DONE) + if (GameObject* pGO = instance->GetGameObject(uiHodirChestGUID)) + pGO->SetRespawnTime(pGO->GetRespawnDelay()); + break; + case TYPE_THORIM: + if (state == DONE) + if (GameObject* pGO = instance->GetGameObject(uiThorimChestGUID)) + pGO->SetRespawnTime(pGO->GetRespawnDelay()); + break; + case TYPE_FREYA: + if (state == DONE) + if (GameObject* pGO = instance->GetGameObject(uiFreyaChestGUID)) + pGO->SetRespawnTime(pGO->GetRespawnDelay()); + break; + } + + return true; + } void SetData(uint32 type, uint32 data) { @@ -317,6 +322,8 @@ public: case TYPE_YOGGSARON: return uiYoggSaronGUID; case TYPE_ALGALON: return uiAlgalonGUID; + // razorscale expedition commander + case DATA_EXP_COMMANDER: return uiExpCommanderGUID; // Assembly of Iron case DATA_STEELBREAKER: return uiAssemblyGUIDs[0]; case DATA_MOLGEIM: return uiAssemblyGUIDs[1]; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h index 8029d661b80..f890355cac3 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h @@ -43,10 +43,13 @@ enum eTypes DATA_BRUNDIR = 22, DATA_RUNEMASTER_MOLGEIM = 23, DATA_STORMCALLER_BRUNDIR = 24, + DATA_EXP_COMMANDER = 25, + NPC_LEVIATHAN = 33113, NPC_IGNIS = 33118, NPC_RAZORSCALE = 33186, + NPC_EXPEDITION_COMMANDER = 33210, NPC_XT002 = 33293, NPC_STEELBREAKER = 32867, NPC_MOLGEIM = 32927, |