Core/Maps: Check group that owns instance (first group to enter a given instance id owns it)
Port From (https://github.com/TrinityCore/TrinityCore/commit/a131542855d23022714a97640be1c8d68a741c31)
This commit is contained in:
@@ -166,7 +166,9 @@ namespace Game.Groups
|
||||
|
||||
DB.Characters.Execute(stmt);
|
||||
|
||||
ConvertLeaderInstancesToGroup(leader, this, false);
|
||||
InstanceMap leaderInstance = leader.GetMap().ToInstanceMap();
|
||||
if (leaderInstance != null)
|
||||
leaderInstance.TrySetOwningGroup(this);
|
||||
|
||||
Cypher.Assert(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
|
||||
}
|
||||
@@ -691,9 +693,6 @@ namespace Game.Groups
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the permanent binds from the new leader to the group
|
||||
ConvertLeaderInstancesToGroup(newLeader, this, true);
|
||||
|
||||
// Update the group leader
|
||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_GROUP_LEADER);
|
||||
|
||||
@@ -721,47 +720,6 @@ namespace Game.Groups
|
||||
BroadcastPacket(groupNewLeader, true);
|
||||
}
|
||||
|
||||
public static void 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
|
||||
foreach (var difficultyDic in player.m_boundInstances.Values)
|
||||
{
|
||||
foreach (var pair in difficultyDic)
|
||||
{
|
||||
if (!switchLeader || group.GetBoundInstance(pair.Value.save.GetDifficultyID(), pair.Key) == null)
|
||||
if (pair.Value.extendState != 0) // not expired
|
||||
group.BindToInstance(pair.Value.save, pair.Value.perm, false);
|
||||
|
||||
// permanent binds are not removed
|
||||
if (switchLeader && !pair.Value.perm)
|
||||
{
|
||||
player.UnbindInstance(pair, difficultyDic, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
Map playerMap = player.GetMap();
|
||||
if (playerMap)
|
||||
{
|
||||
if (!switchLeader && playerMap.IsNonRaidDungeon())
|
||||
{
|
||||
InstanceSave save = Global.InstanceSaveMgr.GetInstanceSave(playerMap.GetInstanceId());
|
||||
if (save != null)
|
||||
{
|
||||
if (save.GetGroupCount() == 0 && save.GetPlayerCount() == 0)
|
||||
{
|
||||
Log.outDebug(LogFilter.Maps, "Group.ConvertLeaderInstancesToGroup: Group for player {0} is taking over unbound instance map {1} with Id {2}", player.GetName(), playerMap.GetId(), playerMap.GetInstanceId());
|
||||
// if nobody is saved to this, then the save wasn't permanent
|
||||
group.BindToInstance(save, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Disband(bool hideDestroy = false)
|
||||
{
|
||||
Global.ScriptMgr.OnGroupDisband(this);
|
||||
@@ -1585,45 +1543,9 @@ namespace Game.Groups
|
||||
return null;
|
||||
}
|
||||
|
||||
public InstanceBind BindToInstance(InstanceSave save, bool permanent, bool load = false)
|
||||
public void LinkOwnedInstance(GroupInstanceReference refe)
|
||||
{
|
||||
if (save == null || IsBGGroup() || IsBFGroup())
|
||||
return null;
|
||||
|
||||
if (!m_boundInstances.ContainsKey(save.GetDifficultyID()))
|
||||
m_boundInstances[save.GetDifficultyID()] = new Dictionary<uint, InstanceBind>();
|
||||
|
||||
if (!m_boundInstances[save.GetDifficultyID()].ContainsKey(save.GetMapId()))
|
||||
m_boundInstances[save.GetDifficultyID()][save.GetMapId()] = new InstanceBind();
|
||||
|
||||
InstanceBind bind = m_boundInstances[save.GetDifficultyID()][save.GetMapId()];
|
||||
if (!load && (bind.save == null || permanent != bind.perm || save != bind.save))
|
||||
{
|
||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.REP_GROUP_INSTANCE);
|
||||
|
||||
stmt.AddValue(0, m_dbStoreId);
|
||||
stmt.AddValue(1, save.GetInstanceId());
|
||||
stmt.AddValue(2, permanent);
|
||||
|
||||
DB.Characters.Execute(stmt);
|
||||
}
|
||||
|
||||
if (bind.save != save)
|
||||
{
|
||||
if (bind.save != null)
|
||||
bind.save.RemoveGroup(this);
|
||||
save.AddGroup(this);
|
||||
}
|
||||
|
||||
bind.save = save;
|
||||
bind.perm = permanent;
|
||||
if (!load)
|
||||
Log.outDebug(LogFilter.Maps, "Group.BindToInstance: Group ({0}, storage id: {1}) is now bound to map {2}, instance {3}, difficulty {4}",
|
||||
GetGUID().ToString(), m_dbStoreId, save.GetMapId(), save.GetInstanceId(), save.GetDifficultyID());
|
||||
|
||||
m_boundInstances[save.GetDifficultyID()][save.GetMapId()] = bind;
|
||||
|
||||
return bind;
|
||||
m_ownedInstancesMgr.InsertLast(refe);
|
||||
}
|
||||
|
||||
public void UnbindInstance(uint mapid, Difficulty difficulty, bool unload = false)
|
||||
@@ -2199,6 +2121,7 @@ namespace Game.Groups
|
||||
ObjectGuid m_masterLooterGuid;
|
||||
Dictionary<Difficulty, Dictionary<uint, InstanceBind>> m_boundInstances = new();
|
||||
Dictionary<uint, Tuple<ObjectGuid, uint>> m_recentInstances = new();
|
||||
GroupInstanceRefManager m_ownedInstancesMgr = new();
|
||||
byte[] m_subGroupsCounts;
|
||||
ObjectGuid m_guid;
|
||||
uint m_dbStoreId;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Framework.Dynamic;
|
||||
using Game.Maps;
|
||||
|
||||
namespace Game.Groups
|
||||
{
|
||||
public class GroupInstanceReference : Reference<Group, InstanceMap>
|
||||
{
|
||||
~GroupInstanceReference() { Unlink(); }
|
||||
|
||||
public new GroupInstanceReference Next() { return (GroupInstanceReference)base.Next(); }
|
||||
|
||||
public override void TargetObjectBuildLink()
|
||||
{
|
||||
GetTarget().LinkOwnedInstance(this);
|
||||
}
|
||||
}
|
||||
|
||||
class GroupInstanceRefManager : RefManager<Group, InstanceMap>
|
||||
{
|
||||
public new GroupInstanceReference GetFirst() { return (GroupInstanceReference)base.GetFirst(); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user