fix(Scripts/RuinsOfAhnQiraj): Rewrite Moam (#12539)

* fix(Scripts/RuinsOfAhnQiraj): Rewrite Moam

* serverside spell for summons, as well as summon phase handling

* end stone phase if he reaches full mana

* add missing emote

* remove unused variable

* move script to the new model

* Update boss_moam.cpp

* should not drain mana while stoned
This commit is contained in:
Skjalf
2022-07-26 01:25:29 -03:00
committed by GitHub
parent b1136c7c24
commit fdb18e0204
2 changed files with 136 additions and 109 deletions

View File

@@ -0,0 +1,12 @@
--
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_moam_mana_drain_filter';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(25676, 'spell_moam_mana_drain_filter');
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_moam_summon_mana_fiends';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(25684, 'spell_moam_summon_mana_fiends');
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_STONE_PHASE');

View File

@@ -15,21 +15,26 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "ruins_of_ahnqiraj.h"
enum Texts
{
EMOTE_AGGRO = 0,
EMOTE_MANA_FULL = 1
EMOTE_MANA_FULL = 1,
EMOTE_STONE_PHASE = 2
};
enum Spells
{
SPELL_TRAMPLE = 15550,
SPELL_DRAIN_MANA_SERVERSIDE = 25676,
SPELL_DRAIN_MANA = 25671,
SPELL_ARCANE_ERUPTION = 25672,
SPELL_SUMMON_MANA_FIENDS = 25684,
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
@@ -46,134 +51,144 @@ enum Events
EVENT_STONE_PHASE_END = 4
};
enum Actions
struct boss_moam : public BossAI
{
ACTION_STONE_PHASE_START = 1,
ACTION_STONE_PHASE_END = 2
};
boss_moam(Creature* creature) : BossAI(creature, DATA_MOAM) {}
class boss_moam : public CreatureScript
{
public:
boss_moam() : CreatureScript("boss_moam") { }
struct boss_moamAI : public BossAI
void Reset() override
{
boss_moamAI(Creature* creature) : BossAI(creature, DATA_MOAM) {}
_Reset();
me->SetPower(POWER_MANA, 0);
me->SetRegeneratingPower(false);
}
void Reset() override
void EnterCombat(Unit* who) override
{
BossAI::EnterCombat(who);
Talk(EMOTE_AGGRO);
events.ScheduleEvent(EVENT_STONE_PHASE, 90000);
events.ScheduleEvent(EVENT_SPELL_TRAMPLE, 9000);
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, 3000);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
DoCastAOE(SPELL_LARGE_OBSIDIAN_CHUNK, true);
}
void SummonedCreatureDies(Creature* /*creature*/, Unit* /*killer*/) override
{
if (!summons.IsAnyCreatureAlive() && me->HasAura(SPELL_ENERGIZE))
{
_Reset();
me->SetPower(POWER_MANA, 0);
me->SetRegeneratingPower(false);
_isStonePhase = false;
events.RescheduleEvent(EVENT_STONE_PHASE_END, 1s);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA))
{
if (me->HasAura(SPELL_ENERGIZE))
{
me->RemoveAurasDueToSpell(SPELL_ENERGIZE);
events.RescheduleEvent(EVENT_STONE_PHASE_END, 1s);
}
Talk(EMOTE_MANA_FULL);
DoCastAOE(SPELL_ARCANE_ERUPTION);
}
void DoAction(int32 action) override
while (uint32 eventId = events.ExecuteEvent())
{
switch (action)
switch (eventId)
{
case ACTION_STONE_PHASE_END:
{
me->RemoveAurasDueToSpell(SPELL_ENERGIZE);
events.ScheduleEvent(EVENT_STONE_PHASE, 90000);
_isStonePhase = false;
break;
}
case ACTION_STONE_PHASE_START:
{
DoCastSelf(SPELL_SUMMON_MANA_FIEND_1);
DoCastSelf(SPELL_SUMMON_MANA_FIEND_2);
DoCastSelf(SPELL_SUMMON_MANA_FIEND_3);
DoCastSelf(SPELL_ENERGIZE);
events.ScheduleEvent(EVENT_STONE_PHASE_END, 90000);
break;
}
case EVENT_STONE_PHASE:
Talk(EMOTE_STONE_PHASE);
DoCastAOE(SPELL_SUMMON_MANA_FIENDS);
DoCastSelf(SPELL_ENERGIZE);
events.CancelEvent(EVENT_SPELL_DRAIN_MANA);
events.ScheduleEvent(EVENT_STONE_PHASE_END, 90000);
break;
case EVENT_STONE_PHASE_END:
me->RemoveAurasDueToSpell(SPELL_ENERGIZE);
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, urand(2000, 6000));
events.ScheduleEvent(EVENT_STONE_PHASE, 90000);
break;
case EVENT_SPELL_DRAIN_MANA:
DoCastAOE(SPELL_DRAIN_MANA_SERVERSIDE);
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, urand(2000, 6000));
break;
case EVENT_SPELL_TRAMPLE:
DoCastAOE(SPELL_TRAMPLE);
events.ScheduleEvent(EVENT_SPELL_TRAMPLE, 15000);
break;
default:
break;
}
}
void EnterCombat(Unit* who) override
{
BossAI::EnterCombat(who);
Talk(EMOTE_AGGRO);
events.ScheduleEvent(EVENT_STONE_PHASE, 90000);
events.ScheduleEvent(EVENT_SPELL_TRAMPLE, 9000);
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, 3000);
}
DoMeleeAttackIfReady();
}
};
void JustDied(Unit* /*killer*/) override
{
_JustDied();
DoCastAOE(SPELL_LARGE_OBSIDIAN_CHUNK, true);
}
// 25676 - Drain Mana (server-side)
class spell_moam_mana_drain_filter : public SpellScript
{
PrepareSpellScript(spell_moam_mana_drain_filter);
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA))
{
Talk(EMOTE_MANA_FULL);
DoCastAOE(SPELL_ARCANE_ERUPTION, true);
me->SetPower(POWER_MANA, 0);
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_STONE_PHASE:
DoAction(ACTION_STONE_PHASE_START);
break;
case EVENT_STONE_PHASE_END:
DoAction(ACTION_STONE_PHASE_END);
break;
case EVENT_SPELL_DRAIN_MANA:
{
std::list<Unit*> targetList;
{
const std::list<HostileReference*>& threatlist = me->GetThreatMgr().getThreatList();
for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
{
if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER && (*itr)->getTarget()->getPowerType() == POWER_MANA)
{
targetList.push_back((*itr)->getTarget());
}
}
}
Acore::Containers::RandomResize(targetList, 6);
for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
{
DoCast(*itr, SPELL_DRAIN_MANA);
}
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, urand(2000, 6000));
break;
}
case EVENT_SPELL_TRAMPLE:
DoCastVictim(SPELL_TRAMPLE);
events.ScheduleEvent(EVENT_SPELL_TRAMPLE, 15000);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
bool _isStonePhase;
};
CreatureAI* GetAI(Creature* creature) const override
void FilterTargets(std::list<WorldObject*>& targets)
{
return GetRuinsOfAhnQirajAI<boss_moamAI>(creature);
targets.remove_if([&](WorldObject* target) -> bool
{
return !target->IsPlayer() || target->ToPlayer()->getPowerType() != POWER_MANA;
});
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
{
caster->CastSpell(GetHitUnit(), SPELL_DRAIN_MANA, true);
}
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_moam_mana_drain_filter::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_moam_mana_drain_filter::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
// 25684 - Summon Mana Fiends (server-side)
class spell_moam_summon_mana_fiends : public SpellScript
{
PrepareSpellScript(spell_moam_summon_mana_fiends);
void HandleScript(SpellEffIndex /*effIndex*/)
{
const uint32 spellIds[3] = { SPELL_SUMMON_MANA_FIEND_1, SPELL_SUMMON_MANA_FIEND_2, SPELL_SUMMON_MANA_FIEND_3 };
for (uint32 spellId : spellIds)
{
GetCaster()->CastSpell((Unit*)nullptr, spellId, true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_moam_summon_mana_fiends::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
void AddSC_boss_moam()
{
new boss_moam();
RegisterRuinsOfAhnQirajCreatureAI(boss_moam);
RegisterSpellScript(spell_moam_mana_drain_filter);
RegisterSpellScript(spell_moam_summon_mana_fiends);
}