mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Creatures: moved combat pulse into heartbeat handling and implemented CREATURE_STATIC_FLAG_2_FORCE_PARTY_MEMBERS_INTO_COMBAT (#29946)
This commit is contained in:
7
sql/updates/world/master/2024_04_28_00_world.sql
Normal file
7
sql/updates/world/master/2024_04_28_00_world.sql
Normal file
File diff suppressed because one or more lines are too long
@@ -543,7 +543,6 @@ void BossAI::_Reset()
|
||||
if (!me->IsAlive())
|
||||
return;
|
||||
|
||||
me->SetCombatPulseDelay(0);
|
||||
me->ResetLootMode();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
@@ -579,9 +578,7 @@ void BossAI::_JustEngagedWith(Unit* who)
|
||||
instance->SetBossState(_bossId, IN_PROGRESS);
|
||||
}
|
||||
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
ScheduleTasks();
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
||||
|
||||
Creature::Creature(bool isWorldObject) : Unit(isWorldObject), MapObject(), m_PlayerDamageReq(0), m_dontClearTapListOnEvade(false), _pickpocketLootRestore(0),
|
||||
m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_ignoreCorpseDecayRatio(false), m_wanderDistance(0.0f),
|
||||
m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
|
||||
m_boundaryCheckTime(2500), m_reactState(REACT_AGGRESSIVE),
|
||||
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0),
|
||||
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_cannotReachTarget(false), m_cannotReachTimer(0),
|
||||
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(),
|
||||
@@ -848,34 +848,6 @@ void Creature::Update(uint32 diff)
|
||||
m_boundaryCheckTime -= diff;
|
||||
}
|
||||
|
||||
// if periodic combat pulse is enabled and we are both in combat and in a dungeon, do this now
|
||||
if (m_combatPulseDelay > 0 && IsEngaged() && GetMap()->IsDungeon())
|
||||
{
|
||||
if (diff > m_combatPulseTime)
|
||||
m_combatPulseTime = 0;
|
||||
else
|
||||
m_combatPulseTime -= diff;
|
||||
|
||||
if (m_combatPulseTime == 0)
|
||||
{
|
||||
Map::PlayerList const& players = GetMap()->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it)
|
||||
{
|
||||
if (Player* player = it->GetSource())
|
||||
{
|
||||
if (player->IsGameMaster())
|
||||
continue;
|
||||
|
||||
if (player->IsAlive() && IsHostileTo(player))
|
||||
EngageWithTarget(player);
|
||||
}
|
||||
}
|
||||
|
||||
m_combatPulseTime = m_combatPulseDelay * IN_MILLISECONDS;
|
||||
}
|
||||
}
|
||||
|
||||
Unit::AIUpdateTick(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
@@ -936,6 +908,14 @@ void Creature::Update(uint32 diff)
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::Heartbeat()
|
||||
{
|
||||
Unit::Heartbeat();
|
||||
|
||||
// Creatures with CREATURE_STATIC_FLAG_2_FORCE_PARTY_MEMBERS_INTO_COMBAT periodically force party members into combat
|
||||
ForcePartyMembersIntoCombat();
|
||||
}
|
||||
|
||||
void Creature::Regenerate(Powers power)
|
||||
{
|
||||
uint32 curValue = GetPower(power);
|
||||
@@ -3644,6 +3624,9 @@ void Creature::AtEngage(Unit* target)
|
||||
ai->JustEngagedWith(target);
|
||||
if (CreatureGroup* formation = GetFormation())
|
||||
formation->MemberEngagingTarget(this, target);
|
||||
|
||||
// Creatures with CREATURE_STATIC_FLAG_2_FORCE_PARTY_MEMBERS_INTO_COMBAT periodically force party members into combat
|
||||
ForcePartyMembersIntoCombat();
|
||||
}
|
||||
|
||||
void Creature::AtDisengage()
|
||||
@@ -3662,6 +3645,38 @@ void Creature::AtDisengage()
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::ForcePartyMembersIntoCombat()
|
||||
{
|
||||
if (!_staticFlags.HasFlag(CREATURE_STATIC_FLAG_2_FORCE_PARTY_MEMBERS_INTO_COMBAT) || !IsEngaged())
|
||||
return;
|
||||
|
||||
Trinity::Containers::FlatSet<Group const*> partiesToForceIntoCombat;
|
||||
for (auto const& [_, combatReference] : GetCombatManager().GetPvECombatRefs())
|
||||
{
|
||||
if (combatReference->IsSuppressedFor(this))
|
||||
continue;
|
||||
|
||||
Player* player = Object::ToPlayer(combatReference->GetOther(this));
|
||||
if (!player || player->IsGameMaster())
|
||||
continue;
|
||||
|
||||
if (Group const* group = player->GetGroup())
|
||||
partiesToForceIntoCombat.insert(group);
|
||||
}
|
||||
|
||||
for (Group const* partyToForceIntoCombat : partiesToForceIntoCombat)
|
||||
{
|
||||
for (GroupReference const* ref = partyToForceIntoCombat->GetFirstMember(); ref != nullptr; ref = ref->next())
|
||||
{
|
||||
Player* player = ref->GetSource();
|
||||
if (!player || !player->IsInWorld() || player->GetMap() != GetMap() || player->IsGameMaster())
|
||||
continue;
|
||||
|
||||
EngageWithTarget(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Creature::IsEscorted() const
|
||||
{
|
||||
if (CreatureAI const* ai = AI())
|
||||
|
||||
@@ -98,6 +98,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
ObjectGuid::LowType GetSpawnId() const { return m_spawnId; }
|
||||
|
||||
void Update(uint32 time) override; // overwrited Unit::Update
|
||||
void Heartbeat() override;
|
||||
|
||||
void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr, float* dist = nullptr) const;
|
||||
bool IsSpawnedOnTransport() const { return m_creatureData && m_creatureData->mapId != GetMapId(); }
|
||||
|
||||
@@ -342,13 +344,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
void SetWanderDistance(float dist) { m_wanderDistance = dist; }
|
||||
|
||||
void DoImmediateBoundaryCheck() { m_boundaryCheckTime = 0; }
|
||||
uint32 GetCombatPulseDelay() const { return m_combatPulseDelay; }
|
||||
void SetCombatPulseDelay(uint32 delay) // (secs) interval at which the creature pulses the entire zone into combat (only works in dungeons)
|
||||
{
|
||||
m_combatPulseDelay = delay;
|
||||
if (m_combatPulseTime == 0 || m_combatPulseTime > delay)
|
||||
m_combatPulseTime = delay;
|
||||
}
|
||||
|
||||
void SendZoneUnderAttackMessage(Player* attacker);
|
||||
|
||||
@@ -441,6 +436,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
|
||||
bool IsThreatFeedbackDisabled() const { return _staticFlags.HasFlag(CREATURE_STATIC_FLAG_3_NO_THREAT_FEEDBACK); }
|
||||
void SetNoThreatFeedback(bool noThreatFeedback) { _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_3_NO_THREAT_FEEDBACK, noThreatFeedback); }
|
||||
void ForcePartyMembersIntoCombat();
|
||||
|
||||
void OverrideSparringHealthPct(float healthPct) { _sparringHealthPct = healthPct; }
|
||||
void OverrideSparringHealthPct(std::vector<float> const& healthPct);
|
||||
@@ -493,8 +489,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool m_ignoreCorpseDecayRatio;
|
||||
float m_wanderDistance;
|
||||
uint32 m_boundaryCheckTime; // (msecs) remaining time for next evade boundary check
|
||||
uint32 m_combatPulseTime; // (msecs) remaining time for next zone-in-combat pulse
|
||||
uint32 m_combatPulseDelay; // (secs) how often the creature puts the entire zone in combat (only works in dungeons)
|
||||
|
||||
ReactStates m_reactState; // for AI, not charmInfo
|
||||
void RegenerateHealth();
|
||||
|
||||
@@ -383,7 +383,6 @@ struct boss_headless_horseman : public ScriptedAI
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
_events.ScheduleEvent(EVENT_HORSEMAN_CLEAVE, 13s, 0, PHASE_1);
|
||||
_events.ScheduleEvent(EVENT_RANDOM_LAUGH, 30s, 60s);
|
||||
|
||||
@@ -337,7 +337,6 @@ struct npc_gatewatcher_petAI : public ScriptedAI
|
||||
}
|
||||
_JustEngagedWith();
|
||||
ScriptedAI::JustEngagedWith(who);
|
||||
me->SetCombatPulseDelay(5);
|
||||
}
|
||||
|
||||
void SetData(uint32 data, uint32 value) override
|
||||
|
||||
@@ -632,7 +632,6 @@ struct boss_faction_championsAI : public BossAI
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
DoCast(me, SPELL_ANTI_AOE, true);
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
if (Creature* pChampionController = instance->GetCreature(DATA_FACTION_CRUSADERS))
|
||||
|
||||
@@ -114,7 +114,6 @@ struct boss_jaraxxus : public BossAI
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetCombatPulseDelay(0);
|
||||
me->ResetLootMode();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
@@ -215,7 +215,6 @@ struct boss_northrend_beastsAI : public BossAI
|
||||
events.SetPhase(PHASE_EVENT);
|
||||
summons.DespawnAll();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetCombatPulseDelay(0);
|
||||
HandleInitialMovement();
|
||||
}
|
||||
|
||||
@@ -248,7 +247,6 @@ struct boss_northrend_beastsAI : public BossAI
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
ScheduleTasks();
|
||||
HandleInstanceProgress();
|
||||
@@ -356,10 +354,7 @@ struct boss_gormok : public boss_northrend_beastsAI
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
// Npc that should keep raid in combat while boss change
|
||||
if (Creature* combatStalker = me->SummonCreature(NPC_BEASTS_COMBAT_STALKER, CombatStalkerPosition))
|
||||
{
|
||||
DoZoneInCombat(combatStalker);
|
||||
combatStalker->SetCombatPulseDelay(5);
|
||||
}
|
||||
DoZoneInCombat();
|
||||
events.SetPhase(PHASE_COMBAT);
|
||||
DoCastSelf(SPELL_TANKING_GORMOK, true);
|
||||
|
||||
@@ -276,7 +276,6 @@ struct boss_twin_baseAI : public BossAI
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
DoCast(me, SurgeSpellId);
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
|
||||
events.ScheduleEvent(EVENT_TWIN_SPIKE, 20s);
|
||||
|
||||
@@ -271,7 +271,6 @@ struct boss_blood_council_controller : public BossAI
|
||||
return;
|
||||
}
|
||||
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
instance->SetBossState(DATA_BLOOD_PRINCE_COUNCIL, IN_PROGRESS);
|
||||
@@ -442,7 +441,6 @@ struct BloodPrincesBossAI : public BossAI
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetCombatPulseDelay(0);
|
||||
|
||||
me->SetImmuneToPC(false);
|
||||
_isEmpowered = false;
|
||||
@@ -452,7 +450,6 @@ struct BloodPrincesBossAI : public BossAI
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_PRINCES_CONTROL)))
|
||||
DoZoneInCombat(controller);
|
||||
|
||||
@@ -289,7 +289,6 @@ struct boss_lady_deathwhisper : public BossAI
|
||||
}
|
||||
|
||||
_phase = PHASE_ONE;
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
scheduler.CancelGroup(GROUP_INTRO);
|
||||
|
||||
@@ -272,7 +272,6 @@ struct boss_professor_putricide : public BossAI
|
||||
Talk(SAY_AGGRO);
|
||||
DoCast(me, SPELL_OOZE_TANK_PROTECTION, true);
|
||||
DoZoneInCombat(me);
|
||||
me->SetCombatPulseDelay(5);
|
||||
instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, IN_PROGRESS);
|
||||
}
|
||||
|
||||
|
||||
@@ -280,7 +280,6 @@ struct boss_sindragosa : public BossAI
|
||||
DoCastSelf(SPELL_PERMAEATING_CHILL);
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetBossState(DATA_SINDRAGOSA, IN_PROGRESS);
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
me->SetFarVisible(true);
|
||||
DoZoneInCombat();
|
||||
|
||||
@@ -552,7 +552,6 @@ struct boss_the_lich_king : public BossAI
|
||||
}
|
||||
|
||||
me->setActive(true);
|
||||
me->SetCombatPulseDelay(5);
|
||||
DoZoneInCombat();
|
||||
|
||||
events.SetPhase(PHASE_ONE);
|
||||
|
||||
@@ -177,7 +177,6 @@ struct boss_four_horsemen_baseAI : public BossAI
|
||||
case ACTION_BEGIN_FIGHTING:
|
||||
if (_ourMovementFinished)
|
||||
break;
|
||||
me->SetCombatPulseDelay(5);
|
||||
BeginFighting();
|
||||
_ourMovementFinished = true;
|
||||
break;
|
||||
@@ -305,7 +304,6 @@ struct boss_four_horsemen_baseAI : public BossAI
|
||||
_ourMovementFinished = false;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
SetCombatMovement(false);
|
||||
me->SetCombatPulseDelay(0);
|
||||
me->ResetLootMode();
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
@@ -329,10 +329,7 @@ struct boss_gothik : public BossAI
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (me->IsInCombat())
|
||||
{
|
||||
summon->AI()->DoAction(_gateIsOpen ? ACTION_GATE_OPENED : ACTION_ACQUIRE_TARGET);
|
||||
summon->SetCombatPulseDelay(5);
|
||||
}
|
||||
else
|
||||
summon->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
@@ -748,7 +748,6 @@ struct npc_kelthuzad_guardian : public ScriptedAI
|
||||
me->SetVisible(false);
|
||||
me->SetHomePosition(me->GetPosition());
|
||||
DoZoneInCombat();
|
||||
me->SetCombatPulseDelay(5);
|
||||
_visibilityTimer = 2 * IN_MILLISECONDS;
|
||||
_bloodTapTimer = 25 * IN_MILLISECONDS;
|
||||
break;
|
||||
@@ -781,7 +780,6 @@ struct npc_kelthuzad_guardian : public ScriptedAI
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetCombatPulseDelay(0);
|
||||
ScriptedAI::Reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -317,14 +317,12 @@ struct PalehoofMinionsBossAI : public BossAI
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetCombatPulseDelay(0);
|
||||
events.Reset();
|
||||
DoCastSelf(SPELL_FREEZE, true);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
ScheduleTasks();
|
||||
}
|
||||
|
||||
@@ -248,14 +248,12 @@ struct IllidariCouncilBossAI : public BossAI
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetCombatPulseDelay(0);
|
||||
events.Reset();
|
||||
DoCastSelf(SPELL_BALANCE_OF_POWER, true);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
if (Creature* illidari = instance->GetCreature(DATA_ILLIDARI_COUNCIL))
|
||||
DoZoneInCombat(illidari);
|
||||
|
||||
@@ -332,7 +332,6 @@ struct boss_essence_of_suffering : public BossAI
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
|
||||
events.ScheduleEvent(EVENT_SOUL_DRAIN, 20s);
|
||||
@@ -401,7 +400,6 @@ struct boss_essence_of_desire : public BossAI
|
||||
events.ScheduleEvent(EVENT_RUNE_SHIELD, 16s);
|
||||
events.ScheduleEvent(EVENT_DEADEN, 31s);
|
||||
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
Talk(DESI_SAY_FREED);
|
||||
}
|
||||
@@ -507,7 +505,6 @@ struct boss_essence_of_anger : public BossAI
|
||||
events.ScheduleEvent(EVENT_SPITE, 20s);
|
||||
events.ScheduleEvent(EVENT_FREED_2, Seconds(1), Minutes(3));
|
||||
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user