Пример #1
0
 public Always(Act.Status status)
 {
     AlwaysStatus = status;
 }
Пример #2
0
        public override IEnumerable <Status> Run()
        {
            while (true)
            {
                Creature.AI.Blackboard.Erase(PathName);
                Agent.Blackboard.SetData <bool>("NoPath", false);
                PlanAct planAct = new PlanAct(Creature.AI, PathName, VoxelName, PlanType)
                {
                    Radius = Radius, MaxTimeouts = MaxTimeouts
                };
                planAct.Initialize();

                bool planSucceeded = false;
                while (true)
                {
                    Act.Status planStatus = planAct.Tick();

                    if (planStatus == Status.Fail)
                    {
                        yield return(Act.Status.Running);

                        break;
                    }

                    else if (planStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);
                    }

                    else if (planStatus == Status.Success)
                    {
                        planSucceeded = true;
                        break;
                    }
                    yield return(Act.Status.Running);
                }

                if (!planSucceeded && planAct.LastResult == AStarPlanner.PlanResultCode.MaxExpansionsReached)
                {
                    yield return(Act.Status.Running);

                    Creature.CurrentCharacterMode = CharacterMode.Idle;
                    Creature.Physics.Velocity     = Vector3.Zero;
                    Timer planTimeout = new Timer(MathFunctions.Rand(30.0f, 120.0f), false, Timer.TimerMode.Real);
                    List <VoxelHandle> exploredVoxels = new List <VoxelHandle>();
                    Color debugColor = new Color(MathFunctions.RandVector3Cube() + Vector3.One * 0.5f);
                    float debugScale = MathFunctions.Rand() * 0.5f + 0.5f;
                    while (!planTimeout.HasTriggered)
                    {
                        // In this case, try to follow a greedy path toward the entity instead of just failing.
                        var greedyPath = planAct.ComputeGreedyFallback(20, exploredVoxels);
                        var goal       = planAct.GetGoal();
                        Creature.AI.Blackboard.SetData("GreedyPath", greedyPath);
                        var greedyPathFollow = new FollowPathAct(Creature.AI, "GreedyPath")
                        {
                            //BlendEnd = true,
                            //BlendStart = false
                        };
                        greedyPathFollow.Initialize();

                        foreach (var currStatus in greedyPathFollow.Run())
                        {
                            if (Debugger.Switches.DrawPaths)
                            {
                                foreach (var voxel in exploredVoxels)
                                {
                                    Drawer3D.DrawBox(voxel.GetBoundingBox().Expand(-debugScale), debugColor, 0.05f, false);
                                }
                            }
                            if (!exploredVoxels.Contains(Agent.Physics.CurrentVoxel))
                            {
                                exploredVoxels.Add(Agent.Physics.CurrentVoxel);
                            }
                            if (Debugger.Switches.DrawPaths)
                            {
                                Drawer3D.DrawLine(Agent.Position, goal.GetVoxel().WorldPosition, debugColor, 0.1f);
                            }
                            if (goal.IsInGoalRegion(Agent.Physics.CurrentVoxel))
                            {
                                yield return(Act.Status.Success);

                                yield break;
                            }
                            yield return(Act.Status.Running);
                        }
                        planTimeout.Update(DwarfTime.LastTime);
                    }
                    continue;
                }
                else if (!planSucceeded)
                {
                    Agent.Blackboard.SetData <bool>("NoPath", true);
                    yield return(Act.Status.Fail);

                    yield break;
                }
                yield return(Act.Status.Success);

                yield break;
            }
        }
