AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
CreatureGroup Class Reference

#include "CreatureGroups.h"

Public Types

typedef std::map< Creature *, FormationInfo > CreatureGroupMemberType
 

Public Member Functions

 CreatureGroup (uint32 id)
 
 ~CreatureGroup ()
 
Creature * GetLeader () const
 
uint32 GetId () const
 
bool IsEmpty () const
 
bool IsFormed () const
 
CreatureGroupMemberType const & GetMembers () const
 
void AddMember (Creature *member)
 
void RemoveMember (Creature *member)
 
void FormationReset (bool dismiss, bool initMotionMaster)
 
void LeaderStartedMoving ()
 
bool CanLeaderStartMoving () const
 
void RemoveFormationMovement ()
 
void MemberEngagingTarget (Creature *member, Unit *target)
 
Unit * GetNewTargetForMember (Creature *member)
 
void MemberEvaded (Creature *member)
 
void RespawnRemovedMembers (Map *map)
 
void DespawnFormation (Milliseconds timeToDespawn=0ms, Seconds forcedRespawnTimer=0s)
 
void RespawnFormation (bool force=false)
 
bool IsFormationInCombat ()
 
bool IsAnyMemberAlive (bool ignoreLeader=false)
 

Private Attributes

Creature * m_leader
 
CreatureGroupMemberType m_members
 
uint32 m_groupID
 
bool m_Formed
 

Detailed Description

Member Typedef Documentation

◆ CreatureGroupMemberType

Constructor & Destructor Documentation

◆ CreatureGroup()

CreatureGroup::CreatureGroup ( uint32  id)
inlineexplicit
101: m_leader(nullptr), m_groupID(id), m_Formed(false) {}
bool m_Formed
Definition CreatureGroups.h:133
Creature * m_leader
Definition CreatureGroups.h:129
uint32 m_groupID
Definition CreatureGroups.h:132

◆ ~CreatureGroup()

CreatureGroup::~CreatureGroup ( )
inline
102{}

Member Function Documentation

◆ AddMember()

void CreatureGroup::AddMember ( Creature *  member)
176{
177 LOG_DEBUG("entities.unit", "CreatureGroup::AddMember: Adding unit {}.", member->GetGUID().ToString());
178
179 //Check if it is a leader
180 if (member->GetSpawnId() == m_groupID)
181 {
182 LOG_DEBUG("entities.unit", "Unit {} is formation leader. Adding group.", member->GetGUID().ToString());
183 m_leader = member;
184 }
185
186 m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetSpawnId())->second;
187 member->SetFormation(this);
188}
#define sFormationMgr
Definition CreatureGroups.h:136
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
CreatureGroupMemberType m_members
Definition CreatureGroups.h:130
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:69
void SetFormation(CreatureGroup *formation)
Definition Creature.h:374
std::string ToString() const
Definition ObjectGuid.cpp:48
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:120

References Object::GetGUID(), Creature::GetSpawnId(), LOG_DEBUG, m_groupID, m_leader, m_members, Creature::SetFormation(), sFormationMgr, and ObjectGuid::ToString().

Referenced by FormationMgr::AddCreatureToGroup().

◆ CanLeaderStartMoving()

bool CreatureGroup::CanLeaderStartMoving ( ) const
434{
435 for (auto const& itr : m_members)
436 {
437 if (itr.first && itr.first != m_leader && itr.first->IsAlive())
438 if (itr.first->IsEngaged() || itr.first->IsInEvadeMode())
439 return false;
440 }
441
442 return true;
443}
bool IsAlive() const
Definition Unit.h:1796

References Unit::IsAlive(), m_leader, and m_members.

Referenced by RandomMovementGenerator< T >::_setRandomLocation(), and Creature::IsFormationLeaderMoveAllowed().

◆ DespawnFormation()

void CreatureGroup::DespawnFormation ( Milliseconds  timeToDespawn = 0ms,
Seconds  forcedRespawnTimer = 0s 
)
459{
460 // Copy the member list first: DespawnOrUnsummon() takes the member out of
461 // the world, which erases it from m_members and would invalidate this loop.
463
464 for (auto const& itr : members)
465 {
466 if (itr.first && itr.first->GetFormation() == this)
467 itr.first->DespawnOrUnsummon(timeToDespawn, forcedRespawnTimer);
468 }
469}
std::map< Creature *, FormationInfo > CreatureGroupMemberType
Definition CreatureGroups.h:98

