public AStarPlanResponse WaitForResponse(AstarPlanRequest request) { // If we already have a request, determine if it has been satisfied. if (LastRequest != null) { // first, if the timer has triggered, return an unsuccessful plan. Timeout.Update(DwarfTime.LastTime); if (Timeout.HasTriggered) { LastRequest = null; return(new AStarPlanResponse() { Success = false }); } // Otherwise, see if there are any responses yet. while (Subscriber.Responses.Count > 0) { AStarPlanResponse response; bool success = Subscriber.Responses.TryDequeue(out response); // If so, determine if the response is what we requested. if (success) { // If not, maybe try another response if (response.Request != LastRequest) { continue; } // Otherwise, we found our guy. return it. LastRequest = null; // Clear the response queue. while (Subscriber.Responses.Count > 0) { AStarPlanResponse dummy; Subscriber.Responses.TryDequeue(out dummy); } return(response); } } // No responses? Return null. return(null); } Timeout.Reset(); // Otherwise, this is a new request. Push it and return null. LastRequest = request; Subscriber.SendRequest(request); return(null); }
public override IEnumerable <Status> Run() { Path = null; Timeouts = 0; PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); Voxel voxUnder = new Voxel(); while (true) { if (Path != null) { yield return(Status.Success); break; } if (Timeouts > MaxTimeouts) { yield return(Status.Fail); break; } PlannerTimer.Update(DwarfTime.LastTime); ChunkManager chunks = PlayState.ChunkManager; if (PlannerTimer.HasTriggered || Timeouts == 0) { if (!chunks.ChunkData.GetVoxel(Agent.Position, ref voxUnder)) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } if (Target == null && Type != PlanType.Edge) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } if (voxUnder != null) { Path = null; AstarPlanRequest aspr = new AstarPlanRequest { Subscriber = PlanSubscriber, Start = voxUnder, MaxExpansions = MaxExpansions, Sender = Agent, HeuristicWeight = Weights[Timeouts] }; switch (Type) { case PlanType.Radius: aspr.GoalRegion = new SphereGoalRegion(Target, Radius); break; case PlanType.Into: aspr.GoalRegion = new VoxelGoalRegion(Target); break; case PlanType.Adjacent: aspr.GoalRegion = new AdjacentVoxelGoalRegion2D(Target); break; case PlanType.Edge: aspr.GoalRegion = new EdgeGoalRegion(); break; } PlanSubscriber.SendRequest(aspr); PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); WaitingOnResponse = true; yield return(Status.Running); } else { Path = null; Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } Timeouts++; } else { if (Target != null && Creature.AI.DrawAIPlan) { Drawer3D.DrawLine(Creature.AI.Position, Target.Position, Color.Blue, 0.25f); } Status statusResult = Status.Running; while (PlanSubscriber.Responses.Count > 0) { AStarPlanResponse response; PlanSubscriber.Responses.TryDequeue(out response); if (response.Success) { Path = response.Path; if (Type == PlanType.Adjacent && Path.Count > 0) { Path.RemoveAt(Path.Count - 1); } WaitingOnResponse = false; statusResult = Status.Success; } else { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); 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 = PlanSubscriber, Start = voxUnder, MaxExpansions = MaxExpansions, Sender = Agent, HeuristicWeight = Weights[Timeouts] }; aspr.GoalRegion = GetGoal(); if (!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 (PlanSubscriber.Responses.Count > 0) { AStarPlanResponse response; if (!PlanSubscriber.Responses.TryDequeue(out response)) { yield return(Status.Running); continue; } if (response.Success) { Path = response.Path; WaitingOnResponse = false; statusResult = Status.Success; } else if (Timeouts < MaxTimeouts) { yield return(Status.Running); } else { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); statusResult = Status.Fail; PlanSubscriber.Service.RemoveSubscriber(PlanSubscriber); } } yield return(statusResult); } } }
public override IEnumerable <Status> Run() { Path = null; Timeouts = 0; PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); Voxel voxUnder = new Voxel(); while (true) { if (Path != null) { yield return(Status.Success); break; } if (Timeouts > MaxTimeouts) { yield return(Status.Fail); break; } PlannerTimer.Update(DwarfTime.LastTime); ChunkManager chunks = PlayState.ChunkManager; if (PlannerTimer.HasTriggered || Timeouts == 0) { if (!chunks.ChunkData.GetVoxel(Agent.Position, ref voxUnder)) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } if (Target == null) { if (Creature.Faction == PlayState.Master.Faction) { PlayState.AnnouncementManager.Announce(Creature.Stats.FullName + " (" + Creature.Stats.CurrentLevel.Name + ")" + " got lost.", Creature.Stats.FullName + "'s target was lost.", () => Agent.ZoomToMe()); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } if (voxUnder != null) { Path = null; AstarPlanRequest aspr = new AstarPlanRequest { Subscriber = PlanSubscriber, Start = voxUnder, MaxExpansions = MaxExpansions, Sender = Agent }; if (Type == PlanType.Radius) { aspr.GoalRegion = new SphereGoalRegion(Target, Radius); } else if (Type == PlanType.Into) { aspr.GoalRegion = new VoxelGoalRegion(Target); } else if (Type == PlanType.Adjacent) { aspr.GoalRegion = new AdjacentVoxelGoalRegion2D(Target); } PlanSubscriber.SendRequest(aspr); PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds); WaitingOnResponse = true; yield return(Status.Running); } else { Path = null; if (Creature.Faction == PlayState.Master.Faction) { PlayState.AnnouncementManager.Announce(Creature.Stats.FullName + " got lost.", Creature.Stats.FullName + " couldn't find a path. The target was invalid.", () => Agent.ZoomToMe()); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); yield return(Status.Fail); break; } Timeouts++; } else { Status statusResult = Status.Running; while (PlanSubscriber.Responses.Count > 0) { AStarPlanResponse response; PlanSubscriber.Responses.TryDequeue(out response); if (response.Success) { Path = response.Path; if (Type == PlanType.Adjacent && Path.Count > 0) { Path.RemoveAt(Path.Count - 1); } WaitingOnResponse = false; statusResult = Status.Success; } else { if (Creature.Faction == PlayState.Master.Faction) { PlayState.AnnouncementManager.Announce(Creature.Stats.FullName + " got lost.", Creature.Stats.FullName + " couldn't find a path in time.", Agent.ZoomToMe); } Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question); statusResult = Status.Fail; } } yield return(statusResult); } } }