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 ( )
123{
124 sScriptMgr->OnConstructGroup(this);
125}
@ 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:769
@ ITEM_QUALITY_UNCOMMON
Definition SharedDefines.h:319
uint32 m_counter
Definition Group.h:375
Battlefield * m_bfGroup
Definition Group.h:365
uint32 m_maxEnchantingLevel
Definition Group.h:376
DifficultyPreventionChangeType _difficultyChangePreventionType
Definition Group.h:381
std::string m_leaderName
Definition Group.h:361
Battleground * m_bgGroup
Definition Group.h:366
Difficulty m_raidDifficulty
Definition Group.h:364
LootMethod m_lootMethod
Definition Group.h:368
uint8 * m_subGroupsCounts
Definition Group.h:373
Difficulty m_dungeonDifficulty
Definition Group.h:363
ItemQualities m_lootThreshold
Definition Group.h:369
GroupType m_groupType
Definition Group.h:362
uint32 _difficultyChangePreventionTime
Definition Group.h:380

References sScriptMgr.

◆ ~Group()

Group::~Group ( )
128{
129 sScriptMgr->OnDestructGroup(this);
130
131 if (m_bgGroup)
132 {
133 LOG_DEBUG("bg.battleground", "Group::~Group: battleground group being deleted.");
134
135 if (m_bgGroup->GetBgRaid(TEAM_ALLIANCE) == this)
136 {
138 }
139 else if (m_bgGroup->GetBgRaid(TEAM_HORDE) == this)
140 {
141 m_bgGroup->SetBgRaid(TEAM_HORDE, nullptr);
142 }
143 else
144 LOG_ERROR("bg.battleground", "Group::~Group: battleground group is not linked to the correct battleground.");
145 }
146
147 Rolls::iterator itr;
148 while (!RollId.empty())
149 {
150 itr = RollId.begin();
151 Roll* r = *itr;
152 RollId.erase(itr);
153 delete(r);
154 }
155
156 // Sub group counters clean up
157 delete[] m_subGroupsCounts;
158}
#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:372
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
2432{
2433 // if player is reinvited to group and in the instance - cancel homebind timer
2434 if (!player->FindMap() || !player->FindMap()->IsDungeon())
2435 return;
2436 InstancePlayerBind* bind = sInstanceSaveMgr->PlayerGetBoundInstance(player->GetGUID(), player->FindMap()->GetId(), player->GetDifficulty(player->FindMap()->IsRaid()));
2437 if (bind && bind->save->GetInstanceId() == player->GetInstanceId())
2438 player->m_InstanceValid = true;
2439}
#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:2486
Difficulty GetDifficulty(bool isRaid) const
Definition Player.h:1949
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
2732{
2733 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2734 if (itr->guid == Guid)
2735 return itr;
2736 return m_memberSlots.end();
2737}
MemberSlotList m_memberSlots
Definition Group.h:357
MemberSlotList::const_iterator member_citerator
Definition Group.h:190

References m_memberSlots.

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

◆ _getMemberWSlot()

Group::member_witerator Group::_getMemberWSlot ( ObjectGuid  Guid)
protected
2740{
2741 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2742 if (itr->guid == Guid)
2743 return itr;
2744 return m_memberSlots.end();
2745}
MemberSlotList::iterator member_witerator
Definition Group.h:193

References m_memberSlots.

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

◆ _homebindIfInstance()

