mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 03:42:37 +01:00
Scripts/AQ20: Rewrite Moam (#31216)
* New register model * Repeat events instead of scheduling them * Added unique names for enums * Added comments for script names * Added AI for Mana Fiend * Added missing emote * Use all emotes * Create master-script to summon Mana Fiends * Implement & use Zero Mana/Full Health spell * Implement Energize script to end stoned phase * Implement Drain Mana master spell script with correct amount of targets and checks to ensure only players and mana-users will be targeted * Implement Drain Mana visual effect * Now, once all Mana Fiends are dead, stone phase is finished * Rework the way stone phase is started and finished * Moam now drops obsidian mineral once dead * Added a check to ensure all combat spells will be used * Added event to handle Arcane Eruption instead of trying to cast it every update tick Credit for a lot of things goes to CMaNGOS
This commit is contained in:
26
sql/updates/world/3.3.5/2025_09_13_01_world.sql
Normal file
26
sql/updates/world/3.3.5/2025_09_13_01_world.sql
Normal file
@@ -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'");
|
||||
@@ -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
|
||||
void JustAppeared() override
|
||||
{
|
||||
DoCastSelf(SPELL_ZERO_MANA_FULL_HEALTH);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
_deadManaFiendCount = 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
boss_moamAI(Creature* creature) : BossAI(creature, DATA_MOAM)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_isStonePhase = false;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
me->SetPower(POWER_MANA, 0);
|
||||
Initialize();
|
||||
events.ScheduleEvent(EVENT_STONE_PHASE, 90s);
|
||||
//events.ScheduleEvent(EVENT_WIDE_SLASH, 11s);
|
||||
}
|
||||
|
||||
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 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 UpdateAI(uint32 diff) override
|
||||
{
|
||||
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();
|
||||
}
|
||||
private:
|
||||
bool _isStonePhase;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetAQ20AI<boss_moamAI>(creature);
|
||||
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);
|
||||
Talk(EMOTE_MANA_FULL);
|
||||
break;
|
||||
case SPELL_SUMMON_MANA_FIENDS:
|
||||
DoCastSelf(SPELL_ENERGIZE);
|
||||
Talk(EMOTE_ENERGIZE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
_JustReachedHome();
|
||||
DoCastSelf(SPELL_ZERO_MANA_FULL_HEALTH);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user