Beispiel #1
0
        /// <summary>
        /// <para>List of rectangles we collide with.</para>
        /// <para>This function checks a specified area for collidable tiles to detect the exact position of the obstacle,
        /// because the gridcollider does not provide such information, and then calls <c>ExtendCollisionTile</c> to detect
        /// the complete obstacle (as opposed to only the tile we collide with)</para>
        /// </summary>
        /// <param name="collider">Collider to use</param>
        /// <param name="collidingEntity">Entity colliding with the Grid, for example a Tank</param>
        /// <param name="leftStart">left tile to start check at</param>
        /// <param name="topStart">top tile to start check at</param>
        /// <param name="checkWidth">how many tiles to check in x</param>
        /// <param name="checkHeight">how many tiles to check in y</param>
        /// <returns>List of rectangles we collide with</returns>
        public static List <Rectangle> GetCollidingRectangles(GridCollider collider, Entity collidingEntity, int leftStart, int topStart, int checkWidth = 3, int checkHeight = 3)
        {
            //create the test entity if it does not exist yet
            if (_testingEntity == null)
            {
                _testingEntity = new Entity(0, 0, null, new BoxCollider(0, 0, CollidableTags.Tester));
            }

            //create list for collisions
            List <Rectangle> collisionList = new List <Rectangle>();

            //check each tile underneath the tank for collision
            for (int x = leftStart; x < checkWidth + leftStart; x++)
            {
                for (int y = topStart; y < checkHeight + topStart; y++)
                {
                    //if we found a tile that actually collides, save it to the list
                    if (collider.GetTile(x, y))
                    {
                        _testingEntity.Collider.SetPosition(x * collider.TileWidth, y * collider.TileHeight);
                        _testingEntity.Collider.Width  = collider.TileWidth;
                        _testingEntity.Collider.Height = collider.TileHeight;
                        if (collidingEntity.Collider.Collide(collidingEntity.X, collidingEntity.Y, _testingEntity) != null)
                        {
                            collisionList.Add(ExtendCollisionTile(collider, x, y));
                        }
                    }
                }
            }

            //return
            return(collisionList);
        }
Beispiel #2
0
        /// <summary>
        /// This code tries to extend the collision tile to the largest possible rectangle (eg find the complete obstacle),
        /// so that following algorithm parts
        /// can work with these rectangles to easily decide whether to move the offending entity on the x or the y axis.
        /// </summary>
        /// <param name="collider">The collider to work with, probably the grid collision collider.</param>
        /// <param name="startX">int x position of the tile in the grid (!= pixel position)</param>
        /// <param name="startY">int y position of the tile in the grid (!= pixel position)</param>
        /// <returns></returns>
        public static Rectangle ExtendCollisionTile(GridCollider collider, int startX, int startY)
        {
            //copy the positions into variables that will be changed to calculate the resulting rectangle
            int left = startX, right = startX + 1, top = startY, bottom = startY + 1;

            //go as far in all directions as the tile is collidable
            while (collider.GetTile(left - 1, startY) && left > 1)
            {
                left--;
            }
            while (collider.GetTile(right, startY) && right < collider.TileColumns)
            {
                right++;
            }
            while (collider.GetTile(startX, top - 1) && top > 1)
            {
                top--;
            }
            while (collider.GetTile(startX, bottom) && bottom < collider.TileRows)
            {
                bottom++;
            }

            //create the rectangle the tank collides with
            return(new Rectangle(left * collider.TileWidth, top * collider.TileHeight, (right - left) * collider.TileWidth, (bottom - top) * collider.TileHeight));
        }
 private void Cleanup()
 {
     if (movementState == MovementState.Stopped)
     {
         gridColliderUnderSlidable = null;
         slidable = null;
     }
 }
Beispiel #4
0
        public void MakeTiles(XmlDocument doc)
        {
            XmlNode graphicsData = doc.SelectSingleNode("map/layer[@name='Graphics']/data");
            XmlNode gridData     = doc.SelectSingleNode("map/layer[@name='Grid']/data");

            var tileset = AddGraphic(new Tilemap(Global.imagePath + "Rooms/tiles.png", 640, 32));

            grid = AddCollider(new GridCollider(Global.screenWidth, Global.screenHeight, 32, 32, Global.Tags.Wall));

            grid.LoadCSV(gridData.InnerXml.Replace("\r", ""), "0", "66");
            tileset.LoadCSV(graphicsData.InnerXml.Replace("\r", ""), ',', '\n', "", 1);
        }
