diff options
Diffstat (limited to 'src/game/MapInstanced.cpp')
-rw-r--r-- | src/game/MapInstanced.cpp | 139 |
1 files changed, 59 insertions, 80 deletions
diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index fcdc2f76c11..ca106d6506c 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -1,7 +1,7 @@ /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -77,6 +77,12 @@ void MapInstanced::RemoveAllObjectsInRemoveList() Map::RemoveAllObjectsInRemoveList(); } +void MapInstanced::RelocationNotify() +{ + for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i) + i->second->RelocationNotify(); +} + bool MapInstanced::RemoveBones(uint64 guid, float x, float y) { bool remove_result = false; @@ -112,93 +118,66 @@ void MapInstanced::UnloadAll() */ Map* MapInstanced::GetInstance(const WorldObject* obj) { - uint32 CurInstanceId = obj->GetInstanceId(); - Map* map = NULL; - - if (obj->GetMapId() == GetId() && CurInstanceId != 0) + if(obj->GetTypeId() == TYPEID_UNIT) { - // the object wants to be put in a certain instance of this map - map = _FindMap(CurInstanceId); - if(!map) - { - // For players if the instanceId is set, it's assumed they are already in a map, - // hence the map must be loaded. For Creatures, GameObjects etc the map must exist - // prior to calling GetMap, they are not allowed to create maps for themselves. - sLog.outError("GetInstance: object %s(%d), typeId %d, in world %d, should be in map %d,%d but that's not loaded yet.", obj->GetName(), obj->GetGUIDLow(), obj->GetTypeId(), obj->IsInWorld(), obj->GetMapId(), obj->GetInstanceId()); - assert(false); - } - return(map); + assert(obj->GetMapId() == GetId() && obj->GetInstanceId()); + return _FindMap(obj->GetInstanceId()); } - else + + Player* player = (Player*)obj; + uint32 instanceId = player->GetInstanceId(); + + if(instanceId) + if(Map *map = _FindMap(instanceId)) + return map; + + if(IsBattleGroundOrArena()) { - // instance not specified, find an existing or create a new one - if(obj->GetTypeId() != TYPEID_PLAYER) + instanceId = player->GetBattleGroundId(); + + if(instanceId) { - sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u TypeID: %u) is in map %d,%d and requested base map instance of map %d, this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), obj->GetMapId(), obj->GetInstanceId(), GetId()); - assert(false); - return NULL; + if(Map *map = _FindMap(instanceId)) + return map; + else + return CreateBattleGround(instanceId); } else + return NULL; + } + + InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty()); + InstanceSave *pSave = pBind ? pBind->save : NULL; + if(!pBind || !pBind->perm) + { + if(Group *group = player->GetGroup()) + if(InstanceGroupBind *groupBind = group->GetBoundInstance(GetId(), player->GetDifficulty())) + pSave = groupBind->save; + } + + if(pSave) + { + if(!instanceId) { - uint32 NewInstanceId = 0; // instanceId of the resulting map - Player* player = (Player*)obj; - - if(IsBattleGroundOrArena()) - { - // instantiate or find existing bg map for player - // the instance id is set in battlegroundid - NewInstanceId = player->GetBattleGroundId(); - if(!NewInstanceId) - { - if(player->GetSession()->PlayerLoading()) - return NULL; - else - assert(NewInstanceId); - } - map = _FindMap(NewInstanceId); - if(!map) - map = CreateBattleGround(NewInstanceId); - return map; - } - - InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty()); - InstanceSave *pSave = pBind ? pBind->save : NULL; - - // the player's permanet player bind is taken into consideration first - // then the player's group bind and finally the solo bind. - if(!pBind || !pBind->perm) - { - InstanceGroupBind *groupBind = NULL; - Group *group = player->GetGroup(); - // use the player's difficulty setting (it may not be the same as the group's) - if(group && (groupBind = group->GetBoundInstance(GetId(), player->GetDifficulty()))) - pSave = groupBind->save; - } - - if(pSave) - { - // solo/perm/group - NewInstanceId = pSave->GetInstanceId(); - map = _FindMap(NewInstanceId); - // it is possible that the save exists but the map doesn't - if(!map) - map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty()); + instanceId = pSave->GetInstanceId(); // go from outside to instance + if(Map *map = _FindMap(instanceId)) return map; - } - else if(!player->GetSession()->PlayerLoading()) - { - // if no instanceId via group members or instance saves is found - // the instance will be created for the first time - NewInstanceId = MapManager::Instance().GenerateInstanceId(); - return CreateInstance(NewInstanceId, NULL, player->GetDifficulty()); - } - else - { - sLog.outError("MAPINSTANCED: Player %s is trying to create instance (MapId %u) when login.", player->GetName(), player->GetMapId()); - return NULL; - } } + else if(instanceId != pSave->GetInstanceId()) // cannot go from one instance to another + return NULL; + // else log in at a saved instance + + return CreateInstance(instanceId, pSave, pSave->GetDifficulty()); } + else if(!player->GetSession()->PlayerLoading()) + { + if(!instanceId) + instanceId = MapManager::Instance().GenerateInstanceId(); + + return CreateInstance(instanceId, NULL, player->GetDifficulty()); + } + + return NULL; } InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty) @@ -221,7 +200,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, } // some instances only have one difficulty - if(!entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + if (entry && !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; sLog.outDebug("MapInstanced::CreateInstance: %smap instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal"); |