Пример #1
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);
                }
            }
        }
Пример #2
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);
                }
            }
        }
Пример #3
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.GetValidVoxelNear(chunks, Agent.Position);

                    if (!voxUnder.IsValid)
                    {
                        if (Debugger.Switches.DrawPaths)
                        {
                            Creature.World.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
                {
                    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 && response.Request.ID == lastId)
                        {
                            Path = response.Path;
                            WaitingOnResponse = false;

                            statusResult = Status.Success;
                        }
                        else if (response.Request.ID != lastId)
                        {
                            if (Debugger.Switches.DrawPaths)
                            {
                                Creature.World.MakeWorldPopup(String.Format("Old Path Dropped", response.Result), Creature.Physics, -10, 1);
                            }
                            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.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.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);
                }
            }
        }
Пример #4
0
        public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            IdleTimer.Update(gameTime);
            SpeakTimer.Update(gameTime);

            OrderEnemyAttack();
            DeleteBadTasks();
            PreEmptTasks();

            if (Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
            {
                Task toReturn = new SatisfyTirednessTask();
                toReturn.SetupScript(Creature);
                if (!Tasks.Contains(toReturn))
                {
                    Tasks.Add(toReturn);
                }
            }

            if (Status.Hunger.IsUnhappy() && Faction.CountResourcesWithTag(Resource.ResourceTags.Food) > 0)
            {
                Task toReturn = new SatisfyHungerTask();
                toReturn.SetupScript(Creature);
                if (!Tasks.Contains(toReturn))
                {
                    Tasks.Add(toReturn);
                }
            }


            if (CurrentTask != null && CurrentAct != null)
            {
                Act.Status status = CurrentAct.Tick();


                bool retried = false;
                if (status == Act.Status.Fail)
                {
                    if (CurrentTask.ShouldRetry(Creature))
                    {
                        if (!Tasks.Contains(CurrentTask))
                        {
                            CurrentTask.Priority = Task.PriorityType.Eventually;
                            Tasks.Add(CurrentTask);
                            CurrentTask.SetupScript(Creature);
                            retried = true;
                        }
                    }
                }

                if (status != Act.Status.Running && !retried)
                {
                    CurrentTask = null;
                }
            }
            else
            {
                bool tantrum = false;
                if (Status.Happiness.IsUnhappy())
                {
                    tantrum = MathFunctions.Rand(0, 1) < 0.25f;
                }

                Task goal = GetEasiestTask(Tasks);
                if (goal != null)
                {
                    if (tantrum)
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Sad);
                        if (Creature.Allies == "Dwarf")
                        {
                            PlayState.AnnouncementManager.Announce(Stats.FullName + " (" + Stats.CurrentLevel.Name + ")" + " refuses to work!",
                                                                   "Our employee is unhappy, and would rather not work!", ZoomToMe);
                        }
                        CurrentTask = null;
                    }
                    else
                    {
                        IdleTimer.Reset(IdleTimer.TargetTimeSeconds);
                        goal.SetupScript(Creature);
                        CurrentTask = goal;
                        Tasks.Remove(goal);
                    }
                }
                else
                {
                    CurrentTask = ActOnIdle();
                }
            }


            PlannerTimer.Update(gameTime);
            UpdateThoughts();
            UpdateXP();

            base.Update(gameTime, chunks, camera);
        }
Пример #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);
                }
            }
        }