private static bool GetTopOrBottomEdge(TileEdges edgesToTest, int x, int y, Vector2 tilePosition, ref LineSegment edge) { if ((edgesToTest & TileEdges.Bottom) != 0) { Tile tile = Main.tile[x, y + 1]; if (IsNeighborSolid(tile) && tile.slope() != 1 && tile.slope() != 2 && !tile.halfBrick()) { return(false); } edge.Start = new Vector2(tilePosition.X, tilePosition.Y + 16f); edge.End = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f); return(true); } if ((edgesToTest & TileEdges.Top) != 0) { Tile tile2 = Main.tile[x, y - 1]; if (!Main.tile[x, y].halfBrick() && IsNeighborSolid(tile2) && tile2.slope() != 3 && tile2.slope() != 4) { return(false); } if (Main.tile[x, y].halfBrick()) { tilePosition.Y += 8f; } edge.Start = new Vector2(tilePosition.X, tilePosition.Y); edge.End = new Vector2(tilePosition.X + 16f, tilePosition.Y); return(true); } return(false); }
private static bool GetClosestEdgeToCircle(Vector2 position, Vector2 size, Vector2 velocity, out Vector2 collisionPoint, out Tile collisionTile) { Rectangle tileBounds = GetTileBounds(position, size); Vector2 vector = position + size * 0.5f; TileEdges tileEdges = TileEdges.None; tileEdges = ((!(velocity.Y < 0f)) ? (tileEdges | TileEdges.Top) : (tileEdges | TileEdges.Bottom)); tileEdges = ((!(velocity.X < 0f)) ? (tileEdges | TileEdges.Left) : (tileEdges | TileEdges.Right)); tileEdges = ((!(velocity.Y > velocity.X)) ? (tileEdges | TileEdges.TopRightSlope) : (tileEdges | TileEdges.BottomLeftSlope)); tileEdges = ((!(velocity.Y > 0f - velocity.X)) ? (tileEdges | TileEdges.TopLeftSlope) : (tileEdges | TileEdges.BottomRightSlope)); collisionPoint = Vector2.Zero; collisionTile = null; float num = float.MaxValue; Vector2 closestPointOut = default(Vector2); float distanceSquaredOut = 0f; for (int i = tileBounds.Left; i < tileBounds.Right; i++) { for (int j = tileBounds.Top; j < tileBounds.Bottom; j++) { if (GetCollisionPointForTile(tileEdges, i, j, vector, ref closestPointOut, ref distanceSquaredOut) && !(distanceSquaredOut >= num) && !(Vector2.Dot(velocity, vector - closestPointOut) > 0f)) { num = distanceSquaredOut; collisionPoint = closestPointOut; collisionTile = Main.tile[i, j]; } } } float num2 = size.X / 2f; return(num < num2 * num2); }
public TileOrientation(Tile tile, Orientation orientation) { Pixels = orientation.Apply(tile.Pixels); Tile = tile; Orientation = orientation; VisualString = string.Join("\n", Pixels); Name = $"{tile.TileId}+{orientation}"; Edges = new TileEdges(Pixels); }
private static bool GetSlopeEdge(ref TileEdges edgesToTest, Tile tile, Vector2 tilePosition, ref LineSegment edge) { switch (tile.slope()) { case 0: return(false); case 1: edgesToTest &= (TileEdges.Bottom | TileEdges.Left | TileEdges.BottomLeftSlope); if ((edgesToTest & TileEdges.BottomLeftSlope) == 0) { return(false); } edge.Start = tilePosition; edge.End = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f); return(true); case 2: edgesToTest &= (TileEdges.Bottom | TileEdges.Right | TileEdges.BottomRightSlope); if ((edgesToTest & TileEdges.BottomRightSlope) == 0) { return(false); } edge.Start = new Vector2(tilePosition.X, tilePosition.Y + 16f); edge.End = new Vector2(tilePosition.X + 16f, tilePosition.Y); return(true); case 3: edgesToTest &= (TileEdges.Top | TileEdges.Left | TileEdges.TopLeftSlope); if ((edgesToTest & TileEdges.TopLeftSlope) == 0) { return(false); } edge.Start = new Vector2(tilePosition.X, tilePosition.Y + 16f); edge.End = new Vector2(tilePosition.X + 16f, tilePosition.Y); return(true); case 4: edgesToTest &= (TileEdges.Top | TileEdges.Right | TileEdges.TopRightSlope); if ((edgesToTest & TileEdges.TopRightSlope) == 0) { return(false); } edge.Start = tilePosition; edge.End = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f); return(true); default: return(false); } }
public Tile(int tileId, IReadOnlyList <string> pixels, Grid grid) { TileId = tileId; Pixels = pixels; Grid = grid; _edges = new TileEdges(pixels); TileOrientations = Orientation.Permutations .Select(orientation => new TileOrientation(this, orientation)) .DistinctBy(tileOrientation => tileOrientation.VisualString) .ToArray(); _outerEdges = new Lazy <IReadOnlyList <string> >(() => _edges.All().Where(Grid.OuterEdges.Contains).ToArray()); }
private static bool GetCollisionPointForTile(TileEdges edgesToTest, int x, int y, Vector2 center, ref Vector2 closestPointOut, ref float distanceSquaredOut) { Tile tile = Main.tile[x, y]; if (tile == null || !tile.nactive() || (!Main.tileSolid[tile.type] && !Main.tileSolidTop[tile.type])) { return(false); } if (!Main.tileSolid[tile.type] && Main.tileSolidTop[tile.type] && tile.frameY != 0) { return(false); } if (Main.tileSolidTop[tile.type]) { edgesToTest &= (TileEdges.Top | TileEdges.BottomLeftSlope | TileEdges.BottomRightSlope); } Vector2 tilePosition = new Vector2((float)x * 16f, (float)y * 16f); bool flag = false; LineSegment edge = default(LineSegment); if (GetSlopeEdge(ref edgesToTest, tile, tilePosition, ref edge)) { closestPointOut = ClosestPointOnLineSegment(center, edge); distanceSquaredOut = Vector2.DistanceSquared(closestPointOut, center); flag = true; } if (GetTopOrBottomEdge(edgesToTest, x, y, tilePosition, ref edge)) { Vector2 vector = ClosestPointOnLineSegment(center, edge); float num = Vector2.DistanceSquared(vector, center); if (!flag || num < distanceSquaredOut) { distanceSquaredOut = num; closestPointOut = vector; } flag = true; } if (GetLeftOrRightEdge(edgesToTest, x, y, tilePosition, ref edge)) { Vector2 vector2 = ClosestPointOnLineSegment(center, edge); float num2 = Vector2.DistanceSquared(vector2, center); if (!flag || num2 < distanceSquaredOut) { distanceSquaredOut = num2; closestPointOut = vector2; } flag = true; } return(flag); }
private static bool GetLeftOrRightEdge(TileEdges edgesToTest, int x, int y, Vector2 tilePosition, ref LineSegment edge) { if ((edgesToTest & TileEdges.Left) != 0) { Tile tile = Main.tile[x, y]; Tile tile2 = Main.tile[x - 1, y]; if (IsNeighborSolid(tile2) && tile2.slope() != 1 && tile2.slope() != 3 && (!tile2.halfBrick() || tile.halfBrick())) { return(false); } edge.Start = new Vector2(tilePosition.X, tilePosition.Y); edge.End = new Vector2(tilePosition.X, tilePosition.Y + 16f); if (tile.halfBrick()) { edge.Start.Y += 8f; } return(true); } if ((edgesToTest & TileEdges.Right) != 0) { Tile tile3 = Main.tile[x, y]; Tile tile4 = Main.tile[x + 1, y]; if (IsNeighborSolid(tile4) && tile4.slope() != 2 && tile4.slope() != 4 && (!tile4.halfBrick() || tile3.halfBrick())) { return(false); } edge.Start = new Vector2(tilePosition.X + 16f, tilePosition.Y); edge.End = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f); if (tile3.halfBrick()) { edge.Start.Y += 8f; } return(true); } return(false); }
record TileRotationData(int Id, bool IsFlipped, int Rotations, TileEdges Edges, int[] Data);