/// <summary> /// Returns the current waypoint target location. /// </summary> /// <param name="gameActor"></param> /// <param name="target"></param> /// <returns>True if the target is valid, false otherwise.</returns> protected bool NewWaypointTarget(GameActor gameActor, ref Vector3 target) { bool validTarget = false; WayPoint.Node activeNode = gameActor.followPathState.ActiveNode; target = gameActor.followPathState.FollowTarget; WayPoint.Edge newEdge = WayPoint.GetNextEdgeFromPath(gameActor.followPathState.ActivePath, activeNode, gameActor); if (newEdge != null) { activeNode.EndTarget(); activeNode.SetVisitedTime(gameActor); // find the opposite node to the new edge of the current node if (newEdge.Node0 == activeNode) { // use node1 off new edge activeNode = newEdge.Node1; } else { // use node0 off new edge activeNode = newEdge.Node0; } target = activeNode.Position; activeNode.BeginTarget(gameActor); gameActor.followPathState.ActiveNode = activeNode; gameActor.followPathState.ActiveEdge = newEdge; validTarget = true; } return(validTarget); }
} // end of FindClosestMatchingWaypointSetTarget() /// <summary> /// Based on the name this is only supposed to be called when we're /// following a valid path and reach one of the WayPoints (nodes). /// So, if this is call without a valid path, it's probably an error /// upstream. /// </summary> /// <param name="gameActor"></param> /// <returns></returns> protected bool ReachedWaypoint(GameActor gameActor, ref Vector3 target) { bool validTarget = true; target = Vector3.Zero; // Save out the previously visited nodes. gameActor.followPathState.PreviousNode = gameActor.followPathState.CurrentNode; gameActor.followPathState.CurrentNode = gameActor.followPathState.ActiveNode; if (gameActor.followPathState.ActiveNode != null) { WayPoint.Node activeNode = gameActor.followPathState.ActiveNode; Vector3 actorPosition = gameActor.Movement.Position; Vector2 actorPosition2d = new Vector2(actorPosition.X, actorPosition.Y); float distance = Vector2.Distance(actorPosition2d, activeNode.Position2d); if (distance < accuracy) { validTarget = NewWaypointTarget(gameActor, ref target); } } else { // Reached the edge itself. Select the nearest node as the next target. Vector3 actorPosition = gameActor.Movement.Position; Vector2 actorPosition2d = new Vector2(actorPosition.X, actorPosition.Y); WayPoint.Node nextNode = gameActor.followPathState.ActiveEdge.NearestNode(actorPosition); target = nextNode.Position; if (gameActor.followPathState.ActiveNode != null) { gameActor.followPathState.ActiveNode.EndTarget(); gameActor.followPathState.ActiveNode = null; } gameActor.followPathState.ActiveNode = nextNode; nextNode.BeginTarget(gameActor); // Visit the "other" node on this edge so that the actor doesn't loop // back around unless absolutely necessary. if (nextNode == gameActor.followPathState.ActiveEdge.Node0) { gameActor.followPathState.ActiveEdge.Node1.SetVisitedTime(gameActor); } else { gameActor.followPathState.ActiveEdge.Node0.SetVisitedTime(gameActor); } } Debug.Assert(gameActor.followPathState.ActiveNode != null, "Still haven't found a node?"); // Only check if we are end of path if there are more than 1 nodes in the path if (gameActor.followPathState.ActivePath.Nodes.Count > 1) { if (gameActor.followPathState.PreviousNode == gameActor.followPathState.ActiveNode) { gameActor.ReachedEOP = gameActor.followPathState.PathColor; } else { gameActor.ReachedEOP = Classification.Colors.None; } } else { gameActor.ReachedEOP = Classification.Colors.None; } return(validTarget); }