Пример #3
0
        public IEnumerable <Status> TrackMovingTarget()
        {
            while (true)
            {
                // This is to support the case of going from one entity to another.
                if (_entity != null)
                {
                    Entity = _entity;
                }
                Creature.AI.Blackboard.Erase("EntityVoxel");
                Act.Status    status = SetTargetVoxelFromEntityAct.SetTarget("EntityVoxel", EntityName, Creature);
                GameComponent entity = Agent.Blackboard.GetData <GameComponent>(EntityName);

                if (entity == null || entity.IsDead)
                {
                    yield return(Status.Success);

                    yield break;
                }

                if (status != Status.Success)
                {
                    yield return(Act.Status.Running);
                }
                List <MoveAction> existingPath =
                    Creature.AI.Blackboard.GetData <List <MoveAction> >("PathToEntity");

                Creature.AI.Blackboard.Erase("PathToEntity");

                PlanWithGreedyFallbackAct planAct = new PlanWithGreedyFallbackAct()
                {
                    Agent    = Creature.AI,
                    PathName = "PathToEntity", VoxelName = "EntityVoxel", PlanType = PlanType, Radius = Radius, MaxTimeouts = 1
                };
                planAct.Initialize();

                bool planSucceeded = false;
                while (true)
                {
                    Act.Status planStatus = planAct.Tick();
                    LastTickedChild = planAct;
                    if (planStatus == Status.Fail)
                    {
                        yield return(Act.Status.Running);

                        break;
                    }

                    else if (planStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);
                    }

                    else if (planStatus == Status.Success)
                    {
                        planSucceeded = true;
                        break;
                    }
                }

                if (!planSucceeded)
                {
                    Agent.SetTaskFailureReason("Failed to reach entity. Path planning failed.");
                    yield return(Act.Status.Fail);

                    yield break;
                }

                FollowPathAct followPath = new FollowPathAct(Creature.AI, "PathToEntity")
                {
                    //BlendEnd = true,
                    //BlendStart = existingPath == null
                };
                followPath.Initialize();

                while (true)
                {
                    if (PlanType == PlanAct.PlanType.Radius && (Creature.Physics.Position - entity.Position).Length() < Radius)
                    {
                        yield return(Act.Status.Success);
                    }

                    Act.Status pathStatus = followPath.Tick();
                    LastTickedChild = followPath;
                    if (pathStatus == Status.Fail)
                    {
                        break;
                    }

                    else if (pathStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);

                        List <MoveAction> path = Agent.Blackboard.GetData <List <MoveAction> >("PathToEntity");
                        if (path == null || path.Count == 0)
                        {
                            Agent.SetTaskFailureReason("Failed to find path to entity.");
                            yield return(Act.Status.Fail);

                            yield break;
                        }
                        var under = VoxelHelpers.FindFirstVoxelBelowIncludingWater(new VoxelHandle(entity.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(entity.Position)));

                        bool targetMoved = under == VoxelHandle.InvalidHandle || (path.Last().DestinationVoxel.WorldPosition - under.WorldPosition).Length() > Math.Max(Radius, 2) * 2;

                        if (MovingTarget && (path.Count > 0 && targetMoved))
                        {
                            break;
                        }

                        if (MovingTarget && (Creature.Physics.Position - entity.Position).Length() < 2)
                        {
                            yield return(Status.Success);

                            yield break;
                        }

                        continue;
                    }

                    else if (pathStatus == Status.Success)
                    {
                        yield return(Act.Status.Success);

                        yield break;
                    }
                }

                yield return(Act.Status.Running);
            }
        }
