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

#include "CreatureGroups.h"

Public Types

typedef std::map< Creature *, FormationInfoCreatureGroupMemberType
 

Public Member Functions

 CreatureGroup (uint32 id)
 
 ~CreatureGroup ()
 
CreatureGetLeader () const
 
uint32 GetId () const
 
bool IsEmpty () const
 
bool IsFormed () const
 
const CreatureGroupMemberTypeGetMembers () const
 
void AddMember (Creature *member)
 
void RemoveMember (Creature *member)
 
void FormationReset (bool dismiss, bool initMotionMaster)
 
void LeaderMoveTo (float x, float y, float z, uint32 move_type)
 
void MemberEngagingTarget (Creature *member, Unit *target)
 
UnitGetNewTargetForMember (Creature *member)
 
void MemberEvaded (Creature *member)
 
void RespawnFormation (bool force=false)
 
bool IsFormationInCombat ()
 
bool IsAnyMemberAlive (bool ignoreLeader=false)
 

Private Attributes

Creaturem_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
96: m_leader(nullptr), m_groupID(id), m_Formed(false) {}
bool m_Formed
Definition CreatureGroups.h:124
Creature * m_leader
Definition CreatureGroups.h:120
uint32 m_groupID
Definition CreatureGroups.h:123

◆ ~CreatureGroup()

CreatureGroup::~CreatureGroup ( )
inline
97{}

Member Function Documentation

◆ AddMember()

void CreatureGroup::AddMember ( Creature member)
171{
172 LOG_DEBUG("entities.unit", "CreatureGroup::AddMember: Adding unit {}.", member->GetGUID().ToString());
173
174 //Check if it is a leader
175 if (member->GetSpawnId() == m_groupID)
176 {
177 LOG_DEBUG("entities.unit", "Unit {} is formation leader. Adding group.", member->GetGUID().ToString());
178 m_leader = member;
179 }
180
181 m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetSpawnId())->second;
182 member->SetFormation(this);
183}
#define sFormationMgr
Definition CreatureGroups.h:127
#define LOG_DEBUG(filterType__,...)
Definition Log.h:169
CreatureGroupMemberType m_members
Definition CreatureGroups.h:121
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:65
void SetFormation(CreatureGroup *formation)
Definition Creature.h:359
std::string ToString() const
Definition ObjectGuid.cpp:47
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:112

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

Referenced by FormationMgr::AddCreatureToGroup().

◆ FormationReset()

void CreatureGroup::FormationReset ( bool  dismiss,
bool  initMotionMaster 
)
324{
325 if (m_members.size() && !(m_members.begin()->second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER))))
326 return;
327
328 for (auto const& itr : m_members)
329 {
330 Creature* member = itr.first;
331 if (member && member != m_leader && member->IsAlive())
332 {
333 if (initMotionMaster)
334 {
335 if (dismiss)
336 member->GetMotionMaster()->Initialize();
337 else
338 member->GetMotionMaster()->MoveIdle();
339
340 LOG_DEBUG("entities.unit", "Set {} movement for member {}", dismiss ? "default" : "idle", member->GetGUID().ToString());
341 }
342 }
343 }
344 m_Formed = !dismiss;
345}
@ GROUP_AI_FLAG_FOLLOW_LEADER
Definition Creature.h:43
void Initialize()
Definition MotionMaster.cpp:73
void MoveIdle()
Definition MotionMaster.cpp:232
MotionMaster * GetMotionMaster()
Definition Unit.h:1673
bool IsAlive() const
Definition Unit.h:1707
std::string ToString(Type &&val, Params &&... params)
Definition StringConvert.h:250

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

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

◆ GetId()

uint32 CreatureGroup::GetId ( ) const
inline

◆ GetLeader()

◆ GetMembers()

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

References m_members.

◆ GetNewTargetForMember()

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

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)
444{
445 for (auto const& itr : m_members)
446 {
447 if (itr.first && itr.first->IsAlive())
448 {
449 if (!ignoreLeader || itr.first != m_leader)
450 {
451 return true;
452 }
453 }
454 }
455
456 return false;
457}

References m_leader, and m_members.

◆ IsEmpty()

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

References m_members.

Referenced by FormationMgr::RemoveCreatureFromGroup().

◆ IsFormationInCombat()

bool CreatureGroup::IsFormationInCombat ( )
431{
432 for (auto const& itr : m_members)
433 {
434 if (itr.first && itr.first->IsInCombat())
435 {
436 return true;
437 }
438 }
439
440 return false;
441}

References m_members.

◆ IsFormed()

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

References m_Formed.

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

◆ LeaderMoveTo()

void CreatureGroup::LeaderMoveTo ( float  x,
float  y,
float  z,
uint32  move_type 
)

