private void OnDrawGizmos() { if (doPath) { if (epf == null) { epf = new EntityPathFinder(GameManager.PathFinder); } Path_ = null; if (epf.IsRunning) { epf.ForceStop(); } else { epf.FindPath(Player.TilePos, Player.TilePos + GameManager.RNG.RandomVec2i(-100, 100)); } /*Debug.Log("calculating path"); * GenerationRandom genRan = new GenerationRandom(Time.frameCount); * Path_ = GameManager.PathFinder.GeneratePath(Vec2i.FromVector3(Player.Position), Vec2i.FromVector3(Player.Position) + genRan.RandomVec2i(-100, 100)); */ return; Settlement t = GameManager.TestSettle; if (t == null) { return; } int curDist = -1; Vec2i pPos = Vec2i.FromVector2(Player.Position2); foreach (SettlementPathNode pn in t.tNodes) { if (pn == null) { continue; } if (NearestNode == null) { NearestNode = pn; curDist = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos); } else { if (Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos) < curDist) { curDist = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos); NearestNode = pn; } } } path = new List <SettlementPathNode>(); if (SettlementPathFinder.SettlementPath(NearestNode, t.IMPORTANT, out path, debug: true)) { Debug.Log("Path found!"); } Debug.Log("Path len: " + path.Count); } if (Path_ == null && epf != null) { if (epf.IsComplete()) { Path_ = epf.GetPath(); } } if (Path_ != null && Path_.Count > 1) { Color old = Gizmos.color; Gizmos.color = Color.yellow; //Debug.Log(Vec2i.ToVector3(path[0].Position + t.BaseCoord)); //Gizmos.DrawCube(Vec2i.ToVector3(path[0].Position + GameManager.TestSettle.BaseCoord), Vector3.one * 2); Gizmos.DrawCube(Vec2i.ToVector3(Path_[0]), Vector3.one * 5); Gizmos.DrawCube(Vec2i.ToVector3(Path_[Path_.Count - 1]), Vector3.one * 5); for (int i = 0; i < Path_.Count - 1; i++) { Gizmos.DrawLine(Vec2i.ToVector3(Path_[i]), Vec2i.ToVector3(Path_[i + 1])); Gizmos.DrawCube(Vec2i.ToVector3(Path_[i]), Vector3.one * 0.5f); } Gizmos.color = old; } return; if (NearestNode == null) { Settlement t = GameManager.TestSettle; if (t == null) { return; } int curDist = -1; Vec2i pPos = Vec2i.FromVector2(Player.Position2); foreach (SettlementPathNode pn in t.tNodes) { if (pn == null) { continue; } if (NearestNode == null) { NearestNode = pn; curDist = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos); } else { if (Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos) < curDist) { curDist = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos); NearestNode = pn; } } } path = new List <SettlementPathNode>(); if (SettlementPathFinder.SettlementPath(NearestNode, t.IMPORTANT, out path, debug: true)) { Debug.Log("Path found!"); } Debug.Log("Path len: " + path.Count); } }
private void CreatePathNodes() { int nodeSize = TileSize / NODE_RES; int tSize = TileSize / NODE_RES; int checkDist = 4; //Create a node at every node position not inside a building for (int x = 0; x < tSize; x++) { for (int z = 0; z < tSize; z++) { if (TestNodes2[x, z] != null) { continue; } if (PathNodes[x, z] != 0) { continue; } //Define the position of this node in the settlement Vec2i pos = new Vec2i(x * NODE_RES, z * NODE_RES); if (IsTileFree(pos.x, pos.z)) { PathNodes[x, z] = 50; //TestNodes2[x, z] = new SettlementPathNode(new Vec2i(x * NODE_RES, z * NODE_RES)); } else { PathNodes[x, z] = -1; } } } for (int x = 0; x < tSize; x++) { for (int z = 0; z < tSize; z++) { if (PathNodes[x, z] <= 0) { continue; } if (PathNodes[x, z] == 100) { continue; } if (x > 0 && PathNodes[x - 1, z] != 0) { //If nodes [x,z] and [x-1,z] are both non 0, check if a path exists between them //If there is no path, we try to remove one of the nodes if (!IsAreaFree((x - 1) * PathNodeRes, z * PathNodeRes - 1, PathNodeRes, 3, Tile.TEST_BLUE)) { PathNodes[x, z] = -1; /* * //Choose the x coord of the node to remove * int remX = GenerationRandom.RandomInt(-1, 1) + x; * //Check if the node belongs to the main path, * //if so, we remove the other node * if (PathNodes[remX, z] == 100) * { * if (remX == x - 1) PathNodes[x, z] = 0; * else PathNodes[x - 1, z] = 0; * } * else * PathNodes[remX, z] = 0;*/ } } if (z > 0 && PathNodes[x, z - 1] != 0) { //If nodes [x,z] and [x,z-1] are both non 0, check if a path exists between them //If there is no path, we try to remove one of the nodes if (!IsAreaFree((x) * PathNodeRes - 1, (z - 1) * PathNodeRes, 3, PathNodeRes, Tile.TEST_BLUE)) { PathNodes[x, z] = -1; continue; //Choose the x coord of the node to remove int remZ = GenerationRandom.RandomInt(-1, 1) + z; //Check if the node belongs to the main path, //if so, we remove the other node if (PathNodes[x, remZ] == 100) { if (remZ == z - 1) { PathNodes[x, z] = 0; } else { PathNodes[x, z - 1] = 0; } } else { PathNodes[x, remZ] = 0; } } } if (x < tSize - 1 && PathNodes[x + 1, z] != 0) { if (!IsAreaFree(x * PathNodeRes, z * PathNodeRes - 1, PathNodeRes, 3, Tile.TEST_BLUE)) { PathNodes[x, z] = -1; continue; //Choose the x coord of the node to remove int remX = GenerationRandom.RandomInt(0, 2) + x; //Check if the node belongs to the main path, //if so, we remove the other node if (PathNodes[remX, z] == 100) { if (remX == x + 1) { PathNodes[x, z] = 0; } else { PathNodes[x + 1, z] = 0; } } else { PathNodes[remX, z] = 0; } } } if (z < tSize - 1 && PathNodes[x, z + 1] != 0) { if (!IsAreaFree(x * PathNodeRes - 1, z * PathNodeRes, 3, PathNodeRes, Tile.TEST_BLUE)) { PathNodes[x, z] = -1; continue; //Choose the x coord of the node to remove int remZ = GenerationRandom.RandomInt(0, 2) + z; //Check if the node belongs to the main path, //if so, we remove the other node if (PathNodes[x, remZ] == 100) { if (remZ == z + 1) { PathNodes[x, z] = 0; } else { PathNodes[x, z + 1] = 0; } } else { PathNodes[x, remZ] = 0; } } } } } float[] nodes_ = new float[4]; //Remove circular path nodes for (int x = 0; x < tSize - 1; x++) { for (int z = 0; z < tSize - 1; z++) { nodes_[0] = PathNodes[x, z]; nodes_[1] = PathNodes[x + 1, z]; nodes_[2] = PathNodes[x + 1, z + 1]; nodes_[3] = PathNodes[x, z + 1]; //If all nodes have a path on them if (nodes_[0] > 0 && nodes_[1] > 0 && nodes_[2] > 0 && nodes_[3] > 0) { int destroy = GenerationRandom.RandomInt(0, 4); while (nodes_[destroy] == 100) { destroy = GenerationRandom.RandomInt(0, 4); } switch (destroy) { case 0: PathNodes[x, z] = 0; break; case 1: PathNodes[x + 1, z] = 0; break; case 2: PathNodes[x + 1, z + 1] = 0; break; case 3: PathNodes[x, z + 1] = 0; break; } } } } //Create a settlement path finder, we will use this to find and remove islands SettlementPathFinder = new SettlementPathFinder(BaseCoord, PathNodes); List <Vec2i> testing; List <Vec2i> tested = new List <Vec2i>(PNSize * PNSize / 4); //Iterate all nodes for (int x = 0; x < tSize; x++) { for (int z = 0; z < tSize; z++) { //If node is 0, we ignore it if (PathNodes[x, z] <= 0) { continue; } int conCount = ConnectedCount(x, z); /* * if (conCount == 0) * { * PathNodes[x, z] = -1; * SettlementPathFinder.PathNodes[x, z] = -1; * }*/ Vec2i pnPos = new Vec2i(x, z); //If we have already tested this point //If a node has only 1 connection, it is a good candidate //for checking for islands //if (conCount == 1) if (true) { float cost; //We check to see if a path can be found to the entrance from this node if (SettlementPathFinder.ConnectNodes(pnPos, EntranceNode, out testing, out cost, false)) { foreach (Vec2i v in testing) { if (PathNodes[v.x, v.z] <= 0) { PathNodes[v.x, v.z] = 50; SettlementPathFinder.PathNodes[v.x, v.z] = 50; } } //If a valid path is found, we add the entire path to the list of tested paths, to reduce double checking. // Debug.Log("Path found with cost " + cost); if (cost < int.MaxValue) { tested.AddRange(testing); foreach (Vec2i v in testing) { PathNodes[v.x, v.z] = 50; SettlementPathFinder.PathNodes[v.x, v.z] = 50; } } } else { //Debug.Log("Node " + x + "," + z + " is island. Path cost = " + cost); bool canMake = true; //If no path is found, we iterate each tested point and remove the path foreach (Vec2i v in testing) { if (PathNodes[v.x, v.z] == -1) { canMake = false; break; } // PathNodes[v.x, v.z] = 0; //SettlementPathFinder.PathNodes[v.x, v.z] = 0; } if (canMake) { foreach (Vec2i v in testing) { if (PathNodes[v.x, v.z] != 100) { PathNodes[v.x, v.z] = 50; SettlementPathFinder.PathNodes[v.x, v.z] = 50; } } } else { //TODO - do we need to delete all points if this happens? } } } } } //Connect all nodes for (int x = 0; x < tSize; x++) { for (int z = 0; z < tSize; z++) { if (PathNodes[x, z] <= 0) { continue; } bool is100 = PathNodes[x, z] == 100; if (x > 0 && PathNodes[x - 1, z] > 0) { if (!(PathNodes[x - 1, z] == 100 && is100)) { SetTiles((x - 1) * NODE_RES, z * NODE_RES - 1, (x) * NODE_RES, z * NODE_RES + 1, Tile.TEST_BLUE); } } if (z > 0 && PathNodes[x, z - 1] > 0) { if (!(PathNodes[x, z - 1] == 100 && is100)) { SetTiles((x) * NODE_RES - 1, (z - 1) * NODE_RES, (x) * NODE_RES + 1, z * NODE_RES, Tile.TEST_BLUE); } } if (x < nodeSize - 1 && PathNodes[x + 1, z] > 0) { if (!(PathNodes[x + 1, z] == 100 && is100)) { SetTiles((x) * NODE_RES, z * NODE_RES - 1, (x + 1) * NODE_RES, z * NODE_RES + 1, Tile.TEST_BLUE); } } if (z < nodeSize - 1 && PathNodes[x, z + 1] > 0) { if (!(PathNodes[x, z + 1] == 100 && is100)) { SetTiles((x) * NODE_RES - 1, (z) * NODE_RES, (x) * NODE_RES + 1, (z + 1) * NODE_RES, Tile.TEST_BLUE); } } } } return; }