Core/Instances: Fixed a bug that caused switching group leader inside active instance to cause players not being saved when a boss was killed.

Closes #5109
This commit is contained in:
Shauren
2013-06-11 15:50:08 +02:00
parent 935a1cf607
commit ef15fe8ed2
3 changed files with 27 additions and 23 deletions
+3 -1
View File
@@ -18698,7 +18698,9 @@ void Player::ConvertInstancesToGroup(Player* player, Group* group, bool switchLe
{
for (BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();)
{
group->BindToInstance(itr->second.save, itr->second.perm, false);
if (!switchLeader || !group->GetBoundInstance(itr->second.save->GetDifficulty(), itr->first))
group->BindToInstance(itr->second.save, itr->second.perm, false);
// permanent binds are not removed
if (switchLeader && !itr->second.perm)
{
+23 -21
View File
@@ -615,30 +615,39 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod& method /*= GROUP_REMOV
}
}
void Group::ChangeLeader(uint64 guid)
void Group::ChangeLeader(uint64 newLeaderGuid)
{
member_witerator slot = _getMemberWSlot(guid);
member_witerator slot = _getMemberWSlot(newLeaderGuid);
if (slot == m_memberSlots.end())
return;
Player* player = ObjectAccessor::FindPlayer(slot->guid);
Player* newLeader = ObjectAccessor::FindPlayer(slot->guid);
// Don't allow switching leader to offline players
if (!player)
if (!newLeader)
return;
sScriptMgr->OnGroupChangeLeader(this, guid, m_leaderGuid);
sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid);
if (!isBGGroup() && !isBFGroup())
{
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Remove the groups permanent instance bindings
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
{
for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();)
{
if (itr->second.perm)
// Do not unbind saves of instances that already had map created (a newLeader entered)
// forcing a new instance with another leader requires group disbanding (confirmed on retail)
if (itr->second.perm && !sMapMgr->FindMap(itr->first, itr->second.save->GetInstanceId()))
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING);
stmt->setUInt32(0, m_dbStoreId);
stmt->setUInt32(1, itr->second.save->GetInstanceId());
trans->Append(stmt);
itr->second.save->RemoveGroup(this);
m_boundInstances[i].erase(itr++);
}
@@ -647,29 +656,22 @@ void Group::ChangeLeader(uint64 guid)
}
}
// Same in the database
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING);
stmt->setUInt32(0, m_dbStoreId);
stmt->setUInt32(1, player->GetGUIDLow());
CharacterDatabase.Execute(stmt);
// Copy the permanent binds from the new leader to the group
Player::ConvertInstancesToGroup(player, this, true);
Player::ConvertInstancesToGroup(newLeader, this, true);
// Update the group leader
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEADER);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEADER);
stmt->setUInt32(0, player->GetGUIDLow());
stmt->setUInt32(0, newLeader->GetGUIDLow());
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
}
m_leaderGuid = player->GetGUID();
m_leaderName = player->GetName();
m_leaderGuid = newLeader->GetGUID();
m_leaderName = newLeader->GetName();
ToggleGroupMemberFlag(slot, MEMBER_FLAG_ASSISTANT, false);
WorldPacket data(SMSG_GROUP_SET_LEADER, m_leaderName.size()+1);
@@ -378,7 +378,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_GROUP_MEMBER, "INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND (permanent = 1 OR instance IN (SELECT instance FROM character_instance WHERE guid = ?))", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_LEADER, "UPDATE groups SET leaderGuid = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_TYPE, "UPDATE groups SET groupType = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_MEMBER_SUBGROUP, "UPDATE group_member SET subgroup = ? WHERE memberGuid = ?", CONNECTION_ASYNC);