void Group::_homebindIfInstance ( Player *  player)
protected
2426{
2427 if (player && !player->IsGameMaster() && player->FindMap() && sMapStore.LookupEntry(player->GetMapId())->IsDungeon())
2428 player->m_InstanceValid = false;
2429}
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
2720{
2721 // Sub group counters initialization
2722 if (!m_subGroupsCounts)
2724
2725 memset((void*)m_subGroupsCounts, 0, (MAX_RAID_SUBGROUPS)*sizeof(uint8));
2726
2727 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2728 ++m_subGroupsCounts[itr->group];
2729}
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)
373{
374 if (!player || player->GetGroupInvite())
375 return false;
376 Group* group = player->GetGroup();
377 if (group && (group->isBGGroup() || group->isBFGroup()))
378 group = player->GetOriginalGroup();
379 if (group)
380 return false;
381
382 RemoveInvite(player);
383
384 m_invitees.insert(player);
385
386 player->SetGroupInvite(this);
387
388 sScriptMgr->OnGroupInviteMember(this, player->GetGUID());
389
390 return true;
391}
Definition Group.h:178
InvitesList m_invitees
Definition Group.h:359
void RemoveInvite(Player *player)
Definition Group.cpp:403
bool isBGGroup() const
Definition Group.cpp:2518
bool isBFGroup() const
Definition Group.cpp:2523
void SetGroupInvite(Group *group)
Definition Player.h:2517
Group * GetGroup()
Definition Player.h:2518
Group * GetGroupInvite()
Definition Player.h:2516
Group * GetOriginalGroup()
Definition Player.h:2533

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)
394{
395 if (!AddInvite(player))
396 return false;
397
398 m_leaderGuid = player->GetGUID();
399 m_leaderName = player->GetName();
400 return true;
401}
ObjectGuid m_leaderGuid
Definition Group.h:360
bool AddInvite(Player *player)
Definition Group.cpp:372
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:377

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 
)
445{
446 if (!player)
447 return false;
448
449 // Get first not-full group
450 uint8 subGroup = 0;
452 {
453 bool groupFound = false;
454 for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup)
455 {
456 if (m_subGroupsCounts[subGroup] < MAXGROUPSIZE)
457 {
458 groupFound = true;
459 break;
460 }
461 }
462 // We are raid group and no one slot is free
463 if (!groupFound)
464 return false;
465 }
466
467 MemberSlot member;
468 member.guid = player->GetGUID();
469 member.name = player->GetName();
470 member.group = subGroup;
471 member.flags = 0;
472 member.roles = roles;
473 m_memberSlots.push_back(member);
474
475 if (!isBGGroup() && !isBFGroup())
476 {
477 sCharacterCache->UpdateCharacterGroup(player->GetGUID(), GetGUID());
478 }
479
480 SubGroupCounterIncrease(subGroup);
481
482 // The inviting group keeps a raw Player* that would dangle once the player logs out
483 if (Group* invitingGroup = player->GetGroupInvite())
484 invitingGroup->RemoveInvite(player);
485
486 if (player->GetGroup())
487 {
488 if (isBGGroup() || isBFGroup()) // if player is in group and he is being added to BG raid group, then call SetBattlegroundRaid()
489 player->SetBattlegroundOrBattlefieldRaid(this, subGroup);
490 else //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
491 player->SetOriginalGroup(this, subGroup);
492 }
493 else //if player is not in group, then call set group
494 player->SetGroup(this, subGroup);
495
496 // if the same group invites the player back, cancel the homebind timer
498
499 if (!isRaidGroup()) // reset targetIcons for non-raid-groups
500 {
501 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
502 m_targetIcons[i].Clear();
503 }
504
505 if (!isBGGroup() && !isBFGroup())
506 {
508 stmt->SetData(0, GetGUID().GetCounter());
509 stmt->SetData(1, member.guid.GetCounter());
510 stmt->SetData(2, member.flags);
511 stmt->SetData(3, member.group);
512 stmt->SetData(4, member.roles);
513 CharacterDatabase.Execute(stmt);
514 }
515
516 SendUpdate();
517
518 if (player)
519 {
520 sScriptMgr->OnGroupAddMember(this, player->GetGUID());
521
522 if (!IsLeader(player->GetGUID()) && !isBGGroup() && !isBFGroup())
523 {
525
527 {
529 player->SendDungeonDifficulty(true);
530 }
531 if (player->GetRaidDifficulty() != GetRaidDifficulty())
532 {
534 player->SendRaidDifficulty(true);
535 }
536 }
537 else if (IsLeader(player->GetGUID()) && isLFGGroup()) // pussywizard
538 {
540 }
541
544
545 // quest related GO state dependent from raid membership
546 if (isRaidGroup())
548
549 {
550 // Broadcast new player group member fields to rest of the group
552
553 UpdateData groupData;
554 WorldPacket groupDataPacket;
555
556 // Broadcast group members' fields to player
557 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
558 {
559 if (itr->GetSource() == player) // pussywizard: no check same map, adding members is single threaded
560 {
561 continue;
562 }
563
564 if (Player* itrMember = itr->GetSource())
565 {
566 if (player->HaveAtClient(itrMember))
567 {
568 itrMember->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
569 itrMember->BuildValuesUpdateBlockForPlayer(&groupData, player);
570 itrMember->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
571 }
572
573 if (itrMember->HaveAtClient(player))
574 {
575 UpdateData newData;
576 WorldPacket newDataPacket;
577 player->BuildValuesUpdateBlockForPlayer(&newData, itrMember);
578 if (newData.HasData())
579 {
580 newData.BuildPacket(newDataPacket);
581 itrMember->SendDirectMessage(&newDataPacket);
582 }
583 }
584 }
585 }
586
587 if (groupData.HasData())
588 {
589 groupData.BuildPacket(groupDataPacket);
590 player->SendDirectMessage(&groupDataPacket);
591 }
592
594 }
595
596 if (m_maxEnchantingLevel < player->GetSkillValue(SKILL_ENCHANTING))
598 }
599
600 return true;
601}
#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:722
@ 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:2507
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:2583
void SendUpdate()
Definition Group.cpp:1894
ObjectGuid GetGUID() const
Definition Group.cpp:2548
void _cancelHomebindIfInstance(Player *player)
Definition Group.cpp:2431
Difficulty GetRaidDifficulty() const
Definition Group.cpp:2695
ObjectGuid m_targetIcons[TARGETICONCOUNT]
Definition Group.h:367
void UpdatePlayerOutOfRange(Player *player)
Definition Group.cpp:1976
GroupReference * GetFirstMember()
Definition Group.h:253
void SubGroupCounterIncrease(uint8 subgroup)
Definition Group.cpp:2747
Difficulty GetDungeonDifficulty() const
Definition Group.cpp:2690
bool isRaidGroup() const
Definition Group.cpp:2513
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:1951
void SetOriginalGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:13499
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2524
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5886
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5644
void SetDungeonDifficulty(Difficulty dungeon_difficulty)
Definition Player.h:1953
void SetGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:11770
bool HaveAtClient(WorldObject const *u) const
Definition Player.cpp:11617
void UpdateForQuestWorldObjects()
Definition PlayerUpdates.cpp:1814
void SetRaidDifficulty(Difficulty raid_difficulty)
Definition Player.h:1954
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:1950
void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty=-1)
Definition PlayerMisc.cpp:177
void SetBattlegroundOrBattlefieldRaid(Group *group, int8 subgroup=-1)
Definition Player.cpp:13471
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(), Player::GetGroupInvite(), 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::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
604{
605 // Idempotent under sidecar event redelivery: never duplicate a MemberSlot.
606 if (IsMember(guid))
607 return;
608
609 if (Player* player = ObjectAccessor::FindPlayer(guid))
610 {
611 AddMember(player);
612 return;
613 }
614
615 // Get first not-full group
616 uint8 subGroup = 0;
618 {
619 bool groupFound = false;
620 for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup)
621 {
622 if (m_subGroupsCounts[subGroup] < MAXGROUPSIZE)
623 {
624 groupFound = true;
625 break;
626 }
627 }
628 // We are raid group and no one slot is free
629 if (!groupFound)
630 return;
631 }
632
633 MemberSlot member;
634 member.guid = guid;
635 sCharacterCache->GetCharacterNameByGuid(guid, member.name);
636 member.group = subGroup;
637 member.flags = 0;
638 member.roles = 0;
639 m_memberSlots.push_back(member);
640
641 if (!isBGGroup() && !isBFGroup())
642 {
643 sCharacterCache->UpdateCharacterGroup(guid, GetGUID());
644 }
645
646 SubGroupCounterIncrease(subGroup);
647}
bool AddMember(Player *player, uint8 roles=0)
Definition Group.cpp:444
bool IsMember(ObjectGuid guid) const
Definition Group.cpp:2578
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  )
2442{
2443 // FG: HACK: force flags update on group leave - for values update hack
2444 // -- not very efficient but safe
2445 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
2446 {
2447 Player* pp = ObjectAccessor::FindPlayer(citr->guid);
2448 if (pp)
2449 {
2452 LOG_DEBUG("group", "-- Forced group value update for '{}'", pp->GetName());
2453 }
2454 }
2455}
@ UNIT_FIELD_FACTIONTEMPLATE
Definition UpdateFields.h:115
@ UNIT_FIELD_BYTES_2
Definition UpdateFields.h:161
void ForceValuesUpdateAtIndex(uint32)
Definition Object.cpp:2165

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 
)
1993{
1994 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1995 {
1996 Player* player = itr->GetSource();
1997 if (!player || (ignore && player->GetGUID() == ignore) || (ignorePlayersInBGRaid && player->GetGroup() != this))
1998 continue;
1999
2000 if (group == -1 || itr->getSubGroup() == group)
2001 player->SendDirectMessage(packet);
2002 }
2003}

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)
2006{
2007 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
2008 {
2009 Player* player = itr->GetSource();
2010 if (player)
2011 if (IsLeader(player->GetGUID()) || IsAssistant(player->GetGUID()))
2012 player->SendDirectMessage(packet);
2013 }
2014}
bool IsAssistant(ObjectGuid guid) const
Definition Group.cpp:2597

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 
)
2166{
2167 // check if this group is LFG group
2168 if (isLFGGroup())
2170
2171 BattlemasterListEntry const* bgEntry = sBattlemasterListStore.LookupEntry(bgTemplate->GetBgTypeID());
2172 if (!bgEntry)
2174
2175 // too many players in the group
2176 if (GetMembersCount() > bgEntry->maxGroupSize)
2177 return ERR_BATTLEGROUND_NONE;
2178
2179 // get a player as reference, to compare other players' stats to (arena team id, level bracket, etc.)
2180 Player* reference = GetFirstMember()->GetSource();
2181 if (!reference)
2183
2184 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgTemplate->GetMapId(), reference->GetLevel());
2185 if (!bracketEntry)
2187
2188 uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
2189 TeamId teamId = reference->GetTeamId();
2190
2192
2193 // check every member of the group to be able to join
2194 uint32 memberscount = 0;
2195 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount)
2196 {
2197 Player* member = itr->GetSource();
2198
2199 // don't let join with offline members
2200 if (!member)
2202
2203 if (!sScriptMgr->CanGroupJoinBattlegroundQueue(this, member, bgTemplate, MinPlayerCount, isRated, arenaSlot))
2205
2206 // don't allow cross-faction groups to join queue
2207 if (member->GetTeamId() != teamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
2209
2210 // don't let join rated matches if the arena team id doesn't match
2211 if (isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)
2213
2214 // not in the same battleground level braket, don't let join
2215 PvPDifficultyEntry const* memberBracketEntry = GetBattlegroundBracketByLevel(bracketEntry->mapId, member->GetLevel());
2216 if (memberBracketEntry != bracketEntry)
2218
2219 // check for deserter debuff in case not arena queue
2220 if (bgTemplate->GetBgTypeID() != BATTLEGROUND_AA && !member->CanJoinToBattleground(bgTemplate))
2222
2223 // check if someone in party is using dungeon system
2224 lfg::LfgState lfgState = sLFGMgr->GetState(member->GetGUID());
2225 if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG)))
2227
2228 // pussywizard: prevent joining when any member is in bg/arena
2229 if (member->InBattleground())
2231
2232 // pussywizard: check for free slot, this is actually ensured before calling this function, but just in case
2233 if (!member->HasFreeBattlegroundQueueId())
2235
2236 // don't let join if someone from the group is already in that bg queue
2237 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
2239
2240 // don't let join if someone from the group is in bg queue random
2241 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom))
2242 return ERR_IN_RANDOM_BG;
2243
2244 // don't let join to bg queue random if someone from the group is already in bg queue
2245 if (bgTemplate->GetBgTypeID() == BATTLEGROUND_RB && member->InBattlegroundQueue())
2246 return ERR_IN_NON_RANDOM_BG;
2247
2248 // don't let Death Knights join BG queues when they are not allowed to be teleported yet
2249 if (member->IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_TELEPORT) && member->GetMapId() == MAP_EBON_HOLD && !member->IsGameMaster() && !member->HasSpell(50977))
2251
2252 if (!member->GetBGAccessByLevel(bgTemplate->GetBgTypeID()))
2254
2255 if (member->HasPlayerFlag(PLAYER_FLAGS_NO_PLAY_TIME)) // Assumed to only apply to full restriction rather than partial
2256 return ERR_GROUP_JOIN_BATTLEGROUND_FAIL; // ERR_ARENA_EXPIRED_CAIS does not seem to be a result, so using this error instead
2257 }
2258
2259 // for arenas: check party size is proper
2260 if (bgTemplate->isArena() && memberscount != MinPlayerCount)
2262
2263 //check against other arena team members
2264 if (isRated)
2265 {
2266 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
2267 for (auto const& itr : arenaTeam->GetMembers())
2268 {
2269 Player* teamMember = ObjectAccessor::FindConnectedPlayer(itr.Guid);
2270 //are they online and not a member of this current group?
2271 if (teamMember && !IsMember(teamMember->GetGUID()))
2272 {
2273 //are they already in queue for a rated arena?
2274 if (teamMember->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
2275 {
2276 GroupQueueInfo ginfo;
2277 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
2278 if (queue.GetPlayerGroupInfoData(teamMember->GetGUID(), &ginfo))
2279 {
2280 if (ginfo.IsRated)
2282 }
2283 }
2284 //are they currently in an arena match?
2285 Battleground* bg = teamMember->GetBattleground(false);
2286 if (bg && bg->isRated() && bg->GetMinPlayersPerTeam() == MinPlayerCount)
2288 }
2289 }
2290 }
2291
2292 return GroupJoinBattlegroundResult(bgTemplate->GetBgTypeID());
2293}
@ 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:810
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:133
@ 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:255
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:12532
bool InBattleground() const
Definition Player.h:2300
TeamId GetTeamId(bool original=false) const
Definition Player.h:2140
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12483
bool InBattlegroundQueue(bool ignoreArena=false) const
Definition Player.cpp:12498
uint32 GetArenaTeamId(uint8 slot) const
Definition Player.cpp:16647
bool HasFreeBattlegroundQueueId() const
Definition Player.cpp:12552
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1351
bool CanJoinToBattleground(Battleground const *bg) const
Definition Player.cpp:11560
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4061
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1125
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition Player.cpp:12611
FROM * GetSource() const
Definition Reference.h:97
uint8 GetLevel() const
Definition Unit.h:1117
#define sWorld
Definition World.h:337
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)
802{
803 member_witerator slot = _getMemberWSlot(newLeaderGuid);
804
805 if (slot == m_memberSlots.end())
806 return;
807
808 Player* newLeader = ObjectAccessor::FindConnectedPlayer(slot->guid);
809
810 // Don't allow switching leader to offline players
811 if (!newLeader)
812 return;
813
814 if (!isBGGroup() && !isBFGroup())
815 {
816 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
817 // Update the group leader
819 stmt->SetData(0, newLeader->GetGUID().GetCounter());
820 stmt->SetData(1, GetGUID().GetCounter());
821 trans->Append(stmt);
822 CharacterDatabase.CommitTransaction(trans);
823
824 sInstanceSaveMgr->CopyBinds(m_leaderGuid, newLeaderGuid, newLeader);
825 }
826
828 oldLeader->RemovePlayerFlag(PLAYER_FLAGS_GROUP_LEADER);
829
831 ObjectGuid const oldLeaderGuid = m_leaderGuid;
832 m_leaderGuid = newLeader->GetGUID();
833 m_leaderName = newLeader->GetName();
835
837 data << slot->name;
838 BroadcastPacket(&data, true);
839
840 sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, oldLeaderGuid); // This hook should be executed at the end
841}
@ 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:1992
void ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply)
Definition Group.cpp:2766
member_witerator _getMemberWSlot(ObjectGuid Guid)
Definition Group.cpp:2739
Definition ObjectGuid.h:121
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 
)
2044{
2045 // Only raid groups have sub groups
2046 if (!isRaidGroup())
2047 return;
2048
2049 // Check if player is really in the raid
2050 member_witerator slot = _getMemberWSlot(guid);
2051 if (slot == m_memberSlots.end())
2052 return;
2053
2054 // Abort if the player is already in the target sub group
2055 uint8 prevSubGroup = GetMemberGroup(guid);
2056 if (prevSubGroup == group)
2057 return;
2058
2059 // Update the player slot with the new sub group setting
2060 slot->group = group;
2061
2062 // Increase the counter of the new sub group..
2064
2065 // ..and decrease the counter of the previous one
2066 SubGroupCounterDecrease(prevSubGroup);
2067
2068 // Preserve new sub group in database for non-raid groups
2069 if (!isBGGroup() && !isBFGroup())
2070 {
2072
2073 stmt->SetData(0, group);
2074 stmt->SetData(1, guid.GetCounter());
2075
2076 CharacterDatabase.Execute(stmt);
2077 }
2078
2079 // In case the moved player is online, update the player object with the new sub group references
2080 if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
2081 {
2082 if (player->GetGroup() == this)
2083 player->GetGroupRef().setSubGroup(group);
2084 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
2085 player->GetOriginalGroupRef().setSubGroup(group);
2086 }
2087
2088 // Broadcast the changes to the group
2089 SendUpdate();
2090}
@ CHAR_UPD_GROUP_MEMBER_SUBGROUP
Definition CharacterDatabase.h:291
uint8 GetMemberGroup(ObjectGuid guid) const
Definition Group.cpp:2626
void SubGroupCounterDecrease(uint8 subgroup)
Definition Group.cpp:2753

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 ( )
335{
336 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
337 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
338 if (player->GetLevel() < sConfigMgr->GetOption<int32>("Group.Raid.LevelRestriction", 10))
339 return true;
340
341 return false;
342}
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)
313{
315 if (restricted)
316 {
319 }
320
321 if (!isBGGroup() && !isBFGroup())
322 {
324
325 stmt->SetData(0, uint8(m_groupType));
326 stmt->SetData(1, GetGUID().GetCounter());
327
328 CharacterDatabase.Execute(stmt);
329 }
330
331 SendUpdate();
332}
@ 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 ( )
345{
347
349
350 if (!sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup())
351 {
353
354 stmt->SetData(0, uint8(m_groupType));
355 stmt->SetData(1, GetGUID().GetCounter());
356
357 CharacterDatabase.Execute(stmt);
358 }
359
360 SendUpdate();
361
362 // update quest related GO states (quest activity dependent from raid membership)
363 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
364 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
365 player->UpdateForQuestWorldObjects();
366
367 // pussywizard: client automatically clears df "eye" near minimap, so remove from raid browser
369 sLFGMgr->LeaveLfg(GetLeaderGUID());
370}
@ GROUPTYPE_RAID
Definition Group.h:89
#define sToCloud9Sidecar
Definition TC9Sidecar.h:81
void _initRaidSubGroupsCounter()
Definition Group.cpp:2719
ObjectGuid GetLeaderGUID() const
Definition Group.cpp:2538
@ 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 
)
1526{
1527 Rolls::iterator rollI = GetRoll(Guid);
1528 if (rollI == RollId.end())
1529 return false;
1530 Roll* roll = *rollI;
1531
1532 Roll::PlayerVote::iterator itr = roll->playerVote.find(playerGUID);
1533 // this condition means that player joins to the party after roll begins
1534 // Xinef: if choice == MAX_ROLL_TYPE, player was removed from the map in removefromgroup
1535 // Xinef: itr can be invalid as it is not used below
1536 if (Choice < MAX_ROLL_TYPE && itr == roll->playerVote.end())
1537 return false;
1538
1539 if (roll->getLoot())
1540 if (roll->getLoot()->items.empty())
1541 return false;
1542
1543 switch (Choice)
1544 {
1545 case ROLL_PASS: // Player choose pass
1546 SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_PASS, *roll);
1547 ++roll->totalPass;
1548 itr->second = PASS;
1549 break;
1550 case ROLL_NEED: // player choose Need
1551 SendLootRoll(ObjectGuid::Empty, playerGUID, 0, 0, *roll);
1552 ++roll->totalNeed;
1553 itr->second = NEED;
1554 break;
1555 case ROLL_GREED: // player choose Greed
1556 SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_GREED, *roll);
1557 ++roll->totalGreed;
1558 itr->second = GREED;
1559 break;
1560 case ROLL_DISENCHANT: // player choose Disenchant
1561 SendLootRoll(ObjectGuid::Empty, playerGUID, 128, ROLL_DISENCHANT, *roll);
1562 ++roll->totalGreed;
1563 itr->second = DISENCHANT;
1564 break;
1565 }
1566
1567 if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
1568 {
1569 CountTheRoll(rollI);
1570 return true;
1571 }
1572 return false;
1573}
@ 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:2705
void CountTheRoll(Rolls::iterator roll)
Definition Group.cpp:1632
void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const &r, bool autoPass=false)
Definition Group.cpp:1046
static ObjectGuid const Empty
Definition ObjectGuid.h:123
uint8 totalGreed
Definition Group.h:169
uint8 totalPlayersRolling
Definition Group.h:167
uint8 totalNeed
Definition Group.h:168
uint8 totalPass
Definition Group.h:170
Loot * getLoot()
Definition Group.cpp:62
PlayerVote playerVote
Definition Group.h:166
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)
1633{
1634 Roll* roll = *rollI;
1635 if (!roll->isValid()) // is loot already deleted ?
1636 {
1637 RollId.erase(rollI);
1638 delete roll;
1639 return;
1640 }
1641
1642 //end of the roll
1643 if (roll->totalNeed > 0)
1644 {
1645 if (!roll->playerVote.empty())
1646 {
1647 uint8 maxresul = 0;
1648 ObjectGuid maxguid; // pussywizard: start with 0 >_>
1649 Player* player = nullptr;
1650
1651 for (Roll::PlayerVote::const_iterator itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
1652 {
1653 if (itr->second != NEED)
1654 continue;
1655
1656 player = ObjectAccessor::FindPlayer(itr->first);
1657 if (!player)
1658 {
1659 --roll->totalNeed;
1660 continue;
1661 }
1662
1663 uint8 randomN = urand(1, 100);
1664 SendLootRoll(ObjectGuid::Empty, itr->first, randomN, ROLL_NEED, *roll);
1665 if (maxresul < randomN)
1666 {
1667 maxguid = itr->first;
1668 maxresul = randomN;
1669 }
1670 }
1671
1672 if (maxguid) // pussywizard: added condition
1673 {
1674 SendLootRollWon(roll->itemGUID, maxguid, maxresul, ROLL_NEED, *roll);
1675 player = ObjectAccessor::FindPlayer(maxguid);
1676
1677 if (player)
1678 {
1680
1681 ItemPosCountVec dest;
1682 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1683 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1684 if (msg == EQUIP_ERR_OK)
1685 {
1686 item->is_looted = true;
1687 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1688 roll->getLoot()->unlootedCount--;
1689 AllowedLooterSet looters = item->GetAllowedLooters();
1690 Item* _item = player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, looters);
1691 if (_item)
1692 sScriptMgr->OnPlayerGroupRollRewardItem(player, _item, item->count, NEED, roll);
1693 player->UpdateLootAchievements(item, roll->getLoot());
1694 }
1695 else
1696 {
1697 if (ShouldMailRollWonItem(this, roll, msg))
1698 {
1699 item->is_looted = true;
1700 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1701 roll->getLoot()->unlootedCount--;
1702 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1703 SendRollWonItemViaMail(player, item, roll->itemid);
1704 }
1705 else
1706 {
1707 item->is_blocked = false;
1708 item->rollWinnerGUID = player->GetGUID();
1709 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1710 }
1711 }
1712 }
1713 }
1714 else
1715 roll->totalNeed = 0;
1716 }
1717 }
1718 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
1719 {
1720 if (!roll->playerVote.empty())
1721 {
1722 uint8 maxresul = 0;
1723 ObjectGuid maxguid; // pussywizard: start with 0
1724 Player* player = nullptr;
1725 RollVote rollvote = NOT_VALID;
1726
1727 Roll::PlayerVote::iterator itr;
1728 for (itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
1729 {
1730 if (itr->second != GREED && itr->second != DISENCHANT)
1731 continue;
1732
1733 player = ObjectAccessor::FindPlayer(itr->first);
1734 if (!player)
1735 {
1736 --roll->totalGreed;
1737 continue;
1738 }
1739
1740 uint8 randomN = urand(1, 100);
1741 SendLootRoll(ObjectGuid::Empty, itr->first, randomN, itr->second, *roll);
1742 if (maxresul < randomN)
1743 {
1744 maxguid = itr->first;
1745 maxresul = randomN;
1746 rollvote = itr->second;
1747 }
1748 }
1749
1750 if (maxguid) // pussywizard: added condition
1751 {
1752 SendLootRollWon(roll->itemGUID, maxguid, maxresul, rollvote, *roll);
1753 player = ObjectAccessor::FindPlayer(maxguid);
1754
1755 if (player)
1756 {
1758
1759 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1760
1761 if (rollvote == GREED)
1762 {
1763 ItemPosCountVec dest;
1764 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1765 if (msg == EQUIP_ERR_OK)
1766 {
1767 item->is_looted = true;
1768 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1769 roll->getLoot()->unlootedCount--;
1770 AllowedLooterSet looters = item->GetAllowedLooters();
1771 Item* _item = player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, looters);
1772 if (_item)
1773 sScriptMgr->OnPlayerGroupRollRewardItem(player, _item, item->count, GREED, roll);
1774 player->UpdateLootAchievements(item, roll->getLoot());
1775 }
1776 else
1777 {
1778 if (ShouldMailRollWonItem(this, roll, msg))
1779 {
1780 item->is_looted = true;
1781 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1782 roll->getLoot()->unlootedCount--;
1783 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1784 SendRollWonItemViaMail(player, item, roll->itemid);
1785 }
1786 else
1787 {
1788 item->is_blocked = false;
1789 item->rollWinnerGUID = player->GetGUID();
1790 player->SendEquipError(msg, nullptr, nullptr, roll->itemid);
1791 }
1792 }
1793 }
1794 else if (rollvote == DISENCHANT)
1795 {
1796 item->is_looted = true;
1797 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1798 roll->getLoot()->unlootedCount--;
1799 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(roll->itemid);
1801
1802 ItemPosCountVec dest;
1803 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1804
1805 if (msg == EQUIP_ERR_OK)
1806 {
1807 player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
1808 }
1809 else
1810 {
1811 Loot loot;
1812 loot.FillLoot(pProto->DisenchantID, LootTemplates_Disenchant, player, true);
1813
1814 uint32 max_slot = loot.GetMaxSlotInLootFor(player);
1815 for(uint32 i = 0; i < max_slot; i++)
1816 {
1817 LootItem* lootItem = loot.LootItemInSlot(i, player);
1818 player->SendEquipError(msg, nullptr, nullptr, lootItem->itemid);
1819 player->SendItemRetrievalMail(lootItem->itemid, lootItem->count);
1820 }
1821 }
1822 }
1823 }
1824 }
1825 else
1826 roll->totalGreed = 0;
1827 }
1828 }
1829 if (roll->totalNeed == 0 && roll->totalGreed == 0) // if, not else, because the totals can be decremented above when a rolling player is offline
1830 {
1831 SendLootAllPassed(*roll);
1832
1833 // remove is_blocked so that the item is lootable by all players
1834 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1835 if (item)
1836 item->is_blocked = false;
1837 }
1838
1839 if (Loot* loot = roll->getLoot(); loot && loot->isLooted() && loot->sourceGameObject)
1840 {
1841 GameObjectTemplate const* goInfo = loot->sourceGameObject->GetGOInfo();
1842 if (goInfo && goInfo->type == GAMEOBJECT_TYPE_CHEST)
1843 {
1844 // Deactivate chest if the last item was rolled in group
1846 }
1847 }
1848
1849 RollId.erase(rollI);
1850 delete roll;
1851}
@ 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:118
static bool ShouldMailRollWonItem(Group const *group, Roll const *roll, InventoryResult msg)
Definition Group.cpp:101
static void SendRollWonItemViaMail(Player *player, LootItem const *lootItem, uint32 itemId)
Definition Group.cpp:67
RollVote
Definition Group.h:50
@ NOT_VALID
Definition Group.h:56
InventoryResult
Definition Item.h:46
@ EQUIP_ERR_OK
Definition Item.h:47
@ 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
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:141
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2547
void SendLootAllPassed(Roll const &roll)
Definition Group.cpp:1093
void SendLootRollWon(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const &r)
Definition Group.cpp:1070
Definition Item.h:220
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2232
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition Player.cpp:13884
void SendItemRetrievalMail(uint32 itemEntry, uint32 count)
Definition PlayerMisc.cpp:432
void UpdateLootAchievements(LootItem *item, Loot *loot)
Definition PlayerUpdates.cpp:2222
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:171
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
uint32 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(), LootItem::count, DISENCHANT, ItemTemplate::DisenchantID, ObjectGuid::Empty, 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, Loot::isLooted(), Reference< TO, FROM >::isValid(), Roll::itemGUID, Roll::itemid, LootItem::itemid, Loot::items, Roll::itemSlot, Loot::LootItemInSlot(), LootTemplates_Disenchant, 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(), ShouldMailRollWonItem(), sObjectMgr, sScriptMgr, Player::StoreNewItem(), Roll::totalGreed, Roll::totalNeed, GameObjectTemplate::type, Loot::unlootedCount, Player::UpdateAchievementCriteria(), Player::UpdateLootAchievements(), and urand().

