private static void UpdateWhenCurrentLocationPrefix(GameLocation __instance) { // Check each object in the location foreach (SObject curObject in __instance.Objects.Values) { // Try to get the object's machine state if (!MachineDelegator.TryGetMachineState(curObject, __instance, out IMachine machine, out IMachineInformation state)) { return; } // Update the state of the machine machine.UpdateTick(state); // Check if the machine has output available for the farmer IEnumerable <ObjectRequest> output = machine.RemoveItem(state, Game1.player, out _); // Display the output if so if (output?.FirstOrDefault() is ObjectRequest visibleOutput) { curObject.heldObject.Value = visibleOutput.Item; curObject.readyForHarvest.Value = true; } else { curObject.heldObject.Value = null; curObject.readyForHarvest.Value = false; } // TODO: call the delegate returned by RemoveItem when a player right clicks the machine to get the held object } }
private static void DrawPostfix(SObject __instance, SpriteBatch spriteBatch, int x, int y) { // Try to get the object's machine state if (!MachineDelegator.TryGetMachineState(__instance, Game1.currentLocation, out IMachine machine, out IMachineInformation state)) { return; } // Signal the machine's manager machine.AfterDraw(state, spriteBatch, x, y); }
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); }