Core/Instances: Reimplement resetting instances from UI
Port From (https://github.com/TrinityCore/TrinityCore/commit/ddd0c7b152d65b980db0cc2d00f15ae62a602936)
This commit is contained in:
@@ -92,12 +92,16 @@ namespace Framework.Constants
|
|||||||
|
|
||||||
public enum InstanceResetMethod
|
public enum InstanceResetMethod
|
||||||
{
|
{
|
||||||
All,
|
Manual,
|
||||||
ChangeDifficulty,
|
OnChangeDifficulty,
|
||||||
Global,
|
Expire,
|
||||||
GroupDisband,
|
}
|
||||||
GroupJoin,
|
|
||||||
RespawnDelay
|
public enum InstanceResetResult
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
NotEmpty,
|
||||||
|
CannotReset
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@@ -188,6 +192,7 @@ namespace Framework.Constants
|
|||||||
CannotEnterTooManyInstances, // Player Has Entered Too Many Instances Recently
|
CannotEnterTooManyInstances, // Player Has Entered Too Many Instances Recently
|
||||||
CannotEnterMaxPlayers, // Target Map Already Has The Maximum Number Of Players Allowed
|
CannotEnterMaxPlayers, // Target Map Already Has The Maximum Number Of Players Allowed
|
||||||
CannotEnterZoneInCombat, // A Boss Encounter Is Currently In Progress On The Target Map
|
CannotEnterZoneInCombat, // A Boss Encounter Is Currently In Progress On The Target Map
|
||||||
|
CannotEnterInstanceShuttingDown,
|
||||||
CannotEnterUnspecifiedReason
|
CannotEnterUnspecifiedReason
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2892,6 +2892,11 @@ namespace Game.Entities
|
|||||||
// flight will started later
|
// flight will started later
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mapEntry.IsDungeon() && instanceId != 0)
|
||||||
|
{
|
||||||
|
// try finding instance by id first
|
||||||
|
map = Global.MapMgr.FindMap(mapId, instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
// Map could be changed before
|
// Map could be changed before
|
||||||
mapEntry = CliDB.MapStorage.LookupByKey(mapId);
|
mapEntry = CliDB.MapStorage.LookupByKey(mapId);
|
||||||
@@ -2940,6 +2945,9 @@ namespace Game.Entities
|
|||||||
case EnterState.CannotEnterZoneInCombat:
|
case EnterState.CannotEnterZoneInCombat:
|
||||||
SendTransferAborted(map.GetId(), TransferAbortReason.ZoneInCombat);
|
SendTransferAborted(map.GetId(), TransferAbortReason.ZoneInCombat);
|
||||||
break;
|
break;
|
||||||
|
case EnterState.CannotEnterInstanceShuttingDown:
|
||||||
|
SendTransferAborted(map.GetId(), TransferAbortReason.NotFound);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
using Framework.Database;
|
|
||||||
using Game.DataStorage;
|
using Game.DataStorage;
|
||||||
using Game.Groups;
|
using Game.Groups;
|
||||||
using Game.Guilds;
|
using Game.Guilds;
|
||||||
@@ -24,7 +23,7 @@ using Game.Maps;
|
|||||||
using Game.Networking.Packets;
|
using Game.Networking.Packets;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Framework.Dynamic;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
{
|
{
|
||||||
@@ -498,9 +497,40 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset all solo instances and optionally send a message on success for each
|
// Reset all solo instances and optionally send a message on success for each
|
||||||
public void ResetInstances(InstanceResetMethod method, bool isRaid, bool isLegacy)
|
public void ResetInstances(InstanceResetMethod method)
|
||||||
{
|
{
|
||||||
|
foreach (var (mapId, instanceId) in m_recentInstances.ToList())
|
||||||
|
{
|
||||||
|
Map map = Global.MapMgr.FindMap(mapId, instanceId);
|
||||||
|
bool forgetInstance = false;
|
||||||
|
if (map)
|
||||||
|
{
|
||||||
|
InstanceMap instance = map.ToInstanceMap();
|
||||||
|
if (instance != null)
|
||||||
|
{
|
||||||
|
switch (instance.Reset(method))
|
||||||
|
{
|
||||||
|
case InstanceResetResult.Success:
|
||||||
|
SendResetInstanceSuccess(map.GetId());
|
||||||
|
forgetInstance = true;
|
||||||
|
break;
|
||||||
|
case InstanceResetResult.NotEmpty:
|
||||||
|
if (method == InstanceResetMethod.Manual)
|
||||||
|
SendResetInstanceFailed(ResetFailedReason.Failed, map.GetId());
|
||||||
|
else if (method == InstanceResetMethod.OnChangeDifficulty)
|
||||||
|
forgetInstance = true;
|
||||||
|
break;
|
||||||
|
case InstanceResetResult.CannotReset:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forgetInstance)
|
||||||
|
m_recentInstances.Remove(mapId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendResetInstanceSuccess(uint MapId)
|
public void SendResetInstanceSuccess(uint MapId)
|
||||||
|
|||||||
+26
-15
@@ -463,12 +463,6 @@ namespace Game.Groups
|
|||||||
|
|
||||||
if (!IsLeader(player.GetGUID()) && !IsBGGroup() && !IsBFGroup())
|
if (!IsLeader(player.GetGUID()) && !IsBGGroup() && !IsBFGroup())
|
||||||
{
|
{
|
||||||
// reset the new member's instances, unless he is currently in one of them
|
|
||||||
// including raid/heroic instances that they are not permanently bound to!
|
|
||||||
player.ResetInstances(InstanceResetMethod.GroupJoin, false, false);
|
|
||||||
player.ResetInstances(InstanceResetMethod.GroupJoin, true, false);
|
|
||||||
player.ResetInstances(InstanceResetMethod.GroupJoin, true, true);
|
|
||||||
|
|
||||||
if (player.GetDungeonDifficultyID() != GetDungeonDifficultyID())
|
if (player.GetDungeonDifficultyID() != GetDungeonDifficultyID())
|
||||||
{
|
{
|
||||||
player.SetDungeonDifficultyID(GetDungeonDifficultyID());
|
player.SetDungeonDifficultyID(GetDungeonDifficultyID());
|
||||||
@@ -754,15 +748,11 @@ namespace Game.Groups
|
|||||||
stmt.AddValue(0, m_dbStoreId);
|
stmt.AddValue(0, m_dbStoreId);
|
||||||
trans.Append(stmt);
|
trans.Append(stmt);
|
||||||
|
|
||||||
DB.Characters.CommitTransaction(trans);
|
|
||||||
|
|
||||||
ResetInstances(InstanceResetMethod.GroupDisband, false, false, null);
|
|
||||||
ResetInstances(InstanceResetMethod.GroupDisband, true, false, null);
|
|
||||||
ResetInstances(InstanceResetMethod.GroupDisband, true, true, null);
|
|
||||||
|
|
||||||
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_LFG_DATA);
|
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_LFG_DATA);
|
||||||
stmt.AddValue(0, m_dbStoreId);
|
stmt.AddValue(0, m_dbStoreId);
|
||||||
DB.Characters.Execute(stmt);
|
trans.Append(stmt);
|
||||||
|
|
||||||
|
DB.Characters.CommitTransaction(trans);
|
||||||
|
|
||||||
Global.GroupMgr.FreeGroupDbStoreId(this);
|
Global.GroupMgr.FreeGroupDbStoreId(this);
|
||||||
}
|
}
|
||||||
@@ -1359,9 +1349,30 @@ namespace Game.Groups
|
|||||||
public Difficulty GetRaidDifficultyID() { return m_raidDifficulty; }
|
public Difficulty GetRaidDifficultyID() { return m_raidDifficulty; }
|
||||||
public Difficulty GetLegacyRaidDifficultyID() { return m_legacyRaidDifficulty; }
|
public Difficulty GetLegacyRaidDifficultyID() { return m_legacyRaidDifficulty; }
|
||||||
|
|
||||||
public void ResetInstances(InstanceResetMethod method, bool isRaid, bool isLegacy, Player SendMsgTo)
|
public void ResetInstances(InstanceResetMethod method, Player notifyPlayer)
|
||||||
{
|
{
|
||||||
|
for (GroupInstanceReference refe = m_ownedInstancesMgr.GetFirst(); refe != null; refe = refe.Next())
|
||||||
|
{
|
||||||
|
InstanceMap map = refe.GetSource();
|
||||||
|
switch (map.Reset(method))
|
||||||
|
{
|
||||||
|
case InstanceResetResult.Success:
|
||||||
|
notifyPlayer.SendResetInstanceSuccess(map.GetId());
|
||||||
|
m_recentInstances.Remove(map.GetId());
|
||||||
|
break;
|
||||||
|
case InstanceResetResult.NotEmpty:
|
||||||
|
if (method == InstanceResetMethod.Manual)
|
||||||
|
notifyPlayer.SendResetInstanceFailed(ResetFailedReason.Failed, map.GetId());
|
||||||
|
else if (method == InstanceResetMethod.OnChangeDifficulty)
|
||||||
|
m_recentInstances.Remove(map.GetId()); // map might not have been reset on difficulty change but we still don't want to zone in there again
|
||||||
|
break;
|
||||||
|
case InstanceResetResult.CannotReset:
|
||||||
|
m_recentInstances.Remove(map.GetId()); // forget the instance, allows retrying different lockout with a new leader
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LinkOwnedInstance(GroupInstanceReference refe)
|
public void LinkOwnedInstance(GroupInstanceReference refe)
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ namespace Game
|
|||||||
reviveAtTrigger = true;
|
reviveAtTrigger = true;
|
||||||
break;
|
break;
|
||||||
case EnterState.CannotEnterCorpseInDifferentInstance:
|
case EnterState.CannotEnterCorpseInDifferentInstance:
|
||||||
player.SendPacket(new AreaTriggerNoCorpse());
|
SendPacket(new AreaTriggerNoCorpse());
|
||||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' does not have a corpse in instance map {1} and cannot enter", player.GetName(), at.target_mapId);
|
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' does not have a corpse in instance map {1} and cannot enter", player.GetName(), at.target_mapId);
|
||||||
break;
|
break;
|
||||||
case EnterState.CannotEnterInstanceBindMismatch:
|
case EnterState.CannotEnterInstanceBindMismatch:
|
||||||
@@ -326,6 +326,11 @@ namespace Game
|
|||||||
player.SendTransferAborted(at.target_mapId, TransferAbortReason.ZoneInCombat);
|
player.SendTransferAborted(at.target_mapId, TransferAbortReason.ZoneInCombat);
|
||||||
reviveAtTrigger = true;
|
reviveAtTrigger = true;
|
||||||
break;
|
break;
|
||||||
|
case EnterState.CannotEnterInstanceShuttingDown:
|
||||||
|
player.SendTransferAborted(at.target_mapId, TransferAbortReason.NotFound);
|
||||||
|
Log.outDebug(LogFilter.Maps, $"MAP: Player '{player.GetName()}' cannot enter instance map {at.target_mapId} because instance is resetting.");
|
||||||
|
reviveAtTrigger = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -594,14 +599,23 @@ namespace Game
|
|||||||
[WorldPacketHandler(ClientOpcodes.ResetInstances)]
|
[WorldPacketHandler(ClientOpcodes.ResetInstances)]
|
||||||
void HandleResetInstances(ResetInstances packet)
|
void HandleResetInstances(ResetInstances packet)
|
||||||
{
|
{
|
||||||
|
Map map = _player.GetMap();
|
||||||
|
if (map != null && map.Instanceable())
|
||||||
|
return;
|
||||||
|
|
||||||
Group group = GetPlayer().GetGroup();
|
Group group = GetPlayer().GetGroup();
|
||||||
if (group)
|
if (group)
|
||||||
{
|
{
|
||||||
if (group.IsLeader(GetPlayer().GetGUID()))
|
if (!group.IsLeader(GetPlayer().GetGUID()))
|
||||||
group.ResetInstances(InstanceResetMethod.All, false, false, GetPlayer());
|
return;
|
||||||
|
|
||||||
|
if (group.IsLFGGroup())
|
||||||
|
return;
|
||||||
|
|
||||||
|
group.ResetInstances(InstanceResetMethod.Manual, _player);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
GetPlayer().ResetInstances(InstanceResetMethod.All, false, false);
|
GetPlayer().ResetInstances(InstanceResetMethod.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
[WorldPacketHandler(ClientOpcodes.SetDungeonDifficulty)]
|
[WorldPacketHandler(ClientOpcodes.SetDungeonDifficulty)]
|
||||||
@@ -635,7 +649,7 @@ namespace Game
|
|||||||
|
|
||||||
// cannot reset while in an instance
|
// cannot reset while in an instance
|
||||||
Map map = GetPlayer().GetMap();
|
Map map = GetPlayer().GetMap();
|
||||||
if (map && map.IsDungeon())
|
if (map && map.Instanceable())
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: player (Name: {0}, {1}) tried to reset the instance while player is inside!",
|
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: player (Name: {0}, {1}) tried to reset the instance while player is inside!",
|
||||||
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
||||||
@@ -645,33 +659,19 @@ namespace Game
|
|||||||
Group group = GetPlayer().GetGroup();
|
Group group = GetPlayer().GetGroup();
|
||||||
if (group)
|
if (group)
|
||||||
{
|
{
|
||||||
if (group.IsLeader(GetPlayer().GetGUID()))
|
if (!group.IsLeader(_player.GetGUID()))
|
||||||
{
|
|
||||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next())
|
|
||||||
{
|
|
||||||
Player groupGuy = refe.GetSource();
|
|
||||||
if (!groupGuy)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!groupGuy.IsInWorld)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (groupGuy.GetMap().IsNonRaidDungeon())
|
if (group.IsLFGGroup())
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: {0} tried to reset the instance while group member (Name: {1}, {2}) is inside!",
|
|
||||||
GetPlayer().GetGUID().ToString(), groupGuy.GetName(), groupGuy.GetGUID().ToString());
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
// the difficulty is set even if the instances can't be reset
|
// the difficulty is set even if the instances can't be reset
|
||||||
//_player.SendDungeonDifficulty(true);
|
group.ResetInstances(InstanceResetMethod.OnChangeDifficulty, _player);
|
||||||
group.ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false, GetPlayer());
|
|
||||||
group.SetDungeonDifficultyID(difficultyID);
|
group.SetDungeonDifficultyID(difficultyID);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false);
|
GetPlayer().ResetInstances(InstanceResetMethod.OnChangeDifficulty);
|
||||||
GetPlayer().SetDungeonDifficultyID(difficultyID);
|
GetPlayer().SetDungeonDifficultyID(difficultyID);
|
||||||
GetPlayer().SendDungeonDifficulty();
|
GetPlayer().SendDungeonDifficulty();
|
||||||
}
|
}
|
||||||
@@ -702,7 +702,7 @@ namespace Game
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((int)(difficultyEntry.Flags & DifficultyFlags.Legacy) >> 5) != setRaidDifficulty.Legacy)
|
if (((int)(difficultyEntry.Flags & DifficultyFlags.Legacy) != 0) != (setRaidDifficulty.Legacy != 0))
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent not matching legacy difficulty {1}!",
|
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent not matching legacy difficulty {1}!",
|
||||||
GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
|
GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
|
||||||
@@ -715,7 +715,7 @@ namespace Game
|
|||||||
|
|
||||||
// cannot reset while in an instance
|
// cannot reset while in an instance
|
||||||
Map map = GetPlayer().GetMap();
|
Map map = GetPlayer().GetMap();
|
||||||
if (map && map.IsDungeon())
|
if (map && map.Instanceable())
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player (Name: {0}, {1} tried to reset the instance while inside!",
|
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player (Name: {0}, {1} tried to reset the instance while inside!",
|
||||||
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
||||||
@@ -725,34 +725,22 @@ namespace Game
|
|||||||
Group group = GetPlayer().GetGroup();
|
Group group = GetPlayer().GetGroup();
|
||||||
if (group)
|
if (group)
|
||||||
{
|
{
|
||||||
if (group.IsLeader(GetPlayer().GetGUID()))
|
if (!group.IsLeader(_player.GetGUID()))
|
||||||
{
|
|
||||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next())
|
|
||||||
{
|
|
||||||
Player groupGuy = refe.GetSource();
|
|
||||||
if (!groupGuy)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!groupGuy.IsInWorld)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (groupGuy.GetMap().IsRaid())
|
if (group.IsLFGGroup())
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player {0} tried to reset the instance while inside!", GetPlayer().GetGUID().ToString());
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
// the difficulty is set even if the instances can't be reset
|
// the difficulty is set even if the instances can't be reset
|
||||||
group.ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0, GetPlayer());
|
group.ResetInstances(InstanceResetMethod.OnChangeDifficulty, _player);
|
||||||
if (setRaidDifficulty.Legacy != 0)
|
if (setRaidDifficulty.Legacy != 0)
|
||||||
group.SetLegacyRaidDifficultyID(difficultyID);
|
group.SetLegacyRaidDifficultyID(difficultyID);
|
||||||
else
|
else
|
||||||
group.SetRaidDifficultyID(difficultyID);
|
group.SetRaidDifficultyID(difficultyID);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0);
|
GetPlayer().ResetInstances(InstanceResetMethod.OnChangeDifficulty);
|
||||||
if (setRaidDifficulty.Legacy != 0)
|
if (setRaidDifficulty.Legacy != 0)
|
||||||
GetPlayer().SetLegacyRaidDifficultyID(difficultyID);
|
GetPlayer().SetLegacyRaidDifficultyID(difficultyID);
|
||||||
else
|
else
|
||||||
|
|||||||
+23
-58
@@ -4786,6 +4786,9 @@ namespace Game.Maps
|
|||||||
return EnterState.CannotEnterAlreadyInMap;
|
return EnterState.CannotEnterAlreadyInMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_shuttingDown)
|
||||||
|
return EnterState.CannotEnterInstanceShuttingDown;
|
||||||
|
|
||||||
// allow GM's to enter
|
// allow GM's to enter
|
||||||
if (player.IsGameMaster())
|
if (player.IsGameMaster())
|
||||||
return base.CannotEnter(player);
|
return base.CannotEnter(player);
|
||||||
@@ -4842,16 +4845,10 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for normal instances cancel the reset schedule when the
|
|
||||||
// first player enters (no players yet)
|
|
||||||
SetResetSchedule(false);
|
|
||||||
|
|
||||||
Log.outInfo(LogFilter.Maps, "MAP: Player '{0}' entered instance '{1}' of map '{2}'", player.GetName(),
|
Log.outInfo(LogFilter.Maps, "MAP: Player '{0}' entered instance '{1}' of map '{2}'", player.GetName(),
|
||||||
GetInstanceId(), GetMapName());
|
GetInstanceId(), GetMapName());
|
||||||
// initialize unload state
|
// initialize unload state
|
||||||
m_unloadTimer = 0;
|
m_unloadTimer = 0;
|
||||||
m_resetAfterUnload = false;
|
|
||||||
m_unloadWhenEmpty = false;
|
|
||||||
|
|
||||||
// this will acquire the same mutex so it cannot be in the previous block
|
// this will acquire the same mutex so it cannot be in the previous block
|
||||||
base.AddPlayerToMap(player, initPlayer);
|
base.AddPlayerToMap(player, initPlayer);
|
||||||
@@ -4888,15 +4885,12 @@ namespace Game.Maps
|
|||||||
|
|
||||||
// if last player set unload timer
|
// if last player set unload timer
|
||||||
if (m_unloadTimer == 0 && GetPlayers().Count == 1)
|
if (m_unloadTimer == 0 && GetPlayers().Count == 1)
|
||||||
m_unloadTimer = m_unloadWhenEmpty ? 1 : (uint)Math.Max(WorldConfig.GetIntValue(WorldCfg.InstanceUnloadDelay), 1);
|
m_unloadTimer = m_shuttingDown ? 1 : (uint)Math.Max(WorldConfig.GetIntValue(WorldCfg.InstanceUnloadDelay), 1);
|
||||||
|
|
||||||
if (i_scenario != null)
|
if (i_scenario != null)
|
||||||
i_scenario.OnPlayerExit(player);
|
i_scenario.OnPlayerExit(player);
|
||||||
|
|
||||||
base.RemovePlayerFromMap(player, remove);
|
base.RemovePlayerFromMap(player, remove);
|
||||||
|
|
||||||
// for normal instances schedule the reset after all players have left
|
|
||||||
SetResetSchedule(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateInstanceData()
|
public void CreateInstanceData()
|
||||||
@@ -4942,47 +4936,44 @@ namespace Game.Maps
|
|||||||
i_owningGroupRef.Link(group, this);
|
i_owningGroupRef.Link(group, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Reset(InstanceResetMethod method)
|
public InstanceResetResult Reset(InstanceResetMethod method)
|
||||||
{
|
{
|
||||||
// note: since the map may not be loaded when the instance needs to be reset
|
// raids can be reset if no boss was killed
|
||||||
// the instance must be deleted from the DB
|
if (method != InstanceResetMethod.Expire && i_instanceLock != null && i_instanceLock.GetData().CompletedEncountersMask != 0)
|
||||||
|
return InstanceResetResult.CannotReset;
|
||||||
|
|
||||||
if (HavePlayers())
|
if (HavePlayers())
|
||||||
{
|
{
|
||||||
// on manual reset, fail
|
switch (method)
|
||||||
if (method == InstanceResetMethod.All || method == InstanceResetMethod.ChangeDifficulty)
|
|
||||||
{
|
{
|
||||||
|
case InstanceResetMethod.Manual:
|
||||||
// notify the players to leave the instance so it can be reset
|
// notify the players to leave the instance so it can be reset
|
||||||
foreach (Player player in GetPlayers())
|
foreach (var player in GetPlayers())
|
||||||
player.SendResetFailedNotify(GetId());
|
player.SendResetFailedNotify(GetId());
|
||||||
}
|
break;
|
||||||
else
|
case InstanceResetMethod.OnChangeDifficulty:
|
||||||
{
|
// no client notification
|
||||||
|
break;
|
||||||
|
case InstanceResetMethod.Expire:
|
||||||
// on lock expiration boot players (do we also care about extension state?)
|
// on lock expiration boot players (do we also care about extension state?)
|
||||||
if (method == InstanceResetMethod.Global)
|
|
||||||
{
|
|
||||||
// set the homebind timer for players inside (1 minute)
|
// set the homebind timer for players inside (1 minute)
|
||||||
foreach (Player player in GetPlayers())
|
foreach (Player player in GetPlayers())
|
||||||
player.m_InstanceValid = false;
|
player.m_InstanceValid = false;
|
||||||
|
m_shuttingDown = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HasPermBoundPlayers())
|
return InstanceResetResult.NotEmpty;
|
||||||
{
|
|
||||||
// the unload timer is not started
|
|
||||||
// instead the map will unload immediately after the players have left
|
|
||||||
m_unloadWhenEmpty = true;
|
|
||||||
m_resetAfterUnload = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unloaded at next update
|
// unloaded at next update
|
||||||
m_unloadTimer = 1;
|
m_unloadTimer = 1;
|
||||||
m_resetAfterUnload = !(method == InstanceResetMethod.Global && HasPermBoundPlayers());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetPlayers().Empty();
|
return InstanceResetResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetScriptName()
|
public string GetScriptName()
|
||||||
@@ -5097,31 +5088,6 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UnloadAll()
|
|
||||||
{
|
|
||||||
Cypher.Assert(!HavePlayers());
|
|
||||||
|
|
||||||
if (m_resetAfterUnload)
|
|
||||||
{
|
|
||||||
DeleteRespawnTimes();
|
|
||||||
DeleteCorpseData();
|
|
||||||
}
|
|
||||||
|
|
||||||
base.UnloadAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetResetSchedule(bool on)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasPermBoundPlayers()
|
|
||||||
{
|
|
||||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_PERM_BIND_BY_INSTANCE);
|
|
||||||
stmt.AddValue(0, GetInstanceId());
|
|
||||||
return !DB.Characters.Query(stmt).IsEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint GetMaxPlayers()
|
public uint GetMaxPlayers()
|
||||||
{
|
{
|
||||||
MapDifficultyRecord mapDiff = GetMapDifficulty();
|
MapDifficultyRecord mapDiff = GetMapDifficulty();
|
||||||
@@ -5168,8 +5134,7 @@ namespace Game.Maps
|
|||||||
InstanceScenario i_scenario;
|
InstanceScenario i_scenario;
|
||||||
InstanceLock i_instanceLock;
|
InstanceLock i_instanceLock;
|
||||||
GroupInstanceReference i_owningGroupRef = new();
|
GroupInstanceReference i_owningGroupRef = new();
|
||||||
bool m_resetAfterUnload;
|
bool m_shuttingDown;
|
||||||
bool m_unloadWhenEmpty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BattlegroundMap : Map
|
public class BattlegroundMap : Map
|
||||||
|
|||||||
@@ -326,8 +326,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
map.UnloadAll();
|
map.UnloadAll();
|
||||||
|
|
||||||
// Free up the instance id and allow it to be reused for bgs and arenas (other instances are handled in the InstanceSaveMgr)
|
// Free up the instance id and allow it to be reused for normal dungeons, bgs and arenas
|
||||||
if (map.IsBattlegroundOrArena())
|
if (map.IsBattlegroundOrArena() || (map.IsDungeon() && !map.GetMapDifficulty().HasResetSchedule()))
|
||||||
FreeInstanceId(map.GetInstanceId());
|
FreeInstanceId(map.GetInstanceId());
|
||||||
|
|
||||||
// erase map
|
// erase map
|
||||||
|
|||||||
Reference in New Issue
Block a user