mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Instances: Fixed not being able to reenter instances that have no encounters completed
Closes #28737
This commit is contained in:
@@ -1731,7 +1731,7 @@ LfgLockMap LFGMgr::GetLockedDungeons(ObjectGuid guid)
|
||||
return LFG_LOCKSTATUS_NOT_IN_SEASON;
|
||||
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_LFG_MAP, dungeon->map, player))
|
||||
return LFG_LOCKSTATUS_RAID_LOCKED;
|
||||
if (dungeon->difficulty > DIFFICULTY_NORMAL && sInstanceLockMgr.FindActiveInstanceLock(guid, { dungeon->map, Difficulty(dungeon->difficulty) }))
|
||||
if (sInstanceLockMgr.FindActiveInstanceLock(guid, { dungeon->map, Difficulty(dungeon->difficulty) }))
|
||||
return LFG_LOCKSTATUS_RAID_LOCKED;
|
||||
if (Optional<ContentTuningLevels> levels = sDB2Manager.GetContentTuningData(dungeon->contentTuningId, player->m_playerData->CtrOptions->ContentTuningConditionMask))
|
||||
{
|
||||
|
||||
@@ -29,7 +29,8 @@ InstanceLockData::InstanceLockData() = default;
|
||||
InstanceLockData::~InstanceLockData() = default;
|
||||
|
||||
InstanceLock::InstanceLock(uint32 mapId, Difficulty difficultyId, InstanceResetTimePoint expiryTime, uint32 instanceId)
|
||||
: _mapId(mapId), _difficultyId(difficultyId), _instanceId(instanceId), _expiryTime(expiryTime), _extended(false), _isInUse(false)
|
||||
: _mapId(mapId), _difficultyId(difficultyId), _instanceId(instanceId), _expiryTime(expiryTime), _extended(false),
|
||||
_isInUse(false), _isNew(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -149,7 +150,7 @@ void InstanceLockMgr::Load()
|
||||
}
|
||||
|
||||
instanceLock = new SharedInstanceLock(mapId, difficulty, expiryTime, instanceId, sharedDataItr->second);
|
||||
_instanceLockDataById[instanceId] = std::weak_ptr<SharedInstanceLockData>(sharedDataItr->second);
|
||||
_instanceLockDataById[instanceId] = sharedDataItr->second;
|
||||
}
|
||||
else
|
||||
instanceLock = new InstanceLock(mapId, difficulty, expiryTime, instanceId);
|
||||
@@ -186,7 +187,7 @@ TransferAbortReason InstanceLockMgr::CanJoinInstanceLock(ObjectGuid const& playe
|
||||
return TRANSFER_ABORT_NONE;
|
||||
}
|
||||
|
||||
if (!entries.MapDifficulty->IsUsingEncounterLocks() && playerInstanceLock->GetInstanceId() && playerInstanceLock->GetInstanceId() != instanceLock->GetInstanceId())
|
||||
if (!entries.MapDifficulty->IsUsingEncounterLocks() && !playerInstanceLock->IsNew() && playerInstanceLock->GetInstanceId() != instanceLock->GetInstanceId())
|
||||
return TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE;
|
||||
|
||||
return TRANSFER_ABORT_NONE;
|
||||
@@ -256,11 +257,13 @@ InstanceLock* InstanceLockMgr::CreateInstanceLockForNewInstance(ObjectGuid const
|
||||
std::shared_ptr<SharedInstanceLockData> sharedData = std::make_shared<SharedInstanceLockData>();
|
||||
_instanceLockDataById[instanceId] = sharedData;
|
||||
instanceLock = new SharedInstanceLock(entries.MapDifficulty->MapID, Difficulty(entries.MapDifficulty->DifficultyID),
|
||||
GetNextResetTime(entries), 0, std::move(sharedData));
|
||||
GetNextResetTime(entries), instanceId, std::move(sharedData));
|
||||
}
|
||||
else
|
||||
instanceLock = new InstanceLock(entries.MapDifficulty->MapID, Difficulty(entries.MapDifficulty->DifficultyID),
|
||||
GetNextResetTime(entries), 0);
|
||||
GetNextResetTime(entries), instanceId);
|
||||
|
||||
instanceLock->SetIsNew(true);
|
||||
|
||||
_temporaryInstanceLocksByPlayer[playerGuid][entries.GetKey()].reset(instanceLock);
|
||||
TC_LOG_DEBUG("instance.locks", "[{}-{} | {}-{}] Created new temporary instance lock for {} in instance {}",
|
||||
@@ -333,7 +336,7 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran
|
||||
{
|
||||
if (entries.IsInstanceIdBound())
|
||||
{
|
||||
ASSERT(!instanceLock->GetInstanceId() || instanceLock->GetInstanceId() == updateEvent.InstanceId);
|
||||
ASSERT(instanceLock->GetInstanceId() == updateEvent.InstanceId);
|
||||
auto sharedDataItr = _instanceLockDataById.find(updateEvent.InstanceId);
|
||||
ASSERT(sharedDataItr != _instanceLockDataById.end());
|
||||
ASSERT(sharedDataItr->second.lock().get() == static_cast<SharedInstanceLock*>(instanceLock)->GetSharedData());
|
||||
@@ -342,6 +345,7 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran
|
||||
instanceLock->SetInstanceId(updateEvent.InstanceId);
|
||||
}
|
||||
|
||||
instanceLock->SetIsNew(false);
|
||||
instanceLock->GetData()->Data = std::move(updateEvent.NewData);
|
||||
if (updateEvent.CompletedEncounter)
|
||||
{
|
||||
@@ -428,7 +432,15 @@ void InstanceLockMgr::OnSharedInstanceLockDataDelete(uint32 instanceId)
|
||||
if (_unloading)
|
||||
return;
|
||||
|
||||
_instanceLockDataById.erase(instanceId);
|
||||
auto itr = _instanceLockDataById.find(instanceId);
|
||||
if (itr == _instanceLockDataById.end())
|
||||
return;
|
||||
|
||||
// weak_ptr state must be checked as well, it might be pointing to a different and valid lock data
|
||||
if (!itr->second.expired())
|
||||
return;
|
||||
|
||||
_instanceLockDataById.erase(itr);
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INSTANCE);
|
||||
stmt->setUInt32(0, instanceId);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
@@ -482,6 +494,9 @@ void InstanceLockMgr::ResetInstanceLocksForPlayer(ObjectGuid const& playerGuid,
|
||||
if (difficulty && *difficulty != playerLockPair.second->GetDifficultyId())
|
||||
continue;
|
||||
|
||||
if (playerLockPair.second->IsExpired())
|
||||
continue;
|
||||
|
||||
locksReset->push_back(playerLockPair.second.get());
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,9 @@ public:
|
||||
bool IsInUse() const { return _isInUse; }
|
||||
void SetInUse(bool inUse) { _isInUse = inUse; }
|
||||
|
||||
bool IsNew() const { return _isNew; }
|
||||
void SetIsNew(bool isNew) { _isNew = isNew; }
|
||||
|
||||
private:
|
||||
uint32 _mapId;
|
||||
Difficulty _difficultyId;
|
||||
@@ -123,6 +126,7 @@ private:
|
||||
bool _extended;
|
||||
InstanceLockData _data;
|
||||
bool _isInUse;
|
||||
bool _isNew;
|
||||
};
|
||||
|
||||
struct SharedInstanceLockData : InstanceLockData
|
||||
|
||||
@@ -2860,7 +2860,7 @@ bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)
|
||||
player->AddInstanceEnterTime(GetInstanceId(), GameTime::GetGameTime());
|
||||
|
||||
MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
|
||||
if (entries.MapDifficulty->HasResetSchedule() && i_instanceLock && i_instanceLock->GetData()->CompletedEncountersMask)
|
||||
if (entries.MapDifficulty->HasResetSchedule() && i_instanceLock && !i_instanceLock->IsNew())
|
||||
{
|
||||
if (!entries.MapDifficulty->IsUsingEncounterLocks())
|
||||
{
|
||||
@@ -2948,7 +2948,7 @@ void InstanceMap::CreateInstanceData()
|
||||
if (!i_data)
|
||||
return;
|
||||
|
||||
if (!i_instanceLock || !i_instanceLock->GetInstanceId())
|
||||
if (!i_instanceLock || i_instanceLock->IsNew())
|
||||
{
|
||||
i_data->Create();
|
||||
return;
|
||||
@@ -2985,7 +2985,7 @@ void InstanceMap::TrySetOwningGroup(Group* group)
|
||||
InstanceResetResult InstanceMap::Reset(InstanceResetMethod method)
|
||||
{
|
||||
// raids can be reset if no boss was killed
|
||||
if (method != InstanceResetMethod::Expire && i_instanceLock && i_instanceLock->GetData()->CompletedEncountersMask)
|
||||
if (method != InstanceResetMethod::Expire && i_instanceLock && !i_instanceLock->IsNew())
|
||||
return InstanceResetResult::CannotReset;
|
||||
|
||||
if (HavePlayers())
|
||||
@@ -3075,7 +3075,7 @@ void InstanceMap::UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateS
|
||||
playerCompletedEncounters = playerLock->GetData()->CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter->Bit);
|
||||
}
|
||||
|
||||
bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired();
|
||||
bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired();
|
||||
|
||||
InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
|
||||
InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateBossStateSaveData(oldData ? *oldData : "", updateSaveDataEvent),
|
||||
@@ -3121,7 +3121,7 @@ void InstanceMap::UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& update
|
||||
if (playerLock)
|
||||
oldData = &playerLock->GetData()->Data;
|
||||
|
||||
bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired();
|
||||
bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired();
|
||||
|
||||
InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
|
||||
InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateAdditionalSaveData(oldData ? *oldData : "", updateSaveDataEvent),
|
||||
@@ -3146,7 +3146,7 @@ void InstanceMap::CreateInstanceLockForPlayer(Player* player)
|
||||
MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
|
||||
InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries);
|
||||
|
||||
bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired();
|
||||
bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired();
|
||||
|
||||
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ InstanceMap* MapManager::CreateInstance(uint32 mapId, uint32 instanceId, Instanc
|
||||
sDB2Manager.GetDownscaledMapDifficultyData(mapId, difficulty);
|
||||
|
||||
TC_LOG_DEBUG("maps", "MapInstanced::CreateInstance: {}map instance {} for {} created with difficulty {}",
|
||||
instanceLock && instanceLock->GetInstanceId() ? "" : "new ", instanceId, mapId, sDifficultyStore.AssertEntry(difficulty)->Name[sWorld->GetDefaultDbcLocale()]);
|
||||
instanceLock && instanceLock->IsNew() ? "" : "new ", instanceId, mapId, sDifficultyStore.AssertEntry(difficulty)->Name[sWorld->GetDefaultDbcLocale()]);
|
||||
|
||||
InstanceMap* map = new InstanceMap(mapId, i_gridCleanUpDelay, instanceId, difficulty, team, instanceLock);
|
||||
ASSERT(map->IsDungeon());
|
||||
|
||||
Reference in New Issue
Block a user