*Fix the bug that players get stuck after teleported out of bg.

*Do not delete the map immediately until all players are teleported.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-08-06 16:14:13 -05:00
parent 50c73d433c
commit befbae3a61
6 changed files with 40 additions and 35 deletions

View File

@@ -1196,6 +1196,21 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
return true;
}
void Map::RemoveAllPlayers()
{
if(HavePlayers())
{
sLog.outError("Map::UnloadAll: there are still players in the instance at unload, should not happen!");
for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
{
Player* plr = itr->getSource();
if(!plr->IsBeingTeleportedFar())
plr->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation());
}
}
}
void Map::UnloadAll()
{
// clear all delayed moves, useless anyway do this moves before map unload.
@@ -2642,12 +2657,7 @@ void InstanceMap::PermBindAllPlayers(Player *player)
void InstanceMap::UnloadAll()
{
while(HavePlayers())
{
sLog.outError("InstanceMap::UnloadAll: there are still players in the instance at unload, should not happen!");
Player *plr = m_mapRefManager.getFirst()->getSource();
plr->TeleportOutOfMap(this);
}
assert(!HavePlayers());
if(m_resetAfterUnload == true)
objmgr.DeleteRespawnTimeForInstance(GetInstanceId());
@@ -2734,16 +2744,17 @@ void BattleGroundMap::SetUnload()
m_unloadTimer = MIN_UNLOAD_DELAY;
}
void BattleGroundMap::UnloadAll()
void BattleGroundMap::RemoveAllPlayers()
{
while(HavePlayers())
if(HavePlayers())
{
Player *plr = m_mapRefManager.getFirst()->getSource();
plr->TeleportTo(plr->GetBattleGroundEntryPoint());
plr->TeleportOutOfMap(this);
for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
{
Player* plr = itr->getSource();
if(!plr->IsBeingTeleportedFar())
plr->TeleportTo(plr->GetBattleGroundEntryPoint());
}
}
Map::UnloadAll();
}
/// Put scripts in the execution queue

View File

@@ -355,6 +355,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
virtual void MoveAllCreaturesInMoveList();
virtual void RemoveAllObjectsInRemoveList();
virtual void RelocationNotify();
virtual void RemoveAllPlayers();
bool CreatureRespawnRelocation(Creature *c); // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader
@@ -610,7 +611,7 @@ class TRINITY_DLL_SPEC BattleGroundMap : public Map
void Remove(Player *, bool);
bool CanEnter(Player* player);
void SetUnload();
void UnloadAll();
void RemoveAllPlayers();
};
/*inline

View File

@@ -46,7 +46,10 @@ void MapInstanced::Update(const uint32& t)
{
if(i->second->CanUnload(t))
{
DestroyInstance(i); // iterator incremented
if(!DestroyInstance(i)) // iterator incremented
{
//m_unloadTimer
}
}
else
{
@@ -203,16 +206,16 @@ BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId)
return map;
}
void MapInstanced::DestroyInstance(uint32 InstanceId)
{
InstancedMaps::iterator itr = m_InstancedMaps.find(InstanceId);
if(itr != m_InstancedMaps.end())
DestroyInstance(itr);
}
// increments the iterator after erase
void MapInstanced::DestroyInstance(InstancedMaps::iterator &itr)
bool MapInstanced::DestroyInstance(InstancedMaps::iterator &itr)
{
itr->second->RemoveAllPlayers();
if(itr->second->HavePlayers())
{
++itr;
return false;
}
itr->second->UnloadAll();
// should only unload VMaps if this is the last instance and grid unloading is enabled
if(m_InstancedMaps.size() <= 1 && sWorld.getConfig(CONFIG_GRID_UNLOAD))
@@ -225,6 +228,7 @@ void MapInstanced::DestroyInstance(InstancedMaps::iterator &itr)
// erase map
delete itr->second;
m_InstancedMaps.erase(itr++);
return true;
}
bool MapInstanced::CanEnter(Player *player)

View File

@@ -44,8 +44,7 @@ class TRINITY_DLL_DECL MapInstanced : public Map
Map* CreateInstance(const uint32 mapId, Player * player, uint32 instanceId);
Map* FindMap(uint32 InstanceId) const { return _FindMap(InstanceId); }
void DestroyInstance(uint32 InstanceId);
void DestroyInstance(InstancedMaps::iterator &itr);
bool DestroyInstance(InstancedMaps::iterator &itr);
void AddGridMapReference(const GridPair &p)
{

View File

@@ -234,13 +234,6 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
return true;
}
void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId)
{
Map *m = _createBaseMap(mapid);
if (m && m->Instanceable())
((MapInstanced*)m)->DestroyInstance(instanceId);
}
void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y)
{
bool remove_result = _createBaseMap(mapid)->RemoveBones(guid, x, y);

View File

@@ -43,9 +43,6 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
Map const* CreateBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_createBaseMap(id); }
Map* FindMap(uint32 mapid, uint32 instanceId = 0) const;
// only const version for outer users
void DeleteInstance(uint32 mapid, uint32 instanceId);
uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const
{
Map const* m = CreateBaseMap(mapid);