aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Creature
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-07-12 12:29:22 +0200
committerShauren <shauren.trinity@gmail.com>2024-07-12 12:29:22 +0200
commitec2631eca3a397dffd2e525b34c131c283beb167 (patch)
treecd3fafd70074bf29af3e507b7e9dbd879fe9a2a4 /src/server/game/Entities/Creature
parent9a7a83ef3074faaad037cfb4c098784695f49d30 (diff)
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)
Diffstat (limited to 'src/server/game/Entities/Creature')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp13
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.cpp29
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.h8
3 files changed, 46 insertions, 4 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index d466920c81f..9b3a159e2f7 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -362,7 +362,7 @@ void Creature::RemoveFromWorld()
GetZoneScript()->OnCreatureRemove(this);
if (m_formation)
- sFormationMgr->RemoveCreatureFromGroup(m_formation, this);
+ FormationMgr::RemoveCreatureFromGroup(m_formation, this);
Unit::RemoveFromWorld();
@@ -2216,8 +2216,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);
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index 4f04f26ea90..179e3c5179f 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -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;
+}
diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h
index be8a9967bf5..c7afaa1cedd 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.h
+++ b/src/server/game/Entities/Creature/CreatureGroups.h
@@ -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()