/** * Check if the given tile is a wall. * If it is, add it to the given graph reference. */ private static void ComputeWall(String name, int x, int y, ref Graph.Graph graph) { // Prepare the regex matcher. RegEx rgx = new RegEx(); rgx.Compile("^Wall([SOW])_([TLBR]{1})(Door)?.*$"); // Get and check the result of the regex. RegExMatch result = rgx.Search(name); if (result != null) { // Get the type of wall. Tile.WallType type = Tile.WallType.WOOD; switch (result.GetString(1)) { case "S": type = Tile.WallType.STONE; break; case "O": type = Tile.WallType.OBSIDIAN; break; case "W": type = Tile.WallType.WOOD; break; } Tile.Orientation dir = Tile.Orientation.OTHER; switch (result.GetString(2)) { case "T": dir = Tile.Orientation.TOP; break; case "B": dir = Tile.Orientation.BOTTOM; break; case "L": dir = Tile.Orientation.LEFT; break; case "R": dir = Tile.Orientation.RIGHT; break; } // Check if the given wall is a door. bool bIsDoor = result.GetString(3).Equals("Door"); // Create a new Wall instance. Tile.Wall wall = new Tile.Wall(type, bIsDoor, dir); wall.Position = new Vector2(x, y); // Add it to the graph object. graph.AddWall(wall, x, y); } }
/** * Checks wether this tile belongs to a given face. */ private static void ComputeFace(int x, int y, ref Graph.Graph graph) { // Check wether this tile is a wall, a vertex, or an empty cell. Vector2 position = new Vector2(x, y); Tile.Wall cellWall = graph.GetWallAt(position); Graph.Vertex cellVtx = graph.GetVertexAt(position); if (cellWall == null && cellVtx == null) { // Get the top and left cells. Vector2 left = position + new Vector2(-1, 0); Vector2 top = position + new Vector2(0, -1); // Get the faces of the cells. Graph.Face leftFace = graph.GetFaceFromPoint(left); Graph.Face topFace = graph.GetFaceFromPoint(top); Graph.Face pointFace; // If both faces are null. if (leftFace == null && topFace == null) { // Create a new face. pointFace = new Graph.Face(); // Add the face to the graph. graph.AddFace(pointFace); // If both faces are different. } else if (leftFace != topFace) { { // Merge both faces together. pointFace = graph.MergeFaces(leftFace, topFace); // If both faces are the same. } } else { // Select it as the point's face. pointFace = leftFace; } // Add the point to the face. pointFace.AddPoint(position); } }
//MOUNTAINS //public Vector2[] GetMountainTileUvs (Tile tile) //{ // string key = tile.wall.ToString (); // if (tileUVMap.ContainsKey (key) == true) { // return tileUVMap [key]; // } else { // Debug.LogError ("No UV map for tile type: " + key); // return tileUVMap ["Void"]; // } //} public Vector2[] GetWallUVsAtQuadrant(Tile.Wall wall, int quadrant, Tile[] neighbours) { if (wall == Tile.Wall.Empty) { return(tileUVMap ["Empty"]); } string key = GetKeyForWall(wall, neighbours, quadrant); if (tileUVMap.ContainsKey(key) == true) { return(tileUVMap [key]); } else { Debug.LogError("No UV map for tile type: " + key); return(tileUVMap ["Void"]); } }
//checks quads neighbouring tiles to assign correct texture string GetKeyForWall(Tile.Wall wall, Tile[] neighbours, int quadrant) { string key = wall.ToString() + "_" + quadrant.ToString(); if (quadrant == 1) { if (IsWallEmptyOrNull(neighbours [0]) && IsWallEmptyOrNull(neighbours [1]) && IsWallEmptyOrNull(neighbours [4])) { key += "Corner"; return(key); } if (!IsWallEmptyOrNull(neighbours [0]) && !IsWallEmptyOrNull(neighbours [1]) && IsWallEmptyOrNull(neighbours [4])) { key += "iCorner"; return(key); } if (IsWallEmptyOrNull(neighbours [0])) { key += "N"; return(key); } if (IsWallEmptyOrNull(neighbours [1])) { key += "E"; return(key); } } if (quadrant == 2) { if (IsWallEmptyOrNull(neighbours [2]) && IsWallEmptyOrNull(neighbours [1]) && IsWallEmptyOrNull(neighbours [5])) { key += "Corner"; return(key); } if (!IsWallEmptyOrNull(neighbours [2]) && !IsWallEmptyOrNull(neighbours [1]) && IsWallEmptyOrNull(neighbours [5])) { key += "iCorner"; return(key); } if (IsWallEmptyOrNull(neighbours [2])) { key += "S"; return(key); } if (IsWallEmptyOrNull(neighbours [1])) { key += "E"; return(key); } } if (quadrant == 3) { if (IsWallEmptyOrNull(neighbours [2]) && IsWallEmptyOrNull(neighbours [3]) && IsWallEmptyOrNull(neighbours [6])) { key += "Corner"; return(key); } if (!IsWallEmptyOrNull(neighbours [2]) && !IsWallEmptyOrNull(neighbours [3]) && IsWallEmptyOrNull(neighbours [6])) { key += "iCorner"; return(key); } if (IsWallEmptyOrNull(neighbours [2])) { key += "S"; return(key); } if (IsWallEmptyOrNull(neighbours [3])) { key += "W"; return(key); } } if (quadrant == 4) { if (IsWallEmptyOrNull(neighbours [0]) && IsWallEmptyOrNull(neighbours [3]) && IsWallEmptyOrNull(neighbours [7])) { key += "Corner"; return(key); } if (!IsWallEmptyOrNull(neighbours [0]) && !IsWallEmptyOrNull(neighbours [3]) && IsWallEmptyOrNull(neighbours [7])) { key += "iCorner"; return(key); } if (IsWallEmptyOrNull(neighbours [0])) { key += "N"; return(key); } if (IsWallEmptyOrNull(neighbours [3])) { key += "W"; return(key); } } return(key); }
// --- Attributes --- // -- Properties -- // -- Public Attributes -- // -- Private Attributes -- // --- /Attributes --- // --- Methods --- // -- Public Methods -- /** * Loads all data from the TileMaps below the given node. * Returns a Graph object, loaded with all the required data. */ public static Graph.Graph LoadGraph(Node root) { // Prepare the Graph instance. Graph.Graph graph = new Graph.Graph(); // Find all tilemap subnodes. Generic.List <TileMap> tilemaps = FindTilemapsUnder(root); // Get the limits of all the tilesets. Rect2 limits = GetTilemapsLimits(tilemaps); // Compute the limits of the loops. Vector2 start = limits.Position; Vector2 end = limits.Position + limits.Size; // Loop through each tilemap. foreach (TileMap tilemap in tilemaps) { // Loop through the limits of the tilemap. for (int x = (int)start.x; x < end.x; x++) { for (int y = (int)start.y; y < end.y; y++) { // First, get the identifier of the cell. int tileID = tilemap.GetCell(x, y); // If the identifier is not -1. if (tileID != -1) { { // Get the name of the tile. String tileName = tilemap.TileSet.TileGetName(tileID); // Check if the tile is a wall. ComputeWall(tileName, x, y, ref graph); // Check if the tile is a vertex. ComputeVertex(tileName, x, y, ref graph); // Compute the cost of the tile. ComputeCost(x, y, tilemap); } } // If the tilemap handles zone splitting. if (tilemap.CollisionMask == 0b1000) { // Compute the face this tile belongs to. ComputeFace(x, y, ref graph); // If there is a tile. if (tileID != -1) { // Compute the resources on that tile. ComputeResource(x, y, tilemap, ref graph); } } } } } // Prepare the list of vertices to remove. Generic.List <Graph.Vertex> VerticesToRemove = new Generic.List <Graph.Vertex>(); // Loop through each vertex. foreach (Graph.Vertex vtx in graph.Vertices) { // Check all four sides. Vector2[] directions = new Vector2[] { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right }; foreach (Vector2 dir in directions) { // Check if a wall is present and has not been computed. Vector2 currentPosition = vtx.Position + dir; Tile.Wall dirWall = graph.GetWallAt(currentPosition); if (dirWall != null && dirWall.Edge == null) { // Get the rooms on each side of the wall. Graph.Face[] faces = graph.GetFacesFromWall(currentPosition); // Start computing a new edge. Graph.Edge edge = new Graph.Edge(faces); // Add the edges to the face. edge.RightFace = faces[0]; edge.LeftFace = faces[1]; // Loop until a new vertex is found. while (graph.GetVertexAt(currentPosition) == null) { // If the wall exists. Tile.Wall wall = graph.GetWallAt(currentPosition); if (wall != null) { // Add the wall to the edge. edge.AddWall(wall); // Increment the position. currentPosition += dir; // If the wall stops abruptly, stop execution. } else { throw new Exception("FATAL ERROR: Stray wall found @ " + currentPosition + " ..."); } } // Add the vertices to the edge. edge.StartVertex = vtx; edge.EndVertex = graph.GetVertexAt(currentPosition); // Add the edge to the graph. vtx.Edges.Add(edge); graph.AddEdge(edge); // Add the edge to the face. foreach (Graph.Face face in faces) { face.AddEdge(edge); } } } // After that is done, check if the vertex object is NOT a tower. if (!vtx.IsTower) { // If the vertex has two edges. if (vtx.Edges.Count == 2) { // Get the vertex's edges. Tuple <Graph.Edge, Graph.Edge> edges = new Tuple <Graph.Edge, Graph.Edge>( vtx.Edges[0], vtx.Edges[1] ); // Merge the edges together. edges.Item1.Merge(edges.Item2); // Remove the second edge. graph.RemoveEdge(edges.Item2); // If the vertex has one single edge. } else if (vtx.Edges.Count == 1) { // Add the vertex's wall to the edge. vtx.Edges[0].AddWall(vtx.Wall); } // Add the vertex to removal. VerticesToRemove.Add(vtx); } } // Remove the vertices. foreach (Graph.Vertex vtx in VerticesToRemove) { graph.RemoveVertex(vtx); } // Return the generated graph. GD.Print(graph.ToString()); return(graph); }