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

#include "Group.h"

Classes

struct  MemberSlot
 

Public Types

typedef std::list< MemberSlot > MemberSlotList
 
typedef MemberSlotList::const_iterator member_citerator
 

Public Member Functions

 Group ()
 
 ~Group ()
 
bool Create (Player *leader)
 
bool LoadGroupFromDB (Field *field)
 
void LoadMemberFromDB (ObjectGuid::LowType guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
 
bool AddInvite (Player *player)
 
void RemoveInvite (Player *player)
 
void RemoveAllInvites ()
 
bool AddLeaderInvite (Player *player)
 
bool AddMember (Player *player, uint8 roles=0)
 
bool RemoveMember (ObjectGuid guid, RemoveMethod const &method=GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker=ObjectGuid::Empty, char const *reason=nullptr)
 
void ChangeLeader (ObjectGuid guid)
 
void SetLootMethod (LootMethod method)
 
void SetLooterGuid (ObjectGuid guid)
 
void SetMasterLooterGuid (ObjectGuid guid)
 
void UpdateLooterGuid (WorldObject *pLootedObject, bool ifneed=false)
 
void SetLootThreshold (ItemQualities threshold)
 
void Disband (bool hideDestroy=false)
 
void SetLfgRoles (ObjectGuid guid, const uint8 roles)
 
bool IsFull () const
 
bool isLFGGroup (bool restricted=false) const
 
bool isRaidGroup () const
 
bool isBFGroup () const
 
bool isBGGroup () const
 
bool IsCreated () const
 
GroupType GetGroupType () const
 
ObjectGuid GetLeaderGUID () const
 
Player * GetLeader ()
 
ObjectGuid GetGUID () const
 
char const * GetLeaderName () const
 
LootMethod GetLootMethod () const
 
ObjectGuid GetLooterGuid () const
 
ObjectGuid GetMasterLooterGuid () const
 
ItemQualities GetLootThreshold () const
 
bool IsMember (ObjectGuid guid) const
 
bool IsLeader (ObjectGuid guid) const
 
ObjectGuid GetMemberGUID (std::string const &name)
 
bool IsAssistant (ObjectGuid guid) const
 
Player * GetInvited (ObjectGuid guid) const
 
Player * GetInvited (std::string const &name) const
 
bool SameSubGroup (ObjectGuid guid1, ObjectGuid guid2) const
 
bool SameSubGroup (ObjectGuid guid1, MemberSlot const *slot2) const
 
bool SameSubGroup (Player const *member1, Player const *member2) const
 
bool HasFreeSlotSubGroup (uint8 subgroup) const
 
MemberSlotList const & GetMemberSlots () const
 
GroupReference * GetFirstMember ()
 
GroupReference const * GetFirstMember () const
 
uint32 GetMembersCount () const
 
uint32 GetInviteeCount () const
 
uint8 GetMemberGroup (ObjectGuid guid) const
 
void ConvertToLFG (bool restricted=true)
 
bool CheckLevelForRaid ()
 
void ConvertToRaid ()
 
void SetBattlegroundGroup (Battleground *bg)
 
void SetBattlefieldGroup (Battlefield *bf)
 
GroupJoinBattlegroundResult CanJoinBattlegroundQueue (Battleground const *bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
 
void DoMinimapPing (ObjectGuid sourceGuid, float mapX, float mapY)
 
void ChangeMembersGroup (ObjectGuid guid, uint8 group)
 
void SetTargetIcon (uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid)
 
void SetGroupMemberFlag (ObjectGuid guid, bool apply, GroupMemberFlags flag)
 
void RemoveUniqueGroupMemberFlag (GroupMemberFlags flag)
 
ObjectGuid GetTargetIcon (uint8 id) const
 
Difficulty GetDifficulty (bool isRaid) const
 
Difficulty GetDungeonDifficulty () const
 
Difficulty GetRaidDifficulty () const
 
void SetDungeonDifficulty (Difficulty difficulty)
 
void SetRaidDifficulty (Difficulty difficulty)
 
uint16 InInstance ()
 
void ResetInstances (uint8 method, bool isRaid, Player *leader)
 
void SendTargetIconList (WorldSession *session)
 
void SendUpdate ()
 
void SendUpdateToPlayer (ObjectGuid playerGUID, MemberSlot *slot=nullptr)
 
void UpdatePlayerOutOfRange (Player *player)
 
void BroadcastPacket (WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty)
 
void BroadcastReadyCheck (WorldPacket const *packet)
 
void OfflineReadyCheck ()
 
bool isRollLootActive () const
 
void SendLootStartRoll (uint32 CountDown, uint32 mapid, Roll const &r)
 
void SendLootStartRollToPlayer (uint32 countDown, uint32 mapId, Player *p, bool canNeed, Roll const &r)
 
void SendPendingRollsToPlayer (Player *player, Map *map)
 
void SendLootRoll (ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const &r, bool autoPass=false)
 
void SendLootRollWon (ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const &r)
 
void SendLootAllPassed (Roll const &roll)
 
void SendLooter (Creature *creature, Player *pLooter)
 
void GroupLoot (Loot *loot, WorldObject *pLootedObject)
 
void NeedBeforeGreed (Loot *loot, WorldObject *pLootedObject)
 
void MasterLoot (Loot *loot, WorldObject *pLootedObject)
 
Rolls::iterator GetRoll (ObjectGuid Guid)
 
void CountTheRoll (Rolls::iterator roll)
 
bool CountRollVote (ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choise)
 
void EndRoll (Loot *loot)
 
void RemovePlayerFromRolls (ObjectGuid guid)
 
std::vector< Roll const * > GetRolls () const
 
void ResetMaxEnchantingLevel ()
 
void LinkMember (GroupReference *pRef)
 
void BroadcastGroupUpdate (void)
 
void AddLfgBuffFlag ()
 
void AddLfgRandomInstanceFlag ()
 
void AddLfgHeroicFlag ()
 
bool IsLfgWithBuff () const
 
bool IsLfgRandomInstance () const
 
bool IsLfgHeroic () const
 
uint32 GetDifficultyChangePreventionTime () const
 
DifficultyPreventionChangeType GetDifficultyChangePreventionReason () const
 
void SetDifficultyChangePrevention (DifficultyPreventionChangeType type)
 
void DoForAllMembers (std::function< void(Player *)> const &worker)
 

Public Attributes

DataMap CustomData
 

Protected Types

typedef MemberSlotList::iterator member_witerator
 
typedef std::set< Player * > InvitesList
 
typedef std::vector< Roll * > Rolls
 

Protected Member Functions

void _homebindIfInstance (Player *player)
 
void _cancelHomebindIfInstance (Player *player)
 
void _initRaidSubGroupsCounter ()
 
member_citerator _getMemberCSlot (ObjectGuid Guid) const
 
member_witerator _getMemberWSlot (ObjectGuid Guid)
 
void SubGroupCounterIncrease (uint8 subgroup)
 
void SubGroupCounterDecrease (uint8 subgroup)
 
void ToggleGroupMemberFlag (member_witerator slot, uint8 flag, bool apply)
 
void AddMemberWithGuid (ObjectGuid guid)
 
void ForcedDisband (bool hideDestroy=false)
 

Protected Attributes

MemberSlotList m_memberSlots
 
GroupRefMgr m_memberMgr
 
InvitesList m_invitees
 
ObjectGuid m_leaderGuid
 
std::string m_leaderName
 
GroupType m_groupType
 
Difficulty m_dungeonDifficulty
 
Difficulty m_raidDifficulty
 
Battlefield * m_bfGroup
 
Battleground * m_bgGroup
 
ObjectGuid m_targetIcons [TARGETICONCOUNT]
 
LootMethod m_lootMethod
 
ItemQualities m_lootThreshold
 
ObjectGuid m_looterGuid
 
ObjectGuid m_masterLooterGuid
 
Rolls RollId
 
uint8 * m_subGroupsCounts
 
ObjectGuid m_guid
 
uint32 m_counter
 
uint32 m_maxEnchantingLevel
 
uint8 m_lfgGroupFlags
 
uint32 _difficultyChangePreventionTime
 
DifficultyPreventionChangeType _difficultyChangePreventionType
 

Friends

class ToCloud9GroupHooks
 

Detailed Description

request member stats checken todo: uninvite people that not accepted invite

Member Typedef Documentation

◆ InvitesList

typedef std::set<Player*> Group::InvitesList
protected

◆ member_citerator

typedef MemberSlotList::const_iterator Group::member_citerator

◆ member_witerator

typedef MemberSlotList::iterator Group::member_witerator
protected

◆ MemberSlotList

typedef std::list<MemberSlot> Group::MemberSlotList

◆ Rolls

typedef std::vector<Roll*> Group::Rolls
protected

Constructor & Destructor Documentation

◆ Group()

Group::Group ( )
106{
107 sScriptMgr->OnConstructGroup(this);
108}
@ RAID_DIFFICULTY_10MAN_NORMAL
Definition DBCEnums.h:273
@ DUNGEON_DIFFICULTY_NORMAL
Definition DBCEnums.h:269
@ GROUPTYPE_NORMAL
Definition Group.h:87
@ DIFFICULTY_PREVENTION_CHANGE_NONE
Definition Group.h:141
@ FREE_FOR_ALL
Definition LootMgr.h:58
#define sScriptMgr
Definition ScriptMgr.h:766
@ ITEM_QUALITY_UNCOMMON
Definition SharedDefines.h:319
uint32 m_counter
Definition Group.h:374
Battlefield * m_bfGroup
Definition Group.h:364
uint32 m_maxEnchantingLevel
Definition Group.h:375
DifficultyPreventionChangeType _difficultyChangePreventionType
Definition Group.h:380
std::string m_leaderName
Definition Group.h:360
Battleground * m_bgGroup
Definition Group.h:365
Difficulty m_raidDifficulty
Definition Group.h:363
LootMethod m_lootMethod
Definition Group.h:367
uint8 * m_subGroupsCounts
Definition Group.h:372
Difficulty m_dungeonDifficulty
Definition Group.h:362
ItemQualities m_lootThreshold
Definition Group.h:368
GroupType m_groupType
Definition Group.h:361
uint32 _difficultyChangePreventionTime
Definition Group.h:379

References sScriptMgr.

◆ ~Group()

Group::~Group ( )
111{
112 sScriptMgr->OnDestructGroup(this);
113
114 if (m_bgGroup)
115 {
116 LOG_DEBUG("bg.battleground", "Group::~Group: battleground group being deleted.");
117
118 if (m_bgGroup->GetBgRaid(TEAM_ALLIANCE) == this)
119 {
121 }
122 else if (m_bgGroup->GetBgRaid(TEAM_HORDE) == this)
123 {
124 m_bgGroup->SetBgRaid(TEAM_HORDE, nullptr);
125 }
126 else
127 LOG_ERROR("bg.battleground", "Group::~Group: battleground group is not linked to the correct battleground.");
128 }
129
130 Rolls::iterator itr;
131 while (!RollId.empty())
132 {
133 itr = RollId.begin();
134 Roll* r = *itr;
135 RollId.erase(itr);
136 delete(r);
137 }
138
139 // Sub group counters clean up
140 delete[] m_subGroupsCounts;
141}
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
@ TEAM_ALLIANCE
Definition SharedDefines.h:748
@ TEAM_HORDE
Definition SharedDefines.h:749
Group * GetBgRaid(TeamId teamId) const
Definition Battleground.h:488
void SetBgRaid(TeamId teamId, Group *bg_raid)
Definition Battleground.cpp:1858
Rolls RollId
Definition Group.h:371
Definition Group.h:151

References Battleground::GetBgRaid(), LOG_DEBUG, LOG_ERROR, m_bgGroup, m_subGroupsCounts, RollId, Battleground::SetBgRaid(), sScriptMgr, TEAM_ALLIANCE, and TEAM_HORDE.

Member Function Documentation

◆ _cancelHomebindIfInstance()

void Group::_cancelHomebindIfInstance ( Player *  player)
protected
2409{
2410 // if player is reinvited to group and in the instance - cancel homebind timer
2411 if (!player->FindMap() || !player->FindMap()->IsDungeon())
2412 return;
2413 InstancePlayerBind* bind = sInstanceSaveMgr->PlayerGetBoundInstance(player->GetGUID(), player->FindMap()->GetId(), player->GetDifficulty(player->FindMap()->IsRaid()));
2414 if (bind && bind->save->GetInstanceId() == player->GetInstanceId())
2415 player->m_InstanceValid = true;
2416}
#define sInstanceSaveMgr
Definition InstanceSaveMgr.h:233
uint32 GetInstanceId() const
Definition InstanceSaveMgr.h:62
bool IsDungeon() const
Definition Map.h:299
bool IsRaid() const
Definition Map.h:301
uint32 GetId() const
Definition Map.h:234
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:120
bool m_InstanceValid
Definition Player.h:2485
Difficulty GetDifficulty(bool isRaid) const
Definition Player.h:1948
Map * FindMap() const
Definition Object.h:638
uint32 GetInstanceId() const
Definition Object.h:520
Definition InstanceSaveMgr.h:40
InstanceSave * save
Definition InstanceSaveMgr.h:41

References WorldObject::FindMap(), Player::GetDifficulty(), Object::GetGUID(), Map::GetId(), WorldObject::GetInstanceId(), InstanceSave::GetInstanceId(), Map::IsDungeon(), Map::IsRaid(), Player::m_InstanceValid, InstancePlayerBind::save, and sInstanceSaveMgr.

Referenced by AddMember().

◆ _getMemberCSlot()

Group::member_citerator Group::_getMemberCSlot ( ObjectGuid  Guid) const
protected
2709{
2710 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2711 if (itr->guid == Guid)
2712 return itr;
2713 return m_memberSlots.end();
2714}
MemberSlotList m_memberSlots
Definition Group.h:356
MemberSlotList::const_iterator member_citerator
Definition Group.h:189

References m_memberSlots.

Referenced by GetMemberGroup(), IsAssistant(), IsMember(), SameSubGroup(), SameSubGroup(), and UpdateLooterGuid().

◆ _getMemberWSlot()

Group::member_witerator Group::_getMemberWSlot ( ObjectGuid  Guid)
protected
2717{
2718 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2719 if (itr->guid == Guid)
2720 return itr;
2721 return m_memberSlots.end();
2722}
MemberSlotList::iterator member_witerator
Definition Group.h:192

References m_memberSlots.

Referenced by ChangeLeader(), ChangeMembersGroup(), RemoveMember(), SendUpdateToPlayer(), SetGroupMemberFlag(), and SetLfgRoles().

◆ _homebindIfInstance()

void Group::_homebindIfInstance ( Player *  player)
protected
2403{
2404 if (player && !player->IsGameMaster() && player->FindMap() && sMapStore.LookupEntry(player->GetMapId())->IsDungeon())
2405 player->m_InstanceValid = false;
2406}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
bool IsGameMaster() const
Definition Player.h:1178
uint32 GetMapId() const
Definition Position.h:281

References WorldObject::FindMap(), WorldLocation::GetMapId(), Map::IsDungeon(), Player::IsGameMaster(), Player::m_InstanceValid, and sMapStore.

Referenced by ForcedDisband(), and RemoveMember().

◆ _initRaidSubGroupsCounter()

void Group::_initRaidSubGroupsCounter ( )
protected
2697{
2698 // Sub group counters initialization
2699 if (!m_subGroupsCounts)
2701
2702 memset((void*)m_subGroupsCounts, 0, (MAX_RAID_SUBGROUPS)*sizeof(uint8));
2703
2704 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2705 ++m_subGroupsCounts[itr->group];
2706}
std::uint8_t uint8
Definition Define.h:109
#define MAX_RAID_SUBGROUPS
Definition Group.h:46

References m_memberSlots, m_subGroupsCounts, and MAX_RAID_SUBGROUPS.

Referenced by ConvertToRaid(), Create(), LoadGroupFromDB(), and ToCloud9GroupHooks::OnGroupCreated().

◆ AddInvite()

bool Group::AddInvite ( Player *  player)
356{
357 if (!player || player->GetGroupInvite())
358 return false;
359 Group* group = player->GetGroup();
360 if (group && (group->isBGGroup() || group->isBFGroup()))
361 group = player->GetOriginalGroup();
362 if (group)
363 return false;
364
365 RemoveInvite(player);
366
367 m_invitees.insert(player);
368
369 player->SetGroupInvite(this);
370
371 sScriptMgr->OnGroupInviteMember(this, player->GetGUID());
372
373 return true;
374}
Definition Group.h:177
InvitesList m_invitees
Definition Group.h:358
void RemoveInvite(Player *player)
Definition Group.cpp:386
bool isBGGroup() const
Definition Group.cpp:2495
bool isBFGroup() const
Definition Group.cpp:2500
void SetGroupInvite(Group *group)
Definition Player.h:2516
Group * GetGroup()
Definition Player.h:2517
Group * GetGroupInvite()
Definition Player.h:2515
Group * GetOriginalGroup()
Definition Player.h:2532

References Player::GetGroup(), Player::GetGroupInvite(), Object::GetGUID(), Player::GetOriginalGroup(), isBFGroup(), isBGGroup(), m_invitees, RemoveInvite(), Player::SetGroupInvite(), and sScriptMgr.

Referenced by AddLeaderInvite(), and WorldSession::HandleGroupInviteOpcode().

◆ AddLeaderInvite()

bool Group::AddLeaderInvite ( Player *  player)
377{
378 if (!AddInvite(player))
379 return false;
380
381 m_leaderGuid = player->GetGUID();
382 m_leaderName = player->GetName();
383 return true;
384}
ObjectGuid m_leaderGuid
Definition Group.h:359
bool AddInvite(Player *player)
Definition Group.cpp:355
std::string const & GetName() const
Definition Object.h:535

References AddInvite(), Object::GetGUID(), WorldObject::GetName(), m_leaderGuid, and m_leaderName.

Referenced by WorldSession::HandleGroupInviteOpcode().

◆ AddLfgBuffFlag()

void Group::AddLfgBuffFlag ( )
inline
@ GROUP_LFG_FLAG_APPLY_RANDOM_BUFF
Definition Group.h:127
uint8 m_lfgGroupFlags
Definition Group.h:376

References GROUP_LFG_FLAG_APPLY_RANDOM_BUFF, and m_lfgGroupFlags.

Referenced by lfg::LFGMgr::MakeNewGroup().

◆ AddLfgHeroicFlag()

void Group::AddLfgHeroicFlag ( )
inline
@ GROUP_LFG_FLAG_IS_HEROIC
Definition Group.h:129

References GROUP_LFG_FLAG_IS_HEROIC, and m_lfgGroupFlags.

Referenced by lfg::LFGMgr::MakeNewGroup().

◆ AddLfgRandomInstanceFlag()

void Group::AddLfgRandomInstanceFlag ( )
inline
@ GROUP_LFG_FLAG_IS_RANDOM_INSTANCE
Definition Group.h:128

References GROUP_LFG_FLAG_IS_RANDOM_INSTANCE, and m_lfgGroupFlags.

Referenced by lfg::LFGMgr::MakeNewGroup().

◆ AddMember()

bool Group::AddMember ( Player *  player,
uint8  roles = 0 
)
428{
429 if (!player)
430 return false;
431
432 // Get first not-full group
433 uint8 subGroup = 0;
435 {
436 bool groupFound = false;
437 for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup)
438 {
439 if (m_subGroupsCounts[subGroup] < MAXGROUPSIZE)
440 {
441 groupFound = true;
442 break;
443 }
444 }
445 // We are raid group and no one slot is free
446 if (!groupFound)
447 return false;
448 }
449
450 MemberSlot member;
451 member.guid = player->GetGUID();
452 member.name = player->GetName();
453 member.group = subGroup;
454 member.flags = 0;
455 member.roles = roles;
456 m_memberSlots.push_back(member);
457
458 if (!isBGGroup() && !isBFGroup())
459 {
460 sCharacterCache->UpdateCharacterGroup(player->GetGUID(), GetGUID());
461 }
462
463 SubGroupCounterIncrease(subGroup);
464
465 player->SetGroupInvite(nullptr);
466 if (player->GetGroup())
467 {
468 if (isBGGroup() || isBFGroup()) // if player is in group and he is being added to BG raid group, then call SetBattlegroundRaid()
469 player->SetBattlegroundOrBattlefieldRaid(this, subGroup);
470 else //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
471 player->SetOriginalGroup(this, subGroup);
472 }
473 else //if player is not in group, then call set group
474 player->SetGroup(this, subGroup);
475
476 // if the same group invites the player back, cancel the homebind timer
478
479 if (!isRaidGroup()) // reset targetIcons for non-raid-groups
480 {
481 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
482 m_targetIcons[i].Clear();
483 }
484
485 if (!isBGGroup() && !isBFGroup())
486 {
488 stmt->SetData(0, GetGUID().GetCounter());
489 stmt->SetData(1, member.guid.GetCounter());
490 stmt->SetData(2, member.flags);
491 stmt->SetData(3, member.group);
492 stmt->SetData(4, member.roles);
493 CharacterDatabase.Execute(stmt);
494 }
495
496 SendUpdate();
497
498 if (player)
499 {
500 sScriptMgr->OnGroupAddMember(this, player->GetGUID());
501
502 if (!IsLeader(player->GetGUID()) && !isBGGroup() && !isBFGroup())
503 {
505
507 {
509 player->SendDungeonDifficulty(true);
510 }
511 if (player->GetRaidDifficulty() != GetRaidDifficulty())
512 {
514 player->SendRaidDifficulty(true);
515 }
516 }
517 else if (IsLeader(player->GetGUID()) && isLFGGroup()) // pussywizard
518 {
520 }
521
524
525 // quest related GO state dependent from raid membership
526 if (isRaidGroup())
528
529 {
530 // Broadcast new player group member fields to rest of the group
532
533 UpdateData groupData;
534 WorldPacket groupDataPacket;
535
536 // Broadcast group members' fields to player
537 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
538 {
539 if (itr->GetSource() == player) // pussywizard: no check same map, adding members is single threaded
540 {
541 continue;
542 }
543
544 if (Player* itrMember = itr->GetSource())
545 {
546 if (player->HaveAtClient(itrMember))
547 {
548 itrMember->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
549 itrMember->BuildValuesUpdateBlockForPlayer(&groupData, player);
550 itrMember->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
551 }
552
553 if (itrMember->HaveAtClient(player))
554 {
555 UpdateData newData;
556 WorldPacket newDataPacket;
557 player->BuildValuesUpdateBlockForPlayer(&newData, itrMember);
558 if (newData.HasData())
559 {
560 newData.BuildPacket(newDataPacket);
561 itrMember->SendDirectMessage(&newDataPacket);
562 }
563 }
564 }
565 }
566
567 if (groupData.HasData())
568 {
569 groupData.BuildPacket(groupDataPacket);
570 player->SendDirectMessage(&groupDataPacket);
571 }
572
574 }
575
576 if (m_maxEnchantingLevel < player->GetSkillValue(SKILL_ENCHANTING))
578 }
579
580 return true;
581}
#define sCharacterCache
Definition CharacterCache.h:88
@ CHAR_REP_GROUP_MEMBER
Definition CharacterDatabase.h:287
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition DatabaseEnv.cpp:21
#define TARGETICONCOUNT
Definition Group.h:47
#define MAXGROUPSIZE
Definition Group.h:44
@ GROUP_UPDATE_FULL
Definition Group.h:122
@ INSTANCE_RESET_GROUP_JOIN
Definition Map.h:719
@ SKILL_ENCHANTING
Definition SharedDefines.h:3187
@ UF_FLAG_PARTY_MEMBER
Definition UpdateFieldFlags.h:33
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
bool isLFGGroup(bool restricted=false) const
Definition Group.cpp:2484
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:2560
void SendUpdate()
Definition Group.cpp:1871
ObjectGuid GetGUID() const
Definition Group.cpp:2525
void _cancelHomebindIfInstance(Player *player)
Definition Group.cpp:2408
Difficulty GetRaidDifficulty() const
Definition Group.cpp:2672
ObjectGuid m_targetIcons[TARGETICONCOUNT]
Definition Group.h:366
void UpdatePlayerOutOfRange(Player *player)
Definition Group.cpp:1953
GroupReference * GetFirstMember()
Definition Group.h:252
void SubGroupCounterIncrease(uint8 subgroup)
Definition Group.cpp:2724
Difficulty GetDungeonDifficulty() const
Definition Group.cpp:2667
bool isRaidGroup() const
Definition Group.cpp:2490
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target)
Definition Object.cpp:255
void RemoveFieldNotifyFlag(uint16 flag)
Definition Object.h:202
void SetFieldNotifyFlag(uint16 flag)
Definition Object.h:201
Definition Player.h:1086
Difficulty GetRaidDifficulty() const
Definition Player.h:1950
void SetOriginalGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:13441
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2523
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5864
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5622
void SetDungeonDifficulty(Difficulty dungeon_difficulty)
Definition Player.h:1952
void SetGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:11748
bool HaveAtClient(WorldObject const *u) const
Definition Player.cpp:11595
void UpdateForQuestWorldObjects()
Definition PlayerUpdates.cpp:1818
void SetRaidDifficulty(Difficulty raid_difficulty)
Definition Player.h:1953
void SendDungeonDifficulty(bool IsInGroup)
Definition PlayerMisc.cpp:169
static void ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
Reset all solo instances and optionally send a message on success for each.
Definition PlayerMisc.cpp:193
Difficulty GetDungeonDifficulty() const
Definition Player.h:1949
void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty=-1)
Definition PlayerMisc.cpp:177
void SetBattlegroundOrBattlefieldRaid(Group *group, int8 subgroup=-1)
Definition Player.cpp:13413
Acore::Types::is_default< T > SetData(const uint8 index, T value)
Definition PreparedStatement.h:77
Definition PreparedStatement.h:157
Definition UpdateData.h:52
bool HasData() const
Definition UpdateData.h:60
bool BuildPacket(WorldPacket &packet)
Definition UpdateData.cpp:48
Definition WorldPacket.h:26