Пример #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 IEnumerable <Status> TrackMovingTarget()
        {
            int maxFailures     = 10;
            int currentFailures = 0;

            while (true)
            {
                Creature.AI.Blackboard.Erase("EntityVoxel");
                Act.Status status = SetTargetVoxelFromEntityAct.SetTarget("EntityVoxel", EntityName, Creature);
                Body       entity = Agent.Blackboard.GetData <Body>(EntityName);

                if (entity == null || entity.IsDead)
                {
                    yield return(Status.Success);

                    yield break;
                }

                if (status != Status.Success)
                {
                    yield return(Act.Status.Running);
                }
                Creature.AI.Blackboard.Erase("PathToEntity");

                PlanAct planAct = new PlanAct(Creature.AI, "PathToEntity", "EntityVoxel", PlanType)
                {
                    Radius = Radius
                };
                planAct.Initialize();

                bool planSucceeded = false;
                while (true)
                {
                    Act.Status planStatus = planAct.Tick();

                    if (planStatus == Status.Fail)
                    {
                        yield return(Act.Status.Running);

                        break;
                    }

                    else if (planStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);
                    }

                    else if (planStatus == Status.Success)
                    {
                        planSucceeded = true;
                        break;
                    }
                }

                if (!planSucceeded)
                {
                    currentFailures++;
                    yield return(Act.Status.Running);

                    Creature.CurrentCharacterMode = Creature.CharacterMode.Idle;
                    Creature.Physics.Velocity     = Vector3.Zero;
                    if (currentFailures > maxFailures)
                    {
                        yield return(Act.Status.Fail);

                        yield break;
                    }

                    continue;
                }


                FollowPathAct followPath = new FollowPathAct(Creature.AI, "PathToEntity");
                followPath.Initialize();

                while (true)
                {
                    if (PlanType == PlanAct.PlanType.Radius && (Creature.Physics.Position - entity.Position).Length() < Radius)
                    {
                        yield return(Act.Status.Success);
                    }

                    Act.Status pathStatus = followPath.Tick();

                    if (pathStatus == Status.Fail)
                    {
                        break;
                    }

                    else if (pathStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);

                        List <Creature.MoveAction> path = Agent.Blackboard.GetData <List <Creature.MoveAction> >("PathToEntity");
                        if (path.Count > 0 && (path.Last().Voxel.Position - entity.LocalTransform.Translation).Length() > 4)
                        {
                            break;
                        }

                        if (MovingTarget && (Creature.Physics.Position - entity.Position).Length() < 2)
                        {
                            yield return(Status.Success);

                            yield break;
                        }

                        continue;
                    }

                    else if (pathStatus == Status.Success)
                    {
                        yield return(Act.Status.Success);

                        yield break;
                    }
                }

                yield return(Act.Status.Running);
            }
        }
Пример #6
0
        public IEnumerable <Status> TrackMovingTarget()
        {
            while (true)
            {
                // This is to support the case of going from one entity to another.
                if (_entity != null)
                {
                    Entity = _entity;
                }
                Creature.AI.Blackboard.Erase("EntityVoxel");
                Act.Status status = SetTargetVoxelFromEntityAct.SetTarget("EntityVoxel", EntityName, Creature);
                Body       entity = Agent.Blackboard.GetData <Body>(EntityName);

                if (entity == null || entity.IsDead)
                {
                    yield return(Status.Success);

                    yield break;
                }

                if (status != Status.Success)
                {
                    yield return(Act.Status.Running);
                }
                List <MoveAction> existingPath =
                    Creature.AI.Blackboard.GetData <List <MoveAction> >("PathToEntity");

                Creature.AI.Blackboard.Erase("PathToEntity");

                PlanWithGreedyFallbackAct planAct = new PlanWithGreedyFallbackAct()
                {
                    Agent    = Creature.AI,
                    PathName = "PathToEntity", VoxelName = "EntityVoxel", PlanType = PlanType, Radius = Radius, MaxTimeouts = 1
                };
                planAct.Initialize();

                bool planSucceeded = false;
                while (true)
                {
                    Act.Status planStatus = planAct.Tick();
                    LastTickedChild = planAct;
                    if (planStatus == Status.Fail)
                    {
                        yield return(Act.Status.Running);

                        break;
                    }

                    else if (planStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);
                    }

                    else if (planStatus == Status.Success)
                    {
                        planSucceeded = true;
                        break;
                    }
                }

                if (!planSucceeded)
                {
                    Agent.SetMessage("Failed to reach entity. Path planning failed.");
                    yield return(Act.Status.Fail);

                    yield break;
                }

                FollowPathAct followPath = new FollowPathAct(Creature.AI, "PathToEntity")
                {
                    BlendEnd   = true,
                    BlendStart = existingPath == null
                };
                followPath.Initialize();

                while (true)
                {
                    if (PlanType == PlanAct.PlanType.Radius && (Creature.Physics.Position - entity.Position).Length() < Radius)
                    {
                        yield return(Act.Status.Success);
                    }

                    Act.Status pathStatus = followPath.Tick();
                    LastTickedChild = followPath;
                    if (pathStatus == Status.Fail)
                    {
                        break;
                    }

                    else if (pathStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);

                        List <MoveAction> path = Agent.Blackboard.GetData <List <MoveAction> >("PathToEntity");
                        if (path == null || path.Count == 0)
                        {
                            Agent.SetMessage("Failed to find path to entity.");
                            yield return(Act.Status.Fail);

                            yield break;
                        }

                        bool targetMoved = (path.Last().DestinationVoxel.WorldPosition - entity.LocalTransform.Translation).Length() > Math.Max(Radius, 2) * 2;

                        if (MovingTarget && (path.Count > 0 && targetMoved))
                        {
                            break;
                        }

                        if (MovingTarget && (Creature.Physics.Position - entity.Position).Length() < 2)
                        {
                            yield return(Status.Success);

                            yield break;
                        }

                        continue;
                    }

                    else if (pathStatus == Status.Success)
                    {
                        yield return(Act.Status.Success);

                        yield break;
                    }
                }

                yield return(Act.Status.Running);
            }
        }
