/// <summary> /// Checks if a wall exists anywhere that prevents movement from the specified tile /// to the adjacent tile in the specified direction (including walls in that tile /// which would prevent movement). If the movement direction is not possible due to /// being at the edge of a map, returns true. If the specified tile is invalid, /// returns true. /// </summary> public bool WallExists(int x, int y, Tile.MoveType direction) { if (!TileIsValid(x, y)) { return(true); } if (0 == (this[y, x].Physics & direction)) { return(true); } switch (direction) { case Tile.MoveType.Wall: throw new ArgumentException(); case Tile.MoveType.Open_NORTH: return(!TileIsValid(x, y - 1) || (this[y - 1, x].Physics & direction.GetOpposite()) == 0); case Tile.MoveType.Open_EAST: return(!TileIsValid(x + 1, y) || (this[y, x + 1].Physics & direction.GetOpposite()) == 0); case Tile.MoveType.Open_SOUTH: return(!TileIsValid(x, y + 1) || (this[y + 1, x].Physics & direction.GetOpposite()) == 0); case Tile.MoveType.Open_WEST: return(!TileIsValid(x - 1, y) || (this[y, x - 1].Physics & direction.GetOpposite()) == 0); case Tile.MoveType.Open_HORIZ: return(WallExists(x, y, Tile.MoveType.Open_NORTH) && WallExists(x, y, Tile.MoveType.Open_EAST) && WallExists(x, y, Tile.MoveType.Open_SOUTH) && WallExists(x, y, Tile.MoveType.Open_WEST)); case Tile.MoveType.Open_UP: case Tile.MoveType.Open_DOWN: case Tile.MoveType.Open_VERT: case Tile.MoveType.Open_ALL: case Tile.MoveType.Open_HEX_NW: case Tile.MoveType.Open_HEX_NE: case Tile.MoveType.Open_HEX_SE: case Tile.MoveType.Open_HEX_SW: case Tile.MoveType.Open_HEX: case Tile.MoveType.Open_HEX_HORIZ: default: throw new NotImplementedException(); } }
/// <summary> /// Draws the border for tile (x, y) in the specified DungeonTiles, /// to the specified graphics and rectangle coordinates. /// </summary> /// <param name="tiles">The DungeonTiles for which this border is being drawn</param> /// <param name="x">The x-location of the tile whose border is being drawn</param> /// <param name="y">The x-location of the tile whose border is being drawn</param> /// <param name="moveDir">The move direction. Currently supports a single horizontal square direction, or all horizontal square directions, but no other combinations</param> /// <param name="g">The graphics on which to draw</param> /// <param name="x1">x1 of the tile's square in graphics.</param> /// <param name="y1">y1 of the tile's square in graphics.</param> /// <param name="x2">x2 of the tile's square in graphics.</param> /// <param name="y2">y2 of the tile's square in graphics.</param> private void DrawBorderFor(DungeonTiles tiles, int x, int y, Tile.MoveType moveDir, Graphics g, int x1, int y1, int x2, int y2) { if (tiles == null || g == null) { return; // no op } if (!tiles.TileIsValid(x, y)) { return; } int adjacentTile_x = 0, adjacentTile_y = 0; // Determine the correct adjacent tile to check physics switch (moveDir) { case Tile.MoveType.Wall: return; // no op case Tile.MoveType.Open_NORTH: adjacentTile_x = x; adjacentTile_y = y - 1; break; case Tile.MoveType.Open_EAST: adjacentTile_x = x + 1; adjacentTile_y = y; break; case Tile.MoveType.Open_SOUTH: adjacentTile_x = x; adjacentTile_y = y + 1; break; case Tile.MoveType.Open_WEST: adjacentTile_x = x - 1; adjacentTile_y = y; break; case Tile.MoveType.Open_HORIZ: DrawBorderFor(tiles, x, y, Tile.MoveType.Open_NORTH, g, x1, y1, x2, y2); DrawBorderFor(tiles, x, y, Tile.MoveType.Open_EAST, g, x1, y1, x2, y2); DrawBorderFor(tiles, x, y, Tile.MoveType.Open_SOUTH, g, x1, y1, x2, y2); DrawBorderFor(tiles, x, y, Tile.MoveType.Open_WEST, g, x1, y1, x2, y2); return; default: throw new NotImplementedException("Unsupported Tile.MoveType specified"); } // 1. Check if THIS cell is even open bool useWall = ((tiles[y, x].Physics & moveDir) == 0); // 2. Check if adjacent cell exists; if not, use a wall border useWall = (useWall || !tiles.TileIsValid(adjacentTile_x, adjacentTile_y)); // 3. If adjacent cell exists, check if its corresponding wall is opened too; if not, use a wall border useWall = (useWall || (tiles[adjacentTile_y, adjacentTile_x].Physics & moveDir.GetOpposite()) == 0); if (this.WallBorder_Pen == null || this.OpenBorder_Pen == null) { throw new Exception("DungeonTileRenderer is in an invalid state: set WallBorder_Pen and OpenBorder_Pen"); } Pen borderPen = useWall ? this.WallBorder_Pen : this.OpenBorder_Pen; // All this work, just to draw a single line. switch (moveDir) { case Tile.MoveType.Open_NORTH: g.DrawLine(borderPen, x1, y1, x2, y1); break; case Tile.MoveType.Open_EAST: g.DrawLine(borderPen, x2, y1, x2, y2); break; case Tile.MoveType.Open_SOUTH: g.DrawLine(borderPen, x1, y2, x2, y2); break; case Tile.MoveType.Open_WEST: g.DrawLine(borderPen, x1, y1, x1, y2); break; default: throw new ArgumentException("Unsupported moveDir to draw border"); } }