void Group::_setLeader(ObjectGuid guid) { member_citerator slot = _getMemberCSlot(guid); if (slot == m_memberSlots.end()) return; if (!isBGGroup()) { uint32 slot_lowguid = slot->guid.GetCounter(); uint32 leader_lowguid = m_leaderGuid.GetCounter(); // TODO: set a time limit to have this function run rarely cause it can be slow CharacterDatabase.BeginTransaction(); // update the group's bound instances when changing leaders // remove all permanent binds from the group // in the DB also remove solo binds that will be replaced with permbinds // from the new leader CharacterDatabase.PExecute( "DELETE FROM group_instance WHERE leaderguid='%u' AND (permanent = 1 OR " "instance IN (SELECT instance FROM character_instance WHERE guid = '%u')" ")", leader_lowguid, slot_lowguid); Player* player = sObjectMgr.GetPlayer(slot->guid); if (player) { for (BoundInstancesMap::iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end();) { if (itr->second.perm) { itr->second.state->RemoveGroup(this); m_boundInstances.erase(itr++); } else ++itr; } } // update the group's solo binds to the new leader CharacterDatabase.PExecute("UPDATE group_instance SET leaderGuid='%u' WHERE leaderGuid = '%u'", slot_lowguid, leader_lowguid); // copy the permanent binds from the new leader to the group // overwriting the solo binds with permanent ones if necessary // in the DB those have been deleted already Player::ConvertInstancesToGroup(player, this, slot->guid); // update the group leader CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE groupId='%u'", slot_lowguid, m_Id); CharacterDatabase.CommitTransaction(); } _updateLeaderFlag(true); m_leaderGuid = slot->guid; m_leaderName = slot->name; _updateLeaderFlag(); }
bool Group::AddLeaderInvite(Player* player) { if (!AddInvite(player)) return false; _updateLeaderFlag(true); m_leaderGuid = player->GetObjectGuid(); m_leaderName = player->GetName(); _updateLeaderFlag(); return true; }
bool Group::Create(ObjectGuid guid, const char* name) { m_leaderGuid = guid; m_leaderName = name; m_groupType = isBGGroup() ? GROUPTYPE_BGRAID : GROUPTYPE_NORMAL; if (m_groupType & GROUPTYPE_RAID) _initRaidSubGroupsCounter(); m_lootMethod = GROUP_LOOT; m_lootThreshold = ITEM_QUALITY_UNCOMMON; m_masterLooterGuid = guid; m_currentLooterGuid = guid; // used for round robin looter m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL; m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; if (!isBGGroup()) { m_Id = sObjectMgr.GenerateGroupLowGuid(); Player* leader = sObjectMgr.GetPlayer(guid); if (leader) { m_dungeonDifficulty = leader->GetDungeonDifficulty(); m_raidDifficulty = leader->GetRaidDifficulty(); } Player::ConvertInstancesToGroup(leader, this, guid); // store group in database CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM groups WHERE groupId ='%u'", m_Id); CharacterDatabase.PExecute("DELETE FROM group_member WHERE groupId ='%u'", m_Id); CharacterDatabase.PExecute("INSERT INTO groups (groupId,leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,groupType,difficulty,raiddifficulty) " "VALUES ('%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')", m_Id, m_leaderGuid.GetCounter(), m_mainTankGuid.GetCounter(), m_mainAssistantGuid.GetCounter(), uint32(m_lootMethod), m_masterLooterGuid.GetCounter(), uint32(m_lootThreshold), m_targetIcons[0].GetRawValue(), m_targetIcons[1].GetRawValue(), m_targetIcons[2].GetRawValue(), m_targetIcons[3].GetRawValue(), m_targetIcons[4].GetRawValue(), m_targetIcons[5].GetRawValue(), m_targetIcons[6].GetRawValue(), m_targetIcons[7].GetRawValue(), uint8(m_groupType), uint32(m_dungeonDifficulty), uint32(m_raidDifficulty)); } if (!AddMember(guid, name)) return false; if (!isBGGroup()) CharacterDatabase.CommitTransaction(); _updateLeaderFlag(); return true; }
bool Group::_removeMember(ObjectGuid guid) { Player* player = sObjectMgr.GetPlayer(guid); if (player) { // if we are removing player from battleground raid if (isBGGroup()) player->RemoveFromBattleGroundRaid(); else { // we can remove player who is in battleground from his original group if (player->GetOriginalGroup() == this) player->SetOriginalGroup(nullptr); else player->SetGroup(nullptr); } } member_witerator slot = _getMemberWSlot(guid); if (slot != m_memberSlots.end()) { SubGroupCounterDecrease(slot->group); m_memberSlots.erase(slot); } if (!isBGGroup()) CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid='%u'", guid.GetCounter()); if (m_leaderGuid == guid) // leader was removed { _updateLeaderFlag(true); if (GetMembersCount() > 0) _setLeader(m_memberSlots.front().guid); return true; } return false; }
void Group::Disband(bool hideDestroy) { Player* player; for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { player = sObjectMgr.GetPlayer(citr->guid); if (!player) continue; // we cannot call _removeMember because it would invalidate member iterator // if we are removing player from battleground raid if (isBGGroup()) player->RemoveFromBattleGroundRaid(); else { // we can remove player who is in battleground from his original group if (player->GetOriginalGroup() == this) player->SetOriginalGroup(nullptr); else player->SetGroup(nullptr); } // quest related GO state dependent from raid membership if (isRaidGroup()) player->UpdateForQuestWorldObjects(); if (!player->GetSession()) continue; WorldPacket data; if (!hideDestroy) { data.Initialize(SMSG_GROUP_DESTROYED, 0); player->GetSession()->SendPacket(&data); } // we already removed player from group and in player->GetGroup() is his original group, send update if (Group* group = player->GetGroup()) { group->SendUpdate(); } else { data.Initialize(SMSG_GROUP_LIST, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 8); data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0); data << uint64(0) << uint32(0) << uint32(0) << uint64(0); player->GetSession()->SendPacket(&data); } _homebindIfInstance(player); } m_memberSlots.clear(); RemoveAllInvites(); if (!isBGGroup()) { CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM groups WHERE groupId='%u'", m_Id); CharacterDatabase.PExecute("DELETE FROM group_member WHERE groupId='%u'", m_Id); CharacterDatabase.CommitTransaction(); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, nullptr); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, nullptr); } _updateLeaderFlag(true); m_leaderGuid.Clear(); m_leaderName.clear(); }