52 for (
auto const& [spawnId, other] : bounds)
54 if (other == creature)
57 if (itr->second->HasMember(other))
58 itr->second->RemoveMember(other);
64 TC_LOG_DEBUG(
"entities.unit",
"Group not found: {}. Creating new group.", leaderSpawnId);
68 itr->second->AddMember(creature);
75 TC_LOG_DEBUG(
"entities.unit",
"Deleting member pointer to GUID: {} from group {}", leaderSpawnId, member->
GetSpawnId());
82 script->OnCreatureGroupDepleted(group);
103 QueryResult result =
WorldDatabase.Query(
"SELECT leaderGUID, memberGUID, dist, angle, groupAI, point_1, point_2 FROM creature_formations ORDER BY leaderGUID");
106 TC_LOG_INFO(
"server.loading",
">> Loaded 0 creatures in formations. DB table `creature_formations` is empty!");
111 std::unordered_set<ObjectGuid::LowType> leaderSpawnIds;
114 Field* fields = result->Fetch();
122 if (!
sObjectMgr->GetCreatureData(leaderSpawnId))
124 TC_LOG_ERROR(
"sql.sql",
"creature_formations table leader guid {} incorrect (not exist)", leaderSpawnId);
128 if (!
sObjectMgr->GetCreatureData(memberSpawnId))
130 TC_LOG_ERROR(
"sql.sql",
"creature_formations table member guid {} incorrect (not exist)", memberSpawnId);
134 leaderSpawnIds.insert(leaderSpawnId);
150 for (
uint8 i = 0; i < 2; ++i)
154 }
while (result->NextRow());
160 TC_LOG_ERROR(
"sql.sql",
"creature_formation contains leader spawn {} which is not included on its formation, removing", leaderSpawnId);
163 if (itr->second.LeaderSpawnId == leaderSpawnId)
189 for (
uint8 i = 0; i < 2; ++i)
201 TC_LOG_DEBUG(
"entities.unit",
"CreatureGroup::AddMember: Adding unit {}.", member->
GetGUID());
207 TC_LOG_DEBUG(
"entities.unit",
"Unit {} is formation leader. Adding group.", member->
GetGUID());
248 for (
auto const& [other, _] :
_members)
253 if (!other->IsAlive())
257 other->EngageWithTarget(target);
265 for (
auto const& [member, _] :
_members)
272 member->GetMotionMaster()->MoveIdle();
274 TC_LOG_DEBUG(
"entities.unit",
"CreatureGroup::FormationReset: Set {} movement for member {}", dismiss ?
"default" :
"idle", member->GetGUID());
286 for (
auto const& [member, formationInfo] :
_members)
291 float angle = formationInfo->FollowAngle + float(
M_PI);
292 float dist = formationInfo->FollowDist;
295 member->GetMotionMaster()->MoveFormation(
_leader, dist, angle, formationInfo->LeaderWaypointIDs[0], formationInfo->LeaderWaypointIDs[1]);
301 for (
auto const& [member, _] :
_members)
305 if (member->IsEngaged() || member->IsReturningHome())
325 if (leaderCreatureData->StringId ==
id)
@ FLAG_LEADER_ASSISTS_MEMBER
@ FLAG_MEMBERS_ASSIST_LEADER
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
#define ASSERT_NOTNULL(pointer)
#define TC_LOG_DEBUG(filterType__, message__,...)
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
ObjectGuid const & GetGUID() const
CreatureGroup(ObjectGuid::LowType leaderSpawnId)
void FormationReset(bool dismiss)
ObjectGuid::LowType GetLeaderSpawnId() const
bool HasAliveMembers() const
void RemoveMember(Creature *member)
void LeaderStartedMoving()
void MemberEngagingTarget(Creature *member, Unit *target)
bool CanLeaderStartMoving() const
ObjectGuid::LowType _leaderSpawnId
bool LeaderHasStringId(std::string_view id) const
void AddMember(Creature *member)
bool HasStringId(std::string_view id) const
ObjectGuid::LowType GetSpawnId() const
void SetFormation(CreatureGroup *formation)
Class used to access individual fields of database query result.
float GetFloat() const noexcept
uint64 GetUInt64() const noexcept
uint32 GetUInt32() const noexcept
uint16 GetUInt16() const noexcept
std::unordered_map< ObjectGuid::LowType, CreatureGroup * > CreatureGroupHolder
CreatureBySpawnIdContainer & GetCreatureBySpawnIdStore()
uint32 GetInstanceId() const
ZoneScript * GetZoneScript() const
uint32 GetInstanceId() const
auto MapEqualRange(M &map, typename M::key_type const &key)
auto MapGetValuePtr(M &map, typename M::key_type const &key)