Referenced by CountRollVote(), EndRoll(), and ForcedDisband().

◆ Create()

bool Group::Create ( Player *  leader)
161{
162 ObjectGuid leaderGuid = leader->GetGUID();
163 ObjectGuid::LowType lowguid = sGroupMgr->GenerateGroupId();
164
165 m_guid = ObjectGuid::Create<HighGuid::Group>(lowguid);
166 m_leaderGuid = leaderGuid;
167 m_leaderName = leader->GetName();
169
170 if (isBGGroup() || isBFGroup())
172
175
176 if (!isLFGGroup())
178
180 m_looterGuid = leaderGuid;
182
185
186 if (!isBGGroup() && !isBFGroup())
187 {
190
191 // Store group in database
193
194 uint8 index = 0;
195
196 stmt->SetData(index++, lowguid);
197 stmt->SetData(index++, m_leaderGuid.GetCounter());
198 stmt->SetData(index++, uint8(m_lootMethod));
199 stmt->SetData(index++, m_looterGuid.GetCounter());
200 stmt->SetData(index++, uint8(m_lootThreshold));
201 stmt->SetData(index++, m_targetIcons[0].GetRawValue());
202 stmt->SetData(index++, m_targetIcons[1].GetRawValue());
203 stmt->SetData(index++, m_targetIcons[2].GetRawValue());
204 stmt->SetData(index++, m_targetIcons[3].GetRawValue());
205 stmt->SetData(index++, m_targetIcons[4].GetRawValue());
206 stmt->SetData(index++, m_targetIcons[5].GetRawValue());
207 stmt->SetData(index++, m_targetIcons[6].GetRawValue());
208 stmt->SetData(index++, m_targetIcons[7].GetRawValue());
209 stmt->SetData(index++, uint8(m_groupType));
210 stmt->SetData(index++, uint8(m_dungeonDifficulty));
211 stmt->SetData(index++, uint8(m_raidDifficulty));
212 stmt->SetData(index++, m_masterLooterGuid.GetCounter());
213
214 CharacterDatabase.Execute(stmt);
215
216 ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
217
218 sScriptMgr->OnCreate(this, leader);
219 }
220 else if (!AddMember(leader))
221 return false;
222
223 return true;
224}
@ 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:370
ObjectGuid m_masterLooterGuid
Definition Group.h:371
ObjectGuid m_guid
Definition Group.h:374
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)
945{
946 if (sToCloud9Sidecar->ClusterModeEnabled() && !this->isBFGroup() && !this->isBGGroup())
947 return;
948
949 ForcedDisband(hideDestroy);
950}
void ForcedDisband(bool hideDestroy=false)
Definition Group.cpp:843

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)
2786{
2787 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
2788 {
2789 Player* member = itr->GetSource();
2790 if (!member)
2791 continue;
2792
2793 worker(member);
2794 }
2795}

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

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

