/// <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);
        }
Exemple #2
0
        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);
 }