diff options
author | Shauren <shauren.trinity@gmail.com> | 2022-08-15 18:39:58 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-10-04 00:19:38 +0200 |
commit | 20357af88ec9265869cca3c1db3c5f43ef37e587 (patch) | |
tree | 2164309e52e436547e011a4e6240cd6444abc9ff | |
parent | ca5f7a15b9c2ca352f7f83ddc065d795f2294d98 (diff) |
Core/Instances: Add instance reset events at lock expiration
-rw-r--r-- | src/server/game/Instances/InstanceLockMgr.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 40 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 2 |
3 files changed, 32 insertions, 11 deletions
diff --git a/src/server/game/Instances/InstanceLockMgr.cpp b/src/server/game/Instances/InstanceLockMgr.cpp index 97687ef8a8e..1296fb951dd 100644 --- a/src/server/game/Instances/InstanceLockMgr.cpp +++ b/src/server/game/Instances/InstanceLockMgr.cpp @@ -362,7 +362,6 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran if (instanceLock->IsExpired()) { - ASSERT(instanceLock->IsExtended(), "Instance lock must have been extended to create instance map from it"); instanceLock->SetExpiryTime(GetNextResetTime(entries)); instanceLock->SetExtended(false); TC_LOG_DEBUG("instance.locks", "[%u-%s | %u-%s] Expired instance lock for %s in instance %u is now active", diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index d69b5581179..ddfe404cc34 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2769,7 +2769,6 @@ template TC_GAME_API void Map::RemoveFromMap(Conversation*, bool); InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty SpawnMode, TeamId InstanceTeam, InstanceLock* instanceLock) : Map(id, expiry, InstanceId, SpawnMode), - m_shuttingDown(false), i_data(nullptr), i_script_id(0), i_scenario(nullptr), i_instanceLock(instanceLock) { //lets initialize visibility distance for dungeons @@ -2783,7 +2782,10 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty sWorldStateMgr->SetValue(WS_TEAM_IN_INSTANCE_HORDE, InstanceTeam == TEAM_HORDE, false, this); if (i_instanceLock) + { i_instanceLock->SetInUse(true); + i_instanceExpireEvent = i_instanceLock->GetExpiryTime(); // ignore extension state for reset event (will ask players to accept extended save on expiration) + } } InstanceMap::~InstanceMap() @@ -2814,9 +2816,6 @@ Map::EnterState InstanceMap::CannotEnter(Player* player) return CANNOT_ENTER_ALREADY_IN_MAP; } - if (m_shuttingDown) - return CANNOT_ENTER_INSTANCE_SHUTTING_DOWN; - // allow GM's to enter if (player->IsGameMaster()) return Map::CannotEnter(player); @@ -2904,6 +2903,12 @@ void InstanceMap::Update(uint32 t_diff) if (i_scenario) i_scenario->Update(t_diff); + + if (i_instanceExpireEvent && i_instanceExpireEvent < GameTime::GetSystemTime()) + { + Reset(InstanceResetMethod::Expire); + i_instanceExpireEvent = sInstanceLockMgr.GetNextResetTime({ GetEntry(), GetMapDifficulty() }); + } } void InstanceMap::RemovePlayerFromMap(Player* player, bool remove) @@ -2915,7 +2920,7 @@ void InstanceMap::RemovePlayerFromMap(Player* player, bool remove) // if last player set unload timer if (!m_unloadTimer && m_mapRefManager.getSize() == 1) - m_unloadTimer = m_shuttingDown ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); + m_unloadTimer = (i_instanceLock && i_instanceLock->IsExpired()) ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); if (i_scenario) i_scenario->OnPlayerExit(player); @@ -2985,13 +2990,30 @@ InstanceResetResult InstanceMap::Reset(InstanceResetMethod method) // no client notification break; case InstanceResetMethod::Expire: - // on lock expiration boot players (do we also care about extension state?) - // set the homebind timer for players inside (1 minute) + { + WorldPackets::Instance::RaidInstanceMessage raidInstanceMessage; + raidInstanceMessage.Type = RAID_INSTANCE_EXPIRED; + raidInstanceMessage.MapID = GetId(); + raidInstanceMessage.DifficultyID = GetDifficultyID(); + raidInstanceMessage.Write(); + + WorldPackets::Instance::PendingRaidLock pendingRaidLock; + pendingRaidLock.TimeUntilLock = 60000; + pendingRaidLock.CompletedMask = i_instanceLock->GetData()->CompletedEncountersMask; + pendingRaidLock.Extending = true; + pendingRaidLock.WarningOnly = GetEntry()->IsFlexLocking(); + pendingRaidLock.Write(); + for (MapReference& ref : m_mapRefManager) - ref.GetSource()->m_InstanceValid = false; + { + ref.GetSource()->SendDirectMessage(raidInstanceMessage.GetRawPacket()); + ref.GetSource()->SendDirectMessage(pendingRaidLock.GetRawPacket()); - m_shuttingDown = true; + if (!pendingRaidLock.WarningOnly) + ref.GetSource()->SetPendingBind(GetInstanceId(), 60000); + } break; + } default: break; } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 732fe9210d9..985ac6f01e2 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -836,7 +836,7 @@ class TC_GAME_API InstanceMap : public Map std::string GetDebugInfo() const override; private: - bool m_shuttingDown; + Optional<SystemTimePoint> i_instanceExpireEvent; InstanceScript* i_data; uint32 i_script_id; InstanceScenario* i_scenario; |