Beispiel #5
0
 /// <summary>
 /// Load tiles in from a GridCollider.
 /// </summary>
 /// <param name="grid">The GridCollider to reference.</param>
 /// <param name="color">The color to set tiles that are collidable on the grid.</param>
 /// <param name="layer">The layer to place the tiles on.</param>
 public void LoadGrid(GridCollider grid, Color color, string layer = "")
 {
     for (var i = 0; i < grid.TileColumns; i++)
     {
         for (var j = 0; j < grid.TileRows; j++)
         {
             if (grid.GetTile(i, j))
             {
                 SetTile(i, j, color, layer);
             }
         }
     }
 }
Beispiel #6
0
        protected override void OnAdded()
        {
            base.OnAdded();

            var triggerGrid = new GridCollider(Data.WidthTiles, Data.HeightTiles, Global.TileSize, Global.TileSize, "tileset");

            Data.IterateTiles((tile) =>
            {
                if (tile.Trigger != null)
                {
                    if (tile.SolidType == TileSolidType.PixelMask)
                    {
                        triggerGrid.SetPixelMaskAt(tile.X, tile.Y, tile.DisplayTid, tile.Properties);
                    }
                    else
                    {
                        triggerGrid.SetTileAt(tile.X, tile.Y, tile.SolidType, tile.Properties);
                    }
                }
            });

            var triggerEntity = new Entity();

            triggerEntity.Type     = Global.TypeTrigger;
            triggerEntity.Collider = triggerGrid;
            Scene.Add(triggerEntity);

            Data.IterateObjects((obj) => Scene.Add(new Object(obj)));

            Log.Debug("Loading groups...");
            Data.IterateEntities((args) =>
            {
                var entity = GameEntity.Create(args);
                if (args.GroupId != -1)
                {
                    EntityGroup group;
                    if (!groups.TryGetValue(args.GroupId, out group))
                    {
                        group = new EntityGroup(args.GroupId, Data.GetGroupReward(args.GroupId));
                        groups[args.GroupId] = group;
                        Log.Debug("Created group " + args.GroupId);
                    }

                    group.Add(entity);
                    entity.Group = group;
                }
                Scene.Add(entity);
            });
        }
Beispiel #7
0
        public override void Added()
        {
            base.Added();

            // Create the grid collider based off of the scene's dimensions.
            GridCollider = new GridCollider(Scene.Width, Scene.Height, GridSize, GridSize);

            // Create the tilemap based off of the scene's dimensions.
            Tilemap = new Tilemap("tiles.png", Scene.Width, Scene.Height, GridSize, GridSize);

            // Add the tilemap graphic.
            AddGraphic(Tilemap);

            // Add the grid collider.
            AddCollider(GridCollider);
        }
    private void UpdateMoveState()
    {
        //We check if we have more than one touch happening.
        //We also check if the first touches phase is Ended (that the finger was lifted)
        if (inputHandler.IsInputDown())
        {
            //We transform the touch position into word space from screen space and store it.
            Vector3 touchPosWorld = Camera.main.ScreenToWorldPoint(inputHandler.GetInputScreenPosition());

            RaycastHit slidableHit;
            // Does the ray intersect with any grid colliders?
            // Bit shift the index of the layer to get a bit mask
            int slidableLayerMask = 1 << Constants.SLIDABLE_LAYER;
            Physics.Raycast(touchPosWorld, raycastDirection, out slidableHit, float.MaxValue, slidableLayerMask);

            if (slidableHit.collider != null)
            {
                Slidable touchedSlidable = slidableHit.collider.GetComponent <Slidable>();

                // Early exit if THIS grid movement controller is not relevant.
                if (!touchedSlidable.BelongsTo(grid))
                {
                    return;
                }
                slidable      = touchedSlidable;
                movementState = MovementState.Moving;
            }

            if (slidable != null)
            {
                // check if we should update our tracked grid collider
                int        gridColliderLayerMask = 1 << Constants.GRID_COLLIDER_LAYER;
                RaycastHit gridColliderHit;
                Physics.Raycast(slidable.transform.position, raycastDirection, out gridColliderHit, float.MaxValue, gridColliderLayerMask);

                if (gridColliderHit.collider != null)
                {
                    gridColliderUnderSlidable = gridColliderHit.collider.GetComponent <GridCollider>();
                }
            }
        }
        if (inputHandler.HasInputEnded())
        {
            movementState = MovementState.Stopped;
            Debug.Log("input ended");
        }
    }
