示例#1
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;
            }
        }
示例#2
0
        public IEnumerable <Act.Status> GreedyFallbackBehavior(Creature agent)
        {
            var edgeGoal = new EdgeGoalRegion();

            while (true)
            {
                DieTimer.Update(DwarfTime.LastTime);
                if (DieTimer.HasTriggered)
                {
                    foreach (var status in Die(agent))
                    {
                        continue;
                    }
                    yield break;
                }
                var creatureVoxel      = agent.Physics.CurrentVoxel;
                List <MoveAction> path = new List <MoveAction>();
                var storage            = new MoveActionTempStorage();
                for (int i = 0; i < 10; i++)
                {
                    if (edgeGoal.IsInGoalRegion(creatureVoxel))
                    {
                        foreach (var status in Die(agent))
                        {
                            continue;
                        }
                        yield return(Act.Status.Success);

                        yield break;
                    }

                    var actions = agent.AI.Movement.GetMoveActions(new MoveState {
                        Voxel = creatureVoxel
                    }, new List <GameComponent>(), storage);

                    float minCost      = float.MaxValue;
                    var   minAction    = new MoveAction();
                    bool  hasMinAction = false;
                    foreach (var action in actions)
                    {
                        var vox = action.DestinationVoxel;

                        float cost = edgeGoal.Heuristic(vox) * 10 + MathFunctions.Rand(0.0f, 0.1f) + agent.AI.Movement.Cost(action.MoveType);

                        if (cost < minCost)
                        {
                            minAction    = action;
                            minCost      = cost;
                            hasMinAction = true;
                        }
                    }

                    if (hasMinAction)
                    {
                        path.Add(minAction);
                        creatureVoxel = minAction.DestinationVoxel;
                    }
                    else
                    {
                        foreach (var status in Die(agent))
                        {
                            continue;
                        }
                        yield return(Act.Status.Success);

                        yield break;
                    }
                }
                if (path.Count == 0)
                {
                    foreach (var status in Die(agent))
                    {
                        continue;
                    }
                    yield return(Act.Status.Success);

                    yield break;
                }
                agent.AI.Blackboard.SetData("GreedyPath", path);
                var pathAct = new FollowPathAct(agent.AI, "GreedyPath");
                pathAct.Initialize();

                foreach (Act.Status status in pathAct.Run())
                {
                    yield return(Act.Status.Running);
                }
                yield return(Act.Status.Running);
            }
        }