示例#1
0
        public static IEnumerator <BTStatus> Hunt(Animal agent, Func <Animal, BTStatus> noNearbyFoodBehavior)
        {
            while (agent.Hunger > Brain.HungerSatiated)
            {
                var agentRegion = RouteRegions.GetRegion(agent.Position.WorldPosition3i);
                var nearPrey    = NetObjectManager.GetObjectsWithin(agent.Position.XZ, agent.DetectionRange).OfType <Animal>()
                                  .Where(x => agent.ShouldFleeUs(x) && RouteRegions.GetRegion(x.Position.WorldPosition3i) == agentRegion)
                                  .OrderBy(x => Vector3.WrappedDistanceSq(x.Position, agent.Position) + (x.AnimationState == AnimalAnimationState.Sleeping ? -200 : 0));
                foreach (var prey in nearPrey)
                {
                    var i = 0;
                    while (prey.Active)
                    {
                        Eco.Simulation.ExternalInputs.PredatorTracker.AddPredator(agent);
                        var route = AIUtilities.GetRoute(agent.Position, prey.Position, prey.Alertness < 50 ? agent.Species.WanderingSpeed : agent.Species.Speed);
                        agent.Target.SetPath(route);
                        agent.Target.Set(prey);
                        agent.NextTick = Math.Min(agent.Target.TargetTime, WorldTime.Seconds + 3);
                        i++;
                        yield return(BTStatus.Running);

                        if (Vector3.WrappedDistance(agent.Position, prey.Position) < 2f || i > 4)
                        {
                            // making this look good will require a lot of work, for now just let it go
                            agent.Hunger = 0;
                            Eco.Simulation.ExternalInputs.PredatorTracker.RemovePredator(agent);
                            yield break;
                        }
                    }
                }
                yield return(noNearbyFoodBehavior(agent));
            }
        }