private static void CheckForActionPostfix(SObject __instance, CheckForActionState __state, Farmer who) { // Check if object was ready for harvest if (!__state.Ready) { return; } // Check what changed int removedCount; if (__instance.heldObject?.Value == null || __instance.heldObject.Value.ParentSheetIndex != __state.Held.ParentSheetIndex) { removedCount = __state.Stack; } else { removedCount = __state.Stack - __instance.heldObject.Value.Stack; } // Make sure stuff was removed if (removedCount <= 0) { return; } // Try to get the object's machine state if (!MachineDelegator.TryGetMachineState(__instance, Game1.currentLocation, out IMachine machine, out IMachineInformation state)) { return; } // Get the machine's remove action _ = machine.RemoveItem(state, who, out Action doRemove); // Update the state of the machine doRemove(); }
private static bool CheckForActionPrefix(SObject __instance, ref CheckForActionState __state, ref bool __result, Farmer who, bool justCheckingForActivity) { return(true); if (who?.ActiveObject != null) { // Try to get the object's machine state if (!MachineDelegator.TryGetMachineState(__instance, Game1.currentLocation, out IMachine machine, out IMachineInformation state)) { return(true); } // Get the machine's insert action List <ObjectRequest> requestedPayload = machine.InsertItem(state, who.ActiveObject, who.Items.ToArray(), who, out Action doInsert)?.ToList() ?? new List <ObjectRequest>(); // Check if there is an insert action if (doInsert != null) { // Check if the game is just probing if (justCheckingForActivity) { __result = true; __state = new CheckForActionState(false, null); return(false); } // Track the original sizes of each modified item in the player's inventory Dictionary <Item, int> originalStacks = new Dictionary <Item, int>(); // Try to satisfy every request HashSet <ObjectRequest> unsatisfiedRequests = requestedPayload.ToHashSet(); bool failed = false; foreach (ObjectRequest request in requestedPayload) { // Keep track of how much of this request is left int remaining = request.Quantity; // Keep searching the player's inventory until either the request is satisfied or there are no more items to satisfy it with while (remaining > 0) { // Try to find that exact item in the player's inventory Item inventoryItem = who.Items.FirstOrDefault(i => i != null && i.Stack > 0 && i == request.Item); // Try to find another item that matches the requested item if the exact item wasn't found if (inventoryItem == null) { inventoryItem = who.Items.FirstOrDefault(i => i != null && i.Stack > 0 && i.ParentSheetIndex == request.Item.ParentSheetIndex); } // Check if the request can't be satisfied if (inventoryItem == null) { failed = true; break; } // Track the original stack size of the item if (!originalStacks.ContainsKey(inventoryItem)) { originalStacks.Add(inventoryItem, inventoryItem.Stack); } // Decrement the quantity as much as possible int removedFromItem = Math.Min(inventoryItem.Stack, remaining); remaining -= removedFromItem; inventoryItem.Stack -= removedFromItem; } // Check if the request failed if (failed) { // Stop trying to satisfy requests break; } // Check if the request was satisfied if (remaining == 0) { // Add the satisfied request unsatisfiedRequests.Remove(request); } } // Check if the request failed if (failed) { // Revert changes to the player's inventory foreach ((Item item, int quantity) in originalStacks) { item.Stack = quantity; } } else { // Remove empty stacks from the player's inventory foreach ((Item item, _) in originalStacks) { if (item.Stack == 0) { who.removeItemFromInventory(item); } } // Update the state of the machine doInsert(); // Set the state so the postfix doesn't check if an item was removed __state = new CheckForActionState(false, null); } } } // Track this object to see if an item was removed from it __state = new CheckForActionState(__instance.readyForHarvest.Value, __instance.heldObject.Value); return(true); }