◆ DoMinimapPing()

void Group::DoMinimapPing ( ObjectGuid  sourceGuid,
float  mapX,
float  mapY 
)
2296{
2298 minimapPing.SourceGuid = sourceGuid;
2299 minimapPing.MapX = mapX;
2300 minimapPing.MapY = mapY;
2301
2302 BroadcastPacket(minimapPing.Write(), true, -1, sourceGuid);
2303}
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)
1577{
1578 for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
1579 {
1580 if ((*itr)->getLoot() == pLoot)
1581 {
1582 Roll* roll = *itr;
1583 for (auto& [playerGuid, vote] : roll->playerVote)
1584 {
1585 if (vote != NOT_EMITED_YET)
1586 continue;
1587
1588 vote = PASS;
1589 ++roll->totalPass;
1590 SendLootRoll(roll->itemGUID, playerGuid, 128, ROLL_PASS, *roll);
1591 }
1592
1593 CountTheRoll(itr);
1594 itr = RollId.begin();
1595 }
1596 else
1597 ++itr;
1598 }
1599}
@ 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
844{
845 sScriptMgr->OnGroupDisband(this);
846
847 // Settle open rolls: only CountTheRoll unblocks a rolled item, and the looted object's roll timer
848 // can't once the group is gone, so the item would stay locked
849 while (!RollId.empty())
850 CountTheRoll(RollId.begin());
851
852 Player* player;
853 uint32 instanceId = 0;
854
855 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
856 {
857 if (!isBGGroup() && !isBFGroup())
858 {
859 sCharacterCache->ClearCharacterGroup(citr->guid);
860 }
861
862 player = ObjectAccessor::FindConnectedPlayer(citr->guid);
863
864 if (player && !instanceId && !isBGGroup() && !isBFGroup())
865 {
866 instanceId = player->GetInstanceId();
867 }
868
869 _homebindIfInstance(player);
870 if (!isBGGroup() && !isBFGroup())
872
873 if (!player)
874 continue;
875
876 //we cannot call _removeMember because it would invalidate member iterator
877 //if we are removing player from battleground raid
878 if (isBGGroup() || isBFGroup())
880 else
881 {
882 //we can remove player who is in battleground from his original group
883 if (player->GetOriginalGroup() == this)
884 player->SetOriginalGroup(nullptr);
885 else
886 player->SetGroup(nullptr);
887 }
888
889 // quest related GO state dependent from raid membership
890 if (isRaidGroup())
892
893 WorldPacket data;
894 if (!hideDestroy)
895 {
897 player->SendDirectMessage(&data);
898 }
899
900 //we already removed player from group and in player->GetGroup() is his original group, send update
901 if (Group* group = player->GetGroup())
902 {
903 group->SendUpdate();
904 }
905 else
906 {
907 data.Initialize(SMSG_GROUP_LIST, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 8);
908 data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
909 data << m_guid << uint32(m_counter) << uint32(0) << uint64(0);
910 player->SendDirectMessage(&data);
911 }
912 }
913 RollId.clear();
914 m_memberSlots.clear();
915
917
918 if (!isBGGroup() && !isBFGroup())
919 {
920 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
921
923 stmt->SetData(0, GetGUID().GetCounter());
924 trans->Append(stmt);
925
926 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER_ALL);
927 stmt->SetData(0, GetGUID().GetCounter());
928 trans->Append(stmt);
929
930 CharacterDatabase.CommitTransaction(trans);
931
932 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
933 stmt->SetData(0, GetGUID().GetCounter());
934 CharacterDatabase.Execute(stmt);
935 }
936
937 // Cleaning up instance saved data for gameobjects when a group is disbanded
938 sInstanceSaveMgr->DeleteInstanceSavedData(instanceId);
939
940 sGroupMgr->RemoveGroup(this);
941 delete this;
942}
@ 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:723
void RemoveAllInvites()
Definition Group.cpp:415
void _homebindIfInstance(Player *player)
Definition Group.cpp:2425
void RemoveFromBattlegroundOrBattlefieldRaid()
Definition Player.cpp:13487
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, CountTheRoll(), 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
2686{
2687 return isRaid ? m_raidDifficulty : m_dungeonDifficulty;
2688}

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
2691{
2692 return m_dungeonDifficulty;
2693}

References m_dungeonDifficulty.

Referenced by AddMember().

◆ GetFirstMember() [1/2]

◆ GetFirstMember() [2/2]

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

References GroupRefMgr::getFirst(), and m_memberMgr.

◆ GetGroupType()

GroupType Group::GetGroupType ( ) const
2534{
2535 return m_groupType;
2536}

References m_groupType.

◆ GetGUID()

◆ GetInvited() [1/2]

Player * Group::GetInvited ( ObjectGuid  guid) const
425{
426 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
427 {
428 if ((*itr) && (*itr)->GetGUID() == guid)
429 return (*itr);
430 }
431 return nullptr;
432}

References m_invitees.

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

◆ GetInvited() [2/2]

Player * Group::GetInvited ( std::string const &  name) const
435{
436 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
437 {
438 if ((*itr) && (*itr)->GetName() == name)
439 return (*itr);
440 }
441 return nullptr;
442}

References m_invitees.

◆ GetInviteeCount()

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

References m_invitees.

Referenced by Player::UninviteFromGroup().

◆ GetLeader()

Player * Group::GetLeader ( )

◆ GetLeaderGUID()

◆ GetLeaderName()

char const * Group::GetLeaderName ( ) const
2554{
2555 return m_leaderName.c_str();
2556}

References m_leaderName.

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

◆ GetLooterGuid()

ObjectGuid Group::GetLooterGuid ( ) const
2564{
2565 return m_looterGuid;
2566}

References m_looterGuid.

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

◆ GetLootMethod()

◆ GetLootThreshold()

ItemQualities Group::GetLootThreshold ( ) const
2574{
2575 return m_lootThreshold;
2576}

References m_lootThreshold.

Referenced by Loot::FillLoot().

◆ GetMasterLooterGuid()

ObjectGuid Group::GetMasterLooterGuid ( ) const

◆ GetMemberGroup()

uint8 Group::GetMemberGroup ( ObjectGuid  guid) const
2627{
2628 member_citerator mslot = _getMemberCSlot(guid);
2629 if (mslot == m_memberSlots.end())
2630 return (MAX_RAID_SUBGROUPS + 1);
2631 return mslot->group;
2632}
member_citerator _getMemberCSlot(ObjectGuid Guid) const
Definition Group.cpp:2731

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)
2589{
2590 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2591 if (itr->name == name)
2592 return itr->guid;
2593
2594 return ObjectGuid::Empty;
2595}

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
2696{
2697 return m_raidDifficulty;
2698}

References m_raidDifficulty.

Referenced by AddMember().

◆ GetRoll()

Group::Rolls::iterator Group::GetRoll ( ObjectGuid  Guid)
2706{
2707 Rolls::iterator iter;
2708 for (iter = RollId.begin(); iter != RollId.end(); ++iter)
2709 if ((*iter)->itemGUID == Guid && (*iter)->isValid())
2710 return iter;
2711 return RollId.end();
2712}

References RollId.

Referenced by CountRollVote().

◆ GetRolls()

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

References RollId.

