diff options
| author | offl <11556157+offl@users.noreply.github.com> | 2025-05-17 13:57:22 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-17 12:57:22 +0200 |
| commit | f7f64edbbe03f0ee30c00e78cbef59222acfb066 (patch) | |
| tree | 4f3fa87a5314d861b8a0e38c0873fffe734150aa /src | |
| parent | 2f331b2fe2699296030312cbba218499daef9ecc (diff) | |
Scripts/SteamVault: Modernize scripts (#30948)
Diffstat (limited to 'src')
3 files changed, 263 insertions, 322 deletions
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp index ce61bc7e4bc..da6666a59a7 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp @@ -15,172 +15,123 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +/* Timers requires update */ + #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "steam_vault.h" -enum Yells +enum ThespiaTexts { SAY_SUMMON = 0, SAY_AGGRO = 1, SAY_SLAY = 2, - SAY_DEAD = 3, + SAY_DEATH = 3 }; -enum Spells +enum ThespiaSpells { SPELL_LIGHTNING_CLOUD = 25033, SPELL_LUNG_BURST = 31481, - SPELL_ENVELOPING_WINDS = 31718 + SPELL_ENVELOPING_WINDS = 31718, + + SPELL_WATER_BOLT_VOLLEY = 34449 }; -enum Events +enum ThespiaEvents { EVENT_LIGHTNING_CLOUD = 1, EVENT_LUNG_BURST, EVENT_ENVELOPING_WINDS }; -class boss_hydromancer_thespia : public CreatureScript +// 17797 - Hydromancer Thespia +struct boss_hydromancer_thespia : public BossAI { - public: - boss_hydromancer_thespia() : CreatureScript("boss_hydromancer_thespia") { } - - struct boss_thespiaAI : public BossAI + boss_hydromancer_thespia(Creature* creature) : BossAI(creature, DATA_HYDROMANCER_THESPIA) { } + + void JustEngagedWith(Unit* who) override + { + Talk(SAY_AGGRO); + BossAI::JustEngagedWith(who); + + events.ScheduleEvent(EVENT_LIGHTNING_CLOUD, 10s, 15s); + events.ScheduleEvent(EVENT_LUNG_BURST, 7s, 12s); + events.ScheduleEvent(EVENT_ENVELOPING_WINDS, 10s, 15s); + } + + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } + + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + _JustDied(); + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) { - boss_thespiaAI(Creature* creature) : BossAI(creature, DATA_HYDROMANCER_THESPIA) { } - - void Reset() override - { - _Reset(); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEAD); - _JustDied(); - } - - void KilledUnit(Unit* who) override - { - if (who->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_SLAY); - } - - void JustEngagedWith(Unit* who) override - { - Talk(SAY_AGGRO); - BossAI::JustEngagedWith(who); - - events.ScheduleEvent(EVENT_LIGHTNING_CLOUD, 15s); - events.ScheduleEvent(EVENT_LUNG_BURST, 7s); - events.ScheduleEvent(EVENT_ENVELOPING_WINDS, 9s); - } - - void ExecuteEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_LIGHTNING_CLOUD: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true)) - DoCast(target, SPELL_LIGHTNING_CLOUD); - // cast twice in Heroic mode - if (IsHeroic()) - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true)) - DoCast(target, SPELL_LIGHTNING_CLOUD); - - events.ScheduleEvent(EVENT_LIGHTNING_CLOUD, 15s, 25s); - break; - case EVENT_LUNG_BURST: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true)) - DoCast(target, SPELL_LUNG_BURST); - events.ScheduleEvent(EVENT_LUNG_BURST, 7s, 12s); - break; - case EVENT_ENVELOPING_WINDS: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 35.0f, true)) - DoCast(target, SPELL_ENVELOPING_WINDS); - // cast twice in Heroic mode - if (IsHeroic()) - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 35.0f, true)) - DoCast(target, SPELL_ENVELOPING_WINDS); - - events.ScheduleEvent(EVENT_ENVELOPING_WINDS, 10s, 15s); - break; - default: - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetSteamVaultAI<boss_thespiaAI>(creature); + case EVENT_LIGHTNING_CLOUD: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true)) + DoCast(target, SPELL_LIGHTNING_CLOUD); + events.Repeat(15s, 25s); + break; + case EVENT_LUNG_BURST: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true)) + DoCast(target, SPELL_LUNG_BURST); + events.Repeat(7s, 12s); + break; + case EVENT_ENVELOPING_WINDS: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 35.0f, true)) + DoCast(target, SPELL_ENVELOPING_WINDS); + events.Repeat(10s, 15s); + break; + default: + break; } + } }; -enum CoilfangWaterElemental +// 17917 - Coilfang Water Elemental +struct npc_coilfang_waterelemental : public ScriptedAI { - EVENT_WATER_BOLT_VOLLEY = 1, - SPELL_WATER_BOLT_VOLLEY = 34449 -}; + npc_coilfang_waterelemental(Creature* creature) : ScriptedAI(creature) { } -class npc_coilfang_waterelemental : public CreatureScript -{ - public: - npc_coilfang_waterelemental() : CreatureScript("npc_coilfang_waterelemental") { } + void Reset() override + { + _scheduler.CancelAll(); + } - struct npc_coilfang_waterelementalAI : public ScriptedAI - { - npc_coilfang_waterelementalAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, 3s, 6s); - } - - 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_WATER_BOLT_VOLLEY: - DoCast(me, SPELL_WATER_BOLT_VOLLEY); - _events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, 7s, 12s); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override + void JustEngagedWith(Unit* /*who*/) override + { + _scheduler.Schedule(4s, 12s, [this](TaskContext task) { - return GetSteamVaultAI<npc_coilfang_waterelementalAI>(creature); - } + DoCastSelf(SPELL_WATER_BOLT_VOLLEY); + task.Repeat(8s, 15s); + }); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _scheduler.Update(diff); + + DoMeleeAttackIfReady(); + } + +private: + TaskScheduler _scheduler; }; void AddSC_boss_hydromancer_thespia() { - new boss_hydromancer_thespia(); - new npc_coilfang_waterelemental(); + RegisterSteamVaultCreatureAI(boss_hydromancer_thespia); + RegisterSteamVaultCreatureAI(npc_coilfang_waterelemental); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp index c28fab71823..dbd8522c400 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp @@ -15,19 +15,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Mekgineer_Steamrigger -SD%Complete: 60 -SDComment: Mechanics' interrrupt heal doesn't work very well, also a proper movement needs to be implemented -> summon further away and move towards target to repair. -SDCategory: Coilfang Resevoir, The Steamvault -EndScriptData */ +/* Timers requires update */ #include "ScriptMgr.h" -#include "InstanceScript.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "InstanceScript.h" +#include "MotionMaster.h" #include "steam_vault.h" -enum Yells +enum SteamriggerTexts { SAY_MECHANICS = 0, SAY_AGGRO = 1, @@ -35,244 +32,237 @@ enum Yells SAY_DEATH = 3 }; -enum Spells +enum SteamriggerSpells { SPELL_SUPER_SHRINK_RAY = 31485, SPELL_SAW_BLADE = 31486, SPELL_ELECTRIFIED_NET = 35107, + SPELL_SUMMON_GNOME_1 = 31528, + SPELL_SUMMON_GNOME_2 = 31529, + SPELL_SUMMON_GNOME_3 = 31530, + SPELL_SUMMON_GNOMES = 31531, + SPELL_DISPEL_MAGIC = 17201, - SPELL_REPAIR = 31532, - H_SPELL_REPAIR = 37936 + SPELL_REPAIR = 31532 +}; + +enum SteamriggerEvents +{ + EVENT_SHRINK = 1, + EVENT_SAW_BLADE, + EVENT_ELECTRIFIED_NET, + EVENT_SUMMON, + EVENT_SUMMON_H }; -enum Creatures +enum SteamriggerMisc { - NPC_STREAMRIGGER_MECHANIC = 17951 + POINT_REPAIR = 1 }; -class boss_mekgineer_steamrigger : public CreatureScript +enum SteamriggerPhases : uint8 { -public: - boss_mekgineer_steamrigger() : CreatureScript("boss_mekgineer_steamrigger") { } + PHASE_NONE = 0, + PHASE_HEALTH_75, + PHASE_HEALTH_50, + PHASE_HEALTH_25 +}; - CreatureAI* GetAI(Creature* creature) const override +// 17796 - Mekgineer Steamrigger +struct boss_mekgineer_steamrigger : public BossAI +{ + boss_mekgineer_steamrigger(Creature* creature) : BossAI(creature, DATA_MEKGINEER_STEAMRIGGER), _phase(PHASE_NONE) { } + + void Reset() override { - return GetSteamVaultAI<boss_mekgineer_steamriggerAI>(creature); + _Reset(); + _phase = PHASE_NONE; } - struct boss_mekgineer_steamriggerAI : public ScriptedAI + void JustEngagedWith(Unit* who) override { - boss_mekgineer_steamriggerAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } - - void Initialize() - { - Shrink_Timer = 20000; - Saw_Blade_Timer = 15000; - Electrified_Net_Timer = 10000; - - Summon75 = false; - Summon50 = false; - Summon25 = false; - } - - InstanceScript* instance; + Talk(SAY_AGGRO); + BossAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_SHRINK, 20s); + events.ScheduleEvent(EVENT_SAW_BLADE, 5s, 20s); + events.ScheduleEvent(EVENT_ELECTRIFIED_NET, 20s, 30s); + if (IsHeroic()) + events.ScheduleEvent(EVENT_SUMMON_H, 15s, 20s); + } - uint32 Shrink_Timer; - uint32 Saw_Blade_Timer; - uint32 Electrified_Net_Timer; - bool Summon75; - bool Summon50; - bool Summon25; + // Do not despawn mechanics + void JustSummoned(Creature* /*summon*/) override { } - void Reset() override + void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override + { + if (_phase < PHASE_HEALTH_75 && !IsHeroic() && me->HealthBelowPctDamaged(75, damage)) { - Initialize(); - - instance->SetBossState(DATA_MEKGINEER_STEAMRIGGER, NOT_STARTED); + _phase++; + events.ScheduleEvent(EVENT_SUMMON, 0s); } - - void JustDied(Unit* /*killer*/) override + if (_phase < PHASE_HEALTH_50 && !IsHeroic() && me->HealthBelowPctDamaged(50, damage)) { - Talk(SAY_DEATH); - - instance->SetBossState(DATA_MEKGINEER_STEAMRIGGER, DONE); + _phase++; + events.ScheduleEvent(EVENT_SUMMON, 0s); } - - void KilledUnit(Unit* /*victim*/) override + if (_phase < PHASE_HEALTH_25 && !IsHeroic() && me->HealthBelowPctDamaged(25, damage)) { - Talk(SAY_SLAY); + _phase++; + events.ScheduleEvent(EVENT_SUMMON, 0s); } + } - void JustEngagedWith(Unit* /*who*/) override - { - Talk(SAY_AGGRO); + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_SLAY); + } - instance->SetBossState(DATA_MEKGINEER_STEAMRIGGER, IN_PROGRESS); - } + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + _JustDied(); + } - //no known summon spells exist - void SummonMechanichs() - { - Talk(SAY_MECHANICS); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - DoSpawnCreature(NPC_STREAMRIGGER_MECHANIC, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240s); - DoSpawnCreature(NPC_STREAMRIGGER_MECHANIC, -5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240s); - DoSpawnCreature(NPC_STREAMRIGGER_MECHANIC, -5, -5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240s); + events.Update(diff); - if (rand32() % 2) - DoSpawnCreature(NPC_STREAMRIGGER_MECHANIC, 5, -7, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240s); - if (rand32() % 2) - DoSpawnCreature(NPC_STREAMRIGGER_MECHANIC, 7, -5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240s); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void UpdateAI(uint32 diff) override + while (uint32 eventId = events.ExecuteEvent()) { - if (!UpdateVictim()) - return; - - if (Shrink_Timer <= diff) - { - DoCastVictim(SPELL_SUPER_SHRINK_RAY); - Shrink_Timer = 20000; - } else Shrink_Timer -= diff; - - if (Saw_Blade_Timer <= diff) + switch (eventId) { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1)) - DoCast(target, SPELL_SAW_BLADE); - else - DoCastVictim(SPELL_SAW_BLADE); - - Saw_Blade_Timer = 15000; - } else Saw_Blade_Timer -= diff; - - if (Electrified_Net_Timer <= diff) - { - DoCastVictim(SPELL_ELECTRIFIED_NET); - Electrified_Net_Timer = 10000; + case EVENT_SHRINK: + DoCastSelf(SPELL_SUPER_SHRINK_RAY); + events.Repeat(15s, 25s); + break; + case EVENT_SAW_BLADE: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1)) + DoCast(target, SPELL_SAW_BLADE); + events.Repeat(10s, 20s); + break; + case EVENT_ELECTRIFIED_NET: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(target, SPELL_ELECTRIFIED_NET); + events.Repeat(15s, 25s); + break; + case EVENT_SUMMON: + Talk(SAY_MECHANICS); + DoCastSelf(SPELL_SUMMON_GNOMES); + break; + case EVENT_SUMMON_H: + DoCastSelf(RAND(SPELL_SUMMON_GNOME_1, SPELL_SUMMON_GNOME_2, SPELL_SUMMON_GNOME_3)); + events.Repeat(20s); + break; + default: + break; } - else Electrified_Net_Timer -= diff; - if (!Summon75) - { - if (HealthBelowPct(75)) - { - SummonMechanichs(); - Summon75 = true; - } - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - if (!Summon50) - { - if (HealthBelowPct(50)) - { - SummonMechanichs(); - Summon50 = true; - } - } + DoMeleeAttackIfReady(); + } - if (!Summon25) - { - if (HealthBelowPct(25)) - { - SummonMechanichs(); - Summon25 = true; - } - } +private: + uint8 _phase; +}; - DoMeleeAttackIfReady(); - } - }; +// 17951 - Steamrigger Mechanic +struct npc_steamrigger_mechanic : public ScriptedAI +{ + npc_steamrigger_mechanic(Creature* creature) : ScriptedAI(creature) { } -}; + void Reset() override + { + _scheduler.CancelAll(); + } + + void IsSummonedBy(WorldObject* ownerWO) override + { + me->SetReactState(REACT_DEFENSIVE); -#define MAX_REPAIR_RANGE (13.0f) //we should be at least at this range for repair -#define MIN_REPAIR_RANGE (7.0f) //we can stop movement at this range to repair but not required + Creature* owner = ownerWO->ToCreature(); + if (!owner) + return; -class npc_steamrigger_mechanic : public CreatureScript -{ -public: - npc_steamrigger_mechanic() : CreatureScript("npc_steamrigger_mechanic") { } + float x, y, z; + owner->GetContactPoint(me, x, y, z); + me->GetMotionMaster()->MovePoint(POINT_REPAIR, x, y, z); + } - CreatureAI* GetAI(Creature* creature) const override + void MovementInform(uint32 type, uint32 pointId) override { - return GetSteamVaultAI<npc_steamrigger_mechanicAI>(creature); + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == POINT_REPAIR) + DoCastSelf(SPELL_REPAIR); } - struct npc_steamrigger_mechanicAI : public ScriptedAI + void JustEngagedWith(Unit* /*who*/) override { - npc_steamrigger_mechanicAI(Creature* creature) : ScriptedAI(creature) + _scheduler.Schedule(5s, 10s, [this](TaskContext task) { - Initialize(); - instance = creature->GetInstanceScript(); - } + DoCastSelf(SPELL_DISPEL_MAGIC); + task.Repeat(5s, 10s); + }); - void Initialize() + _scheduler.Schedule(5s, [this](TaskContext task) { - Repair_Timer = 2000; - } + DoCastSelf(SPELL_REPAIR); + task.Repeat(5s); + }); + } - InstanceScript* instance; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - uint32 Repair_Timer; + _scheduler.Update(diff); - void Reset() override - { - Initialize(); - } + DoMeleeAttackIfReady(); + } - void MoveInLineOfSight(Unit* /*who*/) override - { - //react only if attacked - } +private: + TaskScheduler _scheduler; +}; - void JustEngagedWith(Unit* /*who*/) override { } +// 31531 - Summon Gnomes +class spell_mekgineer_steamrigger_summon_gnomes : public AuraScript +{ + PrepareAuraScript(spell_mekgineer_steamrigger_summon_gnomes); - void UpdateAI(uint32 diff) override - { - if (Repair_Timer <= diff) - { - if (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == IN_PROGRESS) - { - if (Creature* mekgineer = instance->GetCreature(DATA_MEKGINEER_STEAMRIGGER)) - { - if (me->IsWithinDistInMap(mekgineer, MAX_REPAIR_RANGE)) - { - //are we already channeling? Doesn't work very well, find better check? - if (!me->GetChannelSpellId()) - { - //me->GetMotionMaster()->MovementExpired(); - //me->GetMotionMaster()->MoveIdle(); - - DoCast(me, SPELL_REPAIR, true); - } - Repair_Timer = 5000; - } - else - { - //me->GetMotionMaster()->MovementExpired(); - //me->GetMotionMaster()->MoveFollow(pMekgineer, 0, 0); - } - } - } else Repair_Timer = 5000; - } else Repair_Timer -= diff; - - if (!UpdateVictim()) - return; + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_SUMMON_GNOME_1, SPELL_SUMMON_GNOME_2, SPELL_SUMMON_GNOME_3 }); + } - DoMeleeAttackIfReady(); - } - }; + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_SUMMON_GNOME_1, true); + target->CastSpell(target, SPELL_SUMMON_GNOME_2, true); + target->CastSpell(target, SPELL_SUMMON_GNOME_3, true); + } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_mekgineer_steamrigger_summon_gnomes::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } }; void AddSC_boss_mekgineer_steamrigger() { - new boss_mekgineer_steamrigger(); - new npc_steamrigger_mechanic(); + RegisterSteamVaultCreatureAI(boss_mekgineer_steamrigger); + RegisterSteamVaultCreatureAI(npc_steamrigger_mechanic); + RegisterSpellScript(spell_mekgineer_steamrigger_summon_gnomes); } diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h index 739a397a1bb..4de2ada719c 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h @@ -67,6 +67,6 @@ inline AI* GetSteamVaultAI(T* obj) return GetInstanceAI<AI>(obj, SteamVaultScriptName); } -#define RegisterSteamVaultAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSteamVaultAI) +#define RegisterSteamVaultCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSteamVaultAI) #endif |
