/// <summary>
            /// Transforms grid tile indices to grid chunk indices.
            /// </summary>
            /// <param name="gridTile"></param>
            /// <returns></returns>
            public MapIndices GridTileToGridChunk(MapIndices gridTile)
            {
                var x = (int)Math.Floor(gridTile.X / (float)ChunkSize);
                var y = (int)Math.Floor(gridTile.Y / (float)ChunkSize);

                return(new MapIndices(x, y));
            }
Exemple #2
0
 internal TileRef(MapId argMap, GridId gridIndex, MapIndices gridTile, Tile tile)
 {
     MapIndex  = argMap;
     GridTile  = gridTile;
     GridIndex = gridIndex;
     _tile     = tile;
 }
Exemple #3
0
 internal TileRef(MapId argMap, GridId gridIndex, int xIndex, int yIndex, Tile tile)
 {
     MapIndex  = argMap;
     GridTile  = new MapIndices(xIndex, yIndex);
     GridIndex = gridIndex;
     _tile     = tile;
 }
        /// <summary>
        ///     Deserializes an IMapManager and ITileDefinitionManager from a properly formatted NetMessage.
        /// </summary>
        /// <param name="message">The message containing a serialized map and tileDefines.</param>
        private void HandleTileMap(MsgMap message)
        {
            Debug.Assert(_netManager.IsClient, "Why is the server calling this?");

            _gridsReceived++;

            var mapIndex  = message.MapIndex;
            var gridIndex = message.GridIndex;

            var chunkSize  = message.ChunkSize;
            var chunkCount = message.ChunkDefs.Length;

            if (!TryGetMap(mapIndex, out var map))
            {
                map = CreateMap(mapIndex);
            }

            if (!map.GridExists(gridIndex))
            {
                GetMap(mapIndex).CreateGrid(gridIndex, chunkSize);
            }

            var grid = GetMap(mapIndex).GetGrid(gridIndex);

            SuppressOnTileChanged = true;
            var modified = new List <(int x, int y, Tile tile)>();

            for (var i = 0; i < chunkCount; ++i)
            {
                var chunkPos = new MapIndices(message.ChunkDefs[i].X, message.ChunkDefs[i].Y);
                var chunk    = grid.GetChunk(chunkPos);

                var counter = 0;
                for (ushort x = 0; x < chunk.ChunkSize; x++)
                {
                    for (ushort y = 0; y < chunk.ChunkSize; y++)
                    {
                        var tile = (Tile)message.ChunkDefs[i].Tiles[counter];
                        if (chunk.GetTile(x, y).Tile != tile)
                        {
                            chunk.SetTile(x, y, tile);
                            modified.Add((x + chunk.X * chunk.ChunkSize, y + chunk.Y * chunk.ChunkSize, tile));
                        }
                        counter++;
                    }
                }
            }

            SuppressOnTileChanged = false;
            if (modified.Count != 0)
            {
                GridChanged?.Invoke(this, new GridChangedEventArgs(grid, modified));
            }

            if (_gridsReceived == _gridsToReceive)
            {
                IoCManager.Resolve <IEntityManager>().MapsInitialized = true;
            }
        }
            /// <inheritdoc />
            public MapIndices GridTileToChunkTile(MapIndices gridTile)
            {
                var size = ChunkSize;
                var x    = MathHelper.Mod(gridTile.X, size);
                var y    = MathHelper.Mod(gridTile.Y, size);

                return(new MapIndices(x, y));
            }
            (IMapChunk, MapIndices) ChunkAndOffsetForTile(MapIndices pos)
            {
                var gridChunkIndices = GridTileToGridChunk(pos);
                var chunk            = GetChunk(gridChunkIndices);
                var chunkTile        = chunk.GridTileToChunkTile(pos);

                return(chunk, chunkTile);
            }