References _cancelHomebindIfInstance(), UpdateData::BuildPacket(), Object::BuildValuesUpdateBlockForPlayer(), CHAR_REP_GROUP_MEMBER, CharacterDatabase, Group::MemberSlot::flags, ObjectGuid::GetCounter(), Player::GetDungeonDifficulty(), GetDungeonDifficulty(), GetFirstMember(), Player::GetGroup(), GetGUID(), Object::GetGUID(), WorldObject::GetName(), Player::GetRaidDifficulty(), GetRaidDifficulty(), Player::GetSkillValue(), Group::MemberSlot::group, GROUP_UPDATE_FULL, Group::MemberSlot::guid, UpdateData::HasData(), Player::HaveAtClient(), INSTANCE_RESET_GROUP_JOIN, isBFGroup(), isBGGroup(), IsLeader(), isLFGGroup(), isRaidGroup(), m_maxEnchantingLevel, m_memberSlots, m_subGroupsCounts, m_targetIcons, MAX_RAID_SUBGROUPS, MAXGROUPSIZE, Group::MemberSlot::name, GroupReference::next(), Object::RemoveFieldNotifyFlag(), Player::ResetInstances(), Group::MemberSlot::roles, sCharacterCache, Player::SendDirectMessage(), Player::SendDungeonDifficulty(), Player::SendRaidDifficulty(), SendUpdate(), Player::SetBattlegroundOrBattlefieldRaid(), PreparedStatementBase::SetData(), Player::SetDungeonDifficulty(), Object::SetFieldNotifyFlag(), Player::SetGroup(), Player::SetGroupInvite(), Player::SetGroupUpdateFlag(), Player::SetOriginalGroup(), Player::SetRaidDifficulty(), SKILL_ENCHANTING, sScriptMgr, SubGroupCounterIncrease(), TARGETICONCOUNT, UF_FLAG_PARTY_MEMBER, Player::UpdateForQuestWorldObjects(), and UpdatePlayerOutOfRange().

Referenced by AddMemberWithGuid(), Battlefield::AddOrSetPlayerToCorrectBfGroup(), Battleground::AddOrSetPlayerToCorrectBgGroup(), Arena::AddPlayer(), Create(), group_commandscript::HandleGroupJoinCommand(), and lfg::LFGMgr::MakeNewGroup().

◆ AddMemberWithGuid()

void Group::AddMemberWithGuid ( ObjectGuid  guid)
protected
584{
585 // Idempotent under sidecar event redelivery: never duplicate a MemberSlot.
586 if (IsMember(guid))
587 return;
588
589 if (Player* player = ObjectAccessor::FindPlayer(guid))
590 {
591 AddMember(player);
592 return;
593 }
594
595 // Get first not-full group
596 uint8 subGroup = 0;
598 {
599 bool groupFound = false;
600 for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup)
601 {
602 if (m_subGroupsCounts[subGroup] < MAXGROUPSIZE)
603 {
604 groupFound = true;
605 break;
606 }
607 }
608 // We are raid group and no one slot is free
609 if (!groupFound)
610 return;
611 }
612
613 MemberSlot member;
614 member.guid = guid;
615 sCharacterCache->GetCharacterNameByGuid(guid, member.name);
616 member.group = subGroup;
617 member.flags = 0;
618 member.roles = 0;
619 m_memberSlots.push_back(member);
620
621 if (!isBGGroup() && !isBFGroup())
622 {
623 sCharacterCache->UpdateCharacterGroup(guid, GetGUID());
624 }
625
626 SubGroupCounterIncrease(subGroup);
627}
bool AddMember(Player *player, uint8 roles=0)
Definition Group.cpp:427
bool IsMember(ObjectGuid guid) const
Definition Group.cpp:2555
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:269

References AddMember(), ObjectAccessor::FindPlayer(), Group::MemberSlot::flags, GetGUID(), Group::MemberSlot::group, Group::MemberSlot::guid, isBFGroup(), isBGGroup(), IsMember(), m_memberSlots, m_subGroupsCounts, MAX_RAID_SUBGROUPS, MAXGROUPSIZE, Group::MemberSlot::name, Group::MemberSlot::roles, sCharacterCache, and SubGroupCounterIncrease().

Referenced by ToCloud9GroupHooks::OnGroupCreated().

◆ BroadcastGroupUpdate()

void Group::BroadcastGroupUpdate ( void  )
2419{
2420 // FG: HACK: force flags update on group leave - for values update hack
2421 // -- not very efficient but safe
2422 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
2423 {
2424 Player* pp = ObjectAccessor::FindPlayer(citr->guid);
2425 if (pp)
2426 {
2429 LOG_DEBUG("group", "-- Forced group value update for '{}'", pp->GetName());
2430 }
2431 }
2432}
@ UNIT_FIELD_FACTIONTEMPLATE
Definition UpdateFields.h:115
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void ForceValuesUpdateAtIndex(uint32)
Definition Object.cpp:2158

References ObjectAccessor::FindPlayer(), Object::ForceValuesUpdateAtIndex(), WorldObject::GetName(), LOG_DEBUG, m_memberSlots, UNIT_FIELD_BYTES_2, and UNIT_FIELD_FACTIONTEMPLATE.

Referenced by group_commandscript::HandleGroupJoinCommand(), and RemoveMember().

◆ BroadcastPacket()

void Group::BroadcastPacket ( WorldPacket const *  packet,
bool  ignorePlayersInBGRaid,
int  group = -1,
ObjectGuid  ignore = ObjectGuid::Empty 
)
1970{
1971 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1972 {
1973 Player* player = itr->GetSource();
1974 if (!player || (ignore && player->GetGUID() == ignore) || (ignorePlayersInBGRaid && player->GetGroup() != this))
1975 continue;
1976
1977 if (group == -1 || itr->getSubGroup() == group)
1978 player->SendDirectMessage(packet);
1979 }
1980}

References GetFirstMember(), Player::GetGroup(), Object::GetGUID(), GroupReference::next(), and Player::SendDirectMessage().

Referenced by ChangeLeader(), DoMinimapPing(), WorldSession::HandleMessagechatOpcode(), WorldSession::HandleRaidReadyCheckFinishedOpcode(), WorldSession::HandleRaidReadyCheckOpcode(), Unit::Kill(), SendLooter(), Player::SendNewItem(), and SetTargetIcon().

◆ BroadcastReadyCheck()

void Group::BroadcastReadyCheck ( WorldPacket const *  packet)
1983{
1984 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1985 {
1986 Player* player = itr->GetSource();
1987 if (player)
1988 if (IsLeader(player->GetGUID()) || IsAssistant(player->GetGUID()))
1989 player->SendDirectMessage(packet);
1990 }
1991}
bool IsAssistant(ObjectGuid guid) const
Definition Group.cpp:2574

References GetFirstMember(), Object::GetGUID(), IsAssistant(), IsLeader(), GroupReference::next(), and Player::SendDirectMessage().

Referenced by WorldSession::HandleRaidReadyCheckOpcode(), and OfflineReadyCheck().

◆ CanJoinBattlegroundQueue()

GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue ( Battleground const *  bgTemplate,
BattlegroundQueueTypeId  bgQueueTypeId,
uint32  MinPlayerCount,
uint32  MaxPlayerCount,
bool  isRated,
uint32  arenaSlot 
)
2143{
2144 // check if this group is LFG group
2145 if (isLFGGroup())
2147
2148 BattlemasterListEntry const* bgEntry = sBattlemasterListStore.LookupEntry(bgTemplate->GetBgTypeID());
2149 if (!bgEntry)
2151
2152 // too many players in the group
2153 if (GetMembersCount() > bgEntry->maxGroupSize)
2154 return ERR_BATTLEGROUND_NONE;
2155
2156 // get a player as reference, to compare other players' stats to (arena team id, level bracket, etc.)
2157 Player* reference = GetFirstMember()->GetSource();
2158 if (!reference)
2160
2161 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgTemplate->GetMapId(), reference->GetLevel());
2162 if (!bracketEntry)
2164
2165 uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
2166 TeamId teamId = reference->GetTeamId();
2167
2169
2170 // check every member of the group to be able to join
2171 uint32 memberscount = 0;
2172 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount)
2173 {
2174 Player* member = itr->GetSource();
2175
2176 // don't let join with offline members
2177 if (!member)
2179
2180 if (!sScriptMgr->CanGroupJoinBattlegroundQueue(this, member, bgTemplate, MinPlayerCount, isRated, arenaSlot))
2182
2183 // don't allow cross-faction groups to join queue
2184 if (member->GetTeamId() != teamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
2186
2187 // don't let join rated matches if the arena team id doesn't match
2188 if (isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)
2190
2191 // not in the same battleground level braket, don't let join
2192 PvPDifficultyEntry const* memberBracketEntry = GetBattlegroundBracketByLevel(bracketEntry->mapId, member->GetLevel());
2193 if (memberBracketEntry != bracketEntry)
2195
2196 // check for deserter debuff in case not arena queue
2197 if (bgTemplate->GetBgTypeID() != BATTLEGROUND_AA && !member->CanJoinToBattleground(bgTemplate))
2199
2200 // check if someone in party is using dungeon system
2201 lfg::LfgState lfgState = sLFGMgr->GetState(member->GetGUID());
2202 if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG)))
2204
2205 // pussywizard: prevent joining when any member is in bg/arena
2206 if (member->InBattleground())
2208
2209 // pussywizard: check for free slot, this is actually ensured before calling this function, but just in case
2210 if (!member->HasFreeBattlegroundQueueId())
2212
2213 // don't let join if someone from the group is already in that bg queue
2214 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
2216
2217 // don't let join if someone from the group is in bg queue random
2218 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom))
2219 return ERR_IN_RANDOM_BG;
2220
2221 // don't let join to bg queue random if someone from the group is already in bg queue
2222 if (bgTemplate->GetBgTypeID() == BATTLEGROUND_RB && member->InBattlegroundQueue())
2223 return ERR_IN_NON_RANDOM_BG;
2224
2225 // don't let Death Knights join BG queues when they are not allowed to be teleported yet
2226 if (member->IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_TELEPORT) && member->GetMapId() == MAP_EBON_HOLD && !member->IsGameMaster() && !member->HasSpell(50977))
2228
2229 if (!member->GetBGAccessByLevel(bgTemplate->GetBgTypeID()))
2231
2232 if (member->HasPlayerFlag(PLAYER_FLAGS_NO_PLAY_TIME)) // Assumed to only apply to full restriction rather than partial
2233 return ERR_GROUP_JOIN_BATTLEGROUND_FAIL; // ERR_ARENA_EXPIRED_CAIS does not seem to be a result, so using this error instead
2234 }
2235
2236 // for arenas: check party size is proper
2237 if (bgTemplate->isArena() && memberscount != MinPlayerCount)
2239
2240 //check against other arena team members
2241 if (isRated)
2242 {
2243 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
2244 for (auto const& itr : arenaTeam->GetMembers())
2245 {
2246 Player* teamMember = ObjectAccessor::FindConnectedPlayer(itr.Guid);
2247 //are they online and not a member of this current group?
2248 if (teamMember && !IsMember(teamMember->GetGUID()))
2249 {
2250 //are they already in queue for a rated arena?
2251 if (teamMember->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
2252 {
2253 GroupQueueInfo ginfo;
2254 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
2255 if (queue.GetPlayerGroupInfoData(teamMember->GetGUID(), &ginfo))
2256 {
2257 if (ginfo.IsRated)
2259 }
2260 }
2261 //are they currently in an arena match?
2262 Battleground* bg = teamMember->GetBattleground(false);
2263 if (bg && bg->isRated() && bg->GetMinPlayersPerTeam() == MinPlayerCount)
2265 }
2266 }
2267 }
2268
2269 return GroupJoinBattlegroundResult(bgTemplate->GetBgTypeID());
2270}
@ MAP_EBON_HOLD
Definition AreaDefines.h:262
#define sArenaTeamMgr
Definition ArenaTeamMgr.h:69
#define sBattlegroundMgr
Definition BattlegroundMgr.h:190
DBCStorage< BattlemasterListEntry > sBattlemasterListStore(BattlemasterListEntryfmt)
PvPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
Definition DBCStores.cpp:805
std::uint32_t uint32
Definition Define.h:107
#define sLFGMgr
Definition LFGMgr.h:665
@ PLAYER_FLAGS_NO_PLAY_TIME
Definition Player.h:472
GroupJoinBattlegroundResult
Definition SharedDefines.h:3891
@ ERR_BATTLEGROUND_JOIN_TIMED_OUT
Definition SharedDefines.h:3904
@ ERR_BATTLEGROUND_JOIN_FAILED
Definition SharedDefines.h:3905
@ ERR_LFG_CANT_USE_BATTLEGROUND
Definition SharedDefines.h:3906
@ ERR_IN_NON_RANDOM_BG
Definition SharedDefines.h:3908
@ ERR_BATTLEGROUND_NONE
Definition SharedDefines.h:3894
@ ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS
Definition SharedDefines.h:3895
@ ERR_ARENA_TEAM_PARTY_SIZE
Definition SharedDefines.h:3896
@ ERR_BATTLEGROUND_TOO_MANY_QUEUES
Definition SharedDefines.h:3897
@ ERR_GROUP_JOIN_BATTLEGROUND_FAIL
Definition SharedDefines.h:3893
@ ERR_BATTLEGROUND_JOIN_RANGE_INDEX
Definition SharedDefines.h:3903
@ ERR_IN_RANDOM_BG
Definition SharedDefines.h:3907
@ CLASS_DEATH_KNIGHT
Definition SharedDefines.h:131
@ BATTLEGROUND_AA
Definition SharedDefines.h:3742
@ BATTLEGROUND_RB
Definition SharedDefines.h:3749
BattlegroundQueueTypeId
Definition SharedDefines.h:3875
TeamId
Definition SharedDefines.h:747
@ CLASS_CONTEXT_TELEPORT
Definition UnitDefines.h:235
@ CONFIG_ALLOW_JOIN_BG_AND_LFG
Definition WorldConfig.h:132
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition WorldConfig.h:35
Definition ArenaTeam.h:137
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
Definition BattlegroundMgr.cpp:685
Definition BattlegroundQueue.h:68
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo *ginfo)
Definition BattlegroundQueue.cpp:400
Definition Battleground.h:304
uint32 GetMinPlayersPerTeam() const
Definition Battleground.cpp:248
bool isRated() const
Definition Battleground.h:415
uint32 GetMembersCount() const
Definition Group.h:254
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12510
bool InBattleground() const
Definition Player.h:2299
TeamId GetTeamId(bool original=false) const
Definition Player.h:2139
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12461
bool InBattlegroundQueue(bool ignoreArena=false) const
Definition Player.cpp:12476
uint32 GetArenaTeamId(uint8 slot) const
Definition Player.cpp:16589
bool HasFreeBattlegroundQueueId() const
Definition Player.cpp:12530
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1350
bool CanJoinToBattleground(Battleground const *bg) const
Definition Player.cpp:11538
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4051
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1125
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition Player.cpp:12589
FROM * GetSource() const
Definition Reference.h:97
uint8 GetLevel() const
Definition Unit.h:1109
#define sWorld
Definition World.h:318
Player * FindConnectedPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:281
LfgState
Definition LFG.h:67
@ LFG_STATE_NONE
Definition LFG.h:68
@ LFG_STATE_QUEUED
Definition LFG.h:70
Definition DBCStructure.h:604
uint32 maxGroupSize
Definition DBCStructure.h:611
Definition BattlegroundQueue.h:35
bool IsRated
Definition BattlegroundQueue.h:40
Definition DBCStructure.h:1467
uint32 mapId
Definition DBCStructure.h:1469

