diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2016-01-04 16:21:01 +0100 | 
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-03-21 22:41:02 +0100 | 
| commit | 8225fb09c2ff0c84f52ea6b31586cfd41ba1d858 (patch) | |
| tree | 903c6eca3f6b0d8cc735dd06bcef33b53a0c6c72 | |
| parent | e6ab6b4b0b8c74aac5c784d02afd7e193f8fe81b (diff) | |
Merge pull request #16156 from Treeston/3.3.5-instancerevive2
Game/Maps: Instance handling bug-fix follow-up
(cherry picked from commit ae4fcc3685079e1c24cd46545dae169d5be12046)
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 25 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
| -rw-r--r-- | src/server/game/Groups/Group.cpp | 45 | ||||
| -rw-r--r-- | src/server/game/Groups/Group.h | 1 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Maps/MapInstanced.cpp | 4 | 
6 files changed, 45 insertions, 33 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f30b4ac5c44..247de0befe6 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -18314,31 +18314,6 @@ void Player::SendRaidInfo()      GetSession()->SendPacket(instanceInfo.Write());  } -/// convert the player's binds to the group -void Player::ConvertInstancesToGroup(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 (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; -        } -    } -} -  bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report)  {      if (!IsGameMaster() && ar) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 0679fc9167f..a381c2dd351 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2353,7 +2353,6 @@ class Player : public Unit, public GridObject<Player>          void SetPendingBind(uint32 instanceId, uint32 bindTimer);          bool HasPendingBind() const { return _pendingBindId > 0; }          void SendRaidInfo(); -        static void ConvertInstancesToGroup(Player* player, Group* group, bool switchLeader);          bool Satisfy(AccessRequirement const* ar, uint32 target_map, bool report = false);          bool CheckInstanceValidity(bool /*isLogin*/);          bool CheckInstanceCount(uint32 instanceId) const; 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); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 3dbed19fc98..d1beee19ac3 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3145,7 +3145,7 @@ bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)              {                  if (group)                  { -                    // solo saves should be reset when entering a group +                    // solo saves should have been reset when the map was loaded                      InstanceGroupBind* groupBind = group->GetBoundInstance(this);                      if (playerBind && playerBind->save != mapSave)                      { diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 4c065f836b9..e277746290a 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -164,7 +164,11 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player, u              {                  groupBind = group->GetBoundInstance(this);                  if (groupBind) +                { +                    // solo saves should be reset when entering a group's instance +                    player->UnbindInstance(GetId(), player->GetDifficultyID(GetEntry()));                      pSave = groupBind->save; +                }              }          }          if (pSave)  | 
