Example #1
0
        /// <summary>
        /// Replaces SolidConsumerMonitor.FindFood to more efficiently find food for critters.
        /// </summary>
        public static void FindFood(SolidConsumerMonitor.Instance smi, float _)
        {
            var closest = new ClosestEdible(smi.GetComponent <DrowningMonitor>(),
                                            smi.GetComponent <Navigator>());
            // Check the diet type first
            var diet = smi.def.diet;

            Grid.PosToXY(smi.gameObject.transform.GetPosition(), out int x, out int y);
            if (!diet.eatsPlantsDirectly)
            {
                // Check Critter Feeder with priority
                var storages = ListPool <Storage, SolidConsumerMonitor> .Allocate();

                foreach (var creatureFeeder in Components.CreatureFeeders.Items)
                {
                    var go = creatureFeeder.gameObject;
                    if (go != null)
                    {
                        Grid.PosToXY(go.transform.GetPosition(), out int cx, out int cy);
                        // Only check critter feeders that are somewhat nearby
                        if (Math.Abs(x - cx) <= RADIUS && Math.Abs(y - cy) <= RADIUS)
                        {
                            storages.Clear();
                            go.GetComponents(storages);
                            FindFood(storages, diet, ref closest);
                        }
                    }
                }
                storages.Recycle();
            }
            var gsp    = GameScenePartitioner.Instance;
            var nearby = ListPool <ScenePartitionerEntry, GameScenePartitioner> .Allocate();

            gsp.GatherEntries(x - RADIUS, y - RADIUS, RADIUS << 1, RADIUS << 1, diet.
                              eatsPlantsDirectly ? gsp.plants : gsp.pickupablesLayer, nearby);
            // Add plants or critters
            int n = nearby.Count;

            for (int i = 0; i < n; i++)
            {
                if (nearby[i].obj is KMonoBehaviour item && CanEatItem(item, diet))
                {
                    closest.CheckUpdate(item);
                }
            }
            nearby.Recycle();
            smi.targetEdible = closest.target;
        }
Example #2
0
        /// <summary>
        /// Searches critter feeder storage for items to eat.
        /// </summary>
        /// <param name="storages">The storages to search for food.</param>
        /// <param name="diet">The foods that can be eaten.</param>
        /// <param name="closest">The location where the closest valid food will be stored.</param>
        private static void FindFood(List <Storage> storages, Diet diet,
                                     ref ClosestEdible closest)
        {
            int n = storages.Count;

            for (int i = 0; i < n; i++)
            {
                var storage = storages[i];
                if (storage != null)
                {
                    var items = storage.items;
                    int ni    = items.Count;
                    for (int j = 0; j < ni; j++)
                    {
                        var item = items[j];
                        if (item != null && item.TryGetComponent(out KPrefabID prefabID) &&
                            CanEatItem(prefabID, diet))
                        {
                            closest.CheckUpdate(prefabID);
                        }
                    }
                }
            }
        }