Core/Instances: New ZoneScript hook - OnCreatureGroupDepleted

* Triggers when the CreatureGroup no longer has any alive members (either last alive member dies or is removed from the group)

(cherry picked from commit ec2631eca3)
This commit is contained in:
Shauren
2024-07-12 12:29:22 +02:00
committed by Ovahlord
parent db2d4c484b
commit cdfe0f21f7
5 changed files with 63 additions and 6 deletions

View File

@@ -361,7 +361,7 @@ void Creature::RemoveFromWorld()
GetZoneScript()->OnCreatureRemove(this);
if (m_formation)
sFormationMgr->RemoveCreatureFromGroup(m_formation, this);
FormationMgr::RemoveCreatureFromGroup(m_formation, this);
Unit::RemoveFromWorld();
@@ -2112,8 +2112,15 @@ void Creature::setDeathState(DeathState s)
SetNoSearchAssistance(false);
//Dismiss group if is leader
if (m_formation && m_formation->GetLeader() == this)
m_formation->FormationReset(true);
if (m_formation)
{
if (m_formation->GetLeader() == this)
m_formation->FormationReset(true);
if (ZoneScript* script = GetZoneScript())
if (!m_formation->HasAliveMembers())
script->OnCreatureGroupDepleted(m_formation);
}
bool needsFalling = (IsFlying() || IsHovering()) && !IsUnderWater() && !HasUnitState(UNIT_STATE_ROOT);
SetHover(false, false);

View File

@@ -25,6 +25,7 @@
#include "MotionMaster.h"
#include "MovementGenerator.h"
#include "ObjectMgr.h"
#include "ZoneScript.h"
FormationMgr::FormationMgr() = default;
FormationMgr::~FormationMgr() = default;
@@ -74,6 +75,12 @@ void FormationMgr::RemoveCreatureFromGroup(CreatureGroup* group, Creature* membe
TC_LOG_DEBUG("entities.unit", "Deleting member pointer to GUID: {} from group {}", leaderSpawnId, member->GetSpawnId());
group->RemoveMember(member);
// If removed member was alive we need to check if we have any other alive members
// if not - fire OnCreatureGroupDepleted
if (ZoneScript* script = member->GetZoneScript())
if (member->IsAlive() && !group->HasAliveMembers())
script->OnCreatureGroupDepleted(group);
if (group->IsEmpty())
{
if (leaderSpawnId)
@@ -302,3 +309,25 @@ bool CreatureGroup::CanLeaderStartMoving() const
return true;
}
bool CreatureGroup::HasAliveMembers() const
{
return std::ranges::any_of(_members, [](Creature const* member) { return member->IsAlive(); }, &MembersMap::value_type::first);
}
bool CreatureGroup::LeaderHasStringId(std::string_view id) const
{
if (_leader)
return _leader->HasStringId(id);
if (CreatureData const* leaderCreatureData = sObjectMgr->GetCreatureData(_leaderSpawnId))
{
if (leaderCreatureData->StringId == id)
return true;
if (ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(leaderCreatureData->id))->StringId == id)
return true;
}
return false;
}

View File

@@ -74,7 +74,9 @@ class TC_GAME_API CreatureGroup
{
private:
Creature* _leader;
std::unordered_map<Creature*, FormationInfo*> _members;
using MembersMap = std::unordered_map<Creature*, FormationInfo*>;
MembersMap _members;
ObjectGuid::LowType _leaderSpawnId;
bool _formed;
@@ -103,6 +105,10 @@ class TC_GAME_API CreatureGroup
void LeaderStartedMoving();
void MemberEngagingTarget(Creature* member, Unit* target);
bool CanLeaderStartMoving() const;
bool HasAliveMembers() const;
bool LeaderHasStringId(std::string_view id) const;
};
#define sFormationMgr FormationMgr::instance()

View File

@@ -19,6 +19,13 @@
#include "Creature.h"
#include "GameEventSender.h"
ControlZoneHandler::ControlZoneHandler() = default;
ControlZoneHandler::ControlZoneHandler(ControlZoneHandler const& right) = default;
ControlZoneHandler::ControlZoneHandler(ControlZoneHandler&& right) noexcept = default;
ControlZoneHandler& ControlZoneHandler::operator=(ControlZoneHandler const& right) = default;
ControlZoneHandler& ControlZoneHandler::operator=(ControlZoneHandler&& right) noexcept = default;
ControlZoneHandler::~ControlZoneHandler() = default;
ZoneScript::ZoneScript() = default;
ZoneScript::ZoneScript(ZoneScript const& right) = default;
ZoneScript::ZoneScript(ZoneScript&& right) noexcept = default;

View File

@@ -23,6 +23,7 @@
class AreaTrigger;
class Creature;
class CreatureGroup;
class GameObject;
class Player;
class Unit;
@@ -41,8 +42,12 @@ enum class EncounterType : uint8
class TC_GAME_API ControlZoneHandler
{
public:
explicit ControlZoneHandler() = default;
virtual ~ControlZoneHandler() = default;
explicit ControlZoneHandler();
ControlZoneHandler(ControlZoneHandler const& right);
ControlZoneHandler(ControlZoneHandler&& right) noexcept;
ControlZoneHandler& operator=(ControlZoneHandler const& right);
ControlZoneHandler& operator=(ControlZoneHandler&& right) noexcept;
virtual ~ControlZoneHandler();
virtual void HandleCaptureEventHorde([[maybe_unused]] GameObject* controlZone) { }
virtual void HandleCaptureEventAlliance([[maybe_unused]] GameObject* controlZone) { }
@@ -79,6 +84,9 @@ class TC_GAME_API ZoneScript
virtual void OnUnitDeath([[maybe_unused]] Unit* unit) { }
// Triggers when the CreatureGroup no longer has any alive members (either last alive member dies or is removed from the group)
virtual void OnCreatureGroupDepleted([[maybe_unused]] CreatureGroup const* creatureGroup) { }
//All-purpose data storage ObjectGuid
virtual ObjectGuid GetGuidData(uint32 /*DataId*/) const { return ObjectGuid::Empty; }
virtual void SetGuidData(uint32 /*DataId*/, ObjectGuid /*Value*/) { }