aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/3.3.5/2025_09_13_01_world.sql26
-rw-r--r--src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp375
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp18
3 files changed, 279 insertions, 140 deletions
diff --git a/sql/updates/world/3.3.5/2025_09_13_01_world.sql b/sql/updates/world/3.3.5/2025_09_13_01_world.sql
new file mode 100644
index 00000000000..2467ed8bc29
--- /dev/null
+++ b/sql/updates/world/3.3.5/2025_09_13_01_world.sql
@@ -0,0 +1,26 @@
+--
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN (
+'spell_moam_summon_mana_fiends',
+'spell_moam_energize',
+'spell_moam_drain_mana',
+'spell_moam_drain_mana_effect',
+'spell_gen_zero_mana_full_health');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(25684, 'spell_moam_summon_mana_fiends'),
+(25685, 'spell_moam_energize'),
+(25676, 'spell_moam_drain_mana'),
+(25671, 'spell_moam_drain_mana_effect'),
+(25755, 'spell_moam_drain_mana_effect'),
+(23777, 'spell_gen_zero_mana_full_health');
+
+DELETE FROM `creature_text` WHERE `CreatureID` = 15340 AND `GroupID` = 2;
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(15340,2,0,"%s drains your mana and turns to stone.",16,0,100,0,0,0,11474,0,"moam EMOTE_ENERGIZE");
+
+UPDATE `creature_template` SET `AIName` = 'SmartAI', `flags_extra` = `flags_extra`&~2 WHERE `entry` = 15527;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = 15527 AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_param4`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(15527,0,0,0,37,0,100,0,0,0,0,0,0,116,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Mana Fiend - On AI Initialize - Set Corpse Delay"),
+(15527,0,1,0,11,0,100,0,0,0,0,0,0,38,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Mana Fiend - On Spawn - Set In Combat With Zone"),
+(15527,0,2,0,0,0,100,0,5000,7000,5000,7000,0,11,25679,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Mana Fiend - In Combat - Cast 'Arcane Explosion'"),
+(15527,0,3,0,13,0,100,0,10000,20000,0,0,0,11,15122,0,0,0,0,0,2,0,0,0,0,0,0,0,0,"Mana Fiend - Target Casting - Cast 'Counterspell'");
diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp
index 484144c389b..74d89d99ab2 100644
--- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp
+++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp
@@ -17,177 +17,272 @@
#include "ScriptMgr.h"
#include "Containers.h"
+#include "Player.h"
#include "ScriptedCreature.h"
+#include "SpellInfo.h"
+#include "SpellScript.h"
#include "ruins_of_ahnqiraj.h"
-enum Texts
+enum MoamTexts
{
- EMOTE_AGGRO = 0,
- EMOTE_MANA_FULL = 1
+ EMOTE_AGGRO = 0,
+ EMOTE_MANA_FULL = 1,
+ EMOTE_ENERGIZE = 2
};
-enum Spells
+enum MoamSpells
{
+ // Combat
SPELL_TRAMPLE = 15550,
- SPELL_DRAIN_MANA = 25671,
+ SPELL_DRAIN_MANA = 25676,
SPELL_ARCANE_ERUPTION = 25672,
- SPELL_SUMMON_MANA_FIEND_1 = 25681, // TARGET_DEST_CASTER_FRONT
- SPELL_SUMMON_MANA_FIEND_2 = 25682, // TARGET_DEST_CASTER_LEFT
- SPELL_SUMMON_MANA_FIEND_3 = 25683, // TARGET_DEST_CASTER_RIGHT
- SPELL_ENERGIZE = 25685
+ SPELL_SUMMON_MANA_FIENDS = 25684,
+ SPELL_ENERGIZE = 25685,
+
+ // Misc
+ SPELL_ZERO_MANA_FULL_HEALTH = 23777,
+ SPELL_DROP_OBSIDIAN = 27630,
+
+ // Scripts
+ SPELL_SUMMON_MANA_FIEND_1 = 25681,
+ SPELL_SUMMON_MANA_FIEND_2 = 25682,
+ SPELL_SUMMON_MANA_FIEND_3 = 25683,
+ SPELL_DRAIN_MANA_EFFECT = 25671,
+ SPELL_DRAIN_MANA_VISUAL = 26639
};
-enum Events
+enum MoamEvents
{
- EVENT_TRAMPLE = 1,
- EVENT_DRAIN_MANA = 2,
- EVENT_STONE_PHASE = 3,
- EVENT_STONE_PHASE_END = 4,
- EVENT_WIDE_SLASH = 5,
+ EVENT_TRAMPLE = 1,
+ EVENT_DRAIN_MANA,
+ EVENT_STONE_PHASE,
+ EVENT_ARCANE_ERUPTION
};
-enum Actions
+enum MoamMisc
{
- ACTION_STONE_PHASE_START = 1,
- ACTION_STONE_PHASE_END = 2,
+ MAX_MANA_FIENDS = 3
};
-class boss_moam : public CreatureScript
+// 15340 - Moam
+struct boss_moam : public BossAI
{
- public:
- boss_moam() : CreatureScript("boss_moam") { }
+ boss_moam(Creature* creature) : BossAI(creature, DATA_MOAM), _deadManaFiendCount(0) { }
- struct boss_moamAI : public BossAI
- {
- boss_moamAI(Creature* creature) : BossAI(creature, DATA_MOAM)
- {
- Initialize();
- }
+ void JustAppeared() override
+ {
+ DoCastSelf(SPELL_ZERO_MANA_FULL_HEALTH);
+ }
- void Initialize()
- {
- _isStonePhase = false;
- }
+ void Reset() override
+ {
+ _Reset();
+ _deadManaFiendCount = 0;
+ }
- void Reset() override
- {
- _Reset();
+ void JustEngagedWith(Unit* who) override
+ {
+ BossAI::JustEngagedWith(who);
+
+ Talk(EMOTE_AGGRO);
+
+ events.ScheduleEvent(EVENT_TRAMPLE, 10s, 25s);
+ events.ScheduleEvent(EVENT_DRAIN_MANA, 6s);
+ events.ScheduleEvent(EVENT_STONE_PHASE, 90s);
+ events.ScheduleEvent(EVENT_ARCANE_ERUPTION, 1s);
+ }
+
+ void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override
+ {
+ _deadManaFiendCount++;
+
+ if (_deadManaFiendCount == MAX_MANA_FIENDS)
+ {
+ me->RemoveAurasDueToSpell(SPELL_ENERGIZE);
+ _deadManaFiendCount = 0;
+ }
+ }
+
+ void OnSpellCast(SpellInfo const* spell) override
+ {
+ switch (spell->Id)
+ {
+ case SPELL_ARCANE_ERUPTION:
+ // Is there a spell for that? Maybe Zero Mana/Full Health but with a check to prevent setting full health if creature is in combat?
me->SetPower(POWER_MANA, 0);
- Initialize();
- events.ScheduleEvent(EVENT_STONE_PHASE, 90s);
- //events.ScheduleEvent(EVENT_WIDE_SLASH, 11s);
- }
+ Talk(EMOTE_MANA_FULL);
+ break;
+ case SPELL_SUMMON_MANA_FIENDS:
+ DoCastSelf(SPELL_ENERGIZE);
+ Talk(EMOTE_ENERGIZE);
+ break;
+ default:
+ break;
+ }
+ }
- void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
- {
- if (!_isStonePhase && HealthBelowPct(45))
- {
- _isStonePhase = true;
- DoAction(ACTION_STONE_PHASE_START);
- }
- }
+ void JustReachedHome() override
+ {
+ _JustReachedHome();
+ DoCastSelf(SPELL_ZERO_MANA_FULL_HEALTH);
+ }
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_STONE_PHASE_END:
- {
- me->RemoveAurasDueToSpell(SPELL_ENERGIZE);
- events.ScheduleEvent(EVENT_STONE_PHASE, 90s);
- _isStonePhase = false;
- break;
- }
- case ACTION_STONE_PHASE_START:
- {
- DoCast(me, SPELL_SUMMON_MANA_FIEND_1);
- DoCast(me, SPELL_SUMMON_MANA_FIEND_2);
- DoCast(me, SPELL_SUMMON_MANA_FIEND_3);
- DoCast(me, SPELL_ENERGIZE);
- events.ScheduleEvent(EVENT_STONE_PHASE_END, 90s);
- break;
- }
- default:
- break;
- }
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ DoCastSelf(SPELL_DROP_OBSIDIAN, true);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- void UpdateAI(uint32 diff) override
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA))
- {
- if (_isStonePhase)
- DoAction(ACTION_STONE_PHASE_END);
- DoCastAOE(SPELL_ARCANE_ERUPTION);
- me->SetPower(POWER_MANA, 0);
- }
-
- if (_isStonePhase)
- {
- if (events.ExecuteEvent() == EVENT_STONE_PHASE_END)
- DoAction(ACTION_STONE_PHASE_END);
- return;
- }
-
- // Messing up mana-drain channel
- //if (me->HasUnitState(UNIT_STATE_CASTING))
- // return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_STONE_PHASE:
- DoAction(ACTION_STONE_PHASE_START);
- break;
- case EVENT_DRAIN_MANA:
- {
- std::list<Unit*> targetList;
- {
- for (ThreatReference const* ref : me->GetThreatManager().GetUnsortedThreatList())
- if (ref->GetVictim()->GetTypeId() == TYPEID_PLAYER && ref->GetVictim()->GetPowerType() == POWER_MANA)
- targetList.push_back(ref->GetVictim());
- }
-
- Trinity::Containers::RandomResize(targetList, 5);
-
- for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
- DoCast(*itr, SPELL_DRAIN_MANA);
-
- events.ScheduleEvent(EVENT_DRAIN_MANA, 5s, 15s);
- break;
- }/*
- case EVENT_WIDE_SLASH:
- DoCast(me, SPELL_WIDE_SLASH);
- events.ScheduleEvent(EVENT_WIDE_SLASH, 11s);
- break;
- case EVENT_TRASH:
- DoCast(me, SPELL_TRASH);
- events.ScheduleEvent(EVENT_WIDE_SLASH, 15s);
- break;*/
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
+ case EVENT_TRAMPLE:
+ DoCastSelf(SPELL_TRAMPLE);
+ events.Repeat(10s, 15s);
+ break;
+ case EVENT_DRAIN_MANA:
+ DoCastSelf(SPELL_DRAIN_MANA);
+ events.Repeat(6s);
+ break;
+ case EVENT_STONE_PHASE:
+ _deadManaFiendCount = 0;
+ DoCastSelf(SPELL_SUMMON_MANA_FIENDS);
+ events.Repeat(130s);
+ break;
+ case EVENT_ARCANE_ERUPTION:
+ if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA))
+ DoCastSelf(SPELL_ARCANE_ERUPTION);
+ events.Repeat(1s);
+ break;
+ default:
+ break;
}
- private:
- bool _isStonePhase;
- };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetAQ20AI<boss_moamAI>(creature);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
}
+
+ DoMeleeAttackIfReady();
+ }
+
+private:
+ uint8 _deadManaFiendCount;
+};
+
+// 25684 - Summon Mana Fiends
+class spell_moam_summon_mana_fiends : public SpellScript
+{
+ PrepareSpellScript(spell_moam_summon_mana_fiends);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo(
+ {
+ SPELL_SUMMON_MANA_FIEND_1,
+ SPELL_SUMMON_MANA_FIEND_2,
+ SPELL_SUMMON_MANA_FIEND_3
+ });
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ caster->CastSpell(caster, SPELL_SUMMON_MANA_FIEND_1, true);
+ caster->CastSpell(caster, SPELL_SUMMON_MANA_FIEND_2, true);
+ caster->CastSpell(caster, SPELL_SUMMON_MANA_FIEND_3, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_moam_summon_mana_fiends::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+// 25685 - Energize
+class spell_moam_energize : public AuraScript
+{
+ PrepareAuraScript(spell_moam_energize);
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (GetTarget()->GetPower(POWER_MANA) == GetTarget()->GetMaxPower(POWER_MANA))
+ Remove();
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_moam_energize::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_ENERGIZE);
+ }
+};
+
+// 25676 - Drain Mana
+class spell_moam_drain_mana : public SpellScript
+{
+ PrepareSpellScript(spell_moam_drain_mana);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_DRAIN_MANA_EFFECT });
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ Trinity::Containers::RandomResize(targets, [](WorldObject* target)
+ {
+ return target->IsPlayer() && target->ToPlayer()->GetPowerType() == POWER_MANA;
+ }, 6);
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_DRAIN_MANA_EFFECT, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_moam_drain_mana::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_moam_drain_mana::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+// 25671 - Drain Mana
+// 25755 - Drain Mana
+class spell_moam_drain_mana_effect : public SpellScript
+{
+ PrepareSpellScript(spell_moam_drain_mana_effect);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_DRAIN_MANA_VISUAL });
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetHitUnit()->CastSpell(GetCaster(), SPELL_DRAIN_MANA_VISUAL, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_moam_drain_mana_effect::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
void AddSC_boss_moam()
{
- new boss_moam();
+ RegisterAQ20CreatureAI(boss_moam);
+ RegisterSpellScript(spell_moam_summon_mana_fiends);
+ RegisterSpellScript(spell_moam_energize);
+ RegisterSpellScript(spell_moam_drain_mana);
+ RegisterSpellScript(spell_moam_drain_mana_effect);
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index ab852ecba75..22028fa1d39 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -3922,6 +3922,23 @@ private:
uint32 _text;
};
+// 23777 - Zero Mana/Full Health DND
+class spell_gen_zero_mana_full_health : public SpellScript
+{
+ PrepareSpellScript(spell_gen_zero_mana_full_health);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->SetFullHealth();
+ GetCaster()->SetPower(POWER_MANA, 0);
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_gen_zero_mana_full_health::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+};
+
class spell_gen_eject_all_passengers : public SpellScript
{
PrepareSpellScript(spell_gen_eject_all_passengers);
@@ -4828,6 +4845,7 @@ void AddSC_generic_spell_scripts()
RegisterSpellScriptWithArgs(spell_gen_whisper_to_controller_random, "spell_future_you_whisper_to_controller_random", WHISPER_FUTURE_YOU);
RegisterSpellScriptWithArgs(spell_gen_whisper_to_controller_random, "spell_wyrmrest_defender_whisper_to_controller_random", WHISPER_DEFENDER);
RegisterSpellScriptWithArgs(spell_gen_whisper_to_controller_random, "spell_past_you_whisper_to_controller_random", WHISPER_PAST_YOU);
+ RegisterSpellScript(spell_gen_zero_mana_full_health);
RegisterSpellScript(spell_gen_eject_all_passengers);
RegisterSpellScript(spell_gen_eject_passenger);
RegisterSpellScriptWithArgs(spell_gen_eject_passenger_with_seatId, "spell_gen_eject_passenger_1", 0);