/// <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> private void Invalidate(Array2DIndex index, GridCoordinate coordinate, bool bypassSamePositionCheck, GridItemPropertyChange changeType) { var existingData = _visibleGridItems[index]; if (!bypassSamePositionCheck && existingData.Position == coordinate) { return; } var subCoordinate = coordinate.AsSubCoordinates(); if (!_worldGrid.IsValid(subCoordinate.ChunkCoordinate)) { return; } var(chunk, data) = _worldGrid.GetChunkAndCellData(subCoordinate); UpdateData(index, data, coordinate, chunk, changeType); }
private static GridItem CreateGridItemFor(GridCoordinate gridPosition) { int x = gridPosition.X; int y = gridPosition.Y; // TODO UNITY // TODO load this from somewhere else var tileValue = GetTileIndex(x, y); // TODO UNITY // TODO remove random call var variant = GetRotation(x, y); GridItem gridItem = new GridItem(0, variant); if (tileValue > 0) { gridItem = gridItem.AddStructure(tileValue, ItemRotation.Left, 100); } return(gridItem); }
/// <summary> Updates the data at the specified index inside the grid. </summary> /// <param name="index"> Zero-based index of the. </param> /// <param name="data"> The grid data to store. </param> /// <param name="position"> The coordinate of the original GridItem where the data was retrieved /// from. </param> /// <param name="chunk"></param> /// <param name="changeType"></param> private void UpdateData(Array2DIndex index, GridItem data, GridCoordinate position, Chunk chunk, GridItemPropertyChange changeType) { var newData = new SliceUnitData <T>(chunk, position, data, default(T)); var rawIndex = _visibleGridItems.CalculateRawArrayIndex(index); ref var slot = ref _visibleGridItems.Data[rawIndex];
private void Invalidate(Array2DIndex index, GridCoordinate coordinate) => Invalidate(index, coordinate, bypassSamePositionCheck: false, changeType: GridItemPropertyChange.All);
/// <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) { MathUtil.Swap(ref startColumn, ref endColumn); } var startRow = start.Y; var endRow = end.Y; if (startRow > endRow) { MathUtil.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)); } } }
public bool Equals(GridCoordinate other) { return(X == other.X && Y == other.Y); }