References BATTLEGROUND_AA, BATTLEGROUND_RB, BattlegroundMgr::BGQueueTypeId(), Player::CanJoinToBattleground(), CLASS_CONTEXT_TELEPORT, CLASS_DEATH_KNIGHT, CONFIG_ALLOW_JOIN_BG_AND_LFG, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, ERR_ARENA_TEAM_PARTY_SIZE, ERR_BATTLEGROUND_JOIN_FAILED, ERR_BATTLEGROUND_JOIN_RANGE_INDEX, ERR_BATTLEGROUND_JOIN_TIMED_OUT, ERR_BATTLEGROUND_NONE, ERR_BATTLEGROUND_TOO_MANY_QUEUES, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS, ERR_GROUP_JOIN_BATTLEGROUND_FAIL, ERR_IN_NON_RANDOM_BG, ERR_IN_RANDOM_BG, ERR_LFG_CANT_USE_BATTLEGROUND, ObjectAccessor::FindConnectedPlayer(), Player::GetArenaTeamId(), Player::GetBattleground(), GetBattlegroundBracketByLevel(), Player::GetBGAccessByLevel(), Battleground::GetBgTypeID(), GetFirstMember(), Object::GetGUID(), Unit::GetLevel(), Battleground::GetMapId(), WorldLocation::GetMapId(), ArenaTeam::GetMembers(), GetMembersCount(), Battleground::GetMinPlayersPerTeam(), BattlegroundQueue::GetPlayerGroupInfoData(), Reference< TO, FROM >::GetSource(), Player::GetTeamId(), Player::HasFreeBattlegroundQueueId(), Player::HasPlayerFlag(), Player::HasSpell(), Player::InBattleground(), Player::InBattlegroundQueue(), Player::InBattlegroundQueueForBattlegroundQueueType(), Battleground::isArena(), Player::IsClass(), Player::IsGameMaster(), isLFGGroup(), IsMember(), Battleground::isRated(), GroupQueueInfo::IsRated, lfg::LFG_STATE_NONE, lfg::LFG_STATE_QUEUED, MAP_EBON_HOLD, PvPDifficultyEntry::mapId, BattlemasterListEntry::maxGroupSize, GroupReference::next(), PLAYER_FLAGS_NO_PLAY_TIME, sArenaTeamMgr, sBattlegroundMgr, sBattlemasterListStore, sLFGMgr, sScriptMgr, and sWorld.

Referenced by WorldSession::HandleBattlemasterJoinArena(), and WorldSession::HandleBattlemasterJoinOpcode().

◆ ChangeLeader()

void Group::ChangeLeader ( ObjectGuid  guid)
779{
780 member_witerator slot = _getMemberWSlot(newLeaderGuid);
781
782 if (slot == m_memberSlots.end())
783 return;
784
785 Player* newLeader = ObjectAccessor::FindConnectedPlayer(slot->guid);
786
787 // Don't allow switching leader to offline players
788 if (!newLeader)
789 return;
790
791 if (!isBGGroup() && !isBFGroup())
792 {
793 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
794 // Update the group leader
796 stmt->SetData(0, newLeader->GetGUID().GetCounter());
797 stmt->SetData(1, GetGUID().GetCounter());
798 trans->Append(stmt);
799 CharacterDatabase.CommitTransaction(trans);
800
801 sInstanceSaveMgr->CopyBinds(m_leaderGuid, newLeaderGuid, newLeader);
802 }
803
805 oldLeader->RemovePlayerFlag(PLAYER_FLAGS_GROUP_LEADER);
806
808 m_leaderGuid = newLeader->GetGUID();
809 m_leaderName = newLeader->GetName();
811
813 data << slot->name;
814 BroadcastPacket(&data, true);
815
816 sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid); // This hook should be executed at the end - Not used anywhere in the original core
817}
@ CHAR_UPD_GROUP_LEADER
Definition CharacterDatabase.h:289
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition DatabaseEnvFwd.h:69
@ MEMBER_FLAG_ASSISTANT
Definition Group.h:74
@ PLAYER_FLAGS_GROUP_LEADER
Definition Player.h:459
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty)
Definition Group.cpp:1969
void ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply)
Definition Group.cpp:2743
member_witerator _getMemberWSlot(ObjectGuid Guid)
Definition Group.cpp:2716
LowType GetCounter() const
Definition ObjectGuid.h:149
void SetPlayerFlag(PlayerFlags flags)
Definition Player.h:1126
@ SMSG_GROUP_SET_LEADER
Definition Opcodes.h:151

References _getMemberWSlot(), BroadcastPacket(), CHAR_UPD_GROUP_LEADER, CharacterDatabase, ObjectAccessor::FindConnectedPlayer(), ObjectGuid::GetCounter(), GetGUID(), Object::GetGUID(), WorldObject::GetName(), isBFGroup(), isBGGroup(), m_leaderGuid, m_leaderName, m_memberSlots, MEMBER_FLAG_ASSISTANT, PLAYER_FLAGS_GROUP_LEADER, PreparedStatementBase::SetData(), Player::SetPlayerFlag(), sInstanceSaveMgr, SMSG_GROUP_SET_LEADER, sScriptMgr, and ToggleGroupMemberFlag().

Referenced by Battleground::AddOrSetPlayerToCorrectBgGroup(), group_commandscript::HandleGroupLeaderCommand(), WorldSession::HandleGroupSetLeaderOpcode(), and RemoveMember().

◆ ChangeMembersGroup()

void Group::ChangeMembersGroup ( ObjectGuid  guid,
uint8  group 
)
2021{
2022 // Only raid groups have sub groups
2023 if (!isRaidGroup())
2024 return;
2025
2026 // Check if player is really in the raid
2027 member_witerator slot = _getMemberWSlot(guid);
2028 if (slot == m_memberSlots.end())
2029 return;
2030
2031 // Abort if the player is already in the target sub group
2032 uint8 prevSubGroup = GetMemberGroup(guid);
2033 if (prevSubGroup == group)
2034 return;
2035
2036 // Update the player slot with the new sub group setting
2037 slot->group = group;
2038
2039 // Increase the counter of the new sub group..
2041
2042 // ..and decrease the counter of the previous one
2043 SubGroupCounterDecrease(prevSubGroup);
2044
2045 // Preserve new sub group in database for non-raid groups
2046 if (!isBGGroup() && !isBFGroup())
2047 {
2049
2050 stmt->SetData(0, group);
2051 stmt->SetData(1, guid.GetCounter());
2052
2053 CharacterDatabase.Execute(stmt);
2054 }
2055
2056 // In case the moved player is online, update the player object with the new sub group references
2057 if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
2058 {
2059 if (player->GetGroup() == this)
2060 player->GetGroupRef().setSubGroup(group);
2061 else // If player is in BG raid, it is possible that he is also in normal raid - and that normal raid is stored in m_originalGroup reference
2062 player->GetOriginalGroupRef().setSubGroup(group);
2063 }
2064
2065 // Broadcast the changes to the group
2066 SendUpdate();
2067}
@ CHAR_UPD_GROUP_MEMBER_SUBGROUP
Definition CharacterDatabase.h:291
uint8 GetMemberGroup(ObjectGuid guid) const
Definition Group.cpp:2603
void SubGroupCounterDecrease(uint8 subgroup)
Definition Group.cpp:2730

References _getMemberWSlot(), CHAR_UPD_GROUP_MEMBER_SUBGROUP, CharacterDatabase, ObjectAccessor::FindConnectedPlayer(), ObjectGuid::GetCounter(), GetMemberGroup(), isBFGroup(), isBGGroup(), isRaidGroup(), m_memberSlots, SendUpdate(), PreparedStatementBase::SetData(), SubGroupCounterDecrease(), and SubGroupCounterIncrease().

Referenced by WorldSession::HandleGroupChangeSubGroupOpcode(), and WorldSession::HandleGroupSwapSubGroupOpcode().

◆ CheckLevelForRaid()

bool Group::CheckLevelForRaid ( )
318{
319 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
320 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
321 if (player->GetLevel() < sConfigMgr->GetOption<int32>("Group.Raid.LevelRestriction", 10))
322 return true;
323
324 return false;
325}
std::int32_t int32
Definition Define.h:103
#define sConfigMgr
Definition Config.h:93

References ObjectAccessor::FindPlayer(), m_memberSlots, and sConfigMgr.

Referenced by WorldSession::HandleGroupRaidConvertOpcode().

◆ ConvertToLFG()

void Group::ConvertToLFG ( bool  restricted = true)
296{
298 if (restricted)
299 {
302 }
303
304 if (!isBGGroup() && !isBFGroup())
305 {
307
308 stmt->SetData(0, uint8(m_groupType));
309 stmt->SetData(1, GetGUID().GetCounter());
310
311 CharacterDatabase.Execute(stmt);
312 }
313
314 SendUpdate();
315}
@ CHAR_UPD_GROUP_TYPE
Definition CharacterDatabase.h:290
GroupType
Definition Group.h:86
@ GROUPTYPE_LFG_RESTRICTED
Definition Group.h:91
@ GROUPTYPE_LFG
Definition Group.h:92
@ NEED_BEFORE_GREED
Definition LootMgr.h:62

References CHAR_UPD_GROUP_TYPE, CharacterDatabase, GetGUID(), GROUPTYPE_LFG, GROUPTYPE_LFG_RESTRICTED, isBFGroup(), isBGGroup(), m_groupType, m_lootMethod, NEED_BEFORE_GREED, SendUpdate(), and PreparedStatementBase::SetData().

Referenced by lfg::LFGMgr::MakeNewGroup().

◆ ConvertToRaid()

void Group::ConvertToRaid ( )
328{
330
332
333 if (!sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup())
334 {
336
337 stmt->SetData(0, uint8(m_groupType));
338 stmt->SetData(1, GetGUID().GetCounter());
339
340 CharacterDatabase.Execute(stmt);
341 }
342
343 SendUpdate();
344
345 // update quest related GO states (quest activity dependent from raid membership)
346 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
347 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
348 player->UpdateForQuestWorldObjects();
349
350 // pussywizard: client automatically clears df "eye" near minimap, so remove from raid browser
352 sLFGMgr->LeaveLfg(GetLeaderGUID());
353}
@ GROUPTYPE_RAID
Definition Group.h:89
#define sToCloud9Sidecar
Definition TC9Sidecar.h:81
void _initRaidSubGroupsCounter()
Definition Group.cpp:2696
ObjectGuid GetLeaderGUID() const
Definition Group.cpp:2515
@ LFG_STATE_RAIDBROWSER
Definition LFG.h:75

References _initRaidSubGroupsCounter(), CHAR_UPD_GROUP_TYPE, CharacterDatabase, ObjectAccessor::FindPlayer(), GetGUID(), GetLeaderGUID(), GROUPTYPE_RAID, isBFGroup(), isBGGroup(), lfg::LFG_STATE_RAIDBROWSER, m_groupType, m_memberSlots, SendUpdate(), PreparedStatementBase::SetData(), sLFGMgr, and sToCloud9Sidecar.

Referenced by WorldSession::HandleGroupRaidConvertOpcode().

◆ CountRollVote()

bool Group::CountRollVote ( ObjectGuid  playerGUID,
ObjectGuid  Guid,
uint8  Choise 
)
1497{
1498 Rolls::iterator rollI = GetRoll(Guid);
1499 if (rollI == RollId.end())
1500 return false;
1501 Roll* roll = *rollI;
1502
1503 Roll::PlayerVote::iterator itr = roll->playerVote.find(playerGUID);
1504 // this condition means that player joins to the party after roll begins
1505 // Xinef: if choice == MAX_ROLL_TYPE, player was removed from the map in removefromgroup
1506 // Xinef: itr can be invalid as it is not used below
1507 if (Choice < MAX_ROLL_TYPE && itr == roll->playerVote.end())
1508 return false;
1509
1510 if (roll->getLoot())
1511 if (roll->getLoot()->items.empty())
1512 return false;
1513
1514 switch (Choice)
1515 {
1516 case ROLL_PASS: // Player choose pass
1517 SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_PASS, *roll);
1518 ++roll->totalPass;
1519 itr->second = PASS;
1520 break;
1521 case ROLL_NEED: // player choose Need
1522 SendLootRoll(ObjectGuid::Empty, playerGUID, 0, 0, *roll);
1523 ++roll->totalNeed;
1524 itr->second = NEED;
1525 break;
1526 case ROLL_GREED: // player choose Greed
1527 SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_GREED, *roll);
1528 ++roll->totalGreed;
1529 itr->second = GREED;
1530 break;
1531 case ROLL_DISENCHANT: // player choose Disenchant
1532 SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_DISENCHANT, *roll);
1533 ++roll->totalGreed;
1534 itr->second = DISENCHANT;
1535 break;
1536 }
1537
1538 if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
1539 {
1540 CountTheRoll(rollI);
1541 return true;
1542 }
1543 return false;
1544}
@ PASS
Definition Group.h:51
@ NEED
Definition Group.h:52
@ DISENCHANT
Definition Group.h:54
@ GREED
Definition Group.h:53
@ ROLL_PASS
Definition LootMgr.h:33
@ ROLL_GREED
Definition LootMgr.h:35
@ ROLL_NEED
Definition LootMgr.h:34
@ ROLL_DISENCHANT
Definition LootMgr.h:36
Rolls::iterator GetRoll(ObjectGuid Guid)
Definition Group.cpp:2682
void CountTheRoll(Rolls::iterator roll)
Definition Group.cpp:1603
void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const &r, bool autoPass=false)
Definition Group.cpp:1017
static ObjectGuid const Empty
Definition ObjectGuid.h:123
uint8 totalGreed
Definition Group.h:168
uint8 totalPlayersRolling
Definition Group.h:166
uint8 totalNeed
Definition Group.h:167
uint8 totalPass
Definition Group.h:169
Loot * getLoot()
Definition Group.cpp:62
PlayerVote playerVote
Definition Group.h:165
std::vector< LootItem > items
Definition LootMgr.h:320

References CountTheRoll(), DISENCHANT, ObjectGuid::Empty, Roll::getLoot(), GetRoll(), GREED, Loot::items, NEED, PASS, Roll::playerVote, ROLL_DISENCHANT, ROLL_GREED, ROLL_NEED, ROLL_PASS, RollId, SendLootRoll(), Roll::totalGreed, Roll::totalNeed, Roll::totalPass, and Roll::totalPlayersRolling.

Referenced by WorldSession::HandleLootRoll(), and RemovePlayerFromRolls().

◆ CountTheRoll()

