aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Groups/Group.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Groups/Group.cpp')
-rw-r--r--src/server/game/Groups/Group.cpp45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index d0e70eb3dbb..8ebc71b0146 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -148,10 +148,9 @@ bool Group::Create(Player* leader)
CharacterDatabase.Execute(stmt);
+ Group::ConvertLeaderInstancesToGroup(leader, this, false);
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;
@@ -375,9 +374,7 @@ bool Group::AddMember(Player* player)
player->SetGroup(this, subGroup);
// if the same group invites the player back, cancel the homebind timer
- InstanceGroupBind* bind = GetBoundInstance(player);
- if (bind && bind->save->GetInstanceId() == player->GetInstanceId())
- player->m_InstanceValid = true;
+ player->m_InstanceValid = player->CheckInstanceValidity(false);
if (!isRaidGroup()) // reset targetIcons for non-raid-groups
{
@@ -654,7 +651,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid)
}
// Copy the permanent binds from the new leader to the group
- Player::ConvertInstancesToGroup(newLeader, this, true);
+ Group::ConvertLeaderInstancesToGroup(newLeader, this, true);
// Update the group leader
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEADER);
@@ -680,6 +677,42 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid)
BroadcastPacket(&data, true);
}
+/// convert the player's binds to the group
+void Group::ConvertLeaderInstancesToGroup(Player* player, Group* group, bool switchLeader)
+{
+ // copy all binds to the group, when changing leader it's assumed the character
+ // will not have any solo binds
+ for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ for (Player::BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();)
+ {
+ 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)
+ {
+ // increments itr in call
+ player->UnbindInstance(itr, Difficulty(i), false);
+ }
+ else
+ ++itr;
+ }
+ }
+
+ /* if group leader is in a non-raid dungeon map and nobody is actually bound to this map then the group can "take over" the instance *
+ * (example: two-player group disbanded by disconnect where the player reconnects within 60 seconds and the group is reformed) */
+ if (Map* playerMap = player->GetMap())
+ if (!switchLeader && playerMap->IsNonRaidDungeon())
+ if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(playerMap->GetInstanceId()))
+ if (save->GetGroupCount() == 0 && save->GetPlayerCount() == 0)
+ {
+ TC_LOG_DEBUG("maps", "Group::ConvertLeaderInstancesToGroup: Group for player %s is taking over unbound instance map %d with Id %d", player->GetName().c_str(), playerMap->GetId(), playerMap->GetInstanceId());
+ // if nobody is saved to this, then the save wasn't permanent
+ group->BindToInstance(save, false, false);
+ }
+}
+
void Group::Disband(bool hideDestroy /* = false */)
{
sScriptMgr->OnGroupDisband(this);