public Map CreateInstanceForPlayer(uint mapId, Player player, uint loginInstanceId = 0) { if (GetId() != mapId || player == null) { return(null); } Map map; uint newInstanceId; // 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 == 0) { return(null); } map = Global.MapMgr.FindMap(mapId, newInstanceId); if (map == null) { Battleground bg = player.GetBattleground(); if (bg) { map = CreateBattleground(newInstanceId, bg); } else { player.TeleportToBGEntryPoint(); return(null); } } } else if (!IsGarrison()) { InstanceBind pBind = player.GetBoundInstance(GetId(), player.GetDifficultyID(GetEntry())); InstanceSave pSave = pBind != null ? pBind.save : null; // priority: // 1. player's permanent bind // 2. player's current instance id if this is at login // 3. group's current bind // 4. player's current bind if (pBind == null || !pBind.perm) { if (loginInstanceId != 0) // if the player has a saved instance id on login, we either use this instance or relocate him out (return null) { map = FindInstanceMap(loginInstanceId); if (map == null && pSave != null && pSave.GetInstanceId() == loginInstanceId) { map = CreateInstance(loginInstanceId, pSave, pSave.GetDifficultyID(), player.GetTeamId()); } return(map); } InstanceBind groupBind; 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 != null) { // solo saves should be reset when entering a group's instance player.UnbindInstance(GetId(), player.GetDifficultyID(GetEntry())); pSave = groupBind.save; } } } if (pSave != null) { // solo/perm/group newInstanceId = pSave.GetInstanceId(); map = FindInstanceMap(newInstanceId); // it is possible that the save exists but the map doesn't if (map == null) { map = CreateInstance(newInstanceId, pSave, pSave.GetDifficultyID(), player.GetTeamId()); } } else { // if no instanceId via group members or instance saves is found // the instance will be created for the first time newInstanceId = Global.MapMgr.GenerateInstanceId(); Difficulty diff = player.GetGroup() != null?player.GetGroup().GetDifficultyID(GetEntry()) : player.GetDifficultyID(GetEntry()); //Seems it is now possible, but I do not know if it should be allowed map = FindInstanceMap(newInstanceId); if (map == null) { map = CreateInstance(newInstanceId, null, diff, player.GetTeamId()); } } } else { newInstanceId = (uint)player.GetGUID().GetCounter(); map = FindInstanceMap(newInstanceId); if (!map) { map = CreateGarrison(newInstanceId, player); } } return(map); }
public InstanceSave AddInstanceSave(uint mapId, uint instanceId, Difficulty difficulty, long resetTime, uint entranceId, bool canReset, bool load = false) { InstanceSave old_save = GetInstanceSave(instanceId); if (old_save != null) { return(old_save); } MapRecord entry = CliDB.MapStorage.LookupByKey(mapId); if (entry == null) { Log.outError(LogFilter.Server, "InstanceSaveManager.AddInstanceSave: wrong mapid = {0}, instanceid = {1}!", mapId, instanceId); return(null); } if (instanceId == 0) { Log.outError(LogFilter.Server, "InstanceSaveManager.AddInstanceSave: mapid = {0}, wrong instanceid = {1}!", mapId, instanceId); return(null); } DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(difficulty); if (difficultyEntry == null || difficultyEntry.InstanceType != entry.InstanceType) { Log.outError(LogFilter.Server, "InstanceSaveManager.AddInstanceSave: mapid = {0}, instanceid = {1}, wrong dificalty {2}!", mapId, instanceId, difficulty); return(null); } if (entranceId != 0 && Global.ObjectMgr.GetWorldSafeLoc(entranceId) == null) { Log.outWarn(LogFilter.Misc, "InstanceSaveManager.AddInstanceSave: invalid entranceId = {0} defined for instance save with mapid = {1}, instanceid = {2}!", entranceId, mapId, instanceId); entranceId = 0; } if (resetTime == 0) { // initialize reset time // for normal instances if no creatures are killed the instance will reset in two hours if (entry.InstanceType == MapTypes.Raid || difficulty > Difficulty.Normal) { resetTime = GetResetTimeFor(mapId, difficulty); } else { resetTime = GameTime.GetGameTime() + 2 * Time.Hour; // normally this will be removed soon after in InstanceMap.Add, prevent error ScheduleReset(true, resetTime, new InstResetEvent(0, mapId, difficulty, instanceId)); } } Log.outDebug(LogFilter.Maps, "InstanceSaveManager.AddInstanceSave: mapid = {0}, instanceid = {1}", mapId, instanceId); InstanceSave save = new(mapId, instanceId, difficulty, entranceId, resetTime, canReset); if (!load) { save.SaveToDB(); } m_instanceSaveById[instanceId] = save; return(save); }