Merge pull request #16156 from Treeston/3.3.5-instancerevive2
Game/Maps: Instance handling bug-fix follow-up (cherry picked from commit ae4fcc3685079e1c24cd46545dae169d5be12046)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user