Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Group.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Battleground.h"
7#include "BattlegroundMgr.h"
8#include "Common.h"
9#include "Formulas.h"
10#include "Group.h"
11#include "GroupMgr.h"
12#include "InstanceSaveMgr.h"
13#include "LFGMgr.h"
14#include "MapInstanced.h"
15#include "MapManager.h"
16#include "ObjectAccessor.h"
17#include "ObjectMgr.h"
18#include "Opcodes.h"
19#include "Player.h"
20#include "UpdateFieldFlags.h"
21#include "Util.h"
22#include "World.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25
26Roll::Roll(uint64 _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid),
27itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count),
30
32
33void Roll::setLoot(Loot* pLoot)
34{
35 link(pLoot, this);
36}
37
39{
40 return getTarget();
41}
42
51
53{
54 if (m_bgGroup)
55 {
56 SF_LOG_DEBUG("bg.battleground", "Group::~Group: battleground group being deleted.");
57 if (m_bgGroup->GetBgRaid(ALLIANCE) == this) m_bgGroup->SetBgRaid(ALLIANCE, NULL);
58 else if (m_bgGroup->GetBgRaid(HORDE) == this) m_bgGroup->SetBgRaid(HORDE, NULL);
59 else SF_LOG_ERROR("misc", "Group::~Group: battleground group is not linked to the correct battleground.");
60 }
61 Rolls::iterator itr;
62 while (!RollId.empty())
63 {
64 itr = RollId.begin();
65 Roll* r = *itr;
66 RollId.erase(itr);
67 delete (r);
68 }
69
70 // it is undefined whether objectmgr (which stores the groups) or instancesavemgr
71 // will be unloaded first so we must be prepared for both cases
72 // this may unload some instance saves
73 for (uint8 i = 0; i < 15; ++i)
74 for (BoundInstancesMap::iterator itr2 = m_boundInstances[i].begin(); itr2 != m_boundInstances[i].end(); ++itr2)
75 itr2->second.save->RemoveGroup(this);
76
77 // Sub group counters clean up
78 delete[] m_subGroupsCounts;
79}
80
81bool Group::Create(Player* leader)
82{
83 uint64 leaderGuid = leader->GetGUID();
84 uint32 lowguid = sGroupMgr->GenerateGroupId();
85
86 m_guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_GROUP);
87 m_leaderGuid = leaderGuid;
88 m_leaderName = leader->GetName();
89
90 if (isBGGroup() || isBFGroup())
92
95
96 if (!isLFGGroup())
98
100 m_looterGuid = leaderGuid;
101
104
105 if (!isBGGroup() && !isBFGroup())
106 {
109
110 m_dbStoreId = sGroupMgr->GenerateNewGroupDbStoreId();
111
112 sGroupMgr->RegisterGroupDbStoreId(m_dbStoreId, this);
113
114 // Store group in database
115 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GROUP);
116
117 uint8 index = 0;
118
119 stmt->setUInt32(index++, m_dbStoreId);
120 stmt->setUInt32(index++, GUID_LOPART(m_leaderGuid));
121 stmt->setUInt8(index++, uint8(m_lootMethod));
122 stmt->setUInt32(index++, GUID_LOPART(m_looterGuid));
123 stmt->setUInt8(index++, uint8(m_lootThreshold));
124 stmt->setUInt32(index++, uint32(m_targetIcons[0]));
125 stmt->setUInt32(index++, uint32(m_targetIcons[1]));
126 stmt->setUInt32(index++, uint32(m_targetIcons[2]));
127 stmt->setUInt32(index++, uint32(m_targetIcons[3]));
128 stmt->setUInt32(index++, uint32(m_targetIcons[4]));
129 stmt->setUInt32(index++, uint32(m_targetIcons[5]));
130 stmt->setUInt32(index++, uint32(m_targetIcons[6]));
131 stmt->setUInt32(index++, uint32(m_targetIcons[7]));
132 stmt->setUInt8(index++, uint8(m_groupType));
133 stmt->setUInt32(index++, uint8(m_dungeonDifficulty));
134 stmt->setUInt32(index++, uint8(m_raidDifficulty));
135
136 CharacterDatabase.Execute(stmt);
137
138
139 ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
140
141 Player::ConvertInstancesToGroup(leader, this, false);
142 }
143 else if (!AddMember(leader))
144 return false;
145
146 return true;
147}
148
150{
151 m_dbStoreId = fields[15].GetUInt32();
152 m_guid = MAKE_NEW_GUID(sGroupMgr->GenerateGroupId(), 0, HIGHGUID_GROUP);
153 m_leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
154
155 // group leader not exist
156 if (!sObjectMgr->GetPlayerNameByGUID(fields[0].GetUInt32(), m_leaderName))
157 return;
158
159 m_lootMethod = LootMethod(fields[1].GetUInt8());
160 m_looterGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
161 m_lootThreshold = ItemQualities(fields[3].GetUInt8());
162
163 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
164 m_targetIcons[i] = fields[4 + i].GetUInt32();
165
166 m_groupType = GroupType(fields[12].GetUInt8());
169
172
174 sLFGMgr->_LoadFromDB(fields, GetGUID());
175}
176
177void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
178{
179 MemberSlot member;
180 member.guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
181
182 // skip non-existed member
183 if (!sObjectMgr->GetPlayerNameByGUID(member.guid, member.name))
184 {
185 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER);
186 stmt->setUInt32(0, guidLow);
187 CharacterDatabase.Execute(stmt);
188 return;
189 }
190
191 member.group = subgroup;
192 member.flags = memberFlags;
193 member.roles = roles;
194
195 m_memberSlots.push_back(member);
196
197 SubGroupCounterIncrease(subgroup);
198
199 sLFGMgr->SetupGroupMember(member.guid, GetGUID());
200}
201
211
213{
216 if (!isBGGroup() && !isBFGroup())
217 {
218 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
219
220 stmt->setUInt8(0, uint8(m_groupType));
221 stmt->setUInt32(1, m_dbStoreId);
222
223 CharacterDatabase.Execute(stmt);
224 }
225
226 SendUpdate();
227}
228
230{
232
234
235 if (!isBGGroup() && !isBFGroup())
236 {
237 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
238
239 stmt->setUInt8(0, uint8(m_groupType));
240 stmt->setUInt32(1, m_dbStoreId);
241
242 CharacterDatabase.Execute(stmt);
243 }
244
245 SendUpdate();
246
247 // update quest related GO states (quest activity dependent from raid membership)
248 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
249 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
250 player->UpdateForQuestWorldObjects();
251}
252
254{
255 if (m_memberSlots.size() > 5)
256 return; // What message error should we send?
257
259
261 {
262 delete[] m_subGroupsCounts;
263 m_subGroupsCounts = NULL;
264 }
265
266 if (!isBGGroup() && !isBFGroup())
267 {
268 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
269
270 stmt->setUInt8(0, uint8(m_groupType));
271 stmt->setUInt32(1, m_dbStoreId);
272
273 CharacterDatabase.Execute(stmt);
274 }
275
276 SendUpdate();
277
278 // update quest related GO states (quest activity dependent from raid membership)
279 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
280 if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
281 player->UpdateForQuestWorldObjects();
282}
283
285{
286 if (!player || player->GetGroupInvite())
287 return false;
288 Group* group = player->GetGroup();
289 if (group && (group->isBGGroup() || group->isBFGroup()))
290 group = player->GetOriginalGroup();
291 if (group)
292 return false;
293
294 RemoveInvite(player);
295
296 m_invitees.insert(player);
297
298 player->SetGroupInvite(this);
299
300 sScriptMgr->OnGroupInviteMember(this, player->GetGUID());
301
302 return true;
303}
304
306{
307 if (!AddInvite(player))
308 return false;
309
310 m_leaderGuid = player->GetGUID();
311 m_leaderName = player->GetName();
312 return true;
313}
314
316{
317 if (player)
318 {
319 m_invitees.erase(player);
320 player->SetGroupInvite(NULL);
321 }
322}
323
325{
326 for (InvitesList::iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
327 if (*itr)
328 (*itr)->SetGroupInvite(NULL);
329
330 m_invitees.clear();
331}
332
334{
335 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
336 {
337 if ((*itr) && (*itr)->GetGUID() == guid)
338 return (*itr);
339 }
340 return NULL;
341}
342
343Player* Group::GetInvited(const std::string& name) const
344{
345 for (InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
346 {
347 if ((*itr) && (*itr)->GetName() == name)
348 return (*itr);
349 }
350 return NULL;
351}
352
354{
355 // Get first not-full group
356 uint8 subGroup = 0;
358 {
359 bool groupFound = false;
360 for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup)
361 {
362 if (m_subGroupsCounts[subGroup] < MAXGROUPSIZE)
363 {
364 groupFound = true;
365 break;
366 }
367 }
368 // We are raid group and no one slot is free
369 if (!groupFound)
370 return false;
371 }
372
373 MemberSlot member;
374 member.guid = player->GetGUID();
375 member.name = player->GetName();
376 member.group = subGroup;
377 member.flags = 0;
378 member.roles = 0;
379 m_memberSlots.push_back(member);
380
381 SubGroupCounterIncrease(subGroup);
382
383 player->SetGroupInvite(NULL);
384 if (player->GetGroup())
385 {
386 if (isBGGroup() || isBFGroup()) // if player is in group and he is being added to BG raid group, then call SetBattlegroundRaid()
387 player->SetBattlegroundOrBattlefieldRaid(this, subGroup);
388 else //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
389 player->SetOriginalGroup(this, subGroup);
390 }
391 else //if player is not in group, then call set group
392 player->SetGroup(this, subGroup);
393
394 // if the same group invites the player back, cancel the homebind timer
395 InstanceGroupBind* bind = GetBoundInstance(player);
396 if (bind && bind->save->GetInstanceId() == player->GetInstanceId())
397 player->m_InstanceValid = true;
398
399 if (!isRaidGroup()) // reset targetIcons for non-raid-groups
400 {
401 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
402 m_targetIcons[i] = 0;
403 }
404
405 // insert into the table if we're not a battleground group
406 if (!isBGGroup() && !isBFGroup())
407 {
408 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GROUP_MEMBER);
409
410 stmt->setUInt32(0, m_dbStoreId);
411 stmt->setUInt32(1, GUID_LOPART(member.guid));
412 stmt->setUInt8(2, member.flags);
413 stmt->setUInt8(3, member.group);
414 stmt->setUInt8(4, member.roles);
415
416 CharacterDatabase.Execute(stmt);
417 }
418
419 SendUpdate();
420 sScriptMgr->OnGroupAddMember(this, player->GetGUID());
421
422 if (!IsLeader(player->GetGUID()) && !isBGGroup() && !isBFGroup())
423 {
424 // reset the new member's instances, unless he is currently in one of them
425 // including raid/heroic instances that they are not permanently bound to!
428
429 if (player->getLevel() >= LEVELREQUIREMENT_HEROIC)
430 {
432 {
434 player->SendDungeonDifficulty();
435 }
436 if (player->GetRaidDifficulty() != GetRaidDifficulty())
437 {
439 player->SendRaidDifficulty();
440 }
441 }
442 }
445
446 // quest related GO state dependent from raid membership
447 if (isRaidGroup())
449
450 {
451 // Broadcast new player group member fields to rest of the group
453
454 UpdateData groupData(player->GetMapId());
455 WorldPacket groupDataPacket;
456
457 // Broadcast group members' fields to player
458 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
459 {
460 if (itr->GetSource() == player)
461 continue;
462
463 if (Player* member = itr->GetSource())
464 {
465 if (player->HaveAtClient(member))
466 {
467 member->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
468 member->BuildValuesUpdateBlockForPlayer(&groupData, player);
469 member->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
470 }
471
472 if (member->HaveAtClient(player))
473 {
474 UpdateData newData(player->GetMapId());
475 WorldPacket newDataPacket;
476 player->BuildValuesUpdateBlockForPlayer(&newData, member);
477 if (newData.HasData())
478 {
479 newData.BuildPacket(&newDataPacket);
480 member->SendDirectMessage(&newDataPacket);
481 }
482 }
483 }
484 }
485
486 if (groupData.HasData())
487 {
488 groupData.BuildPacket(&groupDataPacket);
489 player->SendDirectMessage(&groupDataPacket);
490 }
491
493 }
494
497
498 return true;
499}
500
501bool Group::RemoveMember(uint64 guid, const RemoveMethod& method /*= GROUP_REMOVEMETHOD_DEFAULT*/, uint64 kicker /*= 0*/, const char* reason /*= NULL*/)
502{
504
505 sScriptMgr->OnGroupRemoveMember(this, guid, method, kicker, reason);
506
507 // LFG group vote kick handled in scripts
508 if (isLFGGroup() && method == GROUP_REMOVEMETHOD_KICK)
509 return m_memberSlots.size();
510
511 // remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group)
512 if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u))
513 {
514 Player* player = ObjectAccessor::FindPlayer(guid);
515 if (player)
516 {
517 // Battleground group handling
518 if (isBGGroup() || isBFGroup())
520 else
521 // Regular group
522 {
523 if (player->GetOriginalGroup() == this)
524 player->SetOriginalGroup(NULL);
525 else
526 player->SetGroup(NULL);
527
528 // quest related GO state dependent from raid membership
530 }
531
532 WorldPacket data;
533
534 if (method == GROUP_REMOVEMETHOD_KICK || method == GROUP_REMOVEMETHOD_KICK_LFG)
535 {
537 player->GetSession()->SendPacket(&data);
538 }
539
540 SendUpdateToPlayer(guid, NULL);
541
542 _homebindIfInstance(player);
543 }
544
545 // Remove player from group in DB
546 if (!isBGGroup() && !isBFGroup())
547 {
548 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER);
549 stmt->setUInt32(0, GUID_LOPART(guid));
550 CharacterDatabase.Execute(stmt);
551 DelinkMember(guid);
552 }
553
554 // Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
555 if ((player && player->GetSkillValue(SKILL_ENCHANTING)) || !player)
557
558 // Remove player from loot rolls
559 for (Rolls::iterator it = RollId.begin(); it != RollId.end(); ++it)
560 {
561 Roll* roll = *it;
562 Roll::PlayerVote::iterator itr2 = roll->playerVote.find(guid);
563 if (itr2 == roll->playerVote.end())
564 continue;
565
566 if (itr2->second == RollType::ROLL_GREED || itr2->second == RollType::ROLL_DISENCHANT)
567 --roll->totalGreed;
568 else if (itr2->second == RollType::ROLL_NEED)
569 --roll->totalNeed;
570 else if (itr2->second == RollType::ROLL_PASS)
571 --roll->totalPass;
572
573 if (itr2->second != RollType::ROLL_INVALID)
574 --roll->totalPlayersRolling;
575
576 roll->playerVote.erase(itr2);
577
579 }
580
581 // Update subgroups
583 if (slot != m_memberSlots.end())
584 {
585 SubGroupCounterDecrease(slot->group);
586 m_memberSlots.erase(slot);
587 }
588
589 // Pick new leader if necessary
590 if (m_leaderGuid == guid)
591 {
592 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
593 {
594 if (ObjectAccessor::FindPlayer(itr->guid))
595 {
596 ChangeLeader(itr->guid);
597 break;
598 }
599 }
600 }
601
602 SendUpdate();
603
604 if (isLFGGroup() && GetMembersCount() == 1)
605 {
607 uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID());
608 if (!mapId || !leader || (leader->IsAlive() && leader->GetMapId() != mapId))
609 {
610 Disband();
611 return false;
612 }
613 }
614
615 if (m_memberMgr.getSize() < ((isLFGGroup() || isBGGroup()) ? 1u : 2u))
616 Disband();
617
618 return true;
619 }
620 // If group size before player removal <= 2 then disband it
621 else
622 {
623 Disband();
624 return false;
625 }
626}
627
628void Group::ChangeLeader(uint64 newLeaderGuid)
629{
630 member_witerator slot = _getMemberWSlot(newLeaderGuid);
631
632 if (slot == m_memberSlots.end())
633 return;
634
635 Player* newLeader = ObjectAccessor::FindPlayer(slot->guid);
636
637 // Don't allow switching leader to offline players
638 if (!newLeader)
639 return;
640
641 sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid);
642
643 if (!isBGGroup() && !isBFGroup())
644 {
645 SQLTransaction trans = CharacterDatabase.BeginTransaction();
646
647 // Remove the groups permanent instance bindings
648 for (uint8 i = 0; i < 15; ++i)
649 {
650 for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();)
651 {
652 // Do not unbind saves of instances that already had map created (a newLeader entered)
653 // forcing a new instance with another leader requires group disbanding (confirmed on retail)
654 if (itr->second.perm && !sMapMgr->FindMap(itr->first, itr->second.save->GetInstanceId()))
655 {
657 stmt->setUInt32(0, m_dbStoreId);
658 stmt->setUInt32(1, itr->second.save->GetInstanceId());
659 trans->Append(stmt);
660
661 itr->second.save->RemoveGroup(this);
662 m_boundInstances[i].erase(itr++);
663 }
664 else
665 ++itr;
666 }
667 }
668
669 // Copy the permanent binds from the new leader to the group
670 Player::ConvertInstancesToGroup(newLeader, this, true);
671
672 // Update the group leader
673 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEADER);
674
675 stmt->setUInt32(0, newLeader->GetGUIDLow());
676 stmt->setUInt32(1, m_dbStoreId);
677
678 trans->Append(stmt);
679
680 CharacterDatabase.CommitTransaction(trans);
681 }
682
683 m_leaderGuid = newLeader->GetGUID();
684 m_leaderName = newLeader->GetName();
686
687 uint8 leaderNameLen = m_leaderName.size();
688
689 WorldPacket data(SMSG_GROUP_SET_LEADER, 1 + 1 + leaderNameLen);
690 data << uint8(0);
691
692 data.WriteBits(leaderNameLen, 6);
693 data.FlushBits();
694
696
697 BroadcastPacket(&data, true);
698}
699
700void Group::Disband(bool hideDestroy /* = false */)
701{
702 bool const wasLFGGroup = isLFGGroup();
703 uint64 const lfgGroupGuid = wasLFGGroup ? GetGUID() : 0;
704 uint8 const lfgQueueId = wasLFGGroup ? sLFGMgr->GetQueueId(lfgGroupGuid) : 0;
705
706 sScriptMgr->OnGroupDisband(this);
707
708 Player* player;
709 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
710 {
711 player = ObjectAccessor::FindPlayerInOrOutOfWorld(citr->guid);
712 if (!player)
713 continue;
714
715 //we cannot call _removeMember because it would invalidate member iterator
716 //if we are removing player from battleground raid
717 if (isBGGroup() || isBFGroup())
719 else
720 {
721 //we can remove player who is in battleground from his original group
722 if (player->GetOriginalGroup() == this)
723 player->SetOriginalGroup(NULL);
724 else
725 player->SetGroup(NULL);
726 }
727
728 // quest related GO state dependent from raid membership
729 if (isRaidGroup() && player->IsInWorld())
731
732 if (!player->GetSession())
733 continue;
734
735 WorldPacket data;
736 if (!hideDestroy)
737 {
739 player->GetSession()->SendPacket(&data);
740 }
741
742 //we already removed player from group and in player->GetGroup() is his original group, send update
743 if (Group* group = player->GetGroup())
744 group->SendUpdate();
745 else
746 SendUpdateToPlayer(player->GetGUID(), NULL);
747
748 if (wasLFGGroup)
749 player->GetSession()->SendLfgClearStatus(lfgGroupGuid, lfgQueueId, true);
750
751 _homebindIfInstance(player);
752 }
753 RollId.clear();
754 m_memberSlots.clear();
755
757
758 if (!isBGGroup() && !isBFGroup())
759 {
760 SQLTransaction trans = CharacterDatabase.BeginTransaction();
761
762 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP);
763 stmt->setUInt32(0, m_dbStoreId);
764 trans->Append(stmt);
765
766 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER_ALL);
767 stmt->setUInt32(0, m_dbStoreId);
768 trans->Append(stmt);
769
770 CharacterDatabase.CommitTransaction(trans);
771
774
775 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
776 stmt->setUInt32(0, m_dbStoreId);
777 CharacterDatabase.Execute(stmt);
778
779 sGroupMgr->FreeGroupDbStoreId(this);
780 }
781
782 sGroupMgr->RemoveGroup(this);
783 delete this;
784}
785
786/*********************************************************/
787/*** LOOT SYSTEM ***/
788/*********************************************************/
789
790void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll& r)
791{
792 WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
793 data << uint64(r.itemGUID); // guid of rolled item
794 data << uint32(mapid); // 3.3.3 mapid
795 data << uint32(r.itemSlot); // itemslot
796 data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
797 data << uint32(r.itemRandomSuffix); // randomSuffix
798 data << uint32(r.itemRandomPropId); // item random property ID
799 data << uint32(r.itemCount); // items in stack
800 data << uint32(countDown); // the countdown time to choose "need" or "greed"
801 data << uint8(r.rollVoteMask); // roll type mask
802 data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it???
803
804 for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
805 {
806 Player* p = ObjectAccessor::FindPlayer(itr->first);
807 if (!p || !p->GetSession())
808 continue;
809
810 if (itr->second == RollType::MAX_ROLL_TYPE)
811 p->GetSession()->SendPacket(&data);
812 }
813}
814
815void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r)
816{
817 if (!p || !p->GetSession())
818 return;
819
820 WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
821 data << uint64(r.itemGUID); // guid of rolled item
822 data << uint32(mapId); // 3.3.3 mapid
823 data << uint32(r.itemSlot); // itemslot
824 data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
825 data << uint32(r.itemRandomSuffix); // randomSuffix
826 data << uint32(r.itemRandomPropId); // item random property ID
827 data << uint32(r.itemCount); // items in stack
828 data << uint32(countDown); // the countdown time to choose "need" or "greed"
829 uint8 voteMask = uint8(r.rollVoteMask);
830 if (!canNeed)
832 data << uint8(voteMask); // roll type mask
833 data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it???
834
835 p->GetSession()->SendPacket(&data);
836}
837
838void Group::SendLootRoll(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, RollType rollType, Roll const& roll)
839{
840 WorldPacket data(SMSG_LOOT_ROLL, (8 + 4 + 8 + 4 + 4 + 4 + 1 + 1 + 1));
841 data << uint64(sourceGuid); // guid of the item rolled
842 data << uint32(roll.itemSlot); // slot
843 data << uint64(targetGuid);
844 data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
845 data << uint32(roll.itemRandomSuffix); // randomSuffix
846 data << uint32(roll.itemRandomPropId); // Item random property ID
847 data << uint32(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
848 data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
849 data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed
850
851 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
852 {
853 Player* p = ObjectAccessor::FindPlayer(itr->first);
854 if (!p || !p->GetSession())
855 continue;
856
857 if (itr->second != RollType::ROLL_INVALID)
858 p->GetSession()->SendPacket(&data);
859 }
860}
861
862void Group::SendLootRollWon(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, RollType rollType, Roll const& roll)
863{
864 WorldPacket data(SMSG_LOOT_ROLL_WON, (8 + 4 + 4 + 4 + 4 + 8 + 1 + 1));
865 data << uint64(sourceGuid); // guid of the item rolled
866 data << uint32(roll.itemSlot); // slot
867 data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
868 data << uint32(roll.itemRandomSuffix); // randomSuffix
869 data << uint32(roll.itemRandomPropId); // Item random property
870 data << uint64(targetGuid); // guid of the player who won.
871 data << uint32(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
872 data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL
873
874 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
875 {
876 Player* p = ObjectAccessor::FindPlayer(itr->first);
877 if (!p || !p->GetSession())
878 continue;
879
880 if (itr->second != RollType::ROLL_INVALID)
881 p->GetSession()->SendPacket(&data);
882 }
883}
884
886{
887 WorldPacket data(SMSG_LOOT_ALL_PASSED, (8 + 4 + 4 + 4 + 4));
888 data << uint64(roll.itemGUID); // Guid of the item rolled
889 data << uint32(roll.itemSlot); // Item loot slot
890 data << uint32(roll.itemid); // The itemEntryId for the item that shall be rolled for
891 data << uint32(roll.itemRandomPropId); // Item random property ID
892 data << uint32(roll.itemRandomSuffix); // Item random suffix ID
893
894 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
895 {
896 Player* player = ObjectAccessor::FindPlayer(itr->first);
897 if (!player || !player->GetSession())
898 continue;
899
900 if (itr->second != RollType::ROLL_INVALID)
901 player->GetSession()->SendPacket(&data);
902 }
903}
904
905// notify group members which player is the allowed looter for the given creature
906void Group::SendLooter(Creature* creature, Player* pLooter)
907{
908 ASSERT(creature);
909
910 ObjectGuid creatureGuid = creature->GetGUID();
911 ObjectGuid looterGuid = pLooter ? pLooter->GetGUID() : 0;
912 ObjectGuid masterLooterGuid = GetLootMethod() == LootMethod::MASTER_LOOT ? GetLooterGuid() : 0;
914
915 data.WriteBit(creatureGuid[5]);
916 data.WriteBit(masterLooterGuid != (uint64)0);
917 if (masterLooterGuid)
918 {
919 data.WriteBit(masterLooterGuid[4]);
920 data.WriteBit(masterLooterGuid[6]);
921 data.WriteBit(masterLooterGuid[0]);
922 data.WriteBit(masterLooterGuid[7]);
923 data.WriteBit(masterLooterGuid[5]);
924 data.WriteBit(masterLooterGuid[2]);
925 data.WriteBit(masterLooterGuid[3]);
926 data.WriteBit(masterLooterGuid[1]);
927 }
928 data.WriteBit(creatureGuid[1]);
929 data.WriteBit(looterGuid != (uint64)0);
930 data.WriteBit(creatureGuid[4]);
931 data.WriteBit(creatureGuid[3]);
932 data.WriteBit(creatureGuid[2]);
933 if (looterGuid)
934 {
935 data.WriteBit(looterGuid[2]);
936 data.WriteBit(looterGuid[3]);
937 data.WriteBit(looterGuid[4]);
938 data.WriteBit(looterGuid[5]);
939 data.WriteBit(looterGuid[6]);
940 data.WriteBit(looterGuid[0]);
941 data.WriteBit(looterGuid[1]);
942 data.WriteBit(looterGuid[7]);
943 }
944 data.WriteBit(creatureGuid[7]);
945 data.WriteBit(creatureGuid[0]);
946 data.WriteBit(creatureGuid[6]);
947 data.FlushBits();
948
949 if (looterGuid)
950 {
951 data.WriteByteSeq(looterGuid[7]);
952 data.WriteByteSeq(looterGuid[1]);
953 data.WriteByteSeq(looterGuid[0]);
954 data.WriteByteSeq(looterGuid[6]);
955 data.WriteByteSeq(looterGuid[5]);
956 data.WriteByteSeq(looterGuid[3]);
957 data.WriteByteSeq(looterGuid[4]);
958 data.WriteByteSeq(looterGuid[2]);
959 }
960
961 if (masterLooterGuid)
962 {
963 data.WriteByteSeq(masterLooterGuid[4]);
964 data.WriteByteSeq(masterLooterGuid[5]);
965 data.WriteByteSeq(masterLooterGuid[6]);
966 data.WriteByteSeq(masterLooterGuid[3]);
967 data.WriteByteSeq(masterLooterGuid[2]);
968 data.WriteByteSeq(masterLooterGuid[7]);
969 data.WriteByteSeq(masterLooterGuid[0]);
970 data.WriteByteSeq(masterLooterGuid[1]);
971 }
972
973 data.WriteByteSeq(creatureGuid[5]);
974 data.WriteByteSeq(creatureGuid[1]);
975 data.WriteByteSeq(creatureGuid[6]);
976 data.WriteByteSeq(creatureGuid[2]);
977 data.WriteByteSeq(creatureGuid[3]);
978 data.WriteByteSeq(creatureGuid[0]);
979 data.WriteByteSeq(creatureGuid[7]);
980 data.WriteByteSeq(creatureGuid[4]);
981
982 BroadcastPacket(&data, false);
983}
984
985void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
986{
987 std::vector<LootItem>::iterator i;
988 ItemTemplate const* item;
989 uint8 itemSlot = 0;
990
991 for (i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
992 {
993 if (i->freeforall)
994 continue;
995
996 item = sObjectMgr->GetItemTemplate(i->itemid);
997 if (!item)
998 {
999 //SF_LOG_DEBUG("misc", "Group::GroupLoot: missing item prototype for item with id: %d", i->itemid);
1000 continue;
1001 }
1002
1003 //roll for over-threshold item if it's one-player loot
1004 if (item->Quality >= uint32(m_lootThreshold))
1005 {
1006 uint64 newitemGUID = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), 0, HIGHGUID_ITEM);
1007 Roll* r = new Roll(newitemGUID, *i);
1008
1009 //a vector is filled with only near party members
1010 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1011 {
1012 Player* member = itr->GetSource();
1013 if (!member || !member->GetSession())
1014 continue;
1015 if (i->AllowedForPlayer(member))
1016 {
1017 if (member->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
1018 {
1020
1021 if (member->GetPassOnGroupLoot())
1022 {
1023 r->playerVote[member->GetGUID()] = RollType::ROLL_PASS;
1024 r->totalPass++;
1025 // can't broadcast the pass now. need to wait until all rolling players are known.
1026 }
1027 else
1029 }
1030 }
1031 }
1032
1033 if (r->totalPlayersRolling > 0)
1034 {
1035 r->setLoot(loot);
1036 r->itemSlot = itemSlot;
1039
1040 loot->items[itemSlot].is_blocked = true;
1041
1042 // If there is any "auto pass", broadcast the pass now.
1043 if (r->totalPass)
1044 {
1045 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1046 {
1047 Player* p = ObjectAccessor::FindPlayer(itr->first);
1048 if (!p || !p->GetSession())
1049 continue;
1050
1051 if (itr->second == RollType::ROLL_PASS)
1052 SendLootRoll(newitemGUID, p->GetGUID(), 128, RollType::ROLL_PASS, *r);
1053 }
1054 }
1055
1056 SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
1057
1058 RollId.push_back(r);
1059
1060 if (Creature* creature = pLootedObject->ToCreature())
1061 {
1062 creature->m_groupLootTimer = 60000;
1063 creature->lootingGroupLowGUID = GetLowGUID();
1064 }
1065 else if (GameObject* go = pLootedObject->ToGameObject())
1066 {
1067 go->m_groupLootTimer = 60000;
1068 go->lootingGroupLowGUID = GetLowGUID();
1069 }
1070 }
1071 else
1072 delete r;
1073 }
1074 else
1075 i->is_underthreshold = true;
1076 }
1077
1078 for (i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i, ++itemSlot)
1079 {
1080 if (!i->follow_loot_rules)
1081 continue;
1082
1083 item = sObjectMgr->GetItemTemplate(i->itemid);
1084 if (!item)
1085 {
1086 //SF_LOG_DEBUG("misc", "Group::GroupLoot: missing item prototype for item with id: %d", i->itemid);
1087 continue;
1088 }
1089
1090 uint64 newitemGUID = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), 0, HIGHGUID_ITEM);
1091 Roll* r = new Roll(newitemGUID, *i);
1092
1093 //a vector is filled with only near party members
1094 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1095 {
1096 Player* member = itr->GetSource();
1097 if (!member || !member->GetSession())
1098 continue;
1099
1100 if (i->AllowedForPlayer(member))
1101 {
1102 if (member->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
1103 {
1106 }
1107 }
1108 }
1109
1110 if (r->totalPlayersRolling > 0)
1111 {
1112 r->setLoot(loot);
1113 r->itemSlot = itemSlot;
1114
1115 loot->quest_items[itemSlot - loot->items.size()].is_blocked = true;
1116
1117 SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
1118
1119 RollId.push_back(r);
1120
1121 if (Creature* creature = pLootedObject->ToCreature())
1122 {
1123 creature->m_groupLootTimer = 60000;
1124 creature->lootingGroupLowGUID = GetLowGUID();
1125 }
1126 else if (GameObject* go = pLootedObject->ToGameObject())
1127 {
1128 go->m_groupLootTimer = 60000;
1129 go->lootingGroupLowGUID = GetLowGUID();
1130 }
1131 }
1132 else
1133 delete r;
1134 }
1135}
1136
1137void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
1138{
1139 ItemTemplate const* item;
1140 uint8 itemSlot = 0;
1141 for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
1142 {
1143 if (i->freeforall)
1144 continue;
1145
1146 item = sObjectMgr->GetItemTemplate(i->itemid);
1147
1148 //roll for over-threshold item if it's one-player loot
1149 if (item->Quality >= uint32(m_lootThreshold))
1150 {
1151 uint64 newitemGUID = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), 0, HIGHGUID_ITEM);
1152 Roll* r = new Roll(newitemGUID, *i);
1153
1154 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1155 {
1156 Player* playerToRoll = itr->GetSource();
1157 if (!playerToRoll || !playerToRoll->GetSession())
1158 continue;
1159
1160 bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
1161 if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
1162 {
1164 if (playerToRoll->GetPassOnGroupLoot())
1165 {
1166 r->playerVote[playerToRoll->GetGUID()] = RollType::ROLL_PASS;
1167 r->totalPass++;
1168 // can't broadcast the pass now. need to wait until all rolling players are known.
1169 }
1170 else
1171 r->playerVote[playerToRoll->GetGUID()] = RollType::MAX_ROLL_TYPE;
1172 }
1173 }
1174
1175 if (r->totalPlayersRolling > 0)
1176 {
1177 r->setLoot(loot);
1178 r->itemSlot = itemSlot;
1181
1184
1185 loot->items[itemSlot].is_blocked = true;
1186
1187 //Broadcast Pass and Send Rollstart
1188 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1189 {
1190 Player* p = ObjectAccessor::FindPlayer(itr->first);
1191 if (!p || !p->GetSession())
1192 continue;
1193
1194 if (itr->second == RollType::ROLL_PASS)
1195 SendLootRoll(newitemGUID, p->GetGUID(), 128, RollType::ROLL_PASS, *r);
1196 else
1197 SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
1198 }
1199
1200 RollId.push_back(r);
1201
1202 if (Creature* creature = lootedObject->ToCreature())
1203 {
1204 creature->m_groupLootTimer = 60000;
1205 creature->lootingGroupLowGUID = GetLowGUID();
1206 }
1207 else if (GameObject* go = lootedObject->ToGameObject())
1208 {
1209 go->m_groupLootTimer = 60000;
1210 go->lootingGroupLowGUID = GetLowGUID();
1211 }
1212 }
1213 else
1214 delete r;
1215 }
1216 else
1217 i->is_underthreshold = true;
1218 }
1219
1220 for (std::vector<LootItem>::iterator i = loot->quest_items.begin(); i != loot->quest_items.end(); ++i, ++itemSlot)
1221 {
1222 if (!i->follow_loot_rules)
1223 continue;
1224
1225 item = sObjectMgr->GetItemTemplate(i->itemid);
1226 uint64 newitemGUID = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), 0, HIGHGUID_ITEM);
1227 Roll* r = new Roll(newitemGUID, *i);
1228
1229 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1230 {
1231 Player* playerToRoll = itr->GetSource();
1232 if (!playerToRoll || !playerToRoll->GetSession())
1233 continue;
1234
1235 bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
1236 if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
1237 {
1239 r->playerVote[playerToRoll->GetGUID()] = RollType::MAX_ROLL_TYPE;
1240 }
1241 }
1242
1243 if (r->totalPlayersRolling > 0)
1244 {
1245 r->setLoot(loot);
1246 r->itemSlot = itemSlot;
1247
1248 loot->quest_items[itemSlot - loot->items.size()].is_blocked = true;
1249
1250 //Broadcast Pass and Send Rollstart
1251 for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
1252 {
1253 Player* p = ObjectAccessor::FindPlayer(itr->first);
1254 if (!p || !p->GetSession())
1255 continue;
1256
1257 if (itr->second == RollType::ROLL_PASS)
1258 SendLootRoll(newitemGUID, p->GetGUID(), 128, RollType::ROLL_PASS, *r);
1259 else
1260 SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
1261 }
1262
1263 RollId.push_back(r);
1264
1265 if (Creature* creature = lootedObject->ToCreature())
1266 {
1267 creature->m_groupLootTimer = 60000;
1268 creature->lootingGroupLowGUID = GetLowGUID();
1269 }
1270 else if (GameObject* go = lootedObject->ToGameObject())
1271 {
1272 go->m_groupLootTimer = 60000;
1273 go->lootingGroupLowGUID = GetLowGUID();
1274 }
1275 }
1276 else
1277 delete r;
1278 }
1279}
1280
1281void Group::MasterLoot(Loot* /*loot*/, WorldObject* pLootedObject)
1282{
1283 SF_LOG_DEBUG("network", "Group::MasterLoot (SMSG_LOOT_MASTER_LIST)");
1284
1285 uint32 realCount = 0;
1286 ObjectGuid lootedGuid = pLootedObject->GetGUID();
1288
1289 data.WriteGuidMask(lootedGuid, 1);
1290 data.WriteBits(0, 24);
1291
1292 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1293 {
1294 Player* looter = itr->GetSource();
1295 if (!looter->IsInWorld())
1296 continue;
1297
1298 if (looter->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
1299 {
1300 ObjectGuid looterGuid = looter->GetGUID();
1301 data.WriteGuidMask(looterGuid, 4, 1, 2, 5, 3, 7, 0, 6);
1302 ++realCount;
1303 }
1304 }
1305
1306 data.WriteGuidMask(lootedGuid, 2, 0, 6, 7, 3, 4);
1307
1308 data.WriteGuidBytes(lootedGuid, 3, 0, 2);
1309
1310 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1311 {
1312 Player* looter = itr->GetSource();
1313 if (!looter->IsInWorld())
1314 continue;
1315
1316 if (looter->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
1317 {
1318 ObjectGuid looterGuid = looter->GetGUID();
1319 data.WriteGuidBytes(looterGuid, 1, 3, 7, 2, 0, 6, 4, 5);
1320 }
1321 }
1322
1323 data.WriteGuidBytes(lootedGuid, 7, 1, 6, 4, 5);
1324
1325 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1326 {
1327 Player* looter = itr->GetSource();
1328 if (looter->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
1329 looter->GetSession()->SendPacket(&data);
1330 }
1331}
1332
1333void Group::CountRollVote(uint64 playerGUID, uint64 Guid, RollType Choice)
1334{
1335 Rolls::iterator rollI = GetRoll(Guid);
1336 if (rollI == RollId.end())
1337 return;
1338 Roll* roll = *rollI;
1339
1340 Roll::PlayerVote::iterator itr = roll->playerVote.find(playerGUID);
1341 // this condition means that player joins to the party after roll begins
1342 if (itr == roll->playerVote.end())
1343 return;
1344
1345 if (roll->getLoot())
1346 if (roll->getLoot()->items.empty())
1347 return;
1348
1349 switch (Choice)
1350 {
1351 case RollType::ROLL_PASS: // Player choose pass
1352 SendLootRoll(0, playerGUID, 128, RollType::ROLL_PASS, *roll);
1353 ++roll->totalPass;
1354 itr->second = RollType::ROLL_PASS;
1355 break;
1356 case RollType::ROLL_NEED: // player choose Need
1357 SendLootRoll(0, playerGUID, 0, RollType::ROLL_NEED, *roll);
1358 ++roll->totalNeed;
1359 itr->second = RollType::ROLL_NEED;
1360 break;
1361 case RollType::ROLL_GREED: // player choose Greed
1362 SendLootRoll(0, playerGUID, 128, RollType::ROLL_GREED, *roll);
1363 ++roll->totalGreed;
1364 itr->second = RollType::ROLL_GREED;
1365 break;
1366 case RollType::ROLL_DISENCHANT: // player choose Disenchant
1367 SendLootRoll(0, playerGUID, 128, RollType::ROLL_DISENCHANT, *roll);
1368 ++roll->totalGreed;
1369 itr->second = RollType::ROLL_DISENCHANT;
1370 break;
1371 }
1372
1373 if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
1374 CountTheRoll(rollI);
1375}
1376
1377//called when roll timer expires
1379{
1380 for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
1381 {
1382 if ((*itr)->getLoot() == pLoot)
1383 {
1384 CountTheRoll(itr); //i don't have to edit player votes, who didn't vote ... he will pass
1385 itr = RollId.begin();
1386 }
1387 else
1388 ++itr;
1389 }
1390}
1391
1392void Group::CountTheRoll(Rolls::iterator rollI)
1393{
1394 Roll* roll = *rollI;
1395 if (!roll->isValid()) // is loot already deleted ?
1396 {
1397 RollId.erase(rollI);
1398 delete roll;
1399 return;
1400 }
1401
1402 //end of the roll
1403 if (roll->totalNeed > 0)
1404 {
1405 if (!roll->playerVote.empty())
1406 {
1407 uint8 maxresul = 0;
1408 uint64 maxguid = (*roll->playerVote.begin()).first;
1409 Player* player;
1410
1411 for (Roll::PlayerVote::const_iterator itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
1412 {
1413 if (itr->second != RollType::ROLL_NEED)
1414 continue;
1415
1416 uint8 randomN = std::rand() % 100 + 1;
1417 SendLootRoll(0, itr->first, randomN, RollType::ROLL_NEED, *roll);
1418 if (maxresul < randomN)
1419 {
1420 maxguid = itr->first;
1421 maxresul = randomN;
1422 }
1423 }
1424 SendLootRollWon(0, maxguid, maxresul, RollType::ROLL_NEED, *roll);
1425 player = ObjectAccessor::FindPlayer(maxguid);
1426
1427 if (player && player->GetSession())
1428 {
1430
1431 ItemPosCountVec dest;
1432 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1433 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1434 if (msg == EQUIP_ERR_OK)
1435 {
1436 item->is_looted = true;
1437 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1438 roll->getLoot()->unlootedCount--;
1439 player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, item->GetAllowedLooters());
1440 }
1441 else
1442 {
1443 item->is_blocked = false;
1444 player->SendEquipError(msg, NULL, NULL, roll->itemid);
1445 }
1446 }
1447 }
1448 }
1449 else if (roll->totalGreed > 0)
1450 {
1451 if (!roll->playerVote.empty())
1452 {
1453 uint8 maxresul = 0;
1454 uint64 maxguid = (*roll->playerVote.begin()).first;
1455 Player* player;
1457
1458 Roll::PlayerVote::iterator itr;
1459 for (itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr)
1460 {
1461 if (itr->second != RollType::ROLL_GREED && itr->second != RollType::ROLL_DISENCHANT)
1462 continue;
1463
1464 uint8 randomN = std::rand() % 100 + 1;
1465 SendLootRoll(0, itr->first, randomN, RollType(itr->second), *roll);
1466 if (maxresul < randomN)
1467 {
1468 maxguid = itr->first;
1469 maxresul = randomN;
1470 rollvote = RollType(itr->second);
1471 }
1472 }
1473 SendLootRollWon(0, maxguid, maxresul, rollvote, *roll);
1474 player = ObjectAccessor::FindPlayer(maxguid);
1475
1476 if (player && player->GetSession())
1477 {
1479
1480 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1481
1482 if (rollvote == RollType::ROLL_GREED)
1483 {
1484 ItemPosCountVec dest;
1485 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count);
1486 if (msg == EQUIP_ERR_OK)
1487 {
1488 item->is_looted = true;
1489 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1490 roll->getLoot()->unlootedCount--;
1491 player->StoreNewItem(dest, roll->itemid, true, item->randomPropertyId, item->GetAllowedLooters());
1492 }
1493 else
1494 {
1495 item->is_blocked = false;
1496 player->SendEquipError(msg, NULL, NULL, roll->itemid);
1497 }
1498 }
1499 else if (rollvote == RollType::ROLL_DISENCHANT)
1500 {
1501 item->is_looted = true;
1502 roll->getLoot()->NotifyItemRemoved(roll->itemSlot);
1503 roll->getLoot()->unlootedCount--;
1504 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(roll->itemid);
1505 player->AutoStoreLoot(pProto->DisenchantID, LootTemplates_Disenchant, true);
1507 }
1508 }
1509 }
1510 }
1511 else
1512 {
1513 SendLootAllPassed(*roll);
1514
1515 // remove is_blocked so that the item is lootable by all players
1516 LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]);
1517 if (item)
1518 item->is_blocked = false;
1519 }
1520
1521 RollId.erase(rollI);
1522 delete roll;
1523}
1524
1525void Group::SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid, uint8 Index)
1526{
1527 if (id >= TARGETICONCOUNT)
1528 return;
1529
1530 // clean other icons
1531 if (targetGuid != 0)
1532 for (int i = 0; i < TARGETICONCOUNT; ++i)
1533 if (m_targetIcons[i] == targetGuid)
1534 SetTargetIcon(i, 0, 0, 0);
1535
1536 m_targetIcons[id] = targetGuid;
1537
1538 WorldPacket data(SMSG_RAID_TARGET_UPDATE_SINGLE, 8 + 1 + 8 + 1);
1539
1540 data.WriteGuidMask(whoGuid, 6);
1541 data.WriteGuidMask(targetGuid, 4);
1542 data.WriteGuidMask(whoGuid, 0, 7);
1543 data.WriteGuidMask(targetGuid, 6);
1544 data.WriteGuidMask(whoGuid, 5, 3, 4);
1545 data.WriteGuidMask(targetGuid, 7, 2, 5, 1);
1546 data.WriteGuidMask(whoGuid, 2, 1);
1547 data.WriteGuidMask(targetGuid, 0, 3);
1548
1549 data.WriteGuidBytes(targetGuid, 1);
1550
1551 data << uint8(id);
1552
1553 data.WriteGuidBytes(whoGuid, 0, 5, 3);
1554 data.WriteGuidBytes(targetGuid, 7, 6);
1555 data.WriteGuidBytes(whoGuid, 1);
1556 data.WriteGuidBytes(targetGuid, 2, 4, 0, 3, 5);
1557 data.WriteGuidBytes(whoGuid, 6);
1558
1559 data << uint8(Index);
1560
1561 data.WriteGuidBytes(whoGuid, 4, 2, 7);
1562
1563 BroadcastPacket(&data, true);
1564}
1565
1567{
1568 if (!session)
1569 return;
1570
1571 uint8 Index = 0;
1573 data.WriteBits(0, 25);
1574
1575 for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
1576 {
1577 if (m_targetIcons[i] == 0)
1578 continue;
1579
1580 ObjectGuid guid = m_targetIcons[i];
1581
1582 data.WriteGuidMask(guid, 2, 1, 3, 7, 6, 4, 0, 5);
1583
1584 data.WriteGuidBytes(guid, 4, 7, 1, 0, 6, 5, 3);
1585 data << uint8(i);
1586 data.WriteGuidBytes(guid, 2);
1587 }
1588
1589 data << uint8(Index);
1590
1591 session->SendPacket(&data);
1592}
1593
1595{
1596 for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr)
1597 SendUpdateToPlayer(witr->guid, &(*witr));
1598}
1599
1601{
1602 Player* player = slot ? ObjectAccessor::FindPlayer(playerGUID) :
1604
1605 if (!player || !player->GetSession())
1606 return;
1607
1608 // if MemberSlot wasn't provided
1609 if (!slot)
1610 {
1611 ObjectGuid groupGuid = m_guid;
1612 ObjectGuid leaderGuid = uint64(0);
1613
1614 WorldPacket data(SMSG_GROUP_LIST, 4 + 1 + 1 + 1 + 4 + 1 + 8 + 1 + 8 + 3);
1615 data.WriteBit(groupGuid[0]);
1616 data.WriteBit(leaderGuid[7]);
1617 data.WriteBit(leaderGuid[1]);
1618 data.WriteBit(0);
1619 data.WriteBit(groupGuid[7]);
1620 data.WriteBit(leaderGuid[6]);
1621 data.WriteBit(leaderGuid[5]);
1622 data.WriteBits(0, 21);
1623 data.WriteBit(leaderGuid[3]);
1624 data.WriteBit(leaderGuid[0]);
1625 data.WriteBit(0);
1626 data.WriteBit(groupGuid[5]);
1627 data.WriteBit(groupGuid[2]);
1628 data.WriteBit(groupGuid[4]);
1629 data.WriteBit(groupGuid[1]);
1630 data.WriteBit(0);
1631 data.WriteBit(leaderGuid[2]);
1632 data.WriteBit(groupGuid[6]);
1633 data.WriteBit(leaderGuid[4]);
1634 data.WriteBit(groupGuid[3]);
1635 data.FlushBits();
1636
1637 data.WriteByteSeq(leaderGuid[0]);
1638 data.WriteByteSeq(groupGuid[1]);
1639 data.WriteByteSeq(leaderGuid[4]);
1640 data.WriteByteSeq(leaderGuid[2]);
1641 data.WriteByteSeq(groupGuid[6]);
1642 data.WriteByteSeq(groupGuid[4]);
1643 data << uint8(0x10);
1644 data << uint8(0);
1645 data << int32(-1);
1646 data.WriteByteSeq(groupGuid[7]);
1647 data.WriteByteSeq(leaderGuid[3]);
1648 data.WriteByteSeq(leaderGuid[1]);
1649 data << uint32(m_counter++);
1650 data.WriteByteSeq(groupGuid[0]);
1651 data.WriteByteSeq(groupGuid[2]);
1652 data.WriteByteSeq(groupGuid[5]);
1653 data.WriteByteSeq(groupGuid[3]);
1654 data.WriteByteSeq(leaderGuid[7]);
1655 data << uint8(0);
1656 data.WriteByteSeq(leaderGuid[5]);
1657 data.WriteByteSeq(leaderGuid[6]);
1658
1659 player->GetSession()->SendPacket(&data);
1660 return;
1661 }
1662
1663 if (player->GetGroup() != this)
1664 return;
1665
1666 uint8 groupPosition = 0;
1667 uint8 i = 0;
1668
1669 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1670 {
1671 if (citr->group != slot->group)
1672 continue;
1673
1674 if (citr->guid == slot->guid)
1675 {
1676 groupPosition = i;
1677 break;
1678 }
1679
1680 i++;
1681 }
1682
1683 ByteBuffer memberData;
1684 ObjectGuid groupGuid = m_guid;
1685 ObjectGuid leaderGuid = m_leaderGuid;
1686 ObjectGuid looterGuid = m_looterGuid;
1687
1688 WorldPacket data(SMSG_GROUP_LIST, 4 + 3 + 4 + 1 + 8 + 1 + 8 + 3 + (GetMembersCount() * (4 + 2 + 8)) + 1 + 8 + 2 + 4 + 4);
1689 data.WriteBit(groupGuid[0]);
1690 data.WriteBit(leaderGuid[7]);
1691 data.WriteBit(leaderGuid[1]);
1692 data.WriteBit(1); // has dungeon and raid difficulty
1693 data.WriteBit(groupGuid[7]);
1694 data.WriteBit(leaderGuid[6]);
1695 data.WriteBit(leaderGuid[5]);
1696 data.WriteBits(GetMembersCount(), 21);
1697
1698 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1699 {
1700 ObjectGuid memberGuid = citr->guid;
1701 std::string memberName = citr->name;
1702
1703 Player* member = ObjectAccessor::FindPlayer(memberGuid);
1704
1705 uint8 onlineState = member ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
1706 onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0);
1707
1708 data.WriteBit(memberGuid[1]);
1709 data.WriteBit(memberGuid[2]);
1710 data.WriteBit(memberGuid[5]);
1711 data.WriteBit(memberGuid[6]);
1712 data.WriteBits(memberName.size(), 6);
1713 data.WriteBit(memberGuid[7]);
1714 data.WriteBit(memberGuid[3]);
1715 data.WriteBit(memberGuid[0]);
1716 data.WriteBit(memberGuid[4]);
1717
1718 memberData.WriteByteSeq(memberGuid[6]);
1719 memberData.WriteByteSeq(memberGuid[3]);
1720 memberData << uint8(citr->roles); // 67
1721 memberData << uint8(onlineState); // 64
1722 memberData.WriteByteSeq(memberGuid[7]);
1723 memberData.WriteByteSeq(memberGuid[4]);
1724 memberData.WriteByteSeq(memberGuid[1]);
1725 memberData.WriteString(memberName);
1726 memberData.WriteByteSeq(memberGuid[5]);
1727 memberData.WriteByteSeq(memberGuid[2]);
1728 memberData << uint8(citr->group); // 65
1729 memberData.WriteByteSeq(memberGuid[0]);
1730 memberData << uint8(citr->flags); // 66
1731 }
1732
1733 data.WriteBit(leaderGuid[3]);
1734 data.WriteBit(leaderGuid[0]);
1735 data.WriteBit(1); // has loot mode
1736 data.WriteBit(groupGuid[5]);
1737
1738 //if (hasLootMode)
1739 {
1740 data.WriteBit(looterGuid[6]);
1741 data.WriteBit(looterGuid[4]);
1742 data.WriteBit(looterGuid[5]);
1743 data.WriteBit(looterGuid[2]);
1744 data.WriteBit(looterGuid[1]);
1745 data.WriteBit(looterGuid[0]);
1746 data.WriteBit(looterGuid[7]);
1747 data.WriteBit(looterGuid[3]);
1748 }
1749
1750 data.WriteBit(groupGuid[2]);
1751 data.WriteBit(groupGuid[4]);
1752 data.WriteBit(groupGuid[1]);
1753 data.WriteBit(0); // is LFG
1754 data.WriteBit(leaderGuid[2]);
1755 data.WriteBit(groupGuid[6]);
1756
1757 /*if (isLFGGroup())
1758 {
1759 }*/
1760
1761 data.WriteBit(leaderGuid[4]);
1762 data.WriteBit(groupGuid[3]);
1763 data.FlushBits();
1764
1765 data.WriteByteSeq(leaderGuid[0]);
1766
1767 //if (hasInstanceDifficulty)
1768 {
1769 data << uint32(m_raidDifficulty); // raid Difficulty
1770 data << uint32(m_dungeonDifficulty); // dungeon Difficulty
1771 }
1772
1773 data.append(memberData);
1774 data.WriteByteSeq(groupGuid[1]);
1775
1776 /*if (isLFGGroup())
1777 {
1778 }*/
1779
1780 data.WriteByteSeq(leaderGuid[4]);
1781 data.WriteByteSeq(leaderGuid[2]);
1782
1783 //if (hasLootMode)
1784 {
1785 data << uint8(m_lootMethod);
1786 data.WriteByteSeq(looterGuid[0]);
1787 data.WriteByteSeq(looterGuid[5]);
1788 data.WriteByteSeq(looterGuid[4]);
1789 data.WriteByteSeq(looterGuid[3]);
1790 data.WriteByteSeq(looterGuid[2]);
1791 data << uint8(m_lootThreshold);
1792 data.WriteByteSeq(looterGuid[7]);
1793 data.WriteByteSeq(looterGuid[1]);
1794 data.WriteByteSeq(looterGuid[6]);
1795 }
1796
1797 data.WriteByteSeq(groupGuid[6]);
1798 data.WriteByteSeq(groupGuid[4]);
1799 data << uint8(m_groupType);
1800 data << uint8(0);
1801 data << uint32(groupPosition);
1802 data.WriteByteSeq(groupGuid[7]);
1803 data.WriteByteSeq(leaderGuid[3]);
1804 data.WriteByteSeq(leaderGuid[1]);
1805 data << uint32(m_counter++);
1806 data.WriteByteSeq(groupGuid[0]);
1807 data.WriteByteSeq(groupGuid[2]);
1808 data.WriteByteSeq(groupGuid[5]);
1809 data.WriteByteSeq(groupGuid[3]);
1810 data.WriteByteSeq(leaderGuid[7]);
1811 data << uint8(0);
1812 data.WriteByteSeq(leaderGuid[5]);
1813 data.WriteByteSeq(leaderGuid[6]);
1814
1815 player->GetSession()->SendPacket(&data);
1816
1817 /*data << uint8(m_groupType); // group type (flags in 3.3)
1818 data << uint8(slot->group);
1819 data << uint8(slot->flags);
1820 data << uint8(slot->roles);
1821 if (isLFGGroup())
1822 {
1823 data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done
1824 data << uint32(sLFGMgr->GetDungeon(m_guid));
1825 data << uint8(0); // 4.x new
1826 }
1827
1828 data << uint64(m_guid);
1829 data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent
1830 data << uint32(GetMembersCount()-1);
1831 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1832 {
1833 if (slot->guid == citr->guid)
1834 continue;
1835
1836 Player* member = ObjectAccessor::FindPlayer(citr->guid);
1837
1838 uint8 onlineState = member ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE;
1839 onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0);
1840
1841 data << citr->name;
1842 data << uint64(citr->guid); // guid
1843 data << uint8(onlineState); // online-state
1844 data << uint8(citr->group); // groupid
1845 data << uint8(citr->flags); // See enum GroupMemberFlags
1846 data << uint8(citr->roles); // Lfg Roles
1847 }
1848
1849 data << uint64(m_leaderGuid); // leader guid
1850
1851 if (GetMembersCount() - 1)
1852 {
1853 data << uint8(m_lootMethod); // loot method
1854 data << uint64(m_looterGuid); // looter guid
1855 data << uint8(m_lootThreshold); // loot threshold
1856 data << uint8(m_dungeonDifficulty); // Dungeon Difficulty
1857 data << uint8(m_raidDifficulty); // Raid Difficulty
1858 }*/
1859}
1860
1862{
1863 ObjectGuid guid = m_guid;
1864
1866 data.WriteGuidMask(guid, 4, 2, 5, 7, 1, 0, 3, 6);
1867
1868 data.WriteGuidBytes(guid, 6, 0, 3, 1, 5);
1869 data << uint8(0);
1870 data.WriteGuidBytes(guid, 7, 2, 4);
1871
1872 BroadcastPacket(&data, false);
1873}
1874
1876{
1877 if (!player || !player->IsInWorld())
1878 return;
1879
1880 WorldPacket data;
1881 player->GetSession()->BuildPartyMemberStatsChangedPacket(player, &data);
1882
1883 Player* member;
1884 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1885 {
1886 member = itr->GetSource();
1887 if (member && !member->IsWithinDist(player, member->GetSightRange(), false))
1888 member->GetSession()->SendPacket(&data);
1889 }
1890}
1891
1892void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group, uint64 ignore)
1893{
1894 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1895 {
1896 Player* player = itr->GetSource();
1897 if (!player || (ignore != 0 && player->GetGUID() == ignore) || (ignorePlayersInBGRaid && player->GetGroup() != this))
1898 continue;
1899
1900 if (WorldSession* session = player->GetSession())
1901 if (session && (group == -1 || itr->getSubGroup() == group))
1902 if (session->IsAddonRegistered(prefix))
1903 session->SendPacket(packet);
1904 }
1905}
1906
1907void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group, uint64 ignore)
1908{
1909 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1910 {
1911 Player* player = itr->GetSource();
1912 if (!player || (ignore != 0 && player->GetGUID() == ignore) || (ignorePlayersInBGRaid && player->GetGroup() != this))
1913 continue;
1914
1915 if (player->GetSession() && (group == -1 || itr->getSubGroup() == group))
1916 player->GetSession()->SendPacket(packet);
1917 }
1918}
1919
1921{
1922 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
1923 {
1924 Player* player = itr->GetSource();
1925 if (player && player->GetSession())
1926 if (IsLeader(player->GetGUID()) || IsAssistant(player->GetGUID()))
1927 player->GetSession()->SendPacket(packet);
1928 }
1929}
1930
1932{
1933 ObjectGuid groupGuid = GetGUID();
1934
1935 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
1936 {
1937 Player* player = ObjectAccessor::FindPlayer(citr->guid);
1938 if (!player || !player->GetSession())
1939 {
1940 ObjectGuid playerGuid = citr->guid;
1941
1942 WorldPacket data(SMSG_RAID_READY_CHECK_CONFIRM, 1 + 1 + 8 + 1 + 8);
1943 data.WriteBit(groupGuid[4]);
1944 data.WriteBit(playerGuid[5]);
1945 data.WriteBit(playerGuid[3]);
1946 data.WriteBit(0);
1947 data.WriteBit(groupGuid[2]);
1948 data.WriteBit(playerGuid[6]);
1949 data.WriteBit(groupGuid[3]);
1950 data.WriteBit(playerGuid[0]);
1951 data.WriteBit(playerGuid[1]);
1952 data.WriteBit(groupGuid[1]);
1953 data.WriteBit(groupGuid[5]);
1954 data.WriteBit(playerGuid[7]);
1955 data.WriteBit(playerGuid[4]);
1956 data.WriteBit(groupGuid[6]);
1957 data.WriteBit(playerGuid[2]);
1958 data.WriteBit(groupGuid[0]);
1959 data.WriteBit(groupGuid[7]);
1960 data.FlushBits();
1961
1962 data.WriteByteSeq(playerGuid[4]);
1963 data.WriteByteSeq(playerGuid[2]);
1964 data.WriteByteSeq(playerGuid[1]);
1965 data.WriteByteSeq(groupGuid[4]);
1966 data.WriteByteSeq(groupGuid[2]);
1967 data.WriteByteSeq(playerGuid[0]);
1968 data.WriteByteSeq(groupGuid[5]);
1969 data.WriteByteSeq(groupGuid[3]);
1970 data.WriteByteSeq(playerGuid[7]);
1971 data.WriteByteSeq(groupGuid[6]);
1972 data.WriteByteSeq(groupGuid[1]);
1973 data.WriteByteSeq(playerGuid[6]);
1974 data.WriteByteSeq(playerGuid[3]);
1975 data.WriteByteSeq(playerGuid[5]);
1976 data.WriteByteSeq(groupGuid[0]);
1977 data.WriteByteSeq(groupGuid[7]);
1978
1979 BroadcastPacket(&data, false);
1980
1981 ReadyCheckMemberHasResponded(playerGuid);
1982 }
1983 }
1984}
1985
1987{
1988 member_witerator slot = _getMemberWSlot(guid);
1989 if (slot == m_memberSlots.end())
1990 return false;
1991
1992 slot->group = group;
1993
1995
1996 if (!isBGGroup() && !isBFGroup())
1997 {
1999
2000 stmt->setUInt8(0, group);
2001 stmt->setUInt32(1, GUID_LOPART(guid));
2002
2003 CharacterDatabase.Execute(stmt);
2004 }
2005
2006 return true;
2007}
2008
2009bool Group::SameSubGroup(Player const* member1, Player const* member2) const
2010{
2011 if (!member1 || !member2)
2012 return false;
2013
2014 if (member1->GetGroup() != this || member2->GetGroup() != this)
2015 return false;
2016 else
2017 return member1->GetSubGroup() == member2->GetSubGroup();
2018}
2019
2020// Allows setting sub groups both for online or offline members
2022{
2023 // Only raid groups have sub groups
2024 if (!isRaidGroup())
2025 return;
2026
2027 // Check if player is really in the raid
2028 member_witerator slot = _getMemberWSlot(guid);
2029 if (slot == m_memberSlots.end())
2030 return;
2031
2032 // Abort if the player is already in the target sub group
2033 uint8 prevSubGroup = GetMemberGroup(guid);
2034 if (prevSubGroup == group)
2035 return;
2036
2037 // Update the player slot with the new sub group setting
2038 slot->group = group;
2039
2040 // Increase the counter of the new sub group..
2042
2043 // ..and decrease the counter of the previous one
2044 SubGroupCounterDecrease(prevSubGroup);
2045
2046 // Preserve new sub group in database for non-raid groups
2047 if (!isBGGroup() && !isBFGroup())
2048 {
2050
2051 stmt->setUInt8(0, group);
2052 stmt->setUInt32(1, GUID_LOPART(guid));
2053
2054 CharacterDatabase.Execute(stmt);
2055 }
2056
2057 // In case the moved player is online, update the player object with the new sub group references
2058 if (Player* player = ObjectAccessor::FindPlayer(guid))
2059 {
2060 if (player->GetGroup() == this)
2061 player->GetGroupRef().setSubGroup(group);
2062 else
2063 {
2064 // 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
2065 prevSubGroup = player->GetOriginalSubGroup();
2066 player->GetOriginalGroupRef().setSubGroup(group);
2067 }
2068 }
2069
2070 // Broadcast the changes to the group
2071 SendUpdate();
2072}
2073
2075{
2076 ChangeMembersGroup(player->GetGUID(), group);
2077}
2078
2079// Retrieve the next Round-Roubin player for the group
2080//
2081// No update done if loot method is Master or FFA.
2082//
2083// If the RR player is not yet set for the group, the first group member becomes the round-robin player.
2084// If the RR player is set, the next player in group becomes the round-robin player.
2085//
2086// If ifneed is true,
2087// the current RR player is checked to be near the looted object.
2088// if yes, no update done.
2089// if not, he loses his turn.
2090void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
2091{
2092 switch (GetLootMethod())
2093 {
2096 return;
2097 default:
2098 // round robin style looting applies for all low
2099 // quality items in each loot method except free for all and master loot
2100 break;
2101 }
2102
2103 uint64 oldLooterGUID = GetLooterGuid();
2104 member_citerator guid_itr = _getMemberCSlot(oldLooterGUID);
2105 if (guid_itr != m_memberSlots.end())
2106 {
2107 if (ifneed)
2108 {
2109 // not update if only update if need and ok
2110 Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid);
2111 if (looter && looter->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
2112 return;
2113 }
2114 ++guid_itr;
2115 }
2116
2117 // search next after current
2118 Player* pNewLooter = NULL;
2119 for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr)
2120 {
2121 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
2122 if (player->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
2123 {
2124 pNewLooter = player;
2125 break;
2126 }
2127 }
2128
2129 if (!pNewLooter)
2130 {
2131 // search from start
2132 for (member_citerator itr = m_memberSlots.begin(); itr != guid_itr; ++itr)
2133 {
2134 if (Player* player = ObjectAccessor::FindPlayer(itr->guid))
2135 if (player->IsWithinDistInMap(pLootedObject, sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_GROUP_XP_DISTANCE), false))
2136 {
2137 pNewLooter = player;
2138 break;
2139 }
2140 }
2141 }
2142
2143 if (pNewLooter)
2144 {
2145 if (oldLooterGUID != pNewLooter->GetGUID())
2146 {
2147 SetLooterGuid(pNewLooter->GetGUID());
2148 SendUpdate();
2149 }
2150 }
2151 else
2152 {
2153 SetLooterGuid(0);
2154 SendUpdate();
2155 }
2156}
2157
2158GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 /*MaxPlayerCount*/, bool isRated, uint32 arenaSlot)
2159{
2160 // check if this group is LFG group
2161 if (isLFGGroup())
2163
2164 BattlemasterListEntry const* bgEntry = sBattlemasterListStore.LookupEntry(uint32(bgOrTemplate->GetTypeID()));
2165 if (!bgEntry)
2167
2168 // check for min / max count
2169 uint32 memberscount = GetMembersCount();
2170
2171 if (memberscount > bgEntry->maxGroupSize) // no MinPlayerCount for battlegrounds
2172 return GroupJoinBattlegroundResult::ERR_BATTLEGROUND_NONE; // ERR_GROUP_JOIN_BATTLEGROUND_TOO_MANY handled on client side
2173
2174 // get a player as reference, to compare other players' stats to (arena team id, queue id based on level, etc.)
2175 Player* reference = GetFirstMember()->GetSource();
2176 // no reference found, can't join this way
2177 if (!reference)
2179
2180 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgOrTemplate->GetMapId(), reference->getLevel());
2181 if (!bracketEntry)
2183
2184 uint32 team = reference->GetTeam();
2185
2187
2188 // check every member of the group to be able to join
2189 memberscount = 0;
2190 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next(), ++memberscount)
2191 {
2192 Player* member = itr->GetSource();
2193 // offline member? don't let join
2194 if (!member)
2196 // don't allow cross-faction join as group
2197 if (member->GetTeam() != team)
2199 // not in the same battleground level braket, don't let join
2200 PvPDifficultyEntry const* memberBracketEntry = GetBattlegroundBracketByLevel(bracketEntry->mapId, member->getLevel());
2201 if (memberBracketEntry != bracketEntry)
2203 // don't let join if someone from the group is already in that bg queue
2204 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId))
2206 // don't let join if someone from the group is in bg queue random
2207 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom))
2209 // don't let join to bg queue random if someone from the group is already in bg queue
2210 if (bgOrTemplate->GetTypeID() == BattlegroundTypeId::BATTLEGROUND_RB && member->InBattlegroundQueue())
2212 // check for deserter debuff in case not arena queue
2213 if (bgOrTemplate->GetTypeID() != BattlegroundTypeId::BATTLEGROUND_AA && !member->CanJoinToBattleground(bgOrTemplate))
2215 // check if member can join any more battleground queues
2216 if (!member->HasFreeBattlegroundQueueId())
2218 // check if someone in party is using dungeon system
2219 if (member->isUsingLfg())
2221 }
2222
2223 // only check for MinPlayerCount since MinPlayerCount == MaxPlayerCount for arenas...
2224 if (bgOrTemplate->isArena() && memberscount != MinPlayerCount)
2226
2228}
2229
2230//===================================================
2231//============== Roll ===============================
2232//===================================================
2233
2235{
2236 // called from link()
2238}
2239
2241{
2242 m_dungeonDifficulty = difficulty;
2243 if (!isBGGroup() && !isBFGroup())
2244 {
2246
2248 stmt->setUInt32(1, m_dbStoreId);
2249
2250 CharacterDatabase.Execute(stmt);
2251 }
2252
2253 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
2254 {
2255 Player* player = itr->GetSource();
2256 if (!player->GetSession())
2257 continue;
2258
2259 player->SetDungeonDifficulty(difficulty);
2260 player->SendDungeonDifficulty();
2261 }
2262}
2263
2265{
2266 m_raidDifficulty = difficulty;
2267 if (!isBGGroup() && !isBFGroup())
2268 {
2270
2271 stmt->setUInt8(0, uint8(m_raidDifficulty));
2272 stmt->setUInt32(1, m_dbStoreId);
2273
2274 CharacterDatabase.Execute(stmt);
2275 }
2276
2277 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
2278 {
2279 Player* player = itr->GetSource();
2280 if (!player->GetSession())
2281 continue;
2282
2283 player->SetRaidDifficulty(difficulty);
2284 player->SendRaidDifficulty();
2285 }
2286}
2287
2289{
2290 for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
2291 {
2292 Player* player = itr->GetSource();
2293 if (player && !player->getAttackers().empty() && player->GetInstanceId() == instanceId && (player->GetMap()->IsRaidOrHeroicDungeon()))
2294 for (std::set<Unit*>::const_iterator i = player->getAttackers().begin(); i != player->getAttackers().end(); ++i)
2295 if ((*i) && (*i)->GetTypeId() == TypeID::TYPEID_UNIT && (*i)->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
2296 return true;
2297 }
2298 return false;
2299}
2300
2301void Group::ResetInstances(InstanceResetMethod method, bool isRaid, Player* SendMsgTo)
2302{
2303 if (isBGGroup() || isBFGroup())
2304 return;
2305
2306 // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_DISBAND
2307
2308 // we assume that when the difficulty changes, all instances that can be reset will be
2310 if (isRaid)
2311 {
2312 diff = GetRaidDifficulty();
2313 }
2314
2315 for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
2316 {
2317 InstanceSave* instanceSave = itr->second.save;
2318 const MapEntry* entry = sMapStore.LookupEntry(itr->first);
2319 if (!entry || entry->IsRaid() != isRaid || (!instanceSave->CanReset() && method != InstanceResetMethod::INSTANCE_RESET_GROUP_DISBAND))
2320 {
2321 ++itr;
2322 continue;
2323 }
2324
2326 {
2327 // the "reset all instances" method can only reset normal maps
2328 if (entry->map_type == MAP_RAID || diff == DIFFICULTY_HEROIC)
2329 {
2330 ++itr;
2331 continue;
2332 }
2333 }
2334
2335 bool isEmpty = true;
2336 // if the map is loaded, reset it
2337 Map* map = sMapMgr->FindMap(instanceSave->GetMapId(), instanceSave->GetInstanceId());
2338 if (map && map->IsInstance() && !(method == InstanceResetMethod::INSTANCE_RESET_GROUP_DISBAND && !instanceSave->CanReset()))
2339 {
2340 if (instanceSave->CanReset())
2341 isEmpty = ((InstanceMap*)map)->Reset(method);
2342 else
2343 isEmpty = !map->HavePlayers();
2344 }
2345
2346 if (SendMsgTo)
2347 {
2348 if (!isEmpty)
2349 SendMsgTo->SendResetInstanceFailed(2, instanceSave->GetMapId());
2351 {
2352 if (Group* group = SendMsgTo->GetGroup())
2353 {
2354 for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
2355 if (Player* player = itr->GetSource())
2356 player->SendResetInstanceSuccess(instanceSave->GetMapId());
2357 }
2358
2359 else
2360 SendMsgTo->SendResetInstanceSuccess(instanceSave->GetMapId());
2361 }
2362 else
2363 SendMsgTo->SendResetInstanceSuccess(instanceSave->GetMapId());
2364 }
2365
2367 {
2368 // do not reset the instance, just unbind if others are permanently bound to it
2369 if (instanceSave->CanReset())
2370 instanceSave->DeleteFromDB();
2371 else
2372 {
2374
2375 stmt->setUInt32(0, instanceSave->GetInstanceId());
2376
2377 CharacterDatabase.Execute(stmt);
2378 }
2379
2380
2381 // i don't know for sure if hash_map iterators
2382 m_boundInstances[diff].erase(itr);
2383 itr = m_boundInstances[diff].begin();
2384 // this unloads the instance save unless online players are bound to it
2385 // (eg. permanent binds or GM solo binds)
2386 instanceSave->RemoveGroup(this);
2387 }
2388 else
2389 ++itr;
2390 }
2391}
2392
2394{
2395 uint32 mapid = player->GetMapId();
2396 MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
2397 return GetBoundInstance(mapEntry);
2398}
2399
2404
2406{
2407 if (!mapEntry || !mapEntry->IsInstance())
2408 return NULL;
2409
2410 DifficultyID difficulty = GetDifficulty(mapEntry);
2411 return GetBoundInstance(difficulty, mapEntry->MapID);
2412}
2413
2415{
2416 // some instances only have one difficulty
2417 GetDownscaledMapDifficultyData(mapId, difficulty);
2418
2419 BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapId);
2420 if (itr != m_boundInstances[difficulty].end())
2421 return &itr->second;
2422 else
2423 return NULL;
2424}
2425
2426InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, bool load)
2427{
2428 if (!save || isBGGroup() || isBFGroup())
2429 return NULL;
2430
2431 InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
2432 if (!load && (!bind.save || permanent != bind.perm || save != bind.save))
2433 {
2434 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GROUP_INSTANCE);
2435
2436 stmt->setUInt32(0, m_dbStoreId);
2437 stmt->setUInt32(1, save->GetInstanceId());
2438 stmt->setBool(2, permanent);
2439
2440 CharacterDatabase.Execute(stmt);
2441 }
2442
2443 if (bind.save != save)
2444 {
2445 if (bind.save)
2446 bind.save->RemoveGroup(this);
2447 save->AddGroup(this);
2448 }
2449
2450 bind.save = save;
2451 bind.perm = permanent;
2452 if (!load)
2453 SF_LOG_DEBUG("maps", "Group::BindToInstance: Group (guid: %u, storage id: %u) is now bound to map %d, instance %d, difficulty %d",
2454 GUID_LOPART(GetGUID()), m_dbStoreId, save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
2455
2456 return &bind;
2457}
2458
2459void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload)
2460{
2461 BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid);
2462 if (itr != m_boundInstances[difficulty].end())
2463 {
2464 if (!unload)
2465 {
2467
2468 stmt->setUInt32(0, m_dbStoreId);
2469 stmt->setUInt32(1, itr->second.save->GetInstanceId());
2470
2471 CharacterDatabase.Execute(stmt);
2472 }
2473
2474 itr->second.save->RemoveGroup(this); // save can become invalid
2475 m_boundInstances[difficulty].erase(itr);
2476 }
2477}
2478
2480{
2481 if (player && !player->IsGameMaster() && sMapStore.LookupEntry(player->GetMapId())->IsInstance())
2482 player->m_InstanceValid = false;
2483}
2484
2486{
2487 // FG: HACK: force flags update on group leave - for values update hack
2488 // -- not very efficient but safe
2489 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
2490 {
2491 Player* pp = ObjectAccessor::FindPlayer(citr->guid);
2492 if (pp && pp->IsInWorld())
2493 {
2496 SF_LOG_DEBUG("misc", "-- Forced group value update for '%s'", pp->GetName().c_str());
2497 }
2498 }
2499}
2500
2502{
2504 Player* member = NULL;
2505 for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
2506 {
2507 member = ObjectAccessor::FindPlayer(citr->guid);
2508 if (member && m_maxEnchantingLevel < member->GetSkillValue(SKILL_ENCHANTING))
2510 }
2511}
2512
2514{
2515 m_lootMethod = method;
2516}
2517
2519{
2520 m_looterGuid = guid;
2521}
2522
2524{
2525 m_lootThreshold = threshold;
2526}
2527
2528void Group::SetLfgRoles(uint64 guid, const uint8 roles)
2529{
2530 member_witerator slot = _getMemberWSlot(guid);
2531 if (slot == m_memberSlots.end())
2532 return;
2533
2534 slot->roles = roles;
2535 SendUpdate();
2536}
2537
2538bool Group::IsFull() const
2539{
2540 return isRaidGroup() ? (m_memberSlots.size() >= MAXRAIDSIZE) : (m_memberSlots.size() >= MAXGROUPSIZE);
2541}
2542
2544{
2545 return m_groupType & GROUPTYPE_LFG;
2546}
2547
2549{
2550 return m_groupType & GROUPTYPE_RAID;
2551}
2552
2554{
2555 return m_bgGroup != NULL;
2556}
2557
2559{
2560 return m_bfGroup != NULL;
2561}
2562
2564{
2565 return GetMembersCount() > 0;
2566}
2567
2569{
2570 return m_leaderGuid;
2571}
2572
2574{
2575 return m_guid;
2576}
2577
2579{
2580 return GUID_LOPART(m_guid);
2581}
2582
2583char const* Group::GetLeaderName() const
2584{
2585 return m_leaderName.c_str();
2586}
2587
2589{
2590 return m_lootMethod;
2591}
2592
2594{
2595 return m_looterGuid;
2596}
2597
2602
2603bool Group::IsMember(uint64 guid) const
2604{
2605 return _getMemberCSlot(guid) != m_memberSlots.end();
2606}
2607
2608bool Group::IsLeader(uint64 guid) const
2609{
2610 return (GetLeaderGUID() == guid);
2611}
2612
2613uint64 Group::GetMemberGUID(const std::string& name)
2614{
2615 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2616 if (itr->name == name)
2617 return itr->guid;
2618 return 0;
2619}
2620
2622{
2623 member_citerator mslot = _getMemberCSlot(guid);
2624 if (mslot == m_memberSlots.end())
2625 return false;
2626 return mslot->flags & uint8(GroupMemberFlags::MEMBER_FLAG_ASSISTANT);
2627}
2628
2629bool Group::SameSubGroup(uint64 guid1, uint64 guid2) const
2630{
2631 member_citerator mslot2 = _getMemberCSlot(guid2);
2632 if (mslot2 == m_memberSlots.end())
2633 return false;
2634 return SameSubGroup(guid1, &*mslot2);
2635}
2636
2637bool Group::SameSubGroup(uint64 guid1, MemberSlot const* slot2) const
2638{
2639 member_citerator mslot1 = _getMemberCSlot(guid1);
2640 if (mslot1 == m_memberSlots.end() || !slot2)
2641 return false;
2642 return (mslot1->group == slot2->group);
2643}
2644
2646{
2647 return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE);
2648}
2649
2650
2652{
2653 member_citerator mslot = _getMemberCSlot(guid);
2654 if (mslot == m_memberSlots.end())
2655 return (MAX_RAID_SUBGROUPS + 1);
2656 return mslot->group;
2657}
2658
2660{
2661 m_bgGroup = bg;
2662}
2663
2665{
2666 m_bfGroup = bg;
2667}
2668
2670{
2671 // Assistants, main assistants and main tanks are only available in raid groups
2672 if (!isRaidGroup())
2673 return;
2674
2675 // Check if player is really in the raid
2676 member_witerator slot = _getMemberWSlot(guid);
2677 if (slot == m_memberSlots.end())
2678 return;
2679
2680 // Do flag specific actions, e.g ensure uniqueness
2681 switch (flag)
2682 {
2684 RemoveUniqueGroupMemberFlag(GroupMemberFlags::MEMBER_FLAG_MAINASSIST); // Remove main assist flag from current if any.
2685 break;
2687 RemoveUniqueGroupMemberFlag(GroupMemberFlags::MEMBER_FLAG_MAINTANK); // Remove main tank flag from current if any.
2688 break;
2690 break;
2691 default:
2692 return; // This should never happen
2693 }
2694
2695 // Switch the actual flag
2696 ToggleGroupMemberFlag(slot, flag, apply);
2697
2698 // Preserve the new setting in the db
2700
2701 stmt->setUInt8(0, slot->flags);
2702 stmt->setUInt32(1, GUID_LOPART(guid));
2703
2704 CharacterDatabase.Execute(stmt);
2705
2706 // Broadcast the changes to the group
2707 SendUpdate();
2708}
2709
2711{
2712 if (!mapEntry->IsRaid())
2713 return m_dungeonDifficulty;
2714
2715 return m_raidDifficulty;
2716}
2717/*
2718DifficultyID Group::GetDungeonDifficulty() const
2719{
2720 return m_dungeonDifficulty;
2721}
2722
2723DifficultyID Group::GetRaidDifficulty() const
2724{
2725 return m_raidDifficulty;
2726}
2727*/
2729{
2730 return !RollId.empty();
2731}
2732
2733Group::Rolls::iterator Group::GetRoll(uint64 Guid)
2734{
2735 Rolls::iterator iter;
2736 for (iter = RollId.begin(); iter != RollId.end(); ++iter)
2737 if ((*iter)->itemGUID == Guid && (*iter)->isValid())
2738 return iter;
2739 return RollId.end();
2740}
2741
2743{
2744 m_memberMgr.insertFirst(pRef);
2745}
2746
2748{
2749 GroupReference* ref = m_memberMgr.getFirst();
2750 while (ref)
2751 {
2752 GroupReference* nextRef = ref->next();
2753 if (ref->GetSource()->GetGUID() == guid)
2754 {
2755 ref->unlink();
2756 break;
2757 }
2758 ref = nextRef;
2759 }
2760}
2761
2763{
2764 return m_boundInstances[difficulty];
2765}
2766
2768{
2769 // Sub group counters initialization
2770 if (!m_subGroupsCounts)
2772
2773 memset((void*)m_subGroupsCounts, 0, (MAX_RAID_SUBGROUPS) * sizeof(uint8));
2774
2775 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2776 ++m_subGroupsCounts[itr->group];
2777}
2778
2780{
2781 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2782 if (itr->guid == Guid)
2783 return itr;
2784 return m_memberSlots.end();
2785}
2786
2788{
2789 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2790 if (itr->guid == Guid)
2791 return itr;
2792 return m_memberSlots.end();
2793}
2794
2796{
2798 ++m_subGroupsCounts[subgroup];
2799}
2800
2802{
2804 --m_subGroupsCounts[subgroup];
2805}
2806
2808{
2809 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2810 if (itr->flags & uint8(flag))
2811 itr->flags &= ~uint8(flag);
2812}
2813
2815{
2816 if (apply)
2817 slot->flags |= uint8(flag);
2818 else
2819 slot->flags &= ~uint8(flag);
2820}
2821
2823{
2825 if (itr == m_memberSlots.end())
2826 return;
2827
2828 itr->roles = role;
2829
2830 PreparedStatement* prepStatement = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_ROLE);
2831 prepStatement->setUInt8(0, role);
2832 prepStatement->setUInt32(1, GUID_LOPART(guid));
2833
2834 CharacterDatabase.Execute(prepStatement);
2835}
2836
2838{
2840 if (itr == m_memberSlots.end())
2841 return 0;
2842
2843 return itr->roles;
2844}
2845
2847{
2848 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2849 if (!itr->roles)
2850 return false;
2851
2852 return true;
2853}
2854
2856{
2858 if (itr == m_memberSlots.end())
2859 return;
2860
2861 itr->readyCheckHasResponded = true;
2862}
2863
2865{
2866 for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2867 itr->readyCheckHasResponded = false;
2868}
2869
2871{
2872 for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
2873 if (!itr->readyCheckHasResponded)
2874 return false;
2875
2876 return true;
2877}
@ CHAR_DEL_GROUP_INSTANCE_PERM_BINDING
@ CHAR_INS_GROUP_MEMBER
@ CHAR_DEL_GROUP_MEMBER_ALL
@ CHAR_DEL_GROUP
@ CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE
@ CHAR_INS_GROUP
@ CHAR_DEL_GROUP_INSTANCE_BY_GUID
@ CHAR_UPD_GROUP_DIFFICULTY
@ CHAR_UPD_GROUP_TYPE
@ CHAR_UPD_GROUP_RAID_DIFFICULTY
@ CHAR_UPD_GROUP_MEMBER_FLAG
@ CHAR_REP_GROUP_INSTANCE
@ CHAR_UPD_GROUP_LEADER
@ CHAR_UPD_GROUP_MEMBER_SUBGROUP
@ CHAR_DEL_GROUP_MEMBER
@ CHAR_UPD_GROUP_ROLE
@ CHAR_DEL_LFG_DATA
@ CREATURE_FLAG_EXTRA_INSTANCE_BIND
Definition Creature.h:29
@ MAP_RAID
Definition DBCEnums.h:395
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition DBCEnums.h:194
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT
Definition DBCEnums.h:216
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT
Definition DBCEnums.h:215
DifficultyID
Definition DBCEnums.h:330
@ DIFFICULTY_NORMAL
Definition DBCEnums.h:332
@ DIFFICULTY_HEROIC
Definition DBCEnums.h:333
@ DIFFICULTY_10MAN_NORMAL
Definition DBCEnums.h:334
DBCStorage< BattlemasterListEntry > sBattlemasterListStore(BattlemasterListEntryfmt)
PvPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
MapDifficulty const * GetDownscaledMapDifficultyData(uint32 mapId, DifficultyID &difficulty)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
#define TARGETICONCOUNT
Definition Group.h:32
@ MEMBER_STATUS_OFFLINE
Definition Group.h:36
@ MEMBER_STATUS_PVP
Definition Group.h:38
@ MEMBER_STATUS_ONLINE
Definition Group.h:37
GroupType
Definition Group.h:61
@ GROUPTYPE_NORMAL
Definition Group.h:62
@ GROUPTYPE_RAID
Definition Group.h:64
@ GROUPTYPE_UNK1
Definition Group.h:66
@ GROUPTYPE_LFG
Definition Group.h:67
@ GROUPTYPE_EVERYONE_IS_ASSISTANT
Definition Group.h:68
@ GROUPTYPE_BGRAID
Definition Group.h:65
#define MAXGROUPSIZE
Definition Group.h:29
GroupMemberFlags
Definition Group.h:48
@ MEMBER_FLAG_MAINASSIST
Definition Group.h:51
@ MEMBER_FLAG_ASSISTANT
Definition Group.h:49
@ MEMBER_FLAG_MAINTANK
Definition Group.h:50
@ GROUP_UPDATE_FULL
Definition Group.h:105
#define MAXRAIDSIZE
Definition Group.h:30
#define MAX_RAID_SUBGROUPS
Definition Group.h:31
#define sGroupMgr
Definition GroupMgr.h:44
InventoryResult
Definition Item.h:27
@ EQUIP_ERR_OK
Definition Item.h:28
@ ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED
#define sLFGMgr
Definition LFGMgr.h:518
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
LootStore LootTemplates_Disenchant("disenchant_loot_template", "item disenchant id", true)
RollMask
Definition LootMgr.h:31
@ ROLL_ALL_TYPE_NO_DISENCHANT
Definition LootMgr.h:37
@ ROLL_FLAG_TYPE_DISENCHANT
Definition LootMgr.h:35
@ ROLL_FLAG_TYPE_NEED
Definition LootMgr.h:33
RollType
Definition LootMgr.h:21
@ ROLL_NEED
Definition LootMgr.h:23
@ ROLL_GREED
Definition LootMgr.h:24
@ MAX_ROLL_TYPE
Definition LootMgr.h:26
@ ROLL_PASS
Definition LootMgr.h:22
@ ROLL_DISENCHANT
Definition LootMgr.h:25
@ ROLL_INVALID
Definition LootMgr.h:27
LootMethod
Definition LootMgr.h:47
@ GROUP_LOOT
Definition LootMgr.h:51
@ FREE_FOR_ALL
Definition LootMgr.h:48
@ MASTER_LOOT
Definition LootMgr.h:50
@ NEED_BEFORE_GREED
Definition LootMgr.h:52
InstanceResetMethod
Definition Map.h:627
@ INSTANCE_RESET_GROUP_DISBAND
Definition Map.h:631
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition Map.h:629
@ INSTANCE_RESET_GROUP_JOIN
Definition Map.h:632
@ LEVELREQUIREMENT_HEROIC
Definition Map.h:226
#define sMapMgr
Definition MapManager.h:145
@ TYPEID_UNIT
Definition Object.h:54
uint32 GUID_LOPART(uint64 x)
@ HIGHGUID_PLAYER
@ HIGHGUID_GROUP
@ HIGHGUID_ITEM
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
#define sObjectMgr
Definition ObjectMgr.h:1617
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:777
#define sScriptMgr
Definition ScriptMgr.h:764
GroupJoinBattlegroundResult
BattlegroundQueueTypeId
RemoveMethod
@ GROUP_REMOVEMETHOD_KICK_LFG
@ GROUP_REMOVEMETHOD_KICK
ItemQualities
@ ITEM_QUALITY_UNCOMMON
@ ALLIANCE
@ HORDE
@ SKILL_ENCHANTING
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ NULL_BAG
Definition Unit.h:336
@ NULL_SLOT
Definition Unit.h:337
@ UF_FLAG_PARTY_MEMBER
@ UNIT_FIELD_SHAPESHIFT_FORM
@ UNIT_FIELD_FACTION_TEMPLATE
uint32 GetMapId() const
BattlegroundTypeId GetTypeID(bool GetRandom=false) const
bool isArena() const
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
void append(T value)
Definition ByteBuffer.h:147
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
Definition Field.h:16
uint32 GetUInt32() const
Definition Field.h:105
void BroadcastGroupUpdate(void)
Definition Group.cpp:2485
uint32 m_counter
Definition Group.h:340
void NeedBeforeGreed(Loot *loot, WorldObject *pLootedObject)
Definition Group.cpp:1137
bool isLFGGroup() const
Definition Group.cpp:2543
void EndRoll(Loot *loot)
Definition Group.cpp:1378
void ReadyCheckMemberHasResponded(uint64 guid)
Definition Group.cpp:2855
Battlefield * m_bfGroup
Definition Group.h:331
bool AddLeaderInvite(Player *player)
Definition Group.cpp:305
void SetBattlefieldGroup(Battlefield *bf)
Definition Group.cpp:2664
void SendLootAllPassed(Roll const &roll)
Definition Group.cpp:885
InvitesList m_invitees
Definition Group.h:324
uint64 m_targetIcons[TARGETICONCOUNT]
Definition Group.h:332
void SendTargetIconList(WorldSession *session)
Definition Group.cpp:1566
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid, uint8 Index)
Definition Group.cpp:1525
uint32 m_maxEnchantingLevel
Definition Group.h:341
void DelinkMember(uint64 guid)
Definition Group.cpp:2747
bool IsCreated() const
Definition Group.cpp:2563
void SubGroupCounterDecrease(uint8 subgroup)
Definition Group.cpp:2801
void SetLootMethod(LootMethod method)
Definition Group.cpp:2513
DifficultyID m_dungeonDifficulty
Definition Group.h:328
void ChangeFlagEveryoneAssistant(bool apply)
Definition Group.cpp:202
void RemoveAllInvites()
Definition Group.cpp:324
std::string m_leaderName
Definition Group.h:326
void _initRaidSubGroupsCounter()
Definition Group.cpp:2767
void LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
Definition Group.cpp:177
bool isRollLootActive() const
Definition Group.cpp:2728
member_citerator _getMemberCSlot(uint64 Guid) const
Definition Group.cpp:2779
void SetLootThreshold(ItemQualities threshold)
Definition Group.cpp:2523
void GroupLoot(Loot *loot, WorldObject *pLootedObject)
Definition Group.cpp:985
void Disband(bool hideDestroy=false)
Definition Group.cpp:700
uint64 m_looterGuid
Definition Group.h:335
InstanceGroupBind * BindToInstance(InstanceSave *save, bool permanent, bool load=false)
Definition Group.cpp:2426
uint64 m_leaderGuid
Definition Group.h:325
void LoadGroupFromDB(Field *field)
Definition Group.cpp:149
bool AddMember(Player *player)
Definition Group.cpp:353
Battleground * m_bgGroup
Definition Group.h:330
void SetGroupMemberFlag(uint64 guid, bool apply, GroupMemberFlags flag)
Definition Group.cpp:2669
Rolls::iterator GetRoll(uint64 Guid)
Definition Group.cpp:2733
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const *bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
Definition Group.cpp:2158
void SendUpdate()
Definition Group.cpp:1594
GroupRefManager m_memberMgr
Definition Group.h:323
void BroadcastPacket(WorldPacket *packet, bool ignorePlayersInBGRaid, int group=-1, uint64 ignore=0)
Definition Group.cpp:1907
Rolls RollId
Definition Group.h:336
member_witerator _getMemberWSlot(uint64 Guid)
Definition Group.cpp:2787
void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r)
Definition Group.cpp:790
void RemoveInvite(Player *player)
Definition Group.cpp:315
void SetDungeonDifficulty(DifficultyID difficulty)
Definition Group.cpp:2240
uint64 m_guid
Definition Group.h:339
bool isBGGroup() const
Definition Group.cpp:2553
void ConvertToRaid()
Definition Group.cpp:229
ItemQualities GetLootThreshold() const
Definition Group.cpp:2598
MemberSlotList m_memberSlots
Definition Group.h:322
uint32 GetMembersCount() const
Definition Group.h:227
Group()
Definition Group.cpp:43
void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, RollType RollType, const Roll &r)
Definition Group.cpp:838
uint64 GetGUID() const
Definition Group.cpp:2573
void ResetMaxEnchantingLevel()
Definition Group.cpp:2501
void _homebindIfInstance(Player *player)
Definition Group.cpp:2479
DifficultyID m_raidDifficulty
Definition Group.h:329
void BroadcastAddonMessagePacket(WorldPacket *packet, const std::string &prefix, bool ignorePlayersInBGRaid, int group=-1, uint64 ignore=0)
Definition Group.cpp:1892
uint32 m_dbStoreId
Definition Group.h:342
BoundInstancesMap m_boundInstances[15]
Definition Group.h:337
uint8 GetMemberGroup(uint64 guid) const
Definition Group.cpp:2651
void ToggleGroupMemberFlag(member_witerator slot, GroupMemberFlags flag, bool apply)
Definition Group.cpp:2814
void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player *p, bool canNeed, Roll const &r)
Definition Group.cpp:815
void SetLooterGuid(uint64 guid)
Definition Group.cpp:2518
bool ReadyCheckAllResponded() const
Definition Group.cpp:2870
const char * GetLeaderName() const
Definition Group.cpp:2583
void SetLfgRoles(uint64 guid, const uint8 roles)
Definition Group.cpp:2528
void BroadcastReadyCheck(WorldPacket *packet)
Definition Group.cpp:1920
void ConvertToLFG()
Definition Group.cpp:212
void SetRaidDifficulty(DifficultyID difficulty)
Definition Group.cpp:2264
MemberSlotList::iterator member_witerator
Definition Group.h:164
bool _readyCheckInProgress
Definition Group.h:343
void SetBattlegroundGroup(Battleground *bg)
Definition Group.cpp:2659
void UpdatePlayerOutOfRange(Player *player)
Definition Group.cpp:1875
LootMethod GetLootMethod() const
Definition Group.cpp:2588
void UpdateLooterGuid(WorldObject *pLootedObject, bool ifneed=false)
Definition Group.cpp:2090
bool IsMember(uint64 guid) const
Definition Group.cpp:2603
Player * GetInvited(uint64 guid) const
Definition Group.cpp:333
bool HasFreeSlotSubGroup(uint8 subgroup) const
Definition Group.cpp:2645
void CountTheRoll(Rolls::iterator roll)
Definition Group.cpp:1392
UNORDERED_MAP< uint32, InstanceGroupBind > BoundInstancesMap
Definition Group.h:162
bool isBFGroup() const
Definition Group.cpp:2558
bool RemoveMember(uint64 guid, const RemoveMethod &method=GROUP_REMOVEMETHOD_DEFAULT, uint64 kicker=0, const char *reason=NULL)
Definition Group.cpp:501
GroupReference * GetFirstMember()
Definition Group.h:225
LootMethod m_lootMethod
Definition Group.h:333
uint32 GetLowGUID() const
Definition Group.cpp:2578
void SetMemberRole(uint64 guid, uint32 role)
Definition Group.cpp:2822
uint64 GetMemberGUID(const std::string &name)
Definition Group.cpp:2613
DifficultyID GetRaidDifficulty() const
Definition Group.h:252
bool AddInvite(Player *player)
Definition Group.cpp:284
void ConvertToGroup()
Definition Group.cpp:253
uint8 * m_subGroupsCounts
Definition Group.h:338
void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, RollType RollType, const Roll &r)
Definition Group.cpp:862
void CountRollVote(uint64 playerGUID, uint64 Guid, RollType Choise)
Definition Group.cpp:1333
uint32 GetMemberRole(uint64 guid) const
Definition Group.cpp:2837
BoundInstancesMap & GetBoundInstances(DifficultyID difficulty)
Definition Group.cpp:2762
MemberSlotList::const_iterator member_citerator
Definition Group.h:160
bool RoleCheckAllResponded() const
Definition Group.cpp:2846
bool _setMembersGroup(uint64 guid, uint8 group)
Definition Group.cpp:1986
DifficultyID GetDifficulty(MapEntry const *mapEntry) const
Definition Group.cpp:2710
void SubGroupCounterIncrease(uint8 subgroup)
Definition Group.cpp:2795
bool Create(Player *leader)
Definition Group.cpp:81
void ReadyCheckResetResponded()
Definition Group.cpp:2864
bool IsFull() const
Definition Group.cpp:2538
bool SameSubGroup(uint64 guid1, uint64 guid2) const
Definition Group.cpp:2629
void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload=false)
Definition Group.cpp:2459
InstanceGroupBind * GetBoundInstance(Player *player)
Definition Group.cpp:2393
bool IsAssistant(uint64 guid) const
Definition Group.cpp:2621
uint64 GetLeaderGUID() const
Definition Group.cpp:2568
~Group()
Definition Group.cpp:52
bool IsLeader(uint64 guid) const
Definition Group.cpp:2608
void SendReadyCheckCompleted()
Definition Group.cpp:1861
uint64 GetLooterGuid() const
Definition Group.cpp:2593
void LinkMember(GroupReference *pRef)
Definition Group.cpp:2742
ItemQualities m_lootThreshold
Definition Group.h:334
bool isRaidGroup() const
Definition Group.cpp:2548
DifficultyID GetDungeonDifficulty() const
Definition Group.h:251
GroupType m_groupType
Definition Group.h:327
void ResetInstances(InstanceResetMethod method, bool isRaid, Player *SendMsgTo)
Definition Group.cpp:2301
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
Definition Group.cpp:2807
bool InCombatToInstance(uint32 instanceId)
Definition Group.cpp:2288
void MasterLoot(Loot *loot, WorldObject *pLootedObject)
Definition Group.cpp:1281
void SendUpdateToPlayer(uint64 playerGUID, MemberSlot *slot=NULL)
Definition Group.cpp:1600
void ChangeMembersGroup(uint64 guid, uint8 group)
Definition Group.cpp:2021
void OfflineReadyCheck()
Definition Group.cpp:1931
void ChangeLeader(uint64 guid)
Definition Group.cpp:628
void SendLooter(Creature *creature, Player *pLooter)
Definition Group.cpp:906
GroupReference * next()
DifficultyID GetDifficulty() const
bool RemoveGroup(Group *group)
uint32 GetInstanceId() const
uint32 GetMapId() const
void AddGroup(Group *group)
bool CanReset() const
Definition Map.h:238
bool HavePlayers() const
Definition Map.h:397
MapEntry const * GetEntry() const
Definition Map.h:244
bool IsRaidOrHeroicDungeon() const
Definition Map.h:373
bool IsInstance() const
Definition Map.h:368
static Player * FindPlayerInOrOutOfWorld(uint64)
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
bool IsInWorld() const
Definition Object.h:114
uint32 GetGUIDLow() const
Definition Object.h:120
void RemoveFieldNotifyFlag(uint16 flag)
Definition Object.h:199
GameObject * ToGameObject()
Definition Object.h:213
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition Object.cpp:270
Creature * ToCreature()
Definition Object.h:207
void SetFieldNotifyFlag(uint16 flag)
Definition Object.h:198
void ForceValuesUpdateAtIndex(uint32)
Definition Object.cpp:2328
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=NULL, uint32 itemid=0)
static DifficultyID CheckLoadedRaidDifficultyID(DifficultyID difficulty)
Definition Player.cpp:20782
uint32 GetTeam() const
Definition Player.h:2527
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition Player.cpp:20654
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition Player.cpp:19249
void SendRaidDifficulty(int32 forcedDifficulty=-1)
Definition Player.cpp:15496
bool m_InstanceValid
Definition Player.h:2922
void SetOriginalGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:20141
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2993
bool isUsingLfg()
Definition Player.cpp:20097
InventoryResult CanRollForItemInLFG(ItemTemplate const *item, WorldObject const *lootedObject) const
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:6563
void SetDungeonDifficulty(DifficultyID dungeon_difficulty)
Definition Player.h:2317
void SendDirectMessage(WorldPacket *data)
Definition Player.cpp:6904
void SendDungeonDifficulty()
Definition Player.cpp:15489
void SetGroup(Group *group, int8 subgroup=-1)
Definition Player.cpp:18506
bool HaveAtClient(WorldObject const *u) const
Definition Player.cpp:18066
void SetGroupInvite(Group *group)
Definition Player.h:2968
bool HasFreeBattlegroundQueueId()
Definition Player.cpp:19274
void RemoveFromBattlegroundOrBattlefieldRaid()
Definition Player.cpp:20129
void UpdateForQuestWorldObjects()
Definition Player.cpp:19410
WorldSession * GetSession() const
Definition Player.h:2417
DifficultyID GetRaidDifficulty() const
Definition Player.h:2316
bool InBattlegroundQueue() const
Definition Player.cpp:19220
Group * GetGroup()
Definition Player.h:2972
bool IsGameMaster() const
Definition Player.h:1369
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, Unit *unit=NULL)
Definition Player.cpp:21033
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=NULL) const
static void ConvertInstancesToGroup(Player *player, Group *group, bool switchLeader)
convert the player's binds to the group
Definition Player.cpp:14099
bool CanJoinToBattleground(Battleground const *bg) const
Definition Player.cpp:18008
void SendResetInstanceSuccess(uint32 MapId)
Definition Player.cpp:15560
void ResetInstances(InstanceResetMethod method, bool isRaid)
Reset all solo instances and optionally send a message on success for each.
Definition Player.cpp:15510
void SetRaidDifficulty(DifficultyID raid_difficulty)
Definition Player.h:2318
bool GetPassOnGroupLoot() const
Definition Player.h:3033
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, AllowedLooterSet const &allowedLooters=AllowedLooterSet())
uint8 GetSubGroup() const
Definition Player.h:2985
void SendResetInstanceFailed(uint32 reason, uint32 MapId)
Definition Player.cpp:15567
DifficultyID GetDungeonDifficulty() const
Definition Player.h:2315
Group * GetGroupInvite()
Definition Player.h:2964
static DifficultyID CheckLoadedDungeonDifficultyID(DifficultyID difficulty)
Definition Player.cpp:20770
Group * GetOriginalGroup()
Definition Player.h:3015
void SetBattlegroundOrBattlefieldRaid(Group *group, int8 subgroup=-1)
Definition Player.cpp:20119
void setBool(const uint8 index, const bool value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
void unlink()
Definition Reference.h:48
void link(Loot *toObj, LootValidatorRef *fromObj)
Definition Reference.h:33
bool isValid() const
Definition Reference.h:65
FROM * GetSource() const
Definition Reference.h:83
Definition Group.h:112
void targetObjectBuildLink()
Definition Group.cpp:2234
void setLoot(Loot *pLoot)
Definition Group.cpp:33
uint64 itemGUID
Definition Group.h:120
int32 itemRandomPropId
Definition Group.h:122
uint8 totalGreed
Definition Group.h:129
uint8 totalPlayersRolling
Definition Group.h:127
uint8 itemSlot
Definition Group.h:131
uint32 itemid
Definition Group.h:121
uint8 itemCount
Definition Group.h:124
~Roll()
Definition Group.cpp:31
uint8 rollVoteMask
Definition Group.h:132
Roll(uint64 _guid, LootItem const &li)
Definition Group.cpp:26
uint32 itemRandomSuffix
Definition Group.h:123
uint8 totalNeed
Definition Group.h:128
uint8 totalPass
Definition Group.h:130
Loot * getLoot()
Definition Group.cpp:38
PlayerVote playerVote
Definition Group.h:126
bool IsAlive() const
Definition Unit.h:2032
AttackerSet const & getAttackers() const
Definition Unit.h:1463
uint8 getLevel() const
Definition Unit.h:1528
bool HasData() const
Definition UpdateData.h:50
bool BuildPacket(WorldPacket *packet)
uint32 GetMapId() const
Definition Object.h:546
Map * GetMap() const
Definition Object.h:740
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1735
uint32 GetInstanceId() const
Definition Object.h:638
std::string const & GetName() const
Definition Object.h:664
float GetSightRange(WorldObject const *target=NULL) const
Definition Object.cpp:2078
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1730
void Initialize(Opcodes opcode, size_t newres=200)
Definition WorldPacket.h:31
Player session in the World.
void SendLfgClearStatus(uint64 lfgGroupGuid=0, uint8 queueIdOverride=0, bool groupLeave=false)
void BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_RAID_READY_CHECK_COMPLETED
Definition Opcodes.h:921
@ SMSG_GROUP_LIST
Definition Opcodes.h:674
@ SMSG_LOOT_MASTER_LIST
Definition Opcodes.h:769
@ SMSG_LOOT_START_ROLL
Definition Opcodes.h:776
@ SMSG_RAID_READY_CHECK_CONFIRM
Definition Opcodes.h:922
@ SMSG_GROUP_UNINVITE
Definition Opcodes.h:678
@ SMSG_LOOT_ALL_PASSED
Definition Opcodes.h:766
@ SMSG_LOOT_LIST
Definition Opcodes.h:768
@ SMSG_GROUP_DESTROYED
Definition Opcodes.h:672
@ SMSG_RAID_TARGET_UPDATE_SINGLE
Definition Opcodes.h:924
@ SMSG_RAID_TARGET_UPDATE_ALL
Definition Opcodes.h:923
@ SMSG_GROUP_SET_LEADER
Definition Opcodes.h:676
@ SMSG_LOOT_ROLL
Definition Opcodes.h:774
@ SMSG_LOOT_ROLL_WON
Definition Opcodes.h:775
#define sWorld
Definition World.h:910
@ CONFIG_INSTANCES_RESET_ANNOUNCE
Definition World.h:165
@ CONFIG_GROUP_XP_DISTANCE
Definition World.h:178
uint32 maxGroupSize
std::string name
Definition Group.h:153
InstanceSave * save
Definition Group.h:137
uint32 DisenchantID
uint32 RequiredDisenchantSkill
uint8 unlootedCount
Definition LootMgr.h:285
void NotifyItemRemoved(uint8 lootIndex, ObjectGuid lootGuid=0)
Definition LootMgr.cpp:599
std::vector< LootItem > items
Definition LootMgr.h:282
void addLootValidatorRef(LootValidatorRef *pLootValidatorRef)
Definition LootMgr.h:302
std::vector< LootItem > quest_items
Definition LootMgr.h:283
bool is_blocked
Definition LootMgr.h:127
int32 randomPropertyId
Definition LootMgr.h:122
uint8 count
Definition LootMgr.h:125
bool is_looted
Definition LootMgr.h:126
const AllowedLooterSet & GetAllowedLooters() const
Definition LootMgr.h:145
bool IsInstance() const
uint32 MapID
bool IsRaid() const
uint32 map_type
uint32 mapId