/// returns a new or existing Instance /// in case of battlegrounds it will only return an existing map, those maps are created by bg-system Map* MapInstanced::CreateInstance(Player * player) { Map* map; uint32 NewInstanceId; // instanceId of the resulting map if(IsBattleGroundOrArena()) { // find existing bg map for player NewInstanceId = player->GetBattleGroundId(); MANGOS_ASSERT(NewInstanceId); map = _FindMap(NewInstanceId); MANGOS_ASSERT(map); } else if (InstanceSave* pSave = player->GetBoundInstanceSaveForSelfOrGroup(GetId())) { // solo/perm/group NewInstanceId = pSave->GetInstanceId(); map = _FindMap(NewInstanceId); // it is possible that the save exists but the map doesn't if (!map) map = CreateInstanceMap(NewInstanceId, pSave->GetDifficulty(), pSave); } else { // if no instanceId via group members or instance saves is found // the instance will be created for the first time NewInstanceId = sObjectMgr.GenerateLowGuid(HIGHGUID_INSTANCE); Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid()); map = CreateInstanceMap(NewInstanceId, diff); } return map; }
/* - return the right instance for the object, based on its InstanceId - create the instance if it's not created already - the player is not actually added to the instance (only in InstanceMap::Add) */ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) { if (GetId() != mapId || !player) return NULL; Map* map = NULL; uint32 NewInstanceId = 0; // instanceId of the resulting map if (IsBattleGroundOrArena()) { // instantiate or find existing bg map for player // the instance id is set in battlegroundid NewInstanceId = player->GetBattleGroundId(); if (!NewInstanceId) return NULL; map = _FindMap(NewInstanceId); if (!map) map = CreateBattleGround(NewInstanceId, player->GetBattleGround()); } else { InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty()); InstanceSave *pSave = pBind ? pBind->save : NULL; // the player's permanent 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(this); if (groupBind) 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()); } else { // if no instanceId via group members or instance saves is found // the instance will be created for the first time NewInstanceId = MapManager::Instance().GenerateInstanceId(); map = CreateInstance(NewInstanceId, NULL, player->GetDifficulty()); } } return map; }
/* - return the right instance for the object, based on its InstanceId - create the instance if it's not created already - the player is not actually added to the instance (only in InstanceMap::Add) */ Map* MapInstanced::GetInstance(const WorldObject* obj) { uint32 CurInstanceId = obj->GetInstanceId(); Map* map = NULL; if (obj->GetMapId() == GetId() && CurInstanceId != 0) { // 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); } else { // instance not specified, find an existing or create a new one if(obj->GetTypeId() != TYPEID_PLAYER) { 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; } else { 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); ((BattleGroundMap*)map)->SetBG(player->GetBattleGround()); } if(!((BattleGroundMap*)map)->GetBG()) { sLog.outError("The bg-class couldn't be assigned (very early) to the battlegroundmap, it's possible, that some db-spawned creatures are now not handled right this is related to battleground alterac valley (av) - please post bugreport, and add information how this bg was created (if you don't have information, report it also) Player: %s (%u) in map:%u requested map:%u", player->GetName(), player->GetGUIDLow(), player->GetMapId(), GetId()); if(player->GetBattleGround()) { sLog.outError("somehow the battleground was found, but please report also - i end this bg now.."); ((BattleGroundMap*)map)->SetBG(player->GetBattleGround()); player->GetBattleGround()->EndBattleGround(0); //to avoid the assert } //assert(false); } 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()); return map; } else { // 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()); } } } }