void Group::CountTheRoll ( Rolls::iterator  roll)
1604{
1605 Roll* roll = *rollI;
1606 if (!roll->isValid()) // is loot already deleted ?
1607 {
1608 RollId.erase(rollI);
1609 delete roll;
1610 return;
1611 }
1612
1613 //end of the roll
1614 if (roll->totalNeed > 0)
1615 {
1616 if (!roll->playerVote.empty())
1617 {
1618 uint8 maxresul = 0;
1619 ObjectGuid maxguid; // pussywizard: start with 0 >_>
1620 Player* player = nullptr;
1621
1622 for (Roll::PlayerVote::const_iterator itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
1623 {
1624 if (itr->second != NEED)
1625 continue;
1626
1627 player = ObjectAccessor::FindPlayer(itr->first);
1628 if (!player)
1629 {
1630 --roll->totalNeed;
1631 continue;
1632 }
1633
1634 uint8 randomN = urand(1, 100);
1635 SendLootRoll(ObjectGuid::Empty, itr->first, randomN, ROLL_NEED, *roll);
1636 if (maxresul < randomN)
1637 {
1638 maxguid = itr->first;
1639 maxresul = randomN;
1640 }
1641 }
1642
1643 if (maxguid) // pussywizard: added condition
1644 {
1645 SendLootRollWon(roll->itemGUID, maxguid, maxresul, ROLL_NEED, *roll);
1646 player = ObjectAccessor::FindPlayer(maxguid);
1647
1648 if (player)
1649 {
1651
1652 ItemPosCountVec dest;
1653 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1654 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1655 if (msg == EQUIP_ERR_OK)
1656 {
1657 item->is_looted = true;
1658 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1659 roll->getLoot()->unlootedCount--;
1660 AllowedLooterSet looters = item->GetAllowedLooters();
1661 Item* _item = player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, looters);
1662 if (_item)
1663 sScriptMgr->OnPlayerGroupRollRewardItem(player, _item, item->count, NEED, roll);
1664 player->UpdateLootAchievements(item, roll->getLoot());
1665 }
1666 else
1667 {
1668 uint32 mailOnFull = sWorld->getIntConfig(CONFIG_LFG_MAIL_ITEM_ON_FULL_INVENTORY);
1669 // Only mail when bags are genuinely full. Unique/max-count failures must
1670 // leave the item on the corpse so it can be re-rolled or freely looted.
1672 {
1673 item->is_looted = true;
1674 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1675 roll->getLoot()->unlootedCount--;
1676 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1677 SendRollWonItemViaMail(player, item, roll->itemid);
1678 }
1679 else
1680 {
1681 item->is_blocked = false;
1682 item->rollWinnerGUID = player->GetGUID();
1683 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1684 }
1685 }
1686 }
1687 }
1688 else
1689 roll->totalNeed = 0;
1690 }
1691 }
1692 if (roll->totalNeed == 0 && roll->totalGreed > 0) // if (roll->totalNeed == 0 && ...), not else if, because totalNeed can be decremented above when a needing player is offline
1693 {
1694 if (!roll->playerVote.empty())
1695 {
1696 uint8 maxresul = 0;
1697 ObjectGuid maxguid; // pussywizard: start with 0
1698 Player* player = nullptr;
1699 RollVote rollvote = NOT_VALID;
1700
1701 Roll::PlayerVote::iterator itr;
1702 for (itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
1703 {
1704 if (itr->second != GREED && itr->second != DISENCHANT)
1705 continue;
1706
1707 player = ObjectAccessor::FindPlayer(itr->first);
1708 if (!player)
1709 {
1710 --roll->totalGreed;
1711 continue;
1712 }
1713
1714 uint8 randomN = urand(1, 100);
1715 SendLootRoll(ObjectGuid::Empty, itr->first, randomN, itr->second, *roll);
1716 if (maxresul < randomN)
1717 {
1718 maxguid = itr->first;
1719 maxresul = randomN;
1720 rollvote = itr->second;
1721 }
1722 }
1723
1724 if (maxguid) // pussywizard: added condition
1725 {
1726 SendLootRollWon(roll->itemGUID, maxguid, maxresul, rollvote, *roll);
1727 player = ObjectAccessor::FindPlayer(maxguid);
1728
1729 if (player)
1730 {
1732
1733 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1734
1735 if (rollvote == GREED)
1736 {
1737 ItemPosCountVec dest;
1738 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1739 if (msg == EQUIP_ERR_OK)
1740 {
1741 item->is_looted = true;
1742 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1743 roll->getLoot()->unlootedCount--;
1744 AllowedLooterSet looters = item->GetAllowedLooters();
1745 Item* _item = player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, looters);
1746 if (_item)
1747 sScriptMgr->OnPlayerGroupRollRewardItem(player, _item, item->count, GREED, roll);
1748 player->UpdateLootAchievements(item, roll->getLoot());
1749 }
1750 else
1751 {
1752 uint32 mailOnFull = sWorld->getIntConfig(CONFIG_LFG_MAIL_ITEM_ON_FULL_INVENTORY);
1753 // Only mail when bags are genuinely full. Unique/max-count failures must
1754 // leave the item on the corpse so it can be re-rolled or freely looted.
1756 {
1757 item->is_looted = true;
1758 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1759 roll->getLoot()->unlootedCount--;
1760 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1761 SendRollWonItemViaMail(player, item, roll->itemid);
1762 }
1763 else
1764 {
1765 item->is_blocked = false;
1766 item->rollWinnerGUID = player->GetGUID();
1767 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1768 }
1769 }
1770 }
1771 else if (rollvote == DISENCHANT)
1772 {
1773 item->is_looted = true;
1774 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1775 roll->getLoot()->unlootedCount--;
1776 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(roll->itemid);
1778
1779 ItemPosCountVec dest;
1780 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1781
1782 if (msg == EQUIP_ERR_OK)
1783 {
1784 player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
1785 }
1786 else
1787 {
1788 Loot loot;
1789 loot.FillLoot(pProto->DisenchantID, LootTemplates_Disenchant, player, true);
1790
1791 uint32 max_slot = loot.GetMaxSlotInLootFor(player);
1792 for(uint32 i = 0; i < max_slot; i++)
1793 {
1794 LootItem* lootItem = loot.LootItemInSlot(i, player);
1795 player->SendEquipError(msg, nullptr, nullptr, lootItem->itemid);
1796 player->SendItemRetrievalMail(lootItem->itemid, lootItem->count);
1797 }
1798 }
1799 }
1800 }
1801 }
1802 else
1803 roll->totalGreed = 0;
1804 }
1805 }
1806 if (roll->totalNeed == 0 && roll->totalGreed == 0) // if, not else, because the totals can be decremented above when a rolling player is offline
1807 {
1808 SendLootAllPassed(*roll);
1809
1810 // remove is_blocked so that the item is lootable by all players
1811 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1812 if (item)
1813 item->is_blocked = false;
1814 }
1815
1816 if (Loot* loot = roll->getLoot(); loot && loot->isLooted() && loot->sourceGameObject)
1817 {
1818 GameObjectTemplate const* goInfo = loot->sourceGameObject->GetGOInfo();
1819 if (goInfo && goInfo->type == GAMEOBJECT_TYPE_CHEST)
1820 {
1821 // Deactivate chest if the last item was rolled in group
1823 }
1824 }
1825
1826 RollId.erase(rollI);
1827 delete roll;
1828}
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition DBCEnums.h:143
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT
Definition DBCEnums.h:165
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT
Definition DBCEnums.h:164
@ GO_JUST_DEACTIVATED
Definition GameObject.h:113
static void SendRollWonItemViaMail(Player *player, LootItem const *lootItem, uint32 itemId)
Definition Group.cpp:67
@ MAIL_ITEM_ON_FULL_INVENTORY_LFG_ONLY
Definition Group.h:135
@ MAIL_ITEM_ON_FULL_INVENTORY_EVERYWHERE
Definition Group.h:136
RollVote
Definition Group.h:50
@ NOT_VALID
Definition Group.h:56
InventoryResult
Definition Item.h:46
@ EQUIP_ERR_OK
Definition Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition Item.h:97
@ NULL_BAG
Definition Item.h:40
@ NULL_SLOT
Definition Item.h:41
LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true)
GuidSet AllowedLooterSet
Definition LootMgr.h:151
#define sObjectMgr
Definition ObjectMgr.h:1731
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:758
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:44
@ GAMEOBJECT_TYPE_CHEST
Definition SharedDefines.h:1567
@ CONFIG_LFG_MAIL_ITEM_ON_FULL_INVENTORY
Definition WorldConfig.h:389
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:136
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2484
void SendLootAllPassed(Roll const &roll)
Definition Group.cpp:1064
void SendLootRollWon(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const &r)
Definition Group.cpp:1041
Definition Item.h:220
Definition ObjectGuid.h:121
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2236
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition Player.cpp:13826
void SendItemRetrievalMail(uint32 itemEntry, uint32 count)
Definition PlayerMisc.cpp:432
void UpdateLootAchievements(LootItem *item, Loot *loot)
Definition PlayerUpdates.cpp:2226
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2635
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4131
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1304
bool isValid() const
Definition Reference.h:79
uint8 itemSlot
Definition Group.h:170
uint32 itemid
Definition Group.h:160
ObjectGuid itemGUID
Definition Group.h:159
Definition GameObjectData.h:32
uint32 type
Definition GameObjectData.h:34
Definition ItemTemplate.h:619
uint32 DisenchantID
Definition ItemTemplate.h:690
Definition LootMgr.h:154
uint32 itemid
Definition LootMgr.h:155
bool is_blocked
Definition LootMgr.h:164
AllowedLooterSet const & GetAllowedLooters() const
Definition LootMgr.h:181
ObjectGuid rollWinnerGUID
Definition LootMgr.h:161
int32 randomPropertyId
Definition LootMgr.h:158
uint8 count
Definition LootMgr.h:162
bool is_looted
Definition LootMgr.h:163
Definition LootMgr.h:313
uint32 GetMaxSlotInLootFor(Player *player) const
Definition LootMgr.cpp:886
LootItem * LootItemInSlot(uint32 lootslot, Player *player, QuestItem **qitem=nullptr, QuestItem **ffaitem=nullptr, QuestItem **conditem=nullptr)
Definition LootMgr.cpp:821
bool isLooted() const
Definition LootMgr.h:368
uint8 unlootedCount
Definition LootMgr.h:323
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT, WorldObject *lootSource=nullptr)
Definition LootMgr.cpp:540
GameObject * sourceGameObject
Definition LootMgr.h:331
void NotifyItemRemoved(uint8 lootIndex)
Definition LootMgr.cpp:743
std::vector< LootItem > quest_items
Definition LootMgr.h:321

References ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, Player::AutoStoreLoot(), Player::CanStoreNewItem(), CONFIG_LFG_MAIL_ITEM_ON_FULL_INVENTORY, LootItem::count, DISENCHANT, ItemTemplate::DisenchantID, ObjectGuid::Empty, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, Loot::FillLoot(), ObjectAccessor::FindPlayer(), GAMEOBJECT_TYPE_CHEST, LootItem::GetAllowedLooters(), Object::GetGUID(), Roll::getLoot(), Loot::GetMaxSlotInLootFor(), GO_JUST_DEACTIVATED, GREED, LootItem::is_blocked, LootItem::is_looted, isLFGGroup(), Loot::isLooted(), Reference< TO, FROM >::isValid(), Roll::itemGUID, Roll::itemid, LootItem::itemid, Loot::items, Roll::itemSlot, Loot::LootItemInSlot(), LootTemplates_Disenchant, MAIL_ITEM_ON_FULL_INVENTORY_EVERYWHERE, MAIL_ITEM_ON_FULL_INVENTORY_LFG_ONLY, NEED, NOT_VALID, Loot::NotifyItemRemoved(), NULL_BAG, NULL_SLOT, Roll::playerVote, Loot::quest_items, LootItem::randomPropertyId, ROLL_NEED, RollId, LootItem::rollWinnerGUID, Player::SendEquipError(), Player::SendItemRetrievalMail(), SendLootAllPassed(), SendLootRoll(), SendLootRollWon(), SendRollWonItemViaMail(), sObjectMgr, sScriptMgr, Player::StoreNewItem(), sWorld, Roll::totalGreed, Roll::totalNeed, GameObjectTemplate::type, Loot::unlootedCount, Player::UpdateAchievementCriteria(), Player::UpdateLootAchievements(), and urand().

Referenced by CountRollVote(), and EndRoll().

◆ Create()

bool Group::Create ( Player *  leader)
144{
145 ObjectGuid leaderGuid = leader->GetGUID();
146 ObjectGuid::LowType lowguid = sGroupMgr->GenerateGroupId();
147
148 m_guid = ObjectGuid::Create<HighGuid::Group>(lowguid);
149 m_leaderGuid = leaderGuid;
150 m_leaderName = leader->GetName();
152
153 if (isBGGroup() || isBFGroup())
155
158
159 if (!isLFGGroup())
161
163 m_looterGuid = leaderGuid;
165
168
169 if (!isBGGroup() && !isBFGroup())
170 {
173
174 // Store group in database
176
177 uint8 index = 0;
178
179 stmt->SetData(index++, lowguid);
180 stmt->SetData(index++, m_leaderGuid.GetCounter());
181 stmt->SetData(index++, uint8(m_lootMethod));
182 stmt->SetData(index++, m_looterGuid.GetCounter());
183 stmt->SetData(index++, uint8(m_lootThreshold));
184 stmt->SetData(index++, m_targetIcons[0].GetRawValue());
185 stmt->SetData(index++, m_targetIcons[1].GetRawValue());
186 stmt->SetData(index++, m_targetIcons[2].GetRawValue());
187 stmt->SetData(index++, m_targetIcons[3].GetRawValue());
188 stmt->SetData(index++, m_targetIcons[4].GetRawValue());
189 stmt->SetData(index++, m_targetIcons[5].GetRawValue());
190 stmt->SetData(index++, m_targetIcons[6].GetRawValue());
191 stmt->SetData(index++, m_targetIcons[7].GetRawValue());
192 stmt->SetData(index++, uint8(m_groupType));
193 stmt->SetData(index++, uint8(m_dungeonDifficulty));
194 stmt->SetData(index++, uint8(m_raidDifficulty));
195 stmt->SetData(index++, m_masterLooterGuid.GetCounter());
196
197 CharacterDatabase.Execute(stmt);
198
199 ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
200
201 sScriptMgr->OnCreate(this, leader);
202 }
203 else if (!AddMember(leader))
204 return false;
205
206 return true;
207}
@ CHAR_INS_GROUP
Definition CharacterDatabase.h:286
#define ASSERT
Definition Errors.h:68
#define sGroupMgr
Definition GroupMgr.h:51
@ GROUPTYPE_BGRAID
Definition Group.h:90
@ GROUP_LOOT
Definition LootMgr.h:61
ObjectGuid m_looterGuid
Definition Group.h:369
ObjectGuid m_masterLooterGuid
Definition Group.h:370
ObjectGuid m_guid
Definition Group.h:373
uint32 LowType
Definition ObjectGuid.h:125
void Clear()
Definition ObjectGuid.h:141

References _initRaidSubGroupsCounter(), AddMember(), ASSERT, CHAR_INS_GROUP, CharacterDatabase, ObjectGuid::Clear(), DUNGEON_DIFFICULTY_NORMAL, ObjectGuid::GetCounter(), Player::GetDungeonDifficulty(), Object::GetGUID(), WorldObject::GetName(), Player::GetRaidDifficulty(), GROUP_LOOT, GROUPTYPE_BGRAID, GROUPTYPE_RAID, isBFGroup(), isBGGroup(), isLFGGroup(), ITEM_QUALITY_UNCOMMON, m_dungeonDifficulty, m_groupType, m_guid, m_leaderGuid, m_leaderName, m_looterGuid, m_lootMethod, m_lootThreshold, m_masterLooterGuid, m_raidDifficulty, m_targetIcons, PLAYER_FLAGS_GROUP_LEADER, RAID_DIFFICULTY_10MAN_NORMAL, PreparedStatementBase::SetData(), Player::SetPlayerFlag(), sGroupMgr, and sScriptMgr.

Referenced by Battlefield::AddOrSetPlayerToCorrectBfGroup(), Battleground::AddOrSetPlayerToCorrectBgGroup(), Arena::AddPlayer(), and lfg::LFGMgr::MakeNewGroup().

◆ Disband()

void Group::Disband ( bool  hideDestroy = false)
916{
917 if (sToCloud9Sidecar->ClusterModeEnabled() && !this->isBFGroup() && !this->isBGGroup())
918 return;
919
920 ForcedDisband(hideDestroy);
921}
void ForcedDisband(bool hideDestroy=false)
Definition Group.cpp:819

References ForcedDisband(), and sToCloud9Sidecar.

Referenced by Arena::AddPlayer(), group_commandscript::HandleGroupDisbandCommand(), WorldSession::HandleGroupDisbandOpcode(), RemoveMember(), and Player::UninviteFromGroup().

◆ DoForAllMembers()

void Group::DoForAllMembers ( std::function< void(Player *)> const &  worker)
2763{
2764 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
2765 {
2766 Player* member = itr->GetSource();
2767 if (!member)
2768 continue;
2769
2770 worker(member);
2771 }
2772}

References GetFirstMember(), and GroupReference::next().

Referenced by BattlegroundQueue::AddGroup(), WorldSession::HandleBattlemasterJoinArena(), and WorldSession::HandleBattlemasterJoinOpcode().

◆ DoMinimapPing()

void Group::DoMinimapPing ( ObjectGuid  sourceGuid,
float  mapX,
float  mapY 
)
2273{
2275 minimapPing.SourceGuid = sourceGuid;
2276 minimapPing.MapX = mapX;
2277 minimapPing.MapY = mapY;
2278
2279 BroadcastPacket(minimapPing.Write(), true, -1, sourceGuid);
2280}
Definition MiscPackets.h:108
float MapY
Definition MiscPackets.h:116
WorldPacket const * Write() override
Definition MiscPackets.cpp:76
float MapX
Definition MiscPackets.h:115
ObjectGuid SourceGuid
Definition MiscPackets.h:114

References BroadcastPacket(), WorldPackets::Misc::MinimapPing::MapX, WorldPackets::Misc::MinimapPing::MapY, WorldPackets::Misc::MinimapPing::SourceGuid, and WorldPackets::Misc::MinimapPing::Write().

Referenced by WorldSession::HandleMinimapPingOpcode().

◆ EndRoll()

void Group::EndRoll ( Loot *  loot)
1548{
1549 for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
1550 {
1551 if ((*itr)->getLoot() == pLoot)
1552 {
1553 Roll* roll = *itr;
1554 for (auto& [playerGuid, vote] : roll->playerVote)
1555 {
1556 if (vote != NOT_EMITED_YET)
1557 continue;
1558
1559 vote = PASS;
1560 ++roll->totalPass;
1561 SendLootRoll(roll->itemGUID, playerGuid, 128, ROLL_PASS, *roll);
1562 }
1563
1564 CountTheRoll(itr);
1565 itr = RollId.begin();
1566 }
1567 else
1568 ++itr;
1569 }
1570}
@ NOT_EMITED_YET
Definition Group.h:55

References CountTheRoll(), Roll::itemGUID, NOT_EMITED_YET, PASS, Roll::playerVote, ROLL_PASS, RollId, SendLootRoll(), and Roll::totalPass.

Referenced by GameObject::Update(), and Creature::Update().

◆ ForcedDisband()

