diff --git a/Source/Game/DungeonFinding/LFGManager.cs b/Source/Game/DungeonFinding/LFGManager.cs index a27e8ec80..72f14e76f 100644 --- a/Source/Game/DungeonFinding/LFGManager.cs +++ b/Source/Game/DungeonFinding/LFGManager.cs @@ -1607,7 +1607,7 @@ namespace Game.DungeonFinding lockStatus = LfgLockStatusType.NotInSeason; else if (Global.DisableMgr.IsDisabledFor(DisableType.LFGMap, dungeon.map, player)) lockStatus = LfgLockStatusType.RaidLocked; - else if (dungeon.difficulty > Difficulty.Normal && Global.InstanceLockMgr.FindActiveInstanceLock(guid, new MapDb2Entries(dungeon.map, dungeon.difficulty)) != null) + else if (Global.InstanceLockMgr.FindActiveInstanceLock(guid, new MapDb2Entries(dungeon.map, dungeon.difficulty)) != null) lockStatus = LfgLockStatusType.RaidLocked; else if (dungeon.seasonal && !IsSeasonActive(dungeon.id)) lockStatus = LfgLockStatusType.NotInSeason; diff --git a/Source/Game/Maps/Instances/InstanceLockManager.cs b/Source/Game/Maps/Instances/InstanceLockManager.cs index 1ab9d006f..f7282ebc2 100644 --- a/Source/Game/Maps/Instances/InstanceLockManager.cs +++ b/Source/Game/Maps/Instances/InstanceLockManager.cs @@ -110,7 +110,7 @@ namespace Game.Maps return TransferAbortReason.None; } - if (!entries.MapDifficulty.IsUsingEncounterLocks() && playerInstanceLock.GetInstanceId() != 0 && playerInstanceLock.GetInstanceId() != instanceLock.GetInstanceId()) + if (!entries.MapDifficulty.IsUsingEncounterLocks() && playerInstanceLock.IsNew() && playerInstanceLock.GetInstanceId() != instanceLock.GetInstanceId()) return TransferAbortReason.LockedToDifferentInstance; return TransferAbortReason.None; @@ -167,11 +167,13 @@ namespace Game.Maps SharedInstanceLockData sharedData = new(); _instanceLockDataById[instanceId] = sharedData; instanceLock = new SharedInstanceLock(entries.MapDifficulty.MapID, (Difficulty)entries.MapDifficulty.DifficultyID, - GetNextResetTime(entries), 0, sharedData); + GetNextResetTime(entries), instanceId, sharedData); } else instanceLock = new InstanceLock(entries.MapDifficulty.MapID, (Difficulty)entries.MapDifficulty.DifficultyID, - GetNextResetTime(entries), 0); + GetNextResetTime(entries), instanceId); + + instanceLock.SetIsNew(true); if (!_temporaryInstanceLocksByPlayer.ContainsKey(playerGuid)) _temporaryInstanceLocksByPlayer[playerGuid] = new Dictionary(); @@ -237,7 +239,7 @@ namespace Game.Maps { if (entries.IsInstanceIdBound()) { - Cypher.Assert(instanceLock.GetInstanceId() == 0 || instanceLock.GetInstanceId() == updateEvent.InstanceId); + Cypher.Assert(instanceLock.GetInstanceId() == updateEvent.InstanceId); var sharedDataItr = _instanceLockDataById.LookupByKey(updateEvent.InstanceId); Cypher.Assert(sharedDataItr != null); Cypher.Assert(sharedDataItr == (instanceLock as SharedInstanceLock).GetSharedData()); @@ -246,6 +248,7 @@ namespace Game.Maps instanceLock.SetInstanceId(updateEvent.InstanceId); } + instanceLock.SetIsNew(false); instanceLock.GetData().Data = updateEvent.NewData; if (updateEvent.CompletedEncounter != null) { @@ -325,6 +328,9 @@ namespace Game.Maps if (_unloading) return; + if (!_instanceLockDataById.ContainsKey(instanceId)) + return; + _instanceLockDataById.Remove(instanceId); PreparedStatement stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_INSTANCE); stmt.AddValue(0, instanceId); @@ -381,6 +387,9 @@ namespace Game.Maps if (difficulty.HasValue && difficulty.Value != playerLockPair.Value.GetDifficultyId()) continue; + if (playerLockPair.Value.IsExpired()) + continue; + locksReset.Add(playerLockPair.Value); } @@ -470,6 +479,7 @@ namespace Game.Maps bool _extended; InstanceLockData _data = new(); bool _isInUse; + bool _isNew; public InstanceLock(uint mapId, Difficulty difficultyId, DateTime expiryTime, uint instanceId) { @@ -523,6 +533,10 @@ namespace Game.Maps public bool IsInUse() { return _isInUse; } public void SetInUse(bool inUse) { _isInUse = inUse; } + + public bool IsNew() { return _isNew; } + + public void SetIsNew(bool isNew) { _isNew = isNew; } } class SharedInstanceLockData : InstanceLockData diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 4cb360513..18e0c8f8c 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -4801,7 +4801,7 @@ namespace Game.Maps player.AddInstanceEnterTime(GetInstanceId(), GameTime.GetGameTime()); MapDb2Entries entries = new(GetEntry(), GetMapDifficulty()); - if (entries.MapDifficulty.HasResetSchedule() && i_instanceLock != null && i_instanceLock.GetData().CompletedEncountersMask != 0) + if (entries.MapDifficulty.HasResetSchedule() && i_instanceLock != null && !i_instanceLock.IsNew()) { if (!entries.MapDifficulty.IsUsingEncounterLocks()) { @@ -4890,7 +4890,7 @@ namespace Game.Maps if (i_data == null) return; - if (i_instanceLock == null || i_instanceLock.GetInstanceId() == 0) + if (i_instanceLock == null || i_instanceLock.IsNew()) { i_data.Create(); return; @@ -4926,7 +4926,7 @@ namespace Game.Maps public InstanceResetResult Reset(InstanceResetMethod method) { // raids can be reset if no boss was killed - if (method != InstanceResetMethod.Expire && i_instanceLock != null && i_instanceLock.GetData().CompletedEncountersMask != 0) + if (method != InstanceResetMethod.Expire && i_instanceLock != null && !i_instanceLock.IsNew()) return InstanceResetResult.CannotReset; if (HavePlayers()) @@ -5015,7 +5015,7 @@ namespace Game.Maps playerCompletedEncounters = playerLock.GetData().CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter.Bit); } - bool isNewLock = playerLock == null || playerLock.GetData().CompletedEncountersMask == 0 || playerLock.IsExpired(); + bool isNewLock = playerLock == null || playerLock.IsNew() || playerLock.IsExpired(); InstanceLock newLock = Global.InstanceLockMgr.UpdateInstanceLockForPlayer(trans, player.GetGUID(), entries, new InstanceLockUpdateEvent(GetInstanceId(), i_data.UpdateBossStateSaveData(oldData, updateSaveDataEvent), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter, i_data.GetEntranceLocationForCompletedEncounters(playerCompletedEncounters))); @@ -5058,7 +5058,7 @@ namespace Game.Maps if (playerLock != null) oldData = playerLock.GetData().Data; - bool isNewLock = playerLock == null || playerLock.GetData().CompletedEncountersMask == 0 || playerLock.IsExpired(); + bool isNewLock = playerLock == null || playerLock.IsNew() || playerLock.IsExpired(); InstanceLock newLock = Global.InstanceLockMgr.UpdateInstanceLockForPlayer(trans, player.GetGUID(), entries, new InstanceLockUpdateEvent(GetInstanceId(), i_data.UpdateAdditionalSaveData(oldData, updateSaveDataEvent), instanceCompletedEncounters, null, null)); @@ -5082,7 +5082,7 @@ namespace Game.Maps MapDb2Entries entries = new(GetEntry(), GetMapDifficulty()); InstanceLock playerLock = Global.InstanceLockMgr.FindActiveInstanceLock(player.GetGUID(), entries); - bool isNewLock = playerLock == null || playerLock.GetData().CompletedEncountersMask == 0 || playerLock.IsExpired(); + bool isNewLock = playerLock == null || playerLock.IsNew() || playerLock.IsExpired(); SQLTransaction trans = new(); diff --git a/Source/Game/Maps/MapManager.cs b/Source/Game/Maps/MapManager.cs index 2bd3e771a..6df7ef547 100644 --- a/Source/Game/Maps/MapManager.cs +++ b/Source/Game/Maps/MapManager.cs @@ -70,7 +70,7 @@ namespace Game.Entities // some instances only have one difficulty Global.DB2Mgr.GetDownscaledMapDifficultyData(mapId, ref difficulty); - Log.outDebug(LogFilter.Maps, $"MapInstanced::CreateInstance: {(instanceLock?.GetInstanceId() != 0 ? "" : "new ")}map instance {instanceId} for {mapId} created with difficulty {difficulty}"); + Log.outDebug(LogFilter.Maps, $"MapInstanced::CreateInstance: {(instanceLock?.IsNew() == true ? "new" : " ")} map instance {instanceId} for {mapId} created with difficulty {difficulty}"); InstanceMap map = new InstanceMap(mapId, i_gridCleanUpDelay, instanceId, difficulty, team, instanceLock); Cypher.Assert(map.IsDungeon());