References m_members.

◆ FormationReset()

void CreatureGroup::FormationReset ( bool  dismiss,
bool  initMotionMaster 
)
387{
388 if (m_members.size() && !(m_members.begin()->second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER))))
389 return;
390
391 for (auto const& itr : m_members)
392 {
393 Creature* member = itr.first;
394 if (member && member != m_leader && member->IsAlive())
395 {
396 if (initMotionMaster)
397 {
398 if (dismiss)
400 else
401 member->GetMotionMaster()->MoveIdle();
402
403 LOG_DEBUG("entities.unit", "Set {} movement for member {}", dismiss ? "default" : "idle", member->GetGUID().ToString());
404 }
405 }
406 }
407 m_Formed = !dismiss;
408}
@ GROUP_AI_FLAG_FOLLOW_LEADER
@ MOTION_SLOT_IDLE
Definition MotionMaster.h:64
Definition Creature.h:47
void MovementExpiredOnSlot(MovementSlot slot, bool reset=true)
Definition MotionMaster.h:221
void MoveIdle()
Definition MotionMaster.cpp:235
MotionMaster * GetMotionMaster()
Definition Unit.h:1761
std::string ToString(Type &&val, Params &&... params)
Definition StringConvert.h:250

References Object::GetGUID(), Unit::GetMotionMaster(), GROUP_AI_FLAG_FOLLOW_LEADER, Unit::IsAlive(), LOG_DEBUG, m_Formed, m_leader, m_members, MOTION_SLOT_IDLE, MotionMaster::MoveIdle(), MotionMaster::MovementExpiredOnSlot(), and ObjectGuid::ToString().

Referenced by Creature::Motion_Initialize(), and Creature::setDeathState().

◆ GetId()

uint32 CreatureGroup::GetId ( ) const
inline

◆ GetLeader()

◆ GetMembers()

CreatureGroupMemberType const & CreatureGroup::GetMembers ( ) const
inline
110{ return m_members; }

References m_members.

◆ GetNewTargetForMember()

Unit * CreatureGroup::GetNewTargetForMember ( Creature *  member)
243{
244 uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
245 if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_ACQUIRE_NEW_TARGET_ON_EVADE)))
246 {
247 return nullptr;
248 }
249
250 if (member == m_leader)
251 {
252 if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_MEMBER_ASSIST_LEADER)))
253 {
254 return nullptr;
255 }
256 }
257 else if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_LEADER_ASSIST_MEMBER)))
258 {
259 return nullptr;
260 }
261
262 for (auto const& itr : m_members)
263 {
264 Creature* pMember = itr.first;
265 if (!pMember)
266 {
267 continue;
268 }
269
270 if (pMember == member || !pMember->IsAlive() || !pMember->GetVictim())
271 {
272 continue;
273 }
274
275 if (pMember == m_leader && !(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_MEMBER_ASSIST_LEADER)))
276 {
277 continue;
278 }
279
280 if (member->IsValidAttackTarget(pMember->GetVictim()))
281 {
282 return pMember->GetVictim();
283 }
284 }
285
286 return nullptr;
287}
@ GROUP_AI_FLAG_ACQUIRE_NEW_TARGET_ON_EVADE
@ GROUP_AI_FLAG_LEADER_ASSIST_MEMBER
@ GROUP_AI_FLAG_MEMBER_ASSIST_LEADER
std::uint8_t uint8
Definition Define.h:109
Unit * GetVictim() const
Definition Unit.h:904
bool IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell=nullptr) const
Definition Unit.cpp:10487

References Creature::GetSpawnId(), Unit::GetVictim(), GROUP_AI_FLAG_ACQUIRE_NEW_TARGET_ON_EVADE, GROUP_AI_FLAG_LEADER_ASSIST_MEMBER, GROUP_AI_FLAG_MEMBER_ASSIST_LEADER, Unit::IsAlive(), Unit::IsValidAttackTarget(), m_leader, m_members, and sFormationMgr.