void Group::ForcedDisband ( bool  hideDestroy = false)
protected
820{
821 sScriptMgr->OnGroupDisband(this);
822
823 Player* player;
824 uint32 instanceId = 0;
825
826 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
827 {
828 if (!isBGGroup() && !isBFGroup())
829 {
830 sCharacterCache->ClearCharacterGroup(citr->guid);
831 }
832
833 player = ObjectAccessor::FindConnectedPlayer(citr->guid);
834
835 if (player && !instanceId && !isBGGroup() && !isBFGroup())
836 {
837 instanceId = player->GetInstanceId();
838 }
839
840 _homebindIfInstance(player);
841 if (!isBGGroup() && !isBFGroup())
843
844 if (!player)
845 continue;
846
847 //we cannot call _removeMember because it would invalidate member iterator
848 //if we are removing player from battleground raid
849 if (isBGGroup() || isBFGroup())
851 else
852 {
853 //we can remove player who is in battleground from his original group
854 if (player->GetOriginalGroup() == this)
855 player->SetOriginalGroup(nullptr);
856 else
857 player->SetGroup(nullptr);
858 }
859
860 // quest related GO state dependent from raid membership
861 if (isRaidGroup())
863
864 WorldPacket data;
865 if (!hideDestroy)
866 {
868 player->SendDirectMessage(&data);
869 }
870
871 //we already removed player from group and in player->GetGroup() is his original group, send update
872 if (Group* group = player->GetGroup())
873 {
874 group->SendUpdate();
875 }
876 else
877 {
878 data.Initialize(SMSG_GROUP_LIST, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 8);
879 data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
880 data << m_guid << uint32(m_counter) << uint32(0) << uint64(0);
881 player->SendDirectMessage(&data);
882 }
883 }
884 RollId.clear();
885 m_memberSlots.clear();
886
888
889 if (!isBGGroup() && !isBFGroup())
890 {
891 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
892
894 stmt->SetData(0, GetGUID().GetCounter());
895 trans->Append(stmt);
896
897 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER_ALL);
898 stmt->SetData(0, GetGUID().GetCounter());
899 trans->Append(stmt);
900
901 CharacterDatabase.CommitTransaction(trans);
902
903 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
904 stmt->SetData(0, GetGUID().GetCounter());
905 CharacterDatabase.Execute(stmt);
906 }
907
908 // Cleaning up instance saved data for gameobjects when a group is disbanded
909 sInstanceSaveMgr->DeleteInstanceSavedData(instanceId);
910
911 sGroupMgr->RemoveGroup(this);
912 delete this;
913}
@ CHAR_DEL_GROUP_MEMBER_ALL
Definition CharacterDatabase.h:385
@ CHAR_DEL_GROUP
Definition CharacterDatabase.h:384
@ CHAR_DEL_LFG_DATA
Definition CharacterDatabase.h:330
std::uint64_t uint64
Definition Define.h:106
@ INSTANCE_RESET_GROUP_LEAVE
Definition Map.h:720
void RemoveAllInvites()
Definition Group.cpp:398
void _homebindIfInstance(Player *player)
Definition Group.cpp:2402
void RemoveFromBattlegroundOrBattlefieldRaid()
Definition Player.cpp:13429
void Initialize(uint16 opcode, std::size_t newres=200)
Definition WorldPacket.h:68
@ SMSG_GROUP_LIST
Definition Opcodes.h:155
@ SMSG_GROUP_DESTROYED
Definition Opcodes.h:154

References _homebindIfInstance(), CHAR_DEL_GROUP, CHAR_DEL_GROUP_MEMBER_ALL, CHAR_DEL_LFG_DATA, CharacterDatabase, ObjectAccessor::FindConnectedPlayer(), Player::GetGroup(), GetGUID(), WorldObject::GetInstanceId(), Player::GetOriginalGroup(), WorldPacket::Initialize(), INSTANCE_RESET_GROUP_LEAVE, isBFGroup(), isBGGroup(), isRaidGroup(), m_counter, m_guid, m_memberSlots, RemoveAllInvites(), Player::RemoveFromBattlegroundOrBattlefieldRaid(), Player::ResetInstances(), RollId, sCharacterCache, Player::SendDirectMessage(), PreparedStatementBase::SetData(), Player::SetGroup(), Player::SetOriginalGroup(), sGroupMgr, sInstanceSaveMgr, SMSG_GROUP_DESTROYED, SMSG_GROUP_LIST, sScriptMgr, and Player::UpdateForQuestWorldObjects().

Referenced by Disband().

◆ GetDifficulty()

Difficulty Group::GetDifficulty ( bool  isRaid) const
2663{
2664 return isRaid ? m_raidDifficulty : m_dungeonDifficulty;
2665}

References m_dungeonDifficulty, and m_raidDifficulty.

Referenced by MapInstanced::CreateInstanceForPlayer().

◆ GetDifficultyChangePreventionReason()

DifficultyPreventionChangeType Group::GetDifficultyChangePreventionReason ( ) const
inline

◆ GetDifficultyChangePreventionTime()

uint32 Group::GetDifficultyChangePreventionTime ( ) const

◆ GetDungeonDifficulty()

Difficulty Group::GetDungeonDifficulty ( ) const
2668{
2669 return m_dungeonDifficulty;
2670}

References m_dungeonDifficulty.

Referenced by AddMember().

◆ GetFirstMember() [1/2]

◆ GetFirstMember() [2/2]

GroupReference const * Group::GetFirstMember ( ) const
inline
253{ return m_memberMgr.getFirst(); }

References GroupRefMgr::getFirst(), and m_memberMgr.

◆ GetGroupType()

GroupType Group::GetGroupType ( ) const
2511{
2512 return m_groupType;
2513}

References m_groupType.

◆ GetGUID()

◆ GetInvited() [1/2]

Player * Group::GetInvited ( ObjectGuid  guid) const
408{
409 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
410 {
411 if ((*itr) && (*itr)->GetGUID() == guid)
412 return (*itr);
413 }
414 return nullptr;
415}

References m_invitees.

Referenced by WorldSession::HandleGroupUninviteGuidOpcode(), and WorldSession::HandleGroupUninviteOpcode().

◆ GetInvited() [2/2]

Player * Group::GetInvited ( std::string const &  name) const
418{
419 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
420 {
421 if ((*itr) && (*itr)->GetName() == name)
422 return (*itr);
423 }
424 return nullptr;
425}

References m_invitees.

◆ GetInviteeCount()

uint32 Group::GetInviteeCount ( ) const
inline
255{ return m_invitees.size(); }

References m_invitees.

Referenced by Player::UninviteFromGroup().

◆ GetLeader()

Player * Group::GetLeader ( )

◆ GetLeaderGUID()

◆ GetLeaderName()

char const * Group::GetLeaderName ( ) const
2531{
2532 return m_leaderName.c_str();
2533}

References m_leaderName.

Referenced by ChatLogScript::OnPlayerCanUseChat(), and Player::Satisfy().

◆ GetLooterGuid()

ObjectGuid Group::GetLooterGuid ( ) const
2541{
2542 return m_looterGuid;
2543}

References m_looterGuid.

Referenced by Unit::Kill(), and UpdateLooterGuid().

◆ GetLootMethod()

◆ GetLootThreshold()

ItemQualities Group::GetLootThreshold ( ) const
2551{
2552 return m_lootThreshold;
2553}

References m_lootThreshold.

Referenced by Loot::FillLoot().

◆ GetMasterLooterGuid()

ObjectGuid Group::GetMasterLooterGuid ( ) const

◆ GetMemberGroup()

uint8 Group::GetMemberGroup ( ObjectGuid  guid) const
2604{
2605 member_citerator mslot = _getMemberCSlot(guid);
2606 if (mslot == m_memberSlots.end())
2607 return (MAX_RAID_SUBGROUPS + 1);
2608 return mslot->group;
2609}
member_citerator _getMemberCSlot(ObjectGuid Guid) const
Definition Group.cpp:2708

References _getMemberCSlot(), m_memberSlots, and MAX_RAID_SUBGROUPS.

Referenced by Battlefield::AddOrSetPlayerToCorrectBfGroup(), Battleground::AddOrSetPlayerToCorrectBgGroup(), ChangeMembersGroup(), WorldSession::HandleGroupSwapSubGroupOpcode(), WorldSession::HandleMessagechatOpcode(), and Unit::Kill().

◆ GetMemberGUID()

ObjectGuid Group::GetMemberGUID ( std::string const &  name)
2566{
2567 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2568 if (itr->name == name)
2569 return itr->guid;
2570
2571 return ObjectGuid::Empty;
2572}

References ObjectGuid::Empty, and m_memberSlots.

Referenced by WorldSession::HandleGroupSwapSubGroupOpcode(), and WorldSession::HandleGroupUninviteOpcode().

◆ GetMembersCount()

◆ GetMemberSlots()

MemberSlotList const & Group::GetMemberSlots ( ) const
inline

◆ GetRaidDifficulty()

Difficulty Group::GetRaidDifficulty ( ) const
2673{
2674 return m_raidDifficulty;
2675}

References m_raidDifficulty.

Referenced by AddMember().

◆ GetRoll()

Group::Rolls::iterator Group::GetRoll ( ObjectGuid  Guid)
2683{
2684 Rolls::iterator iter;
2685 for (iter = RollId.begin(); iter != RollId.end(); ++iter)
2686 if ((*iter)->itemGUID == Guid && (*iter)->isValid())
2687 return iter;
2688 return RollId.end();
2689}

References RollId.

Referenced by CountRollVote().

◆ GetRolls()

std::vector< Roll const * > Group::GetRolls ( ) const
inline
316{ return { RollId.begin(), RollId.end() }; }

References RollId.

◆ GetTargetIcon()

ObjectGuid Group::GetTargetIcon ( uint8  id) const
inline

◆ GroupLoot()

void Group::GroupLoot ( Loot *  loot,
WorldObject *  pLootedObject 
)
1123{
1124 std::vector<LootItem>::iterator i;
1125 ItemTemplate const* item;
1126 uint8 itemSlot = 0;
1127
1128 for (i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
1129 {
1130 if (i->freeforall)
1131 continue;
1132
1133 item = sObjectMgr->GetItemTemplate(i->itemid);
1134 if (!item)
1135 {
1136 continue;
1137 }
1138
1139 // roll for over-threshold item if it's one-player loot
1140 if (item->Quality >= uint32(m_lootThreshold))
1141 {
1142 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1143 Roll* r = new Roll(newitemGUID, *i);
1144
1145 //a vector is filled with only near party members
1146 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1147 {
1148 Player* member = itr->GetSource();
1149 if (!member || !member->GetSession())
1150 continue;
1151
1152 bool canLoot = member->IsAtLootRewardDistance(pLootedObject);
1153 if (!canLoot && !pLootedObject->GetAllowedLooters().empty())
1154 canLoot = pLootedObject->HasAllowedLooter(member->GetGUID());
1155
1156 if (canLoot)
1157 {
1159
1160 RollVote vote = member->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
1161 if (!CanRollOnItem(*i, member, loot))
1162 {
1163 vote = PASS;
1164 ++r->totalPass;
1165 }
1166
1167 r->playerVote[member->GetGUID()] = vote;
1168 }
1169 }
1170
1171 if (r->totalPlayersRolling > 0)
1172 {
1173 r->setLoot(loot);
1174 r->itemSlot = itemSlot;
1177
1178 loot->items[itemSlot].is_blocked = true;
1179
1180 // If there is any "auto pass", broadcast the pass now.
1181 if (r->totalPass)
1182 {
1183 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1184 {
1185 Player* p = ObjectAccessor::FindPlayer(itr->first);
1186 if (!p)
1187 continue;
1188
1189 if (itr->second == PASS)
1190 SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r, true);
1191 }
1192 }
1193
1194 if (r->totalPass == r->totalPlayersRolling)
1195 delete r;
1196 else
1197 {
1198 SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
1199
1200 RollId.push_back(r);
1201
1202 if (Creature* creature = pLootedObject->ToCreature())
1203 {
1204 creature->m_groupLootTimer = 60000;
1205 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1206 }
1207 else if (GameObject* go = pLootedObject->ToGameObject())
1208 {
1209 go->m_groupLootTimer = 60000;
1210 go->lootingGroupLowGUID = GetGUID().GetCounter();
1211 }
1212 }
1213 }
1214 else
1215 delete r;
1216 }
1217 else
1218 i->is_underthreshold = true;
1219 }
1220
1221 for (i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i, ++itemSlot)
1222 {
1223 if (!i->follow_loot_rules)
1224 continue;
1225
1226 item = sObjectMgr->GetItemTemplate(i->itemid);
1227 if (!item)
1228 {
1229 continue;
1230 }
1231
1232 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1233 Roll* r = new Roll(newitemGUID, *i);
1234
1235 //a vector is filled with only near party members
1236 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1237 {
1238 Player* member = itr->GetSource();
1239 if (!member || !member->GetSession())
1240 continue;
1241
1242 bool canLoot = member->IsAtLootRewardDistance(pLootedObject);
1243 if (!canLoot && !pLootedObject->GetAllowedLooters().empty())
1244 canLoot = pLootedObject->HasAllowedLooter(member->GetGUID());
1245
1246 if (canLoot)
1247 {
1249
1250 RollVote vote = NOT_EMITED_YET;
1251 if (!CanRollOnItem(*i, member, loot))
1252 {
1253 vote = PASS;
1254 ++r->totalPass;
1255 }
1256 r->playerVote[member->GetGUID()] = vote;
1257 }
1258 }
1259
1260 if (r->totalPlayersRolling > 0)
1261 {
1262 r->setLoot(loot);
1263 r->itemSlot = itemSlot;
1264
1265 loot->quest_items[itemSlot - loot->items.size()].is_blocked = true;
1266
1267 SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
1268
1269 RollId.push_back(r);
1270
1271 if (Creature* creature = pLootedObject->ToCreature())
1272 {
1273 creature->m_groupLootTimer = 60000;
1274 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1275 }
1276 else if (GameObject* go = pLootedObject->ToGameObject())
1277 {
1278 go->m_groupLootTimer = 60000;
1279 go->lootingGroupLowGUID = GetGUID().GetCounter();
1280 }
1281 }
1282 else
1283 delete r;
1284 }
1285}
bool CanRollOnItem(LootItem const &item, Player const *player, Loot *loot)
Definition Group.cpp:1105
@ ROLL_FLAG_TYPE_DISENCHANT
Definition LootMgr.h:45
Definition Creature.h:47
Definition GameObject.h:120
void SendLootStartRoll(uint32 CountDown, uint32 mapid, Roll const &r)
Definition Group.cpp:927
GameObject * ToGameObject()
Definition Object.h:220
Creature * ToCreature()
Definition Object.h:212
WorldSession * GetSession() const
Definition Player.h:2031
bool IsAtLootRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:13097
bool GetPassOnGroupLoot() const
Definition Player.h:2538
void setLoot(Loot *pLoot)
Definition Group.cpp:57
uint8 rollVoteMask
Definition Group.h:171
bool HasAllowedLooter(ObjectGuid guid) const
Definition Object.cpp:3227
GuidUnorderedSet const & GetAllowedLooters() const
Definition Object.cpp:3237
uint32 Quality
Definition ItemTemplate.h:626
uint32 RequiredDisenchantSkill
Definition ItemTemplate.h:684

References CanRollOnItem(), ItemTemplate::DisenchantID, ObjectAccessor::FindPlayer(), WorldObject::GetAllowedLooters(), ObjectGuid::GetCounter(), GetFirstMember(), GetGUID(), Object::GetGUID(), WorldLocation::GetMapId(), Player::GetPassOnGroupLoot(), Player::GetSession(), WorldObject::HasAllowedLooter(), Player::IsAtLootRewardDistance(), Item, Loot::items, Roll::itemSlot, m_lootThreshold, m_maxEnchantingLevel, GroupReference::next(), NOT_EMITED_YET, PASS, Roll::playerVote, ItemTemplate::Quality, Loot::quest_items, ItemTemplate::RequiredDisenchantSkill, ROLL_FLAG_TYPE_DISENCHANT, ROLL_PASS, RollId, Roll::rollVoteMask, SendLootRoll(), SendLootStartRoll(), Roll::setLoot(), sObjectMgr, Object::ToCreature(), Object::ToGameObject(), Roll::totalPass, and Roll::totalPlayersRolling.

Referenced by Player::SendLoot().

◆ HasFreeSlotSubGroup()

bool Group::HasFreeSlotSubGroup ( uint8  subgroup) const

◆ InInstance()

uint16 Group::InInstance ( )

◆ IsAssistant()

◆ isBFGroup()

◆ isBGGroup()

◆ IsCreated()

bool Group::IsCreated ( ) const
2506{
2507 return GetMembersCount() > 0;
2508}

References GetMembersCount().

Referenced by Player::UninviteFromGroup().

◆ IsFull()

bool Group::IsFull ( ) const

◆ IsLeader()

◆ isLFGGroup()

◆ IsLfgHeroic()

bool Group::IsLfgHeroic ( ) const
inline

◆ IsLfgRandomInstance()

◆ IsLfgWithBuff()

◆ IsMember()

◆ isRaidGroup()

◆ isRollLootActive()

bool Group::isRollLootActive ( ) const
2678{
2679 return !RollId.empty();
2680}

References RollId.

Referenced by Player::CanUninviteFromGroup().

◆ LinkMember()

void Group::LinkMember ( GroupReference *  pRef)
2692{
2694}
void insertFirst(LinkedListElement *pElem)
Definition LinkedList.h:105

References LinkedListHead::insertFirst(), and m_memberMgr.

Referenced by GroupReference::targetObjectBuildLink().

◆ LoadGroupFromDB()

bool Group::LoadGroupFromDB ( Field *  field)
210{
211 ObjectGuid::LowType groupLowGuid = fields[16].Get<uint32>();
212 m_guid = ObjectGuid::Create<HighGuid::Group>(groupLowGuid);
213
214 m_leaderGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].Get<uint32>());
215
216 // group leader not exist
217 if (!sCharacterCache->GetCharacterNameByGuid(m_leaderGuid, m_leaderName))
218 {
219 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
221 stmt->SetData(0, groupLowGuid);
222 trans->Append(stmt);
223 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER_ALL);
224 stmt->SetData(0, groupLowGuid);
225 trans->Append(stmt);
226 CharacterDatabase.CommitTransaction(trans);
227 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
228 stmt->SetData(0, groupLowGuid);
229 CharacterDatabase.Execute(stmt);
230 return false;
231 }
232
233 m_lootMethod = LootMethod(fields[1].Get<uint8>());
234 m_looterGuid = ObjectGuid::Create<HighGuid::Player>(fields[2].Get<uint32>());
235 m_lootThreshold = ItemQualities(fields[3].Get<uint8>());
236
237 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
238 m_targetIcons[i].Set(fields[4 + i].Get<uint64>());
239
240 m_groupType = GroupType(fields[12].Get<uint8>());
243
244 uint32 diff = fields[13].Get<uint8>();
245 if (diff >= MAX_DUNGEON_DIFFICULTY)
247 else
249
250 uint32 r_diff = fields[14].Get<uint8>();
251 if (r_diff >= MAX_RAID_DIFFICULTY)
253 else
255
256 m_masterLooterGuid = ObjectGuid::Create<HighGuid::Player>(fields[15].Get<uint32>());
257
259 sLFGMgr->_LoadFromDB(fields, GetGUID());
260
261 return true;
262}
#define MAX_RAID_DIFFICULTY
Definition DBCEnums.h:282
Difficulty
Definition DBCEnums.h:266
#define MAX_DUNGEON_DIFFICULTY
Definition DBCEnums.h:281
LootMethod
Definition LootMgr.h:57
ItemQualities
Definition SharedDefines.h:316

