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

◆ ~CreatureGroup()

CreatureGroup::~CreatureGroup ( )
inline
96{}

Member Function Documentation

◆ AddMember()

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

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 
)
322{
323 if (m_members.size() && !(m_members.begin()->second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER))))
324 return;
325
326 for (auto const& itr : m_members)
327 {
328 Creature* member = itr.first;
329 if (member && member != m_leader && member->IsAlive())
330 {
331 if (initMotionMaster)
332 {
333 if (dismiss)
334 member->GetMotionMaster()->Initialize();
335 else
336 member->GetMotionMaster()->MoveIdle();
337
338 LOG_DEBUG("entities.unit", "Set {} movement for member {}", dismiss ? "default" : "idle", member->GetGUID().ToString());
339 }
340 }
341 }
342 m_Formed = !dismiss;
343}
Definition: Creature.h:46
MotionMaster * GetMotionMaster()
Definition: Unit.h:1601
bool IsAlive() const
Definition: Unit.h:1204
void Initialize()
Definition: MotionMaster.cpp:73
void MoveIdle()
Definition: MotionMaster.cpp:232

References Object::GetGUID(), Unit::GetMotionMaster(), 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
104{ return m_members; }

References m_members.

◆ GetNewTargetForMember()

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

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

◆ IsAnyMemberAlive()

bool CreatureGroup::IsAnyMemberAlive ( bool  ignoreLeader = false)
442{
443 for (auto const& itr : m_members)
444 {
445 if (itr.first && itr.first->IsAlive())
446 {
447 if (!ignoreLeader || itr.first != m_leader)
448 {
449 return true;
450 }
451 }
452 }
453
454 return false;
455}

References m_leader, and m_members.

◆ IsEmpty()

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

References m_members.

Referenced by FormationMgr::RemoveCreatureFromGroup().

◆ IsFormationInCombat()

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

References m_members.

◆ IsFormed()

bool CreatureGroup::IsFormed ( ) const
inline
102{ 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.

346{
349 if (!m_leader)
350 return;
351
352 float pathDist = m_leader->GetExactDist(x, y, z);
353 float pathAngle = std::atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
354
355 for (auto const& itr : m_members)
356 {
357 Creature* member = itr.first;
358 FormationInfo const& pFormationInfo = itr.second;
359 if (member == m_leader || !member->IsAlive() || member->GetVictim() || !pFormationInfo.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER)))
360 continue;
361
362 // Xinef: If member is stunned / rooted etc don't allow to move him
364 continue;
365
366 // Xinef: this should be automatized, if turn angle is greater than PI/2 (90�) we should swap formation angle
367 float followAngle = pFormationInfo.follow_angle;
368 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)
369 {
370 // pussywizard: in both cases should be 2*M_PI - follow_angle
371 // pussywizard: also, GetCurrentWaypointID() returns 0..n-1, while point_1 must be > 0, so +1
372 // pussywizard: db table waypoint_data shouldn't have point id 0 and shouldn't have any gaps for this to work!
373 // if (m_leader->GetCurrentWaypointID()+1 == pFormationInfo->point_1 || m_leader->GetCurrentWaypointID()+1 == itr->second->point_2)
374 followAngle = Position::NormalizeOrientation(pFormationInfo.follow_angle + static_cast<float>(M_PI)); //(2 * M_PI) - itr->second->follow_angle;
375 }
376
377 float const followDist = pFormationInfo.follow_dist;
378
379 float dx = x + std::cos(followAngle + pathAngle) * followDist;
380 float dy = y + std::sin(followAngle + pathAngle) * followDist;
381 float dz = z;
382
385 if (move_type < 2)
386 member->UpdateGroundPositionZ(dx, dy, dz);
387
388 // 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
390 switch (move_type)
391 {
394 break;
397 break;
400 break;
401 }
402
403 // xinef: if we move members to position without taking care of sizes, we should compare distance without sizes
404 // xinef: change members speed basing on distance - if too far speed up, if too close slow down
406 float const speedRate = m_leader->GetSpeedRate(mtype) * member->GetExactDist(dx, dy, dz) / pathDist;
407
408 if (speedRate > 0.01f) // don't move if speed rate is too low
409 {
410 member->SetSpeedRate(mtype, speedRate);
411 member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
412 member->SetHomePosition(dx, dy, dz, pathAngle);
413 }
414 }
415}
@ WAYPOINT_MOVE_TYPE_RUN
Definition: WaypointMgr.h:29
@ WAYPOINT_MOVE_TYPE_LAND
Definition: WaypointMgr.h:30
@ WAYPOINT_MOVE_TYPE_WALK
Definition: WaypointMgr.h:28
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition: UnitDefines.h:354
@ MOVEMENTFLAG_WALKING
Definition: UnitDefines.h:352
@ UNIT_STATE_NOT_MOVE
Definition: UnitDefines.h:197
UnitMoveType
Definition: UnitDefines.h:327
void NormalizeMapCoord(float &c)
Definition: GridDefines.h:208
UnitMoveType SelectSpeedType(uint32 moveFlags)
Definition: MoveSplineInit.cpp:29
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:337
Definition: CreatureGroups.h:51
float follow_dist
Definition: CreatureGroups.h:63
float follow_angle
Definition: CreatureGroups.h:64
bool HasGroupFlag(uint16 flag) const
Definition: CreatureGroups.h:69
void UpdateGroundPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1530
float GetExactDist(float x, float y, float z) const
Definition: Position.h:178
static float NormalizeOrientation(float o)
Definition: Position.h:233
float GetOrientation() const
Definition: Position.h:120
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
uint32 GetUnitMovementFlags() const
Definition: Unit.h:1614
void SetUnitMovementFlags(uint32 f)
Definition: Unit.h:1615
void AddUnitMovementFlag(uint32 f)
Definition: Unit.h:1611
float GetSpeedRate(UnitMoveType mtype) const
Definition: Unit.h:1587
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition: Unit.h:1589
bool HasUnitState(const uint32 f) const
Definition: Unit.h:673
void RemoveUnitMovementFlag(uint32 f)
Definition: Unit.h:1612
void MovePoint(uint32 id, const Position &pos, bool generatePath=true, bool forceDestination=true)
Definition: MotionMaster.h:211

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

References Creature::AI(), UnitAI::AttackStart(), Creature::GetSpawnId(), Unit::GetVictim(), Unit::IsAlive(), Unit::IsValidAttackTarget(), m_leader, m_members, and sFormationMgr.

◆ MemberEvaded()

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

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

◆ RemoveMember()

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

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

Referenced by FormationMgr::RemoveCreatureFromGroup().

◆ RespawnFormation()

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

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