public override IEnumerable <Status> Run() { Path = null; Timeouts = 0; PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); var lastId = -1; Vector3 goalPos = Vector3.Zero; Agent.Blackboard.SetData <bool>("NoPath", false); while (true) { if (Path != null) { yield return(Status.Success); break; } if (Timeouts > MaxTimeouts) { Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } if (WaitingOnResponse && Debugger.Switches.DrawPaths) { Drawer3D.DrawLine(Creature.AI.Position, goalPos, Color.Blue, 0.25f); } PlannerTimer.Update(DwarfTime.LastTime); ChunkManager chunks = Creature.Manager.World.ChunkManager; if (PlannerTimer.HasTriggered || Timeouts == 0) { if (!Target.IsValid && Type != PlanType.Edge) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } var voxUnder = VoxelHelpers.FindValidVoxelNear(chunks, Agent.Position); if (!voxUnder.IsValid) { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Invalid request"), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); yield return(Status.Fail); break; } Path = null; AstarPlanRequest aspr = new AstarPlanRequest { Subscriber = Agent.PlanSubscriber, Start = voxUnder, MaxExpansions = MaxExpansions, Sender = Agent, HeuristicWeight = Weights[Timeouts] }; lastId = aspr.ID; aspr.GoalRegion = GetGoal(); goalPos = GetGoal().GetVoxel().GetBoundingBox().Center(); Agent.PlanSubscriber.Clear(); if (!Agent.PlanSubscriber.SendRequest(aspr, aspr.ID)) { yield return(Status.Fail); yield break; } PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); WaitingOnResponse = true; yield return(Status.Running); Timeouts++; } else { Status statusResult = Status.Running; while (Agent.PlanSubscriber.Responses.Count > 0) { AStarPlanResponse response; if (!Agent.PlanSubscriber.Responses.TryDequeue(out response)) { yield return(Status.Running); continue; } LastResult = response.Result; if (response.Success && response.Request.ID == lastId) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else if (response.Request.ID != lastId && response.Path != null && response.Path.Count > 0) { var goal = GetGoal(); bool obeysGoal = goal == null ? false : (response.Success && (goal.IsInGoalRegion(response.Path.Last().DestinationVoxel))); if (Debugger.Switches.DrawPaths) { if (obeysGoal) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Using Old Path", response.Result), Creature.Physics, -10, 1); } else { Creature.World.UserInterface.MakeWorldPopup(String.Format("Old Path Dropped", response.Result), Creature.Physics, -10, 1); } } if (obeysGoal) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else { continue; } } else if (response.Result == AStarPlanner.PlanResultCode.Invalid || response.Result == AStarPlanner.PlanResultCode.NoSolution || response.Result == AStarPlanner.PlanResultCode.Cancelled || response.Result == AStarPlanner.PlanResultCode.Invalid) { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Path: {0}", response.Result), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); statusResult = Status.Fail; yield return(Status.Fail); } else if (Timeouts <= MaxTimeouts) { Timeouts++; yield return(Status.Running); } else { if (Debugger.Switches.DrawPaths) { Creature.World.UserInterface.MakeWorldPopup(String.Format("Max timeouts reached", response.Result), Creature.Physics, -10, 1); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); Agent.Blackboard.SetData <bool>("NoPath", true); statusResult = Status.Fail; } } yield return(statusResult); } } }
public override IEnumerable <Status> Run() { Path = null; Timeouts = 0; PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); while (true) { if (Path != null) { yield return(Status.Success); break; } if (Timeouts > MaxTimeouts) { yield return(Status.Fail); break; } PlannerTimer.Update(DwarfTime.LastTime); ChunkManager chunks = Creature.Manager.World.ChunkManager; if (PlannerTimer.HasTriggered || Timeouts == 0) { if (!Target.IsValid && Type != PlanType.Edge) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } var voxUnder = new VoxelHandle(chunks.ChunkData, GlobalVoxelCoordinate.FromVector3(Agent.Position)); if (!voxUnder.IsValid) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } Path = null; AstarPlanRequest aspr = new AstarPlanRequest { Subscriber = Agent.PlanSubscriber, Start = voxUnder, MaxExpansions = MaxExpansions, Sender = Agent, HeuristicWeight = Weights[Timeouts] }; aspr.GoalRegion = GetGoal(); if (!Agent.PlanSubscriber.SendRequest(aspr)) { yield return(Status.Fail); yield break; } PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); WaitingOnResponse = true; yield return(Status.Running); Timeouts++; } else { //if (Target.IsValid && Creature.AI.DrawAIPlan) // Drawer3D.DrawLine(Creature.AI.Position, Target.WorldPosition, Color.Blue, 0.25f); Status statusResult = Status.Running; while (Agent.PlanSubscriber.Responses.Count > 0) { AStarPlanResponse response; if (!Agent.PlanSubscriber.Responses.TryDequeue(out response)) { yield return(Status.Running); continue; } LastResult = response.Result; if (response.Success) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else if (response.Result == AStarPlanner.PlanResultCode.Invalid || response.Result == AStarPlanner.PlanResultCode.NoSolution || response.Result == AStarPlanner.PlanResultCode.Cancelled || response.Result == AStarPlanner.PlanResultCode.Invalid) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); statusResult = Status.Fail; yield return(Status.Fail); } else if (Timeouts <= MaxTimeouts) { Timeouts++; yield return(Status.Running); } else { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); statusResult = Status.Fail; } } yield return(statusResult); } } }