References _initRaidSubGroupsCounter(), CHAR_DEL_GROUP, CHAR_DEL_GROUP_MEMBER_ALL, CHAR_DEL_LFG_DATA, CharacterDatabase, DUNGEON_DIFFICULTY_NORMAL, Field::Get(), GetGUID(), GROUPTYPE_LFG, GROUPTYPE_RAID, m_dungeonDifficulty, m_groupType, m_guid, m_leaderGuid, m_leaderName, m_looterGuid, m_lootMethod, m_lootThreshold, m_masterLooterGuid, m_raidDifficulty, m_targetIcons, MAX_DUNGEON_DIFFICULTY, MAX_RAID_DIFFICULTY, RAID_DIFFICULTY_10MAN_NORMAL, sCharacterCache, PreparedStatementBase::SetData(), sLFGMgr, and TARGETICONCOUNT.

Referenced by GroupMgr::LoadGroups().

◆ LoadMemberFromDB()

void Group::LoadMemberFromDB ( ObjectGuid::LowType  guidLow,
uint8  memberFlags,
uint8  subgroup,
uint8  roles 
)
265{
266 MemberSlot member;
267 member.guid = ObjectGuid::Create<HighGuid::Player>(guidLow);
268
269 // skip non-existed member
270 if (!sCharacterCache->GetCharacterNameByGuid(member.guid, member.name))
271 {
273 stmt->SetData(0, guidLow);
274 stmt->SetData(1, GetGUID().GetCounter());
275 CharacterDatabase.Execute(stmt);
276 return;
277 }
278
279 member.group = subgroup;
280 member.flags = memberFlags;
281 member.roles = roles;
282
283 m_memberSlots.push_back(member);
284
285 if (!isBGGroup() && !isBFGroup())
286 {
287 sCharacterCache->UpdateCharacterGroup(ObjectGuid(HighGuid::Player, guidLow), GetGUID());
288 }
289
290 SubGroupCounterIncrease(subgroup);
291
292 sLFGMgr->SetupGroupMember(member.guid, GetGUID());
293}
@ CHAR_DEL_GROUP_MEMBER
Definition CharacterDatabase.h:288

References CHAR_DEL_GROUP_MEMBER, CharacterDatabase, Group::MemberSlot::flags, GetGUID(), Group::MemberSlot::group, Group::MemberSlot::guid, isBFGroup(), isBGGroup(), m_memberSlots, Group::MemberSlot::name, Player, Group::MemberSlot::roles, sCharacterCache, PreparedStatementBase::SetData(), sLFGMgr, and SubGroupCounterIncrease().

Referenced by GroupMgr::LoadGroups().

◆ MasterLoot()

void Group::MasterLoot ( Loot *  loot,
WorldObject *  pLootedObject 
)
1443{
1444 LOG_DEBUG("network", "Group::MasterLoot (SMSG_LOOT_MASTER_LIST, 330)");
1445
1446 for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i)
1447 {
1448 if (i->freeforall)
1449 continue;
1450
1451 i->is_blocked = !i->is_underthreshold;
1452 }
1453
1454 for (std::vector<LootItem>::iterator i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i)
1455 {
1456 if (!i->follow_loot_rules)
1457 continue;
1458
1459 i->is_blocked = !i->is_underthreshold;
1460 }
1461
1462 std::vector<Player*> looters;
1463 bool hasAllowedLooters = !pLootedObject->GetAllowedLooters().empty();
1464 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1465 {
1466 Player* looter = itr->GetSource();
1467 if (!looter->IsInWorld())
1468 {
1469 continue;
1470 }
1471
1472 bool canLoot = looter->IsAtLootRewardDistance(pLootedObject);
1473 if (!canLoot && hasAllowedLooters)
1474 canLoot = pLootedObject->HasAllowedLooter(looter->GetGUID());
1475
1476 if (canLoot)
1477 {
1478 looters.push_back(looter);
1479 }
1480 }
1481
1482 WorldPacket data(SMSG_LOOT_MASTER_LIST, 1 + looters.size() * (1 + 8));
1483 data << uint8(looters.size());
1484
1485 for (Player* looter : looters)
1486 {
1487 data << looter->GetGUID();
1488 }
1489
1490 for (Player* looter : looters)
1491 {
1492 looter->SendDirectMessage(&data);
1493 }
1494}
bool IsInWorld() const
Definition Object.h:115
@ SMSG_LOOT_MASTER_LIST
Definition Opcodes.h:706

References WorldObject::GetAllowedLooters(), GetFirstMember(), Object::GetGUID(), WorldObject::HasAllowedLooter(), Player::IsAtLootRewardDistance(), Object::IsInWorld(), Loot::items, LOG_DEBUG, GroupReference::next(), Loot::quest_items, and SMSG_LOOT_MASTER_LIST.

Referenced by Player::SendLoot().

◆ NeedBeforeGreed()

void Group::NeedBeforeGreed ( Loot *  loot,
WorldObject *  pLootedObject 
)
1288{
1289 ItemTemplate const* item;
1290 uint8 itemSlot = 0;
1291 for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
1292 {
1293 if (i->freeforall)
1294 continue;
1295
1296 item = sObjectMgr->GetItemTemplate(i->itemid);
1297
1298 //roll for over-threshold item if it's one-player loot
1299 if (item->Quality >= uint32(m_lootThreshold))
1300 {
1301 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1302 Roll* r = new Roll(newitemGUID, *i);
1303
1304 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1305 {
1306 Player* playerToRoll = itr->GetSource();
1307 if (!playerToRoll || !playerToRoll->GetSession())
1308 continue;
1309
1310 bool canLoot = playerToRoll->IsAtGroupRewardDistance(lootedObject);
1311 if (!canLoot && !lootedObject->GetAllowedLooters().empty())
1312 canLoot = lootedObject->HasAllowedLooter(playerToRoll->GetGUID());
1313
1314 if (canLoot)
1315 {
1317
1318 RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
1319 if (!CanRollOnItem(*i, playerToRoll, loot))
1320 {
1321 vote = PASS;
1322 r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
1323 }
1324
1325 r->playerVote[playerToRoll->GetGUID()] = vote;
1326 }
1327 }
1328
1329 if (r->totalPlayersRolling > 0)
1330 {
1331 r->setLoot(loot);
1332 r->itemSlot = itemSlot;
1335
1337 r->rollVoteMask &= ~ROLL_FLAG_TYPE_NEED;
1338
1339 loot->items[itemSlot].is_blocked = true;
1340
1341 //Broadcast Pass and Send Rollstart
1342 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1343 {
1344 Player* p = ObjectAccessor::FindPlayer(itr->first);
1345 if (!p)
1346 continue;
1347
1348 if (itr->second == PASS)
1349 SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
1350 else
1351 SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
1352 }
1353
1354 RollId.push_back(r);
1355
1356 if (Creature* creature = lootedObject->ToCreature())
1357 {
1358 creature->m_groupLootTimer = 60000;
1359 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1360 }
1361 else if (GameObject* go = lootedObject->ToGameObject())
1362 {
1363 go->m_groupLootTimer = 60000;
1364 go->lootingGroupLowGUID = GetGUID().GetCounter();
1365 }
1366 }
1367 else
1368 delete r;
1369 }
1370 else
1371 i->is_underthreshold = true;
1372 }
1373
1374 for (std::vector<LootItem>::iterator i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i, ++itemSlot)
1375 {
1376 if (!i->follow_loot_rules)
1377 continue;
1378
1379 item = sObjectMgr->GetItemTemplate(i->itemid);
1380 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1381 Roll* r = new Roll(newitemGUID, *i);
1382
1383 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1384 {
1385 Player* playerToRoll = itr->GetSource();
1386 if (!playerToRoll || !playerToRoll->GetSession())
1387 continue;
1388
1389 if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
1390 {
1392
1393 RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
1394 if (!CanRollOnItem(*i, playerToRoll, loot))
1395 {
1396 vote = PASS;
1397 r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
1398 }
1399
1400 r->playerVote[playerToRoll->GetGUID()] = vote;
1401 }
1402 }
1403
1404 if (r->totalPlayersRolling > 0)
1405 {
1406 r->setLoot(loot);
1407 r->itemSlot = itemSlot;
1408
1409 loot->quest_items[itemSlot - loot->items.size()].is_blocked = true;
1410
1411 //Broadcast Pass and Send Rollstart
1412 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1413 {
1414 Player* p = ObjectAccessor::FindPlayer(itr->first);
1415 if (!p)
1416 continue;
1417
1418 if (itr->second == PASS)
1419 SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
1420 else
1421 SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
1422 }
1423
1424 RollId.push_back(r);
1425
1426 if (Creature* creature = lootedObject->ToCreature())
1427 {
1428 creature->m_groupLootTimer = 60000;
1429 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1430 }
1431 else if (GameObject* go = lootedObject->ToGameObject())
1432 {
1433 go->m_groupLootTimer = 60000;
1434 go->lootingGroupLowGUID = GetGUID().GetCounter();
1435 }
1436 }
1437 else
1438 delete r;
1439 }
1440}
@ ITEM_FLAG2_CAN_ONLY_ROLL_GREED
Definition ItemTemplate.h:191
void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player *p, bool canNeed, Roll const &r)
Definition Group.cpp:995
InventoryResult CanRollForItemInLFG(ItemTemplate const *item, WorldObject const *lootedObject) const
Definition PlayerStorage.cpp:2444
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:13076
bool HasFlag2(ItemFlags2 flag) const
Definition ItemTemplate.h:828

References Player::CanRollForItemInLFG(), CanRollOnItem(), ItemTemplate::DisenchantID, EQUIP_ERR_OK, ObjectAccessor::FindPlayer(), WorldObject::GetAllowedLooters(), ObjectGuid::GetCounter(), GetFirstMember(), GetGUID(), Object::GetGUID(), WorldLocation::GetMapId(), Player::GetPassOnGroupLoot(), Player::GetSession(), WorldObject::HasAllowedLooter(), ItemTemplate::HasFlag2(), Player::IsAtGroupRewardDistance(), Item, ITEM_FLAG2_CAN_ONLY_ROLL_GREED, Loot::items, Roll::itemSlot, m_lootThreshold, m_maxEnchantingLevel, GroupReference::next(), NOT_EMITED_YET, PASS, Roll::playerVote, ItemTemplate::Quality, Loot::quest_items, ItemTemplate::RequiredDisenchantSkill, ROLL_FLAG_TYPE_DISENCHANT, ROLL_PASS, RollId, Roll::rollVoteMask, SendLootRoll(), SendLootStartRollToPlayer(), Roll::setLoot(), sObjectMgr, Object::ToCreature(), Object::ToGameObject(), Roll::totalPass, and Roll::totalPlayersRolling.

Referenced by Player::SendLoot().

◆ OfflineReadyCheck()

void Group::OfflineReadyCheck ( )
1994{
1995 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1996 {
1997 Player* player = ObjectAccessor::FindConnectedPlayer(citr->guid);
1998 if (!player)
1999 {
2001 data << citr->guid;
2002 data << uint8(0);
2003 BroadcastReadyCheck(&data);
2004 }
2005 }
2006}
void BroadcastReadyCheck(WorldPacket const *packet)
Definition Group.cpp:1982
@ MSG_RAID_READY_CHECK_CONFIRM
Definition Opcodes.h:972

References BroadcastReadyCheck(), ObjectAccessor::FindConnectedPlayer(), m_memberSlots, and MSG_RAID_READY_CHECK_CONFIRM.

Referenced by WorldSession::HandleRaidReadyCheckOpcode().

◆ RemoveAllInvites()

void Group::RemoveAllInvites ( )
399{
400 for (Player* invitee : m_invitees)
401 if (invitee && invitee->GetGroupInvite() == this)
402 invitee->SetGroupInvite(nullptr);
403
404 m_invitees.clear();
405}

References m_invitees.

Referenced by ForcedDisband(), and Player::UninviteFromGroup().

◆ RemoveInvite()

void Group::RemoveInvite ( Player *  player)
387{
388 if (!player)
389 return;
390
391 m_invitees.erase(player);
392
393 // Clear pending invite from current group, Keep an invite from another group.
394 if (player->GetGroupInvite() == this)
395 player->SetGroupInvite(nullptr);
396}

References Player::GetGroupInvite(), m_invitees, and Player::SetGroupInvite().

Referenced by AddInvite(), WorldSession::HandleGroupAcceptOpcode(), and Player::UninviteFromGroup().

◆ RemoveMember()

bool Group::RemoveMember ( ObjectGuid  guid,
RemoveMethod const &  method = GROUP_REMOVEMETHOD_DEFAULT,
ObjectGuid  kicker = ObjectGuid::Empty,
char const *  reason = nullptr 
)
630{
632
633 // LFG group vote kick handled in scripts
634 if (isLFGGroup(true) && method == GROUP_REMOVEMETHOD_KICK)
635 {
636 sLFGMgr->InitBoot(GetGUID(), kicker, guid, std::string(reason ? reason : ""));
637 return m_memberSlots.size() > 0;
638 }
639
640 // remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group),
641 // except in cluster mode, where this branch is taken for any size: the group
642 // service owns the group lifecycle and local Disband() is a no-op, so always
643 // unlink the removed member here; waiting for the disband event leaves the
644 // last two members with a dangling group pointer whenever that event is lost
645 // (group service restart).
646 if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u)
647 || (sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup()))
648 {
650 if (player)
651 {
652 // Battleground group handling
653 if (isBGGroup() || isBFGroup())
655 else
656 // Regular group
657 {
658 if (player->GetOriginalGroup() == this)
659 player->SetOriginalGroup(nullptr);
660 else
661 player->SetGroup(nullptr);
662
663 // quest related GO state dependent from raid membership
665 }
666
667 // BG/BF groups stay locally owned in cluster mode (see the gates above),
668 // so their removal packets must not be delegated to the group service.
669 if (!sToCloud9Sidecar->ClusterModeEnabled() || isBGGroup() || isBFGroup())
670 {
671 WorldPacket data;
672
673 if (method == GROUP_REMOVEMETHOD_KICK || method == GROUP_REMOVEMETHOD_KICK_LFG)
674 {
676 player->GetSession()->SendPacket(&data);
677 }
678
679 // Do we really need to send this opcode?
680 data.Initialize(SMSG_GROUP_LIST, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 8);
681 data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
682 data << m_guid << uint32(m_counter) << uint32(0) << uint64(0);
683 player->GetSession()->SendPacket(&data);
684 }
685 }
686
687 // Remove player from group in DB
688 if (!isBGGroup() && !isBFGroup())
689 {
691 stmt->SetData(0, guid.GetCounter());
692 stmt->SetData(1, GetGUID().GetCounter());
693 CharacterDatabase.Execute(stmt);
694 }
695
696 // Remove player from loot rolls
698
699 // Update subgroups
701 if (slot != m_memberSlots.end())
702 {
703 SubGroupCounterDecrease(slot->group);
704 m_memberSlots.erase(slot);
705
706 if (!isBGGroup() && !isBFGroup())
707 {
708 sCharacterCache->ClearCharacterGroup(guid);
709 }
710 }
711
712 // Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
713 if (!player || player->GetSkillValue(SKILL_ENCHANTING))
714 {
716 }
717
718 // Pick new leader if necessary
719 bool validLeader = true;
720 if (m_leaderGuid == guid)
721 {
722 validLeader = false;
723 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
724 {
726 {
727 ChangeLeader(itr->guid);
728 validLeader = true;
729 break;
730 }
731 }
732 }
733
734 _homebindIfInstance(player);
735 if (!isBGGroup() && !isBFGroup())
737
738 sScriptMgr->OnGroupRemoveMember(this, guid, method, kicker, reason);
739
740 SendUpdate();
741
742 if (!validLeader)
743 {
744 // pussywizard: temp do nothing, something causes crashes in MakeNewGroup
745 //Disband();
746 //return false;
747 }
748
749 if (isLFGGroup() && GetMembersCount() == 1)
750 {
752 uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID());
753 lfg::LfgState state = sLFGMgr->GetState(GetGUID());
754 if (!mapId || !leader || (leader->IsAlive() && leader->GetMapId() != mapId) || state == lfg::LFG_STATE_NONE)
755 {
756 Disband();
757 return false;
758 }
759 }
760
761 if (m_memberMgr.getSize() < ((isLFGGroup() || isBGGroup() || isBFGroup()) ? 1u : 2u))
762 {
763 Disband();
764 return false;
765 }
766
767 return true;
768 }
769 // If group size before player removal <= 2 then disband it
770 else
771 {
772 sScriptMgr->OnGroupRemoveMember(this, guid, method, kicker, reason);
773 Disband();
774 return false;
775 }
776}
@ GROUP_REMOVEMETHOD_KICK_LFG
Definition SharedDefines.h:3846
@ GROUP_REMOVEMETHOD_KICK
Definition SharedDefines.h:3844
void BroadcastGroupUpdate(void)
Definition Group.cpp:2418
void Disband(bool hideDestroy=false)
Definition Group.cpp:915
void ResetMaxEnchantingLevel()
Definition Group.cpp:2434
void ChangeLeader(ObjectGuid guid)
Definition Group.cpp:778
void RemovePlayerFromRolls(ObjectGuid guid)
Definition Group.cpp:1572
uint32 getSize() const
Definition LinkedList.h:115
bool IsAlive() const
Definition Unit.h:1796
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition WorldSession.cpp:308
@ SMSG_GROUP_UNINVITE
Definition Opcodes.h:149

References _getMemberWSlot(), _homebindIfInstance(), BroadcastGroupUpdate(), ChangeLeader(), CHAR_DEL_GROUP_MEMBER, CharacterDatabase, Disband(), ObjectAccessor::FindConnectedPlayer(), ObjectGuid::GetCounter(), GetGUID(), GetLeaderGUID(), WorldLocation::GetMapId(), GetMembersCount(), Player::GetOriginalGroup(), Player::GetSession(), LinkedListHead::getSize(), Player::GetSkillValue(), GROUP_REMOVEMETHOD_KICK, GROUP_REMOVEMETHOD_KICK_LFG, WorldPacket::Initialize(), INSTANCE_RESET_GROUP_LEAVE, Unit::IsAlive(), isBFGroup(), isBGGroup(), isLFGGroup(), lfg::LFG_STATE_NONE, m_counter, m_guid, m_leaderGuid, m_memberMgr, m_memberSlots, Player::RemoveFromBattlegroundOrBattlefieldRaid(), RemovePlayerFromRolls(), Player::ResetInstances(), ResetMaxEnchantingLevel(), sCharacterCache, WorldSession::SendPacket(), SendUpdate(), PreparedStatementBase::SetData(), Player::SetGroup(), Player::SetOriginalGroup(), SKILL_ENCHANTING, sLFGMgr, SMSG_GROUP_LIST, SMSG_GROUP_UNINVITE, sScriptMgr, sToCloud9Sidecar, SubGroupCounterDecrease(), and Player::UpdateForQuestWorldObjects().

