aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Maps/Map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Maps/Map.cpp')
-rw-r--r--src/server/game/Maps/Map.cpp90
1 files changed, 29 insertions, 61 deletions
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();