◆ GetTargetIcon()

ObjectGuid Group::GetTargetIcon ( uint8  id) const
inline

◆ GroupLoot()

void Group::GroupLoot ( Loot *  loot,
WorldObject *  pLootedObject 
)
1152{
1153 std::vector<LootItem>::iterator i;
1154 ItemTemplate const* item;
1155 uint8 itemSlot = 0;
1156
1157 for (i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
1158 {
1159 if (i->freeforall)
1160 continue;
1161
1162 item = sObjectMgr->GetItemTemplate(i->itemid);
1163 if (!item)
1164 {
1165 continue;
1166 }
1167
1168 // roll for over-threshold item if it's one-player loot
1169 if (item->Quality >= uint32(m_lootThreshold))
1170 {
1171 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1172 Roll* r = new Roll(newitemGUID, *i, pLootedObject->GetMap()->IsRaid());
1173
1174 //a vector is filled with only near party members
1175 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1176 {
1177 Player* member = itr->GetSource();
1178 if (!member || !member->GetSession())
1179 continue;
1180
1181 bool canLoot = member->IsAtLootRewardDistance(pLootedObject);
1182 if (!canLoot && !pLootedObject->GetAllowedLooters().empty())
1183 canLoot = pLootedObject->HasAllowedLooter(member->GetGUID());
1184
1185 if (canLoot)
1186 {
1188
1189 RollVote vote = member->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
1190 if (!CanRollOnItem(*i, member, loot))
1191 {
1192 vote = PASS;
1193 ++r->totalPass;
1194 }
1195
1196 r->playerVote[member->GetGUID()] = vote;
1197 }
1198 }
1199
1200 if (r->totalPlayersRolling > 0)
1201 {
1202 r->setLoot(loot);
1203 r->itemSlot = itemSlot;
1206
1207 loot->items[itemSlot].is_blocked = true;
1208
1209 // If there is any "auto pass", broadcast the pass now.
1210 if (r->totalPass)
1211 {
1212 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1213 {
1214 Player* p = ObjectAccessor::FindPlayer(itr->first);
1215 if (!p)
1216 continue;
1217
1218 if (itr->second == PASS)
1219 SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r, true);
1220 }
1221 }
1222
1223 if (r->totalPass == r->totalPlayersRolling)
1224 delete r;
1225 else
1226 {
1227 SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
1228
1229 RollId.push_back(r);
1230
1231 if (Creature* creature = pLootedObject->ToCreature())
1232 {
1233 creature->m_groupLootTimer = 60000;
1234 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1235 }
1236 else if (GameObject* go = pLootedObject->ToGameObject())
1237 {
1238 go->m_groupLootTimer = 60000;
1239 go->lootingGroupLowGUID = GetGUID().GetCounter();
1240 }
1241 }
1242 }
1243 else
1244 delete r;
1245 }
1246 else
1247 i->is_underthreshold = true;
1248 }
1249
1250 for (i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i, ++itemSlot)
1251 {
1252 if (!i->follow_loot_rules)
1253 continue;
1254
1255 item = sObjectMgr->GetItemTemplate(i->itemid);
1256 if (!item)
1257 {
1258 continue;
1259 }
1260
1261 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1262 Roll* r = new Roll(newitemGUID, *i, pLootedObject->GetMap()->IsRaid());
1263
1264 //a vector is filled with only near party members
1265 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1266 {
1267 Player* member = itr->GetSource();
1268 if (!member || !member->GetSession())
1269 continue;
1270
1271 bool canLoot = member->IsAtLootRewardDistance(pLootedObject);
1272 if (!canLoot && !pLootedObject->GetAllowedLooters().empty())
1273 canLoot = pLootedObject->HasAllowedLooter(member->GetGUID());
1274
1275 if (canLoot)
1276 {
1278
1279 RollVote vote = NOT_EMITED_YET;
1280 if (!CanRollOnItem(*i, member, loot))
1281 {
1282 vote = PASS;
1283 ++r->totalPass;
1284 }
1285 r->playerVote[member->GetGUID()] = vote;
1286 }
1287 }
1288
1289 if (r->totalPlayersRolling > 0)
1290 {
1291 r->setLoot(loot);
1292 r->itemSlot = itemSlot;
1293
1294 loot->quest_items[itemSlot - loot->items.size()].is_blocked = true;
1295
1296 SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
1297
1298 RollId.push_back(r);
1299
1300 if (Creature* creature = pLootedObject->ToCreature())
1301 {
1302 creature->m_groupLootTimer = 60000;
1303 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1304 }
1305 else if (GameObject* go = pLootedObject->ToGameObject())
1306 {
1307 go->m_groupLootTimer = 60000;
1308 go->lootingGroupLowGUID = GetGUID().GetCounter();
1309 }
1310 }
1311 else
1312 delete r;
1313 }
1314}
bool CanRollOnItem(LootItem const &item, Player const *player, Loot *loot)
Definition Group.cpp:1134
@ ROLL_FLAG_TYPE_DISENCHANT
Definition LootMgr.h:45
Definition Creature.h:47
Definition GameObject.h:125
void SendLootStartRoll(uint32 CountDown, uint32 mapid, Roll const &r)
Definition Group.cpp:956
GameObject * ToGameObject()
Definition Object.h:220
Creature * ToCreature()
Definition Object.h:212
WorldSession * GetSession() const
Definition Player.h:2032
bool IsAtLootRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:13141
bool GetPassOnGroupLoot() const
Definition Player.h:2539
void setLoot(Loot *pLoot)
Definition Group.cpp:57
uint8 rollVoteMask
Definition Group.h:172
Map * GetMap() const
Definition Object.h:637
bool HasAllowedLooter(ObjectGuid guid) const
Definition Object.cpp:3234
GuidUnorderedSet const & GetAllowedLooters() const
Definition Object.cpp:3244
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(), WorldObject::GetMap(), WorldLocation::GetMapId(), Player::GetPassOnGroupLoot(), Player::GetSession(), WorldObject::HasAllowedLooter(), Player::IsAtLootRewardDistance(), Map::IsRaid(), 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
2529{
2530 return GetMembersCount() > 0;
2531}

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
2701{
2702 return !RollId.empty();
2703}

References RollId.

Referenced by Player::CanUninviteFromGroup().

◆ LinkMember()

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

References LinkedListHead::insertFirst(), and m_memberMgr.

Referenced by GroupReference::targetObjectBuildLink().

◆ LoadGroupFromDB()

