diff options
author | Shauren <shauren.trinity@gmail.com> | 2013-06-11 15:50:08 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2013-06-11 15:50:08 +0200 |
commit | ef15fe8ed28cb2d65574e8c5c755d39f8a06a994 (patch) | |
tree | b0e130efeabd77cd3799132c07a067413fe70b04 | |
parent | 935a1cf607782916fdb8e3a77489738a3d07b66f (diff) |
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
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Groups/Group.cpp | 44 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 2 |
3 files changed, 27 insertions, 23 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 28213785911..a7d37dd870f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -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) { diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index c21cc9210dc..59da04f3673 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -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); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 446f89aef4f..427ccfd5ebf 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -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); |