Referenced by group_commandscript::HandleGroupRemoveCommand(), lfg::LFGMgr::MakeNewGroup(), and Player::RemoveFromGroup().

◆ RemovePlayerFromRolls()

void Group::RemovePlayerFromRolls ( ObjectGuid  guid)
1573{
1574 for (Rolls::iterator it = RollId.begin(); it != RollId.end();)
1575 {
1576 Roll* roll = *it;
1577 Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid);
1578 if (itr2 == roll->playerVote.end())
1579 {
1580 ++it;
1581 continue;
1582 }
1583
1584 if (itr2->second == GREED || itr2->second == DISENCHANT)
1585 --roll->totalGreed;
1586 else if (itr2->second == NEED)
1587 --roll->totalNeed;
1588 else if (itr2->second == PASS)
1589 --roll->totalPass;
1590
1591 if (itr2->second != NOT_VALID)
1592 --roll->totalPlayersRolling;
1593
1594 roll->playerVote.erase(itr2);
1595
1596 if (CountRollVote(guid, roll->itemGUID, MAX_ROLL_TYPE))
1597 it = RollId.begin();
1598 else
1599 ++it;
1600 }
1601}
@ MAX_ROLL_TYPE
Definition LootMgr.h:37
bool CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choise)
Definition Group.cpp:1496

References CountRollVote(), DISENCHANT, GREED, Roll::itemGUID, MAX_ROLL_TYPE, NEED, NOT_VALID, PASS, Roll::playerVote, RollId, Roll::totalGreed, Roll::totalNeed, Roll::totalPass, and Roll::totalPlayersRolling.

Referenced by RemoveMember().

◆ RemoveUniqueGroupMemberFlag()

void Group::RemoveUniqueGroupMemberFlag ( GroupMemberFlags  flag)
2737{
2738 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2739 if (itr->flags & flag)
2740 itr->flags &= ~flag;
2741}

References m_memberSlots.

Referenced by WorldSession::HandlePartyAssignmentOpcode(), and SetGroupMemberFlag().

◆ ResetInstances()

void Group::ResetInstances ( uint8  method,
bool  isRaid,
Player *  leader 
)
2335{
2336 if (isBGGroup() || isBFGroup() || isLFGGroup())
2337 return;
2338
2339 switch (method)
2340 {
2341 case INSTANCE_RESET_ALL:
2342 {
2343 if (leader->GetDifficulty(false) != DUNGEON_DIFFICULTY_NORMAL)
2344 break;
2345 std::vector<InstanceSave*> toUnbind;
2346 BoundInstancesMap const& m_boundInstances = sInstanceSaveMgr->PlayerGetBoundInstances(leader->GetGUID(), Difficulty(DUNGEON_DIFFICULTY_NORMAL));
2347 for (BoundInstancesMap::const_iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end(); ++itr)
2348 {
2349 InstanceSave* instanceSave = itr->second.save;
2350 MapEntry const* entry = sMapStore.LookupEntry(itr->first);
2351 if (!entry || entry->IsRaid() || !instanceSave->CanReset())
2352 continue;
2353
2354 Map* map = sMapMgr->FindMap(instanceSave->GetMapId(), instanceSave->GetInstanceId());
2355 if (!map || map->ToInstanceMap()->Reset(method))
2356 {
2357 leader->SendResetInstanceSuccess(instanceSave->GetMapId());
2358 toUnbind.push_back(instanceSave);
2359 }
2360 else
2361 {
2362 leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId());
2363 }
2364
2365 sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
2366 }
2367 for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
2368 sInstanceSaveMgr->UnbindAllFor(*itr);
2369 }
2370 break;
2372 {
2373 std::vector<InstanceSave*> toUnbind;
2374 BoundInstancesMap const& m_boundInstances = sInstanceSaveMgr->PlayerGetBoundInstances(leader->GetGUID(), leader->GetDifficulty(isRaid));
2375 for (BoundInstancesMap::const_iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end(); ++itr)
2376 {
2377 InstanceSave* instanceSave = itr->second.save;
2378 MapEntry const* entry = sMapStore.LookupEntry(itr->first);
2379 if (!entry || entry->IsRaid() != isRaid || !instanceSave->CanReset())
2380 continue;
2381
2382 Map* map = sMapMgr->FindMap(instanceSave->GetMapId(), instanceSave->GetInstanceId());
2383 if (!map || map->ToInstanceMap()->Reset(method))
2384 {
2385 leader->SendResetInstanceSuccess(instanceSave->GetMapId());
2386 toUnbind.push_back(instanceSave);
2387 }
2388 else
2389 {
2390 leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId());
2391 }
2392
2393 sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
2394 }
2395 for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
2396 sInstanceSaveMgr->UnbindAllFor(*itr);
2397 }
2398 break;
2399 }
2400}
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
Definition InstanceSaveMgr.h:47
#define sMapMgr
Definition MapMgr.h:220
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition Map.h:717
@ INSTANCE_RESET_ALL
Definition Map.h:716
@ INSTANCE_RESET_FAILED
Definition Player.h:799
bool Reset(uint8 method, GuidList *globalSkipList=nullptr)
Definition Map.cpp:2233
Definition InstanceSaveMgr.h:57
uint32 GetMapId() const
Definition InstanceSaveMgr.h:63
bool CanReset() const
Definition InstanceSaveMgr.h:82
Definition Map.h:168
InstanceMap * ToInstanceMap()
Definition Map.h:390
void SendResetInstanceFailed(InstanceResetFailureReason reason, uint32 MapId)
Definition PlayerMisc.cpp:331
void SendResetInstanceSuccess(uint32 MapId)
Definition PlayerMisc.cpp:324
Definition DBCStructure.h:1361
bool IsRaid() const
Definition DBCStructure.h:1390

References InstanceSave::CanReset(), DUNGEON_DIFFICULTY_NORMAL, Player::GetDifficulty(), Object::GetGUID(), InstanceSave::GetInstanceId(), InstanceSave::GetMapId(), INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_FAILED, isBFGroup(), isBGGroup(), isLFGGroup(), MapEntry::IsRaid(), InstanceMap::Reset(), Player::SendResetInstanceFailed(), Player::SendResetInstanceSuccess(), sInstanceSaveMgr, sMapMgr, sMapStore, and Map::ToInstanceMap().

Referenced by WorldSession::HandleSetDungeonDifficultyOpcode(), and WorldSession::HandleSetRaidDifficultyOpcode().

◆ ResetMaxEnchantingLevel()

void Group::ResetMaxEnchantingLevel ( )
2435{
2437 Player* pMember = nullptr;
2438 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
2439 {
2440 pMember = ObjectAccessor::FindPlayer(citr->guid);
2441 if (pMember && pMember->GetSession() && !pMember->GetSession()->IsSocketClosed()
2442 && m_maxEnchantingLevel < pMember->GetSkillValue(SKILL_ENCHANTING))
2443 {
2445 }
2446 }
2447}
bool IsSocketClosed() const
Definition WorldSession.cpp:639

References ObjectAccessor::FindPlayer(), Player::GetSession(), Player::GetSkillValue(), WorldSession::IsSocketClosed(), m_maxEnchantingLevel, m_memberSlots, and SKILL_ENCHANTING.

Referenced by WorldSession::LogoutPlayer(), and RemoveMember().

◆ SameSubGroup() [1/3]

bool Group::SameSubGroup ( ObjectGuid  guid1,
MemberSlot const *  slot2 
) const
2591{
2592 member_citerator mslot1 = _getMemberCSlot(guid1);
2593 if (mslot1 == m_memberSlots.end() || !slot2)
2594 return false;
2595 return (mslot1->group == slot2->group);
2596}

References _getMemberCSlot(), Group::MemberSlot::group, and m_memberSlots.

◆ SameSubGroup() [2/3]

bool Group::SameSubGroup ( ObjectGuid  guid1,
ObjectGuid  guid2 
) const
2583{
2584 member_citerator mslot2 = _getMemberCSlot(guid2);
2585 if (mslot2 == m_memberSlots.end())
2586 return false;
2587 return SameSubGroup(guid1, &*mslot2);
2588}
bool SameSubGroup(ObjectGuid guid1, ObjectGuid guid2) const
Definition Group.cpp:2582

References _getMemberCSlot(), m_memberSlots, and SameSubGroup().

Referenced by Player::IsInSameGroupWith(), SameSubGroup(), and PetAI::UpdateAllies().

◆ SameSubGroup() [3/3]

bool Group::SameSubGroup ( Player const *  member1,
Player const *  member2 
) const
2009{
2010 if (!member1 || !member2)
2011 return false;
2012
2013 if (member1->GetGroup() != this || member2->GetGroup() != this)
2014 return false;
2015 else
2016 return member1->GetSubGroup() == member2->GetSubGroup();
2017}

References Player::GetGroup(), and Player::GetSubGroup().

◆ SendLootAllPassed()

void Group::SendLootAllPassed ( Roll const &  roll)
1065{
1066 WorldPacket data(SMSG_LOOT_ALL_PASSED, (8 + 4 + 4 + 4 + 4));
1067 data << roll.itemGUID; // Guid of the item rolled
1068 data << uint32(roll.itemSlot); // Item loot slot
1069 data << uint32(roll.itemid); // The itemEntryId for the item that shall be rolled for
1070 data << uint32(roll.itemRandomPropId); // Item random property ID
1071 data << uint32(roll.itemRandomSuffix); // Item random suffix ID
1072
1073 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
1074 {
1075 Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
1076 if (!player)
1077 continue;
1078
1079 if (itr->second != NOT_VALID)
1080 player->SendDirectMessage(&data);
1081 }
1082}
@ SMSG_LOOT_ALL_PASSED
Definition Opcodes.h:700

References ObjectAccessor::FindConnectedPlayer(), Roll::itemGUID, Roll::itemid, Roll::itemRandomPropId, Roll::itemRandomSuffix, Roll::itemSlot, NOT_VALID, Roll::playerVote, Player::SendDirectMessage(), and SMSG_LOOT_ALL_PASSED.

Referenced by CountTheRoll().

◆ SendLooter()

void Group::SendLooter ( Creature *  creature,
Player *  pLooter 
)
1086{
1087 ASSERT(creature);
1088
1089 WorldPacket data(SMSG_LOOT_LIST, (8 + 8));
1090 data << creature->GetGUID();
1091
1092 if (GetLootMethod() == MASTER_LOOT && creature->loot.hasOverThresholdItem())
1094 else
1095 data << uint8(0);
1096
1097 if (groupLooter)
1098 data << groupLooter->GetPackGUID();
1099 else
1100 data << uint8(0);
1101
1102 BroadcastPacket(&data, false);
1103}
@ MASTER_LOOT
Definition LootMgr.h:60
Loot loot
Definition Creature.h:231
ObjectGuid GetMasterLooterGuid() const
Definition Group.cpp:2545
LootMethod GetLootMethod() const
Definition Group.cpp:2535
PackedGuid WriteAsPacked() const
Definition ObjectGuid.h:325
@ SMSG_LOOT_LIST
Definition Opcodes.h:1047
bool hasOverThresholdItem() const
Definition LootMgr.cpp:952

References ASSERT, BroadcastPacket(), Object::GetGUID(), GetLootMethod(), GetMasterLooterGuid(), Object::GetPackGUID(), Loot::hasOverThresholdItem(), Creature::loot, MASTER_LOOT, SMSG_LOOT_LIST, and ObjectGuid::WriteAsPacked().

Referenced by Unit::Kill().

◆ SendLootRoll()

void Group::SendLootRoll ( ObjectGuid  SourceGuid,
ObjectGuid  TargetGuid,
uint8  RollNumber,
uint8  RollType,
Roll const &  r,
bool  autoPass = false 
)
1018{
1019 WorldPacket data(SMSG_LOOT_ROLL, (8 + 4 + 8 + 4 + 4 + 4 + 1 + 1 + 1));
1020 data << sourceGuid; // guid of the item rolled
1021 data << uint32(roll.itemSlot); // slot
1022 data << targetGuid;
1023 data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
1024 data << uint32(roll.itemRandomSuffix); // randomSuffix
1025 data << uint32(roll.itemRandomPropId); // Item random property ID
1026 data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
1027 data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
1028 data << uint8(autoPass); // 1: "You automatically passed on: %s because you cannot loot that item."
1029
1030 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
1031 {
1033 if (!p)
1034 continue;
1035
1036 if (itr->second != NOT_VALID)
1037 p->SendDirectMessage(&data);
1038 }
1039}
@ SMSG_LOOT_ROLL
Definition Opcodes.h:704

References ObjectAccessor::FindConnectedPlayer(), Roll::itemid, Roll::itemRandomPropId, Roll::itemRandomSuffix, Roll::itemSlot, NOT_VALID, Roll::playerVote, Player::SendDirectMessage(), and SMSG_LOOT_ROLL.

Referenced by CountRollVote(), CountTheRoll(), EndRoll(), GroupLoot(), and NeedBeforeGreed().

◆ SendLootRollWon()

void Group::SendLootRollWon ( ObjectGuid  SourceGuid,
ObjectGuid  TargetGuid,
uint8  RollNumber,
uint8  RollType,
Roll const &  r 
)
1042{
1043 WorldPacket data(SMSG_LOOT_ROLL_WON, (8 + 4 + 4 + 4 + 4 + 8 + 1 + 1));
1044 data << sourceGuid; // guid of the item rolled
1045 data << uint32(roll.itemSlot); // slot
1046 data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
1047 data << uint32(roll.itemRandomSuffix); // randomSuffix
1048 data << uint32(roll.itemRandomPropId); // Item random property
1049 data << targetGuid; // guid of the player who won.
1050 data << uint8(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
1051 data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL
1052
1053 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
1054 {
1056 if (!p)
1057 continue;
1058
1059 if (itr->second != NOT_VALID)
1060 p->SendDirectMessage(&data);
1061 }
1062}
@ SMSG_LOOT_ROLL_WON
Definition Opcodes.h:701

References ObjectAccessor::FindConnectedPlayer(), Roll::itemid, Roll::itemRandomPropId, Roll::itemRandomSuffix, Roll::itemSlot, NOT_VALID, Roll::playerVote, Player::SendDirectMessage(), and SMSG_LOOT_ROLL_WON.

Referenced by CountTheRoll().

◆ SendLootStartRoll()

void Group::SendLootStartRoll ( uint32  CountDown,
uint32  mapid,
Roll const &  r 
)
928{
929 WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
930 data << r.itemGUID; // guid of rolled item
931 data << uint32(mapid); // 3.3.3 mapid
932 data << uint32(r.itemSlot); // itemslot
933 data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
934 data << uint32(r.itemRandomSuffix); // randomSuffix
935 data << uint32(r.itemRandomPropId); // item random property ID
936 data << uint32(r.itemCount); // items in stack
937 data << uint32(CountDown); // the countdown time to choose "need" or "greed"
938 data << uint8(r.rollVoteMask); // roll type mask
939
940 for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
941 {
943 if (!p)
944 continue;
945
946 if (itr->second == NOT_EMITED_YET)
947 p->SendDirectMessage(&data);
948 }
949}
@ SMSG_LOOT_START_ROLL
Definition Opcodes.h:703

References ObjectAccessor::FindConnectedPlayer(), Roll::itemCount, Roll::itemGUID, Roll::itemid, Roll::itemRandomPropId, Roll::itemRandomSuffix, Roll::itemSlot, NOT_EMITED_YET, Roll::playerVote, Roll::rollVoteMask, Player::SendDirectMessage(), and SMSG_LOOT_START_ROLL.

Referenced by GroupLoot().

◆ SendLootStartRollToPlayer()

void Group::SendLootStartRollToPlayer ( uint32  countDown,
uint32  mapId,
Player *  p,
bool  canNeed,
Roll const &  r 
)
996{
997 if (!p)
998 return;
999
1000 WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
1001 data << r.itemGUID; // guid of rolled item
1002 data << uint32(mapId); // 3.3.3 mapid
1003 data << uint32(r.itemSlot); // itemslot
1004 data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
1005 data << uint32(r.itemRandomSuffix); // randomSuffix
1006 data << uint32(r.itemRandomPropId); // item random property ID
1007 data << uint32(r.itemCount); // items in stack
1008 data << uint32(countDown); // the countdown time to choose "need" or "greed"
1009 uint8 voteMask = r.rollVoteMask;
1010 if (!canNeed)
1011 voteMask &= ~ROLL_FLAG_TYPE_NEED;
1012 data << uint8(voteMask); // roll type mask
1013
1014 p->SendDirectMessage(&data);
1015}

References Roll::itemCount, Roll::itemGUID, Roll::itemid, Roll::itemRandomPropId, Roll::itemRandomSuffix, Roll::itemSlot, Roll::rollVoteMask, Player::SendDirectMessage(), and SMSG_LOOT_START_ROLL.

Referenced by NeedBeforeGreed(), and SendPendingRollsToPlayer().

◆ SendPendingRollsToPlayer()

void Group::SendPendingRollsToPlayer ( Player *  player,
Map *  map 
)
952{
953 for (Roll* roll : RollId)
954 {
955 auto itr = roll->playerVote.find(player->GetGUID());
956 if (itr == roll->playerVote.end())
957 continue;
958
959 if (itr->second != NOT_EMITED_YET)
960 continue;
961
962 Loot* loot = roll->getLoot();
963 if (!loot)
964 continue;
965
966 // Get remaining time from the loot source object
967 uint32 remainingTime = 60000;
968 WorldObject* lootedObject = nullptr;
969 if (GameObject* go = loot->sourceGameObject)
970 {
971 remainingTime = go->m_groupLootTimer;
972 lootedObject = go;
973 }
974 else if (!loot->sourceWorldObjectGUID.IsEmpty())
975 {
976 if (Creature* creature = map->GetCreature(loot->sourceWorldObjectGUID))
977 {
978 remainingTime = creature->m_groupLootTimer;
979 lootedObject = creature;
980 }
981 }
982
983 bool canNeed = true;
985 {
986 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(roll->itemid);
987 if (proto && lootedObject)
988 canNeed = (player->CanRollForItemInLFG(proto, lootedObject) == EQUIP_ERR_OK);
989 }
990
991 SendLootStartRollToPlayer(remainingTime, map->GetId(), player, canNeed, *roll);
992 }
993}
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2442
bool IsEmpty() const
Definition ObjectGuid.h:165
Definition Object.h:482
ObjectGuid sourceWorldObjectGUID
Definition LootMgr.h:330

References Player::CanRollForItemInLFG(), EQUIP_ERR_OK, Map::GetCreature(), Object::GetGUID(), Map::GetId(), GetLootMethod(), ObjectGuid::IsEmpty(), NEED_BEFORE_GREED, NOT_EMITED_YET, RollId, SendLootStartRollToPlayer(), sObjectMgr, Loot::sourceGameObject, and Loot::sourceWorldObjectGUID.

◆ SendTargetIconList()

void Group::SendTargetIconList ( WorldSession *  session)
1852{
1853 if (!session)
1854 return;
1855
1857 data << uint8(1); // list targets
1858
1859 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
1860 {
1861 if (!m_targetIcons[i])
1862 continue;
1863
1864 data << uint8(i);
1865 data << m_targetIcons[i];
1866 }
1867
1868 session->SendPacket(&data);
1869}
@ MSG_RAID_TARGET_UPDATE
Definition Opcodes.h:831

References m_targetIcons, MSG_RAID_TARGET_UPDATE, WorldSession::SendPacket(), and TARGETICONCOUNT.

Referenced by WorldSession::HandleRaidTargetUpdateOpcode().

◆ SendUpdate()

void Group::SendUpdate ( )
1872{
1873 if (sToCloud9Sidecar->ClusterModeEnabled() && !this->isBFGroup() && !this->isBGGroup())
1874 {
1875 // Group service responsible for sending these updates.
1876 return;
1877 }
1878
1879 for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr)
1880 SendUpdateToPlayer(witr->guid, &(*witr));
1881}
void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot *slot=nullptr)
Definition Group.cpp:1883