bool Group::LoadGroupFromDB ( Field *  field)
227{
228 ObjectGuid::LowType groupLowGuid = fields[16].Get<uint32>();
229 m_guid = ObjectGuid::Create<HighGuid::Group>(groupLowGuid);
230
231 m_leaderGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].Get<uint32>());
232
233 // group leader not exist
234 if (!sCharacterCache->GetCharacterNameByGuid(m_leaderGuid, m_leaderName))
235 {
236 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
238 stmt->SetData(0, groupLowGuid);
239 trans->Append(stmt);
240 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER_ALL);
241 stmt->SetData(0, groupLowGuid);
242 trans->Append(stmt);
243 CharacterDatabase.CommitTransaction(trans);
244 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
245 stmt->SetData(0, groupLowGuid);
246 CharacterDatabase.Execute(stmt);
247 return false;
248 }
249
250 m_lootMethod = LootMethod(fields[1].Get<uint8>());
251 m_looterGuid = ObjectGuid::Create<HighGuid::Player>(fields[2].Get<uint32>());
252 m_lootThreshold = ItemQualities(fields[3].Get<uint8>());
253
254 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
255 m_targetIcons[i].Set(fields[4 + i].Get<uint64>());
256
257 m_groupType = GroupType(fields[12].Get<uint8>());
260
261 uint32 diff = fields[13].Get<uint8>();
262 if (diff >= MAX_DUNGEON_DIFFICULTY)
264 else
266
267 uint32 r_diff = fields[14].Get<uint8>();
268 if (r_diff >= MAX_RAID_DIFFICULTY)
270 else
272
273 m_masterLooterGuid = ObjectGuid::Create<HighGuid::Player>(fields[15].Get<uint32>());
274
276 sLFGMgr->_LoadFromDB(fields, GetGUID());
277
278 return true;
279}
#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 
)
282{
283 MemberSlot member;
284 member.guid = ObjectGuid::Create<HighGuid::Player>(guidLow);
285
286 // skip non-existed member
287 if (!sCharacterCache->GetCharacterNameByGuid(member.guid, member.name))
288 {
290 stmt->SetData(0, guidLow);
291 stmt->SetData(1, GetGUID().GetCounter());
292 CharacterDatabase.Execute(stmt);
293 return;
294 }
295
296 member.group = subgroup;
297 member.flags = memberFlags;
298 member.roles = roles;
299
300 m_memberSlots.push_back(member);
301
302 if (!isBGGroup() && !isBFGroup())
303 {
304 sCharacterCache->UpdateCharacterGroup(ObjectGuid(HighGuid::Player, guidLow), GetGUID());
305 }
306
307 SubGroupCounterIncrease(subgroup);
308
309 sLFGMgr->SetupGroupMember(member.guid, GetGUID());
310}
@ 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 
)
1472{
1473 LOG_DEBUG("network", "Group::MasterLoot (SMSG_LOOT_MASTER_LIST, 330)");
1474
1475 for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i)
1476 {
1477 if (i->freeforall)
1478 continue;
1479
1480 i->is_blocked = !i->is_underthreshold;
1481 }
1482
1483 for (std::vector<LootItem>::iterator i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i)
1484 {
1485 if (!i->follow_loot_rules)
1486 continue;
1487
1488 i->is_blocked = !i->is_underthreshold;
1489 }
1490
1491 std::vector<Player*> looters;
1492 bool hasAllowedLooters = !pLootedObject->GetAllowedLooters().empty();
1493 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1494 {
1495 Player* looter = itr->GetSource();
1496 if (!looter->IsInWorld())
1497 {
1498 continue;
1499 }
1500
1501 bool canLoot = looter->IsAtLootRewardDistance(pLootedObject);
1502 if (!canLoot && hasAllowedLooters)
1503 canLoot = pLootedObject->HasAllowedLooter(looter->GetGUID());
1504
1505 if (canLoot)
1506 {
1507 looters.push_back(looter);
1508 }
1509 }
1510
1511 WorldPacket data(SMSG_LOOT_MASTER_LIST, 1 + looters.size() * (1 + 8));
1512 data << uint8(looters.size());
1513
1514 for (Player* looter : looters)
1515 {
1516 data << looter->GetGUID();
1517 }
1518
1519 for (Player* looter : looters)
1520 {
1521 looter->SendDirectMessage(&data);
1522 }
1523}
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 
)
1317{
1318 ItemTemplate const* item;
1319 uint8 itemSlot = 0;
1320 for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
1321 {
1322 if (i->freeforall)
1323 continue;
1324
1325 item = sObjectMgr->GetItemTemplate(i->itemid);
1326
1327 //roll for over-threshold item if it's one-player loot
1328 if (item->Quality >= uint32(m_lootThreshold))
1329 {
1330 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1331 Roll* r = new Roll(newitemGUID, *i, lootedObject->GetMap()->IsRaid());
1332
1333 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1334 {
1335 Player* playerToRoll = itr->GetSource();
1336 if (!playerToRoll || !playerToRoll->GetSession())
1337 continue;
1338
1339 bool canLoot = playerToRoll->IsAtGroupRewardDistance(lootedObject);
1340 if (!canLoot && !lootedObject->GetAllowedLooters().empty())
1341 canLoot = lootedObject->HasAllowedLooter(playerToRoll->GetGUID());
1342
1343 if (canLoot)
1344 {
1346
1347 RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
1348 if (!CanRollOnItem(*i, playerToRoll, loot))
1349 {
1350 vote = PASS;
1351 r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
1352 }
1353
1354 r->playerVote[playerToRoll->GetGUID()] = vote;
1355 }
1356 }
1357
1358 if (r->totalPlayersRolling > 0)
1359 {
1360 r->setLoot(loot);
1361 r->itemSlot = itemSlot;
1364
1366 r->rollVoteMask &= ~ROLL_FLAG_TYPE_NEED;
1367
1368 loot->items[itemSlot].is_blocked = true;
1369
1370 //Broadcast Pass and Send Rollstart
1371 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1372 {
1373 Player* p = ObjectAccessor::FindPlayer(itr->first);
1374 if (!p)
1375 continue;
1376
1377 if (itr->second == PASS)
1378 SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
1379 else
1380 SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
1381 }
1382
1383 RollId.push_back(r);
1384
1385 if (Creature* creature = lootedObject->ToCreature())
1386 {
1387 creature->m_groupLootTimer = 60000;
1388 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1389 }
1390 else if (GameObject* go = lootedObject->ToGameObject())
1391 {
1392 go->m_groupLootTimer = 60000;
1393 go->lootingGroupLowGUID = GetGUID().GetCounter();
1394 }
1395 }
1396 else
1397 delete r;
1398 }
1399 else
1400 i->is_underthreshold = true;
1401 }
1402
1403 for (std::vector<LootItem>::iterator i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i, ++itemSlot)
1404 {
1405 if (!i->follow_loot_rules)
1406 continue;
1407
1408 item = sObjectMgr->GetItemTemplate(i->itemid);
1409 ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate());
1410 Roll* r = new Roll(newitemGUID, *i, lootedObject->GetMap()->IsRaid());
1411
1412 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1413 {
1414 Player* playerToRoll = itr->GetSource();
1415 if (!playerToRoll || !playerToRoll->GetSession())
1416 continue;
1417
1418 if (playerToRoll->IsAtGroupRewardDistance(lootedObject))
1419 {
1421
1422 RollVote vote = playerToRoll->GetPassOnGroupLoot() ? PASS : NOT_EMITED_YET;
1423 if (!CanRollOnItem(*i, playerToRoll, loot))
1424 {
1425 vote = PASS;
1426 r->totalPass++; // Can't broadcast the pass now. need to wait until all rolling players are known
1427 }
1428
1429 r->playerVote[playerToRoll->GetGUID()] = vote;
1430 }
1431 }
1432
1433 if (r->totalPlayersRolling > 0)
1434 {
1435 r->setLoot(loot);
1436 r->itemSlot = itemSlot;
1437
1438 loot->quest_items[itemSlot - loot->items.size()].is_blocked = true;
1439
1440 //Broadcast Pass and Send Rollstart
1441 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1442 {
1443 Player* p = ObjectAccessor::FindPlayer(itr->first);
1444 if (!p)
1445 continue;
1446
1447 if (itr->second == PASS)
1448 SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
1449 else
1450 SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
1451 }
1452
1453 RollId.push_back(r);
1454
1455 if (Creature* creature = lootedObject->ToCreature())
1456 {
1457 creature->m_groupLootTimer = 60000;
1458 creature->lootingGroupLowGUID = GetGUID().GetCounter();
1459 }
1460 else if (GameObject* go = lootedObject->ToGameObject())
1461 {
1462 go->m_groupLootTimer = 60000;
1463 go->lootingGroupLowGUID = GetGUID().GetCounter();
1464 }
1465 }
1466 else
1467 delete r;
1468 }
1469}
@ 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:1024
InventoryResult CanRollForItemInLFG(ItemTemplate const *item, WorldObject const *lootedObject) const
Definition PlayerStorage.cpp:2444
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:13120
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(), WorldObject::GetMap(), WorldLocation::GetMapId(), Player::GetPassOnGroupLoot(), Player::GetSession(), WorldObject::HasAllowedLooter(), ItemTemplate::HasFlag2(), Player::IsAtGroupRewardDistance(), Map::IsRaid(), 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 ( )
2017{
2018 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
2019 {
2020 Player* player = ObjectAccessor::FindConnectedPlayer(citr->guid);
2021 if (!player)
2022 {
2024 data << citr->guid;
2025 data << uint8(0);
2026 BroadcastReadyCheck(&data);
2027 }
2028 }
2029}
void BroadcastReadyCheck(WorldPacket const *packet)
Definition Group.cpp:2005
@ 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 ( )
416{
417 for (Player* invitee : m_invitees)
418 if (invitee && invitee->GetGroupInvite() == this)
419 invitee->SetGroupInvite(nullptr);
420
421 m_invitees.clear();
422}

References m_invitees.

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

◆ RemoveInvite()

void Group::RemoveInvite ( Player *  player)
404{
405 if (!player)
406 return;
407
408 m_invitees.erase(player);
409
410 // Clear pending invite from current group, Keep an invite from another group.
411 if (player->GetGroupInvite() == this)
412 player->SetGroupInvite(nullptr);
413}

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 
)
650{
652
653 // LFG group vote kick handled in scripts
654 if (isLFGGroup(true) && method == GROUP_REMOVEMETHOD_KICK)
655 {
656 sLFGMgr->InitBoot(GetGUID(), kicker, guid, std::string(reason ? reason : ""));
657 return m_memberSlots.size() > 0;
658 }
659
660 // remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group),
661 // except in cluster mode, where this branch is taken for any size: the group
662 // service owns the group lifecycle and local Disband() is a no-op, so always
663 // unlink the removed member here; waiting for the disband event leaves the
664 // last two members with a dangling group pointer whenever that event is lost
665 // (group service restart).
666 if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u)
667 || (sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup()))
668 {
670 if (player)
671 {
672 // Battleground group handling
673 if (isBGGroup() || isBFGroup())
675 else
676 // Regular group
677 {
678 if (player->GetOriginalGroup() == this)
679 player->SetOriginalGroup(nullptr);
680 else
681 player->SetGroup(nullptr);
682
683 // quest related GO state dependent from raid membership
685 }
686
687 // BG/BF groups stay locally owned in cluster mode (see the gates above),
688 // so their removal packets must not be delegated to the group service.
689 if (!sToCloud9Sidecar->ClusterModeEnabled() || isBGGroup() || isBFGroup())
690 {
691 WorldPacket data;
692
693 if (method == GROUP_REMOVEMETHOD_KICK || method == GROUP_REMOVEMETHOD_KICK_LFG)
694 {
696 player->GetSession()->SendPacket(&data);
697 }
698
699 // Do we really need to send this opcode?
700 data.Initialize(SMSG_GROUP_LIST, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 8);
701 data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0);
702 data << m_guid << uint32(m_counter) << uint32(0) << uint64(0);
703 player->GetSession()->SendPacket(&data);
704 }
705 }
706
707 // Remove player from group in DB
708 if (!isBGGroup() && !isBFGroup())
709 {
711 stmt->SetData(0, guid.GetCounter());
712 stmt->SetData(1, GetGUID().GetCounter());
713 CharacterDatabase.Execute(stmt);
714 }
715
716 // Remove player from loot rolls
718
719 // Update subgroups
721 if (slot != m_memberSlots.end())
722 {
723 SubGroupCounterDecrease(slot->group);
724 m_memberSlots.erase(slot);
725
726 if (!isBGGroup() && !isBFGroup())
727 {
728 sCharacterCache->ClearCharacterGroup(guid);
729 }
730 }
731
732 // Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
733 if (!player || player->GetSkillValue(SKILL_ENCHANTING))
734 {
736 }
737
738 // Pick new leader if necessary
739 bool validLeader = true;
740 if (m_leaderGuid == guid)
741 {
742 validLeader = false;
743 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
744 {
746 {
747 ChangeLeader(itr->guid);
748 validLeader = true;
749 break;
750 }
751 }
752 }
753
754 _homebindIfInstance(player);
755 if (!isBGGroup() && !isBFGroup())
757
758 sScriptMgr->OnGroupRemoveMember(this, guid, method, kicker, reason);
759
760 SendUpdate();
761
762 if (!validLeader)
763 {
764 // pussywizard: temp do nothing, something causes crashes in MakeNewGroup
765 //Disband();
766 //return false;
767 }
768
769 if (isLFGGroup() && GetMembersCount() == 1)
770 {
772 uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID());
773 lfg::LfgState state = sLFGMgr->GetState(GetGUID());
774 if (!mapId || !leader || (leader->IsAlive() && leader->GetMapId() != mapId) || state == lfg::LFG_STATE_NONE)
775 {
776 Disband();
777 return false;
778 }
779 }
780
781 if (m_memberMgr.getSize() < ((isLFGGroup() || isBGGroup() || isBFGroup()) ? 1u : 2u))
782 {
783 Disband();
784 return false;
785 }
786
787 return true;
788 }
789 // If group size before player removal <= 2 then disband it
790 else
791 {
792 // As in the branch above: a player who leaves or is kicked can't win a roll the disband settles
794
795 sScriptMgr->OnGroupRemoveMember(this, guid, method, kicker, reason);
796 Disband();
797 return false;
798 }
799}
@ GROUP_REMOVEMETHOD_KICK_LFG
Definition SharedDefines.h:3846
@ GROUP_REMOVEMETHOD_KICK
Definition SharedDefines.h:3844
void BroadcastGroupUpdate(void)
Definition Group.cpp:2441
void Disband(bool hideDestroy=false)
Definition Group.cpp:944
void ResetMaxEnchantingLevel()
Definition Group.cpp:2457
void ChangeLeader(ObjectGuid guid)
Definition Group.cpp:801
void RemovePlayerFromRolls(ObjectGuid guid)
Definition Group.cpp:1601
uint32 getSize() const
Definition LinkedList.h:115
bool IsAlive() const
Definition Unit.h:1812
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition WorldSession.cpp:309
@ 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)
1602{
1603 for (Rolls::iterator it = RollId.begin(); it != RollId.end();)
1604 {
1605 Roll* roll = *it;
1606 Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid);
1607 if (itr2 == roll->playerVote.end())
1608 {
1609 ++it;
1610 continue;
1611 }
1612
1613 if (itr2->second == GREED || itr2->second == DISENCHANT)
1614 --roll->totalGreed;
1615 else if (itr2->second == NEED)
1616 --roll->totalNeed;
1617 else if (itr2->second == PASS)
1618 --roll->totalPass;
1619
1620 if (itr2->second != NOT_VALID)
1621 --roll->totalPlayersRolling;
1622
1623 roll->playerVote.erase(itr2);
1624
1625 if (CountRollVote(guid, roll->itemGUID, MAX_ROLL_TYPE))
1626 it = RollId.begin();
1627 else
1628 ++it;
1629 }
1630}
@ MAX_ROLL_TYPE
Definition LootMgr.h:37
bool CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choise)
Definition Group.cpp:1525

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)
2760{
2761 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2762 if (itr->flags & flag)
2763 itr->flags &= ~flag;
2764}

References m_memberSlots.

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

◆ ResetInstances()

void Group::ResetInstances ( uint8  method,
bool  isRaid,
Player *  leader 
)
2358{
2359 if (isBGGroup() || isBFGroup() || isLFGGroup())
2360 return;
2361
2362 switch (method)
2363 {
2364 case INSTANCE_RESET_ALL:
2365 {
2366 if (leader->GetDifficulty(false) != DUNGEON_DIFFICULTY_NORMAL)
2367 break;
2368 std::vector<InstanceSave*> toUnbind;
2369 BoundInstancesMap const& m_boundInstances = sInstanceSaveMgr->PlayerGetBoundInstances(leader->GetGUID(), Difficulty(DUNGEON_DIFFICULTY_NORMAL));
2370 for (BoundInstancesMap::const_iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end(); ++itr)
2371 {
2372 InstanceSave* instanceSave = itr->second.save;
2373 MapEntry const* entry = sMapStore.LookupEntry(itr->first);
2374 if (!entry || entry->IsRaid() || !instanceSave->CanReset())
2375 continue;
2376
2377 Map* map = sMapMgr->FindMap(instanceSave->GetMapId(), instanceSave->GetInstanceId());
2378 if (!map || map->ToInstanceMap()->Reset(method))
2379 {
2380 leader->SendResetInstanceSuccess(instanceSave->GetMapId());
2381 toUnbind.push_back(instanceSave);
2382 }
2383 else
2384 {
2385 leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId());
2386 }
2387
2388 sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
2389 }
2390 for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
2391 sInstanceSaveMgr->UnbindAllFor(*itr);
2392 }
2393 break;
2395 {
2396 std::vector<InstanceSave*> toUnbind;
2397 BoundInstancesMap const& m_boundInstances = sInstanceSaveMgr->PlayerGetBoundInstances(leader->GetGUID(), leader->GetDifficulty(isRaid));
2398 for (BoundInstancesMap::const_iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end(); ++itr)
2399 {
2400 InstanceSave* instanceSave = itr->second.save;
2401 MapEntry const* entry = sMapStore.LookupEntry(itr->first);
2402 if (!entry || entry->IsRaid() != isRaid || !instanceSave->CanReset())
2403 continue;
2404
2405 Map* map = sMapMgr->FindMap(instanceSave->GetMapId(), instanceSave->GetInstanceId());
2406 if (!map || map->ToInstanceMap()->Reset(method))
2407 {
2408 leader->SendResetInstanceSuccess(instanceSave->GetMapId());
2409 toUnbind.push_back(instanceSave);
2410 }
2411 else
2412 {
2413 leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId());
2414 }
2415
2416 sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId());
2417 }
2418 for (std::vector<InstanceSave*>::const_iterator itr = toUnbind.begin(); itr != toUnbind.end(); ++itr)
2419 sInstanceSaveMgr->UnbindAllFor(*itr);
2420 }
2421 break;
2422 }
2423}
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
Definition InstanceSaveMgr.h:47
#define sMapMgr
Definition MapMgr.h:220
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition Map.h:720
@ INSTANCE_RESET_ALL
Definition Map.h:719
@ 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 ( )
2458{
2460 Player* pMember = nullptr;
2461 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
2462 {
2463 pMember = ObjectAccessor::FindPlayer(citr->guid);
2464 if (pMember && pMember->GetSession() && !pMember->GetSession()->IsSocketClosed()
2465 && m_maxEnchantingLevel < pMember->GetSkillValue(SKILL_ENCHANTING))
2466 {
2468 }
2469 }
2470}
bool IsSocketClosed() const
Definition WorldSession.cpp:640

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
2614{
2615 member_citerator mslot1 = _getMemberCSlot(guid1);
2616 if (mslot1 == m_memberSlots.end() || !slot2)
2617 return false;
2618 return (mslot1->group == slot2->group);
2619}

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

◆ SameSubGroup() [2/3]

bool Group::SameSubGroup ( ObjectGuid  guid1,
ObjectGuid  guid2 
) const
2606{
2607 member_citerator mslot2 = _getMemberCSlot(guid2);
2608 if (mslot2 == m_memberSlots.end())
2609 return false;
2610 return SameSubGroup(guid1, &*mslot2);
2611}
bool SameSubGroup(ObjectGuid guid1, ObjectGuid guid2) const
Definition Group.cpp:2605

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
2032{
2033 if (!member1 || !member2)
2034 return false;
2035
2036 if (member1->GetGroup() != this || member2->GetGroup() != this)
2037 return false;
2038 else
2039 return member1->GetSubGroup() == member2->GetSubGroup();
2040}

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

◆ SendLootAllPassed()

void Group::SendLootAllPassed ( Roll const &  roll)
1094{
1095 WorldPacket data(SMSG_LOOT_ALL_PASSED, (8 + 4 + 4 + 4 + 4));
1096 data << roll.itemGUID; // Guid of the item rolled
1097 data << uint32(roll.itemSlot); // Item loot slot
1098 data << uint32(roll.itemid); // The itemEntryId for the item that shall be rolled for
1099 data << uint32(roll.itemRandomPropId); // Item random property ID
1100 data << uint32(roll.itemRandomSuffix); // Item random suffix ID
1101
1102 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
1103 {
1104 Player* player = ObjectAccessor::FindConnectedPlayer(itr->first);
1105 if (!player)
1106 continue;
1107
1108 if (itr->second != NOT_VALID)
1109 player->SendDirectMessage(&data);
1110 }
1111}
@ 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 
)
1115{
1116 ASSERT(creature);
1117
1118 WorldPacket data(SMSG_LOOT_LIST, (8 + 8));
1119 data << creature->GetGUID();
1120
1121 if (GetLootMethod() == MASTER_LOOT && creature->loot.hasOverThresholdItem())
1123 else
1124 data << uint8(0);
1125
1126 if (groupLooter)
1127 data << groupLooter->GetPackGUID();
1128 else
1129 data << uint8(0);
1130
1131 BroadcastPacket(&data, false);
1132}
@ MASTER_LOOT
Definition LootMgr.h:60
Loot loot
Definition Creature.h:231
ObjectGuid GetMasterLooterGuid() const
Definition Group.cpp:2568
LootMethod GetLootMethod() const
Definition Group.cpp:2558
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 
)
1047{
1048 WorldPacket data(SMSG_LOOT_ROLL, (8 + 4 + 8 + 4 + 4 + 4 + 1 + 1 + 1));
1049 data << sourceGuid; // guid of the item rolled
1050 data << uint32(roll.itemSlot); // slot
1051 data << targetGuid;
1052 data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
1053 data << uint32(roll.itemRandomSuffix); // randomSuffix
1054 data << uint32(roll.itemRandomPropId); // Item random property ID
1055 data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
1056 data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
1057 data << uint8(autoPass); // 1: "You automatically passed on: %s because you cannot loot that item."
1058
1059 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
1060 {
1062 if (!p)
1063 continue;
1064
1065 if (itr->second != NOT_VALID)
1066 p->SendDirectMessage(&data);
1067 }
1068}
@ 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 
)
1071{
1072 WorldPacket data(SMSG_LOOT_ROLL_WON, (8 + 4 + 4 + 4 + 4 + 8 + 1 + 1));
1073 data << sourceGuid; // guid of the item rolled
1074 data << uint32(roll.itemSlot); // slot
1075 data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
1076 data << uint32(roll.itemRandomSuffix); // randomSuffix
1077 data << uint32(roll.itemRandomPropId); // Item random property
1078 data << targetGuid; // guid of the player who won.
1079 data << uint8(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
1080 data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL
1081
1082 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
1083 {
1085 if (!p)
1086 continue;
1087
1088 if (itr->second != NOT_VALID)
1089 p->SendDirectMessage(&data);
1090 }
1091}
@ 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 
)
957{
958 WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
959 data << r.itemGUID; // guid of rolled item
960 data << uint32(mapid); // 3.3.3 mapid
961 data << uint32(r.itemSlot); // itemslot
962 data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
963 data << uint32(r.itemRandomSuffix); // randomSuffix
964 data << uint32(r.itemRandomPropId); // item random property ID
965 data << uint32(r.itemCount); // items in stack
966 data << uint32(CountDown); // the countdown time to choose "need" or "greed"
967 data << uint8(r.rollVoteMask); // roll type mask
968
969 for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
970 {
972 if (!p)
973 continue;
974
975 if (itr->second == NOT_EMITED_YET)
976 p->SendDirectMessage(&data);
977 }
978}
@ 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 
)
1025{
1026 if (!p)
1027 return;
1028
1029 WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
1030 data << r.itemGUID; // guid of rolled item
1031 data << uint32(mapId); // 3.3.3 mapid
1032 data << uint32(r.itemSlot); // itemslot
1033 data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
1034 data << uint32(r.itemRandomSuffix); // randomSuffix
1035 data << uint32(r.itemRandomPropId); // item random property ID
1036 data << uint32(r.itemCount); // items in stack
1037 data << uint32(countDown); // the countdown time to choose "need" or "greed"
1038 uint8 voteMask = r.rollVoteMask;
1039 if (!canNeed)
1040 voteMask &= ~ROLL_FLAG_TYPE_NEED;
1041 data << uint8(voteMask); // roll type mask
1042
1043 p->SendDirectMessage(&data);
1044}

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 
)
981{
982 for (Roll* roll : RollId)
983 {
984 auto itr = roll->playerVote.find(player->GetGUID());
985 if (itr == roll->playerVote.end())
986 continue;
987
988 if (itr->second != NOT_EMITED_YET)
989 continue;
990
991 Loot* loot = roll->getLoot();
992 if (!loot)
993 continue;
994
995 // Get remaining time from the loot source object
996 uint32 remainingTime = 60000;
997 WorldObject* lootedObject = nullptr;
998 if (GameObject* go = loot->sourceGameObject)
999 {
1000 remainingTime = go->m_groupLootTimer;
1001 lootedObject = go;
1002 }
1003 else if (!loot->sourceWorldObjectGUID.IsEmpty())
1004 {
1005 if (Creature* creature = map->GetCreature(loot->sourceWorldObjectGUID))
1006 {
1007 remainingTime = creature->m_groupLootTimer;
1008 lootedObject = creature;
1009 }
1010 }
1011
1012 bool canNeed = true;
1014 {
1015 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(roll->itemid);
1016 if (proto && lootedObject)
1017 canNeed = (player->CanRollForItemInLFG(proto, lootedObject) == EQUIP_ERR_OK);
1018 }
1019
1020 SendLootStartRollToPlayer(remainingTime, map->GetId(), player, canNeed, *roll);
1021 }
1022}
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)
1875{
1876 if (!session)
1877 return;
1878
1880 data << uint8(1); // list targets
1881
1882 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
1883 {
1884 if (!m_targetIcons[i])
1885 continue;
1886
1887 data << uint8(i);
1888 data << m_targetIcons[i];
1889 }
1890
1891 session->SendPacket(&data);
1892}
@ 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 ( )
1895{
1896 if (sToCloud9Sidecar->ClusterModeEnabled() && !this->isBFGroup() && !this->isBGGroup())
1897 {
1898 // Group service responsible for sending these updates.
1899 return;
1900 }
1901
1902 for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr)
1903 SendUpdateToPlayer(witr->guid, &(*witr));
1904}
void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot *slot=nullptr)
Definition Group.cpp:1906

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 
)
1907{
1908 Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID);
1909
1910 if (!player || player->GetGroup() != this)
1911 return;
1912
1913 // if MemberSlot wasn't provided
1914 if (!slot)
1915 {
1916 member_witerator witr = _getMemberWSlot(playerGUID);
1917
1918 if (witr == m_memberSlots.end()) // if there is no MemberSlot for such a player
1919 return;
1920
1921 slot = &(*witr);
1922 }
1923
1924 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));
1925 data << uint8(m_groupType); // group type (flags in 3.3)
1926 data << uint8(slot->group);
1927 data << uint8(slot->flags);
1928 data << uint8(slot->roles);
1929 if (isLFGGroup())
1930 {
1931 data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done
1932 data << uint32(sLFGMgr->GetDungeon(m_guid));
1933 }
1934
1935 data << m_guid;
1936 data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent
1937 data << uint32(GetMembersCount() - 1);
1938 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1939 {
1940 if (slot->guid == citr->guid)
1941 continue;
1942
1943 Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid);
1944
1945 uint8 onlineState = (member && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
1946 onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0);
1947
1948 data << citr->name;
1949 data << citr->guid; // guid
1950 data << uint8(onlineState); // online-state
1951 data << uint8(citr->group); // groupid
1952 data << uint8(citr->flags); // See enum GroupMemberFlags
1953 data << uint8(citr->roles); // Lfg Roles
1954 }
1955
1956 data << m_leaderGuid; // leader guid
1957
1958 if (GetMembersCount() - 1)
1959 {
1960 data << uint8(m_lootMethod); // loot method
1961
1963 data << m_masterLooterGuid; // master looter guid
1964 else
1965 data << uint64(0); // looter guid
1966
1967 data << uint8(m_lootThreshold); // loot threshold
1968 data << uint8(m_dungeonDifficulty); // Dungeon Difficulty
1969 data << uint8(m_raidDifficulty); // Raid Difficulty
1970 data << uint8(m_raidDifficulty >= RAID_DIFFICULTY_10MAN_HEROIC); // 3.3 Dynamic Raid Difficulty - 0 normal/1 heroic
1971 }
1972
1973 player->SendDirectMessage(&data);
1974}
@ 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)
2640{
2641 m_bfGroup = bg;
2642}

References m_bfGroup.

Referenced by Battlefield::AddOrSetPlayerToCorrectBfGroup().

◆ SetBattlegroundGroup()

void Group::SetBattlegroundGroup ( Battleground *  bg)
2635{
2636 m_bgGroup = bg;
2637}

References m_bgGroup.

Referenced by Battleground::SetBgRaid().

◆ SetDifficultyChangePrevention()

◆ SetDungeonDifficulty()

void Group::SetDungeonDifficulty ( Difficulty  difficulty)
2316{
2317 m_dungeonDifficulty = difficulty;
2318 if (!sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup())
2319 {
2321
2323 stmt->SetData(1, GetGUID().GetCounter());
2324
2325 CharacterDatabase.Execute(stmt);
2326 }
2327
2328 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
2329 {
2330 Player* player = itr->GetSource();
2331 player->SetDungeonDifficulty(difficulty);
2332 player->SendDungeonDifficulty(true);
2333 }
2334}
@ 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 
)
2645{
2646 // Assistants, main assistants and main tanks are only available in raid groups
2647 if (!isRaidGroup())
2648 return;
2649
2650 // Check if player is really in the raid
2651 member_witerator slot = _getMemberWSlot(guid);
2652 if (slot == m_memberSlots.end())
2653 return;
2654
2655 // Do flag specific actions, e.g ensure uniqueness
2656 switch (flag)
2657 {
2659 RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); // Remove main assist flag from current if any.
2660 break;
2662 RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main tank flag from current if any.
2663 break;
2665 break;
2666 default:
2667 return; // This should never happen
2668 }
2669
2670 // Switch the actual flag
2671 ToggleGroupMemberFlag(slot, flag, apply);
2672
2673 // Preserve the new setting in the db
2675
2676 stmt->SetData(0, slot->flags);
2677 stmt->SetData(1, guid.GetCounter());
2678
2679 CharacterDatabase.Execute(stmt);
2680
2681 // Broadcast the changes to the group
2682 SendUpdate();
2683}
@ 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:2759

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 
)
2493{
2494 member_witerator slot = _getMemberWSlot(guid);
2495 if (slot == m_memberSlots.end())
2496 return;
2497
2498 slot->roles = roles;
2499 SendUpdate();
2500}

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

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

◆ SetLooterGuid()

void Group::SetLooterGuid ( ObjectGuid  guid)
2478{
2479 m_looterGuid = guid;
2480}

References m_looterGuid.

Referenced by UpdateLooterGuid().

◆ SetLootMethod()

void Group::SetLootMethod ( LootMethod  method)
2473{
2474 m_lootMethod = method;
2475}

References m_lootMethod.

Referenced by WorldSession::HandleLootMethodOpcode().

◆ SetLootThreshold()

void Group::SetLootThreshold ( ItemQualities  threshold)
2488{
2489 m_lootThreshold = threshold;
2490}

References m_lootThreshold.

Referenced by WorldSession::HandleLootMethodOpcode().

◆ SetMasterLooterGuid()

void Group::SetMasterLooterGuid ( ObjectGuid  guid)
2483{
2484 m_masterLooterGuid = guid;
2485}

References m_masterLooterGuid.

Referenced by WorldSession::HandleLootMethodOpcode().

◆ SetRaidDifficulty()

void Group::SetRaidDifficulty ( Difficulty  difficulty)
2337{
2338 m_raidDifficulty = difficulty;
2339 if (!sToCloud9Sidecar->ClusterModeEnabled() && !isBGGroup() && !isBFGroup())
2340 {
2342
2343 stmt->SetData(0, uint8(m_raidDifficulty));
2344 stmt->SetData(1, GetGUID().GetCounter());
2345
2346 CharacterDatabase.Execute(stmt);
2347 }
2348
2349 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
2350 {
2351 Player* player = itr->GetSource();
2352 player->SetRaidDifficulty(difficulty);
2353 player->SendRaidDifficulty(true);
2354 }
2355}
@ 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 
)
1854{
1855 if (id >= TARGETICONCOUNT)
1856 return;
1857
1858 // clean other icons
1859 if (targetGuid)
1860 for (int i = 0; i < TARGETICONCOUNT; ++i)
1861 if (m_targetIcons[i] == targetGuid)
1863
1864 m_targetIcons[id] = targetGuid;
1865
1866 WorldPacket data(MSG_RAID_TARGET_UPDATE, (1 + 8 + 1 + 8));
1867 data << uint8(0); // set targets
1868 data << whoGuid;
1869 data << uint8(id);
1870 data << targetGuid;
1871 BroadcastPacket(&data, true);
1872}
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid)
Definition Group.cpp:1853

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
2754{
2756 --m_subGroupsCounts[subgroup];
2757}

References m_subGroupsCounts.

Referenced by ChangeMembersGroup(), and RemoveMember().

◆ SubGroupCounterIncrease()

void Group::SubGroupCounterIncrease ( uint8  subgroup)
protected
2748{
2750 ++m_subGroupsCounts[subgroup];
2751}

References m_subGroupsCounts.

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

◆ ToggleGroupMemberFlag()

void Group::ToggleGroupMemberFlag ( member_witerator  slot,
uint8  flag,
bool  apply 
)
protected
2767{
2768 if (apply)
2769 slot->flags |= flag;
2770 else
2771 slot->flags &= ~flag;
2772}

Referenced by ChangeLeader(), and SetGroupMemberFlag().

◆ UpdateLooterGuid()

void Group::UpdateLooterGuid ( WorldObject *  pLootedObject,
bool  ifneed = false 
)
2104{
2105 // round robin style looting applies for all low
2106 // quality items in each loot method except free for all
2107 if (GetLootMethod() == FREE_FOR_ALL)
2108 return;
2109
2110 ObjectGuid oldLooterGUID = GetLooterGuid();
2111 member_citerator guid_itr = _getMemberCSlot(oldLooterGUID);
2112 if (guid_itr != m_memberSlots.end())
2113 {
2114 if (ifneed)
2115 {
2116 // not update if only update if need and ok
2117 Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
2118 if (looter && looter->IsAtLootRewardDistance(pLootedObject))
2119 return;
2120 }
2121 ++guid_itr;
2122 }
2123
2124 // search next after current
2125 Player* pNewLooter = nullptr;
2126 for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr)
2127 {
2128 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
2129 if (player->IsAtLootRewardDistance(pLootedObject))
2130 {
2131 pNewLooter = player;
2132 break;
2133 }
2134 }
2135
2136 if (!pNewLooter)
2137 {
2138 // search from start
2139 for (member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr)
2140 {
2141 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
2142 if (player->IsAtLootRewardDistance(pLootedObject))
2143 {
2144 pNewLooter = player;
2145 break;
2146 }
2147 }
2148 }
2149
2150 if (pNewLooter)
2151 {
2152 if (oldLooterGUID != pNewLooter->GetGUID())
2153 {
2154 SetLooterGuid(pNewLooter->GetGUID());
2155 SendUpdate();
2156 }
2157 }
2158 else
2159 {
2161 SendUpdate();
2162 }
2163}
ObjectGuid GetLooterGuid() const
Definition Group.cpp:2563
void SetLooterGuid(ObjectGuid guid)
Definition Group.cpp:2477

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)
1977{
1978 if (!player || !player->IsInWorld())
1979 return;
1980
1981 WorldPacket data;
1982 player->GetSession()->BuildPartyMemberStatsChangedPacket(player, &data);
1983
1984 for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next())
1985 {
1986 Player* member = itr->GetSource();
1987 if (member && (!member->IsInMap(player) || !member->IsWithinDist(player, member->GetSightRange(player), false)))
1988 member->SendDirectMessage(&data);
1989 }
1990}
float GetSightRange(WorldObject const *target=nullptr) const override
Definition Player.cpp:16721
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: