feat(Core/AI): Implement ScheduleHealthCheckEvent() for events that fire … (#15275)
This commit is contained in:
@@ -577,6 +577,7 @@ void BossAI::_Reset()
|
|||||||
events.Reset();
|
events.Reset();
|
||||||
scheduler.CancelAll();
|
scheduler.CancelAll();
|
||||||
summons.DespawnAll();
|
summons.DespawnAll();
|
||||||
|
_healthCheckEvents.clear();
|
||||||
if (instance)
|
if (instance)
|
||||||
instance->SetBossState(_bossId, NOT_STARTED);
|
instance->SetBossState(_bossId, NOT_STARTED);
|
||||||
}
|
}
|
||||||
@@ -586,6 +587,7 @@ void BossAI::_JustDied()
|
|||||||
events.Reset();
|
events.Reset();
|
||||||
scheduler.CancelAll();
|
scheduler.CancelAll();
|
||||||
summons.DespawnAll();
|
summons.DespawnAll();
|
||||||
|
_healthCheckEvents.clear();
|
||||||
if (instance)
|
if (instance)
|
||||||
{
|
{
|
||||||
instance->SetBossState(_bossId, DONE);
|
instance->SetBossState(_bossId, DONE);
|
||||||
@@ -667,6 +669,39 @@ void BossAI::UpdateAI(uint32 diff)
|
|||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BossAI::DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/)
|
||||||
|
{
|
||||||
|
if (!_healthCheckEvents.empty())
|
||||||
|
{
|
||||||
|
_healthCheckEvents.remove_if([&](HealthCheckEventData data) -> bool
|
||||||
|
{
|
||||||
|
return _ProccessHealthCheckEvent(data._healthPct, damage, data._exec);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes a function once the creature reaches the defined health point percent.
|
||||||
|
*
|
||||||
|
* @param healthPct The health percent at which the code will be executed.
|
||||||
|
* @param exec The fuction to be executed.
|
||||||
|
*/
|
||||||
|
void BossAI::ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> exec)
|
||||||
|
{
|
||||||
|
_healthCheckEvents.push_back(HealthCheckEventData(healthPct, exec));
|
||||||
|
};
|
||||||
|
|
||||||
|
bool BossAI::_ProccessHealthCheckEvent(uint8 healthPct, uint32 damage, std::function<void()> exec) const
|
||||||
|
{
|
||||||
|
if (me->HealthBelowPctDamaged(healthPct, damage))
|
||||||
|
{
|
||||||
|
exec();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// WorldBossAI - for non-instanced bosses
|
// WorldBossAI - for non-instanced bosses
|
||||||
|
|
||||||
WorldBossAI::WorldBossAI(Creature* creature) :
|
WorldBossAI::WorldBossAI(Creature* creature) :
|
||||||
|
|||||||
@@ -430,6 +430,14 @@ private:
|
|||||||
bool _isHeroic;
|
bool _isHeroic;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct HealthCheckEventData
|
||||||
|
{
|
||||||
|
HealthCheckEventData(uint8 healthPct, std::function<void()> exec) : _healthPct(healthPct), _exec(exec) { };
|
||||||
|
|
||||||
|
uint8 _healthPct;
|
||||||
|
std::function<void()> _exec;
|
||||||
|
};
|
||||||
|
|
||||||
class BossAI : public ScriptedAI
|
class BossAI : public ScriptedAI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -440,12 +448,15 @@ public:
|
|||||||
|
|
||||||
bool CanRespawn() override;
|
bool CanRespawn() override;
|
||||||
|
|
||||||
|
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override;
|
||||||
void JustSummoned(Creature* summon) override;
|
void JustSummoned(Creature* summon) override;
|
||||||
void SummonedCreatureDespawn(Creature* summon) override;
|
void SummonedCreatureDespawn(Creature* summon) override;
|
||||||
void SummonedCreatureDespawnAll() override;
|
void SummonedCreatureDespawnAll() override;
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override;
|
void UpdateAI(uint32 diff) override;
|
||||||
|
|
||||||
|
void ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> exec);
|
||||||
|
|
||||||
// Hook used to execute events scheduled into EventMap without the need
|
// Hook used to execute events scheduled into EventMap without the need
|
||||||
// to override UpdateAI
|
// to override UpdateAI
|
||||||
// note: You must re-schedule the event within this method if the event
|
// note: You must re-schedule the event within this method if the event
|
||||||
@@ -464,6 +475,7 @@ protected:
|
|||||||
void _JustEngagedWith();
|
void _JustEngagedWith();
|
||||||
void _JustDied();
|
void _JustDied();
|
||||||
void _JustReachedHome() { me->setActive(false); }
|
void _JustReachedHome() { me->setActive(false); }
|
||||||
|
[[nodiscard]] bool _ProccessHealthCheckEvent(uint8 healthPct, uint32 damage, std::function<void()> exec) const;
|
||||||
|
|
||||||
void TeleportCheaters();
|
void TeleportCheaters();
|
||||||
|
|
||||||
@@ -473,6 +485,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 const _bossId;
|
uint32 const _bossId;
|
||||||
|
std::list<HealthCheckEventData> _healthCheckEvents;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WorldBossAI : public ScriptedAI
|
class WorldBossAI : public ScriptedAI
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ enum Events
|
|||||||
EVENT_SACRIFICE = 1,
|
EVENT_SACRIFICE = 1,
|
||||||
EVENT_HELLFIRE = 2,
|
EVENT_HELLFIRE = 2,
|
||||||
EVENT_ENRAGE = 3,
|
EVENT_ENRAGE = 3,
|
||||||
EVENT_HEALTH_CHECK_50 = 4,
|
|
||||||
EVENT_HEALTH_CHECK_20 = 5
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_thorngrin_the_tender : public CreatureScript
|
class boss_thorngrin_the_tender : public CreatureScript
|
||||||
@@ -64,6 +62,12 @@ public:
|
|||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
|
ScheduleHealthCheckEvent(20, [&]() {
|
||||||
|
Talk(SAY_20_PERCENT_HP);
|
||||||
|
});
|
||||||
|
ScheduleHealthCheckEvent(50, [&]() {
|
||||||
|
Talk(SAY_50_PERCENT_HP);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* who) override
|
void MoveInLineOfSight(Unit* who) override
|
||||||
@@ -83,8 +87,6 @@ public:
|
|||||||
events.ScheduleEvent(EVENT_SACRIFICE, 6000);
|
events.ScheduleEvent(EVENT_SACRIFICE, 6000);
|
||||||
events.ScheduleEvent(EVENT_HELLFIRE, 18000);
|
events.ScheduleEvent(EVENT_HELLFIRE, 18000);
|
||||||
events.ScheduleEvent(EVENT_ENRAGE, 15000);
|
events.ScheduleEvent(EVENT_ENRAGE, 15000);
|
||||||
events.ScheduleEvent(EVENT_HEALTH_CHECK_50, 500);
|
|
||||||
events.ScheduleEvent(EVENT_HEALTH_CHECK_20, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
void KilledUnit(Unit* victim) override
|
||||||
@@ -129,22 +131,6 @@ public:
|
|||||||
me->CastSpell(me, SPELL_ENRAGE, false);
|
me->CastSpell(me, SPELL_ENRAGE, false);
|
||||||
events.ScheduleEvent(EVENT_ENRAGE, 30000);
|
events.ScheduleEvent(EVENT_ENRAGE, 30000);
|
||||||
break;
|
break;
|
||||||
case EVENT_HEALTH_CHECK_50:
|
|
||||||
if (me->HealthBelowPct(50))
|
|
||||||
{
|
|
||||||
Talk(SAY_50_PERCENT_HP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
events.ScheduleEvent(EVENT_HEALTH_CHECK_50, 500);
|
|
||||||
break;
|
|
||||||
case EVENT_HEALTH_CHECK_20:
|
|
||||||
if (me->HealthBelowPct(20))
|
|
||||||
{
|
|
||||||
Talk(SAY_20_PERCENT_HP);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
events.ScheduleEvent(EVENT_HEALTH_CHECK_20, 500);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
|
|||||||
Reference in New Issue
Block a user