/// <summary> /// splits the input collection into 1 List for each contiguous area formed by the input tile coordinates. /// </summary> /// ![left = input tile list , right = output separated into different areas](Map_GetTiles_ContiguousCombined.png) public static List <List <Vector3Int> > ContiguousAreasOfInputTiles(ICollection <Vector3Int> inputTiles) { if (inputTiles.Count == 0) { return(new List <List <Vector3Int> >()); } List <List <Vector3Int> > areas = new List <List <Vector3Int> >(); HashSet <Vector3Int> unusedTiles = new HashSet <Vector3Int>(inputTiles); while (unusedTiles.Count > 0) { HashSet <Vector3Int> area = new HashSet <Vector3Int>(); Queue <Vector3Int> queue = new Queue <Vector3Int>(); queue.Enqueue(unusedTiles.First()); while (queue.Count > 0) { Vector3Int current = queue.Dequeue(); area.Add(current); unusedTiles.Remove(current); List <Vector3Int> neighbours = GetTiles.AdjacentToTile(current); neighbours.RemoveAll(x => !unusedTiles.Contains(x)); foreach (var tile in neighbours) { queue.Enqueue(tile); } } areas.Add(area.ToList()); } return(areas); }
/// <summary> /// returns the 3 edges which share the input corner /// </summary> /// ![green = input corner , blue = result](GetEdges_AdjacentToCorner.png) public static List <Vector3Int> AdjacentToCorner(Vector3Int corner) { //INTERIM INEFFICIENT SOLUTION: we get the neighbouring tile coordinates then Edge AB AC and BC //SHOULD just directly offset the coordinates depending on the 2 different corner position types List <Vector3Int> tiles = GetTiles.AdjacentToCorner(corner); Vector3Int edgeA = GetEdge.BetweenTiles(tiles[0], tiles[1]); Vector3Int edgeB = GetEdge.BetweenTiles(tiles[0], tiles[2]); Vector3Int edgeC = GetEdge.BetweenTiles(tiles[1], tiles[2]); return(new List <Vector3Int> { edgeA, edgeB, edgeC }); }
/// <summary> /// returns all tiles of a cone starting at a point with given direction, length and width /// </summary> /// ![yellow = origin , blue = direction, green/blue = cone tiles](GetTiles_Cone.png) public static List <Vector3Int> Cone(Vector3Int origin, Vector3Int targetDirection, float coneWidthHalfAngle, int coneLength) { Vector3 originCartesian = HexConverter.TileCoordToCartesianCoord(origin); IEnumerable <Vector3Int> ring = GetTiles.Ring(origin, coneLength, 1); HashSet <Vector3Int> cone = new HashSet <Vector3Int>(); foreach (Vector3Int target in ring) { Vector3 targetWorldPos = HexConverter.TileCoordToCartesianCoord(target); Vector3 lookWorldPos = HexConverter.TileCoordToCartesianCoord((origin + targetDirection)); float angle = Vector3.Angle(targetWorldPos - originCartesian, lookWorldPos - originCartesian); if (Mathf.Abs(angle) > coneWidthHalfAngle + 0.001) { continue; } List <Vector3Int> linePointsL = GetTiles.Line(origin, target, false, -0.00001f); //for more consistent results we use 2 lines, one slightly left of center List <Vector3Int> linePointsR = GetTiles.Line(origin, target, false, +0.00001f); //and this her slightly right of center cone.UnionWith(linePointsL); cone.UnionWith(linePointsR); } return(cone.ToList()); }
/// <summary> /// returns all tiles of a ring around center in order specified by parameters (startDirection, clockwise) /// </summary> public static List <Vector3Int> Ring(Vector3Int center, int radius, TileDirection startDirection = TileDirection.TopRight, bool clockwise = true) { if (radius < 1) { throw new System.ArgumentException("radius needs to be larger than 0"); } List <Vector3Int> ringTiles = new List <Vector3Int>(); System.Func <Vector3Int, Vector3Int, Vector3Int> rotationMethod; if (clockwise == true) { rotationMethod = GetTile.FromTileRotated60DegreeClockwise; } else { rotationMethod = GetTile.FromTileRotated60DegreeCounterClockwise; } Vector3Int startOfRing = center + (TileDirectionVectors[(int)startDirection] * radius); ringTiles.Add(startOfRing); Vector3Int[] ringCornerTiles = new Vector3Int[6]; ringCornerTiles[0] = startOfRing; for (int i = 1; i < 6; i++) { ringCornerTiles[i] = rotationMethod(center, ringCornerTiles[i - 1]); } for (int i = 0; i < 6; i++) { List <Vector3Int> tilesOfRingSegment = GetTiles.Line(ringCornerTiles[i], ringCornerTiles[(i + 1) % 6], false); ringTiles.AddRange(tilesOfRingSegment); } ringTiles.RemoveAt(ringTiles.Count - 1); return(ringTiles); }
public EditorCursor cursor; // This should not be here but I added the cursor visualiser lazily, that's why it's here. Cut me some slack it WAS 2:00 AM. :P void Awake() { // Get the LevelManager because it's very important... 'level-editor' level = GetComponent <LevelManager>(); getTiles = new GetTiles(level); }