fix(Scripts/BlackTemple): Fix Zerevor not casting Dampen Magic OOC (#19768)

* fix(Scripts/BlackTemple): Fix Zerevor not casting Dampen Magic OOC

* Update boss_illidari_council.cpp

* recast every 1min

* implement the recast checks

* Update CreatureAI.h

* Update boss_illidari_council.cpp

* Update boss_illidari_council.cpp

* fix ooc cast

* Update boss_illidari_council.cpp

* always respect the 60s lock

* Update boss_illidari_council.cpp

* Update boss_illidari_council.cpp
This commit is contained in:
Andrew
2024-09-02 20:44:34 -03:00
committed by GitHub
parent 0158fa3e9e
commit 0954e314a0
3 changed files with 92 additions and 50 deletions

View File

@@ -220,6 +220,9 @@ public:
virtual bool OnTeleportUnreacheablePlayer(Player* /*player*/) { return false; }
// Called when an aura is removed or expires.
virtual void OnAuraRemove(AuraApplication* /*aurApp*/, AuraRemoveMode /*mode*/) { }
protected:
virtual void MoveInLineOfSight(Unit* /*who*/);

View File

@@ -4603,6 +4603,9 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMo
i = m_appliedAuras.begin();
sScriptMgr->OnAuraRemove(this, aurApp, removeMode);
if (this->ToCreature() && this->ToCreature()->IsAIEnabled)
this->ToCreature()->AI()->OnAuraRemove(aurApp, removeMode);
}
void Unit::_UnapplyAura(AuraApplication* aurApp, AuraRemoveMode removeMode)

View File