Beispiel #9
0
    private void InitGrid()
    {
        grid = new GridCell[rows][];
        for (int r = 0; r < rows; r++)
        {
            grid[r] = new GridCell[columns];
            for (int c = 0; c < columns; c++)
            {
                Vector3      gridColliderPos = GetGridColliderWorldPos(r, c);
                GridCollider gridCollider    = Instantiate(gridColliderPrefab, gridColliderPos, Quaternion.identity).GetComponent <GridCollider>();
                gridCollider.transform.parent = gameObject.transform;
                gridCollider.SetPosition(r, c);
                // Raycast to hit GridObject
                GridObject gridObject = GetGridObject(gridColliderPos);

                grid[r][c] = new GridCell(gridCollider, gridObject);
            }
        }
    }
Beispiel #10
0
        // Our new constructor takes in the new J,I coordinates, and a Player object
        public GameScene(int nextJ = 0, int nextI = 0, Player player = null, HaguruClock clock = null) : base()
        {
            screenJ = nextJ;
            screenI = nextI;

            // If a Player object isn't passed in, start at the default x,y position of 100,100
            if (player == null)
            {
                Global.player = new Player(100, 100);
            }
            else
            {
                Global.player = player;
            }

            //if no Clock is passed in start a new clock at the default pos
            if (clock == null)
            {
                Global.clock = new HaguruClock();
            }
            else
            {
                Global.clock = clock;
            }

            // Create and load our Tilemap and GridCollider
            tilemap = new Tilemap(Assets.TILESET, WIDTH, HEIGHT, Global.GRID_WIDTH, Global.GRID_HEIGHT);
            grid    = new GridCollider(WIDTH, HEIGHT, Global.GRID_WIDTH, Global.GRID_HEIGHT);
            string mapToLoad    = Assets.MAP_WORLD;
            string solidsToLoad = Assets.MAP_SOLID;

            LoadWorld(mapToLoad, solidsToLoad);

            // Since we are constantly switching Scenes we need to do some checking,
            // ensuring that the music doesn't get restarted.
            // We should probably add an isPlaying boolean to the Music class. I will do this soon.
            if (Global.gameMusic == null)
            {
                Global.gameMusic = new Music(Assets.MUSIC_GAME);
                Global.gameMusic.Play();
                Global.gameMusic.Volume = 0.40f;
            }
        }
Beispiel #11
0
        public PixelMaskTest()
        {
            player          = new Entity(80, 80);
            player.Collider = new PixelMask("gfx/mask2");
            player.OriginX  = player.Width / 2;
            player.OriginY  = player.Height / 2;
            var playerSprite = new Sprite("gfx/mask2");

            playerSprite.CenterOrigin();
            player.Add(playerSprite);
            Add(player);

            var entity1 = new Entity(40, 30);

            entity1.Type     = TypeSolid;
            entity1.Collider = new PixelMask("gfx/mask1");
            entity1.Add(new Sprite("gfx/mask1"));
            Add(entity1);

            var tileset      = new Tileset("gfx/mask_tiles", 16, 16);
            var tilemap      = new Tilemap(tileset, 5, 5);
            var gridCollider = new GridCollider(8, 8, 16, 16, new PixelMaskSet(tileset));

            SetTile(tilemap, gridCollider, 0, 0, 0);
            SetTile(tilemap, gridCollider, 1, 0, 4);
            SetTile(tilemap, gridCollider, 2, 0, 1);
            SetTile(tilemap, gridCollider, 0, 1, 4);
            SetTile(tilemap, gridCollider, 1, 1, 4);
            SetTile(tilemap, gridCollider, 2, 1, 4);
            SetTile(tilemap, gridCollider, 0, 2, 2);
            SetTile(tilemap, gridCollider, 1, 2, 4);
            SetTile(tilemap, gridCollider, 2, 2, 3);

            var mapEntity = new Entity(100, 100);

            mapEntity.Type = TypeSolid;
            mapEntity.Add(tilemap);
            mapEntity.Collider = gridCollider;
            Add(mapEntity);
        }
