diff --git a/sql/updates/world/4.3.4/2020_10_01_00_world.sql b/sql/updates/world/4.3.4/2020_10_01_00_world.sql new file mode 100644 index 00000000000..d28087450f0 --- /dev/null +++ b/sql/updates/world/4.3.4/2020_10_01_00_world.sql @@ -0,0 +1,56 @@ +-- Template Updates +UPDATE `creature_template` SET `flags_extra`= `flags_extra` | 512 WHERE `entry` IN (32857, 33694); +UPDATE `creature_template` SET `speed_run`= 1.42857 WHERE `entry`= 33694; +UPDATE `creature_template` SET `speed_run`= 1.28571 WHERE `entry`= 33692; +UPDATE `creature_template` SET `speed_walk`= 0.888888, `speed_run`= 1.58731 WHERE `entry`= 33693; +UPDATE `creature_template` SET `ScriptName`= 'npc_assembly_lightning_elemental' WHERE `entry`= 32958; +UPDATE `creature_template` SET `flags_extra`= 128 WHERE `entry`= 32866; + +DELETE FROM `creature_template_addon` WHERE `entry`= 32866; +INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES +(32866, '61877'); + +-- Spawn Groups +DELETE FROM `spawn_group_template` WHERE `groupId`= 67; +INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES +(67, 'Ulduar - Assembly of Iron', 4); + +DELETE FROM `spawn_group` WHERE `groupId`= 67; +INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES +(67, 0, 136421), -- Steelbreaker +(67, 0, 136760), -- Runemaster Molgeim +(67, 0, 136316); -- Stormcaller Brundir + +-- Correct spawn positions +UPDATE `creature` SET `position_x`= 1575.9601, `position_y`= 120.35938, `position_z`= 427.4189, `orientation`= 0.122173048555850982 WHERE `guid`= 136421; +UPDATE `creature` SET `position_x`= 1589.5435, `position_y`= 106.98612, `position_z`= 427.4189, `orientation`= 2.338741064071655273 WHERE `guid`= 136760; +UPDATE `creature` SET `position_x`= 1592.9392, `position_y`= 120.38715, `position_z`= 427.4189, `orientation`= 3.141592741012573242 WHERE `guid`= 136316; + +-- Correct Model Info Data +UPDATE `creature_model_info` SET `BoundingRadius`= 6.22840118408203125 WHERE `DisplayID`= 28344; -- Steelbreaker +UPDATE `creature_model_info` SET `CombatReach`= 0, `BoundingRadius`= 1.330477356910705566 WHERE `DisplayID`= 28324; -- Stormcaller Brundir + +-- Conditions +DELETE FROM `conditions` WHERE `SourceEntry` IN (61942, 61975, 61920, 64320) AND `SourceTypeOrReferenceId`= 13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES +(13, 1, 61942, 0, 0, 31, 0, 3, 32867, 0, 0, 0, '', 'Lightning Channel Pre-fight Visual - Target Steelbreaker'), +(13, 1, 61975, 0, 0, 31, 0, 3, 32867, 0, 0, 0, '', 'Rune of Power - Target Steelbreaker'), +(13, 7, 61920, 0, 0, 31, 0, 3, 32867, 0, 0, 0, '', 'Supercharge - Target Steelbreaker'), +(13, 7, 61920, 0, 1, 31, 0, 3, 32927, 0, 0, 0, '', 'Supercharge - Target Runemaster Molgeim'), +(13, 7, 61920, 0, 2, 31, 0, 3, 32857, 0, 0, 0, '', 'Supercharge - Target Stormcaller Brundir'), +(13, 7, 64320, 0, 0, 31, 0, 3, 32867, 0, 0, 0, '', 'Rune of Power - Target Steelbreaker'), +(13, 7, 64320, 0, 1, 31, 0, 3, 32927, 0, 0, 0, '', 'Rune of Power - Target Runemaster Molgeim'), +(13, 7, 64320, 0, 2, 31, 0, 3, 32857, 0, 0, 0, '', 'Rune of Power - Target Stormcaller Brundir'); + +-- Spell Scripts +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_assembly_supercharge', +'spell_assembly_berserk', +'spell_assembly_random_aggro_periodic', +'spell_assembly_lightning_tendrils_visual'); + +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(61920, 'spell_assembly_supercharge'), +(62535, 'spell_assembly_berserk'), +(61906, 'spell_assembly_random_aggro_periodic'), +(61884, 'spell_assembly_lightning_tendrils_visual'); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 137294efeb9..a29c88842b6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -251,7 +251,7 @@ class ActivateLivingConstellation : public BasicEvent bool Execute(uint64 execTime, uint32 /*diff*/) override { - if (!_instance || _instance->GetBossState(BOSS_ALGALON) != IN_PROGRESS) + if (!_instance || _instance->GetBossState(DATA_ALGALON) != IN_PROGRESS) return true; // delete event _owner->CastSpell((Unit*)nullptr, SPELL_TRIGGER_3_ADDS, TRIGGERED_FULL_MASK); @@ -306,7 +306,7 @@ class boss_algalon_the_observer : public CreatureScript struct boss_algalon_the_observerAI : public BossAI { - boss_algalon_the_observerAI(Creature* creature) : BossAI(creature, BOSS_ALGALON) + boss_algalon_the_observerAI(Creature* creature) : BossAI(creature, DATA_ALGALON) { Initialize(); _firstPull = true; @@ -504,7 +504,7 @@ class boss_algalon_the_observer : public CreatureScript void EnterEvadeMode(EvadeReason why) override { - instance->SetBossState(BOSS_ALGALON, FAIL); + instance->SetBossState(DATA_ALGALON, FAIL); BossAI::EnterEvadeMode(why); me->SetImmuneToPC(false); me->SetSheath(SHEATH_STATE_UNARMED); @@ -584,7 +584,7 @@ class boss_algalon_the_observer : public CreatureScript me->SetImmuneToPC(false); break; case EVENT_START_COMBAT: - instance->SetBossState(BOSS_ALGALON, IN_PROGRESS); + instance->SetBossState(DATA_ALGALON, IN_PROGRESS); break; case EVENT_INTRO_TIMER_DONE: { @@ -661,7 +661,7 @@ class boss_algalon_the_observer : public CreatureScript _hasYelled = false; break; case EVENT_OUTRO_START: - instance->SetBossState(BOSS_ALGALON, DONE); + instance->SetBossState(DATA_ALGALON, DONE); break; case EVENT_OUTRO_1: me->RemoveAllAuras(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp index d0d6e227989..3f2b8a5e868 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp @@ -15,13 +15,6 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Assembly of Iron encounter -SD%Complete: 60% -SDComment: chain lightning won't cast, supercharge don't work (auras don't stack from different casters) -SDCategory: Ulduar - Ulduar -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" #include "MotionMaster.h" @@ -30,715 +23,849 @@ EndScriptData */ #include "SpellAuras.h" #include "SpellMgr.h" #include "SpellScript.h" +#include "Spell.h" #include "TemporarySummon.h" #include "ulduar.h" -enum AssemblySpells +enum Spells { // General - SPELL_SUPERCHARGE = 61920, - SPELL_BERSERK = 47008, // Hard enrage, don't know the correct ID. - SPELL_KILL_CREDIT = 65195, // spell_dbc + SPELL_SUPERCHARGE = 61920, + SPELL_BERSERK = 62535, + SPELL_KILL_CREDIT = 65195, // Serverside spell // Steelbreaker - SPELL_HIGH_VOLTAGE = 61890, - SPELL_FUSION_PUNCH = 61903, - SPELL_STATIC_DISRUPTION = 44008, - SPELL_OVERWHELMING_POWER = 64637, - SPELL_ELECTRICAL_CHARGE = 61902, + SPELL_HIGH_VOLTAGE = 61890, + SPELL_STATIC_DISRUPTION = 44008, + SPELL_ELECTRICAL_CHARGE = 61902, // Runemaster Molgeim - SPELL_SHIELD_OF_RUNES = 62274, - SPELL_SHIELD_OF_RUNES_BUFF = 62277, - SPELL_SUMMON_RUNE_OF_POWER = 63513, - SPELL_RUNE_OF_DEATH = 62269, - SPELL_RUNE_OF_SUMMONING = 62273, // This is the spell that summons the rune - SPELL_RUNE_OF_SUMMONING_SUMMON = 62020, // Spell that summons + SPELL_RUNE_OF_POWER_PRE_FIGHT = 61975, + SPELL_RUNE_OF_POWER = 61973, + SPELL_SHIELD_OF_RUNES = 62274, + SPELL_SHIELD_OF_RUNES_BUFF = 62277, + SPELL_RUNE_OF_DEATH = 62269, + SPELL_RUNE_OF_SUMMONING = 62273, + SPELL_RUNE_OF_SUMMONING_SUMMON = 62020, // Stormcaller Brundir - SPELL_CHAIN_LIGHTNING = 61879, - SPELL_OVERLOAD = 61869, - SPELL_LIGHTNING_WHIRL = 61915, - SPELL_LIGHTNING_TENDRILS = 61887, - SPELL_LIGHTNING_TENDRILS_VISUAL = 61883, - SPELL_STORMSHIELD = 64187 + SPELL_LIGHTNING_CHANNEL_PRE_FIGHT_VISUAL = 61942, + SPELL_CHAIN_LIGHTNING = 61879, + SPELL_LIGHTNING_WHIRL = 61915, + SPELL_LIGHTNING_TENDRILS_VISUAL = 61883, + SPELL_STORMSHIELD = 64187, + SPELL_RANDOM_AGGRO_PERIODIC = 61906 }; -enum AssemblyEvents -{ - // General - EVENT_BERSERK = 1, +#define SPELL_OVERLOAD RAID_MODE(61869, 63481) +#define SPELL_LIGHTNING_TENDRILS RAID_MODE(61887, 63486) +#define SPELL_FUSION_PUNCH RAID_MODE(61903, 63493) +#define SPELL_OVERWHELMING_POWER RAID_MODE(64637, 61888) +#define SPELL_STATIC_DISRUPTION RAID_MODE(44008, 61912) +enum Events +{ // Steelbreaker - EVENT_FUSION_PUNCH = 2, - EVENT_STATIC_DISRUPTION = 3, - EVENT_OVERWHELMING_POWER = 4, + EVENT_FUSION_PUNCH = 1, + EVENT_STATIC_DISRUPTION, + EVENT_OVERWHELMING_POWER, - // Molgeim - EVENT_RUNE_OF_POWER = 5, - EVENT_SHIELD_OF_RUNES = 6, - EVENT_RUNE_OF_DEATH = 7, - EVENT_RUNE_OF_SUMMONING = 8, - EVENT_LIGHTNING_BLAST = 9, + // Runemaster Molgeim + EVENT_RUNE_OF_POWER_INTRO, + EVENT_RUNE_OF_POWER, + EVENT_SHIELD_OF_RUNES, + EVENT_RUNE_OF_DEATH, + EVENT_RUNE_OF_SUMMONING, + EVENT_LIGHTNING_BLAST, - // Brundir - EVENT_CHAIN_LIGHTNING = 10, - EVENT_OVERLOAD = 11, - EVENT_LIGHTNING_WHIRL = 12, - EVENT_LIGHTNING_TENDRILS = 13, - EVENT_FLIGHT = 14, - EVENT_ENDFLIGHT = 15, - EVENT_GROUND = 16, - EVENT_LAND = 17, - EVENT_MOVE_POSITION = 18 + // Stormcaller Brundir + EVENT_MOVE_INTRO, + EVENT_CHAIN_LIGHTNING, + EVENT_OVERLOAD, + EVENT_LIGHTNING_WHIRL, + EVENT_LIGHTNING_TENDRILS, + EVENT_FLIGHT, + EVENT_LAND }; -enum AssemblyActions +enum Phases : uint8 { - ACTION_SUPERCHARGE = 1, - ACTION_ADD_CHARGE = 2 + PHASE_INTRO = 1, + PHASE_ONE = 2, + PHASE_TWO = 3, + PHASE_THREE = 4 }; -enum AssemblyYells +enum Actions { - SAY_STEELBREAKER_AGGRO = 0, - SAY_STEELBREAKER_SLAY = 1, - SAY_STEELBREAKER_POWER = 2, - SAY_STEELBREAKER_DEATH = 3, - SAY_STEELBREAKER_ENCOUNTER_DEFEATED = 4, - SAY_STEELBREAKER_BERSERK = 5, + ACTION_SUPERCHARGE = 1, + ACTION_ADD_CHARGE, + ACTION_BERSERK_TRIGGERED +}; - SAY_MOLGEIM_AGGRO = 0, - SAY_MOLGEIM_SLAY = 1, - SAY_MOLGEIM_RUNE_DEATH = 2, - SAY_MOLGEIM_SUMMON = 3, - SAY_MOLGEIM_DEATH = 4, - SAY_MOLGEIM_ENCOUNTER_DEFEATED = 5, - SAY_MOLGEIM_BERSERK = 6, +enum Texts +{ + // Steelbreaker + SAY_STEELBREAKER_AGGRO = 0, + SAY_STEELBREAKER_SLAY = 1, + SAY_STEELBREAKER_POWER = 2, + SAY_STEELBREAKER_DEATH = 3, + SAY_STEELBREAKER_ENCOUNTER_DEFEATED = 4, + SAY_STEELBREAKER_BERSERK = 5, - SAY_BRUNDIR_AGGRO = 0, - SAY_BRUNDIR_SLAY = 1, - SAY_BRUNDIR_SPECIAL = 2, - SAY_BRUNDIR_FLIGHT = 3, - SAY_BRUNDIR_DEATH = 4, - SAY_BRUNDIR_ENCOUNTER_DEFEATED = 5, - SAY_BRUNDIR_BERSERK = 6, - EMOTE_BRUNDIR_OVERLOAD = 7 + // Runemaster Molgeim + SAY_MOLGEIM_AGGRO = 0, + SAY_MOLGEIM_SLAY = 1, + SAY_MOLGEIM_RUNE_DEATH = 2, + SAY_MOLGEIM_SUMMON = 3, + SAY_MOLGEIM_DEATH = 4, + SAY_MOLGEIM_ENCOUNTER_DEFEATED = 5, + SAY_MOLGEIM_BERSERK = 6, + + // Stormcaller Brundir + SAY_BRUNDIR_AGGRO = 0, + SAY_BRUNDIR_SLAY = 1, + SAY_BRUNDIR_SPECIAL = 2, + SAY_BRUNDIR_FLIGHT = 3, + SAY_BRUNDIR_DEATH = 4, + SAY_BRUNDIR_ENCOUNTER_DEFEATED = 5, + SAY_BRUNDIR_BERSERK = 6, + EMOTE_BRUNDIR_OVERLOAD = 7 +}; + +enum MovePoints +{ + POINT_ID_MOVE_INTRO = 1, + POINT_ID_FLIGHT_START, + POINT_ID_LAND }; enum Misc { - NPC_WORLD_TRIGGER = 22515, - - DATA_PHASE_3 = 1 + NPC_WORLD_TRIGGER = 22515, + DATA_PHASE_3 = 1 }; -class boss_steelbreaker : public CreatureScript +std::array BrundirIntroWaypoints = { - public: - boss_steelbreaker() : CreatureScript("boss_steelbreaker") { } + Position(1563.3f, 120.467f, 427.3189f), + Position(1567.86f, 129.128f, 427.3189f), + Position(1567.87f, 111.979f, 427.3189f), + Position(1576.02f, 107.71f, 427.3189f), + Position(1576.19f, 133.968f, 427.3189f), + Position(1584.52f, 111.742f, 427.3189f), + Position(1584.58f, 129.175f, 427.3189f), + Position(1588.82f, 120.42f, 427.3189f) +}; - struct boss_steelbreakerAI : public BossAI +namespace EncounterHelper +{ + // Let's use cheap AI macros instead of having the SpellMgr go through storages + void CleanupAuras(ScriptedAI const* ai, InstanceScript* instance) + { + instance->DoRemoveAurasDueToSpellOnPlayers(ai->SPELL_FUSION_PUNCH); + instance->DoRemoveAurasDueToSpellOnPlayers(ai->SPELL_OVERWHELMING_POWER); + instance->DoRemoveAurasDueToSpellOnPlayers(ai->SPELL_STATIC_DISRUPTION); + } +} + +struct boss_steelbreaker : public ScriptedAI +{ + boss_steelbreaker(Creature* creature) : ScriptedAI(creature), _instance(nullptr) { } + + void InitializeAI() override + { + // For dynamic linking compatability + _instance = me->GetInstanceScript(); + } + + void JustEngagedWith(Unit* who) override + { + if (_instance->GetBossState(DATA_ASSEMBLY_OF_IRON) != IN_PROGRESS) { - boss_steelbreakerAI(Creature* creature) : BossAI(creature, BOSS_ASSEMBLY_OF_IRON) - { - Initialize(); - } - - void Initialize() - { - phase = 0; - } - - uint32 phase; - - void Reset() override - { - _Reset(); - Initialize(); - me->RemoveAllAuras(); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - Talk(SAY_STEELBREAKER_AGGRO); - DoCast(me, SPELL_HIGH_VOLTAGE); - events.SetPhase(++phase); - events.ScheduleEvent(EVENT_BERSERK, 900000); - events.ScheduleEvent(EVENT_FUSION_PUNCH, 15000); - } - - uint32 GetData(uint32 type) const override - { - if (type == DATA_PHASE_3) - return (phase >= 3) ? 1 : 0; - - return 0; - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_SUPERCHARGE: - me->SetFullHealth(); - me->AddAura(SPELL_SUPERCHARGE, me); - events.SetPhase(++phase); - events.RescheduleEvent(EVENT_FUSION_PUNCH, 15000); - if (phase >= 2) - events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 30000); - if (phase >= 3) - events.RescheduleEvent(EVENT_OVERWHELMING_POWER, urand(2000, 5000)); - break; - case ACTION_ADD_CHARGE: - DoCast(me, SPELL_ELECTRICAL_CHARGE, true); - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - - if (instance->GetBossState(BOSS_ASSEMBLY_OF_IRON) == DONE) - { - DoCastAOE(SPELL_KILL_CREDIT, true); - Talk(SAY_STEELBREAKER_ENCOUNTER_DEFEATED); - } - else - { - me->SetLootRecipient(nullptr); - Talk(SAY_STEELBREAKER_DEATH); - //DoCastAOE(SPELL_SUPERCHARGE, true); - - if (Creature* Brundir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRUNDIR))) - if (Brundir->IsAlive()) - Brundir->AI()->DoAction(ACTION_SUPERCHARGE); - - if (Creature* Molgeim = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MOLGEIM))) - if (Molgeim->IsAlive()) - Molgeim->AI()->DoAction(ACTION_SUPERCHARGE); - } - } - - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_STEELBREAKER_SLAY); - - if (phase == 3) - DoCast(me, SPELL_ELECTRICAL_CHARGE); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BERSERK: - Talk(SAY_STEELBREAKER_BERSERK); - DoCast(SPELL_BERSERK); - events.CancelEvent(EVENT_BERSERK); - break; - case EVENT_FUSION_PUNCH: - if (me->IsWithinMeleeRange(me->GetVictim())) - DoCastVictim(SPELL_FUSION_PUNCH); - events.ScheduleEvent(EVENT_FUSION_PUNCH, urand(13000, 22000)); - break; - case EVENT_STATIC_DISRUPTION: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_STATIC_DISRUPTION); - events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(20000, 40000)); - break; - case EVENT_OVERWHELMING_POWER: - Talk(SAY_STEELBREAKER_POWER); - DoCastVictim(SPELL_OVERWHELMING_POWER); - events.ScheduleEvent(EVENT_OVERWHELMING_POWER, RAID_MODE(60000, 35000)); - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, IN_PROGRESS); + Talk(SAY_STEELBREAKER_AGGRO, who); } -}; -class boss_runemaster_molgeim : public CreatureScript -{ - public: - boss_runemaster_molgeim() : CreatureScript("boss_runemaster_molgeim") { } + DoZoneInCombat(); - struct boss_runemaster_molgeimAI : public BossAI + for (uint32 type : { DATA_RUNEMASTER_MOLGEIM, DATA_STORMCALLER_BRUNDIR }) + if (Creature* golem = _instance->GetCreature(type)) + DoZoneInCombat(golem); + + DoCastSelf(SPELL_HIGH_VOLTAGE); + DoCastSelf(SPELL_BERSERK); + _events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_FUSION_PUNCH, 15s); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + EncounterHelper::CleanupAuras(this, _instance); + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, FAIL); + } + + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) { - boss_runemaster_molgeimAI(Creature* creature) : BossAI(creature, BOSS_ASSEMBLY_OF_IRON) - { - Initialize(); - } - - void Initialize() - { - phase = 0; - } - - uint32 phase; - - void Reset() override - { - _Reset(); - Initialize(); - me->RemoveAllAuras(); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - Talk(SAY_MOLGEIM_AGGRO); - events.SetPhase(++phase); - events.ScheduleEvent(EVENT_BERSERK, 900000); - events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, 30000); - events.ScheduleEvent(EVENT_RUNE_OF_POWER, 20000); - } - - uint32 GetData(uint32 type) const override - { - if (type == DATA_PHASE_3) - return (phase >= 3) ? 1 : 0; - - return 0; - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_SUPERCHARGE: - { - me->SetFullHealth(); - me->AddAura(SPELL_SUPERCHARGE, me); - events.SetPhase(++phase); - events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000); - events.RescheduleEvent(EVENT_RUNE_OF_POWER, 25000); - if (phase >= 2) - events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000); - if (phase >= 3) - events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000, 30000)); - break; - } - } - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - - if (instance->GetBossState(BOSS_ASSEMBLY_OF_IRON) == DONE) - { - DoCastAOE(SPELL_KILL_CREDIT, true); - Talk(SAY_MOLGEIM_ENCOUNTER_DEFEATED); - } - else - { - me->SetLootRecipient(nullptr); - Talk(SAY_MOLGEIM_DEATH); - //DoCastAOE(SPELL_SUPERCHARGE, true); - - if (Creature* Brundir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRUNDIR))) - if (Brundir->IsAlive()) - Brundir->AI()->DoAction(ACTION_SUPERCHARGE); - - if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STEELBREAKER))) - if (Steelbreaker->IsAlive()) - Steelbreaker->AI()->DoAction(ACTION_SUPERCHARGE); - } - } - - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_MOLGEIM_SLAY); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BERSERK: - Talk(SAY_MOLGEIM_BERSERK); - DoCast(SPELL_BERSERK); - events.CancelEvent(EVENT_BERSERK); - break; - case EVENT_RUNE_OF_POWER: - { - Unit* target = me; - switch (urand(0, 2)) - { - case 1: - if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STEELBREAKER))) - if (Steelbreaker->IsAlive()) - target = Steelbreaker; - break; - case 2: - if (Creature* Brundir = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STEELBREAKER))) - if (Brundir->IsAlive()) - target = Brundir; - break; - default: - break; - } - DoCast(target, SPELL_SUMMON_RUNE_OF_POWER); - events.ScheduleEvent(EVENT_RUNE_OF_POWER, 60000); - break; - } - case EVENT_SHIELD_OF_RUNES: - DoCast(me, SPELL_SHIELD_OF_RUNES); - events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, urand(27000, 34000)); - break; - case EVENT_RUNE_OF_DEATH: - Talk(SAY_MOLGEIM_RUNE_DEATH); - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_RUNE_OF_DEATH); - events.ScheduleEvent(EVENT_RUNE_OF_DEATH, urand(30000, 40000)); - break; - case EVENT_RUNE_OF_SUMMONING: - Talk(SAY_MOLGEIM_SUMMON); - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_RUNE_OF_SUMMONING); - events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(30000, 45000)); - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); + Talk(SAY_STEELBREAKER_SLAY, who); + DoAction(ACTION_ADD_CHARGE); } + } + + void JustDied(Unit* /*killer*/) override + { + if (_events.IsInPhase(PHASE_THREE)) + { + EncounterHelper::CleanupAuras(this, _instance); + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, DONE); + DoCastAOE(SPELL_KILL_CREDIT, true); + Talk(SAY_STEELBREAKER_ENCOUNTER_DEFEATED); + } + else + { + me->SetLootRecipient(nullptr); + Talk(SAY_STEELBREAKER_DEATH); + DoCastAOE(SPELL_SUPERCHARGE); + } + } + + uint32 GetData(uint32 type) const override + { + if (type == DATA_PHASE_3) + return uint8(_events.IsInPhase(PHASE_THREE)); + + return 0; + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_SUPERCHARGE: + _events.SetPhase(!_events.IsInPhase(PHASE_TWO) ? PHASE_TWO : PHASE_THREE); + _events.RescheduleEvent(EVENT_FUSION_PUNCH, 13s, 22s); + + if (_events.IsInPhase(PHASE_TWO) || _events.IsInPhase(PHASE_THREE)) + _events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 20s, 40s); + + if (_events.IsInPhase(PHASE_THREE)) + _events.RescheduleEvent(EVENT_OVERWHELMING_POWER, 2s, 5s); + break; + case ACTION_ADD_CHARGE: + if (_events.IsInPhase(PHASE_THREE)) + DoCast(me, SPELL_ELECTRICAL_CHARGE, true); + break; + case ACTION_BERSERK_TRIGGERED: + Talk(SAY_STEELBREAKER_BERSERK); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasSpellFocus()) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FUSION_PUNCH: + DoCastVictim(SPELL_FUSION_PUNCH); + _events.Repeat(13s, 22s); + break; + case EVENT_STATIC_DISRUPTION: + { + // Steelbreaker prefers ranged targets above melee targets but falls back to melee targets if no ranged target is available + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, -10.f); + if (!target) + target = SelectTarget(SELECT_TARGET_RANDOM); + + DoCast(target, SPELL_STATIC_DISRUPTION); + _events.Repeat(20s, 40s); + break; + } + case EVENT_OVERWHELMING_POWER: + Talk(SAY_STEELBREAKER_POWER); + DoCastVictim(SPELL_OVERWHELMING_POWER); + _events.Repeat(RAID_MODE(60s, 35s)); + break; + default: + break; + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } + + DoMeleeAttackIfReady(); + } +private: + EventMap _events; + InstanceScript* _instance; }; -class boss_stormcaller_brundir : public CreatureScript +struct boss_runemaster_molgeim : public ScriptedAI { - public: - boss_stormcaller_brundir() : CreatureScript("boss_stormcaller_brundir") { } + boss_runemaster_molgeim(Creature* creature) : ScriptedAI(creature), _instance(nullptr), _summons(me) { } - struct boss_stormcaller_brundirAI : public BossAI + void InitializeAI() override + { + // For dynamic linking compatability + _instance = me->GetInstanceScript(); + } + + void JustAppeared() override + { + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_RUNE_OF_POWER_INTRO, 300ms, 0, PHASE_INTRO); + } + + void JustEngagedWith(Unit* who) override + { + if (_instance->GetBossState(DATA_ASSEMBLY_OF_IRON) != IN_PROGRESS) { - boss_stormcaller_brundirAI(Creature* creature) : BossAI(creature, BOSS_ASSEMBLY_OF_IRON) + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, IN_PROGRESS); + Talk(SAY_MOLGEIM_AGGRO, who); + } + + DoZoneInCombat(); + me->InterruptNonMeleeSpells(true); + + for (uint32 type : { DATA_STEELBREAKER, DATA_STORMCALLER_BRUNDIR }) + if (Creature* golem = _instance->GetCreature(type)) + DoZoneInCombat(golem); + + DoCastSelf(SPELL_BERSERK); + + _events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_RUNE_OF_POWER, 28s); + _events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, 45s); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + EncounterHelper::CleanupAuras(this, _instance); + _summons.DespawnAll(); + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, FAIL); + } + + void JustDied(Unit* /*killer*/) override + { + if (_events.IsInPhase(PHASE_THREE)) + { + EncounterHelper::CleanupAuras(this, _instance); + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, DONE); + DoCastAOE(SPELL_KILL_CREDIT, true); + Talk(SAY_MOLGEIM_ENCOUNTER_DEFEATED); + } + else + { + me->SetLootRecipient(nullptr); + Talk(SAY_MOLGEIM_DEATH); + DoCastAOE(SPELL_SUPERCHARGE); + } + } + + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_MOLGEIM_SLAY); + } + + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + } + + uint32 GetData(uint32 type) const override + { + if (type == DATA_PHASE_3) + return uint8(_events.IsInPhase(PHASE_THREE)); + + return 0; + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_SUPERCHARGE: + _events.SetPhase(!_events.IsInPhase(PHASE_TWO) ? PHASE_TWO : PHASE_THREE); + if (_events.IsInPhase(PHASE_TWO)) + _events.ScheduleEvent(EVENT_RUNE_OF_DEATH, 37s); + else if (_events.IsInPhase(PHASE_THREE)) + _events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, 13s); + break; + case ACTION_BERSERK_TRIGGERED: + Talk(SAY_MOLGEIM_BERSERK); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) + return; + + _events.Update(diff); + + if ((me->HasUnitState(UNIT_STATE_CASTING) || me->HasSpellFocus()) && !_events.IsInPhase(PHASE_INTRO)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - Initialize(); + case EVENT_RUNE_OF_POWER_INTRO: + DoCastSelf(SPELL_RUNE_OF_POWER_PRE_FIGHT); + _events.Repeat(11s); + break; + case EVENT_RUNE_OF_POWER: + { + std::vector aliveBosses = { me }; + if (Creature* steelbreaker = _instance->GetCreature(DATA_STEELBREAKER)) + if (steelbreaker->IsAlive()) + aliveBosses.push_back(steelbreaker); + + if (Creature* brundir = _instance->GetCreature(DATA_STORMCALLER_BRUNDIR)) + if (brundir->IsAlive()) + aliveBosses.push_back(brundir); + + if (Creature* target = Trinity::Containers::SelectRandomContainerElement(aliveBosses)) + DoCast(target, SPELL_RUNE_OF_POWER); + + _events.Repeat(32s, 47s); + break; + } + case EVENT_SHIELD_OF_RUNES: + DoCastSelf(SPELL_SHIELD_OF_RUNES); + _events.Repeat(32s, 48s); + break; + case EVENT_RUNE_OF_DEATH: + Talk(SAY_MOLGEIM_RUNE_DEATH); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_RUNE_OF_DEATH); + _events.Repeat(47s, 54s); + break; + case EVENT_RUNE_OF_SUMMONING: + Talk(SAY_MOLGEIM_SUMMON); + _summons.RemoveNotExisting(); // Keeping the summon list clean + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_RUNE_OF_SUMMONING); + _events.Repeat(23s, 33s); + break; + default: + break; } - void Initialize() - { - phase = 0; - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - uint32 phase; + DoMeleeAttackIfReady(); + } +private: + EventMap _events; + InstanceScript* _instance; + SummonList _summons; +}; - void Reset() override - { - _Reset(); - Initialize(); - me->RemoveAllAuras(); +struct boss_stormcaller_brundir : public ScriptedAI +{ + boss_stormcaller_brundir(Creature* creature) : ScriptedAI(creature), _instance(nullptr), _summons(me) { } + + void InitializeAI() override + { + // For dynamic linking compatability + _instance = me->GetInstanceScript(); + } + + void JustAppeared() override + { + me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, false); // Should be interruptable unless overridden by spell (Overload) + me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, false); // Reset immumity, Brundir should be stunnable by default + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_MOVE_INTRO, 300ms, 0, PHASE_INTRO); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + EncounterHelper::CleanupAuras(this, _instance); + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, FAIL); + } + + void JustEngagedWith(Unit* who) override + { + me->GetMotionMaster()->Initialize(); + + if (_instance->GetBossState(DATA_ASSEMBLY_OF_IRON) != IN_PROGRESS) + { + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, IN_PROGRESS); + Talk(SAY_BRUNDIR_AGGRO, who); + } + + DoZoneInCombat(); + me->InterruptNonMeleeSpells(true); + + for (uint32 type : { DATA_STEELBREAKER, DATA_RUNEMASTER_MOLGEIM }) + if (Creature* golem = _instance->GetCreature(type)) + DoZoneInCombat(golem); + + DoCastSelf(SPELL_BERSERK); + + _events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 1ms); + _events.ScheduleEvent(EVENT_OVERLOAD, 42s, 1min); + } + + uint32 GetData(uint32 type) const override + { + if (type == DATA_PHASE_3) + return uint8(_events.IsInPhase(PHASE_THREE)); + + return 0; + } + + void JustDied(Unit* /*killer*/) override + { + if (_events.IsInPhase(PHASE_THREE)) + { + EncounterHelper::CleanupAuras(this, _instance); + _instance->SetBossState(DATA_ASSEMBLY_OF_IRON, DONE); + DoCastAOE(SPELL_KILL_CREDIT, true); + Talk(SAY_BRUNDIR_ENCOUNTER_DEFEATED); + } + else + { + me->SetLootRecipient(nullptr); + Talk(SAY_BRUNDIR_DEATH); + DoCastAOE(SPELL_SUPERCHARGE); + } + } + + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) + Talk(SAY_BRUNDIR_SLAY); + } + + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + } + + void OnSpellCastFinished(SpellInfo const* spell, SpellFinishReason reason) override + { + if (spell->Id == SPELL_OVERLOAD && (reason == SPELL_FINISHED_FINISHED || reason == SPELL_FINISHED_CANCELED)) + _summons.DespawnAll(); + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_SUPERCHARGE: + _events.SetPhase(!_events.IsInPhase(PHASE_TWO) ? PHASE_TWO : PHASE_THREE); + if (_events.IsInPhase(PHASE_TWO) || _events.IsInPhase(PHASE_THREE)) + _events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, 13s, 15s); + + if (_events.IsInPhase(PHASE_THREE)) + { + me->InterruptNonMeleeSpells(true); + DoCastSelf(SPELL_STORMSHIELD); + me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true); // Apply immumity to stuns + _events.ScheduleEvent(EVENT_LIGHTNING_TENDRILS, 48s, 50s); + } + break; + case ACTION_BERSERK_TRIGGERED: + Talk(SAY_BRUNDIR_BERSERK); + break; + default: + break; + } + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != EFFECT_MOTION_TYPE && type != POINT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_ID_MOVE_INTRO: + DoCastSelf(SPELL_LIGHTNING_CHANNEL_PRE_FIGHT_VISUAL); + _events.ScheduleEvent(EVENT_MOVE_INTRO, 4s + 500ms, 0, PHASE_INTRO); + break; + case POINT_ID_FLIGHT_START: + me->SetHover(true); + break; + case POINT_ID_LAND: me->SetHover(false); - me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, false); // Should be interruptable unless overridden by spell (Overload) - me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, false); // Reset immumity, Brundir should be stunnable by default - } + me->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS); + me->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS_VISUAL); + ResetThreatList(); + me->SetReactState(REACT_AGGRESSIVE); + break; + default: + break; + } + } - uint32 GetData(uint32 type) const override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) + return; + + _events.Update(diff); + + if ((me->HasUnitState(UNIT_STATE_CASTING) || me->HasSpellFocus()) && !_events.IsInPhase(PHASE_INTRO)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - if (type == DATA_PHASE_3) - return (phase >= 3) ? 1 : 0; - - return 0; - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - Talk(SAY_BRUNDIR_AGGRO); - events.SetPhase(++phase); - events.ScheduleEvent(EVENT_MOVE_POSITION, 1000); - events.ScheduleEvent(EVENT_BERSERK, 900000); - events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 4000); - events.ScheduleEvent(EVENT_OVERLOAD, urand(60000, 120000)); - } - - void DoAction(int32 action) override - { - switch (action) + case EVENT_MOVE_INTRO: { - case ACTION_SUPERCHARGE: + me->ReleaseSpellFocus(me->GetCurrentSpell(CURRENT_CHANNELED_SPELL), false); + me->InterruptNonMeleeSpells(true); + // Generate new random waypoints if we run out of them. + if (_potentialWaypoints.empty()) { - me->SetFullHealth(); - me->AddAura(SPELL_SUPERCHARGE, me); - events.SetPhase(++phase); - events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, urand(7000, 12000)); - events.RescheduleEvent(EVENT_OVERLOAD, urand(40000, 50000)); - if (phase >= 2) - events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, urand(15000, 250000)); - if (phase >= 3) - { - DoCast(me, SPELL_STORMSHIELD); - events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, urand(50000, 60000)); - me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true); // Apply immumity to stuns - } - break; - } - } - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - - if (instance->GetBossState(BOSS_ASSEMBLY_OF_IRON) == DONE) - { - DoCastAOE(SPELL_KILL_CREDIT, true); - Talk(SAY_BRUNDIR_ENCOUNTER_DEFEATED); - } - else - { - me->SetLootRecipient(nullptr); - Talk(SAY_BRUNDIR_DEATH); - //DoCastAOE(SPELL_SUPERCHARGE, true); - - if (Creature* Molgeim = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MOLGEIM))) - if (Molgeim->IsAlive()) - Molgeim->AI()->DoAction(ACTION_SUPERCHARGE); - - if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STEELBREAKER))) - if (Steelbreaker->IsAlive()) - Steelbreaker->AI()->DoAction(ACTION_SUPERCHARGE); - } - } - - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_BRUNDIR_SLAY); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BERSERK: - Talk(SAY_BRUNDIR_BERSERK); - DoCast(SPELL_BERSERK); - events.CancelEvent(EVENT_BERSERK); - break; - case EVENT_CHAIN_LIGHTNING: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_CHAIN_LIGHTNING); - events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, urand(7000, 10000)); - break; - case EVENT_OVERLOAD: - Talk(EMOTE_BRUNDIR_OVERLOAD); - Talk(SAY_BRUNDIR_SPECIAL); - DoCast(SPELL_OVERLOAD); - events.ScheduleEvent(EVENT_OVERLOAD, urand(60000, 120000)); - break; - case EVENT_LIGHTNING_WHIRL: - DoCast(SPELL_LIGHTNING_WHIRL); - events.ScheduleEvent(EVENT_LIGHTNING_WHIRL, urand(15000, 20000)); - break; - case EVENT_LIGHTNING_TENDRILS: - Talk(SAY_BRUNDIR_FLIGHT); - DoCast(me, SPELL_LIGHTNING_TENDRILS); - DoCast(me, SPELL_LIGHTNING_TENDRILS_VISUAL); - me->AttackStop(); - me->SetHover(true); - events.DelayEvents(35000); - events.ScheduleEvent(EVENT_FLIGHT, 2500); - events.ScheduleEvent(EVENT_ENDFLIGHT, 32500); - events.ScheduleEvent(EVENT_LIGHTNING_TENDRILS, 90000); - break; - case EVENT_FLIGHT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - me->GetMotionMaster()->MovePoint(0, *target); - events.ScheduleEvent(EVENT_FLIGHT, 6000); - break; - case EVENT_ENDFLIGHT: - me->GetMotionMaster()->Initialize(); - me->GetMotionMaster()->MovePoint(0, 1586.920166f, 119.848984f, me->GetPositionZ()); - events.CancelEvent(EVENT_FLIGHT); - events.CancelEvent(EVENT_ENDFLIGHT); - events.ScheduleEvent(EVENT_LAND, 4000); - break; - case EVENT_LAND: - me->SetHover(false); - events.CancelEvent(EVENT_LAND); - events.ScheduleEvent(EVENT_GROUND, 2500); - break; - case EVENT_GROUND: - me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHTNING_TENDRILS, me)); - me->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS_VISUAL); - DoStartMovement(me->GetVictim()); - events.CancelEvent(EVENT_GROUND); - ResetThreatList(); - break; - case EVENT_MOVE_POSITION: - if (me->IsWithinMeleeRange(me->GetVictim())) - { - float x = float(irand(-25, 25)); - float y = float(irand(-25, 25)); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX() + x, me->GetPositionY() + y, me->GetPositionZ()); - // Prevention to go outside the room or into the walls - if (Creature* trigger = me->FindNearestCreature(NPC_WORLD_TRIGGER, 100.0f, true)) - if (me->GetDistance(trigger) >= 50.0f) - me->GetMotionMaster()->MovePoint(0, *trigger); - } - events.ScheduleEvent(EVENT_MOVE_POSITION, urand(7500, 10000)); - break; - default: - break; + std::transform(BrundirIntroWaypoints.begin(), BrundirIntroWaypoints.end(), std::back_inserter(_potentialWaypoints), [](Position const& pos) { return pos; }); + Trinity::Containers::RandomShuffle(_potentialWaypoints); } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + Position const dest = _potentialWaypoints.front(); + _potentialWaypoints.erase(_potentialWaypoints.begin()); + + me->GetMotionMaster()->MovePoint(POINT_ID_MOVE_INTRO, dest); + break; } + case EVENT_CHAIN_LIGHTNING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_CHAIN_LIGHTNING); + _events.Repeat(6s, 8s); + break; + case EVENT_OVERLOAD: + Talk(EMOTE_BRUNDIR_OVERLOAD); + Talk(SAY_BRUNDIR_SPECIAL); + DoCast(SPELL_OVERLOAD); + _events.Repeat(42s, 1min); + break; + case EVENT_LIGHTNING_WHIRL: + DoCastSelf(SPELL_LIGHTNING_WHIRL); + _events.Repeat(15s, 20s); + break; + case EVENT_LIGHTNING_TENDRILS: + { + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + me->StopMoving(); - DoMeleeAttackIfReady(); + Talk(SAY_BRUNDIR_FLIGHT); + DoCastSelf(SPELL_LIGHTNING_TENDRILS); + DoCastSelf(SPELL_LIGHTNING_TENDRILS_VISUAL); + + me->GetMotionMaster()->MoveTakeoff(POINT_ID_FLIGHT_START, { me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10.f }, 7.5f); + _events.DelayEvents(29s); + _events.ScheduleEvent(EVENT_FLIGHT, 2s + 500ms); + _events.ScheduleEvent(EVENT_LAND, 23s); + _events.Repeat(88s); + break; + } + case EVENT_FLIGHT: + DoCastSelf(SPELL_RANDOM_AGGRO_PERIODIC); + me->SetReactState(REACT_AGGRESSIVE); + break; + case EVENT_LAND: + me->RemoveAurasDueToSpell(SPELL_RANDOM_AGGRO_PERIODIC); + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + me->GetMotionMaster()->MoveLand(POINT_ID_LAND, { me->GetPositionX(), me->GetPositionY(), me->GetFloorZ() }, 3.75f); + break; + default: + break; } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetUlduarAI(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } + + DoMeleeAttackIfReady(); + } + +private: + EventMap _events; + InstanceScript* _instance; + SummonList _summons; + std::vector _potentialWaypoints; }; -class spell_shield_of_runes : public SpellScriptLoader +struct npc_assembly_lightning_elemental : public ScriptedAI { - public: - spell_shield_of_runes() : SpellScriptLoader("spell_shield_of_runes") { } + npc_assembly_lightning_elemental(Creature* creature) : ScriptedAI(creature) { } - class spell_shield_of_runes_AuraScript : public AuraScript - { - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - if (!GetTargetApplication()->GetRemoveMode().HasFlag(AuraRemoveFlags::Expired)) - caster->CastSpell(caster, SPELL_SHIELD_OF_RUNES_BUFF, false); - } + void InitializeAI() override + { + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* molgeim = instance->GetCreature(DATA_RUNEMASTER_MOLGEIM)) + if (molgeim->IsAIEnabled) + molgeim->AI()->JustSummoned(me); + } - void Register() override - { - AfterEffectRemove.Register(&spell_shield_of_runes_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL); - } - }; + void JustAppeared() override + { + if (Unit* target = me->SelectNearestTarget(100.f, true)) + me->EngageWithTarget(target); + } - AuraScript* GetAuraScript() const override - { - return new spell_shield_of_runes_AuraScript(); - } + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(2s); + } }; -class spell_assembly_meltdown : public SpellScriptLoader +class spell_shield_of_runes : public AuraScript { - public: - spell_assembly_meltdown() : SpellScriptLoader("spell_assembly_meltdown") { } + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (!GetTargetApplication()->GetRemoveMode().HasFlag(AuraRemoveFlags::Expired)) + caster->CastSpell(caster, SPELL_SHIELD_OF_RUNES_BUFF, false); + } - class spell_assembly_meltdown_SpellScript : public SpellScript - { - void HandleInstaKill(SpellEffIndex /*effIndex*/) - { - if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_STEELBREAKER))) - Steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE); - } - - void Register() override - { - OnEffectHitTarget.Register(&spell_assembly_meltdown_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_assembly_meltdown_SpellScript(); - } + void Register() override + { + AfterEffectRemove.Register(&spell_shield_of_runes::AfterRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL); + } }; -class spell_assembly_rune_of_summoning : public SpellScriptLoader +class spell_assembly_meltdown : public SpellScript { - public: - spell_assembly_rune_of_summoning() : SpellScriptLoader("spell_assembly_rune_of_summoning") { } + void HandleInstaKill(SpellEffIndex /*effIndex*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* steelbreaker = instance->GetCreature(DATA_STEELBREAKER)) + if (steelbreaker->IsAIEnabled) + steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE); + } - class spell_assembly_rune_of_summoning_AuraScript : public AuraScript + void Register() override + { + OnEffectHitTarget.Register(&spell_assembly_meltdown::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL); + } +}; + +class spell_assembly_rune_of_summoning : public AuraScript +{ + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_RUNE_OF_SUMMONING_SUMMON }); + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_RUNE_OF_SUMMONING_SUMMON, true, nullptr, aurEff, GetTarget()->IsSummon() ? GetTarget()->ToTempSummon()->GetSummonerGUID() : ObjectGuid::Empty); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (TempSummon* summ = GetTarget()->ToTempSummon()) + summ->DespawnOrUnsummon(1); + } + + void Register() override + { + OnEffectPeriodic.Register(&spell_assembly_rune_of_summoning::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + OnEffectRemove.Register(&spell_assembly_rune_of_summoning::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +class spell_assembly_random_aggro_periodic : public AuraScript +{ + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + GetTarget()->GetThreatManager().ResetAllThreat(); + } + + void Register() override + { + OnEffectPeriodic.Register(&spell_assembly_random_aggro_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +class spell_assembly_supercharge : public SpellScript +{ + void FilterTargets(std::list& targets) + { + targets.remove_if([this](WorldObject const* target)->bool { - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_RUNE_OF_SUMMONING_SUMMON }); - } + Unit const* unitTarget = target->ToUnit(); + return (!unitTarget || unitTarget == GetCaster() || unitTarget->isDead()); + }); + } - void HandlePeriodic(AuraEffect const* aurEff) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_RUNE_OF_SUMMONING_SUMMON, true, nullptr, aurEff, GetTarget()->IsSummon() ? GetTarget()->ToTempSummon()->GetSummonerGUID() : ObjectGuid::Empty); - } + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + if (target->IsAIEnabled) + target->AI()->DoAction(ACTION_SUPERCHARGE); + } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (TempSummon* summ = GetTarget()->ToTempSummon()) - summ->DespawnOrUnsummon(1); - } + void Register() override + { + OnEffectHitTarget.Register(&spell_assembly_supercharge::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; - void Register() override - { - OnEffectPeriodic.Register(&spell_assembly_rune_of_summoning_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - OnEffectRemove.Register(&spell_assembly_rune_of_summoning_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; +class spell_assembly_berserk : public AuraScript +{ + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + if (Creature* target = GetTarget()->ToCreature()) + if (target->IsAIEnabled) + target->AI()->DoAction(ACTION_BERSERK_TRIGGERED); + } - AuraScript* GetAuraScript() const override - { - return new spell_assembly_rune_of_summoning_AuraScript(); - } + void Register() override + { + OnEffectPeriodic.Register(&spell_assembly_berserk::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + +class spell_assembly_lightning_tendrils_visual : public SpellScript +{ + void SetDest(SpellDestination& dest) + { + Position oldDest = dest._position; + oldDest.m_positionZ = GetCaster()->GetFloorZ(); + + // The caster is hovering high in the air so default target selections do not work. + float dist = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster()) * float(rand_norm()); + float angle = frand(0.f, float(M_PI * 2)); + oldDest.m_positionX += std::cos(angle) * dist; + oldDest.m_positionY += std::sin(angle) * dist; + dest.Relocate(oldDest); + } + + void Register() + { + OnDestinationTargetSelect.Register(&spell_assembly_lightning_tendrils_visual::SetDest, EFFECT_0, TARGET_DEST_CASTER_RANDOM); + } }; class achievement_assembly_i_choose_you : public AchievementCriteriaScript @@ -754,11 +881,16 @@ class achievement_assembly_i_choose_you : public AchievementCriteriaScript void AddSC_boss_assembly_of_iron() { - new boss_steelbreaker(); - new boss_runemaster_molgeim(); - new boss_stormcaller_brundir(); - new spell_shield_of_runes(); - new spell_assembly_meltdown(); - new spell_assembly_rune_of_summoning(); + RegisterUlduarCreatureAI(boss_steelbreaker); + RegisterUlduarCreatureAI(boss_runemaster_molgeim); + RegisterUlduarCreatureAI(boss_stormcaller_brundir); + RegisterUlduarCreatureAI(npc_assembly_lightning_elemental); + RegisterSpellScript(spell_shield_of_runes); + RegisterSpellScript(spell_assembly_meltdown); + RegisterSpellScript(spell_assembly_rune_of_summoning); + RegisterSpellScript(spell_assembly_random_aggro_periodic); + RegisterSpellScript(spell_assembly_supercharge); + RegisterSpellScript(spell_assembly_berserk); + RegisterSpellScript(spell_assembly_lightning_tendrils_visual); new achievement_assembly_i_choose_you(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp index 4ad0ccff9d4..f156279573f 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp @@ -107,7 +107,7 @@ class boss_auriaya : public CreatureScript struct boss_auriayaAI : public BossAI { - boss_auriayaAI(Creature* creature) : BossAI(creature, BOSS_AURIAYA) + boss_auriayaAI(Creature* creature) : BossAI(creature, DATA_AURIAYA) { Initialize(); } @@ -316,7 +316,7 @@ class npc_auriaya_seeping_trigger : public CreatureScript void UpdateAI(uint32 /*diff*/) override { - if (instance->GetBossState(BOSS_AURIAYA) != IN_PROGRESS) + if (instance->GetBossState(DATA_AURIAYA) != IN_PROGRESS) me->DespawnOrUnsummon(); } @@ -393,7 +393,7 @@ class npc_sanctum_sentry : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA)) + if (Creature* auriaya = instance->GetCreature(DATA_AURIAYA)) auriaya->AI()->DoAction(ACTION_CRAZY_CAT_LADY); } @@ -472,7 +472,7 @@ class npc_feral_defender : public CreatureScript void JustDied(Unit* /*killer*/) override { DoCast(me, SPELL_SUMMON_ESSENCE); - if (Creature* auriaya = instance->GetCreature(BOSS_AURIAYA)) + if (Creature* auriaya = instance->GetCreature(DATA_AURIAYA)) auriaya->AI()->DoAction(ACTION_RESPAWN_DEFENDER); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 5693072fdf7..8d0d4980758 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -220,7 +220,7 @@ class boss_flame_leviathan : public CreatureScript struct boss_flame_leviathanAI : public BossAI { - boss_flame_leviathanAI(Creature* creature) : BossAI(creature, BOSS_LEVIATHAN) + boss_flame_leviathanAI(Creature* creature) : BossAI(creature, DATA_FLAME_LEVIATHAN) { Initialize(); } @@ -1273,7 +1273,7 @@ class npc_lorekeeper : public CreatureScript player->PlayerTalkClass->SendCloseGossip(); _instance->instance->LoadGrid(364, -16); // make sure leviathan is loaded - if (Creature* leviathan = _instance->GetCreature(BOSS_LEVIATHAN)) + if (Creature* leviathan = _instance->GetCreature(DATA_FLAME_LEVIATHAN)) { leviathan->AI()->DoAction(ACTION_START_HARD_MODE); me->SetVisible(false); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 43c56a2cf32..05430fc4962 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -266,7 +266,7 @@ class boss_freya : public CreatureScript struct boss_freyaAI : public BossAI { - boss_freyaAI(Creature* creature) : BossAI(creature, BOSS_FREYA) + boss_freyaAI(Creature* creature) : BossAI(creature, DATA_FREYA) { _encounterFinished = false; Initialize(); @@ -344,7 +344,7 @@ class boss_freya : public CreatureScript Creature* Elder[3]; for (uint8 n = 0; n < 3; ++n) { - Elder[n] = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_BRIGHTLEAF + n)); + Elder[n] = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRIGHTLEAF + n)); if (Elder[n] && Elder[n]->IsAlive()) { me->AddAura(SPELL_DRAINED_OF_POWER, Elder[n]); @@ -625,7 +625,7 @@ class boss_freya : public CreatureScript for (uint8 n = 0; n < 3; ++n) { - Creature* Elder = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_BRIGHTLEAF + n)); + Creature* Elder = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRIGHTLEAF + n)); if (Elder && Elder->IsAlive()) { Elder->RemoveAllAuras(); @@ -698,7 +698,7 @@ class boss_elder_brightleaf : public CreatureScript struct boss_elder_brightleafAI : public BossAI { - boss_elder_brightleafAI(Creature* creature) : BossAI(creature, BOSS_BRIGHTLEAF) + boss_elder_brightleafAI(Creature* creature) : BossAI(creature, DATA_BRIGHTLEAF) { } @@ -799,7 +799,7 @@ class boss_elder_stonebark : public CreatureScript struct boss_elder_stonebarkAI : public BossAI { - boss_elder_stonebarkAI(Creature* creature) : BossAI(creature, BOSS_STONEBARK) + boss_elder_stonebarkAI(Creature* creature) : BossAI(creature, DATA_STONEBARK) { } @@ -906,7 +906,7 @@ class boss_elder_ironbranch : public CreatureScript struct boss_elder_ironbranchAI : public BossAI { - boss_elder_ironbranchAI(Creature* creature) : BossAI(creature, BOSS_IRONBRANCH) + boss_elder_ironbranchAI(Creature* creature) : BossAI(creature, DATA_IRONBRANCH) { } @@ -1068,7 +1068,7 @@ class npc_ancient_water_spirit : public CreatureScript { Initialize(); instance = me->GetInstanceScript(); - if (Creature* freya = instance->GetCreature(BOSS_FREYA)) + if (Creature* freya = instance->GetCreature(DATA_FREYA)) waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount; else waveCount = 0; @@ -1106,7 +1106,7 @@ class npc_ancient_water_spirit : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* freya = instance->GetCreature(BOSS_FREYA)) + if (Creature* freya = instance->GetCreature(DATA_FREYA)) { ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false; ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(1); @@ -1136,7 +1136,7 @@ class npc_storm_lasher : public CreatureScript { Initialize(); instance = me->GetInstanceScript(); - if (Creature* freya = instance->GetCreature(BOSS_FREYA)) + if (Creature* freya = instance->GetCreature(DATA_FREYA)) waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount; else waveCount = 0; @@ -1180,7 +1180,7 @@ class npc_storm_lasher : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* freya = instance->GetCreature(BOSS_FREYA)) + if (Creature* freya = instance->GetCreature(DATA_FREYA)) { ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false; ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(2); @@ -1210,7 +1210,7 @@ class npc_snaplasher : public CreatureScript npc_snaplasherAI(Creature* creature) : ScriptedAI(creature) { instance = me->GetInstanceScript(); - if (Creature* freya = instance->GetCreature(BOSS_FREYA)) + if (Creature* freya = instance->GetCreature(DATA_FREYA)) waveCount = ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->trioWaveCount; else waveCount = 0; @@ -1229,7 +1229,7 @@ class npc_snaplasher : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* freya = instance->GetCreature(BOSS_FREYA)) + if (Creature* freya = instance->GetCreature(DATA_FREYA)) { ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->checkElementalAlive[waveCount] = false; ENSURE_AI(boss_freya::boss_freyaAI, freya->AI())->LasherDead(4); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index 004cb00d1c0..16198ea616c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -106,7 +106,7 @@ class boss_general_vezax : public CreatureScript struct boss_general_vezaxAI : public BossAI { - boss_general_vezaxAI(Creature* creature) : BossAI(creature, BOSS_VEZAX) + boss_general_vezaxAI(Creature* creature) : BossAI(creature, DATA_VEZAX) { Initialize(); } @@ -334,7 +334,7 @@ class boss_saronite_animus : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* vezax = instance->GetCreature(BOSS_VEZAX)) + if (Creature* vezax = instance->GetCreature(DATA_VEZAX)) vezax->AI()->DoAction(ACTION_ANIMUS_DIE); } @@ -432,7 +432,7 @@ class npc_saronite_vapors : public CreatureScript DoCast(me, SPELL_SARONITE_VAPORS); me->DespawnOrUnsummon(30000); - if (Creature* vezax = instance->GetCreature(BOSS_VEZAX)) + if (Creature* vezax = instance->GetCreature(DATA_VEZAX)) vezax->AI()->DoAction(ACTION_VAPORS_DIE); } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index e0875923993..38c98d35add 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -215,7 +215,7 @@ class npc_flash_freeze : public CreatureScript || me->EnsureVictim()->HasAura(SPELL_FLASH_FREEZE_HELPER)) return; - if (me->EnsureVictim()->GetGUID() != targetGUID || instance->GetBossState(BOSS_HODIR) != IN_PROGRESS) + if (me->EnsureVictim()->GetGUID() != targetGUID || instance->GetBossState(DATA_HODIR) != IN_PROGRESS) me->DespawnOrUnsummon(); if (checkDespawnTimer <= diff) @@ -240,7 +240,7 @@ class npc_flash_freeze : public CreatureScript // Prevents to have Ice Block on other place than target is me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation()); if (target->GetTypeId() == TYPEID_PLAYER) - if (Creature* hodir = instance->GetCreature(BOSS_HODIR)) + if (Creature* hodir = instance->GetCreature(DATA_HODIR)) hodir->AI()->DoAction(ACTION_CHEESE_THE_FREEZE); } } @@ -294,7 +294,7 @@ class npc_ice_block : public CreatureScript helper->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); helper->SetControlled(false, UNIT_STATE_ROOT); - if (Creature* hodir = instance->GetCreature(BOSS_HODIR)) + if (Creature* hodir = instance->GetCreature(DATA_HODIR)) { if (!hodir->IsInCombat()) { @@ -322,7 +322,7 @@ class boss_hodir : public CreatureScript struct boss_hodirAI : public BossAI { - boss_hodirAI(Creature* creature) : BossAI(creature, BOSS_HODIR) + boss_hodirAI(Creature* creature) : BossAI(creature, DATA_HODIR) { Initialize(); me->SetReactState(REACT_PASSIVE); @@ -714,7 +714,7 @@ class npc_hodir_priest : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* hodir = instance->GetCreature(BOSS_HODIR)) + if (Creature* hodir = instance->GetCreature(DATA_HODIR)) hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } @@ -779,7 +779,7 @@ class npc_hodir_shaman : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* hodir = instance->GetCreature(BOSS_HODIR)) + if (Creature* hodir = instance->GetCreature(DATA_HODIR)) hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } @@ -843,7 +843,7 @@ class npc_hodir_druid : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* hodir = instance->GetCreature(BOSS_HODIR)) + if (Creature* hodir = instance->GetCreature(DATA_HODIR)) hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } @@ -926,7 +926,7 @@ class npc_hodir_mage : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* hodir = instance->GetCreature(BOSS_HODIR)) + if (Creature* hodir = instance->GetCreature(DATA_HODIR)) hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp index e730ad534d1..992a0ceab30 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp @@ -120,7 +120,7 @@ class boss_ignis : public CreatureScript struct boss_ignis_AI : public BossAI { - boss_ignis_AI(Creature* creature) : BossAI(creature, BOSS_IGNIS) + boss_ignis_AI(Creature* creature) : BossAI(creature, DATA_IGNIS) { Initialize(); } @@ -328,7 +328,7 @@ class npc_iron_construct : public CreatureScript if (me->HasAura(RAID_MODE(SPELL_BRITTLE, SPELL_BRITTLE_25)) && damage >= 5000) { DoCast(SPELL_SHATTER); - if (Creature* ignis = _instance->GetCreature(BOSS_IGNIS)) + if (Creature* ignis = _instance->GetCreature(DATA_IGNIS)) if (ignis->AI()) ignis->AI()->DoAction(ACTION_REMOVE_BUFF); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp index 063dccbcdf8..a24b23bab47 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp @@ -104,7 +104,7 @@ class boss_kologarn : public CreatureScript struct boss_kologarnAI : public BossAI { - boss_kologarnAI(Creature* creature) : BossAI(creature, BOSS_KOLOGARN), + boss_kologarnAI(Creature* creature) : BossAI(creature, DATA_KOLOGARN), left(false), right(false) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -162,7 +162,7 @@ class boss_kologarn : public CreatureScript void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override { - bool isEncounterInProgress = instance->GetBossState(BOSS_KOLOGARN) == IN_PROGRESS; + bool isEncounterInProgress = instance->GetBossState(DATA_KOLOGARN) == IN_PROGRESS; if (who->GetEntry() == NPC_LEFT_ARM) { left = apply; @@ -339,7 +339,7 @@ class spell_ulduar_rubble_summon : public SpellScriptLoader if (!caster) return; - ObjectGuid originalCaster = caster->GetInstanceScript() ? caster->GetInstanceScript()->GetGuidData(BOSS_KOLOGARN) : ObjectGuid::Empty; + ObjectGuid originalCaster = caster->GetInstanceScript() ? caster->GetInstanceScript()->GetGuidData(DATA_KOLOGARN) : ObjectGuid::Empty; uint32 spellId = GetEffectValue(); for (uint8 i = 0; i < 5; ++i) caster->CastSpell(caster, spellId, true, nullptr, nullptr, originalCaster); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 59e7c1f6ba5..bf80b3fdd2b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -372,7 +372,7 @@ static bool IsEncounterFinished(Unit* who) mkii->DespawnOrUnsummon(120000); vx001->DespawnOrUnsummon(120000); aerial->DespawnOrUnsummon(120000); - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->JustDied(who); return true; } @@ -386,7 +386,7 @@ class boss_mimiron : public CreatureScript struct boss_mimironAI : public BossAI { - boss_mimironAI(Creature* creature) : BossAI(creature, BOSS_MIMIRON) + boss_mimironAI(Creature* creature) : BossAI(creature, DATA_MIMIRON) { me->SetReactState(REACT_PASSIVE); _fireFighter = false; @@ -439,7 +439,7 @@ class boss_mimiron : public CreatureScript void JustDied(Unit* /*killer*/) override { - instance->SetBossState(BOSS_MIMIRON, DONE); + instance->SetBossState(DATA_MIMIRON, DONE); events.Reset(); me->CombatStop(true); me->SetDisableGravity(false); @@ -453,7 +453,7 @@ class boss_mimiron : public CreatureScript void Reset() override { - if (instance->GetBossState(BOSS_MIMIRON) == DONE) // Mimiron will attempt to reset because he is not dead and will be set to friendly before despawning. + if (instance->GetBossState(DATA_MIMIRON) == DONE) // Mimiron will attempt to reset because he is not dead and will be set to friendly before despawning. return; _Reset(); @@ -481,7 +481,7 @@ class boss_mimiron : public CreatureScript void UpdateAI(uint32 diff) override { - if (!UpdateVictim() && instance->GetBossState(BOSS_MIMIRON) != DONE) + if (!UpdateVictim() && instance->GetBossState(DATA_MIMIRON) != DONE) return; events.Update(diff); @@ -684,7 +684,7 @@ class boss_leviathan_mk_ii : public CreatureScript struct boss_leviathan_mk_iiAI : public BossAI { - boss_leviathan_mk_iiAI(Creature* creature) : BossAI(creature, BOSS_MIMIRON) + boss_leviathan_mk_iiAI(Creature* creature) : BossAI(creature, DATA_MIMIRON) { _fireFighter = false; _setupMine = true; @@ -784,7 +784,7 @@ class boss_leviathan_mk_ii : public CreatureScript void KilledUnit(Unit* victim) override { if (victim->GetTypeId() == TYPEID_PLAYER) - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->Talk(events.IsInPhase(PHASE_LEVIATHAN_MK_II) ? SAY_MKII_SLAY : SAY_V07TRON_SLAY); } @@ -799,7 +799,7 @@ class boss_leviathan_mk_ii : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoCast(me, SPELL_HALF_HEAL); - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->DoAction(DO_ACTIVATE_VX001); break; case WP_MKII_P4_POS_1: @@ -809,7 +809,7 @@ class boss_leviathan_mk_ii : public CreatureScript events.ScheduleEvent(EVENT_MOVE_POINT_3, 1); break; case WP_MKII_P4_POS_3: - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->DoAction(DO_ACTIVATE_V0L7R0N_2); break; case WP_MKII_P4_POS_4: @@ -929,7 +929,7 @@ class boss_vx_001 : public CreatureScript struct boss_vx_001AI : public BossAI { - boss_vx_001AI(Creature* creature) : BossAI(creature, BOSS_MIMIRON) + boss_vx_001AI(Creature* creature) : BossAI(creature, DATA_MIMIRON) { me->SetDisableGravity(true); // This is the unfold visual state of VX-001, it has to be set on create as it requires an objectupdate if set later. me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SPECIAL_UNARMED); // This is a hack to force the yet to be unfolded visual state. @@ -952,7 +952,7 @@ class boss_vx_001 : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); // | UNIT_FLAG_NOT_SELECTABLE); DoCast(me, SPELL_HALF_HEAL); // has no effect, wat DoCast(me, SPELL_TORSO_DISABLED); - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->DoAction(DO_ACTIVATE_AERIAL); } else if (events.IsInPhase(PHASE_VOL7RON)) @@ -1024,7 +1024,7 @@ class boss_vx_001 : public CreatureScript void KilledUnit(Unit* victim) override { if (victim->GetTypeId() == TYPEID_PLAYER) - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->Talk(events.IsInPhase(PHASE_VX_001) ? SAY_VX001_SLAY : SAY_V07TRON_SLAY); } @@ -1112,7 +1112,7 @@ class boss_aerial_command_unit : public CreatureScript struct boss_aerial_command_unitAI : public BossAI { - boss_aerial_command_unitAI(Creature* creature) : BossAI(creature, BOSS_MIMIRON) + boss_aerial_command_unitAI(Creature* creature) : BossAI(creature, DATA_MIMIRON) { me->SetReactState(REACT_PASSIVE); fireFigther = false; @@ -1205,7 +1205,7 @@ class boss_aerial_command_unit : public CreatureScript void KilledUnit(Unit* victim) override { if (victim->GetTypeId() == TYPEID_PLAYER) - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->Talk(events.IsInPhase(PHASE_AERIAL_COMMAND_UNIT) ? SAY_AERIAL_SLAY : SAY_V07TRON_SLAY); } @@ -1215,7 +1215,7 @@ class boss_aerial_command_unit : public CreatureScript { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->DoAction(DO_ACTIVATE_V0L7R0N_1); } } @@ -1438,7 +1438,7 @@ class npc_mimiron_computer : public CreatureScript { case EVENT_SELF_DESTRUCT_10: Talk(SAY_SELF_DESTRUCT_10); - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->DoAction(DO_ACTIVATE_HARD_MODE); events.ScheduleEvent(EVENT_SELF_DESTRUCT_9, 60000); break; @@ -1480,7 +1480,7 @@ class npc_mimiron_computer : public CreatureScript break; case EVENT_SELF_DESTRUCT_FINALIZED: Talk(SAY_SELF_DESTRUCT_FINALIZED); - if (Creature* mimiron = instance->GetCreature(BOSS_MIMIRON)) + if (Creature* mimiron = instance->GetCreature(DATA_MIMIRON)) mimiron->AI()->DoAction(DO_ACTIVATE_SELF_DESTRUCT); DoCast(me, SPELL_SELF_DESTRUCTION_AURA); DoCast(me, SPELL_SELF_DESTRUCTION_VISUAL); @@ -1521,7 +1521,7 @@ class npc_mimiron_flames : public CreatureScript void UpdateAI(uint32 diff) override { - if (instance->GetBossState(BOSS_MIMIRON) != IN_PROGRESS) + if (instance->GetBossState(DATA_MIMIRON) != IN_PROGRESS) me->DespawnOrUnsummon(); events.Update(diff); @@ -2370,7 +2370,7 @@ class spell_mimiron_summon_assault_bot : public SpellScriptLoader { if (Unit* caster = GetCaster()) if (InstanceScript* instance = caster->GetInstanceScript()) - if (instance->GetBossState(BOSS_MIMIRON) == IN_PROGRESS) + if (instance->GetBossState(DATA_MIMIRON) == IN_PROGRESS) caster->CastSpell(caster, SPELL_SUMMON_ASSAULT_BOT, false, nullptr, aurEff, instance->GetGuidData(DATA_AERIAL_COMMAND_UNIT)); } @@ -2433,7 +2433,7 @@ class spell_mimiron_summon_fire_bot : public SpellScriptLoader { if (Unit* caster = GetCaster()) if (InstanceScript* instance = caster->GetInstanceScript()) - if (instance->GetBossState(BOSS_MIMIRON) == IN_PROGRESS) + if (instance->GetBossState(DATA_MIMIRON) == IN_PROGRESS) caster->CastSpell(caster, SPELL_SUMMON_FIRE_BOT, false, nullptr, aurEff, instance->GetGuidData(DATA_AERIAL_COMMAND_UNIT)); } @@ -2611,7 +2611,7 @@ class spell_mimiron_summon_junk_bot : public SpellScriptLoader { if (Unit* caster = GetCaster()) if (InstanceScript* instance = caster->GetInstanceScript()) - if (instance->GetBossState(BOSS_MIMIRON) == IN_PROGRESS) + if (instance->GetBossState(DATA_MIMIRON) == IN_PROGRESS) caster->CastSpell(caster, SPELL_SUMMON_JUNK_BOT, false, nullptr, aurEff, instance->GetGuidData(DATA_AERIAL_COMMAND_UNIT)); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index f9c7fc09fa7..06688479c9a 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -244,7 +244,7 @@ class boss_razorscale_controller : public CreatureScript void DoAction(int32 action) override { - if (instance->GetBossState(BOSS_RAZORSCALE) != IN_PROGRESS) + if (instance->GetBossState(DATA_RAZORSCALE) != IN_PROGRESS) return; switch (action) @@ -331,7 +331,7 @@ class go_razorscale_harpoon : public GameObjectScript bool GossipHello(Player* /*player*/) override { - if (instance->GetCreature(BOSS_RAZORSCALE)) + if (instance->GetCreature(DATA_RAZORSCALE)) me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); return true; } @@ -350,7 +350,7 @@ class boss_razorscale : public CreatureScript struct boss_razorscaleAI : public BossAI { - boss_razorscaleAI(Creature* creature) : BossAI(creature, BOSS_RAZORSCALE) + boss_razorscaleAI(Creature* creature) : BossAI(creature, DATA_RAZORSCALE) { Initialize(); // Do not let Razorscale be affected by Battle Shout buff @@ -691,7 +691,7 @@ class npc_expedition_commander : public CreatureScript switch (Phase) { case 1: - instance->SetBossState(BOSS_RAZORSCALE, IN_PROGRESS); + instance->SetBossState(DATA_RAZORSCALE, IN_PROGRESS); summons.DespawnAll(); AttackStartTimer = 1000; Phase = 2; @@ -738,7 +738,7 @@ class npc_expedition_commander : public CreatureScript Phase = 5; break; case 5: - if (Creature* razorscale = instance->GetCreature(BOSS_RAZORSCALE)) + if (Creature* razorscale = instance->GetCreature(DATA_RAZORSCALE)) { razorscale->AI()->DoAction(ACTION_EVENT_START); me->SetInCombatWith(razorscale); @@ -769,7 +769,7 @@ class npc_expedition_commander : public CreatureScript bool GossipHello(Player* player) override { InstanceScript* instance = me->GetInstanceScript(); - if (instance && instance->GetBossState(BOSS_RAZORSCALE) == NOT_STARTED) + if (instance && instance->GetBossState(DATA_RAZORSCALE) == NOT_STARTED) { player->PrepareGossipMenu(me); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index 04eed490aa2..cda3d9c65a0 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -423,7 +423,7 @@ class LightningFieldEvent : public BasicEvent { if (InstanceScript* instance = _owner->GetInstanceScript()) { - if (instance->GetBossState(BOSS_THORIM) == IN_PROGRESS) + if (instance->GetBossState(DATA_THORIM) == IN_PROGRESS) { _owner->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_FIELD); _owner->m_Events.AddEvent(this, eventTime + 1000); @@ -447,7 +447,7 @@ class boss_thorim : public CreatureScript struct boss_thorimAI : public BossAI { - boss_thorimAI(Creature* creature) : BossAI(creature, BOSS_THORIM) + boss_thorimAI(Creature* creature) : BossAI(creature, DATA_THORIM) { _encounterFinished = false; Initialize(); @@ -1158,7 +1158,7 @@ class npc_thorim_pre_phase : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) + if (Creature* thorim = _instance->GetCreature(DATA_THORIM)) thorim->AI()->DoAction(ACTION_INCREASE_PREADDS_COUNT); } @@ -1275,7 +1275,7 @@ class npc_thorim_arena_phase : public CreatureScript return; // this should only happen if theres no alive player in the arena -> summon orb - if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) + if (Creature* thorim = _instance->GetCreature(DATA_THORIM)) thorim->AI()->DoAction(ACTION_BERSERK); ScriptedAI::EnterEvadeMode(why); } @@ -1420,7 +1420,7 @@ class npc_runic_colossus : public CreatureScript // open the Runic Door _instance->HandleGameObject(_instance->GetGuidData(DATA_RUNIC_DOOR), true); - if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) + if (Creature* thorim = _instance->GetCreature(DATA_THORIM)) thorim->AI()->Talk(SAY_SPECIAL); if (Creature* giant = _instance->GetCreature(DATA_RUNE_GIANT)) @@ -2062,7 +2062,7 @@ class spell_thorim_activate_lightning_orb_periodic : public SpellScriptLoader if (!triggers.empty()) { Creature* target = Trinity::Containers::SelectRandomContainerElement(triggers); - if (Creature* thorim = instance->GetCreature(BOSS_THORIM)) + if (Creature* thorim = instance->GetCreature(DATA_THORIM)) thorim->AI()->SetGUID(target->GetGUID(), DATA_CHARGED_PILLAR); } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index a045e9b3f18..03dee360fde 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -178,7 +178,7 @@ class boss_xt002 : public CreatureScript struct boss_xt002_AI : public BossAI { - boss_xt002_AI(Creature* creature) : BossAI(creature, BOSS_XT002) + boss_xt002_AI(Creature* creature) : BossAI(creature, DATA_XT002) { Initialize(); _transferHealth = 0; @@ -460,7 +460,7 @@ class npc_xt002_heart : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (Creature* xt002 = _instance->GetCreature(BOSS_XT002)) + if (Creature* xt002 = _instance->GetCreature(DATA_XT002)) { xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetHealth()); xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE); @@ -506,7 +506,7 @@ class npc_scrapbot : public CreatureScript Initialize(); - if (Creature* xt002 = _instance->GetCreature(BOSS_XT002)) + if (Creature* xt002 = _instance->GetCreature(DATA_XT002)) me->GetMotionMaster()->MoveFollow(xt002, 0.0f, 0.0f); } @@ -514,7 +514,7 @@ class npc_scrapbot : public CreatureScript { if (_rangeCheckTimer <= diff) { - if (Creature* xt002 = _instance->GetCreature(BOSS_XT002)) + if (Creature* xt002 = _instance->GetCreature(DATA_XT002)) { if (me->IsWithinMeleeRange(xt002)) { @@ -569,7 +569,7 @@ class npc_pummeller : public CreatureScript { Initialize(); - if (Creature* xt002 = _instance->GetCreature(BOSS_XT002)) + if (Creature* xt002 = _instance->GetCreature(DATA_XT002)) { Position pos = xt002->GetPosition(); me->GetMotionMaster()->MovePoint(0, pos); @@ -683,7 +683,7 @@ class npc_boombot : public CreatureScript me->SetFloatValue(UNIT_FIELD_MAXDAMAGE, 18000.0f); /// @todo proper waypoints? - if (Creature* xt002 = _instance->GetCreature(BOSS_XT002)) + if (Creature* xt002 = _instance->GetCreature(DATA_XT002)) me->GetMotionMaster()->MoveFollow(xt002, 0.0f, 0.0f); } @@ -956,7 +956,7 @@ class spell_xt002_heart_overload_periodic : public SpellScriptLoader { uint8 a = urand(0, 4); uint32 spellId = spells[a]; - toyPile->CastSpell(toyPile, spellId, true, nullptr, nullptr, instance->GetGuidData(BOSS_XT002)); + toyPile->CastSpell(toyPile, spellId, true, nullptr, nullptr, instance->GetGuidData(DATA_XT002)); } } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index e05bfceb165..55f51bfe574 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -446,7 +446,7 @@ class boss_voice_of_yogg_saron : public CreatureScript struct boss_voice_of_yogg_saronAI : public BossAI { - boss_voice_of_yogg_saronAI(Creature* creature) : BossAI(creature, BOSS_YOGG_SARON) + boss_voice_of_yogg_saronAI(Creature* creature) : BossAI(creature, DATA_YOGG_SARON) { Initialize(); SetCombatMovement(false); @@ -530,7 +530,7 @@ class boss_voice_of_yogg_saron : public CreatureScript void JustDied(Unit* /*killer*/) override { // don't despawn Yogg-Saron's corpse, remove him from SummonList! - if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON)) + if (Creature* yogg = instance->GetCreature(DATA_YOGG_SARON)) summons.Despawn(yogg); _JustDied(); @@ -552,10 +552,10 @@ class boss_voice_of_yogg_saron : public CreatureScript { case EVENT_LOCK_DOOR: DoCast(me, SPELL_INSANE_PERIODIC); - instance->SetBossState(BOSS_YOGG_SARON, IN_PROGRESS); + instance->SetBossState(DATA_YOGG_SARON, IN_PROGRESS); break; case EVENT_EXTINGUISH_ALL_LIFE: - if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON)) + if (Creature* yogg = instance->GetCreature(DATA_YOGG_SARON)) { yogg->AI()->Talk(EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE, me); yogg->CastSpell((Unit*)nullptr, SPELL_EXTINGUISH_ALL_LIFE, true); @@ -583,7 +583,7 @@ class boss_voice_of_yogg_saron : public CreatureScript break; case EVENT_ILLUSION: { - if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON)) + if (Creature* yogg = instance->GetCreature(DATA_YOGG_SARON)) { yogg->AI()->Talk(EMOTE_YOGG_SARON_MADNESS); yogg->AI()->Talk(SAY_YOGG_SARON_MADNESS); @@ -824,7 +824,7 @@ class boss_sara : public CreatureScript break; case EVENT_TRANSFORM_4: DoCast(me, SPELL_PHASE_2_TRANSFORM); - if (Creature* yogg = _instance->GetCreature(BOSS_YOGG_SARON)) + if (Creature* yogg = _instance->GetCreature(DATA_YOGG_SARON)) DoCast(yogg, SPELL_RIDE_YOGG_SARON_VEHICLE); DoCast(me, SPELL_SHADOWY_BARRIER_SARA); _events.SetPhase(PHASE_TWO); @@ -1071,7 +1071,7 @@ class boss_brain_of_yogg_saron : public CreatureScript voice->AI()->DoAction(ACTION_PHASE_THREE); if (Creature* sara = _instance->GetCreature(DATA_SARA)) sara->AI()->DoAction(ACTION_PHASE_THREE); - if (Creature* yogg = _instance->GetCreature(BOSS_YOGG_SARON)) + if (Creature* yogg = _instance->GetCreature(DATA_YOGG_SARON)) yogg->AI()->DoAction(ACTION_PHASE_THREE); for (uint8 i = DATA_THORIM_YS; i <= DATA_MIMIRON_YS; ++i) @@ -2986,7 +2986,7 @@ class spell_yogg_saron_in_the_maws_of_the_old_god : public SpellScriptLoader { if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { - if (Creature* yogg = instance->GetCreature(BOSS_YOGG_SARON)) + if (Creature* yogg = instance->GetCreature(DATA_YOGG_SARON)) { if (yogg->FindCurrentSpellBySpellId(SPELL_DEAFENING_ROAR)) { diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index eb49e3f75e4..77ff0d2a835 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -33,48 +33,49 @@ static BossBoundaryData const boundaries = { - { BOSS_LEVIATHAN, new RectangleBoundary(148.0f, 401.3f, -155.0f, 90.0f) }, - { BOSS_IGNIS, new RectangleBoundary(495.0f, 680.0f, 90.0f, 400.0f) }, - { BOSS_RAZORSCALE, new RectangleBoundary(370.0f, 810.0f, -542.0f, -55.0f) }, - { BOSS_XT002, new RectangleBoundary(755.0f, 940.0f, -125.0f, 95.0f) }, - { BOSS_ASSEMBLY_OF_IRON, new CircleBoundary(Position(1587.2f, 121.0f), 90.0) }, - { BOSS_ALGALON, new CircleBoundary(Position(1632.668f, -307.7656f), 45.0) }, - { BOSS_ALGALON, new ZRangeBoundary(410.0f, 470.0f) }, - { BOSS_HODIR, new EllipseBoundary(Position(2001.5f, -240.0f), 50.0, 75.0) }, + { DATA_FLAME_LEVIATHAN, new RectangleBoundary(148.0f, 401.3f, -155.0f, 90.0f) }, + { DATA_IGNIS, new RectangleBoundary(495.0f, 680.0f, 90.0f, 400.0f) }, + { DATA_RAZORSCALE, new RectangleBoundary(370.0f, 810.0f, -542.0f, -55.0f) }, + { DATA_XT002, new RectangleBoundary(755.0f, 940.0f, -125.0f, 95.0f) }, + { DATA_ASSEMBLY_OF_IRON, new CircleBoundary(Position(1587.2f, 121.0f), 90.0) }, + { DATA_ALGALON, new CircleBoundary(Position(1632.668f, -307.7656f), 45.0) }, + { DATA_ALGALON, new ZRangeBoundary(410.0f, 470.0f) }, + { DATA_HODIR, new EllipseBoundary(Position(2001.5f, -240.0f), 50.0, 75.0) }, // Thorim sets boundaries dynamically - { BOSS_FREYA, new RectangleBoundary(2094.6f, 2520.0f, -250.0f, 200.0f) }, - { BOSS_MIMIRON, new CircleBoundary(Position(2744.0f, 2569.0f), 70.0) }, - { BOSS_VEZAX, new RectangleBoundary(1740.0f, 1930.0f, 31.0f, 228.0f) }, - { BOSS_YOGG_SARON, new CircleBoundary(Position(1980.42f, -27.68f), 105.0) } + { DATA_FREYA, new RectangleBoundary(2094.6f, 2520.0f, -250.0f, 200.0f) }, + { DATA_MIMIRON, new CircleBoundary(Position(2744.0f, 2569.0f), 70.0) }, + { DATA_VEZAX, new RectangleBoundary(1740.0f, 1930.0f, 31.0f, 228.0f) }, + { DATA_YOGG_SARON, new CircleBoundary(Position(1980.42f, -27.68f), 105.0) } }; static DoorData const doorData[] = { - { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM }, - { GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM }, - { GO_IRON_COUNCIL_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_ROOM }, - { GO_ARCHIVUM_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_PASSAGE }, - { GO_HODIR_ENTRANCE, BOSS_HODIR, DOOR_TYPE_ROOM }, - { GO_HODIR_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE }, - { GO_HODIR_ICE_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE }, - { GO_MIMIRON_DOOR_1, BOSS_MIMIRON, DOOR_TYPE_ROOM }, - { GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM }, - { GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM }, - { GO_THORIM_ENCOUNTER_DOOR, BOSS_THORIM, DOOR_TYPE_ROOM }, - { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_HODIR, DOOR_TYPE_PASSAGE }, - { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_MIMIRON, DOOR_TYPE_PASSAGE }, - { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_THORIM, DOOR_TYPE_PASSAGE }, - { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_FREYA, DOOR_TYPE_PASSAGE }, - { GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE }, - { GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM }, - { GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM }, - { GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM }, - { GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE }, - { GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE }, - { GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE }, + { GO_LEVIATHAN_DOOR, DATA_FLAME_LEVIATHAN, DOOR_TYPE_ROOM }, + { GO_XT_002_DOOR, DATA_XT002, DOOR_TYPE_ROOM }, + { GO_IRON_COUNCIL_DOOR, DATA_ASSEMBLY_OF_IRON, DOOR_TYPE_ROOM }, + { GO_ARCHIVUM_DOOR, DATA_ASSEMBLY_OF_IRON, DOOR_TYPE_PASSAGE }, + { GO_HODIR_ENTRANCE, DATA_HODIR, DOOR_TYPE_ROOM }, + { GO_HODIR_DOOR, DATA_HODIR, DOOR_TYPE_PASSAGE }, + { GO_HODIR_ICE_DOOR, DATA_HODIR, DOOR_TYPE_PASSAGE }, + { GO_MIMIRON_DOOR_1, DATA_MIMIRON, DOOR_TYPE_ROOM }, + { GO_MIMIRON_DOOR_2, DATA_MIMIRON, DOOR_TYPE_ROOM }, + { GO_MIMIRON_DOOR_3, DATA_MIMIRON, DOOR_TYPE_ROOM }, + { GO_THORIM_ENCOUNTER_DOOR, DATA_THORIM, DOOR_TYPE_ROOM }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, DATA_HODIR, DOOR_TYPE_PASSAGE }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, DATA_MIMIRON, DOOR_TYPE_PASSAGE }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, DATA_THORIM, DOOR_TYPE_PASSAGE }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, DATA_FREYA, DOOR_TYPE_PASSAGE }, + { GO_VEZAX_DOOR, DATA_VEZAX, DOOR_TYPE_PASSAGE }, + { GO_YOGG_SARON_DOOR, DATA_YOGG_SARON, DOOR_TYPE_ROOM }, + { GO_DOODAD_UL_SIGILDOOR_03, DATA_ALGALON, DOOR_TYPE_ROOM }, + { GO_DOODAD_UL_UNIVERSEFLOOR_01, DATA_ALGALON, DOOR_TYPE_ROOM }, + { GO_DOODAD_UL_UNIVERSEFLOOR_02, DATA_ALGALON, DOOR_TYPE_SPAWN_HOLE }, + { GO_DOODAD_UL_UNIVERSEGLOBE01, DATA_ALGALON, DOOR_TYPE_SPAWN_HOLE }, + { GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, DATA_ALGALON, DOOR_TYPE_SPAWN_HOLE }, { 0, 0, DOOR_TYPE_ROOM }, }; +/* MinionData const minionData[] = { { NPC_STEELBREAKER, BOSS_ASSEMBLY_OF_IRON }, @@ -82,22 +83,27 @@ MinionData const minionData[] = { NPC_BRUNDIR, BOSS_ASSEMBLY_OF_IRON }, { 0, 0, } }; +*/ ObjectData const creatureData[] = { - { NPC_FLAME_LEVIATHAN, BOSS_LEVIATHAN }, - { NPC_IGNIS, BOSS_IGNIS }, - { NPC_RAZORSCALE, BOSS_RAZORSCALE }, - { NPC_XT002, BOSS_XT002 }, - { NPC_KOLOGARN, BOSS_KOLOGARN }, - { NPC_AURIAYA, BOSS_AURIAYA }, - { NPC_HODIR, BOSS_HODIR }, - { NPC_THORIM, BOSS_THORIM }, - { NPC_FREYA, BOSS_FREYA }, - { NPC_MIMIRON, BOSS_MIMIRON }, - { NPC_VEZAX, BOSS_VEZAX }, - { NPC_YOGG_SARON, BOSS_YOGG_SARON }, - { NPC_ALGALON, BOSS_ALGALON }, + { NPC_FLAME_LEVIATHAN, DATA_FLAME_LEVIATHAN }, + { NPC_IGNIS, DATA_IGNIS }, + { NPC_RAZORSCALE, DATA_RAZORSCALE }, + { NPC_XT002, DATA_XT002 }, + { NPC_KOLOGARN, DATA_KOLOGARN }, + { NPC_AURIAYA, DATA_AURIAYA }, + { NPC_HODIR, DATA_HODIR }, + { NPC_THORIM, DATA_THORIM }, + { NPC_FREYA, DATA_FREYA }, + { NPC_MIMIRON, DATA_MIMIRON }, + { NPC_VEZAX, DATA_VEZAX }, + { NPC_YOGG_SARON, DATA_YOGG_SARON }, + { NPC_ALGALON, DATA_ALGALON }, + { BOSS_STEELBREAKER, DATA_STEELBREAKER }, + { BOSS_RUNEMASTER_MOLGEIM, DATA_RUNEMASTER_MOLGEIM }, + { BOSS_STORMCALLER_BRUNDIR, DATA_STORMCALLER_BRUNDIR }, + { NPC_EXPEDITION_COMMANDER, DATA_EXPEDITION_COMMANDER }, { NPC_RAZORSCALE_CONTROLLER, DATA_RAZORSCALE_CONTROL }, @@ -147,7 +153,7 @@ class instance_ulduar : public InstanceMapScript SetBossNumber(MAX_ENCOUNTER); LoadBossBoundaries(boundaries); LoadDoorData(doorData); - LoadMinionData(minionData); + //LoadMinionData(minionData); LoadObjectData(creatureData, objectData); _algalonTimer = 61; @@ -175,7 +181,6 @@ class instance_ulduar : public InstanceMapScript GuidVector LeviathanVehicleGUIDs; ObjectGuid XTToyPileGUIDs[4]; - ObjectGuid AssemblyGUIDs[3]; ObjectGuid ElderGUIDs[3]; ObjectGuid FreyaAchieveTriggerGUID; @@ -233,22 +238,22 @@ class instance_ulduar : public InstanceMapScript } // Keepers at Observation Ring - if (GetBossState(BOSS_FREYA) == DONE && _summonObservationRingKeeper[0] && !KeeperGUIDs[0]) + if (GetBossState(DATA_FREYA) == DONE && _summonObservationRingKeeper[0] && !KeeperGUIDs[0]) { _summonObservationRingKeeper[0] = false; instance->SummonCreature(NPC_FREYA_OBSERVATION_RING, ObservationRingKeepersPos[0]); } - if (GetBossState(BOSS_HODIR) == DONE && _summonObservationRingKeeper[1] && !KeeperGUIDs[1]) + if (GetBossState(DATA_HODIR) == DONE && _summonObservationRingKeeper[1] && !KeeperGUIDs[1]) { _summonObservationRingKeeper[1] = false; instance->SummonCreature(NPC_HODIR_OBSERVATION_RING, ObservationRingKeepersPos[1]); } - if (GetBossState(BOSS_THORIM) == DONE && _summonObservationRingKeeper[2] && !KeeperGUIDs[2]) + if (GetBossState(DATA_THORIM) == DONE && _summonObservationRingKeeper[2] && !KeeperGUIDs[2]) { _summonObservationRingKeeper[2] = false; instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]); } - if (GetBossState(BOSS_MIMIRON) == DONE && _summonObservationRingKeeper[3] && !KeeperGUIDs[3]) + if (GetBossState(DATA_MIMIRON) == DONE && _summonObservationRingKeeper[3] && !KeeperGUIDs[3]) { _summonObservationRingKeeper[3] = false; instance->SummonCreature(NPC_MIMIRON_OBSERVATION_RING, ObservationRingKeepersPos[3]); @@ -265,6 +270,11 @@ class instance_ulduar : public InstanceMapScript instance->SummonCreature(NPC_MIMIRON_YS, YSKeepersPos[3]); } + void Create() override + { + instance->SpawnGroupSpawn(SPAWN_GROUP_ASSEMBLY_OF_IRON, true); + } + void OnCreatureCreate(Creature* creature) override { InstanceScript::OnCreatureCreate(creature); @@ -282,7 +292,7 @@ class instance_ulduar : public InstanceMapScript case NPC_SALVAGED_DEMOLISHER: case NPC_SALVAGED_SIEGE_ENGINE: case NPC_SALVAGED_CHOPPER: - if (GetBossState(BOSS_LEVIATHAN) == DONE) + if (GetBossState(DATA_FLAME_LEVIATHAN) == DONE) DespawnLeviatanVehicle(creature); else LeviathanVehicleGUIDs.push_back(creature->GetGUID()); @@ -299,21 +309,6 @@ class instance_ulduar : public InstanceMapScript } } break; - - // Assembly of Iron - case NPC_STEELBREAKER: - AssemblyGUIDs[0] = creature->GetGUID(); - AddMinion(creature, true); - break; - case NPC_MOLGEIM: - AssemblyGUIDs[1] = creature->GetGUID(); - AddMinion(creature, true); - break; - case NPC_BRUNDIR: - AssemblyGUIDs[2] = creature->GetGUID(); - AddMinion(creature, true); - break; - // Hodir case NPC_EIVI_NIGHTFEATHER: if (TeamInInstance == HORDE) @@ -361,17 +356,17 @@ class instance_ulduar : public InstanceMapScript // Freya case NPC_IRONBRANCH: ElderGUIDs[0] = creature->GetGUID(); - if (GetBossState(BOSS_FREYA) == DONE) + if (GetBossState(DATA_FREYA) == DONE) creature->DespawnOrUnsummon(); break; case NPC_BRIGHTLEAF: ElderGUIDs[1] = creature->GetGUID(); - if (GetBossState(BOSS_FREYA) == DONE) + if (GetBossState(DATA_FREYA) == DONE) creature->DespawnOrUnsummon(); break; case NPC_STONEBARK: ElderGUIDs[2] = creature->GetGUID(); - if (GetBossState(BOSS_FREYA) == DONE) + if (GetBossState(DATA_FREYA) == DONE) creature->DespawnOrUnsummon(); break; case NPC_FREYA_ACHIEVE_TRIGGER: @@ -426,7 +421,7 @@ class instance_ulduar : public InstanceMapScript case NPC_ALGALON_STALKER_ASTEROID_TARGET_01: case NPC_ALGALON_STALKER_ASTEROID_TARGET_02: case NPC_UNLEASHED_DARK_MATTER: - if (Creature* algalon = GetCreature(BOSS_ALGALON)) + if (Creature* algalon = GetCreature(DATA_ALGALON)) algalon->AI()->JustSummoned(creature); break; } @@ -448,11 +443,6 @@ class instance_ulduar : public InstanceMapScript } } break; - case NPC_STEELBREAKER: - case NPC_MOLGEIM: - case NPC_BRUNDIR: - AddMinion(creature, false); - break; default: break; } @@ -470,7 +460,7 @@ class instance_ulduar : public InstanceMapScript break; case GO_KOLOGARN_BRIDGE: KologarnBridgeGUID = gameObject->GetGUID(); - if (GetBossState(BOSS_KOLOGARN) == DONE) + if (GetBossState(DATA_KOLOGARN) == DONE) HandleGameObject(ObjectGuid::Empty, false, gameObject); break; case GO_THORIM_DARK_IRON_PORTCULLIS: @@ -497,11 +487,11 @@ class instance_ulduar : public InstanceMapScript break; case GO_LEVIATHAN_GATE: LeviathanGateGUID = gameObject->GetGUID(); - if (GetBossState(BOSS_LEVIATHAN) == DONE) + if (GetBossState(DATA_FLAME_LEVIATHAN) == DONE) gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); break; case GO_MOLE_MACHINE: - if (GetBossState(BOSS_RAZORSCALE) == IN_PROGRESS) + if (GetBossState(DATA_RAZORSCALE) == IN_PROGRESS) gameObject->SetGoState(GO_STATE_ACTIVE); break; case GO_BRAIN_ROOM_DOOR_1: @@ -551,7 +541,7 @@ class instance_ulduar : public InstanceMapScript // Champion/Conqueror of Ulduar if (unit->GetTypeId() == TYPEID_PLAYER) { - for (uint8 i = 0; i < BOSS_ALGALON; ++i) + for (uint8 i = 0; i < DATA_ALGALON; ++i) { if (GetBossState(i) == IN_PROGRESS) { @@ -601,19 +591,19 @@ class instance_ulduar : public InstanceMapScript { // Flame Leviathan's Tower Event triggers case EVENT_TOWER_OF_STORM_DESTROYED: - if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN)) + if (Creature* flameLeviathan = GetCreature(DATA_FLAME_LEVIATHAN)) flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_STORM_DESTROYED); break; case EVENT_TOWER_OF_FROST_DESTROYED: - if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN)) + if (Creature* flameLeviathan = GetCreature(DATA_FLAME_LEVIATHAN)) flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FROST_DESTROYED); break; case EVENT_TOWER_OF_FLAMES_DESTROYED: - if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN)) + if (Creature* flameLeviathan = GetCreature(DATA_FLAME_LEVIATHAN)) flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FLAMES_DESTROYED); break; case EVENT_TOWER_OF_LIFE_DESTROYED: - if (Creature* flameLeviathan = GetCreature(BOSS_LEVIATHAN)) + if (Creature* flameLeviathan = GetCreature(DATA_FLAME_LEVIATHAN)) flameLeviathan->AI()->DoAction(ACTION_TOWER_OF_LIFE_DESTROYED); break; @@ -636,34 +626,40 @@ class instance_ulduar : public InstanceMapScript switch (type) { - case BOSS_LEVIATHAN: + case DATA_FLAME_LEVIATHAN: if (state == DONE) _events.ScheduleEvent(EVENT_DESPAWN_LEVIATHAN_VEHICLES, 5 * IN_MILLISECONDS); break; - case BOSS_IGNIS: - case BOSS_RAZORSCALE: - case BOSS_XT002: - case BOSS_ASSEMBLY_OF_IRON: - case BOSS_AURIAYA: - case BOSS_VEZAX: - case BOSS_YOGG_SARON: + case DATA_ASSEMBLY_OF_IRON: + if (state == FAIL) + { + instance->SpawnGroupDespawn(SPAWN_GROUP_ASSEMBLY_OF_IRON); + _events.ScheduleEvent(EVENT_RESPAWN_ASSEMBLY_OF_IRON, 30s); + } break; - case BOSS_MIMIRON: + case DATA_IGNIS: + case DATA_RAZORSCALE: + case DATA_XT002: + case DATA_AURIAYA: + case DATA_VEZAX: + case DATA_YOGG_SARON: + break; + case DATA_MIMIRON: if (state == DONE) instance->SummonCreature(NPC_MIMIRON_OBSERVATION_RING, ObservationRingKeepersPos[3]); break; - case BOSS_FREYA: + case DATA_FREYA: if (state == DONE) instance->SummonCreature(NPC_FREYA_OBSERVATION_RING, ObservationRingKeepersPos[0]); break; - case BOSS_IRONBRANCH: - case BOSS_STONEBARK: - case BOSS_BRIGHTLEAF: - if (GetBossState(BOSS_BRIGHTLEAF) == DONE && GetBossState(BOSS_IRONBRANCH) == DONE && GetBossState(BOSS_STONEBARK) == DONE && GetBossState(BOSS_FREYA) != DONE) + case DATA_IRONBRANCH: + case DATA_STONEBARK: + case DATA_BRIGHTLEAF: + if (GetBossState(DATA_BRIGHTLEAF) == DONE && GetBossState(DATA_IRONBRANCH) == DONE && GetBossState(DATA_STONEBARK) == DONE && GetBossState(DATA_FREYA) != DONE) if (Creature* trigger = instance->GetCreature(FreyaAchieveTriggerGUID)) trigger->CastSpell(trigger, SPELL_LUMBERJACKED_CREDIT, true); break; - case BOSS_KOLOGARN: + case DATA_KOLOGARN: if (state == DONE) { if (GameObject* gameObject = instance->GetGameObject(KologarnChestGUID)) @@ -674,7 +670,7 @@ class instance_ulduar : public InstanceMapScript HandleGameObject(KologarnBridgeGUID, false); } break; - case BOSS_HODIR: + case DATA_HODIR: if (state == DONE) { if (GameObject* HodirRareCache = instance->GetGameObject(HodirRareCacheGUID)) @@ -686,10 +682,10 @@ class instance_ulduar : public InstanceMapScript instance->SummonCreature(NPC_HODIR_OBSERVATION_RING, ObservationRingKeepersPos[1]); } break; - case BOSS_THORIM: + case DATA_THORIM: if (state == DONE) { - if (Creature* thorim = GetCreature(BOSS_THORIM)) + if (Creature* thorim = GetCreature(DATA_THORIM)) { if (GameObject* cache = instance->GetGameObject(thorim->AI()->GetData(DATA_THORIM_HARDMODE) ? CacheOfStormsHardmodeGUID : CacheOfStormsGUID)) { @@ -707,7 +703,7 @@ class instance_ulduar : public InstanceMapScript DoCloseDoorOrButton(ThorimDarkIronPortcullisGUID); } break; - case BOSS_ALGALON: + case DATA_ALGALON: if (state == DONE) { _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); @@ -764,7 +760,7 @@ class instance_ulduar : public InstanceMapScript { case DATA_COLOSSUS: ColossusData = data; - if (data >= 2 && GetBossState(BOSS_LEVIATHAN) == NOT_STARTED) + if (data >= 2 && GetBossState(DATA_FLAME_LEVIATHAN) == NOT_STARTED) { _events.ScheduleEvent(EVENT_LEVIATHAN_BREAK_DOOR, 5 * IN_MILLISECONDS); SaveToDB(); @@ -774,7 +770,7 @@ class instance_ulduar : public InstanceMapScript HodirRareCacheData = data; if (!HodirRareCacheData) { - if (Creature* hodir = GetCreature(BOSS_HODIR)) + if (Creature* hodir = GetCreature(DATA_HODIR)) if (GameObject* gameObject = instance->GetGameObject(HodirRareCacheGUID)) hodir->RemoveGameObject(gameObject, false); } @@ -817,21 +813,12 @@ class instance_ulduar : public InstanceMapScript case DATA_TOY_PILE_2: case DATA_TOY_PILE_3: return XTToyPileGUIDs[data - DATA_TOY_PILE_0]; - - // Assembly of Iron - case DATA_STEELBREAKER: - return AssemblyGUIDs[0]; - case DATA_MOLGEIM: - return AssemblyGUIDs[1]; - case DATA_BRUNDIR: - return AssemblyGUIDs[2]; - // Freya - case BOSS_BRIGHTLEAF: + case DATA_BRIGHTLEAF: return ElderGUIDs[0]; - case BOSS_IRONBRANCH: + case DATA_IRONBRANCH: return ElderGUIDs[1]; - case BOSS_STONEBARK: + case DATA_STONEBARK: return ElderGUIDs[2]; // Mimiron @@ -927,43 +914,43 @@ class instance_ulduar : public InstanceMapScript return keepersCount == 0; case CRITERIA_C_O_U_LEVIATHAN_10: case CRITERIA_C_O_U_LEVIATHAN_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_LEVIATHAN)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_FLAME_LEVIATHAN)) == 0; case CRITERIA_C_O_U_IGNIS_10: case CRITERIA_C_O_U_IGNIS_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_IGNIS)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_IGNIS)) == 0; case CRITERIA_C_O_U_RAZORSCALE_10: case CRITERIA_C_O_U_RAZORSCALE_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_RAZORSCALE)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_RAZORSCALE)) == 0; case CRITERIA_C_O_U_XT002_10: case CRITERIA_C_O_U_XT002_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_XT002)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_XT002)) == 0; case CRITERIA_C_O_U_IRON_COUNCIL_10: case CRITERIA_C_O_U_IRON_COUNCIL_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_ASSEMBLY_OF_IRON)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_ASSEMBLY_OF_IRON)) == 0; case CRITERIA_C_O_U_KOLOGARN_10: case CRITERIA_C_O_U_KOLOGARN_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_KOLOGARN)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_KOLOGARN)) == 0; case CRITERIA_C_O_U_AURIAYA_10: case CRITERIA_C_O_U_AURIAYA_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_AURIAYA)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_AURIAYA)) == 0; case CRITERIA_C_O_U_HODIR_10: case CRITERIA_C_O_U_HODIR_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_HODIR)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_HODIR)) == 0; case CRITERIA_C_O_U_THORIM_10: case CRITERIA_C_O_U_THORIM_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_THORIM)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_THORIM)) == 0; case CRITERIA_C_O_U_FREYA_10: case CRITERIA_C_O_U_FREYA_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_FREYA)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_FREYA)) == 0; case CRITERIA_C_O_U_MIMIRON_10: case CRITERIA_C_O_U_MIMIRON_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_MIMIRON)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_MIMIRON)) == 0; case CRITERIA_C_O_U_VEZAX_10: case CRITERIA_C_O_U_VEZAX_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_VEZAX)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_VEZAX)) == 0; case CRITERIA_C_O_U_YOGG_SARON_10: case CRITERIA_C_O_U_YOGG_SARON_25: - return (_CoUAchivePlayerDeathMask & (1 << BOSS_YOGG_SARON)) == 0; + return (_CoUAchivePlayerDeathMask & (1 << DATA_YOGG_SARON)) == 0; } return false; @@ -988,7 +975,7 @@ class instance_ulduar : public InstanceMapScript data >> _algalonTimer; data >> tempState; _algalonSummoned = tempState != 0; - if (_algalonSummoned && GetBossState(BOSS_ALGALON) != DONE) + if (_algalonSummoned && GetBossState(DATA_ALGALON) != DONE) { _summonAlgalon = true; if (_algalonTimer && _algalonTimer <= 60) @@ -1005,16 +992,19 @@ class instance_ulduar : public InstanceMapScript _summonYSKeeper[i] = tempState != 0; } - if (GetBossState(BOSS_FREYA) == DONE && !_summonYSKeeper[0]) + if (GetBossState(DATA_FREYA) == DONE && !_summonYSKeeper[0]) _summonObservationRingKeeper[0] = true; - if (GetBossState(BOSS_HODIR) == DONE && !_summonYSKeeper[1]) + if (GetBossState(DATA_HODIR) == DONE && !_summonYSKeeper[1]) _summonObservationRingKeeper[1] = true; - if (GetBossState(BOSS_THORIM) == DONE && !_summonYSKeeper[2]) + if (GetBossState(DATA_THORIM) == DONE && !_summonYSKeeper[2]) _summonObservationRingKeeper[2] = true; - if (GetBossState(BOSS_MIMIRON) == DONE && !_summonYSKeeper[3]) + if (GetBossState(DATA_MIMIRON) == DONE && !_summonYSKeeper[3]) _summonObservationRingKeeper[3] = true; data >> _CoUAchivePlayerDeathMask; + + if (GetBossState(DATA_ASSEMBLY_OF_IRON) != DONE) + instance->SpawnGroupSpawn(SPAWN_GROUP_ASSEMBLY_OF_IRON, true); } void Update(uint32 diff) override @@ -1037,7 +1027,7 @@ class instance_ulduar : public InstanceMapScript { DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 0); _events.CancelEvent(EVENT_UPDATE_ALGALON_TIMER); - if (Creature* algalon = GetCreature(BOSS_ALGALON)) + if (Creature* algalon = GetCreature(DATA_ALGALON)) algalon->AI()->DoAction(EVENT_DESPAWN_ALGALON); } break; @@ -1049,11 +1039,17 @@ class instance_ulduar : public InstanceMapScript DespawnLeviatanVehicle(vehicleCreature); break; case EVENT_LEVIATHAN_BREAK_DOOR: - if (Creature* leviathan = GetCreature(BOSS_LEVIATHAN)) + if (Creature* leviathan = GetCreature(DATA_FLAME_LEVIATHAN)) leviathan->AI()->DoAction(ACTION_MOVE_TO_CENTER_POSITION); if (GameObject* gameObject = instance->GetGameObject(LeviathanGateGUID)) gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); break; + case EVENT_RESPAWN_ASSEMBLY_OF_IRON: + SetBossState(DATA_ASSEMBLY_OF_IRON, NOT_STARTED); + instance->SpawnGroupSpawn(SPAWN_GROUP_ASSEMBLY_OF_IRON, true); + break; + default: + break; } } } @@ -1073,7 +1069,7 @@ class instance_ulduar : public InstanceMapScript // Leviathan doors are set to DOOR_TYPE_ROOM except the one it uses to enter the room // which has to be set to DOOR_TYPE_PASSAGE if (door->GetEntry() == GO_LEVIATHAN_DOOR && door->GetPositionX() > 400.f) - door->SetGoState(GetBossState(BOSS_LEVIATHAN) == DONE ? GO_STATE_ACTIVE : GO_STATE_READY); + door->SetGoState(GetBossState(DATA_FLAME_LEVIATHAN) == DONE ? GO_STATE_ACTIVE : GO_STATE_READY); else InstanceScript::UpdateDoorState(door); } @@ -1085,9 +1081,9 @@ class instance_ulduar : public InstanceMapScript if (door->GetEntry() == GO_LEVIATHAN_DOOR && door->GetPositionX() > 400.f) { if (add) - GetBossInfo(BOSS_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].insert(door->GetGUID()); + GetBossInfo(DATA_FLAME_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].insert(door->GetGUID()); else - GetBossInfo(BOSS_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].erase(door->GetGUID()); + GetBossInfo(DATA_FLAME_LEVIATHAN)->door[DOOR_TYPE_PASSAGE].erase(door->GetGUID()); if (add) UpdateDoorState(door); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 5f07fdad555..3a7df5df2e6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -27,27 +27,27 @@ extern Position const ObservationRingKeepersPos[4]; extern Position const YSKeepersPos[4]; extern Position const AlgalonLandPos; +static constexpr uint8 const MAX_ENCOUNTER = 17; + enum UlduarBosses { - MAX_ENCOUNTER = 17, - - BOSS_LEVIATHAN = 0, - BOSS_IGNIS = 1, - BOSS_RAZORSCALE = 2, - BOSS_XT002 = 3, - BOSS_ASSEMBLY_OF_IRON = 4, - BOSS_KOLOGARN = 5, - BOSS_AURIAYA = 6, - BOSS_HODIR = 7, - BOSS_THORIM = 8, - BOSS_FREYA = 9, - BOSS_MIMIRON = 10, - BOSS_VEZAX = 11, - BOSS_YOGG_SARON = 12, - BOSS_ALGALON = 13, - BOSS_BRIGHTLEAF = 14, - BOSS_IRONBRANCH = 15, - BOSS_STONEBARK = 16, + DATA_FLAME_LEVIATHAN = 0, + DATA_IGNIS = 1, + DATA_RAZORSCALE = 2, + DATA_XT002 = 3, + DATA_ASSEMBLY_OF_IRON = 4, + DATA_KOLOGARN = 5, + DATA_AURIAYA = 6, + DATA_HODIR = 7, + DATA_THORIM = 8, + DATA_FREYA = 9, + DATA_MIMIRON = 10, + DATA_VEZAX = 11, + DATA_YOGG_SARON = 12, + DATA_ALGALON = 13, + DATA_BRIGHTLEAF = 14, + DATA_IRONBRANCH = 15, + DATA_STONEBARK = 16 }; enum UlduarNPCs @@ -64,9 +64,6 @@ enum UlduarNPCs NPC_EXPEDITION_COMMANDER = 33210, NPC_XT002 = 33293, NPC_XT_TOY_PILE = 33337, - NPC_STEELBREAKER = 32867, - NPC_MOLGEIM = 32927, - NPC_BRUNDIR = 32857, NPC_KOLOGARN = 32930, NPC_FOCUSED_EYEBEAM = 33632, NPC_FOCUSED_EYEBEAM_RIGHT = 33802, @@ -82,6 +79,11 @@ enum UlduarNPCs NPC_YOGG_SARON = 33288, NPC_ALGALON = 32871, + // Assembly of Iron + BOSS_STEELBREAKER = 32867, + BOSS_RUNEMASTER_MOLGEIM = 32927, + BOSS_STORMCALLER_BRUNDIR = 32857, + //XT002 NPC_XS013_SCRAPBOT = 33343, @@ -400,8 +402,8 @@ enum UlduarData // Assembly of Iron DATA_STEELBREAKER, - DATA_MOLGEIM, - DATA_BRUNDIR, + DATA_RUNEMASTER_MOLGEIM, + DATA_STORMCALLER_BRUNDIR, // Hodir DATA_HODIR_RARE_CACHE, @@ -478,11 +480,17 @@ enum UlduarSharedSpells enum UlduarEvents { - EVENT_DESPAWN_ALGALON = 1, - EVENT_UPDATE_ALGALON_TIMER = 2, - ACTION_INIT_ALGALON = 6, - EVENT_DESPAWN_LEVIATHAN_VEHICLES = 7, - EVENT_LEVIATHAN_BREAK_DOOR = 8 + EVENT_DESPAWN_ALGALON = 1, + EVENT_UPDATE_ALGALON_TIMER = 2, + ACTION_INIT_ALGALON = 6, + EVENT_DESPAWN_LEVIATHAN_VEHICLES = 7, + EVENT_LEVIATHAN_BREAK_DOOR = 8, + EVENT_RESPAWN_ASSEMBLY_OF_IRON = 9 +}; + +enum UlduarSpawnGroups +{ + SPAWN_GROUP_ASSEMBLY_OF_IRON = 67 }; enum YoggSaronIllusions @@ -498,6 +506,8 @@ inline AI* GetUlduarAI(T* obj) return GetInstanceAI(obj, UlduarScriptName); } +#define RegisterUlduarCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUlduarAI) + class KeeperDespawnEvent : public BasicEvent { public: