TrinityCore
Loading...
Searching...
No Matches
Group.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Group.h"
19#include "Battleground.h"
20#include "BattlegroundMgr.h"
21#include "CharacterCache.h"
22#include "DatabaseEnv.h"
23#include "DB2Stores.h"
24#include "Formulas.h"
25#include "GameObject.h"
26#include "GameTime.h"
27#include "GroupMgr.h"
28#include "Item.h"
29#include "LFGMgr.h"
30#include "Log.h"
31#include "Loot.h"
32#include "MapManager.h"
33#include "MiscPackets.h"
34#include "ObjectAccessor.h"
35#include "ObjectMgr.h"
36#include "PartyPackets.h"
37#include "Pet.h"
38#include "Player.h"
39#include "UpdateData.h"
40#include "WorldSession.h"
41
43{
44 return Seconds(std::max<time_t>(_endTime - GameTime::GetGameTime(), 0));
45}
46
48{
49 _startTime = startTime ? *startTime : GameTime::GetGameTime();
50 _endTime = _startTime + duration.count();
51}
52
54{
55 return _endTime > GameTime::GetGameTime();
56}
57
72
74{
75 if (m_bgGroup)
76 {
77 TC_LOG_DEBUG("bg.battleground", "Group::~Group: battleground group being deleted.");
78 if (m_bgGroup->GetBgRaid(ALLIANCE) == this)
79 m_bgGroup->SetBgRaid(ALLIANCE, nullptr);
80 else if (m_bgGroup->GetBgRaid(HORDE) == this)
81 m_bgGroup->SetBgRaid(HORDE, nullptr);
82 else
83 TC_LOG_ERROR("misc", "Group::~Group: battleground group is not linked to the correct battleground.");
84 }
85
86 // Sub group counters clean up
87 delete[] m_subGroupsCounts;
88}
89
91{
93 {
96 {
98 m_isLeaderOffline = false;
99 }
100 }
101
102 UpdateReadyCheck(diff);
103}
104
106{
107 Player* newLeader = nullptr;
108
109 // Attempt to give leadership to main assistant first
110 if (isRaidGroup())
111 {
112 for (Group::MemberSlot const& memberSlot : m_memberSlots)
113 {
114 if ((memberSlot.flags & MEMBER_FLAG_ASSISTANT) == MEMBER_FLAG_ASSISTANT)
115 if (Player* player = ObjectAccessor::FindPlayer(memberSlot.guid))
116 {
117 newLeader = player;
118 break;
119 }
120 }
121 }
122
123 // If there aren't assistants in raid, or if the group is not a raid, pick the first available member
124 if (!newLeader)
125 {
126 for (Group::MemberSlot const& memberSlot : m_memberSlots)
127 if (Player* player = ObjectAccessor::FindPlayer(memberSlot.guid))
128 {
129 newLeader = player;
130 break;
131 }
132 }
133
134 if (newLeader)
135 {
136 ChangeLeader(newLeader->GetGUID());
137 SendUpdate();
138 }
139}
140
142{
143 ObjectGuid leaderGuid = leader->GetGUID();
144
145 m_guid = ObjectGuid::Create<HighGuid::Party>(sGroupMgr->GenerateGroupId());
146 m_leaderGuid = leaderGuid;
148 m_leaderName = leader->GetName();
150
151 if (isBGGroup() || isBFGroup())
152 {
155 }
156
159
161 m_looterGuid = leaderGuid;
163
167
168 if (!isBGGroup() && !isBFGroup())
169 {
173
174 m_dbStoreId = sGroupMgr->GenerateNewGroupDbStoreId();
175
176 sGroupMgr->RegisterGroupDbStoreId(m_dbStoreId, this);
177
178 // Store group in database
180
181 uint8 index = 0;
182
183 stmt->setUInt32(index++, m_dbStoreId);
184 stmt->setUInt64(index++, m_leaderGuid.GetCounter());
185 stmt->setUInt8(index++, uint8(m_lootMethod));
186 stmt->setUInt64(index++, m_looterGuid.GetCounter());
187 stmt->setUInt8(index++, uint8(m_lootThreshold));
188 for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i)
189 stmt->setBinary(index++, m_targetIcons[i].GetRawValue());
190 stmt->setUInt16(index++, m_groupFlags);
191 stmt->setUInt32(index++, uint8(m_dungeonDifficulty));
192 stmt->setUInt32(index++, uint8(m_raidDifficulty));
193 stmt->setUInt32(index++, uint8(m_legacyRaidDifficulty));
194 stmt->setUInt64(index++, m_masterLooterGuid.GetCounter());
195 stmt->setInt8(index++, int8(m_pingRestriction));
196
197 CharacterDatabase.Execute(stmt);
198
199 if (InstanceMap* leaderInstance = leader->GetMap()->ToInstanceMap())
200 leaderInstance->TrySetOwningGroup(this);
201
202 bool addMemberResult = AddMember(leader);
203 ASSERT(addMemberResult); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
204 }
205 else if (!AddMember(leader))
206 return false;
207
208 return true;
209}
210
212{
213 m_dbStoreId = fields[17].GetUInt32();
214 m_guid = ObjectGuid::Create<HighGuid::Party>(sGroupMgr->GenerateGroupId());
215 m_leaderGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
216
217 // group leader not exist
218 CharacterCacheEntry const* leader = sCharacterCache->GetCharacterCacheByGuid(m_leaderGuid);
219 if (!leader)
220 return;
221
223 m_leaderName = leader->Name;
224 m_lootMethod = LootMethod(fields[1].GetUInt8());
225 m_looterGuid = ObjectGuid::Create<HighGuid::Player>(fields[2].GetUInt64());
226 m_lootThreshold = ItemQualities(fields[3].GetUInt8());
227
228 for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i)
229 if (std::span<uint8 const> rawGuidBytes = fields[4 + i].GetBinaryView(); rawGuidBytes.size() == ObjectGuid::BytesSize)
230 m_targetIcons[i].SetRawValue(rawGuidBytes);
231
232 m_groupFlags = GroupFlags(fields[12].GetUInt16());
235
239
240 m_masterLooterGuid = fields[16].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[16].GetUInt64()) : ObjectGuid::Empty;
241
242 m_pingRestriction = RestrictPingsTo(fields[18].GetInt8());
243
245 sLFGMgr->_LoadFromDB(fields, GetGUID());
246}
247
248void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
249{
250 MemberSlot member;
251 member.guid = ObjectGuid::Create<HighGuid::Player>(guidLow);
252
253 // skip non-existed member
254 CharacterCacheEntry const* character = sCharacterCache->GetCharacterCacheByGuid(member.guid);
255 if (!character)
256 {
258 stmt->setUInt64(0, guidLow);
259 CharacterDatabase.Execute(stmt);
260 return;
261 }
262
264 memberFlags |= MEMBER_FLAG_ASSISTANT;
265
266 member.name = character->Name;
267 member.race = Races(character->Race);
268 member._class = character->Class;
269 member.group = subgroup;
270 member.flags = memberFlags;
271 member.roles = roles;
272 member.readyChecked = false;
273
274 m_memberSlots.push_back(member);
275
276 SubGroupCounterIncrease(subgroup);
277
278 sLFGMgr->SetupGroupMember(member.guid, GetGUID());
279}
280
298
300{
302
304
305 if (!isBGGroup() && !isBFGroup())
306 {
308
309 stmt->setUInt16(0, m_groupFlags);
310 stmt->setUInt32(1, m_dbStoreId);
311
312 CharacterDatabase.Execute(stmt);
313 }
314
315 SendUpdate();
316
317 // update quest related GO states (quest activity dependent from raid membership)
318 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
319 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
320 player->UpdateVisibleObjectInteractions(false, true, false, true);
321}
322
324{
325 if (m_memberSlots.size() > 5)
326 return; // What message error should we send?
327
329
331 {
332 delete[] m_subGroupsCounts;
333 m_subGroupsCounts = nullptr;
334 }
335
336 if (!isBGGroup() && !isBFGroup())
337 {
339
340 stmt->setUInt16(0, m_groupFlags);
341 stmt->setUInt32(1, m_dbStoreId);
342
343 CharacterDatabase.Execute(stmt);
344 }
345
346 SendUpdate();
347
348 // update quest related GO states (quest activity dependent from raid membership)
349 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
350 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
351 player->UpdateVisibleObjectInteractions(false, true, false, true);
352}
353
355{
356 if (!player || player->GetGroupInvite())
357 return false;
358 Group* group = player->GetGroup();
359 if (group && (group->isBGGroup() || group->isBFGroup()))
360 group = player->GetOriginalGroup();
361 if (group)
362 return false;
363
364 RemoveInvite(player);
365
366 m_invitees.insert(player);
367
368 player->SetGroupInvite(this);
369
370 sScriptMgr->OnGroupInviteMember(this, player->GetGUID());
371
372 return true;
373}
374
376{
377 if (!AddInvite(player))
378 return false;
379
380 m_leaderGuid = player->GetGUID();
382 m_leaderName = player->GetName();
383 return true;
384}
385
387{
388 if (player)
389 {
390 m_invitees.erase(player);
391 player->SetGroupInvite(nullptr);
392 }
393}
394
396{
397 for (InvitesList::iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
398 if (*itr)
399 (*itr)->SetGroupInvite(nullptr);
400
401 m_invitees.clear();
402}
403
405{
406 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
407 {
408 if ((*itr) && (*itr)->GetGUID() == guid)
409 return (*itr);
410 }
411 return nullptr;
412}
413
414Player* Group::GetInvited(const std::string& name) const
415{
416 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
417 {
418 if ((*itr) && (*itr)->GetName() == name)
419 return (*itr);
420 }
421 return nullptr;
422}
423
425{
426 // Get first not-full group
427 uint8 subGroup = 0;
429 {
430 bool groupFound = false;
431 for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup)
432 {
433 if (m_subGroupsCounts[subGroup] < MAX_GROUP_SIZE)
434 {
435 groupFound = true;
436 break;
437 }
438 }
439 // We are raid group and no one slot is free
440 if (!groupFound)
441 return false;
442 }
443
444 MemberSlot member;
445 member.guid = player->GetGUID();
446 member.name = player->GetName();
447 member.race = Races(player->GetRace());
448 member._class = player->GetClass();
449 member.group = subGroup;
450 member.flags = 0;
451 member.roles = 0;
452 member.readyChecked = false;
453 m_memberSlots.push_back(member);
454
455 SubGroupCounterIncrease(subGroup);
456
457 player->SetGroupInvite(nullptr);
458 if (player->GetGroup())
459 {
460 if (isBGGroup() || isBFGroup()) // if player is in group and he is being added to BG raid group, then call SetBattlegroundRaid()
461 player->SetBattlegroundOrBattlefieldRaid(this, subGroup);
462 else //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
463 player->SetOriginalGroup(this, subGroup);
464 }
465 else //if player is not in group, then call set group
466 player->SetGroup(this, subGroup);
467
470
471 // if the same group invites the player back, cancel the homebind timer
472 player->m_InstanceValid = player->CheckInstanceValidity(false);
473
474 if (!isRaidGroup()) // reset targetIcons for non-raid-groups
475 {
476 for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i)
477 m_targetIcons[i].Clear();
478 }
479
480 // insert into the table if we're not a battleground group
481 if (!isBGGroup() && !isBFGroup())
482 {
484
485 stmt->setUInt32(0, m_dbStoreId);
486 stmt->setUInt64(1, member.guid.GetCounter());
487 stmt->setUInt8(2, member.flags);
488 stmt->setUInt8(3, member.group);
489 stmt->setUInt8(4, member.roles);
490
491 CharacterDatabase.Execute(stmt);
492 }
493
494 SendUpdate();
495 sScriptMgr->OnGroupAddMember(this, player->GetGUID());
496
497 if (!IsLeader(player->GetGUID()) && !isBGGroup() && !isBFGroup())
498 {
500 {
502 player->SendDungeonDifficulty();
503 }
504 if (player->GetRaidDifficultyID() != GetRaidDifficultyID())
505 {
507 player->SendRaidDifficulty(false);
508 }
510 {
512 player->SendRaidDifficulty(true);
513 }
514 }
515
517 if (Pet* pet = player->GetPet())
518 pet->SetGroupUpdateFlag(GROUP_UPDATE_PET_FULL);
519
521
522 // quest related GO state dependent from raid membership
523 if (isRaidGroup())
524 player->UpdateVisibleObjectInteractions(false, true, false, true);
525
527
528 {
529 // Broadcast new player group member fields to rest of the group
530 UpdateData groupData(player->GetMapId());
531 WorldPacket groupDataPacket;
532
533 // Broadcast group members' fields to player
534 for (GroupReference const& itr : GetMembers())
535 {
536 Player* existingMember = itr.GetSource();
537 if (existingMember == player)
538 continue;
539
540 if (player->HaveAtClient(existingMember))
542
543 if (existingMember->HaveAtClient(player))
544 {
545 UpdateData newData(player->GetMapId());
546 WorldPacket newDataPacket;
548 if (newData.HasData())
549 {
550 newData.BuildPacket(&newDataPacket);
551 existingMember->SendDirectMessage(&newDataPacket);
552 }
553 }
554 }
555
556 if (groupData.HasData())
557 {
558 groupData.BuildPacket(&groupDataPacket);
559 player->SendDirectMessage(&groupDataPacket);
560 }
561 }
562
563 return true;
564}
565
566bool Group::RemoveMember(ObjectGuid guid, RemoveMethod method /*= GROUP_REMOVEMETHOD_DEFAULT*/, ObjectGuid kicker /*= 0*/, const char* reason /*= nullptr*/)
567{
569
570 sScriptMgr->OnGroupRemoveMember(this, guid, method, kicker, reason);
571
573 if (player)
574 {
575 for (GroupReference const& itr : GetMembers())
576 {
577 Player* groupMember = itr.GetSource();
578 if (groupMember->GetGUID() == guid)
579 continue;
580
581 groupMember->RemoveAllGroupBuffsFromCaster(guid);
582 player->RemoveAllGroupBuffsFromCaster(groupMember->GetGUID());
583 }
584 }
585
586 // LFG group vote kick handled in scripts
587 if (isLFGGroup() && method == GROUP_REMOVEMETHOD_KICK)
588 return !m_memberSlots.empty();
589
590 if (player)
592
593 // remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group)
594 if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u))
595 {
596 if (player)
597 {
598 // Battleground group handling
599 if (isBGGroup() || isBFGroup())
601 else
602 // Regular group
603 {
604 if (player->GetOriginalGroup() == this)
605 player->SetOriginalGroup(nullptr);
606 else
607 player->SetGroup(nullptr);
608
609 // quest related GO state dependent from raid membership
610 player->UpdateVisibleObjectInteractions(false, true, false, true);
611 }
612
614
615 if (method == GROUP_REMOVEMETHOD_KICK || method == GROUP_REMOVEMETHOD_KICK_LFG)
617
618 _homebindIfInstance(player);
619 }
620
621 // Remove player from group in DB
622 if (!isBGGroup() && !isBFGroup())
623 {
625 stmt->setUInt64(0, guid.GetCounter());
626 CharacterDatabase.Execute(stmt);
627 DelinkMember(guid);
628 }
629
630 // Update subgroups
632 if (slot != m_memberSlots.end())
633 {
634 SubGroupCounterDecrease(slot->group);
635 m_memberSlots.erase(slot);
636 }
637
638 // Pick new leader if necessary
639 if (m_leaderGuid == guid)
640 {
641 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
642 {
644 {
645 ChangeLeader(itr->guid);
646 break;
647 }
648 }
649 }
650
651 SendUpdate();
652
653 if (isLFGGroup() && GetMembersCount() == 1)
654 {
656 uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID());
657 if (!mapId || !leader || (leader->IsAlive() && leader->GetMapId() != mapId))
658 {
659 Disband();
660 return false;
661 }
662 }
663
664 if (m_memberMgr.size() < ((isLFGGroup() || isBGGroup()) ? 1u : 2u))
665 Disband();
666 else if (player)
667 {
668 // send update to removed player too so party frames are destroyed clientside
670 }
671
672 return true;
673 }
674 // If group size before player removal <= 2 then disband it
675 else
676 {
677 Disband();
678 return false;
679 }
680}
681
683{
684 member_witerator slot = _getMemberWSlot(newLeaderGuid);
685
686 if (slot == m_memberSlots.end())
687 return;
688
689 Player* newLeader = ObjectAccessor::FindConnectedPlayer(slot->guid);
690
691 // Don't allow switching leader to offline players
692 if (!newLeader)
693 return;
694
695 sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid);
696
697 if (!isBGGroup() && !isBFGroup())
698 {
699 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
700
701 // Update the group leader
703
704 stmt->setUInt64(0, newLeader->GetGUID().GetCounter());
705 stmt->setUInt32(1, m_dbStoreId);
706
707 trans->Append(stmt);
708
709 CharacterDatabase.CommitTransaction(trans);
710 }
711
713 oldLeader->RemovePlayerFlag(PLAYER_FLAGS_GROUP_LEADER);
714
716 m_leaderGuid = newLeader->GetGUID();
718 m_leaderName = newLeader->GetName();
720
722 groupNewLeader.Name = m_leaderName;
723 groupNewLeader.PartyIndex = GetGroupCategory();
724 BroadcastPacket(groupNewLeader.Write(), true);
725}
726
727void Group::Disband(bool hideDestroy /* = false */)
728{
729 sScriptMgr->OnGroupDisband(this);
730
731 Player* player;
732 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
733 {
734 player = ObjectAccessor::FindConnectedPlayer(citr->guid);
735 if (!player)
736 continue;
737
738 //we cannot call _removeMember because it would invalidate member iterator
739 //if we are removing player from battleground raid
740 if (isBGGroup() || isBFGroup())
742 else
743 {
744 //we can remove player who is in battleground from his original group
745 if (player->GetOriginalGroup() == this)
746 player->SetOriginalGroup(nullptr);
747 else
748 player->SetGroup(nullptr);
749 }
750
752
753 // quest related GO state dependent from raid membership
754 if (isRaidGroup())
755 player->UpdateVisibleObjectInteractions(false, true, false, true);
756
757 if (!hideDestroy)
759
761
762 _homebindIfInstance(player);
763 }
764
765 m_memberSlots.clear();
766
768
769 if (!isBGGroup() && !isBFGroup())
770 {
771 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
772
774 stmt->setUInt32(0, m_dbStoreId);
775 trans->Append(stmt);
776
777 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER_ALL);
778 stmt->setUInt32(0, m_dbStoreId);
779 trans->Append(stmt);
780
781 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
782 stmt->setUInt32(0, m_dbStoreId);
783 trans->Append(stmt);
784
785 CharacterDatabase.CommitTransaction(trans);
786
787 sGroupMgr->FreeGroupDbStoreId(this);
788 }
789
790 sGroupMgr->RemoveGroup(this);
791 delete this;
792}
793
794void Group::SetTargetIcon(uint8 symbol, ObjectGuid target, ObjectGuid changedBy)
795{
796 if (symbol >= TARGET_ICONS_COUNT)
797 return;
798
799 // clean other icons
800 if (!target.IsEmpty())
801 for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i)
802 if (m_targetIcons[i] == target)
803 SetTargetIcon(i, ObjectGuid::Empty, changedBy);
804
805 m_targetIcons[symbol] = target;
806
808 updateSingle.PartyIndex = GetGroupCategory();
809 updateSingle.Target = target;
810 updateSingle.ChangedBy = changedBy;
811 updateSingle.Symbol = symbol;
812 BroadcastPacket(updateSingle.Write(), true);
813}
814
816{
817 if (!session)
818 return;
819
821 updateAll.PartyIndex = GetGroupCategory();
822 for (uint8 i = 0; i < TARGET_ICONS_COUNT; i++)
823 updateAll.TargetIcons.emplace_back(i, m_targetIcons[i]);
824
825 session->SendPacket(updateAll.Write());
826}
827
829{
830 for (MemberSlot const& memberSlot : m_memberSlots)
831 SendUpdateToPlayer(memberSlot.guid, &memberSlot);
832}
833
834void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot const* slot) const
835{
836 Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID);
837
838 if (!player || !player->GetSession() || player->GetGroup() != this)
839 return;
840
841 // if MemberSlot wasn't provided
842 if (!slot)
843 {
844 member_citerator witr = _getMemberCSlot(playerGUID);
845
846 if (witr == m_memberSlots.end()) // if there is no MemberSlot for such a player
847 return;
848
849 slot = &(*witr);
850 }
851
853
854 partyUpdate.PartyFlags = m_groupFlags;
855 partyUpdate.PartyIndex = m_groupCategory;
857
858 partyUpdate.PartyGUID = m_guid;
859 partyUpdate.LeaderGUID = m_leaderGuid;
861
863
865
866 partyUpdate.MyIndex = -1;
867 uint8 index = 0;
868 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr, ++index)
869 {
870 if (slot->guid == citr->guid)
871 partyUpdate.MyIndex = index;
872
873 Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid);
874
875 WorldPackets::Party::PartyPlayerInfo& playerInfos = partyUpdate.PlayerList.emplace_back();
876
877 playerInfos.GUID = citr->guid;
878 playerInfos.Name = citr->name;
879 playerInfos.Class = citr->_class;
880
881 playerInfos.FactionGroup = Player::GetFactionGroupForRace(citr->race);
882
883 playerInfos.Connected = member && member->GetSession() && !member->GetSession()->PlayerLogout();
884
885 playerInfos.Subgroup = citr->group; // groupid
886 playerInfos.Flags = citr->flags; // See enum GroupMemberFlags
887 playerInfos.RolesAssigned = citr->roles; // Lfg Roles
888 }
889
890 if (GetMembersCount() > 1)
891 {
892 // LootSettings
893 partyUpdate.LootSettings.emplace();
894 partyUpdate.LootSettings->Method = m_lootMethod;
895 partyUpdate.LootSettings->Threshold = m_lootThreshold;
897
898 // Difficulty Settings
899 partyUpdate.DifficultySettings.emplace();
900 partyUpdate.DifficultySettings->DungeonDifficultyID = m_dungeonDifficulty;
901 partyUpdate.DifficultySettings->RaidDifficultyID = m_raidDifficulty;
902 partyUpdate.DifficultySettings->LegacyRaidDifficultyID = m_legacyRaidDifficulty;
903 }
904
905 // LfgInfos
906 if (isLFGGroup())
907 {
908 partyUpdate.LfgInfos.emplace();
909
910 partyUpdate.LfgInfos->Slot = sLFGMgr->GetLFGDungeonEntry(sLFGMgr->GetDungeon(m_guid));
911 partyUpdate.LfgInfos->BootCount = 0;
912 partyUpdate.LfgInfos->Aborted = false;
913
914 partyUpdate.LfgInfos->MyFlags = sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0;
915 partyUpdate.LfgInfos->MyRandomSlot = sLFGMgr->GetSelectedRandomDungeon(player->GetGUID());
916
917 partyUpdate.LfgInfos->MyPartialClear = 0;
918 partyUpdate.LfgInfos->MyGearDiff = 0.0f;
919 partyUpdate.LfgInfos->MyFirstReward = false;
920 if (lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(partyUpdate.LfgInfos->MyRandomSlot, player->GetLevel()))
921 if (Quest const* quest = sObjectMgr->GetQuestTemplate(reward->firstQuest))
922 partyUpdate.LfgInfos->MyFirstReward = player->CanRewardQuest(quest, false);
923
924 partyUpdate.LfgInfos->MyStrangerCount = 0;
925 partyUpdate.LfgInfos->MyKickVoteCount = 0;
926 }
927
928 player->SendDirectMessage(partyUpdate.Write());
929}
930
932{
934 partyUpdate.PartyFlags = GROUP_FLAG_DESTROYED;
935 partyUpdate.PartyIndex = m_groupCategory;
936 partyUpdate.PartyType = GROUP_TYPE_NONE;
937 partyUpdate.PartyGUID = m_guid;
938 partyUpdate.MyIndex = -1;
940 player->SendDirectMessage(partyUpdate.Write());
941}
942
943void Group::UpdatePlayerOutOfRange(Player const* player) const
944{
945 if (!player || !player->IsInWorld())
946 return;
947
949 packet.Initialize(player);
950 packet.Write();
951
952 for (GroupReference const& itr : GetMembers())
953 {
954 Player const* member = itr.GetSource();
955 if (member != player && (!member->IsInMap(player) || !member->IsWithinDist(player, member->GetSightRange(), false)))
956 member->SendDirectMessage(packet.GetRawPacket());
957 }
958}
959
960void Group::BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignore /*= ObjectGuid::Empty*/) const
961{
962 for (GroupReference const& itr : GetMembers())
963 {
964 Player* player = itr.GetSource();
965 if ((!ignore.IsEmpty() && player->GetGUID() == ignore) || (ignorePlayersInBGRaid && player->GetGroup() != this))
966 continue;
967
968 if (player->GetSession()->IsAddonRegistered(prefix) && (group == -1 || itr.getSubGroup() == group))
969 player->SendDirectMessage(packet);
970 }
971}
972
973void Group::BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignoredPlayer) const
974{
975 for (GroupReference const& itr : GetMembers())
976 {
977 Player const* player = itr.GetSource();
978 if ((!ignoredPlayer.IsEmpty() && player->GetGUID() == ignoredPlayer) || (ignorePlayersInBGRaid && player->GetGroup() != this))
979 continue;
980
981 if (group == -1 || itr.getSubGroup() == group)
982 player->SendDirectMessage(packet);
983 }
984}
985
987{
989 if (slot == m_memberSlots.end())
990 return false;
991
992 slot->group = group;
993
995
996 if (!isBGGroup() && !isBFGroup())
997 {
999
1000 stmt->setUInt8(0, group);
1001 stmt->setUInt64(1, guid.GetCounter());
1002
1003 CharacterDatabase.Execute(stmt);
1004 }
1005
1006 return true;
1007}
1008
1009bool Group::SameSubGroup(Player const* member1, Player const* member2) const
1010{
1011 if (!member1 || !member2)
1012 return false;
1013
1014 if (member1->GetGroup() != this || member2->GetGroup() != this)
1015 return false;
1016 else
1017 return member1->GetSubGroup() == member2->GetSubGroup();
1018}
1019
1020// Allows setting sub groups both for online or offline members
1022{
1023 // Only raid groups have sub groups
1024 if (!isRaidGroup())
1025 return;
1026
1027 // Check if player is really in the raid
1028 member_witerator slot = _getMemberWSlot(guid);
1029 if (slot == m_memberSlots.end())
1030 return;
1031
1032 uint8 prevSubGroup = slot->group;
1033 // Abort if the player is already in the target sub group
1034 if (prevSubGroup == group)
1035 return;
1036
1037 // Update the player slot with the new sub group setting
1038 slot->group = group;
1039
1040 // Increase the counter of the new sub group..
1042
1043 // ..and decrease the counter of the previous one
1044 SubGroupCounterDecrease(prevSubGroup);
1045
1046 // Preserve new sub group in database for non-raid groups
1047 if (!isBGGroup() && !isBFGroup())
1048 {
1050
1051 stmt->setUInt8(0, group);
1052 stmt->setUInt64(1, guid.GetCounter());
1053
1054 CharacterDatabase.Execute(stmt);
1055 }
1056
1057 // In case the moved player is online, update the player object with the new sub group references
1058 if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
1059 {
1060 if (player->GetGroup() == this)
1061 player->GetGroupRef().setSubGroup(group);
1062 else
1063 {
1064 // 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
1065 player->GetOriginalGroupRef().setSubGroup(group);
1066 }
1067 }
1068
1069 // Broadcast the changes to the group
1070 SendUpdate();
1071}
1072
1074{
1075 if (!isRaidGroup())
1076 return;
1077
1078 member_witerator slots[2];
1079 slots[0] = _getMemberWSlot(firstGuid);
1080 slots[1] = _getMemberWSlot(secondGuid);
1081 if (slots[0] == m_memberSlots.end() || slots[1] == m_memberSlots.end())
1082 return;
1083
1084 if (slots[0]->group == slots[1]->group)
1085 return;
1086
1087 uint8 tmp = slots[0]->group;
1088 slots[0]->group = slots[1]->group;
1089 slots[1]->group = tmp;
1090
1091 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1092 for (uint8 i = 0; i < 2; i++)
1093 {
1094 // Preserve new sub group in database for non-raid groups
1095 if (!isBGGroup() && !isBFGroup())
1096 {
1098
1099 stmt->setUInt8(0, slots[i]->group);
1100 stmt->setUInt64(1, slots[i]->guid.GetCounter());
1101
1102 trans->Append(stmt);
1103 }
1104
1105 if (Player* player = ObjectAccessor::FindConnectedPlayer(slots[i]->guid))
1106 {
1107 if (player->GetGroup() == this)
1108 player->GetGroupRef().setSubGroup(slots[i]->group);
1109 else
1110 player->GetOriginalGroupRef().setSubGroup(slots[i]->group);
1111 }
1112 }
1113 CharacterDatabase.CommitTransaction(trans);
1114
1115 SendUpdate();
1116}
1117
1118// Retrieve the next Round-Roubin player for the group
1119//
1120// No update done if loot method is FFA.
1121//
1122// If the RR player is not yet set for the group, the first group member becomes the round-robin player.
1123// If the RR player is set, the next player in group becomes the round-robin player.
1124//
1125// If ifneed is true,
1126// the current RR player is checked to be near the looted object.
1127// if yes, no update done.
1128// if not, he loses his turn.
1129void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
1130{
1131 // round robin style looting applies for all low
1132 // quality items in each loot method except free for all
1133 if (GetLootMethod() == FREE_FOR_ALL)
1134 return;
1135
1136 ObjectGuid oldLooterGUID = GetLooterGuid();
1137 member_citerator guid_itr = _getMemberCSlot(oldLooterGUID);
1138 if (guid_itr != m_memberSlots.end())
1139 {
1140 if (ifneed)
1141 {
1142 // not update if only update if need and ok
1143 Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
1144 if (looter && looter->IsAtGroupRewardDistance(pLootedObject))
1145 return;
1146 }
1147 ++guid_itr;
1148 }
1149
1150 // search next after current
1151 Player* pNewLooter = nullptr;
1152 for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr)
1153 {
1154 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
1155 if (player->IsAtGroupRewardDistance(pLootedObject))
1156 {
1157 pNewLooter = player;
1158 break;
1159 }
1160 }
1161
1162 if (!pNewLooter)
1163 {
1164 // search from start
1165 for (member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr)
1166 {
1167 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
1168 if (player->IsAtGroupRewardDistance(pLootedObject))
1169 {
1170 pNewLooter = player;
1171 break;
1172 }
1173 }
1174 }
1175
1176 if (pNewLooter)
1177 {
1178 if (oldLooterGUID != pNewLooter->GetGUID())
1179 {
1180 SetLooterGuid(pNewLooter->GetGUID());
1181 SendUpdate();
1182 }
1183 }
1184 else
1185 {
1187 SendUpdate();
1188 }
1189}
1190
1191GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(BattlegroundTemplate const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 /*MaxPlayerCount*/, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid) const
1192{
1193 errorGuid = ObjectGuid::Empty;
1194
1195 // check if this group is LFG group
1196 if (isLFGGroup())
1198
1199 BattlemasterListEntry const* bgEntry = sBattlemasterListStore.LookupEntry(bgOrTemplate->Id);
1200 if (!bgEntry)
1201 return ERR_BATTLEGROUND_JOIN_FAILED; // shouldn't happen
1202
1203 // check for min / max count
1204 uint32 memberscount = GetMembersCount();
1205
1206 if (int32(memberscount) > bgEntry->MaxGroupSize) // no MinPlayerCount for battlegrounds
1207 return ERR_BATTLEGROUND_NONE; // ERR_GROUP_JOIN_BATTLEGROUND_TOO_MANY handled on client side
1208
1209 // get a player as reference, to compare other players' stats to (arena team id, queue id based on level, etc.)
1210 auto membersIterator = GetMembers().begin();
1211 auto membersEnd = GetMembers().end();
1212 // no reference found, can't join this way
1213 if (membersIterator == membersEnd)
1215
1216 Player* reference = membersIterator->GetSource();
1217 PVPDifficultyEntry const* bracketEntry = DB2Manager::GetBattlegroundBracketByLevel(bgOrTemplate->MapIDs.front(), reference->GetLevel());
1218 if (!bracketEntry)
1220
1221 uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
1222 Team team = reference->GetTeam();
1223 bool isMercenary = reference->HasAura(SPELL_MERCENARY_CONTRACT_HORDE) || reference->HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE);
1224
1225 // check every member of the group to be able to join
1226 memberscount = 0;
1227 for (; membersIterator != membersEnd; ++membersIterator)
1228 {
1229 Player* member = membersIterator->GetSource();
1230 // offline member? don't let join
1231 if (!member)
1233 errorGuid = member->GetGUID();
1234 // rbac permissions
1235 if (!member->CanJoinToBattleground(bgOrTemplate))
1237 // don't allow cross-faction join as group
1238 if (member->GetTeam() != team)
1240 // not in the same battleground level braket, don't let join
1241 PVPDifficultyEntry const* memberBracketEntry = DB2Manager::GetBattlegroundBracketByLevel(bracketEntry->MapID, member->GetLevel());
1242 if (memberBracketEntry != bracketEntry)
1244 // don't let join rated matches if the arena team id doesn't match
1245 if (isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)
1247 // don't let join if someone from the group is already in that bg queue
1248 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
1249 return ERR_BATTLEGROUND_JOIN_FAILED; // not blizz-like
1250 // don't let join if someone from the group is in bg queue random
1253 if (bgOrTemplate->Id != BATTLEGROUND_AA && isInRandomBgQueue)
1254 return ERR_IN_RANDOM_BG;
1255 // don't let join to bg queue random if someone from the group is already in bg queue
1256 if (BattlegroundMgr::IsRandomBattleground(bgOrTemplate->Id) && member->InBattlegroundQueue(true) && !isInRandomBgQueue)
1257 return ERR_IN_NON_RANDOM_BG;
1258 // check for deserter debuff in case not arena queue
1259 if (bgOrTemplate->Id != BATTLEGROUND_AA && member->IsDeserter())
1261 // check if member can join any more battleground queues
1262 if (!member->HasFreeBattlegroundQueueId())
1263 return ERR_BATTLEGROUND_TOO_MANY_QUEUES; // not blizz-like
1264 // check if someone in party is using dungeon system
1265 if (member->isUsingLfg())
1267 // check Freeze debuff
1268 if (member->HasAura(9454))
1270 if (isMercenary != (member->HasAura(SPELL_MERCENARY_CONTRACT_HORDE) || member->HasAura(SPELL_MERCENARY_CONTRACT_ALLIANCE)))
1272
1273 memberscount++;
1274 }
1275
1276 errorGuid = ObjectGuid::Empty;
1277
1278 // only check for MinPlayerCount since MinPlayerCount == MaxPlayerCount for arenas...
1279 if (bgOrTemplate->IsArena() && memberscount != MinPlayerCount)
1281
1282 return ERR_BATTLEGROUND_NONE;
1283}
1284
1286{
1287 m_dungeonDifficulty = difficulty;
1288 if (!isBGGroup() && !isBFGroup())
1289 {
1291
1293 stmt->setUInt32(1, m_dbStoreId);
1294
1295 CharacterDatabase.Execute(stmt);
1296 }
1297
1298 for (GroupReference const& itr : GetMembers())
1299 {
1300 Player* player = itr.GetSource();
1301 player->SetDungeonDifficultyID(difficulty);
1302 player->SendDungeonDifficulty();
1303 }
1304}
1305
1307{
1308 m_raidDifficulty = difficulty;
1309 if (!isBGGroup() && !isBFGroup())
1310 {
1312
1313 stmt->setUInt8(0, uint8(m_raidDifficulty));
1314 stmt->setUInt32(1, m_dbStoreId);
1315
1316 CharacterDatabase.Execute(stmt);
1317 }
1318
1319 for (GroupReference const& itr : GetMembers())
1320 {
1321 Player* player = itr.GetSource();
1322 player->SetRaidDifficultyID(difficulty);
1323 player->SendRaidDifficulty(false);
1324 }
1325}
1326
1328{
1329 m_legacyRaidDifficulty = difficulty;
1330 if (!isBGGroup() && !isBFGroup())
1331 {
1333
1335 stmt->setUInt32(1, m_dbStoreId);
1336
1337 CharacterDatabase.Execute(stmt);
1338 }
1339
1340 for (GroupReference const& itr : GetMembers())
1341 {
1342 Player* player = itr.GetSource();
1343 player->SetLegacyRaidDifficultyID(difficulty);
1344 player->SendRaidDifficulty(true);
1345 }
1346}
1347
1349{
1350 if (!mapEntry->IsRaid())
1351 return m_dungeonDifficulty;
1352
1353 MapDifficultyEntry const* defaultDifficulty = sDB2Manager.GetDefaultMapDifficulty(mapEntry->ID);
1354 if (!defaultDifficulty)
1356
1357 DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(defaultDifficulty->DifficultyID);
1358 if (!difficulty || difficulty->Flags & DIFFICULTY_FLAG_LEGACY)
1360
1361 return m_raidDifficulty;
1362}
1363
1365{
1367 {
1368 InstanceMap* map = ref.GetSource();
1369 switch (map->Reset(method))
1370 {
1372 notifyPlayer->SendResetInstanceSuccess(map->GetId());
1373 m_recentInstances.erase(map->GetId());
1374 break;
1376 if (method == InstanceResetMethod::Manual)
1378 else if (method == InstanceResetMethod::OnChangeDifficulty)
1379 m_recentInstances.erase(map->GetId()); // map might not have been reset on difficulty change but we still don't want to zone in there again
1380 break;
1382 m_recentInstances.erase(map->GetId()); // forget the instance, allows retrying different lockout with a new leader
1383 break;
1384 default:
1385 break;
1386 }
1387 }
1388}
1389
1394
1396{
1397 if (player && !player->IsGameMaster() && sMapStore.LookupEntry(player->GetMapId())->IsDungeon())
1398 player->m_InstanceValid = false;
1399}
1400
1402{
1403 // FG: HACK: force flags update on group leave - for values update hack
1404 // -- not very efficient but safe
1405 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1406 {
1407 if (Player * pp = ObjectAccessor::FindPlayer(citr->guid))
1408 {
1409 pp->ForceUpdateFieldChange(pp->m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PvpFlags));
1410 pp->ForceUpdateFieldChange(pp->m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::FactionTemplate));
1411 TC_LOG_DEBUG("misc", "-- Forced group value update for '{}'", pp->GetName());
1412 }
1413 }
1414}
1415
1417{
1418 if (AsUnderlyingType(timerType) < 0 || AsUnderlyingType(timerType) >= std::ssize(m_countdowns))
1419 return;
1420
1421 if (!m_countdowns[AsUnderlyingType(timerType)])
1422 m_countdowns[AsUnderlyingType(timerType)] = std::make_unique<CountdownInfo>();
1423
1424 m_countdowns[AsUnderlyingType(timerType)]->StartCountdown(duration, startTime);
1425}
1426
1428{
1429 if (AsUnderlyingType(timerType) < 0 || AsUnderlyingType(timerType) >= std::ssize(m_countdowns))
1430 return nullptr;
1431
1432 return m_countdowns[AsUnderlyingType(timerType)].get();
1433}
1434
1436{
1437 m_lootMethod = method;
1438}
1439
1441{
1442 m_looterGuid = guid;
1443}
1444
1449
1451{
1452 m_lootThreshold = threshold;
1453}
1454
1456{
1457 member_witerator slot = _getMemberWSlot(guid);
1458 if (slot == m_memberSlots.end())
1459 return;
1460
1461 slot->roles = roles;
1462 SendUpdate();
1463}
1464
1466{
1467 member_citerator slot = _getMemberCSlot(guid);
1468 if (slot == m_memberSlots.end())
1469 return 0;
1470
1471 return slot->roles;
1472}
1473
1475{
1477 return;
1478
1480 if (m_readyCheckTimer <= Milliseconds::zero())
1481 EndReadyCheck();
1482}
1483
1485{
1487 return;
1488
1489 member_witerator slot = _getMemberWSlot(starterGuid);
1490 if (slot == m_memberSlots.end())
1491 return ;
1492
1493 m_readyCheckStarted = true;
1494 m_readyCheckTimer = duration;
1495
1497
1498 SetMemberReadyChecked(&(*slot));
1499
1501 readyCheckStarted.PartyGUID = m_guid;
1502 readyCheckStarted.PartyIndex = GetGroupCategory();
1503 readyCheckStarted.InitiatorGUID = starterGuid;
1504 readyCheckStarted.Duration = duration;
1505 BroadcastPacket(readyCheckStarted.Write(), false);
1506}
1507
1509{
1511 return;
1512
1513 m_readyCheckStarted = false;
1514 m_readyCheckTimer = Milliseconds::zero();
1515
1517
1518 WorldPackets::Party::ReadyCheckCompleted readyCheckCompleted;
1519 readyCheckCompleted.PartyIndex = 0;
1520 readyCheckCompleted.PartyGUID = m_guid;
1521 BroadcastPacket(readyCheckCompleted.Write(), false);
1522}
1523
1525{
1526 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1527 if (!citr->readyChecked)
1528 return false;
1529 return true;
1530}
1531
1533{
1535 return;
1536
1537 member_witerator slot = _getMemberWSlot(guid);
1538 if (slot != m_memberSlots.end())
1539 SetMemberReadyCheck(&(*slot), ready);
1540}
1541
1543{
1545 response.PartyGUID = m_guid;
1546 response.Player = slot->guid;
1547 response.IsReady = ready;
1548 BroadcastPacket(response.Write(), false);
1549
1551}
1552
1554{
1555 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
1556 {
1557 Player* player = ObjectAccessor::FindConnectedPlayer(itr->guid);
1558 if (!player || !player->GetSession())
1559 SetMemberReadyCheck(&(*itr), false);
1560 }
1561}
1562
1564{
1565 slot->readyChecked = true;
1567 EndReadyCheck();
1568}
1569
1571{
1572 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
1573 itr->readyChecked = false;
1574}
1575
1576void Group::AddRaidMarker(uint8 markerId, uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid)
1577{
1578 if (markerId >= RAID_MARKERS_COUNT || m_markers[markerId])
1579 return;
1580
1581 m_activeMarkers |= (1 << markerId);
1582 m_markers[markerId] = std::make_unique<RaidMarker>(mapId, positionX, positionY, positionZ, transportGuid);
1584}
1585
1587{
1588 if (markerId > RAID_MARKERS_COUNT)
1589 return;
1590
1591 for (uint8 i = 0; i < RAID_MARKERS_COUNT; i++)
1592 if (m_markers[i] && (markerId == i || markerId == RAID_MARKERS_COUNT))
1593 {
1594 m_markers[i] = nullptr;
1595 m_activeMarkers &= ~(1 << i);
1596 }
1597
1599}
1600
1602{
1604
1605 packet.PartyIndex = GetGroupCategory();
1607
1608 for (uint8 i = 0; i < RAID_MARKERS_COUNT; i++)
1609 if (m_markers[i])
1610 packet.RaidMarkers.push_back(m_markers[i].get());
1611
1612 if (session)
1613 session->SendPacket(packet.Write());
1614 else
1615 BroadcastPacket(packet.Write(), false);
1616}
1617
1618bool Group::IsFull() const
1619{
1620 return isRaidGroup() ? (m_memberSlots.size() >= MAX_RAID_SIZE) : (m_memberSlots.size() >= MAX_GROUP_SIZE);
1621}
1622
1624{
1625 return (m_groupFlags & GROUP_FLAG_LFG) != 0;
1626}
1627
1629{
1630 return (m_groupFlags & GROUP_FLAG_RAID) != 0;
1631}
1632
1634{
1635 return m_bgGroup != nullptr;
1636}
1637
1639{
1640 return m_bfGroup != nullptr;
1641}
1642
1644{
1645 return GetMembersCount() > 0;
1646}
1647
1649{
1650 return m_leaderGuid;
1651}
1652
1654{
1655 return m_guid;
1656}
1657
1658char const* Group::GetLeaderName() const
1659{
1660 return m_leaderName.c_str();
1661}
1662
1664{
1665 return m_lootMethod;
1666}
1667
1669{
1670 if (GetLootMethod() == FREE_FOR_ALL)
1671 return ObjectGuid::Empty;
1672 return m_looterGuid;
1673}
1674
1679
1684
1686{
1687 return _getMemberCSlot(guid) != m_memberSlots.end();
1688}
1689
1691{
1692 return (GetLeaderGUID() == guid);
1693}
1694
1695ObjectGuid Group::GetMemberGUID(std::string const& name) const
1696{
1697 auto itr = std::ranges::find(m_memberSlots, name, &MemberSlot::name);
1698 if (itr != m_memberSlots.end())
1699 return itr->guid;
1700
1701 return ObjectGuid::Empty;
1702}
1703
1705{
1706 member_citerator mslot = _getMemberCSlot(guid);
1707 if (mslot == m_memberSlots.end())
1708 return 0u;
1709 return mslot->flags;
1710}
1711
1713{
1714 member_citerator mslot2 = _getMemberCSlot(guid2);
1715 if (mslot2 == m_memberSlots.end())
1716 return false;
1717 return SameSubGroup(guid1, &*mslot2);
1718}
1719
1720bool Group::SameSubGroup(ObjectGuid guid1, MemberSlot const* slot2) const
1721{
1722 member_citerator mslot1 = _getMemberCSlot(guid1);
1723 if (mslot1 == m_memberSlots.end() || !slot2)
1724 return false;
1725 return (mslot1->group == slot2->group);
1726}
1727
1729{
1730 return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAX_GROUP_SIZE);
1731}
1732
1734{
1735 member_citerator mslot = _getMemberCSlot(guid);
1736 if (mslot == m_memberSlots.end())
1737 return (MAX_RAID_SUBGROUPS+1);
1738 return mslot->group;
1739}
1740
1742{
1743 m_bgGroup = bg;
1744}
1745
1747{
1748 m_bfGroup = bf;
1749}
1750
1752{
1753 // Assistants, main assistants and main tanks are only available in raid groups
1754 if (!isRaidGroup())
1755 return;
1756
1757 // Check if player is really in the raid
1758 member_witerator slot = _getMemberWSlot(guid);
1759 if (slot == m_memberSlots.end())
1760 return;
1761
1762 // Do flag specific actions, e.g ensure uniqueness
1763 switch (flag)
1764 {
1766 RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); // Remove main assist flag from current if any.
1767 break;
1769 RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main tank flag from current if any.
1770 break;
1772 break;
1773 default:
1774 return; // This should never happen
1775 }
1776
1777 // Switch the actual flag
1778 ToggleGroupMemberFlag(slot, flag, apply);
1779
1780 // Preserve the new setting in the db
1782
1783 stmt->setUInt8(0, slot->flags);
1784 stmt->setUInt64(1, guid.GetCounter());
1785
1786 CharacterDatabase.Execute(stmt);
1787
1788 // Broadcast the changes to the group
1789 SendUpdate();
1790}
1791
1793{
1794 m_memberMgr.push_front(pRef);
1795}
1796
1798{
1799 auto itr = std::ranges::find(m_memberMgr, guid, [](GroupReference const& ref) { return ref.GetSource()->GetGUID(); });
1800 if (itr != m_memberMgr.end())
1801 itr->unlink();
1802}
1803
1805{
1806 // Sub group counters initialization
1807 if (!m_subGroupsCounts)
1809
1810 memset((void*)m_subGroupsCounts, 0, (MAX_RAID_SUBGROUPS)*sizeof(uint8));
1811
1812 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
1813 ++m_subGroupsCounts[itr->group];
1814}
1815
1817{
1818 return std::ranges::find(m_memberSlots, Guid, &MemberSlot::guid);
1819}
1820
1822{
1823 return std::ranges::find(m_memberSlots, Guid, &MemberSlot::guid);
1824}
1825
1827{
1829 ++m_subGroupsCounts[subgroup];
1830}
1831
1833{
1835 --m_subGroupsCounts[subgroup];
1836}
1837
1839{
1840 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
1841 if (itr->flags & flag)
1842 itr->flags &= ~flag;
1843}
1844
1846{
1847 if (apply)
1848 slot->flags |= flag;
1849 else
1850 slot->flags &= ~flag;
1851}
1852
1858
1860{
1861 m_isLeaderOffline = false;
1862}
1863
1865{
1866 if (apply)
1868 else
1870
1871 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
1873
1874 if (!isBGGroup() && !isBFGroup())
1875 {
1877
1878 stmt->setUInt16(0, m_groupFlags);
1879 stmt->setUInt32(1, m_dbStoreId);
1880
1881 CharacterDatabase.Execute(stmt);
1882 }
1883
1884 SendUpdate();
1885}
1886
1891
1893{
1894 m_pingRestriction = restrictTo;
1895
1896 if (!isBGGroup() && !isBFGroup())
1897 {
1899
1900 stmt->setInt8(0, int8(m_pingRestriction));
1901 stmt->setUInt32(1, m_dbStoreId);
1902
1903 CharacterDatabase.Execute(stmt);
1904 }
1905
1906 SendUpdate();
1907}
@ SPELL_MERCENARY_CONTRACT_ALLIANCE
@ SPELL_MERCENARY_CONTRACT_HORDE
#define sCharacterCache
@ CHAR_INS_GROUP_MEMBER
@ CHAR_DEL_GROUP_MEMBER_ALL
@ CHAR_DEL_GROUP
@ CHAR_INS_GROUP
@ CHAR_UPD_GROUP_DIFFICULTY
@ CHAR_UPD_GROUP_TYPE
@ CHAR_UPD_GROUP_RAID_DIFFICULTY
@ CHAR_UPD_GROUP_MEMBER_FLAG
@ CHAR_UPD_GROUP_LEADER
@ CHAR_UPD_GROUP_PING_RESTRICTION
@ CHAR_UPD_GROUP_MEMBER_SUBGROUP
@ CHAR_UPD_GROUP_LEGACY_RAID_DIFFICULTY
@ CHAR_DEL_GROUP_MEMBER
@ CHAR_DEL_LFG_DATA
@ IN_MILLISECONDS
Definition Common.h:38
@ MINUTE
Definition Common.h:32
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< BattlemasterListEntry > sBattlemasterListStore("BattlemasterList.db2", &BattlemasterListLoadInfo::Instance)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
@ DIFFICULTY_FLAG_LEGACY
Definition DBCEnums.h:980
Difficulty
Definition DBCEnums.h:932
@ DIFFICULTY_NORMAL_RAID
Definition DBCEnums.h:945
@ DIFFICULTY_NORMAL
Definition DBCEnums.h:934
@ DIFFICULTY_10_N
Definition DBCEnums.h:936
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint8_t uint8
Definition Define.h:156
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
#define ASSERT
Definition Errors.h:80
#define sGroupMgr
Definition GroupMgr.h:66
RestrictPingsTo
Definition Group.h:195
@ GROUP_TYPE_NORMAL
Definition Group.h:90
@ GROUP_TYPE_NONE
Definition Group.h:89
#define RAID_MARKERS_COUNT
Definition Group.h:55
GroupFlags
Definition Group.h:95
@ GROUP_FLAG_LFG_RESTRICTED
Definition Group.h:99
@ GROUP_FLAG_RAID
Definition Group.h:98
@ GROUP_MASK_BGRAID
Definition Group.h:108
@ GROUP_FLAG_NONE
Definition Group.h:96
@ GROUP_FLAG_EVERYONE_ASSISTANT
Definition Group.h:103
@ GROUP_FLAG_LFG
Definition Group.h:100
@ GROUP_FLAG_DESTROYED
Definition Group.h:101
#define MAX_GROUP_SIZE
Definition Group.h:50
GroupMemberFlags
Definition Group.h:75
@ MEMBER_FLAG_ASSISTANT
Definition Group.h:76
@ MEMBER_FLAG_MAINASSIST
Definition Group.h:78
@ MEMBER_FLAG_MAINTANK
Definition Group.h:77
#define MAX_RAID_SIZE
Definition Group.h:51
@ GROUP_UPDATE_FULL
Definition Group.h:141
#define TARGET_ICONS_COUNT
Definition Group.h:54
CountdownTimerType
Definition Group.h:176
@ GROUP_UPDATE_PET_FULL
Definition Group.h:159
@ GROUP_CATEGORY_HOME
Definition Group.h:113
@ GROUP_CATEGORY_INSTANCE
Definition Group.h:114
#define MAX_RAID_SUBGROUPS
Definition Group.h:52
#define sLFGMgr
Definition LFGMgr.h:515
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
LootMethod
Definition Loot.h:89
@ PERSONAL_LOOT
Definition Loot.h:95
@ MASTER_LOOT
Definition Loot.h:92
@ FREE_FOR_ALL
Definition Loot.h:90
InstanceResetMethod
Definition Map.h:864
#define sObjectMgr
Definition ObjectMgr.h:1885
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
@ PLAYER_FLAGS_GROUP_LEADER
Definition Player.h:520
Races
Definition RaceMask.h:27
#define sScriptMgr
Definition ScriptMgr.h:1449
GroupJoinBattlegroundResult
@ ERR_BATTLEGROUND_JOIN_TIMED_OUT
@ ERR_BATTLEGROUND_JOIN_FAILED
@ ERR_LFG_CANT_USE_BATTLEGROUND
@ ERR_IN_NON_RANDOM_BG
@ ERR_BATTLEGROUND_NONE
@ ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS
@ ERR_ARENA_TEAM_PARTY_SIZE
@ ERR_BATTLEGROUND_TOO_MANY_QUEUES
@ ERR_BATTLEGROUND_JOIN_MERCENARY
@ ERR_BATTLEGROUND_JOIN_RANGE_INDEX
@ ERR_IN_RANDOM_BG
@ INSTANCE_RESET_FAILED
ItemQualities
@ ITEM_QUALITY_UNCOMMON
@ ALLIANCE
@ HORDE
@ BATTLEGROUND_AA
@ BATTLEGROUND_RANDOM_EPIC
@ BATTLEGROUND_RB
RemoveMethod
@ GROUP_REMOVEMETHOD_KICK_LFG
@ GROUP_REMOVEMETHOD_KICK
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:565
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
bool IsInWorld() const
Definition BaseEntity.h:158
static BattlegroundQueueTypeId BGQueueTypeId(uint16 battlemasterListId, BattlegroundQueueIdType type, bool rated, uint8 teamSize)
static bool IsRandomBattleground(uint32 battlemasterListId)
Group * GetBgRaid(Team team) const
void SetBgRaid(Team team, Group *bg_raid)
static PVPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
Class used to access individual fields of database query result.
Definition Field.h:94
uint64 GetUInt64() const noexcept
Definition Field.cpp:71
uint32 GetUInt32() const noexcept
Definition Field.cpp:57
Seconds GetTimeLeft() const
Definition Group.cpp:42
void StartCountdown(Seconds duration, Optional< time_t > startTime={ })
Definition Group.cpp:47
bool IsRunning() const
Definition Group.cpp:53
Definition Group.h:205
ObjectGuid m_targetIcons[TARGET_ICONS_COUNT]
Definition Group.h:439
member_citerator _getMemberCSlot(ObjectGuid Guid) const
Definition Group.cpp:1816
bool IsReadyCheckCompleted(void) const
Definition Group.cpp:1524
void BroadcastGroupUpdate(void)
Definition Group.cpp:1401
bool isLFGGroup() const
Definition Group.cpp:1623
bool m_isLeaderOffline
Definition Group.h:449
void StartLeaderOfflineTimer()
Definition Group.cpp:1853
uint8 GetMemberGroup(ObjectGuid guid) const
Definition Group.cpp:1733
void SwapMembersGroups(ObjectGuid firstGuid, ObjectGuid secondGuid)
Definition Group.cpp:1073
ObjectGuid GetMasterLooterGuid() const
Definition Group.cpp:1675
Battlefield * m_bfGroup
Definition Group.h:438
void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot const *slot=nullptr) const
Definition Group.cpp:834
uint8 m_leaderFactionGroup
Definition Group.h:430
ObjectGuid GetMemberGUID(std::string const &name) const
Definition Group.cpp:1695
bool AddLeaderInvite(Player *player)
Definition Group.cpp:375
void SetBattlefieldGroup(Battlefield *bf)
Definition Group.cpp:1746
InvitesList m_invitees
Definition Group.h:428
void ResetInstances(InstanceResetMethod method, Player *notifyPlayer)
Definition Group.cpp:1364
void DeleteRaidMarker(uint8 markerId)
Definition Group.cpp:1586
GroupCategory GetGroupCategory() const
Definition Group.h:303
RestrictPingsTo m_pingRestriction
Definition Group.h:462
Difficulty m_legacyRaidDifficulty
Definition Group.h:436
bool IsCreated() const
Definition Group.cpp:1643
void SendUpdate() const
Definition Group.cpp:828
bool _setMembersGroup(ObjectGuid guid, uint8 group)
Definition Group.cpp:986
void SubGroupCounterDecrease(uint8 subgroup)
Definition Group.cpp:1832
void SetLootMethod(LootMethod method)
Definition Group.cpp:1435
void ChangeMembersGroup(ObjectGuid guid, uint8 group)
Definition Group.cpp:1021
void SendTargetIconList(WorldSession *session) const
Definition Group.cpp:815
void SetEveryoneIsAssistant(bool apply)
Definition Group.cpp:1864
GroupCategory m_groupCategory
Definition Group.h:433
ObjectGuid m_leaderGuid
Definition Group.h:429
void RemoveAllInvites()
Definition Group.cpp:395
std::string m_leaderName
Definition Group.h:431
void AddRaidMarker(uint8 markerId, uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid=ObjectGuid::Empty)
Definition Group.cpp:1576
void _initRaidSubGroupsCounter()
Definition Group.cpp:1804
void EndReadyCheck()
Definition Group.cpp:1508
ObjectGuid m_looterGuid
Definition Group.h:442
std::array< std::unique_ptr< RaidMarker >, RAID_MARKERS_COUNT > m_markers
Definition Group.h:457
void SetLootThreshold(ItemQualities threshold)
Definition Group.cpp:1450
void Disband(bool hideDestroy=false)
Definition Group.cpp:727
void LoadGroupFromDB(Field *field)
Definition Group.cpp:211
bool AddMember(Player *player)
Definition Group.cpp:424
bool IsLeader(ObjectGuid guid) const
Definition Group.cpp:1690
Battleground * m_bgGroup
Definition Group.h:437
Difficulty m_raidDifficulty
Definition Group.h:435
void SetMemberReadyCheck(ObjectGuid guid, bool ready)
Definition Group.cpp:1532
void BroadcastAddonMessagePacket(WorldPacket const *packet, const std::string &prefix, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty) const
Definition Group.cpp:960
GroupRefManager m_memberMgr
Definition Group.h:427
void SetDungeonDifficultyID(Difficulty difficulty)
Definition Group.cpp:1285
void SetRestrictPingsTo(RestrictPingsTo restrictTo)
Definition Group.cpp:1892
uint32 m_activeMarkers
Definition Group.h:458
void SetMasterLooterGuid(ObjectGuid guid)
Definition Group.cpp:1445
void SetRaidDifficultyID(Difficulty difficulty)
Definition Group.cpp:1306
Trinity::unique_trackable_ptr< Group > m_scriptRef
Definition Group.h:465
ObjectGuid GetGUID() const
Definition Group.cpp:1653
void RemoveInvite(Player *player)
Definition Group.cpp:386
void SetLegacyRaidDifficultyID(Difficulty difficulty)
Definition Group.cpp:1327
bool isBGGroup() const
Definition Group.cpp:1633
void ConvertToRaid()
Definition Group.cpp:299
ItemQualities GetLootThreshold() const
Definition Group.cpp:1680
void SetOfflineMembersReadyChecked(void)
Definition Group.cpp:1553
std::unordered_map< uint32, std::pair< ObjectGuid, uint32 > > m_recentInstances
Definition Group.h:444
MemberSlotList m_memberSlots
Definition Group.h:426
void StartReadyCheck(ObjectGuid starterGuid, Milliseconds duration=Milliseconds(READYCHECK_DURATION))
Definition Group.cpp:1484
void SendRaidMarkersChanged(WorldSession *session=nullptr) const
Definition Group.cpp:1601
uint32 GetMembersCount() const
Definition Group.h:335
Group()
Definition Group.cpp:58
void StopLeaderOfflineTimer()
Definition Group.cpp:1859
void UpdatePlayerOutOfRange(Player const *player) const
Definition Group.cpp:943
void Update(uint32 diff)
Definition Group.cpp:90
void ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply)
Definition Group.cpp:1845
void _homebindIfInstance(Player *player)
Definition Group.cpp:1395
Difficulty GetRaidDifficultyID() const
Definition Group.h:360
void SetLfgRoles(ObjectGuid guid, uint8 roles)
Definition Group.cpp:1455
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag)
Definition Group.cpp:1751
TimeTracker m_leaderOfflineTimer
Definition Group.h:450
void ResetMemberReadyChecked(void)
Definition Group.cpp:1570
member_witerator _getMemberWSlot(ObjectGuid Guid)
Definition Group.cpp:1821
ObjectGuid GetLooterGuid() const
Definition Group.cpp:1668
Milliseconds m_readyCheckTimer
Definition Group.h:454
uint32 m_dbStoreId
Definition Group.h:448
void DelinkMember(ObjectGuid guid)
Definition Group.cpp:1797
void ChangeLeader(ObjectGuid guid)
Definition Group.cpp:682
const char * GetLeaderName() const
Definition Group.cpp:1658
void ConvertToLFG()
Definition Group.cpp:281
ObjectGuid m_masterLooterGuid
Definition Group.h:443
MemberSlotList::iterator member_witerator
Definition Group.h:242
void SetBattlegroundGroup(Battleground *bg)
Definition Group.cpp:1741
uint8 GetLfgRoles(ObjectGuid guid) const
Definition Group.cpp:1465
LootMethod GetLootMethod() const
Definition Group.cpp:1663
void UpdateLooterGuid(WorldObject *pLootedObject, bool ifneed=false)
Definition Group.cpp:1129
CountdownInfo const * GetCountdownInfo(CountdownTimerType timerType) const
Definition Group.cpp:1427
bool RemoveMember(ObjectGuid guid, RemoveMethod method=GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker=ObjectGuid::Empty, const char *reason=nullptr)
Definition Group.cpp:566
bool m_readyCheckStarted
Definition Group.h:453
Player * GetInvited(ObjectGuid guid) const
Definition Group.cpp:404
bool HasFreeSlotSubGroup(uint8 subgroup) const
Definition Group.cpp:1728
bool isBFGroup() const
Definition Group.cpp:1638
void LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
Definition Group.cpp:248
bool IsMember(ObjectGuid guid) const
Definition Group.cpp:1685
void UpdateReadyCheck(uint32 diff)
Definition Group.cpp:1474
LootMethod m_lootMethod
Definition Group.h:440
Difficulty GetDungeonDifficultyID() const
Definition Group.h:359
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignoredPlayer=ObjectGuid::Empty) const
Definition Group.cpp:973
void SelectNewPartyOrRaidLeader()
Definition Group.cpp:105
GroupRefManager & GetMembers()
Definition Group.h:332
bool SameSubGroup(ObjectGuid guid1, ObjectGuid guid2) const
Definition Group.cpp:1712
void LinkOwnedInstance(GroupInstanceReference *ref)
Definition Group.cpp:1390
ObjectGuid m_guid
Definition Group.h:447
bool AddInvite(Player *player)
Definition Group.cpp:354
void ConvertToGroup()
Definition Group.cpp:323
uint8 * m_subGroupsCounts
Definition Group.h:446
Difficulty GetDifficultyID(MapEntry const *mapEntry) const
Definition Group.cpp:1348
MemberSlotList::const_iterator member_citerator
Definition Group.h:219
std::array< std::unique_ptr< CountdownInfo >, 3 > m_countdowns
Definition Group.h:460
void SetMemberReadyChecked(MemberSlot *slot)
Definition Group.cpp:1563
void SubGroupCounterIncrease(uint8 subgroup)
Definition Group.cpp:1826
void SetTargetIcon(uint8 symbol, ObjectGuid target, ObjectGuid changedBy)
Definition Group.cpp:794
bool Create(Player *leader)
Definition Group.cpp:141
RestrictPingsTo GetRestrictPings() const
Definition Group.cpp:1887
bool IsFull() const
Definition Group.cpp:1618
ObjectGuid GetLeaderGUID() const
Definition Group.cpp:1648
Difficulty m_dungeonDifficulty
Definition Group.h:434
uint8 GetMemberFlags(ObjectGuid guid) const
Definition Group.cpp:1704
Difficulty GetLegacyRaidDifficultyID() const
Definition Group.h:361
~Group()
Definition Group.cpp:73
void SetLooterGuid(ObjectGuid guid)
Definition Group.cpp:1440
void LinkMember(GroupReference *pRef)
Definition Group.cpp:1792
ItemQualities m_lootThreshold
Definition Group.h:441
bool isRaidGroup() const
Definition Group.cpp:1628
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(BattlegroundTemplate const *bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot, ObjectGuid &errorGuid) const
Definition Group.cpp:1191
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
Definition Group.cpp:1838
GroupInstanceRefManager m_ownedInstancesMgr
Definition Group.h:445
void SendUpdateDestroyGroupToPlayer(Player *player) const
Definition Group.cpp:931
GroupFlags m_groupFlags
Definition Group.h:432
void StartCountdown(CountdownTimerType timerType, Seconds duration, Optional< time_t > startTime={ })
Definition Group.cpp:1416
InstanceResetResult Reset(InstanceResetMethod method)
Definition Map.cpp:3047
uint32 size() const
Definition LinkedList.h:129
void push_back(LinkedListElement *pElem)
Definition LinkedList.h:114
void push_front(LinkedListElement *pElem)
Definition LinkedList.h:109
uint32 GetId() const
Definition Map.cpp:3257
InstanceMap * ToInstanceMap()
Definition Map.h:490
LowType GetCounter() const
Definition ObjectGuid.h:336
static ObjectGuid const Empty
Definition ObjectGuid.h:314
bool IsEmpty() const
Definition ObjectGuid.h:362
uint64 GetRawValue(std::size_t i) const
Definition ObjectGuid.h:325
void SetRawValue(std::span< uint8 const > rawBytes)
static constexpr std::size_t BytesSize
Definition ObjectGuid.h:319
uint64 LowType
Definition ObjectGuid.h:321
void Clear()
Definition ObjectGuid.h:329
void BuildValuesUpdateBlockForPlayerWithFlag(UpdateData *data, UF::UpdateFieldFlag flags, Player const *target) const
Definition Object.cpp:100
Definition Pet.h:40
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:25768
bool m_InstanceValid
Definition Player.h:2761
void SetOriginalGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:26770
void SetPlayerFlag(PlayerFlags flags)
Definition Player.h:2911
void SetPartyType(GroupCategory category, uint8 type)
Definition Player.cpp:26783
int32 NextGroupUpdateSequenceNumber(GroupCategory category)
Definition Player.cpp:26800
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2804
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
void SendResetInstanceFailed(ResetFailedReason reason, uint32 mapID) const
Definition Player.cpp:21932
void SetGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:24940
void SendDungeonDifficulty(int32 forcedDifficulty=-1) const
Definition Player.cpp:21866
void SetGroupInvite(Group *group)
Definition Player.h:2795
void RemoveFromBattlegroundOrBattlefieldRaid()
Definition Player.cpp:26758
void SetRaidDifficultyID(Difficulty raid_difficulty)
Definition Player.h:2187
Group * GetOriginalGroup() const
Definition Player.h:2815
bool CanRewardQuest(Quest const *quest, bool msg) const
Definition Player.cpp:14619
void UpdateVisibleObjectInteractions(bool allUnits, bool onlySpellClicks, bool gameObjectQuestGiverStatus, bool questObjectiveGameObjects)
Definition Player.cpp:25949
bool HaveAtClient(BaseEntity const *u) const
Definition Player.cpp:24475
Pet * GetPet() const
Definition Player.cpp:22060
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition Player.cpp:26434
bool IsDeserter() const
Definition Player.h:2592
bool InBattlegroundQueue(bool ignoreArena=false) const
Definition Player.cpp:25735
WorldSession * GetSession() const
Definition Player.h:2272
void ResetGroupUpdateSequenceIfNeeded(Group const *group)
Definition Player.cpp:26789
Difficulty GetDungeonDifficultyID() const
Definition Player.h:2183
void SetLegacyRaidDifficultyID(Difficulty raid_difficulty)
Definition Player.h:2188
bool CanJoinToBattleground(BattlegroundTemplate const *bg) const
Definition Player.cpp:24387
bool HasFreeBattlegroundQueueId() const
Definition Player.cpp:25796
bool IsGameMaster() const
Definition Player.h:1309
static Difficulty CheckLoadedLegacyRaidDifficultyID(Difficulty difficulty)
Definition Player.cpp:30673
static uint8 GetFactionGroupForRace(uint8 race)
Definition Player.cpp:6488
void SetDungeonDifficultyID(Difficulty dungeon_difficulty)
Definition Player.h:2186
bool CheckInstanceValidity(bool)
Definition Player.cpp:20180
Difficulty GetRaidDifficultyID() const
Definition Player.h:2184
void SendResetInstanceSuccess(uint32 MapId) const
Definition Player.cpp:21925
static Difficulty CheckLoadedRaidDifficultyID(Difficulty difficulty)
Definition Player.cpp:30658
void SendRaidDifficulty(bool legacy, int32 forcedDifficulty=-1) const
Definition Player.cpp:21873
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2796
uint8 GetSubGroup() const
Definition Player.h:2802
void FailCriteria(CriteriaFailEvent condition, int32 failAsset)
Definition Player.cpp:27582
Group * GetGroupInvite() const
Definition Player.h:2794
static Difficulty CheckLoadedDungeonDifficultyID(Difficulty difficulty)
Definition Player.cpp:30643
uint32 GetArenaTeamId(uint8) const
Definition Player.h:2175
Difficulty GetLegacyRaidDifficultyID() const
Definition Player.h:2185
void SetBattlegroundOrBattlefieldRaid(Group *group, int8 subgroup=-1)
Definition Player.cpp:26748
Team GetTeam() const
Definition Player.h:2423
bool isUsingLfg() const
Definition Player.cpp:26732
void setInt8(uint8 index, int8 value)
void setBinary(uint8 index, std::vector< uint8 > &&value)
void setUInt16(uint8 index, uint16 value)
void setUInt32(uint8 index, uint32 value)
void setUInt64(uint8 index, uint64 value)
void setUInt8(uint8 index, uint8 value)
iterator end()
Definition RefManager.h:36
iterator begin()
Definition RefManager.h:35
FROM * GetSource() const
Definition Reference.h:87
uint8 GetClass() const
Definition Unit.h:764
bool IsAlive() const
Definition Unit.h:1185
void RemoveAllGroupBuffsFromCaster(ObjectGuid casterGUID)
Definition Unit.cpp:4559
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition Unit.h:1881
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
uint8 GetLevel() const
Definition Unit.h:757
uint8 GetRace() const
Definition Unit.h:761
bool HasData() const
Definition UpdateData.h:49
bool BuildPacket(WorldPacket *packet)
constexpr uint32 GetMapId() const
Definition Position.h:216
Map * GetMap() const
Definition Object.h:411
float GetSightRange(WorldObject const *target=nullptr) const
Definition Object.cpp:797
std::string const & GetName() const
Definition Object.h:342
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:496
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:469
WorldPacket const * GetRawPacket() const
Definition Packet.h:38
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
Optional< PartyLootSettings > LootSettings
Optional< PartyDifficultySettings > DifficultySettings
std::vector< PartyPlayerInfo > PlayerList
WorldPacket const * Write() override
Optional< PartyLFGInfo > LfgInfos
WorldPacket const * Write() override
std::vector< RaidMarker const * > RaidMarkers
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPackets::Duration< Milliseconds > Duration
std::vector< std::pair< uint8, ObjectGuid > > TargetIcons
Player session in the World.
bool PlayerLogout() const
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
bool IsAddonRegistered(std::string_view prefix) const
time_t GetGameTime()
Definition GameTime.cpp:52
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
@ LFG_STATE_FINISHED_DUNGEON
Definition LFG.h:81
BattlegroundTypeId Id
std::vector< int32 > MapIDs
ObjectGuid guid
Definition Group.h:209
std::string name
Definition Group.h:210
bool readyChecked
Definition Group.h:216
bool IsRaid() const
void Update(int32 diff)
Definition Timer.h:121
bool Passed() const
Definition Timer.h:131
void Reset(int32 expiry)
Definition Timer.h:136
UpdateField< int32, 32, 45 > FactionTemplate
UpdateField< uint8, 64, 86 > PvpFlags
Reward info.
Definition LFGMgr.h:237