Пример #1
0
        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);
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        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);
                }
            }
        }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
        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);
                }
            }
        }