Beispiel #12
0
        public override void Update()
        {
            base.Update();

            //returns true if we collide witht the grid at any position
            if (Tank.Collider.Overlap(Tank.X, Tank.Y, CollidableTags.Wall))
            {
                //notify the tank
                Tank.WallCollision = true;

                //extract the wallCollider from the list of colliders with the tag wallcollider
                GridCollider wallGridCollider = (GridCollider)Tank.Collider.CollideList(Tank.X, Tank.Y, CollidableTags.Wall)[0];

                //calculate colliding tiles check start position, eg the top-left-most tile the tank could hit
                int leftmostTile = wallGridCollider.GridX(Tank.Collider.Left);
                int topmostTile  = wallGridCollider.GridY(Tank.Collider.Top);

                //get the collision rectangles
                List <Rectangle> collidingRectangles = CollisionUtilites.GetCollidingRectangles(wallGridCollider, Tank, leftmostTile, topmostTile);

                //filter out identical rectangles created when the tile checker found multiple colliding candidates
                collidingRectangles = collidingRectangles.Distinct().ToList();

                //reset out of all rectangles
                foreach (Rectangle obstacle in collidingRectangles)
                {
                    Vector2 projection = CollisionUtilites.ShortestProjection(Tank, obstacle);
                    //something smells fishy: the projection is larger than a complete tile? f**k that.
                    if (Math.Abs(projection.X) < wallGridCollider.TileWidth && Math.Abs(projection.Y) < wallGridCollider.TileHeight)
                    {
                        Tank.AddPosition(projection);
                    }
                }
            }
            else
            {
                Tank.WallCollision = false;
            }
        }
Beispiel #13
0
        /// <summary>
        /// Load level data from a string into a Scene.
        /// </summary>
        /// <param name="data">The level data to load.</param>
        /// <param name="scene">The Scene to load into.</param>
        public void LoadLevel(string data, Scene scene)
        {
            Entities.Clear();

            CurrentLevel = data;

            var xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(data);

            var xmlLevel = xmlDoc["level"];

            scene.Width  = int.Parse(xmlDoc["level"].Attributes["width"].Value);
            scene.Height = int.Parse(xmlDoc["level"].Attributes["height"].Value);

            int i = 0;

            foreach (var layer in Layers.Values)
            {
                if (layer.Type == "GridLayerDefinition")
                {
                    var Entity = new Entity();

                    var grid = new GridCollider(scene.Width, scene.Height, layer.GridWidth, layer.GridHeight);

                    grid.LoadString(xmlLevel[layer.Name].InnerText);
                    if (ColliderTags.ContainsKey(layer.Name))
                    {
                        grid.AddTag(ColliderTags[layer.Name]);
                    }

                    if (DisplayGrids)
                    {
                        var tilemap = new Tilemap(scene.Width, scene.Height, layer.GridWidth, layer.GridHeight);
                        tilemap.LoadString(xmlLevel[layer.Name].InnerText, layer.Color);
                        Entity.AddGraphic(tilemap);
                    }

                    Entity.AddCollider(grid);

                    scene.Add(Entity);
                    Entities.Add(layer.Name, Entity);
                }
                if (layer.Type == "TileLayerDefinition")
                {
                    var Entity = new Entity();

                    var xmlTiles = xmlLevel[layer.Name];

                    var tileset = xmlTiles.Attributes["tileset"].Value;

                    var tilepath = ImagePath + TileMaps[tileset];

                    foreach (var kv in assetMappings)
                    {
                        var find    = kv.Key;
                        var replace = kv.Value;

                        if (tilepath.EndsWith(find))
                        {
                            tilepath = replace;
                            break;
                        }
                    }

                    var tilemap = new Tilemap(tilepath, scene.Width, scene.Height, layer.GridWidth, layer.GridHeight);

                    var exportMode = xmlTiles.Attributes["exportMode"].Value;
                    switch (exportMode)
                    {
                    case "CSV":
                        tilemap.LoadCSV(xmlTiles.InnerText);
                        break;

                    case "XMLCoords":
                        foreach (XmlElement t in xmlTiles)
                        {
                            tilemap.SetTile(t);
                        }
                        break;
                    }

                    tilemap.Update();

                    Entity.AddGraphic(tilemap);

                    Entity.Layer = BaseTileDepth - i * TileDepthIncrement;
                    i++;

                    scene.Add(Entity);
                    Entities.Add(layer.Name, Entity);
                }
                if (layer.Type == "EntityLayerDefinition")
                {
                    var xmlEntities = xmlLevel[layer.Name];

                    if (xmlEntities != null)
                    {
                        foreach (XmlElement e in xmlEntities)
                        {
                            CreateEntity(e, scene);
                        }
                    }
                }
            }

            if (UseCameraBounds)
            {
                scene.CameraBounds    = new Rectangle(0, 0, scene.Width, scene.Height);
                scene.UseCameraBounds = true;
            }
        }
Beispiel #14
0
 public GridCell(GridCollider gridCollider, GridObject gridObject)
 {
     this.gridCollider = gridCollider;
     this.gridObject   = gridObject;
 }
Beispiel #15
0
 /// <summary>
 /// Load tiles in from a GridCollider.
 /// </summary>
 /// <param name="grid">The GridCollider to reference.</param>
 /// <param name="color">The color to set tiles that are collidable on the grid.</param>
 /// <param name="layer">The layer to place the tiles on.</param>
 public void LoadGrid(GridCollider grid, Color color, Enum layer)
 {
     LoadGrid(grid, color, Util.EnumValueToString(layer));
 }
Beispiel #16
0
        /// <summary>
        /// Load tiles in from a GridCollider and choose tiles based on the shape of the grid.
        /// </summary>
        /// <param name="grid">The GridCollider to reference.</param>
        /// <param name="layer">The layer to place the tiles on.</param>
        public void LoadGridAutoTile(GridCollider grid, string layer = "")
        {
            if (autoTileTable == null)
            {
                SetAutoTileData(autoTileDefaultData);
            }

            for (var i = 0; i < grid.TileColumns; i++)
            {
                for (var j = 0; j < grid.TileRows; j++)
                {
                    if (grid.GetTile(i, j))
                    {
                        int tileValue = 0;

                        /*
                         * auto tiling grid
                         *
                         * 128 001 016
                         * 008 ___ 002
                         * 064 004 032
                         *
                         */

                        if (grid.GetTile(i - 1, j - 1))
                        {
                            tileValue += 128;
                        }
                        if (grid.GetTile(i, j - 1))
                        {
                            tileValue += 1;
                        }
                        if (grid.GetTile(i + 1, j - 1))
                        {
                            tileValue += 16;
                        }
                        if (grid.GetTile(i + 1, j))
                        {
                            tileValue += 2;
                        }
                        if (grid.GetTile(i + 1, j + 1))
                        {
                            tileValue += 32;
                        }
                        if (grid.GetTile(i, j + 1))
                        {
                            tileValue += 4;
                        }
                        if (grid.GetTile(i - 1, j + 1))
                        {
                            tileValue += 64;
                        }
                        if (grid.GetTile(i - 1, j))
                        {
                            tileValue += 8;
                        }

                        if (autoTileTable.ContainsKey(tileValue))
                        {
                            tileValue = Rand.ChooseElement <int>(autoTileTable[tileValue]);
                        }

                        SetTile(i, j, tileValue, layer);
                    }
                }
            }
        }
Beispiel #17
0
 private void SetTile(Tilemap tilemap, GridCollider gridCollider, int x, int y, int id)
 {
     tilemap.SetTileAt(x, y, id);
     gridCollider.SetPixelMaskAt(x, y, id);
 }
        /// <summary>
        /// Creates a grid collider from any TiledTileLayer. Each tile that have an image set it will 
        /// create a collider the size of the tile.
        /// </summary>
        /// <param name="tileLayer">
        /// The tile layer with all the information needed to generate a grid collider.
        /// </param>
        /// <param name="tags">
        /// The tags that will be applied to all of the colliders in the grid collider.
        /// </param>
        /// <returns>
        /// A grid collider with a collider at each position where a tile is set.
        /// </returns>
        public GridCollider CreateGridCollider(TiledTileLayer tileLayer, params int[] tags)
        {
            var grid = new GridCollider(PixelWidth, PixelHeight, TileWidth, TileHeight, tags);

            foreach(var tile in tileLayer.Tiles)
            {
                if(tile.Gid > 0)
                {
                    grid.SetTile(tile.X, tile.Y);
                }
            }

            return grid;
        }
