public void Transformation_ShallBeSet() { var point = new Point(10, 1); var result = new TilePattern(point); Assert.AreEqual(point, result.Transformation); }
//////////////// public static float GaugeNearbyManaShards(Vector2 worldPos, out Point?nearestShardTile) { var config = FMCConfig.Instance; int maxTileRange = config.Get <int>(nameof(config.ManaShardPKEDetectionTileRangeMax)); if (maxTileRange <= 0) { nearestShardTile = null; return(0f); } var pattern = new TilePattern(new TilePatternBuilder { IsActive = true, IsAnyOfType = new HashSet <int> { ModContent.TileType <ManaCrystalShardTile>() } }); int maxDist = maxTileRange * 16; nearestShardTile = TileFinderLibraries.GetNearestTile(worldPos, pattern, maxDist); if (!nearestShardTile.HasValue) { return(0f); } Vector2 worldPosAt = new Vector2(nearestShardTile.Value.X * 16, nearestShardTile.Value.Y * 16); float distPerc = (worldPosAt - worldPos).Length() / (float)maxDist; return(Math.Max(1f - distPerc, 0f)); }
public static IList <(ushort x, ushort y)> FindNearbyHittableTiles( Vector2 position, Rectangle hitArea, bool respectsPlatforms) { var tilePattern = new TilePattern( new TilePatternBuilder { IsActive = true, HasSolidProperties = true, IsPlatform = respectsPlatforms } ); //true, respectsPlatforms, false, null, null, null ); IList <(ushort, ushort)> hits = TileFinderHelpers.GetTileMatchesInWorldRectangle(hitArea, tilePattern); if (hits.Count == 0) { Point?point = TileFinderHelpers.GetNearestTile(position, tilePattern, 32); if (point.HasValue) { hits.Add(((ushort)point.Value.X, (ushort)point.Value.Y)); } } return(hits); }
public static void TeleportTile(int tileX, int tileY) { var config = FMCConfig.Instance; (int newTileX, int newTileY)tileAt; TilePattern pattern = ModContent.GetInstance <FMCWorld>().ManaCrystalShardPattern; int rad = config.Get <int>(nameof(FMCConfig.ManaCrystalShardTeleportRadius)); var within = new Rectangle( (int)MathHelper.Clamp(tileX - rad, 64, (Main.maxTilesX - 64) - (rad + rad)), (int)MathHelper.Clamp(tileY - rad, 64, (Main.maxTilesY - 64) - (rad + rad)), rad + rad, rad + rad ); if (FindableManaCrystalsWorldGenPass.GetRandomShardAttachableTile(within, 100, pattern, out tileAt)) { TileLibraries.Swap1x1Synced(tileX, tileY, tileAt.newTileX, tileAt.newTileY, true, true, true); for (int i = 0; i < 4; i++) { Dust.NewDust( Position: new Vector2(tileX << 4, tileY << 4), Width: 16, Height: 17, Type: 229 ); } } }
/// <summary> /// Attempts a basic trace to see if a given entity is visible from a given point by line of sight (no obstructing tiles). /// </summary> /// <param name="position"></param> /// <param name="ent"></param> /// <param name="blockingTilePatten"></param> /// <returns></returns> public static bool SimpleLineOfSight(Vector2 position, Entity ent, TilePattern blockingTilePatten) { var trace = new Utils.PerLinePoint(delegate(int tileX, int tileY) { return(!blockingTilePatten.Check(tileX, tileY)); }); return(Utils.PlotTileLine(position, ent.Center, 1, trace)); }
//////////////// /// <summary> /// Drops from a given point to the ground. /// </summary> /// <param name="worldPos"></param> /// <param name="invertGravity"></param> /// <param name="ground">Tile pattern checker to define what "ground" is.</param> /// <param name="groundPos"></param> /// <returns>`true` if a ground point was found within world boundaries.</returns> public static bool DropToGround(Vector2 worldPos, bool invertGravity, TilePattern ground, out Vector2 groundPos) { int furthestTileY = invertGravity ? 42 : Main.maxTilesY - 42; return(WorldHelpers.DropToGround(worldPos, invertGravity, ground, furthestTileY, out groundPos)); }
//////////////// public MountedMirrorsGenPass(int mirrors) : base("PopulateMountedMirrors", 1f) { this.MirrorSpacePattern = new TilePattern(new TilePatternBuilder { AreaFromCenter = new Rectangle(-1, -1, 3, 3), HasWall = true, HasLava = false, HasSolidProperties = false, IsPlatform = false, IsActuated = false, }); this.NeededMirrors = mirrors; }
//////////////// public AmbushManager(WorldSize size) { var dungeonWalls = new HashSet <int>(TileWallHelpers.UnsafeDungeonWallTypes); dungeonWalls.Add(WallID.LihzahrdBrickUnsafe); this.ViableAmbushTilePattern = new TilePattern(new TilePatternBuilder { HasSolidProperties = false, IsPlatform = false, IsActuated = false, MaximumBrightness = 0.25f, CustomCheck = (x, y) => !dungeonWalls.Contains(Main.tile[x, y].wall) }); }
public void ShouldSerializeTilePattern() { var expected = "{" + "\"Height\":8," + "\"Interleave\":true," + "\"Map\":[[0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,14,14,14,14,14,14,14,14],[1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,5,5,5,5,5,5,5,5,7,7,7,7,7,7,7,7,9,9,9,9,9,9,9,9,11,11,11,11,11,11,11,11,13,13,13,13,13,13,13,13,15,15,15,15,15,15,15,15]]," + "\"Order\":\"Planar\"," + "\"Size\":16," + "\"Width\":8}"; var tilePattern = new TilePattern() { Height = 8, Interleave = true, Order = EnumTileOrder.Planar, Size = 16, Width = 8, }; tilePattern.Map.AddRange(new List <List <short> >() { new List <short>() { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, }, new List <short>() { 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11, 11, 11, 11, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15, 15, 15, }, }); var result = JsonConvert.SerializeObject(tilePattern); Assert.That(expected, Is.EqualTo(result)); }
private IntroMovieSet( TileStructure shipExterior, TileStructure shipInterior, int extTileLeft, int extTileTop, int intTileLeft, int intTileTop, bool isFlipped ) : this(extTileLeft, extTileTop, intTileLeft, intTileTop) { shipExterior.PaintToWorld( leftTileX: extTileLeft, topTileY: extTileTop, paintAir: false, respectLiquids: true, flipHorizontally: isFlipped, flipVertically: false ); shipInterior.PaintToWorld( leftTileX: intTileLeft, topTileY: intTileTop, paintAir: false, respectLiquids: true, flipHorizontally: isFlipped, flipVertically: false ); // var nonDeckPattern = new TilePattern(new TilePatternBuilder { IsNotAnyOfType = new HashSet <int> { TileID.Platforms } }); this.ExteriorDeckWidth = TileFinderHelpers.GetFloorWidth( nonFloorPattern: nonDeckPattern, tileX: extTileLeft + (shipExterior.Bounds.Width / 2), tileY: extTileTop, maxFallRange: 50, floorX: out this.ExteriorDeckX, floorY: out this.ExteriorDeckY ); }
public void ShouldRearrangeBits() { var data = new byte[] { 0x18, 0x10 }; var plan = new List <List <short> >() { new List <short>() { 0, 0, 0, 0, 0, 0, 0, 0, }, new List <short>() { 1, 1, 1, 1, 1, 1, 1, 1, }, }; var pattern = new TilePattern(plan) { Interleave = false, Size = 2, }; var bits = new BitList(data); var bitsRearranged = bits.RearrangeBitsWith2Planes(pattern); Assert.That(bitsRearranged[0], Is.EqualTo(false)); Assert.That(bitsRearranged[1], Is.EqualTo(false)); Assert.That(bitsRearranged[2], Is.EqualTo(false)); Assert.That(bitsRearranged[3], Is.EqualTo(false)); Assert.That(bitsRearranged[4], Is.EqualTo(false)); Assert.That(bitsRearranged[5], Is.EqualTo(false)); Assert.That(bitsRearranged[6], Is.EqualTo(true)); Assert.That(bitsRearranged[7], Is.EqualTo(true)); Assert.That(bitsRearranged[8], Is.EqualTo(true)); Assert.That(bitsRearranged[9], Is.EqualTo(false)); Assert.That(bitsRearranged[10], Is.EqualTo(false)); Assert.That(bitsRearranged[11], Is.EqualTo(false)); Assert.That(bitsRearranged[12], Is.EqualTo(false)); Assert.That(bitsRearranged[13], Is.EqualTo(false)); Assert.That(bitsRearranged[14], Is.EqualTo(false)); Assert.That(bitsRearranged[15], Is.EqualTo(false)); }
/// <summary> /// Drops from a given point to the ground. /// </summary> /// <param name="worldPos"></param> /// <param name="invertGravity"></param> /// <param name="ground">Tile pattern checker to define what "ground" is.</param> /// <param name="furthestTileY">Limit to check tiles down (or up) to before giving up.</param> /// <param name="groundPos"></param> /// <returns>`true` if a ground point was found within world boundaries.</returns> public static bool DropToGround(Vector2 worldPos, bool invertGravity, TilePattern ground, int furthestTileY, out Vector2 groundPos) { bool hitGround = true; int tileX = (int)worldPos.X >> 4; int tileY = (int)worldPos.Y >> 4; if (invertGravity) { do { tileY--; if (tileY >= furthestTileY) { hitGround = false; break; } } while(!ground.Check(tileX, tileY)); } else { do { tileY++; if (tileY >= furthestTileY) { hitGround = false; break; } } while(!ground.Check(tileX, tileY)); } groundPos = new Vector2(worldPos.X, tileY * 16); return(hitGround); }
/// <summary> /// Enumerates all positionf of the tiles adjacent to the current tile. /// </summary> /// <param name="tile">The postion of the tile.</param> /// <param name="index"></param> /// <param name="pattern">The pattern that is used.</param> /// <returns></returns> /// <remarks> /// The first tile is usually the north tile. The only tiles in a triangular pattern, with one odd and one even /// coordinate. In that case first title is the south located tile. The following tiltes are enumerated counter /// clockwise. /// </remarks> public static TilePosition GetAdjacentTile(this ITilePosition tile, int index, TilePattern pattern) { if (index <= 0) { throw new ArgumentOutOfRangeException(nameof(index)); } int x = tile.X; int y = tile.Y; switch (pattern) { case TilePattern.Triangular: // check for odd tiles return(((x & 1) ^ (y & 1)) == 1 ? _oddTriangularAdjacents[index % (int)pattern](tile) : _evenTriangularAdjacents[index % (int)pattern](tile)); case TilePattern.Rectangular: return(_rectangularAdjacents[index % (int)pattern](tile)); case TilePattern.Hexangular: return(_hexangularAdjacents[index % (int)pattern](tile)); default: throw new ArgumentOutOfRangeException(nameof(pattern), pattern, $"Pattern {pattern} not supported."); } }
/// <summary> /// Enumerates all positionf of the tiles adjacent to the current tile. /// </summary> /// <param name="tile">The postion of the tile.</param> /// <param name="pattern">The pattern that is used.</param> /// <returns></returns> /// <remarks> /// The first tile is usually the north tile. The only tiles in a triangular pattern, with one odd and one even /// coordinate. In that case first title is the south located tile. The following tiltes are enumerated counter /// clockwise. /// </remarks> public static IEnumerable <TilePosition> GetAdjacentTiles(this ITilePosition tile, TilePattern pattern) { int x = tile.X; int y = tile.Y; switch (pattern) { case TilePattern.Triangular: // check for odd tiles return(((x & 1) ^ (y & 1)) == 1 ? _oddTriangularAdjacents.Select(t => t(tile)) : _evenTriangularAdjacents.Select(t => t(tile))); case TilePattern.Rectangular: return(_rectangularAdjacents.Select(t => t(tile))); case TilePattern.Hexangular: return(_hexangularAdjacents.Select(t => t(tile))); default: throw new ArgumentOutOfRangeException(nameof(pattern), pattern, $"Pattern {pattern} not supported."); } }
public void ShallNotBeDoor() { var result = new TilePattern(new Point(10, 1)); Assert.False(result.IsDoor); }
/// <summary> /// Finds the top left tile of a given pattern. /// </summary> /// <param name="pattern"></param> /// <param name="tileX"></param> /// <param name="tileY"></param> /// <param name="maxDistance"></param> /// <param name="coords"></param> /// <returns>Returns tile coordinates, or else `null` if not found within the given max amounts.</returns> public static bool FindTopLeftOfSquare( TilePattern pattern, int tileX, int tileY, int maxDistance, out (int TileX, int TileY) coords)
GameObject IdentifyTile(int x, int y) { GameObject tmp; TileType up = grid.GetTileType(x, y - 1); TileType down = grid.GetTileType(x, y + 1); TileType left = grid.GetTileType(x - 1, y); TileType right = grid.GetTileType(x + 1, y); int i; int emptyCorners = (grid.GetTileType(x - 1, y - 1) == TileType.EMPTY ? 1 : 0) + (grid.GetTileType(x + 1, y - 1) == TileType.EMPTY ? 1 : 0) + (grid.GetTileType(x - 1, y + 1) == TileType.EMPTY ? 1 : 0) + (grid.GetTileType(x + 1, y + 1) == TileType.EMPTY ? 1 : 0); var outerCornerPattern = TilePattern.Create("? ?", " S?", "???"); GridTileMatcher.MatchPattern(grid, x, y, outerCornerPattern).IfPresent(rotation => { var gameObject = Instantiate(outerCorner); gameObject.transform.localRotation = Quaternion.Euler(-90, 0, 0) * rotation.ToQuat(); }); i = (up == TileType.EMPTY ? 1 : 0) + (left == TileType.EMPTY ? 1 : 0) + (right == TileType.EMPTY ? 1 : 0) + (down == TileType.EMPTY ? 1 : 0); if (grid.GetTileType(x, y) == TileType.EMPTY) { tmp = Instantiate(groundUp); return(tmp); } if (i == 1) { tmp = Instantiate(straightWall); if (up == TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 180, 0); } else if (left == TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 270, 0); } else if (right == TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 90, 0); } return(tmp); } if (i == 2 && !(up != TileType.EMPTY && down != TileType.EMPTY || left != TileType.EMPTY && right != TileType.EMPTY)) { tmp = Instantiate(innerCorner); if (grid.GetTileType(x - 1, y - 1) != TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 90, 0); } else if (grid.GetTileType(x - 1, y + 1) != TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 180, 0); } else if (grid.GetTileType(x + 1, y + 1) != TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 270, 0); } return(tmp); } if (i == 0 && emptyCorners == 1) { tmp = Instantiate(outerCorner); if (grid.GetTileType(x - 1, y - 1) == TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 180, 0); } else if (grid.GetTileType(x - 1, y + 1) == TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 270, 0); } else if (grid.GetTileType(x + 1, y - 1) == TileType.EMPTY) { tmp.transform.localRotation = Quaternion.Euler(-90, 90, 0); } return(tmp); } tmp = Instantiate(ground); return(tmp); }
public static bool GetRandomShardAttachableTile( Rectangle within, int maxAttempts, TilePattern pattern, out (int TileX, int TileY) randTile)