/// <summary> Initializes the given chunk. </summary> public static void InitializeChunk(Chunk chunk, IPerlinNoiseProvider noiseProvider) { var position = chunk.Position; for (int y = 0; y < Chunk.NumberOfGridItemsHigh; y++) { for (int x = 0; x < Chunk.NumberOfGridItemsWide; x++) { var gridPosition = new GridCoordinate(position, new InnerChunkGridCoordinate(x, y)); var gridItem = GetGridItemAt(gridPosition, chunk, noiseProvider); chunk[gridPosition.InnerChunkGridCoordinate] = gridItem; } } }
/// <summary> /// Checks the array index/position to verify that it has the correct position information and if /// it does not, re-reads the data from the world and updates the data. /// </summary> /// <param name="index"> The index position to update. </param> /// <param name="coordinate"> The coordinate representing the position to update. </param> private void Invalidate(Array2DIndex index, GridCoordinate coordinate, bool bypassSamePositionCheck = false) { var existingData = _visibleGridItems[index]; if (!bypassSamePositionCheck && existingData.Position == coordinate) { return; } var chunkCoordinate = coordinate.ChunkCoordinate; if (!_worldGrid.IsValid(chunkCoordinate)) { return; } var chunk = _worldGrid[chunkCoordinate]; var data = chunk[coordinate.InnerChunkGridCoordinate]; UpdateData(index, data, coordinate, chunk); }
private static GridItem GetGridItemAt(GridCoordinate gridPosition, Chunk chunk, IPerlinNoiseProvider noiseProvider) { // TODO UNITY // TODO load this from somewhere else var tileValue = noiseProvider.GetNoise(gridPosition.X / 10f, gridPosition.Y / 10f); // TODO UNITY // TODO remove random call byte variant = (byte)random.Next(0, 4); GridItem gridItem; if (tileValue > 0.7f) { gridItem = new GridItem(TileType.Water, variant); } else if (tileValue < 0.3f) { gridItem = new GridItem(TileType.Hill, variant); } else { gridItem = new GridItem(TileType.Path, variant); } var buildingValue = noiseProvider.GetNoise(-gridPosition.X / 8f, gridPosition.Y / 8f); if (gridPosition.X % 2 == 0 && gridPosition.Y % 2 == 0 && buildingValue > 0.85f && gridItem.Type != TileType.Water) { // TODO UNITY //gridItem.BuildingType = BuildingType.TreeStump; //gridItem.BuildingInstance = 1; //gridItem.Entity = chunk.Storage.CreateEntity(TreeTrunk.Instance); } return(gridItem); }
private void ValidateConversion(GridCoordinate gridPosition, Array2DIndex arrayIndex) { var worked = ConvertToGridItemIndex(gridPosition).X == arrayIndex.X && ConvertToGridItemIndex(gridPosition).Y == arrayIndex.Y; if (worked) { return; } // to aid in debugging worked = ConvertToGridItemIndex(gridPosition).X == arrayIndex.X && ConvertToGridItemIndex(gridPosition).Y == arrayIndex.Y; var message = new StringBuilder(); message.AppendFormat("Array Index ({0}) was converted into Grid Position ({1})", arrayIndex, gridPosition); message.AppendFormat("But we expected ({0},{1})", ConvertToGridItemIndex(gridPosition).X, ConvertToGridItemIndex(gridPosition).Y); Debug.WriteLine(message); }
public bool Equals(GridCoordinate other) { return(X == other.X && Y == other.Y); }
private void HandleChunkItemChanged(Chunk chunk, GridCoordinate coordinate, GridItem oldvalue, GridItem newvalue) { Invalidate(ConvertToGridItemIndex(coordinate), coordinate, bypassSamePositionCheck: true); }
/// <summary> /// Checks the array index/position to verify that it has the correct position information and if /// it does not, re-reads the data from the world and updates the data. /// </summary> /// <param name="coordinate"> The coordinate representing the position to update. </param> private void InvalidatePosition(GridCoordinate coordinate) { Validate(coordinate); Invalidate(ConvertToGridItemIndex(coordinate), coordinate); }
/// <summary> Updates the cells that have changed because the target has changed. </summary> /// <param name="previousCoordinate"> The last position we were at. </param> private void UpdateChangedUnits(GridCoordinate previousCoordinate) { var xDiff = _currentPosition.X - previousCoordinate.X; var yDiff = _currentPosition.Y - previousCoordinate.Y; if (xDiff == 0 && yDiff == 0) { return; } if (Math.Abs(xDiff) >= _visibleGridItems.Width || Math.Abs(yDiff) >= _visibleGridItems.Height ) { // if we ever move more units than we have, then just invalidate the whole thing. UpdateAllUnits(); return; } // if we're at (x,y) from (x-1, y-1), then (x+halfWidth, y+halfHeight) just came into view (of // course if we just came from (x+1, y+1), then (x-halfWidth, y-halfWidth) just came into view. // This used to be `amountToOffsetX = MathUtils.Signed(xDiff, _numUnitsWideHalfThreshold)` but // then when we moved right it would update the top-right corner one higher than when we moved // up. I'm not sure why we need to invalidate one higher when moving in the positive direction // but it seems to work. // // My current theory as to why is that it has something to do with one of the conversion // algorithms preferring the positive direction over the negative. var amountToOffsetX = xDiff > 0 ? _numUnitsWideHalfThreshold + 1 : -_numUnitsWideHalfThreshold; var amountToOffsetY = yDiff > 0 ? _numUnitsHighHalfThreshold + 1 : -_numUnitsHighHalfThreshold; var start = previousCoordinate.OffsetBy(amountToOffsetX, amountToOffsetY); var end = _currentPosition.OffsetBy(amountToOffsetX, amountToOffsetY); var startColumn = start.X; var endColumn = end.X; // make sure our for loop will work :: ) if (startColumn > endColumn) { MathUtils.Swap(ref startColumn, ref endColumn); } var startRow = start.Y; var endRow = end.Y; if (startRow > endRow) { MathUtils.Swap(ref startRow, ref endRow); } // OPTIMIZATION 1 - Instead of using PositiveRemainder, we could just have loop through twice // (when needed) because we know that we can only have to dis-jointed sets of rows[/columns] // // OPTIMIZATION 2 - We're currently always hitting the area where the rows/columns overlap // twice. We could optimize this out (especially if/when we do #1 above). // update the rows that need to be updated for (var y = startRow; y < endRow; y++) { for (var x = _currentPosition.X - _numUnitsWideHalfThreshold; x <= _currentPosition.X + _numUnitsWideHalfThreshold; x++) { InvalidatePosition(new GridCoordinate(x, y)); } } // update that columns that need to be updated for (var y = _currentPosition.Y - _numUnitsHighHalfThreshold; y <= _currentPosition.Y + _numUnitsHighHalfThreshold; y++) { for (var x = startColumn; x < endColumn; x++) { InvalidatePosition(new GridCoordinate(x, y)); } } }