Core/Groups: Reimplement group id recycling
This commit is contained in:
@@ -57,7 +57,7 @@ Loot* Roll::getLoot()
|
||||
Group::Group() : m_leaderGuid(0), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL),
|
||||
m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL),
|
||||
m_bgGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(0),
|
||||
m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0)
|
||||
m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0), m_storageId(0)
|
||||
{
|
||||
for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
|
||||
m_targetIcons[i] = 0;
|
||||
@@ -96,6 +96,7 @@ bool Group::Create(Player *leader)
|
||||
{
|
||||
uint64 leaderGuid = leader->GetGUID();
|
||||
uint32 lowguid = sObjectMgr->GenerateLowGuid(HIGHGUID_GROUP);
|
||||
|
||||
m_guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_GROUP);
|
||||
m_leaderGuid = leaderGuid;
|
||||
m_leaderName = leader->GetName();
|
||||
@@ -117,17 +118,20 @@ bool Group::Create(Player *leader)
|
||||
m_dungeonDifficulty = leader->GetDungeonDifficulty();
|
||||
m_raidDifficulty = leader->GetRaidDifficulty();
|
||||
|
||||
m_storageId = sObjectMgr->GenerateNewGroupStorageId();
|
||||
|
||||
sObjectMgr->RegisterGroupStorageId(m_storageId, this);
|
||||
|
||||
// store group in database
|
||||
CharacterDatabase.PExecute("INSERT INTO groups (guid,leaderGuid,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,groupType,difficulty,raiddifficulty) "
|
||||
"VALUES ('%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')",
|
||||
lowguid, GUID_LOPART(m_leaderGuid), uint32(m_lootMethod),
|
||||
m_storageId, GUID_LOPART(m_leaderGuid), uint32(m_lootMethod),
|
||||
GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6],
|
||||
m_targetIcons[7], uint8(m_groupType), uint32(m_dungeonDifficulty), m_raidDifficulty);
|
||||
|
||||
ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
|
||||
|
||||
Player::ConvertInstancesToGroup(leader, this, false);
|
||||
|
||||
}
|
||||
else if (!AddMember(leader))
|
||||
return false;
|
||||
@@ -135,18 +139,15 @@ bool Group::Create(Player *leader)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Group::LoadGroupFromDB(const uint32 &groupGuid, QueryResult result, bool loadMembers)
|
||||
void Group::LoadGroupFromDB(Field *fields)
|
||||
{
|
||||
if (isBGGroup())
|
||||
return false;
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
m_guid = MAKE_NEW_GUID(groupGuid, 0, HIGHGUID_GROUP);
|
||||
m_storageId = fields[15].GetUInt32();
|
||||
m_guid = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_GROUP), 0, HIGHGUID_GROUP);
|
||||
m_leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
|
||||
// group leader not exist
|
||||
if (!sObjectMgr->GetPlayerNameByGUID(fields[0].GetUInt32(), m_leaderName))
|
||||
return false;
|
||||
return;
|
||||
|
||||
m_lootMethod = LootMethod(fields[1].GetUInt8());
|
||||
m_looterGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
@@ -171,27 +172,9 @@ bool Group::LoadGroupFromDB(const uint32 &groupGuid, QueryResult result, bool lo
|
||||
else
|
||||
m_raidDifficulty = Difficulty(r_diff);
|
||||
|
||||
if (loadMembers)
|
||||
{
|
||||
// 0 1 2 3
|
||||
result = CharacterDatabase.PQuery("SELECT memberGuid, memberFlags, subgroup, roles FROM group_member WHERE guid=%u", groupGuid);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
LoadMemberFromDB(fields[0].GetUInt32(), fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt8());
|
||||
} while (result->NextRow());
|
||||
|
||||
if (GetMembersCount() < 2) // group too small
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
|
||||
void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
|
||||
{
|
||||
MemberSlot member;
|
||||
member.guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
|
||||
@@ -200,7 +183,7 @@ bool Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup,
|
||||
if (!sObjectMgr->GetPlayerNameByGUID(member.guid, member.name))
|
||||
{
|
||||
CharacterDatabase.PQuery("DELETE FROM group_member WHERE memberGuid=%u", guidLow);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
member.group = subgroup;
|
||||
@@ -210,8 +193,6 @@ bool Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup,
|
||||
m_memberSlots.push_back(member);
|
||||
|
||||
SubGroupCounterIncrease(subgroup);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Group::ConvertToLFG()
|
||||
@@ -219,7 +200,7 @@ void Group::ConvertToLFG()
|
||||
m_groupType = GroupType(m_groupType | GROUPTYPE_LFG | GROUPTYPE_UNK1);
|
||||
m_lootMethod = NEED_BEFORE_GREED;
|
||||
if (!isBGGroup())
|
||||
CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), GUID_LOPART(m_guid));
|
||||
CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_storageId);
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
@@ -230,7 +211,7 @@ void Group::ConvertToRaid()
|
||||
_initRaidSubGroupsCounter();
|
||||
|
||||
if (!isBGGroup())
|
||||
CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), GUID_LOPART(m_guid));
|
||||
CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_storageId);
|
||||
SendUpdate();
|
||||
|
||||
// update quest related GO states (quest activity dependent from raid membership)
|
||||
@@ -363,7 +344,7 @@ bool Group::AddMember(Player *player)
|
||||
// insert into the table if we're not a battleground group
|
||||
if (!isBGGroup())
|
||||
CharacterDatabase.PExecute("INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(%u, %u, %u, %u, %u)",
|
||||
GUID_LOPART(m_guid), GUID_LOPART(member.guid), member.flags, member.group, member.roles);
|
||||
m_storageId, GUID_LOPART(member.guid), member.flags, member.group, member.roles);
|
||||
|
||||
SendUpdate();
|
||||
sScriptMgr->OnGroupAddMember(this, player->GetGUID());
|
||||
@@ -550,13 +531,13 @@ void Group::ChangeLeader(const uint64 &guid)
|
||||
|
||||
// Same in the database
|
||||
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND (permanent = 1 OR instance IN (SELECT instance FROM character_instance WHERE guid = '%u'))",
|
||||
GUID_LOPART(m_guid), player->GetGUIDLow());
|
||||
m_storageId, player->GetGUIDLow());
|
||||
|
||||
// Copy the permanent binds from the new leader to the group
|
||||
Player::ConvertInstancesToGroup(player, this, true);
|
||||
|
||||
// update the group leader
|
||||
CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", player->GetGUIDLow(), GUID_LOPART(m_guid));
|
||||
CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", player->GetGUIDLow(), m_storageId);
|
||||
}
|
||||
|
||||
m_leaderGuid = player->GetGUID();
|
||||
@@ -628,19 +609,14 @@ void Group::Disband(bool hideDestroy /* = false */)
|
||||
|
||||
if (!isBGGroup())
|
||||
{
|
||||
uint32 lowguid = GUID_LOPART(m_guid);
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
trans->PAppend("DELETE FROM groups WHERE guid=%u", lowguid);
|
||||
trans->PAppend("DELETE FROM group_member WHERE guid=%u", lowguid);
|
||||
trans->PAppend("DELETE FROM groups WHERE guid = %u", m_storageId);
|
||||
trans->PAppend("DELETE FROM group_member WHERE guid = %u", m_storageId);
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
|
||||
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
|
||||
|
||||
// If the deleted group guid is lower than the one we have stored for the next group creation,
|
||||
// use this one instead.
|
||||
if (lowguid < sObjectMgr->GetNextGroupGuid())
|
||||
sObjectMgr->SetNextGroupGuid(lowguid);
|
||||
|
||||
sObjectMgr->FreeGroupStorageId(this);
|
||||
}
|
||||
|
||||
sObjectMgr->RemoveGroup(this);
|
||||
@@ -1584,7 +1560,7 @@ void Group::SetDungeonDifficulty(Difficulty difficulty)
|
||||
{
|
||||
m_dungeonDifficulty = difficulty;
|
||||
if (!isBGGroup())
|
||||
CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE guid ='%u'", m_dungeonDifficulty, GUID_LOPART(m_guid));
|
||||
CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE guid ='%u'", m_dungeonDifficulty, m_storageId);
|
||||
|
||||
for (GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
@@ -1601,7 +1577,7 @@ void Group::SetRaidDifficulty(Difficulty difficulty)
|
||||
{
|
||||
m_raidDifficulty = difficulty;
|
||||
if (!isBGGroup())
|
||||
CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE guid ='%u'", m_raidDifficulty, GUID_LOPART(m_guid));
|
||||
CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE guid ='%u'", m_raidDifficulty, m_storageId);
|
||||
|
||||
for (GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
@@ -1743,7 +1719,7 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, boo
|
||||
|
||||
InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
|
||||
if (!load && (!bind.save || permanent != bind.perm || save != bind.save))
|
||||
CharacterDatabase.PExecute("REPLACE INTO group_instance (guid, instance, permanent) VALUES (%u, %u, %u)", GUID_LOPART(GetGUID()), save->GetInstanceId(), permanent);
|
||||
CharacterDatabase.PExecute("REPLACE INTO group_instance (guid, instance, permanent) VALUES (%u, %u, %u)", m_storageId, save->GetInstanceId(), permanent);
|
||||
|
||||
if (bind.save != save)
|
||||
{
|
||||
@@ -1755,7 +1731,9 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, boo
|
||||
bind.save = save;
|
||||
bind.perm = permanent;
|
||||
if (!load)
|
||||
sLog->outDebug(LOG_FILTER_MAPS, "Group::BindToInstance: %d is now bound to map %d, instance %d, difficulty %d", GUID_LOPART(GetGUID()), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
|
||||
sLog->outDebug(LOG_FILTER_MAPS, "Group::BindToInstance: Group (guid: %u, storage id: %u) is now bound to map %d, instance %d, difficulty %d",
|
||||
GUID_LOPART(GetGUID()), m_storageId, save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
|
||||
|
||||
return &bind;
|
||||
}
|
||||
|
||||
@@ -1765,7 +1743,7 @@ void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload)
|
||||
if (itr != m_boundInstances[difficulty].end())
|
||||
{
|
||||
if (!unload)
|
||||
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND instance=%u", GUID_LOPART(GetGUID()), itr->second.save->GetInstanceId());
|
||||
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND instance=%u", m_storageId, itr->second.save->GetInstanceId());
|
||||
itr->second.save->RemoveGroup(this); // save can become invalid
|
||||
m_boundInstances[difficulty].erase(itr);
|
||||
}
|
||||
|
||||
@@ -183,8 +183,8 @@ class Group
|
||||
|
||||
// group manipulation methods
|
||||
bool Create(Player *leader);
|
||||
bool LoadGroupFromDB(const uint32 &guid, QueryResult result, bool loadMembers = true);
|
||||
bool LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles);
|
||||
void LoadGroupFromDB(Field *field);
|
||||
void LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles);
|
||||
bool AddInvite(Player *player);
|
||||
void RemoveInvite(Player *player);
|
||||
void RemoveAllInvites();
|
||||
@@ -213,6 +213,8 @@ class Group
|
||||
const uint64& GetLooterGuid() const;
|
||||
ItemQualities GetLootThreshold() const;
|
||||
|
||||
uint32 GetStorageId() { return m_storageId; };
|
||||
|
||||
// member manipulation methods
|
||||
bool IsMember(const uint64& guid) const;
|
||||
bool IsLeader(const uint64& guid) const;
|
||||
@@ -328,5 +330,6 @@ class Group
|
||||
uint64 m_guid;
|
||||
uint32 m_counter; // used only in SMSG_GROUP_LIST
|
||||
uint32 m_maxEnchantingLevel;
|
||||
uint32 m_storageId; // Represents the ID used in database (Can be reused by other groups if group was disbanded)
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user