Пример #7
0
        public IEnumerable <Status> TrackMovingTarget()
        {
            while (true)
            {
                Creature.AI.Blackboard.Erase("EntityVoxel");
                Act.Status status = SetTargetVoxelFromEntityAct.SetTarget("EntityVoxel", EntityName, Creature);
                Body       entity = Agent.Blackboard.GetData <Body>(EntityName);

                if (entity == null || entity.IsDead)
                {
                    yield return(Status.Success);

                    yield break;
                }

                if (status != Status.Success)
                {
                    yield return(Act.Status.Running);
                }
                Creature.AI.Blackboard.Erase("PathToEntity");
                PlanAct planAct = new PlanAct(Creature.AI, "PathToEntity", "EntityVoxel", PlanAct.PlanType.Adjacent);
                planAct.Initialize();

                bool planSucceeded = false;
                while (true)
                {
                    Act.Status planStatus = planAct.Tick();

                    if (planStatus == Status.Fail)
                    {
                        yield return(Act.Status.Running);

                        break;
                    }

                    else if (planStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);
                    }

                    else if (planStatus == Status.Success)
                    {
                        planSucceeded = true;
                        break;
                    }
                }

                if (!planSucceeded)
                {
                    yield return(Act.Status.Running);

                    continue;
                }


                FollowPathAnimationAct followPath = new FollowPathAnimationAct(Creature.AI, "PathToEntity");
                followPath.Initialize();

                while (true)
                {
                    Act.Status pathStatus = followPath.Tick();

                    if (pathStatus == Status.Fail)
                    {
                        break;
                    }

                    else if (pathStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);

                        List <Creature.MoveAction> path = Agent.Blackboard.GetData <List <Creature.MoveAction> >("PathToEntity");
                        if (path.Count > 0 && (path.Last().Voxel.Position - entity.LocalTransform.Translation).Length() > 4)
                        {
                            break;
                        }

                        if (MovingTarget && (Creature.Physics.Position - entity.Position).Length() < 2)
                        {
                            yield return(Status.Success);

                            yield break;
                        }

                        continue;
                    }

                    else if (pathStatus == Status.Success)
                    {
                        yield return(Act.Status.Success);

                        yield break;
                    }
                }

                yield return(Act.Status.Running);
            }
        }