To do: This should probably get its own movement generator or use WaypointMovementGenerator. If the leader's path is known, member's path can be plotted as well using formation offsets.

348{
351 if (!m_leader)
352 return;
353
354 float pathDist = m_leader->GetExactDist(x, y, z);
355 float pathAngle = std::atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
356
357 for (auto const& itr : m_members)
358 {
359 Creature* member = itr.first;
360 FormationInfo const& pFormationInfo = itr.second;
361 if (member == m_leader || !member->IsAlive() || member->GetVictim() || !pFormationInfo.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER)))
362 continue;
363
364 // Xinef: If member is stunned / rooted etc don't allow to move him
366 continue;
367
368 // Xinef: this should be automatized, if turn angle is greater than PI/2 (90�) we should swap formation angle
369 float followAngle = pFormationInfo.follow_angle;
370 if (static_cast<float>(M_PI) - std::fabs(std::fabs(m_leader->GetOrientation() - pathAngle) - static_cast<float>(M_PI)) > static_cast<float>(M_PI)* 0.5f)
371 {
372 // pussywizard: in both cases should be 2*M_PI - follow_angle
373 // pussywizard: also, GetCurrentWaypointID() returns 0..n-1, while point_1 must be > 0, so +1
374 // pussywizard: db table waypoint_data shouldn't have point id 0 and shouldn't have any gaps for this to work!
375 // if (m_leader->GetCurrentWaypointID()+1 == pFormationInfo->point_1 || m_leader->GetCurrentWaypointID()+1 == itr->second->point_2)
376 followAngle = Position::NormalizeOrientation(pFormationInfo.follow_angle + static_cast<float>(M_PI)); //(2 * M_PI) - itr->second->follow_angle;
377 }
378
379 float const followDist = pFormationInfo.follow_dist;
380
381 float dx = x + std::cos(followAngle + pathAngle) * followDist;
382 float dy = y + std::sin(followAngle + pathAngle) * followDist;
383 float dz = z;
384
387 if (move_type < 2)
388 member->UpdateGroundPositionZ(dx, dy, dz);
389
390 // pussywizard: setting the same movementflags is not enough, spline decides whether leader walks/runs, so spline param is now passed as "run" parameter to this function
392 switch (move_type)
393 {
396 break;
399 break;
402 break;
403 }
404
405 // xinef: if we move members to position without taking care of sizes, we should compare distance without sizes
406 // xinef: change members speed basing on distance - if too far speed up, if too close slow down
408 float const speedRate = m_leader->GetSpeedRate(mtype) * member->GetExactDist(dx, dy, dz) / pathDist;
409
410 if (speedRate > 0.01f) // don't move if speed rate is too low
411 {
412 member->SetSpeedRate(mtype, speedRate);
413 member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
414 member->SetHomePosition(dx, dy, dz, pathAngle);
415 }
416 }
417}
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition UnitDefines.h:375
@ MOVEMENTFLAG_WALKING
Definition UnitDefines.h:373
@ UNIT_STATE_NOT_MOVE
Definition UnitDefines.h:218
UnitMoveType
Definition UnitDefines.h:348
@ WAYPOINT_MOVE_TYPE_RUN
Definition WaypointMgr.h:29
@ WAYPOINT_MOVE_TYPE_LAND
Definition WaypointMgr.h:30
@ WAYPOINT_MOVE_TYPE_WALK
Definition WaypointMgr.h:28
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:340
void MovePoint(uint32 id, const Position &pos, bool generatePath=true, bool forceDestination=true)
Definition MotionMaster.h:213
uint32 GetUnitMovementFlags() const
Definition Unit.h:746
void SetUnitMovementFlags(uint32 f)
Definition Unit.h:747
void AddUnitMovementFlag(uint32 f)
Definition Unit.h:743
float GetSpeedRate(UnitMoveType mtype) const
Definition Unit.h:1654
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition Unit.h:1656
bool HasUnitState(const uint32 f) const
Definition Unit.h:707
void RemoveUnitMovementFlag(uint32 f)
Definition Unit.h:744
void UpdateGroundPositionZ(float x, float y, float &z) const
Definition Object.cpp:1541
void NormalizeMapCoord(float &c)
Definition GridDefines.h:198
UnitMoveType SelectSpeedType(uint32 moveFlags)
Definition MoveSplineInit.cpp:29
Definition CreatureGroups.h:52
float follow_dist
Definition CreatureGroups.h:64
float follow_angle
Definition CreatureGroups.h:65
bool HasGroupFlag(uint16 flag) const
Definition CreatureGroups.h:70
float GetExactDist(float x, float y, float z) const
Definition Position.h:182
static float NormalizeOrientation(float o)
Definition Position.h:237
float GetOrientation() const
Definition Position.h:124
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122

