/// <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; }
/// <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); } } } } }