◆ IsAnyMemberAlive()

bool CreatureGroup::IsAnyMemberAlive ( bool  ignoreLeader = false)
500{
501 for (auto const& itr : m_members)
502 {
503 if (itr.first && itr.first->IsAlive())
504 {
505 if (!ignoreLeader || itr.first != m_leader)
506 {
507 return true;
508 }
509 }
510 }
511
512 return false;
513}

References m_leader, and m_members.

Referenced by instance_azjol_nerub::instance_azjol_nerub_InstanceScript::OnUnitDeath().

◆ IsEmpty()

bool CreatureGroup::IsEmpty ( ) const
inline
107{ return m_members.empty(); }

References m_members.

Referenced by FormationMgr::RemoveCreatureFromGroup().

◆ IsFormationInCombat()

bool CreatureGroup::IsFormationInCombat ( )
487{
488 for (auto const& itr : m_members)
489 {
490 if (itr.first && itr.first->IsInCombat())
491 {
492 return true;
493 }
494 }
495
496 return false;
497}

References m_members.

◆ IsFormed()

bool CreatureGroup::IsFormed ( ) const
inline
108{ return m_Formed; }

References m_Formed.

Referenced by Creature::Motion_Initialize(), and npc_cameron::UpdateAI().

◆ LeaderStartedMoving()

void CreatureGroup::LeaderStartedMoving ( )
411{
412 if (!m_leader)
413 return;
414
415 for (auto const& itr : m_members)
416 {
417 Creature* member = itr.first;
418 FormationInfo const& pFormationInfo = itr.second;
419 if (member == m_leader || !member->IsAlive() || member->GetVictim() || !pFormationInfo.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER)))
420 continue;
421
423 continue;
424
425 float const followAngle = pFormationInfo.follow_angle;
426 float const followDist = pFormationInfo.follow_dist;
427
429 member->GetMotionMaster()->MoveFormation(m_leader, followDist, followAngle, pFormationInfo.point_1, pFormationInfo.point_2);
430 }
431}
@ UNIT_STATE_NOT_MOVE
Definition UnitDefines.h:225
@ UNIT_STATE_FOLLOW_MOVE
Definition UnitDefines.h:199
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition UnitDefines.h:260
void MoveFormation(Unit *leader, float dist, float angle, uint32 point1, uint32 point2)
Definition MotionMaster.cpp:471
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:748
bool isPossessed() const
Definition Unit.h:1316
bool HasUnitState(const uint32 f) const
Definition Unit.h:737
Definition CreatureGroups.h:54
float follow_dist
Definition CreatureGroups.h:66
uint32 point_1
Definition CreatureGroups.h:69
float follow_angle
Definition CreatureGroups.h:67
uint32 point_2
Definition CreatureGroups.h:70
bool HasGroupFlag(uint16 flag) const
Definition CreatureGroups.h:72

References FormationInfo::follow_angle, FormationInfo::follow_dist, Unit::GetMotionMaster(), Unit::GetVictim(), GROUP_AI_FLAG_FOLLOW_LEADER, FormationInfo::HasGroupFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), Unit::IsAlive(), Unit::isPossessed(), m_leader, m_members, MotionMaster::MoveFormation(), FormationInfo::point_1, FormationInfo::point_2, UNIT_FLAG_PLAYER_CONTROLLED, UNIT_STATE_FOLLOW_MOVE, and UNIT_STATE_NOT_MOVE.

Referenced by RandomMovementGenerator< T >::_setRandomLocation(), Creature::Motion_Initialize(), and Creature::SignalFormationMovement().

◆ MemberEngagingTarget()

void CreatureGroup::MemberEngagingTarget ( Creature *  member,
Unit *  target 
)
203{
204 uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
205 if (member == m_leader)
206 {
207 if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_MEMBER_ASSIST_LEADER)))
208 {
209 return;
210 }
211 }
212 else if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_LEADER_ASSIST_MEMBER)))
213 {
214 return;
215 }
216
217 for (auto const& itr : m_members)
218 {
219 Creature* pMember = itr.first;
220 if (!pMember)
221 {
222 continue;
223 }
224
225 if (pMember == member || !pMember->IsAlive() || pMember->GetVictim())
226 {
227 continue;
228 }
229
230 if (pMember == m_leader && !(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_LEADER_ASSIST_MEMBER)))
231 {
232 continue;
233 }
234
235 if (pMember->IsValidAttackTarget(target))
236 {
237 pMember->EngageWithTarget(target);
238 }
239 }
240}
void EngageWithTarget(Unit *who)
Definition Unit.cpp:7306

