/// <summary> /// Searches for fetchable pickups for the given chore. /// </summary> /// <param name="chore">The chore to complete.</param> /// <returns>The pickup to fetch, or null if none are currently available.</returns> internal Pickupable FindFetchTarget(FetchChore chore) { Pickupable bestMatch = null; var destination = chore.destination; float required = chore.originalAmount, target = required * thresholdFraction, canGet = 0.0f; foreach (var pickup in fmPickups) { var pickupable = pickup.pickupable; // Is this item accessible? if (FetchManager.IsFetchablePickup(pickupable, ref chore.tagBits, ref chore. requiredTagBits, ref chore.forbiddenTagBits, destination)) { float amount = pickupable.UnreservedAmount; if (bestMatch == null) { // Indicate if anything can be found at all bestMatch = pickupable; canGet = amount; } if (amount >= target) { // Already have the best one in our sights bestMatch = pickupable; canGet = amount; break; } } } // Do not start a fetch entry if nothing is available if (bestMatch != null) { Tag itemType = bestMatch.PrefabID(); if (outstanding.TryGetValue(itemType, out FetchData current) && !current. NeedsScan) { // Retire it, with the best item we could do outstanding.TryRemove(itemType, out _); #if DEBUG PUtil.LogDebug("{3} {0} ({2}) with {1:F2}".F(destination.name, canGet, itemType, (canGet >= target) ? "Complete" : "Retire")); #endif } else if (canGet < target && outstanding.TryAdd(itemType, new FetchData( target))) { // Start searching for a better option #if DEBUG PUtil.LogDebug("Find {0} ({3}): have {1:F2}, want {2:F2}".F( destination.name, canGet, target, itemType)); #endif bestMatch = null; } } return(bestMatch); }
public static void Postfix(FetchManager __instance, Storage destination, ref TagBits tag_bits, ref TagBits required_tags, ref TagBits forbid_tags, float required_amount, ref Pickupable __result) { // only do this for the egg cracker if (!destination.ToString().Contains(__EGG_CRACKER_NAME)) { return; } List <FetchManager.Pickup> pickup_list = pickupListRef(__instance); List <Pickupable> egg_list = new List <Pickupable>(); if (__DEBUG) { Debug.Log(String.Format("Number of pickupbables available: {0}", pickup_list.Count)); } // get a list of all the available eggs for this fetch order foreach (FetchManager.Pickup pickup in pickup_list) { if (__DEBUG) { string debug_output = "Checking item on list:\n"; debug_output += "Position:\n"; UnityEngine.Vector3 pos = pickup.pickupable.GetTargetPoint(); debug_output += String.Format("X: {0} Y: {1} Z: {2}\n", pos.x, pos.y, pos.z); debug_output += "\nTag bits:\n" + string.Join <Tag>(",", (IEnumerable <Tag>)tag_bits.GetTagsVerySlow()); // TODO: use below code taken from FetchManager.IsFetchablePickup() to log if each pickup is valid // pickup_id.HasAnyTags_AssumeLaundered(ref tag_bits) && pickup_id.HasAllTags_AssumeLaundered(ref required_tags) && !pickup_id.HasAnyTags_AssumeLaundered(ref forbid_tags) && (!((Object)source != (Object)null) || (source.ignoreSourcePriority || !destination.ShouldOnlyTransferFromLowerPriority || !(destination.masterPriority <= source.masterPriority)) && (destination.storageNetworkID == -1 || destination.storageNetworkID != source.storageNetworkID)); debug_output += "------\n\n"; Debug.Log(debug_output); } if (FetchManager.IsFetchablePickup(pickup.pickupable, ref tag_bits, ref required_tags, ref forbid_tags, destination)) { egg_list.Add(pickup.pickupable); } } if (egg_list.Count == 0) { __result = (Pickupable)null; } // sort the list of eggs by incubation in ascending order (lowest incubation first) int sort_egg_incubation(Pickupable x, Pickupable y) { double x_incubation = Math.Round((x.gameObject.GetAmounts().Get(Db.Get().Amounts.Incubation)).value, 5); double y_incubation = Math.Round((y.gameObject.GetAmounts().Get(Db.Get().Amounts.Incubation)).value, 5); return(x_incubation.CompareTo(y_incubation)); } // return the first egg in the list (least incubation) egg_list.Sort(sort_egg_incubation); if (__DEBUG) { string debug_output = "Sorted list of eggs:\n"; foreach (Pickupable p in egg_list) { debug_output += "Position:\n"; UnityEngine.Vector3 pos = p.GetTargetPoint(); debug_output += String.Format("X: {0} Y: {1} Z: {2}\n", pos.x, pos.y, pos.z); debug_output += String.Format("Incubation: {0}\n", Math.Round((p.gameObject.GetAmounts().Get(Db.Get().Amounts.Incubation)).value, 5)); debug_output += "------\n\n"; } Debug.Log(debug_output); } __result = egg_list[0]; }