mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-19 22:49:39 -04:00
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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user