References Unit::EngageWithTarget(), Creature::GetSpawnId(), Unit::GetVictim(), GROUP_AI_FLAG_LEADER_ASSIST_MEMBER, GROUP_AI_FLAG_MEMBER_ASSIST_LEADER, Unit::IsAlive(), Unit::IsValidAttackTarget(), m_leader, m_members, and sFormationMgr.

◆ MemberEvaded()

void CreatureGroup::MemberEvaded ( Creature *  member)
290{
291 uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
292 if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_EVADE_MASK)))
293 {
294 return;
295 }
296
297 // Copy the member list first: Respawn() below takes the member out of the
298 // world, which erases it from m_members and would invalidate this loop.
300
301 for (auto const& itr : members)
302 {
303 Creature* pMember = itr.first;
304 // This should never happen
305 if (!pMember)
306 continue;
307
308 // A previous member's Respawn() or EnterEvadeMode() may have removed
309 // this one from the group already.
310 if (pMember->GetFormation() != this)
311 continue;
312
313 if (pMember == member || pMember->IsInEvadeMode() || !itr.second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_EVADE_MASK)))
314 continue;
315
316 // EVADE_TOGETHER and RESPAWN_ON_EVADE are independent: living members evade, dead members respawn.
317 if (pMember->IsAlive())
318 {
319 if (!itr.second.HasGroupFlag(
320 std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_EVADE_TOGETHER)))
321 continue;
322
323 if (!pMember->IsInCombat())
324 continue;
325
326 if (pMember->IsAIEnabled)
327 if (CreatureAI* pMemberAI = pMember->AI())
328 pMemberAI->EnterEvadeMode();
329 }
330 else
331 {
332 if (!itr.second.HasGroupFlag(
333 std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_RESPAWN_ON_EVADE)))
334 continue;
335
336 if (itr.second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_DONT_RESPAWN_LEADER_ON_EVADE)) && pMember == m_leader)
337 continue;
338
339 pMember->Respawn();
340 }
341 }
342
343 RespawnRemovedMembers(member->GetMap());
344}
@ GROUP_AI_FLAG_EVADE_MASK
@ GROUP_AI_FLAG_EVADE_TOGETHER
@ GROUP_AI_FLAG_DONT_RESPAWN_LEADER_ON_EVADE
@ GROUP_AI_FLAG_RESPAWN_ON_EVADE
Definition CreatureAI.h:69
void RespawnRemovedMembers(Map *map)
Definition CreatureGroups.cpp:349
void Respawn(bool force=false)
Definition Creature.cpp:2044
CreatureGroup const * GetFormation() const
Definition Creature.h:372
bool IsInEvadeMode() const
Definition Creature.h:138
CreatureAI * AI() const
Definition Creature.h:144
bool IsAIEnabled
Definition Unit.h:2102
bool IsInCombat() const
Definition Unit.h:941
Map * GetMap() const
Definition Object.h:637

References Creature::AI(), Creature::GetFormation(), WorldObject::GetMap(), Creature::GetSpawnId(), GROUP_AI_FLAG_DONT_RESPAWN_LEADER_ON_EVADE, GROUP_AI_FLAG_EVADE_MASK, GROUP_AI_FLAG_EVADE_TOGETHER, GROUP_AI_FLAG_RESPAWN_ON_EVADE, Unit::IsAIEnabled, Unit::IsAlive(), Unit::IsInCombat(), Creature::IsInEvadeMode(), m_leader, m_members, Creature::Respawn(), RespawnRemovedMembers(), and sFormationMgr.

◆ RemoveFormationMovement()

