mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-18 19:35:42 +00:00
fix(Scripts/AzjolNerub): Fix Anubarak impale sequence (#22717)
This commit is contained in:
@@ -746,27 +746,39 @@ void BossAI::UpdateAI(uint32 diff)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void BossAI::OnSpellCastFinished(SpellInfo const* spellInfo, SpellFinishReason reason)
|
||||
{
|
||||
ScriptedAI::OnSpellCastFinished(spellInfo, reason);
|
||||
// Check if any health check events are pending (i.e. waiting for the boss to stop casting.
|
||||
if (_nextHealthCheck.IsPending() && me->IsInCombat())
|
||||
{
|
||||
_nextHealthCheck.UpdateStatus(HEALTH_CHECK_PROCESSED);
|
||||
// This must be delayed because creature might still have unit state casting at this point, which might break scripts.
|
||||
scheduler.Schedule(1s, [this](TaskContext context)
|
||||
{
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
context.Repeat();
|
||||
else
|
||||
ProcessHealthCheck();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void BossAI::DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask)
|
||||
{
|
||||
ScriptedAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask);
|
||||
|
||||
if (_nextHealthCheck._valid)
|
||||
if (!_nextHealthCheck.HasBeenProcessed())
|
||||
{
|
||||
if (!_nextHealthCheck._allowedWhileCasting && me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (me->HealthBelowPctDamaged(_nextHealthCheck._healthPct, damage))
|
||||
{
|
||||
_nextHealthCheck._exec();
|
||||
_nextHealthCheck._valid = false;
|
||||
|
||||
_healthCheckEvents.remove_if([&](HealthCheckEventData data) -> bool
|
||||
if (!_nextHealthCheck._allowedWhileCasting && me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
return data._healthPct == _nextHealthCheck._healthPct;
|
||||
});
|
||||
_nextHealthCheck.UpdateStatus(HEALTH_CHECK_PENDING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_healthCheckEvents.empty())
|
||||
_nextHealthCheck = _healthCheckEvents.front();
|
||||
ProcessHealthCheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -780,18 +792,32 @@ void BossAI::DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damage
|
||||
*/
|
||||
void BossAI::ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> exec, bool allowedWhileCasting /*=true*/)
|
||||
{
|
||||
_healthCheckEvents.push_back(HealthCheckEventData(healthPct, exec, true, allowedWhileCasting));
|
||||
_healthCheckEvents.push_back(HealthCheckEventData(healthPct, exec, HEALTH_CHECK_SCHEDULED, allowedWhileCasting));
|
||||
_nextHealthCheck = _healthCheckEvents.front();
|
||||
};
|
||||
|
||||
void BossAI::ScheduleHealthCheckEvent(std::initializer_list<uint8> healthPct, std::function<void()> exec, bool allowedWhileCasting /*=true*/)
|
||||
{
|
||||
for (auto const& checks : healthPct)
|
||||
_healthCheckEvents.push_back(HealthCheckEventData(checks, exec, true, allowedWhileCasting));
|
||||
_healthCheckEvents.push_back(HealthCheckEventData(checks, exec, HEALTH_CHECK_SCHEDULED, allowedWhileCasting));
|
||||
|
||||
_nextHealthCheck = _healthCheckEvents.front();
|
||||
}
|
||||
|
||||
void BossAI::ProcessHealthCheck()
|
||||
{
|
||||
_nextHealthCheck.UpdateStatus(HEALTH_CHECK_PROCESSED);
|
||||
_nextHealthCheck._exec();
|
||||
|
||||
_healthCheckEvents.remove_if([&](HealthCheckEventData data) -> bool
|
||||
{
|
||||
return data._healthPct == _nextHealthCheck._healthPct;
|
||||
});
|
||||
|
||||
if (!_healthCheckEvents.empty())
|
||||
_nextHealthCheck = _healthCheckEvents.front();
|
||||
}
|
||||
|
||||
void BossAI::ScheduleEnrageTimer(uint32 spellId, Milliseconds timer, uint8 textId /*= 0*/)
|
||||
{
|
||||
me->m_Events.AddEventAtOffset([this, spellId, textId]
|
||||
|
||||
@@ -454,14 +454,27 @@ private:
|
||||
std::unordered_set<uint32> _uniqueTimedEvents;
|
||||
};
|
||||
|
||||
enum HealthCheckStatus
|
||||
{
|
||||
HEALTH_CHECK_PROCESSED,
|
||||
HEALTH_CHECK_SCHEDULED,
|
||||
HEALTH_CHECK_PENDING
|
||||
};
|
||||
|
||||
struct HealthCheckEventData
|
||||
{
|
||||
HealthCheckEventData(uint8 healthPct, std::function<void()> exec, bool valid = true, bool allowedWhileCasting = true) : _healthPct(healthPct), _exec(exec), _valid(valid), _allowedWhileCasting(allowedWhileCasting) { };
|
||||
HealthCheckEventData(uint8 healthPct, std::function<void()> exec, uint8 status = HEALTH_CHECK_SCHEDULED, bool allowedWhileCasting = true, Milliseconds Delay = 0s) : _healthPct(healthPct), _exec(exec), _status(status), _allowedWhileCasting(allowedWhileCasting), _delay(Delay) { };
|
||||
|
||||
uint8 _healthPct;
|
||||
std::function<void()> _exec;
|
||||
bool _valid;
|
||||
uint8 _status;
|
||||
bool _allowedWhileCasting;
|
||||
Milliseconds _delay;
|
||||
|
||||
[[nodiscard]] bool HasBeenProcessed() const { return _status == HEALTH_CHECK_PROCESSED; };
|
||||
[[nodiscard]] bool IsPending() const { return _status == HEALTH_CHECK_PENDING; };
|
||||
[[nodiscard]] Milliseconds GetDelay() const { return _delay; };
|
||||
void UpdateStatus(uint8 status) { _status = status; };
|
||||
};
|
||||
|
||||
class BossAI : public ScriptedAI
|
||||
@@ -476,6 +489,7 @@ public:
|
||||
|
||||
bool CanRespawn() override;
|
||||
|
||||
void OnSpellCastFinished(SpellInfo const* spell, SpellFinishReason reason) override;
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override;
|
||||
void JustSummoned(Creature* summon) override;
|
||||
void SummonedCreatureDespawn(Creature* summon) override;
|
||||
@@ -485,6 +499,7 @@ public:
|
||||
|
||||
void ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> exec, bool allowedWhileCasting = true);
|
||||
void ScheduleHealthCheckEvent(std::initializer_list<uint8> healthPct, std::function<void()> exec, bool allowedWhileCasting = true);
|
||||
void ProcessHealthCheck();
|
||||
|
||||
// @brief Casts the spell after the fixed time and says the text id if provided. Timer will run even if the creature is casting or out of combat.
|
||||
// @param spellId The spell to cast.
|
||||
|
||||
Reference in New Issue
Block a user