References Unit::AddUnitMovementFlag(), FormationInfo::follow_angle, FormationInfo::follow_dist, Position::GetExactDist(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Unit::GetSpeedRate(), Unit::GetUnitMovementFlags(), Unit::GetVictim(), GROUP_AI_FLAG_FOLLOW_LEADER, FormationInfo::HasGroupFlag(), Unit::HasUnitState(), Unit::IsAlive(), m_leader, m_members, MOVEMENTFLAG_DISABLE_GRAVITY, MOVEMENTFLAG_WALKING, MotionMaster::MovePoint(), Acore::NormalizeMapCoord(), Position::NormalizeOrientation(), Unit::RemoveUnitMovementFlag(), Movement::SelectSpeedType(), Creature::SetHomePosition(), Unit::SetSpeedRate(), Unit::SetUnitMovementFlags(), UNIT_STATE_NOT_MOVE, WorldObject::UpdateGroundPositionZ(), WAYPOINT_MOVE_TYPE_LAND, WAYPOINT_MOVE_TYPE_RUN, and WAYPOINT_MOVE_TYPE_WALK.

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

◆ MemberEngagingTarget()

void CreatureGroup::MemberEngagingTarget ( Creature member,
Unit target 
)
197{
198 uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
199 if (member == m_leader)
200 {
201 if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_MEMBER_ASSIST_LEADER)))
202 {
203 return;
204 }
205 }
206 else if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_LEADER_ASSIST_MEMBER)))
207 {
208 return;
209 }
210
211 for (auto const& itr : m_members)
212 {
213 Creature* pMember = itr.first;
214 if (!pMember)
215 {
216 continue;
217 }
218
219 if (pMember == member || !pMember->IsAlive() || pMember->GetVictim())
220 {
221 continue;
222 }
223
224 if (pMember == m_leader && !(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_LEADER_ASSIST_MEMBER)))
225 {
226 continue;
227 }
228
229 if (pMember->IsValidAttackTarget(target) && pMember->AI())
230 {
231 pMember->AI()->AttackStart(target);
232 }
233 }
234}
CreatureAI * AI() const
Definition Creature.h:141
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:27

References Creature::AI(), UnitAI::AttackStart(), 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)
284{
285 uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
286 if (!(groupAI & std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_EVADE_MASK)))
287 {
288 return;
289 }
290
291 for (auto const& itr : m_members)
292 {
293 Creature* pMember = itr.first;
294 // This should never happen
295 if (!pMember)
296 continue;
297
298 if (pMember == member || pMember->IsInEvadeMode() || !itr.second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_EVADE_MASK)))
299 continue;
300
301 if (itr.second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_EVADE_TOGETHER)))
302 {
303 if (!pMember->IsAlive() || !pMember->IsInCombat())
304 continue;
305
306 if (pMember->IsAIEnabled)
307 if (CreatureAI* pMemberAI = pMember->AI())
308 pMemberAI->EnterEvadeMode();
309 }
310 else
311 {
312 if (pMember->IsAlive())
313 continue;
314
315 if (itr.second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_DONT_RESPAWN_LEADER_ON_EVADE)) && pMember == m_leader)
316 continue;
317
318 pMember->Respawn();
319 }
320 }
321}
@ GROUP_AI_FLAG_EVADE_MASK
@ GROUP_AI_FLAG_EVADE_TOGETHER
@ GROUP_AI_FLAG_DONT_RESPAWN_LEADER_ON_EVADE
Definition CreatureAI.h:70
void Respawn(bool force=false)
Definition Creature.cpp:2044
bool IsInEvadeMode() const
Definition Creature.h:135
bool IsAIEnabled
Definition Unit.h:2012
bool IsInCombat() const
Definition Unit.h:893

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

◆ RemoveMember()

void CreatureGroup::RemoveMember ( Creature member)
186{
187 if (m_leader == member)
188 {
189 m_leader = nullptr;
190 }
191
192 m_members.erase(member);
193 member->SetFormation(nullptr);
194}

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

Referenced by FormationMgr::RemoveCreatureFromGroup().

◆ RespawnFormation()

void CreatureGroup::RespawnFormation ( bool  force = false)
420{
421 for (auto const& itr : m_members)
422 {
423 if (itr.first && !itr.first->IsAlive())
424 {
425 itr.first->Respawn(force);
426 }
427 }
428}

References m_members.

Member Data Documentation

◆ m_Formed

bool CreatureGroup::m_Formed
private

Referenced by FormationReset(), and IsFormed().

◆ m_groupID

uint32 CreatureGroup::m_groupID
private

Referenced by AddMember(), and GetId().

◆ m_leader

◆ m_members


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