public List <WorldPlaceDataDetails> GetWorldPlaceDataDetails() { List <WorldPlaceDataDetails> resultList = new List <WorldPlaceDataDetails>(); WorldPlaceData placeData; for (int y = 0; y < this.MapHeight; y++) { for (int x = 0; x < this.MapWidth; x++) { placeData = _worldPlaces[x, y]; if (placeData == null) { continue; } WorldPlaceDataDetails result = new WorldPlaceDataDetails() { WorldPosX = placeData.WorldPosX, WorldPosY = placeData.WorldPosY, WmId = placeData.WmId, PlaceType = (int)placeData.Type, PlaceName = placeData.PlaceName }; resultList.Add(result); } } return(resultList); }
public WorldDetailsCmdBuilder(bool isListConfirmation, WorldPlaceDataDetails details = null) { if (!isListConfirmation && details == null) { throw new Exception("WorldDetailsCmdBuilder - detail object cannot be NULL for no list confirmation!"); } _details = details; _isListConfirmation = isListConfirmation; }
public void AddOrUpdateWorldPlaceDetails(WorldPlaceDataDetails details) { bool found = false; lock (_dataLock) { for (int i = 0; i < _worldPlaceDetailsList.Count; i++) { if (_worldPlaceDetailsList[i].WmId == details.WmId) { _worldPlaceDetailsList[i] = details; found = true; break; } } if (!found) { _worldPlaceDetailsList.Add(details); } } }
public bool Execute() { bool executed = false; try { if (_cmdElements.Length < 2) { throw new Exception("wrong count of elements"); } if (_cmdElements[1].Equals("position", GlobalData.InputDataStringComparison)) { string jsonTxt = _rawText.Substring($"{_keyWord} position".Length); WorldPlaceDataDetails details = JsonConvert.DeserializeObject <WorldPlaceDataDetails>(jsonTxt); _gameStateDetails.AddOrUpdateWorldPlaceDetails(details); } else if (_cmdElements[1].Equals("endlist", GlobalData.InputDataStringComparison)) { _gameStateDetails.WorldPlaceDetailsListConfirmed = true; } else { throw new Exception($"wrong second keyword [{_cmdElements[1]}]"); } executed = true; } catch (Exception exception) { _chat.UpdateLog($"Cannot execute world place details command: {exception.Message}"); } return(executed); }
public SandWmSectionBuilder(WorldPlaceDataDetails details, Camera camera) { _details = details; _camera = camera; }
private async void HandleCharactersMovementAsync() { if (_movementHandlingInProgress) { _logger.UpdateLog("Character movement handling already started!"); return; } _movementHandlingInProgress = true; _logger.UpdateLog("Game state handler - character movement handling started!"); try { List <CharacterMovementDetails> movementDetailsListTemp = new List <CharacterMovementDetails>(); CharacterData characterData; List <GeoDataElement> geoDataList = new List <GeoDataElement>(); CharacterPositionUpdateDetails positionDetailsToSend = null; int count = 0; int wmId; int parentObjectId; bool isOnWorldMap; GeoDataValidationDetails geoDataValidationDetails = null; bool geoMovementValid = false; Point3 <double> lastValidMovementPoint = new Point3 <double>(0, 0, 0); bool exitPointFound = false; Point3 <double> exitPosition = null; double lastTParamValue = 0; int timeArrivalMsIncomplete = 0; bool worldMovingValid = false; do { #region Main list item removal //MAIN LIST ITEM REMOVAL lock (_movementDetailsLock) { count = _movementDetailsList.Count; if (count > 0) { movementDetailsListTemp = _movementDetailsList.Clone(); foreach (CharacterMovementDetails item in _movementDetailsList) { item.Dispose(); } _movementDetailsList.Clear(); } } #endregion #region Interval handling //INTERVAL HANDLING if (count == 0) { await Task.Factory.StartNew(() => Thread.Sleep(GameStateHandler._movementHandlingTickMs)); continue; } #endregion #region Movement details handling //MOV. DETAILS HANDLING foreach (CharacterMovementDetails movementDetails in movementDetailsListTemp) { if (geoDataList.Count > 0) { geoDataList.Clear(); } if (movementDetails.CharId < 0) { _logger.UpdateLog("Movement details handling warning - character's ID less than 0!"); continue; } //characterData = await _characterInfo.GetCharacterByNameTaskStart(movementDetails.CharName); characterData = await _characterInfo.GetCharacterByIdTaskStart(movementDetails.CharId); if (characterData == null) { _logger.UpdateLog($"Movement details handling warning - character's ID [{movementDetails.CharId}] not found!"); continue; } wmId = characterData.WmId; parentObjectId = characterData.ParentObjectId; isOnWorldMap = characterData.IsOnWorldMap; switch (movementDetails.Type) { case CharacterMovementDetails.MovementType.SwitchMovementType: { #region Local enter/exit point veryfication //LOCAL ENTER/EXIT POINT VERYFICATION exitPointFound = false; if (characterData.IsOnWorldMap) { using (BoxedData geoBoxedData = await _geoDataInfo.GetLocalGeoDataOfExitElementsTaskStart(wmId, parentObjectId)) { geoDataList = (List <GeoDataElement>)geoBoxedData.Data; if (!String.IsNullOrEmpty(geoBoxedData.Msg)) { _logger.UpdateLog(geoBoxedData.Msg); } } exitPosition = GeoDataValidator.GetRandomExitPosition(geoDataList); if (exitPosition != null) { exitPointFound = true; //PLACING CHARACTER ON ENTRY POINT characterData.MoveCharacterLocal ( exitPosition.Copy(), exitPosition.Copy(), 0 ); } } #endregion #region State change section //STATE CHANGE SECTION if (!exitPointFound && characterData.IsOnWorldMap) { _logger.UpdateLog($"Cannot find location exit point for character's ID [{movementDetails.CharId}] wm_id [{wmId}] parent object ID [{parentObjectId}]"); SendMessageToPlayer(movementDetails.CharId, "Error: cannot find entry point!"); } else { characterData.IsOnWorldMap = !isOnWorldMap; _logger.UpdateLog($"Movement type switched for character's ID [{movementDetails.CharId}] to {(characterData.IsOnWorldMap ? "world" : "local")} state"); positionDetailsToSend = new CharacterPositionUpdateDetails() { MovementType = (characterData.IsOnWorldMap ? "switchmap" : "switchlocal"), CharId = movementDetails.CharId, OldLocationLocal = characterData.CurrentLoc.Copy(), NewLocationLocal = characterData.CurrentLoc.Copy(), TimeArrivalMsLocal = 0, OldLocationWorld = characterData.CurrentWorldLoc.Copy(), NewLocationWorld = characterData.CurrentWorldLoc.Copy() }; if (characterData.IsOnWorldMap) { SendMovementDetailsToCurrentPlayerAsync(positionDetailsToSend, movementDetails.CharId); } SendMovementDetailsToPlayersInLocationAsync(positionDetailsToSend, wmId, false, parentObjectId); } #endregion } break; case CharacterMovementDetails.MovementType.Local: { #region Local movement handling //LOCAL MOVEMENT HANDLING if (isOnWorldMap) { _logger.UpdateLog($"Movement details handling warning - local movement cancelled for character's ID [{movementDetails.CharId}], reason: world map state"); } else { #region Geo data validation //GEO DATA VALIDATION using ( BoxedData geoBoxedData = await _geoDataInfo.GetLocalGeoDataTaskStart ( wmId, parentObjectId, PointConverter.Point3DoubleToInt(movementDetails.OldLocationLocal), PointConverter.Point3DoubleToInt(movementDetails.NewLocationLocal) ) ) { geoDataList = (List <GeoDataElement>)geoBoxedData.Data; if (!String.IsNullOrEmpty(geoBoxedData.Msg)) { _logger.UpdateLog(geoBoxedData.Msg); } } using (BoxedData geoValidationBoxedData = await GeoDataValidator.ValidateMovementTaskStart(geoDataList, movementDetails)) { geoDataValidationDetails = (GeoDataValidationDetails)geoValidationBoxedData.Data; if (!String.IsNullOrEmpty(geoValidationBoxedData.Msg)) { _logger.UpdateLog(geoValidationBoxedData.Msg); } geoMovementValid = geoDataValidationDetails.Valid; lastValidMovementPoint = geoDataValidationDetails.LastValidMovementPoint; lastTParamValue = geoDataValidationDetails.LastTParamValue; geoDataValidationDetails.Dispose(); geoDataValidationDetails = null; } #endregion //_logger.UpdateLog($"GEO VALID [{geoMovementValid}]"); //geoMovementValid = true; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //CHARACTER MOVING if (geoMovementValid) { characterData.MoveCharacterLocal ( movementDetails.OldLocationLocal.Copy(), movementDetails.NewLocationLocal.Copy(), movementDetails.TimeArrivalMsLocal ); positionDetailsToSend = new CharacterPositionUpdateDetails() { MovementType = "movelocal", CharId = movementDetails.CharId, OldLocationLocal = movementDetails.OldLocationLocal.Copy(), NewLocationLocal = movementDetails.NewLocationLocal.Copy(), TimeArrivalMsLocal = movementDetails.TimeArrivalMsLocal, OldLocationWorld = new Point2 <int>(0, 0), NewLocationWorld = new Point2 <int>(0, 0) }; SendMovementDetailsToPlayersInLocationAsync(positionDetailsToSend, wmId, isOnWorldMap, parentObjectId); } else { timeArrivalMsIncomplete = Convert.ToInt32(Convert.ToDouble(movementDetails.TimeArrivalMsLocal) * lastTParamValue); characterData.MoveCharacterLocal ( movementDetails.OldLocationLocal.Copy(), lastValidMovementPoint.Copy(), timeArrivalMsIncomplete ); positionDetailsToSend = new CharacterPositionUpdateDetails() { MovementType = "movelocal", CharId = movementDetails.CharId, OldLocationLocal = movementDetails.OldLocationLocal.Copy(), NewLocationLocal = lastValidMovementPoint.Copy(), TimeArrivalMsLocal = timeArrivalMsIncomplete, OldLocationWorld = new Point2 <int>(0, 0), NewLocationWorld = new Point2 <int>(0, 0) }; SendMovementDetailsToPlayersInLocationAsync(positionDetailsToSend, wmId, isOnWorldMap, parentObjectId); } } #endregion } break; case CharacterMovementDetails.MovementType.World: { #region World map movement handling //WORLD MAP MOVEMENT HANDLING if (!isOnWorldMap) { _logger.UpdateLog($"Movement details handling warning - world map movement cancelled for character's ID [{movementDetails.CharId}], reason: local movement state"); } else { Point2 <int> oldLocWorld = movementDetails.OldLocationWorld.Copy(); Point2 <int> newLocWorld = movementDetails.NewLocationWorld.Copy(); //WORLD MOVEMENT VALIDATION worldMovingValid = true; int distanceX = Math.Abs(oldLocWorld.X - newLocWorld.X); int distanceY = Math.Abs(oldLocWorld.Y - newLocWorld.Y); if ( oldLocWorld.X != characterData.CurrentWorldLoc.X || oldLocWorld.Y != characterData.CurrentWorldLoc.Y || distanceX > 2 || distanceY > 2 ) { worldMovingValid = false; //_logger.UpdateLog($"Movement details handling warning - world map movement cancelled for character's ID [{movementDetails.CharId}]"); } //CHARACTER MOVING if (worldMovingValid) { WorldPlaceDataDetails worldPlaceDetails = _geoDataInfo.GetWorldPlaceDataDetails(newLocWorld.X, newLocWorld.Y); int newWmId = (worldPlaceDetails != null ? worldPlaceDetails.WmId : -1); characterData.MoveCharacterWorld(newLocWorld); positionDetailsToSend = new CharacterPositionUpdateDetails() { MovementType = "moveworld", CharId = movementDetails.CharId, OldLocationLocal = new Point3 <double>(0, 0, 0), NewLocationLocal = new Point3 <double>(0, 0, 0), TimeArrivalMsLocal = 0, OldLocationWorld = oldLocWorld, NewLocationWorld = newLocWorld }; SendMovementDetailsToPlayersInLocationAsync(positionDetailsToSend, wmId, isOnWorldMap, parentObjectId); ChangeWmIdAsync(characterData, newWmId); } else { SendMessageToPlayer(movementDetails.CharId, "You're moving too far"); } } #endregion } break; default: throw new Exception($"unknown movement type [{movementDetails.Type.ToString()}]!"); } } #endregion #region Temp. list disposal //TEMP. LIST DISPOSAL foreach (CharacterMovementDetails item in movementDetailsListTemp) { item.Dispose(); } movementDetailsListTemp.Clear(); #endregion }while (_movementHandlingInProgress); } catch (Exception exception) { _logger.UpdateLog($"Character movement handling error: {exception.Message}"); } finally { _movementHandlingInProgress = false; _logger.UpdateLog("Game state handler - character movement handling stopped!"); } }
private void ReloadScene() { try { DestroyCurrentWorldMapSectionObjects(); SetPlayerPosition(_gameStateDetails.Position.x, _gameStateDetails.Position.y); int mapWidth = _gameStateDetails.MapWidth; int mapHeight = _gameStateDetails.MapHeight; List <WorldPlaceDataDetails> worldPlaceDetailsList = _gameStateDetails.GetWorldPlaceDataDetails(); _worldMapSectionObjects = new GameObject[mapWidth, mapHeight]; GameObject createdMapSection = null; int worldPosX; int worldPosY; foreach (WorldPlaceDataDetails details in worldPlaceDetailsList) { //BUILDING SECTIONS BASED ON SERVER INSTANCES worldPosX = details.WorldPosX; worldPosY = details.WorldPosY; if (worldPosX >= mapWidth || worldPosY >= mapHeight) { _chat.UpdateLog($"World map - ReloadScene() - WARNING - position over the constraints! Pos [{worldPosX}, {worldPosY}] constr [{mapWidth} - 1, {mapHeight} - 1]"); continue; } switch ((PlaceType)details.PlaceType) { case PlaceType.Urban: createdMapSection = WorldMapSectionCreator.CreateWorldMapSection(new UrbanWmSectionBuilder(details, _camera), this); break; case PlaceType.Sand: createdMapSection = WorldMapSectionCreator.CreateWorldMapSection(new SandWmSectionBuilder(details, _camera), this); break; default: //forest createdMapSection = WorldMapSectionCreator.CreateWorldMapSection(new ForestWmSectionBuilder(details, _camera), this); break; } _worldMapSectionObjects[worldPosX, worldPosY] = createdMapSection; } WorldPlaceDataDetails dummyDetails; Transform sectionTransform; for (int x = 0; x < mapWidth; x++) { for (int y = 0; y < mapHeight; y++) { //EMPTY SECTIONS FILLING if (_worldMapSectionObjects[x, y] == null) { dummyDetails = new WorldPlaceDataDetails() { WorldPosX = x, WorldPosY = y, WmId = -1, PlaceType = (int)PlaceType.Forest, PlaceName = "" }; createdMapSection = WorldMapSectionCreator.CreateWorldMapSection(new ForestWmSectionBuilder(dummyDetails, _camera), this); _worldMapSectionObjects[x, y] = createdMapSection; } //POSITIONING sectionTransform = _worldMapSectionObjects[x, y].GetComponent <Transform>(); sectionTransform.position = new Vector3 ( x * _distanceBetweenSections, sectionTransform.position.y, y * _distanceBetweenSections ); } } HideLoadingScreen(); } catch (Exception exception) { MainGameHandler.ShowMessageBox($"Failed to reload world map scene: {exception.Message}"); } }