/// <inheritdoc /> public void RemovePlayer(int characterId) { Character player; if (Players.TryRemove(characterId, out player)) { _logger.LogDebug($"Player {characterId} left game world"); TradeManagers.TryRemove(characterId, out var tradeManager); tradeManager.Dispose(); PartyManagers.TryRemove(characterId, out var partyManager); partyManager.Dispose(); DuelManagers.TryRemove(characterId, out var duelManager); duelManager.Dispose(); player.Client.OnPacketArrived -= Client_OnPacketArrived; IMap map = null; // Try find player's map. if (Maps.ContainsKey(player.MapId)) { map = Maps[player.MapId]; } else if (player.Party != null && PartyMaps.ContainsKey(player.Party.Id)) { map = PartyMaps[player.Party.Id]; } else if (PartyMaps.ContainsKey(player.PreviousPartyId)) { map = PartyMaps[player.PreviousPartyId]; } if (map is null) { _logger.LogError($"Couldn't find character's {characterId} map {player.MapId}."); } else { map.UnloadPlayer(player); } player.Dispose(); } else { // 0 means, that connection with client was lost, when he was in character selection screen. if (characterId != 0) { _logger.LogError($"Couldn't remove player {characterId} from game world"); } } }
/// <inheritdoc /> public void LoadPlayerInMap(int characterId) { var player = Players[characterId]; if (Maps.ContainsKey(player.MapId)) { Maps[player.MapId].LoadPlayer(player); } else { var mapDef = _mapDefinitions.Maps.FirstOrDefault(d => d.Id == player.MapId); // Map is not found. if (mapDef is null) { _logger.LogWarning($"Unknown map {player.MapId} for character {player.Id}. Fallback to 0 map."); var town = Maps[0].GetNearestSpawn(player.PosX, player.PosY, player.PosZ, player.Country); player.Teleport(0, town.X, town.Y, town.Z); return; } if (mapDef.CreateType == CreateType.Party) { IPartyMap map; Guid partyId; if (player.Party is null) // This is very uncommon, but if: // * player is an admin he can load into map even without party. // * player entered portal, while being in party, but while he was loading, all party members left. { partyId = player.PreviousPartyId; } else { partyId = player.Party.Id; } PartyMaps.TryGetValue(partyId, out map); if (map is null) { map = _mapFactory.CreatePartyMap(mapDef.Id, mapDef, _mapsLoader.LoadMapConfiguration(mapDef.Id), player.Party); map.OnAllMembersLeft += PartyMap_OnAllMembersLeft; PartyMaps.TryAdd(partyId, map); } map.LoadPlayer(player); } } }