void CreatureGroup::RemoveFormationMovement ( )
446{
447 for (auto const& itr : m_members)
448 {
449 Creature* member = itr.first;
450 if (!member || member == m_leader)
451 continue;
452
455 }
456}
@ FORMATION_MOTION_TYPE
Definition MotionMaster.h:58
MovementGeneratorType GetMotionSlotType(int slot) const
Definition MotionMaster.cpp:1093

References FORMATION_MOTION_TYPE, Unit::GetMotionMaster(), MotionMaster::GetMotionSlotType(), m_leader, m_members, MOTION_SLOT_IDLE, and MotionMaster::MovementExpiredOnSlot().

Referenced by RemoveMember().

◆ RemoveMember()

void CreatureGroup::RemoveMember ( Creature *  member)
191{
192 if (m_leader == member)
193 {
195 m_leader = nullptr;
196 }
197
198 m_members.erase(member);
199 member->SetFormation(nullptr);
200}
void RemoveFormationMovement()
Definition CreatureGroups.cpp:445

References m_leader, m_members, RemoveFormationMovement(), and Creature::SetFormation().

Referenced by FormationMgr::RemoveCreatureFromGroup().

◆ RespawnFormation()

void CreatureGroup::RespawnFormation ( bool  force = false)
472{
473 // Copy the member list first: Respawn() takes the member out of the world,
474 // which erases it from m_members and would invalidate this loop.
476
477 for (auto const& itr : members)
478 {
479 if (itr.first && itr.first->GetFormation() == this && !itr.first->IsAlive())
480 {
481 itr.first->Respawn(force);
482 }
483 }
484}

References m_members.

Referenced by boss_krik_thir::boss_krik_thirAI::Reset().

◆ RespawnRemovedMembers()

void CreatureGroup::RespawnRemovedMembers ( Map *  map)
350{
351 auto const membersItr = sFormationMgr->CreatureGroupMembers.find(m_groupID);
352 if (membersItr == sFormationMgr->CreatureGroupMembers.end())
353 return;
354
355 time_t now = GameTime::GetGameTime().count();
356 for (ObjectGuid::LowType spawnId : membersItr->second)
357 {
358 bool const inWorld = std::any_of(m_members.begin(), m_members.end(), [spawnId](auto const& itr)
359 {
360 return itr.first->GetSpawnId() == spawnId;
361 });
362 if (inWorld)
363 continue;
364
365 auto const infoItr = sFormationMgr->CreatureGroupMap.find(spawnId);
366 if (infoItr == sFormationMgr->CreatureGroupMap.end())
367 continue;
368
369 FormationInfo const& info = infoItr->second;
370 if (!info.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_RESPAWN_ON_EVADE)))
371 continue;
372
373 if (spawnId == m_groupID && info.HasGroupFlag(
374 std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_DONT_RESPAWN_LEADER_ON_EVADE)))
375 continue;
376
377 // Only creatures with a respawn still pending on this map: one without a stored time (alive, never loaded)
378 // is left alone, one already due (evade cascade of the same tick) is left to ProcessRespawns().
379 if (map->GetCreatureRespawnTime(spawnId) <= now)
380 continue;
381
382 map->SaveCreatureRespawnTime(spawnId, now);
383 }
384}
time_t GetCreatureRespawnTime(ObjectGuid::LowType dbGuid) const
Definition Map.h:416
void SaveCreatureRespawnTime(ObjectGuid::LowType dbGuid, time_t &respawnTime)
Definition Map.cpp:2477
uint32 LowType
Definition ObjectGuid.h:125
Seconds GetGameTime()
Definition GameTime.cpp:38

References Map::GetCreatureRespawnTime(), GameTime::GetGameTime(), GROUP_AI_FLAG_DONT_RESPAWN_LEADER_ON_EVADE, GROUP_AI_FLAG_RESPAWN_ON_EVADE, FormationInfo::HasGroupFlag(), m_groupID, m_members, Map::SaveCreatureRespawnTime(), and sFormationMgr.

Referenced by MemberEvaded().

Member Data Documentation

◆ m_Formed

bool CreatureGroup::m_Formed
private

Referenced by FormationReset(), and IsFormed().

◆ m_groupID

uint32 CreatureGroup::m_groupID
private

◆ m_leader

◆ m_members


The documentation for this class was generated from the following files: