Beispiel #1
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);
            }
        }
        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);
            }
        }