Beispiel #19
0
        public DungeonMap(DungeonData data)
        {
            Data = data;

            Type   = Global.TypeMap;
            Width  = data.WidthTiles * Global.TileSize;
            Height = data.HeightTiles * Global.TileSize;

            var solidGrid = new GridCollider(data.WidthTiles, data.HeightTiles, Global.TileSize, Global.TileSize, "tileset");

            Collider = solidGrid;

            var groundMap = new Tilemap(data.Tileset, data.WidthTiles, data.HeightTiles);

            groundMap.Layer = Global.LayerMapGround;
            Add(groundMap);

            var backMap = new Tilemap(data.Tileset, data.WidthTiles, data.HeightTiles);

            backMap.Layer = Global.LayerMapWall;
            Add(backMap);

            var frontMap = new Tilemap(data.Tileset, data.WidthTiles, data.HeightTiles);

            frontMap.Layer = Global.LayerMapRoof;
            Add(frontMap);

            Data.IterateTiles((tile) =>
            {
                if (tile.Trigger == null)
                {
                    if (tile.SolidType == TileSolidType.PixelMask)
                    {
                        solidGrid.SetPixelMaskAt(tile.X, tile.Y, tile.DisplayTid, tile.Properties);
                    }
                    else
                    {
                        solidGrid.SetTileAt(tile.X, tile.Y, tile.SolidType, tile.Properties);
                    }
                }

                switch (tile.Type)
                {
                case DungeonTileType.Ground:
                    RenderFlatTile(groundMap, tile, TileGround);
                    break;

                case DungeonTileType.Wall:
                    RenderWallTile(solidGrid, backMap, tile, TileWall);
                    break;

                case DungeonTileType.Roof:
                    RenderFlatTile(frontMap, tile, TileRoof);
                    break;
                }

                if (tile.Trigger != null)
                {
                    backMap.SetTileAt(tile.X, tile.Y, tile.DisplayTid);
                }
            });

            tireLayer       = new DrawLayer(data.WidthTiles * Global.TileSize, data.HeightTiles * Global.TileSize);
            tireLayer.Layer = Global.LayerTireEffect;
            Add(tireLayer);
        }
Beispiel #20
0
        private void RenderWallTile(GridCollider solidGrid, Tilemap tilemap, DungeonTile tile, int tid)
        {
            var neighbors = GetNeighbors(tile);

            // vertical
            if (GetTileTypeAt(tile.X - 1, tile.Y) == DungeonTileType.Roof && GetTileTypeAt(tile.X + 1, tile.Y) == DungeonTileType.Ground)
            {
                SetTile(tilemap, tile, tid + 16, Direction.Left);
            }
            else if (GetTileTypeAt(tile.X + 1, tile.Y) == DungeonTileType.Roof && GetTileTypeAt(tile.X - 1, tile.Y) == DungeonTileType.Ground)
            {
                SetTile(tilemap, tile, tid + 18, Direction.Right);
            }

            // horizontal
            else if (GetTileTypeAt(tile.X, tile.Y - 1) == DungeonTileType.Roof && GetTileTypeAt(tile.X, tile.Y + 1) == DungeonTileType.Ground)
            {
                SetTile(tilemap, tile, tid + 1, Direction.Up);
            }
            else if (GetTileTypeAt(tile.X, tile.Y + 1) == DungeonTileType.Roof && GetTileTypeAt(tile.X, tile.Y - 1) == DungeonTileType.Ground)
            {
                SetTile(tilemap, tile, tid + 33, Direction.Down);
            }

            // corner outer
            else if (GetTileTypeAt(tile.X + 1, tile.Y + 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X + 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y + 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 0);
            }
            else if (GetTileTypeAt(tile.X - 1, tile.Y + 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X - 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y + 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 2);
            }
            else if (GetTileTypeAt(tile.X + 1, tile.Y - 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X + 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y - 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 32);
            }
            else if (GetTileTypeAt(tile.X - 1, tile.Y - 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X - 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y - 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 34);
            }

            // corner inner
            else if (GetTileTypeAt(tile.X - 1, tile.Y - 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X + 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y + 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 3);
                solidGrid.SetPixelMaskAt(tile.X, tile.Y, tid + 3);
            }
            else if (GetTileTypeAt(tile.X + 1, tile.Y - 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X - 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y + 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 4);
                solidGrid.SetPixelMaskAt(tile.X, tile.Y, tid + 4);
            }
            else if (GetTileTypeAt(tile.X - 1, tile.Y + 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X + 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y - 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 19);
                solidGrid.SetPixelMaskAt(tile.X, tile.Y, tid + 19);
            }
            else if (GetTileTypeAt(tile.X + 1, tile.Y + 1) == DungeonTileType.Ground && GetTileTypeAt(tile.X - 1, tile.Y) == DungeonTileType.Wall && GetTileTypeAt(tile.X, tile.Y - 1) == DungeonTileType.Wall)
            {
                SetTile(tilemap, tile, tid + 20);
                solidGrid.SetPixelMaskAt(tile.X, tile.Y, tid + 20);
            }

            // error
            else
            {
                Log.Error("Unkown wall tile at " + tile);
            }
        }