References m_memberSlots, SendUpdateToPlayer(), and sToCloud9Sidecar.

Referenced by AddMember(), Battleground::AddOrSetPlayerToCorrectBgGroup(), ChangeMembersGroup(), ConvertToLFG(), ConvertToRaid(), WorldSession::HandleGroupAssistantLeaderOpcode(), group_commandscript::HandleGroupLeaderCommand(), WorldSession::HandleGroupSetLeaderOpcode(), WorldSession::HandleLootMethodOpcode(), WorldSession::HandlePartyAssignmentOpcode(), WorldSession::LogoutPlayer(), lfg::LFGMgr::MakeNewGroup(), RemoveMember(), SetGroupMemberFlag(), SetLfgRoles(), and UpdateLooterGuid().

◆ SendUpdateToPlayer()

void Group::SendUpdateToPlayer ( ObjectGuid  playerGUID,
MemberSlot *  slot = nullptr 
)
1884{
1885 Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID);
1886
1887 if (!player || player->GetGroup() != this)
1888 return;
1889
1890 // if MemberSlot wasn't provided
1891 if (!slot)
1892 {
1893 member_witerator witr = _getMemberWSlot(playerGUID);
1894
1895 if (witr == m_memberSlots.end()) // if there is no MemberSlot for such a player
1896 return;
1897
1898 slot = &(*witr);
1899 }
1900
1901 WorldPacket data(SMSG_GROUP_LIST, (1 + 1 + 1 + 1 + 1 + 4 + 8 + 4 + 4 + (GetMembersCount() - 1) * (13 + 8 + 1 + 1 + 1 + 1) + 8 + 1 + 8 + 1 + 1 + 1 + 1));
1902 data << uint8(m_groupType); // group type (flags in 3.3)
1903 data << uint8(slot->group);
1904 data << uint8(slot->flags);
1905 data << uint8(slot->roles);
1906 if (isLFGGroup())
1907 {
1908 data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done
1909 data << uint32(sLFGMgr->GetDungeon(m_guid));
1910 }
1911
1912 data << m_guid;
1913 data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent
1914 data << uint32(GetMembersCount() - 1);
1915 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1916 {
1917 if (slot->guid == citr->guid)
1918 continue;
1919
1920 Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid);
1921
1922 uint8 onlineState = (member && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
1923 onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0);
1924
1925 data << citr->name;
1926 data << citr->guid; // guid
1927 data << uint8(onlineState); // online-state
1928 data << uint8(citr->group); // groupid
1929 data << uint8(citr->flags); // See enum GroupMemberFlags
1930 data << uint8(citr->roles); // Lfg Roles
1931 }
1932
1933 data << m_leaderGuid; // leader guid
1934
1935 if (GetMembersCount() - 1)
1936 {
1937 data << uint8(m_lootMethod); // loot method
1938
1940 data << m_masterLooterGuid; // master looter guid
1941 else
1942 data << uint64(0); // looter guid
1943
1944 data << uint8(m_lootThreshold); // loot threshold
1945 data << uint8(m_dungeonDifficulty); // Dungeon Difficulty
1946 data << uint8(m_raidDifficulty); // Raid Difficulty
1947 data << uint8(m_raidDifficulty >= RAID_DIFFICULTY_10MAN_HEROIC); // 3.3 Dynamic Raid Difficulty - 0 normal/1 heroic
1948 }
1949
1950 player->SendDirectMessage(&data);
1951}
@ RAID_DIFFICULTY_10MAN_HEROIC
Definition DBCEnums.h:275
@ MEMBER_STATUS_OFFLINE
Definition Group.h:61
@ MEMBER_STATUS_PVP
Definition Group.h:63
@ MEMBER_STATUS_ONLINE
Definition Group.h:62
bool PlayerLogout() const
Definition WorldSession.h:451
@ LFG_STATE_FINISHED_DUNGEON
Definition LFG.h:74

References _getMemberWSlot(), ObjectAccessor::FindConnectedPlayer(), Group::MemberSlot::flags, Player::GetGroup(), GetMembersCount(), Player::GetSession(), Group::MemberSlot::group, Group::MemberSlot::guid, isBFGroup(), isBGGroup(), isLFGGroup(), lfg::LFG_STATE_FINISHED_DUNGEON, m_counter, m_dungeonDifficulty, m_groupType, m_guid, m_leaderGuid, m_lootMethod, m_lootThreshold, m_masterLooterGuid, m_memberSlots, m_raidDifficulty, MASTER_LOOT, MEMBER_STATUS_OFFLINE, MEMBER_STATUS_ONLINE, MEMBER_STATUS_PVP, WorldSession::PlayerLogout(), RAID_DIFFICULTY_10MAN_HEROIC, Group::MemberSlot::roles, Player::SendDirectMessage(), sLFGMgr, and SMSG_GROUP_LIST.

Referenced by SendUpdate().

◆ SetBattlefieldGroup()

void Group::SetBattlefieldGroup ( Battlefield *  bf)
2617{
2618 m_bfGroup = bg;
2619}

References m_bfGroup.

Referenced by Battlefield::AddOrSetPlayerToCorrectBfGroup().

◆ SetBattlegroundGroup()

void Group::SetBattlegroundGroup ( Battleground *  bg)
2612{
2613 m_bgGroup = bg;
2614}

References m_bgGroup.

Referenced by Battleground::SetBgRaid().

◆ SetDifficultyChangePrevention()

◆ SetDungeonDifficulty()

void Group::SetDungeonDifficulty ( Difficulty  difficulty)
2293{
2294 m_dungeonDifficulty = difficulty;
2295 if (!sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup())
2296 {
2298
2300 stmt->SetData(1, GetGUID().GetCounter());
2301
2302 CharacterDatabase.Execute(stmt);
2303 }
2304
2305 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
2306 {
2307 Player* player = itr->GetSource();
2308 player->SetDungeonDifficulty(difficulty);
2309 player->SendDungeonDifficulty(true);
2310 }
2311}
@ CHAR_UPD_GROUP_DIFFICULTY
Definition CharacterDatabase.h:293

References CHAR_UPD_GROUP_DIFFICULTY, CharacterDatabase, GetFirstMember(), GetGUID(), isBFGroup(), isBGGroup(), m_dungeonDifficulty, GroupReference::next(), Player::SendDungeonDifficulty(), PreparedStatementBase::SetData(), Player::SetDungeonDifficulty(), and sToCloud9Sidecar.

Referenced by WorldSession::HandleSetDungeonDifficultyOpcode(), and lfg::LFGMgr::MakeNewGroup().

◆ SetGroupMemberFlag()

void Group::SetGroupMemberFlag ( ObjectGuid  guid,
bool  apply,
GroupMemberFlags  flag 
)
2622{
2623 // Assistants, main assistants and main tanks are only available in raid groups
2624 if (!isRaidGroup())
2625 return;
2626
2627 // Check if player is really in the raid
2628 member_witerator slot = _getMemberWSlot(guid);
2629 if (slot == m_memberSlots.end())
2630 return;
2631
2632 // Do flag specific actions, e.g ensure uniqueness
2633 switch (flag)
2634 {
2636 RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); // Remove main assist flag from current if any.
2637 break;
2639 RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main tank flag from current if any.
2640 break;
2642 break;
2643 default:
2644 return; // This should never happen
2645 }
2646
2647 // Switch the actual flag
2648 ToggleGroupMemberFlag(slot, flag, apply);
2649
2650 // Preserve the new setting in the db
2652
2653 stmt->SetData(0, slot->flags);
2654 stmt->SetData(1, guid.GetCounter());
2655
2656 CharacterDatabase.Execute(stmt);
2657
2658 // Broadcast the changes to the group
2659 SendUpdate();
2660}
@ CHAR_UPD_GROUP_MEMBER_FLAG
Definition CharacterDatabase.h:292
@ MEMBER_FLAG_MAINASSIST
Definition Group.h:76
@ MEMBER_FLAG_MAINTANK
Definition Group.h:75
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
Definition Group.cpp:2736

References _getMemberWSlot(), CHAR_UPD_GROUP_MEMBER_FLAG, CharacterDatabase, ObjectGuid::GetCounter(), isRaidGroup(), m_memberSlots, MEMBER_FLAG_ASSISTANT, MEMBER_FLAG_MAINASSIST, MEMBER_FLAG_MAINTANK, RemoveUniqueGroupMemberFlag(), SendUpdate(), PreparedStatementBase::SetData(), and ToggleGroupMemberFlag().

Referenced by WorldSession::HandleGroupAssistantLeaderOpcode(), and WorldSession::HandlePartyAssignmentOpcode().

◆ SetLfgRoles()

void Group::SetLfgRoles ( ObjectGuid  guid,
const uint8  roles 
)
2470{
2471 member_witerator slot = _getMemberWSlot(guid);
2472 if (slot == m_memberSlots.end())
2473 return;
2474
2475 slot->roles = roles;
2476 SendUpdate();
2477}

References _getMemberWSlot(), m_memberSlots, and SendUpdate().

Referenced by lfg::LFGMgr::MakeNewGroup().

◆ SetLooterGuid()

void Group::SetLooterGuid ( ObjectGuid  guid)
2455{
2456 m_looterGuid = guid;
2457}

References m_looterGuid.

Referenced by UpdateLooterGuid().

◆ SetLootMethod()

void Group::SetLootMethod ( LootMethod  method)
2450{
2451 m_lootMethod = method;
2452}

References m_lootMethod.

Referenced by WorldSession::HandleLootMethodOpcode().

◆ SetLootThreshold()

void Group::SetLootThreshold ( ItemQualities  threshold)
2465{
2466 m_lootThreshold = threshold;
2467}

References m_lootThreshold.

Referenced by WorldSession::HandleLootMethodOpcode().

◆ SetMasterLooterGuid()

void Group::SetMasterLooterGuid ( ObjectGuid  guid)
2460{
2461 m_masterLooterGuid = guid;
2462}

References m_masterLooterGuid.

Referenced by WorldSession::HandleLootMethodOpcode().

◆ SetRaidDifficulty()

void Group::SetRaidDifficulty ( Difficulty  difficulty)
2314{
2315 m_raidDifficulty = difficulty;
2316 if (!sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup())
2317 {
2319
2320 stmt->SetData(0, uint8(m_raidDifficulty));
2321 stmt->SetData(1, GetGUID().GetCounter());
2322
2323 CharacterDatabase.Execute(stmt);
2324 }
2325
2326 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
2327 {
2328 Player* player = itr->GetSource();
2329 player->SetRaidDifficulty(difficulty);
2330 player->SendRaidDifficulty(true);
2331 }
2332}
@ CHAR_UPD_GROUP_RAID_DIFFICULTY
Definition CharacterDatabase.h:294

References CHAR_UPD_GROUP_RAID_DIFFICULTY, CharacterDatabase, GetFirstMember(), GetGUID(), isBFGroup(), isBGGroup(), m_raidDifficulty, GroupReference::next(), Player::SendRaidDifficulty(), PreparedStatementBase::SetData(), Player::SetRaidDifficulty(), and sToCloud9Sidecar.

Referenced by WorldSession::HandleSetRaidDifficultyOpcode().

◆ SetTargetIcon()

void Group::SetTargetIcon ( uint8  id,
ObjectGuid  whoGuid,
ObjectGuid  targetGuid 
)
1831{
1832 if (id >= TARGETICONCOUNT)
1833 return;
1834
1835 // clean other icons
1836 if (targetGuid)
1837 for (int i = 0; i < TARGETICONCOUNT; ++i)
1838 if (m_targetIcons[i] == targetGuid)
1840
1841 m_targetIcons[id] = targetGuid;
1842
1843 WorldPacket data(MSG_RAID_TARGET_UPDATE, (1 + 8 + 1 + 8));
1844 data << uint8(0); // set targets
1845 data << whoGuid;
1846 data << uint8(id);
1847 data << targetGuid;
1848 BroadcastPacket(&data, true);
1849}
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid)
Definition Group.cpp:1830

References BroadcastPacket(), ObjectGuid::Empty, m_targetIcons, MSG_RAID_TARGET_UPDATE, SetTargetIcon(), and TARGETICONCOUNT.

Referenced by WorldSession::HandleRaidTargetUpdateOpcode(), and SetTargetIcon().

◆ SubGroupCounterDecrease()

void Group::SubGroupCounterDecrease ( uint8  subgroup)
protected
2731{
2733 --m_subGroupsCounts[subgroup];
2734}

References m_subGroupsCounts.

Referenced by ChangeMembersGroup(), and RemoveMember().

◆ SubGroupCounterIncrease()

void Group::SubGroupCounterIncrease ( uint8  subgroup)
protected
2725{
2727 ++m_subGroupsCounts[subgroup];
2728}

References m_subGroupsCounts.

Referenced by AddMember(), AddMemberWithGuid(), ChangeMembersGroup(), and LoadMemberFromDB().

◆ ToggleGroupMemberFlag()

void Group::ToggleGroupMemberFlag ( member_witerator  slot,
uint8  flag,
bool  apply 
)
protected
2744{
2745 if (apply)
2746 slot->flags |= flag;
2747 else
2748 slot->flags &= ~flag;
2749}

Referenced by ChangeLeader(), and SetGroupMemberFlag().

◆ UpdateLooterGuid()

void Group::UpdateLooterGuid ( WorldObject *  pLootedObject,
bool  ifneed = false 
)
2081{
2082 // round robin style looting applies for all low
2083 // quality items in each loot method except free for all
2084 if (GetLootMethod() == FREE_FOR_ALL)
2085 return;
2086
2087 ObjectGuid oldLooterGUID = GetLooterGuid();
2088 member_citerator guid_itr = _getMemberCSlot(oldLooterGUID);
2089 if (guid_itr != m_memberSlots.end())
2090 {
2091 if (ifneed)
2092 {
2093 // not update if only update if need and ok
2094 Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
2095 if (looter && looter->IsAtLootRewardDistance(pLootedObject))
2096 return;
2097 }
2098 ++guid_itr;
2099 }
2100
2101 // search next after current
2102 Player* pNewLooter = nullptr;
2103 for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr)
2104 {
2105 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
2106 if (player->IsAtLootRewardDistance(pLootedObject))
2107 {
2108 pNewLooter = player;
2109 break;
2110 }
2111 }
2112
2113 if (!pNewLooter)
2114 {
2115 // search from start
2116 for (member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr)
2117 {
2118 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
2119 if (player->IsAtLootRewardDistance(pLootedObject))
2120 {
2121 pNewLooter = player;
2122 break;
2123 }
2124 }
2125 }
2126
2127 if (pNewLooter)
2128 {
2129 if (oldLooterGUID != pNewLooter->GetGUID())
2130 {
2131 SetLooterGuid(pNewLooter->GetGUID());
2132 SendUpdate();
2133 }
2134 }
2135 else
2136 {
2138 SendUpdate();
2139 }
2140}
ObjectGuid GetLooterGuid() const
Definition Group.cpp:2540
void SetLooterGuid(ObjectGuid guid)
Definition Group.cpp:2454

References _getMemberCSlot(), ObjectGuid::Empty, ObjectAccessor::FindPlayer(), FREE_FOR_ALL, Object::GetGUID(), GetLooterGuid(), GetLootMethod(), Player::IsAtLootRewardDistance(), m_memberSlots, SendUpdate(), and SetLooterGuid().

Referenced by Unit::Kill(), and Player::SendLoot().

◆ UpdatePlayerOutOfRange()

void Group::UpdatePlayerOutOfRange ( Player *  player)
1954{
1955 if (!player || !player->IsInWorld())
1956 return;
1957
1958 WorldPacket data;
1959 player->GetSession()->BuildPartyMemberStatsChangedPacket(player, &data);
1960
1961 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1962 {
1963 Player* member = itr->GetSource();
1964 if (member && (!member->IsInMap(player) || !member->IsWithinDist(player, member->GetSightRange(player), false)))
1965 member->SendDirectMessage(&data);
1966 }
1967}
float GetSightRange(WorldObject const *target=nullptr) const override
Definition Player.cpp:16663
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1381
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:1344
void BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
Definition GroupHandler.cpp:817

References WorldSession::BuildPartyMemberStatsChangedPacket(), GetFirstMember(), Player::GetSession(), Player::GetSightRange(), WorldObject::IsInMap(), Object::IsInWorld(), WorldObject::IsWithinDist(), GroupReference::next(), and Player::SendDirectMessage().

Referenced by AddMember().

Friends And Related Symbol Documentation

◆ ToCloud9GroupHooks

friend class ToCloud9GroupHooks
friend

Member Data Documentation

◆ _difficultyChangePreventionTime

uint32 Group::_difficultyChangePreventionTime
protected

◆ _difficultyChangePreventionType

DifficultyPreventionChangeType Group::_difficultyChangePreventionType
protected

◆ CustomData

DataMap Group::CustomData

◆ m_bfGroup

Battlefield* Group::m_bfGroup
protected

Referenced by isBFGroup(), and SetBattlefieldGroup().

◆ m_bgGroup

Battleground* Group::m_bgGroup
protected

◆ m_counter

uint32 Group::m_counter
protected

◆ m_dungeonDifficulty

◆ m_groupType

◆ m_guid

◆ m_invitees

◆ m_leaderGuid

◆ m_leaderName

std::string Group::m_leaderName
protected

◆ m_lfgGroupFlags

◆ m_looterGuid

◆ m_lootMethod

◆ m_lootThreshold

◆ m_masterLooterGuid

◆ m_maxEnchantingLevel

uint32 Group::m_maxEnchantingLevel
protected

◆ m_memberMgr

GroupRefMgr Group::m_memberMgr
protected

◆ m_memberSlots

◆ m_raidDifficulty

◆ m_subGroupsCounts

◆ m_targetIcons

◆ RollId


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