private PathDistance findClosestPaths(List <List <Coordinates> > paths, Random rand) { PathDistance result = new PathDistance(Constants.TOO_MUCH_FOR_DUNGEON_GENERATION); foreach (List <Coordinates> path_1 in paths) { foreach (List <Coordinates> path_2 in paths) { if (!(path_1 [0] == path_2 [0])) { PathDistance temp = findClosestPoints(path_1, path_2); if (temp.distance < result.distance) { result = temp; } else if (temp.distance == result.distance && (rand.Next() % 2 == 0)) { result = temp; } } } } return(result); }
private void addMemo(List <GraphPoint> finalPath) { // We did not hit the memoization cache, so we must fill it List <GraphPoint> rev = new List <GraphPoint>(finalPath); rev.Reverse(); List <GraphPoint> toGoal = new List <GraphPoint>(); // Work backwards from the end, setting the memoization at a GraphPoint to be the path from the GraphPoint to the goal float dist = 0; foreach (GraphPoint gp in rev) { // We must move every item over so this operation is O(n) // If we were to use a LinkedList, we would have to copy over anyway O(n), so this is cleaner toGoal.Insert(0, gp); Vector2[] path = getWorldPath(toGoal); if (path.Length >= 2) { dist += Vector2.Distance(path[0], path[1]); } PathDistance pd = new PathDistance(); pd.dist = dist; pd.path = path; memoized[gp] = pd; } }
private Vector2[] getFromMemo(Node cur, PathDistance memo) { Vector2[] mp = memo.path; Vector2[] worldPath = new Vector2[cur.path.Count + mp.Length]; getWorldPath(cur.path, worldPath); for (int i = 0; i < mp.Length; i++) { worldPath[cur.path.Count + i] = mp[i]; } return(worldPath); }
////////////////////////////////////////////////////////////////////////////////// /* | */ /* PRIVATES */ /* | */ ////////////////////////////////////////////////////////////////////////////////// private void recursiveMergePaths(DungeonGrid grid, PathableArea area, Random rand) { List <List <Coordinates> > tempPaths = grid.findAreas(Constants.PATH_MARKER, area.position, new Coordinates(area.position.x + area.sizeX, area.position.y + area.sizeY)); if (tempPaths.Count == 1) { return; } PathDistance closest = findClosestPaths(tempPaths, rand); grid.drawPath(closest.path_1, closest.path_2, rand); recursiveMergePaths(grid, area, rand); }
////////////////////////////////////////////////////////////////////////////////// /* | */ /* PRIVATES */ /* | */ ////////////////////////////////////////////////////////////////////////////////// private void mergePaths(DungeonGrid grid, PathableArea area, Random rand) { List <List <Coordinates> > tempPaths = grid.findAreas(Constants.PATH_MARKER, area.position, new Coordinates(area.position.x + area.sizeX, area.position.y + area.sizeY)); if (tempPaths.Count == 1) { return; } bool[,] linkedGraph = new bool[tempPaths.Count, tempPaths.Count]; for (int i = 0; i < tempPaths.Count; i++) { for (int j = 0; j < tempPaths.Count; j++) { linkedGraph [i, j] = (i == j ? true : false); } } int actual = 0; foreach (List <Coordinates> tempPath in tempPaths) { int linkTo = rand.Next() % tempPaths.Count; int count = 0; while (linkedGraph [actual, linkTo] && count < tempPaths.Count) { linkTo = (linkTo + 1) % tempPaths.Count; count++; } if (count == tempPaths.Count) { continue; } linkedGraph [actual, linkTo] = true; linkedGraph [linkTo, actual] = true; linkAll(linkedGraph, tempPaths.Count, actual, linkTo); PathDistance points = findClosestPoints(tempPath, tempPaths [linkTo]); grid.drawPath(points.path_1, points.path_2, rand); actual++; } }
protected PathDistance findClosestPoints(List <Coordinates> a, List <Coordinates> b) { PathDistance result = new PathDistance(Constants.TOO_MUCH_FOR_DUNGEON_GENERATION); foreach (Coordinates p1 in a) { foreach (Coordinates p2 in b) { int distance = Math.Abs(p1.x - p2.x) + Math.Abs(p1.y - p2.y); if (distance < result.distance) { result.distance = distance; result.path_1 = p1; result.path_2 = p2; } } } return(result); }
private void FixedUpdate() { var currentMousePosition = Input.mousePosition; if (currentMousePosition == previousMousePosition) { return; } PathLine.enabled = false; TargetCircle.enabled = false; TrajectoryRenderer.enabled = false; var eventSys = EventSystem.current; if (!characterCombatController || !characterCombatController.MyTurn && GlobalTBModeController.Instance.IsTurnBased || !characterCombatController.IsTargetingSkill && !DrawCharacterPath || eventSys.IsPointerOverGameObject()) { return; } Ray ray = cam.ScreenPointToRay(currentMousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100, ~LayerMask.GetMask("VisibilityColliders"))) { previousMousePosition = currentMousePosition; if (characterCombatController.IsTargetingSkill) { TrajectoryRenderer.enabled = true; var skillTrajectoryStartPoint = character.transform.position + Vector3.up; var skillTrajectoryEndPoint = hit.point; if (hit.collider.gameObject.layer == 12) { skillTrajectoryEndPoint += Vector3.up; } ValidDestination = Vector3.Distance(skillTrajectoryStartPoint, skillTrajectoryEndPoint) <= characterCombatController.SkillBeingTargeted.Range; DrawTrajectory(skillTrajectoryStartPoint, skillTrajectoryEndPoint, ValidDestination, characterCombatController.SkillBeingTargeted.TrajectoryArc); } else if (DrawCharacterPath && GlobalTBModeController.Instance.IsTurnBased && !character.IsMoving) { NavMeshHit navHit; var distanceToNavMesh = 0.2f; var targetPoint = hit.point; if (hit.collider.gameObject.CompareTag("Interactable")) { distanceToNavMesh = hit.collider.gameObject.GetComponent <Interactable>().InteractionDistance; var lowestPointInCollider = hit.collider.gameObject.GetComponent <Collider>().bounds.min.y; targetPoint = new Vector3(targetPoint.x, lowestPointInCollider, targetPoint.z); } if (!NavMesh.SamplePosition(targetPoint, out navHit, distanceToNavMesh, NavMesh.AllAreas)) { return; } StartCoroutine(character.GetPathEnumerator(hit.point, res => { var path = res; if (path.Length > 1) { PathLine.enabled = true; TargetCircle.enabled = true; var pathLength = PathDistance.CalculatePathLength(path); ValidDestination = pathLength <= characterCombatController.MovementLeft; DrawLine(PathLine, path, ValidDestination); DrawTargetCircle(targetPoint, ValidDestination); } })); } } }