@@ -88,12 +88,6 @@ enum Misc
EVENT_SPELL_JUDGEMENT = 5,
EVENT_SPELL_CONSECRATION = 6,
EVENT_SPELL_FLAMESTRIKE = 10,
EVENT_SPELL_BLIZZARD = 11,
EVENT_SPELL_ARCANE_BOLT = 12,
EVENT_SPELL_DAMPEN_MAGIC = 13,
EVENT_SPELL_ARCANE_EXPLOSION = 14,
EVENT_SPELL_REFLECTIVE_SHIELD = 20,
EVENT_SPELL_CIRCLE_OF_HEALING = 21,
EVENT_SPELL_DIVINE_WRATH = 22,
@@ -378,22 +372,67 @@ private:
struct boss_high_nethermancer_zerevor : public boss_illidari_council_memberAI
{
boss_high_nethermancer_zerevor(Creature* creature) : boss_illidari_council_memberAI(creature) { }
boss_high_nethermancer_zerevor(Creature* creature) : boss_illidari_council_memberAI(creature), _canCastDampenMagic(true) { }
void Reset() override
{
scheduler.CancelAll();
_canCastDampenMagic = true;
boss_illidari_council_memberAI::Reset();
CastDampenMagicIfPossible();
}
void AttackStart(Unit* who) override
{
if (who && me->Attack(who, true))
me->GetMotionMaster()->MoveChase(who, 20.0f);
AttackStartCaster(who, 20.0f);
}
void JustEngagedWith(Unit* who) override
{
boss_illidari_council_memberAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 25000);
events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 5000);
events.ScheduleEvent(EVENT_SPELL_ARCANE_BOLT, 15000);
events.ScheduleEvent(EVENT_SPELL_DAMPEN_MAGIC, 0);
events.ScheduleEvent(EVENT_SPELL_ARCANE_EXPLOSION, 10000);
ScheduleTimedEvent(25s, [&]
{
if (roll_chance_i(50))
Talk(SAY_COUNCIL_SPECIAL);
DoCastRandomTarget(SPELL_FLAMESTRIKE, 0, 100.0f);
}, 40s);
ScheduleTimedEvent(15s, [&]
{
DoCastVictim(SPELL_ARCANE_BOLT);
}, 3s);
ScheduleTimedEvent(5s, [&]
{
DoCastRandomTarget(SPELL_BLIZZARD, 0, 100.0f);
}, 40s);
ScheduleTimedEvent(10s, [&]
{
if (SelectTarget(SelectTargetMethod::Random, 0, 10.0f))
DoCastAOE(SPELL_ARCANE_EXPLOSION);
}, 10s);
if (Aura* aura = me->GetAura(SPELL_DAMPEN_MAGIC))
{
if (aura->GetDuration() <= 4 * MINUTE * IN_MILLISECONDS)
CastDampenMagicIfPossible();
}
}
void OnAuraRemove(AuraApplication* auraApp, AuraRemoveMode mode) override
{
if (auraApp->GetBase()->GetId() == SPELL_DAMPEN_MAGIC)
if (mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE)
if (!CastDampenMagicIfPossible())
{
scheduler.Schedule(1s, [this](TaskContext context)
{
if (!CastDampenMagicIfPossible())
context.Repeat();
});
}
}
void UpdateAI(uint32 diff) override
@@ -401,41 +440,44 @@ struct boss_high_nethermancer_zerevor : public boss_illidari_council_memberAI
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
scheduler.Update(diff,
std::bind(&BossAI::DoMeleeAttackIfReady, this));
}
bool CastDampenMagicIfPossible()
{
if (_canCastDampenMagic)
{
case EVENT_SPELL_DAMPEN_MAGIC:
me->CastSpell(me, SPELL_DAMPEN_MAGIC, false);
events.ScheduleEvent(EVENT_SPELL_DAMPEN_MAGIC, 120000);
break;
case EVENT_SPELL_ARCANE_BOLT:
me->CastSpell(me->GetVictim(), SPELL_ARCANE_BOLT, false);
events.ScheduleEvent(EVENT_SPELL_ARCANE_BOLT, 3000);
break;
case EVENT_SPELL_FLAMESTRIKE:
if (roll_chance_i(50))
Talk(SAY_COUNCIL_SPECIAL);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f))
me->CastSpell(target, SPELL_FLAMESTRIKE, false);
events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 40000);
break;
case EVENT_SPELL_BLIZZARD:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f))
me->CastSpell(target, SPELL_BLIZZARD, false);
events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 40000);
break;
case EVENT_SPELL_ARCANE_EXPLOSION:
if (SelectTarget(SelectTargetMethod::Random, 0, 10.0f))
me->CastSpell(me, SPELL_ARCANE_EXPLOSION, false);
events.ScheduleEvent(EVENT_SPELL_ARCANE_EXPLOSION, 10000);
break;
_canCastDampenMagic = false;
me->m_Events.AddEventAtOffset([this] {
_canCastDampenMagic = true;
}, 1min);
if (me->IsInCombat())
{
scheduler.Schedule(1s, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_DAMPEN_MAGIC);
});
}
else
{
me->m_Events.AddEventAtOffset([this] {
DoCastSelf(SPELL_DAMPEN_MAGIC);
}, 1s);
}
return true;
}
DoMeleeAttackIfReady();
return false;
}
private:
bool _canCastDampenMagic;
};
struct boss_lady_malande : public boss_illidari_council_memberAI
@@ -572,9 +614,7 @@ class spell_illidari_council_empyreal_balance : public SpellScript
{
PreventHitDefaultEffect(effIndex);
if (GetHitUnit())
{
_targetCount++;
}
}
void HandleAfterCast()
@@ -585,7 +625,7 @@ class spell_illidari_council_empyreal_balance : public SpellScript
return;
}
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
auto const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID))
{
@@ -619,19 +659,15 @@ class spell_illidari_council_empyreal_equivalency : public SpellScript
{
PreventHitDefaultEffect(effIndex);
if (GetHitUnit())
{
_targetCount++;
}
}
void HandleAfterCast()
{
if (_targetCount != 4)
{
return;
}
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
auto const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID))
target->SetHealth(GetCaster()->GetHealth() / _targetCount);