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)
170{
171 LOG_DEBUG("entities.unit", "CreatureGroup::AddMember: Adding unit {}.", member->GetGUID().ToString());
172
173 //Check if it is a leader
174 if (member->GetSpawnId() == m_groupID)
175 {
176 LOG_DEBUG("entities.unit", "Unit {} is formation leader. Adding group.", member->GetGUID().ToString());
177 m_leader = member;
178 }
179
180 m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetSpawnId())->second;
181 member->SetFormation(this);
182}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:169
#define sFormationMgr
Definition: CreatureGroups.h:127
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:65
void SetFormation(CreatureGroup *formation)
Definition: Creature.h:355
CreatureGroupMemberType m_members
Definition: CreatureGroups.h:121
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:112
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 
)
323{
324 if (m_members.size() && !(m_members.begin()->second.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER))))
325 return;
326
327 for (auto const& itr : m_members)
328 {
329 Creature* member = itr.first;
330 if (member && member != m_leader && member->IsAlive())
331 {
332 if (initMotionMaster)
333 {
334 if (dismiss)
335 member->GetMotionMaster()->Initialize();
336 else
337 member->GetMotionMaster()->MoveIdle();
338
339 LOG_DEBUG("entities.unit", "Set {} movement for member {}", dismiss ? "default" : "idle", member->GetGUID().ToString());
340 }
341 }
342 }
343 m_Formed = !dismiss;
344}
Definition: Creature.h:43
MotionMaster * GetMotionMaster()
Definition: Unit.h:1620
bool IsAlive() const
Definition: Unit.h:1654
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
105{ return m_members; }

References m_members.

◆ GetNewTargetForMember()

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

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

◆ IsAnyMemberAlive()

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

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 ( )
430{
431 for (auto const& itr : m_members)
432 {
433 if (itr.first && itr.first->IsInCombat())
434 {
435 return true;
436 }
437 }
438
439 return false;
440}

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.

347{
350 if (!m_leader)
351 return;
352
353 float pathDist = m_leader->GetExactDist(x, y, z);
354 float pathAngle = std::atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
355
356 for (auto const& itr : m_members)
357 {
358 Creature* member = itr.first;
359 FormationInfo const& pFormationInfo = itr.second;
360 if (member == m_leader || !member->IsAlive() || member->GetVictim() || !pFormationInfo.HasGroupFlag(std::underlying_type_t<GroupAIFlags>(GroupAIFlags::GROUP_AI_FLAG_FOLLOW_LEADER)))
361 continue;
362
363 // Xinef: If member is stunned / rooted etc don't allow to move him
365 continue;
366
367 // Xinef: this should be automatized, if turn angle is greater than PI/2 (90�) we should swap formation angle
368 float followAngle = pFormationInfo.follow_angle;
369 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)
370 {
371 // pussywizard: in both cases should be 2*M_PI - follow_angle
372 // pussywizard: also, GetCurrentWaypointID() returns 0..n-1, while point_1 must be > 0, so +1
373 // pussywizard: db table waypoint_data shouldn't have point id 0 and shouldn't have any gaps for this to work!
374 // if (m_leader->GetCurrentWaypointID()+1 == pFormationInfo->point_1 || m_leader->GetCurrentWaypointID()+1 == itr->second->point_2)
375 followAngle = Position::NormalizeOrientation(pFormationInfo.follow_angle + static_cast<float>(M_PI)); //(2 * M_PI) - itr->second->follow_angle;
376 }
377
378 float const followDist = pFormationInfo.follow_dist;
379
380 float dx = x + std::cos(followAngle + pathAngle) * followDist;
381 float dy = y + std::sin(followAngle + pathAngle) * followDist;
382 float dz = z;
383
386 if (move_type < 2)
387 member->UpdateGroundPositionZ(dx, dy, dz);
388
389 // 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
391 switch (move_type)
392 {
395 break;
398 break;
401 break;
402 }
403
404 // xinef: if we move members to position without taking care of sizes, we should compare distance without sizes
405 // xinef: change members speed basing on distance - if too far speed up, if too close slow down
407 float const speedRate = m_leader->GetSpeedRate(mtype) * member->GetExactDist(dx, dy, dz) / pathDist;
408
409 if (speedRate > 0.01f) // don't move if speed rate is too low
410 {
411 member->SetSpeedRate(mtype, speedRate);
412 member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
413 member->SetHomePosition(dx, dy, dz, pathAngle);
414 }
415 }
416}
@ 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
@ 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 NormalizeMapCoord(float &c)
Definition: GridDefines.h:207
UnitMoveType SelectSpeedType(uint32 moveFlags)
Definition: MoveSplineInit.cpp:29
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:336
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
void UpdateGroundPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1541
float GetExactDist(float x, float y, float z) const
Definition: Position.h:177
static float NormalizeOrientation(float o)
Definition: Position.h:232
float GetOrientation() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:116
float GetPositionY() const
Definition: Position.h:117
uint32 GetUnitMovementFlags() const
Definition: Unit.h:737
void SetUnitMovementFlags(uint32 f)
Definition: Unit.h:738
void AddUnitMovementFlag(uint32 f)
Definition: Unit.h:734
float GetSpeedRate(UnitMoveType mtype) const
Definition: Unit.h:1601
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition: Unit.h:1603
bool HasUnitState(const uint32 f) const
Definition: Unit.h:701
void RemoveUnitMovementFlag(uint32 f)
Definition: Unit.h:735
void MovePoint(uint32 id, const Position &pos, bool generatePath=true, bool forceDestination=true)
Definition: MotionMaster.h:213

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

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

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)
185{
186 if (m_leader == member)
187 {
188 m_leader = nullptr;
189 }
190
191 m_members.erase(member);
192 member->SetFormation(nullptr);
193}

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

Referenced by FormationMgr::RemoveCreatureFromGroup().

◆ RespawnFormation()

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

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