diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 43 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 4 | ||||
-rw-r--r-- | src/server/game/Groups/Group.cpp | 40 | ||||
-rw-r--r-- | src/server/game/Groups/Group.h | 4 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 93 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 90 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 29 | ||||
-rw-r--r-- | src/server/game/Maps/MapManager.cpp | 4 |
8 files changed, 159 insertions, 148 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 61efb379d2a..acc9a53f9f9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17400,6 +17400,11 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol // flight will started later } } + else if (mapEntry->IsDungeon() && instanceId) + { + // try finding instance by id first + map = sMapMgr->FindMap(mapId, instanceId); + } // Map could be changed before mapEntry = sMapStore.LookupEntry(mapId); @@ -17447,6 +17452,9 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol case Map::CANNOT_ENTER_ZONE_IN_COMBAT: SendTransferAborted(map->GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT); break; + case Map::CANNOT_ENTER_INSTANCE_SHUTTING_DOWN: + SendTransferAborted(map->GetId(), TRANSFER_ABORT_NOT_FOUND); + break; default: break; } @@ -20589,8 +20597,41 @@ void Player::SendResetFailedNotify(uint32 /*mapid*/) const } /// Reset all solo instances and optionally send a message on success for each -void Player::ResetInstances(InstanceResetMethod /*method*/, bool /*isRaid*/, bool /*isLegacy*/) +void Player::ResetInstances(InstanceResetMethod method) { + for (auto itr = m_recentInstances.begin(); itr != m_recentInstances.end(); ) + { + Map* map = sMapMgr->FindMap(itr->first, itr->second); + bool forgetInstance = false; + if (map) + { + if (InstanceMap* instance = map->ToInstanceMap()) + { + switch (instance->Reset(method)) + { + case InstanceResetResult::Success: + SendResetInstanceSuccess(map->GetId()); + forgetInstance = true; + break; + case InstanceResetResult::NotEmpty: + if (method == InstanceResetMethod::Manual) + SendResetInstanceFailed(INSTANCE_RESET_FAILED, map->GetId()); + else if (method == InstanceResetMethod::OnChangeDifficulty) + forgetInstance = true; + break; + case InstanceResetResult::CannotReset: + break; + default: + break; + } + } + } + + if (forgetInstance) + itr = m_recentInstances.erase(itr); + else + ++itr; + } } void Player::SendResetInstanceSuccess(uint32 MapId) const diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 64f12463459..aba0480d681 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -92,6 +92,8 @@ class SpellCastTargets; class TradeData; enum GroupCategory : uint8; +enum class InstanceResetMethod : uint8; +enum class InstanceResetResult : uint8; enum InventoryType : uint8; enum ItemClass : uint8; enum LootError : uint8; @@ -2085,7 +2087,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendDungeonDifficulty(int32 forcedDifficulty = -1) const; void SendRaidDifficulty(bool legacy, int32 forcedDifficulty = -1) const; - void ResetInstances(InstanceResetMethod method, bool isRaid, bool isLegacy); + void ResetInstances(InstanceResetMethod method); void SendResetInstanceSuccess(uint32 MapId) const; void SendResetInstanceFailed(ResetFailedReason reason, uint32 mapID) const; void SendResetFailedNotify(uint32 mapid) const; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index c799212b059..11f07340955 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -481,12 +481,6 @@ bool Group::AddMember(Player* player) 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(INSTANCE_RESET_GROUP_JOIN, false, false); - player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, true, false); - player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, true, true); - if (player->GetDungeonDifficultyID() != GetDungeonDifficultyID()) { player->SetDungeonDifficultyID(GetDungeonDifficultyID()); @@ -768,15 +762,11 @@ void Group::Disband(bool hideDestroy /* = false */) stmt->setUInt32(0, m_dbStoreId); trans->Append(stmt); - CharacterDatabase.CommitTransaction(trans); - - ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, false, nullptr); - ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, false, nullptr); - ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, true, nullptr); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA); stmt->setUInt32(0, m_dbStoreId); - CharacterDatabase.Execute(stmt); + trans->Append(stmt); + + CharacterDatabase.CommitTransaction(trans); sGroupMgr->FreeGroupDbStoreId(this); } @@ -1359,8 +1349,30 @@ Difficulty Group::GetDifficultyID(MapEntry const* mapEntry) const return m_raidDifficulty; } -void Group::ResetInstances(InstanceResetMethod /*method*/, bool /*isRaid*/, bool /*isLegacy*/, Player* /*SendMsgTo*/) +void Group::ResetInstances(InstanceResetMethod method, Player* notifyPlayer) { + for (GroupInstanceReference& ref : m_ownedInstancesMgr) + { + InstanceMap* map = ref.GetSource(); + switch (map->Reset(method)) + { + case InstanceResetResult::Success: + notifyPlayer->SendResetInstanceSuccess(map->GetId()); + m_recentInstances.erase(map->GetId()); + break; + case InstanceResetResult::NotEmpty: + if (method == InstanceResetMethod::Manual) + notifyPlayer->SendResetInstanceFailed(INSTANCE_RESET_FAILED, map->GetId()); + else if (method == InstanceResetMethod::OnChangeDifficulty) + m_recentInstances.erase(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.erase(map->GetId()); // forget the instance, allows retrying different lockout with a new leader + break; + default: + break; + } + } } void Group::LinkOwnedInstance(GroupInstanceReference* ref) diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 58b27fb459b..3b565aa9c6c 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -41,6 +41,8 @@ class WorldSession; struct ItemDisenchantLootEntry; struct MapEntry; +enum class InstanceResetMethod : uint8; +enum class InstanceResetResult : uint8; enum LootMethod : uint8; #define MAX_GROUP_SIZE 5 @@ -304,7 +306,7 @@ class TC_GAME_API Group Difficulty GetDungeonDifficultyID() const { return m_dungeonDifficulty; } Difficulty GetRaidDifficultyID() const { return m_raidDifficulty; } Difficulty GetLegacyRaidDifficultyID() const { return m_legacyRaidDifficulty; } - void ResetInstances(InstanceResetMethod method, bool isRaid, bool isLegacy, Player* SendMsgTo); + void ResetInstances(InstanceResetMethod method, Player* notifyPlayer); // -no description- //void SendInit(WorldSession* session); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 1bcf20acb93..60cdd99619c 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -595,7 +595,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge reviveAtTrigger = true; break; case Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE: - player->GetSession()->SendPacket(WorldPackets::AreaTrigger::AreaTriggerNoCorpse().Write()); + SendPacket(WorldPackets::AreaTrigger::AreaTriggerNoCorpse().Write()); TC_LOG_DEBUG("maps", "MAP: Player '%s' does not have a corpse in instance map %d and cannot enter", player->GetName().c_str(), at->target_mapId); break; case Map::CANNOT_ENTER_INSTANCE_BIND_MISMATCH: @@ -621,6 +621,11 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge player->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_ZONE_IN_COMBAT); reviveAtTrigger = true; break; + case Map::CANNOT_ENTER_INSTANCE_SHUTTING_DOWN: + player->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_NOT_FOUND); + TC_LOG_DEBUG("maps", "MAP: Player '%s' cannot enter instance map %d because instance is resetting.", player->GetName().c_str(), at->target_mapId); + reviveAtTrigger = true; + break; default: break; } @@ -880,13 +885,22 @@ void WorldSession::HandleSetTitleOpcode(WorldPackets::Character::SetTitle& packe void WorldSession::HandleResetInstancesOpcode(WorldPackets::Instance::ResetInstances& /*packet*/) { + Map* map = _player->FindMap(); + if (map && map->Instanceable()) + return; + if (Group* group = _player->GetGroup()) { - if (group->IsLeader(_player->GetGUID())) - group->ResetInstances(INSTANCE_RESET_ALL, false, false, _player); + if (!group->IsLeader(_player->GetGUID())) + return; + + if (group->isLFGGroup()) + return; + + group->ResetInstances(InstanceResetMethod::Manual, _player); } else - _player->ResetInstances(INSTANCE_RESET_ALL, false, false); + _player->ResetInstances(InstanceResetMethod::Manual); } void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPackets::Misc::SetDungeonDifficulty& setDungeonDifficulty) @@ -919,7 +933,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPackets::Misc::SetDunge // cannot reset while in an instance Map* map = _player->FindMap(); - if (map && map->IsDungeon()) + if (map && map->Instanceable()) { TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player (Name: %s, %s) tried to reset the instance while player is inside!", _player->GetName().c_str(), _player->GetGUID().ToString().c_str()); @@ -929,33 +943,19 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPackets::Misc::SetDunge Group* group = _player->GetGroup(); if (group) { - if (group->IsLeader(_player->GetGUID())) - { - for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) - { - Player* groupGuy = itr->GetSource(); - if (!groupGuy) - continue; + if (!group->IsLeader(_player->GetGUID())) + return; - if (!groupGuy->IsInWorld()) - return; + if (group->isLFGGroup()) + return; - if (groupGuy->GetMap()->IsNonRaidDungeon()) - { - TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player %s tried to reset the instance while group member (Name: %s, %s) is inside!", - _player->GetGUID().ToString().c_str(), groupGuy->GetName().c_str(), groupGuy->GetGUID().ToString().c_str()); - return; - } - } - // the difficulty is set even if the instances can't be reset - //_player->SendDungeonDifficulty(true); - group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, false, _player); - group->SetDungeonDifficultyID(difficultyID); - } + // the difficulty is set even if the instances can't be reset + group->ResetInstances(InstanceResetMethod::OnChangeDifficulty, _player); + group->SetDungeonDifficultyID(difficultyID); } else { - _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, false); + _player->ResetInstances(InstanceResetMethod::OnChangeDifficulty); _player->SetDungeonDifficultyID(difficultyID); _player->SendDungeonDifficulty(); } @@ -985,7 +985,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDiff return; } - if (((difficultyEntry->Flags & DIFFICULTY_FLAG_LEGACY) >> 5) != setRaidDifficulty.Legacy) + if (((difficultyEntry->Flags & DIFFICULTY_FLAG_LEGACY) != 0) != setRaidDifficulty.Legacy) { TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent not matching legacy difficulty %u!", _player->GetGUID().ToString().c_str(), difficultyEntry->ID); @@ -998,7 +998,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDiff // cannot reset while in an instance Map* map = _player->FindMap(); - if (map && map->IsDungeon()) + if (map && map->Instanceable()) { TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: player (Name: %s, %s) tried to reset the instance while player is inside!", _player->GetName().c_str(), _player->GetGUID().ToString().c_str()); @@ -1008,35 +1008,22 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDiff Group* group = _player->GetGroup(); if (group) { - if (group->IsLeader(_player->GetGUID())) - { - for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) - { - Player* groupGuy = itr->GetSource(); - if (!groupGuy) - continue; + if (!group->IsLeader(_player->GetGUID())) + return; - if (!groupGuy->IsInWorld()) - return; + if (group->isLFGGroup()) + return; - if (groupGuy->GetMap()->IsRaid()) - { - TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: player %s tried to reset the instance while group member (Name: %s, %s) is inside!", - _player->GetGUID().ToString().c_str(), groupGuy->GetName().c_str(), groupGuy->GetGUID().ToString().c_str()); - return; - } - } - // the difficulty is set even if the instances can't be reset - group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, setRaidDifficulty.Legacy != 0, _player); - if (setRaidDifficulty.Legacy) - group->SetLegacyRaidDifficultyID(difficultyID); - else - group->SetRaidDifficultyID(difficultyID); - } + // the difficulty is set even if the instances can't be reset + group->ResetInstances(InstanceResetMethod::OnChangeDifficulty, _player); + if (setRaidDifficulty.Legacy) + group->SetLegacyRaidDifficultyID(difficultyID); + else + group->SetRaidDifficultyID(difficultyID); } else { - _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, setRaidDifficulty.Legacy != 0); + _player->ResetInstances(InstanceResetMethod::OnChangeDifficulty); if (setRaidDifficulty.Legacy) _player->SetLegacyRaidDifficultyID(difficultyID); else diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c8540ac80e7..d2295ac58c9 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2769,7 +2769,7 @@ 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_resetAfterUnload(false), m_unloadWhenEmpty(false), + m_shuttingDown(false), i_data(nullptr), i_script_id(0), i_scenario(nullptr), i_instanceLock(instanceLock) { //lets initialize visibility distance for dungeons @@ -2808,6 +2808,9 @@ 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); @@ -2867,15 +2870,9 @@ bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/) } } - // for normal instances cancel the reset schedule when the - // first player enters (no players yet) - SetResetSchedule(false); - TC_LOG_DEBUG("maps", "MAP: Player '%s' entered instance '%u' of map '%s'", player->GetName().c_str(), GetInstanceId(), GetMapName()); // initialize unload state m_unloadTimer = 0; - m_resetAfterUnload = false; - m_unloadWhenEmpty = false; // this will acquire the same mutex so it cannot be in the previous block Map::AddPlayerToMap(player, initPlayer); @@ -2912,15 +2909,12 @@ void InstanceMap::RemovePlayerFromMap(Player* player, bool remove) // if last player set unload timer if (!m_unloadTimer && m_mapRefManager.getSize() == 1) - m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); + m_unloadTimer = m_shuttingDown ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); if (i_scenario) i_scenario->OnPlayerExit(player); Map::RemovePlayerFromMap(player, remove); - - // for normal instances schedule the reset after all players have left - SetResetSchedule(true); } void InstanceMap::CreateInstanceData() @@ -2966,47 +2960,45 @@ void InstanceMap::TrySetOwningGroup(Group* group) /* Returns true if there are no players in the instance */ -bool InstanceMap::Reset(InstanceResetMethod method) +InstanceResetResult InstanceMap::Reset(InstanceResetMethod method) { - // note: since the map may not be loaded when the instance needs to be reset - // the instance must be deleted from the DB + // raids can be reset if no boss was killed + if (method != InstanceResetMethod::Expire && i_instanceLock && i_instanceLock->GetData()->CompletedEncountersMask) + return InstanceResetResult::CannotReset; if (HavePlayers()) { - // on manual reset, fail - if (method == INSTANCE_RESET_ALL || method == INSTANCE_RESET_CHANGE_DIFFICULTY) - { - // notify the players to leave the instance so it can be reset - for (MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) - itr->GetSource()->SendResetFailedNotify(GetId()); - } - else + switch (method) { - // on lock expiration boot players (do we also care about extension state?) - if (method == INSTANCE_RESET_GLOBAL) - { + case InstanceResetMethod::Manual: + // notify the players to leave the instance so it can be reset + for (MapReference& ref : m_mapRefManager) + ref.GetSource()->SendResetFailedNotify(GetId()); + break; + case InstanceResetMethod::OnChangeDifficulty: + // 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) - for (MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) - itr->GetSource()->m_InstanceValid = false; - } + for (MapReference& ref : m_mapRefManager) + ref.GetSource()->m_InstanceValid = false; - if (!HasPermBoundPlayers()) - { - // the unload timer is not started - // instead the map will unload immediately after the players have left - m_unloadWhenEmpty = true; - m_resetAfterUnload = true; - } + m_shuttingDown = true; + break; + default: + break; } + + return InstanceResetResult::NotEmpty; } else { // unloaded at next update m_unloadTimer = MIN_UNLOAD_DELAY; - m_resetAfterUnload = !(method == INSTANCE_RESET_GLOBAL && HasPermBoundPlayers()); } - return m_mapRefManager.isEmpty(); + return InstanceResetResult::Success; } std::string const& InstanceMap::GetScriptName() const @@ -3128,23 +3120,6 @@ void InstanceMap::CreateInstanceLockForPlayer(Player* player) } } -void InstanceMap::UnloadAll() -{ - ASSERT(!HavePlayers()); - - if (m_resetAfterUnload) - { - DeleteRespawnTimes(); - DeleteCorpseData(); - } - - Map::UnloadAll(); -} - -void InstanceMap::SetResetSchedule(bool /*on*/) -{ -} - MapDifficultyEntry const* Map::GetMapDifficulty() const { return sDB2Manager.GetMapDifficultyData(GetId(), GetDifficultyID()); @@ -3231,13 +3206,6 @@ bool Map::GetEntrancePos(int32 &mapid, float &x, float &y) return i_mapEntry->GetEntrancePos(mapid, x, y); } -bool InstanceMap::HasPermBoundPlayers() const -{ - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PERM_BIND_BY_INSTANCE); - stmt->setUInt16(0,GetInstanceId()); - return !!CharacterDatabase.Query(stmt); -} - uint32 InstanceMap::GetMaxPlayers() const { MapDifficultyEntry const* mapDiff = GetMapDifficulty(); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 8f06fd77538..732fe9210d9 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -276,6 +276,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> CANNOT_ENTER_TOO_MANY_INSTANCES, // Player has entered too many instances recently CANNOT_ENTER_MAX_PLAYERS, // Target map already has the maximum number of players allowed CANNOT_ENTER_ZONE_IN_COMBAT, // A boss encounter is currently in progress on the target map + CANNOT_ENTER_INSTANCE_SHUTTING_DOWN, CANNOT_ENTER_UNSPECIFIED_REASON }; static EnterState PlayerCannotEnter(uint32 mapid, Player* player, bool loginCheck = false); @@ -787,14 +788,18 @@ class TC_GAME_API Map : public GridRefManager<NGridType> WorldStateValueContainer _worldStateValues; }; -enum InstanceResetMethod +enum class InstanceResetMethod : uint8 { - INSTANCE_RESET_ALL, - INSTANCE_RESET_CHANGE_DIFFICULTY, - INSTANCE_RESET_GLOBAL, - INSTANCE_RESET_GROUP_DISBAND, - INSTANCE_RESET_GROUP_JOIN, - INSTANCE_RESET_RESPAWN_DELAY + Manual, + OnChangeDifficulty, + Expire +}; + +enum class InstanceResetResult : uint8 +{ + Success, + NotEmpty, + CannotReset }; class TC_GAME_API InstanceMap : public Map @@ -806,7 +811,7 @@ class TC_GAME_API InstanceMap : public Map void RemovePlayerFromMap(Player*, bool) override; void Update(uint32) override; void CreateInstanceData(); - bool Reset(InstanceResetMethod method); + InstanceResetResult Reset(InstanceResetMethod method); uint32 GetScriptId() const { return i_script_id; } std::string const& GetScriptName() const; InstanceScript* GetInstanceScript() { return i_data; } @@ -818,13 +823,8 @@ class TC_GAME_API InstanceMap : public Map void UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateSaveDataEvent); void UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& updateSaveDataEvent); void CreateInstanceLockForPlayer(Player* player); - void UnloadAll() override; EnterState CannotEnter(Player* player) override; - void SetResetSchedule(bool on); - /* this checks if any players have a permanent bind (included reactivatable expired binds) to the instance ID - it needs a DB query, so use sparingly */ - bool HasPermBoundPlayers() const; uint32 GetMaxPlayers() const; TeamId GetTeamIdInInstance() const; Team GetTeamInInstance() const { return GetTeamIdInInstance() == TEAM_ALLIANCE ? ALLIANCE : HORDE; } @@ -836,8 +836,7 @@ class TC_GAME_API InstanceMap : public Map std::string GetDebugInfo() const override; private: - bool m_resetAfterUnload; - bool m_unloadWhenEmpty; + bool m_shuttingDown; InstanceScript* i_data; uint32 i_script_id; InstanceScenario* i_scenario; diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 788d27301a4..5254559785e 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -335,8 +335,8 @@ bool MapManager::DestroyMap(Map* map) map->UnloadAll(); - // Free up the instance id and allow it to be reused for bgs and arenas (other instances are handled in the InstanceSaveMgr) - if (map->IsBattlegroundOrArena()) + // Free up the instance id and allow it to be reused for normal dungeons, bgs and arenas + if (map->IsBattlegroundOrArena() || (map->IsDungeon() && !map->GetMapDifficulty()->HasResetSchedule())) sMapMgr->FreeInstanceId(map->GetInstanceId()); // erase map |