Exemple #7
0
            /// <summary>
            ///     Constructs an instance of a MapGrid chunk.
            /// </summary>
            /// <param name="manager"></param>
            /// <param name="grid"></param>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <param name="chunkSize"></param>
            public Chunk(MapManager manager, MapGrid grid, int x, int y, ushort chunkSize)
            {
                _mapManager  = manager;
                ChunkSize    = chunkSize;
                _grid        = grid;
                _gridIndices = new MapIndices(x, y);

                _tiles = new Tile[ChunkSize, ChunkSize];
            }
            /// <inheritdoc />
            public void SetTile(int xIndex, int yIndex, Tile tile)
            {
                var gridTileIndices  = new MapIndices(xIndex, yIndex);
                var gridChunkIndices = GridTileToGridChunk(gridTileIndices);
                var chunk            = GetChunk(gridChunkIndices);
                var chunkTileIndices = chunk.GridTileToChunkTile(gridTileIndices);

                chunk.SetTile((ushort)chunkTileIndices.X, (ushort)chunkTileIndices.Y, tile);
            }
            public TileRef GetTile(MapIndices indices)
            {
                // array out of bounds
                if (indices.X >= ChunkSize || indices.X < 0 || indices.Y >= ChunkSize || indices.Y < 0)
                {
                    throw new ArgumentOutOfRangeException("Tile indices out of bounds.");
                }

                return(new TileRef(_grid.MapID, _grid.Index, indices.X, indices.Y, _tiles[indices.X, indices.Y]));
            }
            /// <summary>
            ///     Constructs an instance of a MapGrid chunk.
            /// </summary>
            /// <param name="manager"></param>
            /// <param name="grid"></param>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <param name="chunkSize"></param>
            public Chunk(MapManager manager, MapGrid grid, int x, int y, ushort chunkSize)
            {
                _mapManager      = manager;
                LastModifiedTick = _mapManager._gameTiming.CurTick;
                ChunkSize        = chunkSize;
                _grid            = grid;
                _gridIndices     = new MapIndices(x, y);

                _tiles    = new Tile[ChunkSize, ChunkSize];
                _snapGrid = new SnapGridCell[ChunkSize, ChunkSize];
            }
            /// <inheritdoc />
            public IMapChunk GetChunk(MapIndices chunkIndices)
            {
                Chunk output;

                if (_chunks.TryGetValue(chunkIndices, out output))
                {
                    return(output);
                }

                return(_chunks[chunkIndices] = new Chunk(_mapManager, this, chunkIndices.X, chunkIndices.Y, ChunkSize));
            }
            /// <inheritdoc />
            public bool IndicesToTile(MapIndices indices, out TileRef tile)
            {
                MapIndices chunkindices = new MapIndices(indices.X / ChunkSize, indices.Y / ChunkSize);

                if (!_chunks.ContainsKey(chunkindices))
                {
                    tile = new TileRef(); //Nothing should ever use or access this, bool check should occur first
                    return(false);
                }
                Chunk chunk = _chunks[chunkindices];

                tile = chunk.GetTile(new MapIndices(indices.X % ChunkSize, indices.Y % ChunkSize));
                return(true);
            }
            /// <inheritdoc />
            public IEnumerable <TileRef> GetTilesIntersecting(Box2 worldArea, bool ignoreEmpty = true, Predicate <TileRef> predicate = null)
            {
                //TODO: needs world -> local -> tile translations.
                var gridTileLt = new MapIndices((int)Math.Floor(worldArea.Left), (int)Math.Floor(worldArea.Top));
                var gridTileRb = new MapIndices((int)Math.Floor(worldArea.Right), (int)Math.Floor(worldArea.Bottom));

                var tiles = new List <TileRef>();

                for (var x = gridTileLt.X; x <= gridTileRb.X; x++)
                {
                    for (var y = gridTileLt.Y; y <= gridTileRb.Y; y++)
                    {
                        var   gridChunk = GridTileToGridChunk(new MapIndices(x, y));
                        Chunk chunk;
                        if (_chunks.TryGetValue(gridChunk, out chunk))
                        {
                            var chunkTile = chunk.GridTileToChunkTile(new MapIndices(x, y));
                            var tile      = chunk.GetTile((ushort)chunkTile.X, (ushort)chunkTile.Y);

                            if (ignoreEmpty && tile.Tile.IsEmpty)
                            {
                                continue;
                            }

                            if (predicate == null || predicate(tile))
                            {
                                tiles.Add(tile);
                            }
                        }
                        else if (!ignoreEmpty)
                        {
                            var tile = new TileRef(MapID, Index, x, y, new Tile());

                            if (predicate == null || predicate(tile))
                            {
                                tiles.Add(tile);
                            }
                        }
                    }
                }
                return(tiles);
            }
            /// <summary>
            /// Expands the AABB for this grid when a new tile is added. If the tile is already inside the existing AABB,
            /// nothing happens. If it is outside, the AABB is expanded to fit the new tile.
            /// </summary>
            /// <param name="gridTile">The new tile to check.</param>
            public void UpdateAABB(MapIndices gridTile)
            {
                var worldPos = GridTileToLocal(gridTile).ToWorld();

                if (AABBWorld.Contains(worldPos.Position))
                {
                    return;
                }

                // rect union
                var a = AABBWorld;
                var b = worldPos;

                var x     = Math.Min(a.Left, b.X);
                var width = Math.Max(a.Left + a.Width, b.X);

                var y      = Math.Min(a.Top, b.Y);
                var height = Math.Max(a.Top + a.Height, b.Y);

                AABBWorld = new Box2(x, y, width - x, height - y);
            }
            /// <summary>
            /// Expands the AABB for this grid when a new tile is added. If the tile is already inside the existing AABB,
            /// nothing happens. If it is outside, the AABB is expanded to fit the new tile.
            /// </summary>
            /// <param name="gridTile">The new tile to check.</param>
            public void UpdateAABB(MapIndices gridTile)
            {
                var worldPos = GridTileToLocal(gridTile).ToWorld();

                if (AABBWorld.Contains(worldPos.Position))
                {
                    return;
                }

                // rect union
                var a = AABBWorld;
                var b = worldPos;

                var min_x = Math.Min(a.Left, b.X);
                var max_x = Math.Max(a.Right, b.X);

                var min_y = Math.Min(a.Bottom, b.Y);
                var max_y = Math.Max(a.Top, b.Y);

                AABBWorld = Box2.FromDimensions(min_x, min_y, max_x - min_x, max_y - min_y);
            }
