aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Groups
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Groups')
-rw-r--r--src/server/game/Groups/Group.cpp45
-rw-r--r--src/server/game/Groups/Group.h1
2 files changed, 40 insertions, 6 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 5f8813c2071..e3528d053f5 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -157,10 +157,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;
@@ -410,9 +409,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
{
@@ -693,7 +690,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid, int8 partyIndex)
}
// 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);
@@ -720,6 +717,42 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid, int8 partyIndex)
BroadcastPacket(groupNewLeader.Write(), 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->GetDifficultyID(), 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);
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index fab6edd5603..ba11dcff200 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -226,6 +226,7 @@ class Group
bool AddMember(Player* player);
bool RemoveMember(ObjectGuid guid, const RemoveMethod &method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, const char* reason = NULL);
void ChangeLeader(ObjectGuid guid, int8 partyIndex = 0);
+ static void ConvertLeaderInstancesToGroup(Player* player, Group* group, bool switchLeader);
void SetLootMethod(LootMethod method);
void SetLooterGuid(ObjectGuid guid);
void SetMasterLooterGuid(ObjectGuid guid);