Exemple #16
0
 /// <summary>
 ///     Translates chunk tile indices to grid tile indices.
 /// </summary>
 /// <param name="chunkTile">The indices relative to the chunk origin.</param>
 /// <returns>The indices relative to the grid origin.</returns>
 private MapIndices ChunkTileToGridTile(MapIndices chunkTile)
 {
     return(chunkTile + _gridIndices * ChunkSize);
 }
 /// <inheritdoc />
 public GridLocalCoordinates GridTileToLocal(MapIndices gridTile)
 {
     return(new GridLocalCoordinates(gridTile.X * TileSize + (TileSize / 2), gridTile.Y * TileSize + (TileSize / 2), this));
 }
 public IEnumerable <SnapGridComponent> GetSnapGridCell(MapIndices pos, SnapGridOffset offset)
 {
     var(chunk, chunkTile) = ChunkAndOffsetForTile(pos);
     return(chunk.GetSnapGridCell((ushort)chunkTile.X, (ushort)chunkTile.Y, offset));
 }
 public void RemoveFromSnapGridCell(MapIndices pos, SnapGridOffset offset, SnapGridComponent snap)
 {
     var(chunk, chunkTile) = ChunkAndOffsetForTile(pos);
     chunk.RemoveFromSnapGridCell((ushort)chunkTile.X, (ushort)chunkTile.Y, offset, snap);
 }