/// <summary>Processes the input chest's items and places the result to the output</summary> /// <param name="furnace"></param> private void FinishSmelting(IndustrialFurnaceController furnace) { // TODO: Add checks to prevent loss of items, since it is possible that 'output amount' > 'input amount' Monitor.Log("Processing the outputs."); // Collect the object data to a dictionary (ID, amount) first to fix losing items with over 999 stacks Dictionary <int, int> smeltablesDictionary = new Dictionary <int, int>(); foreach (Item item in furnace.input.items) { int objectId = item.ParentSheetIndex; if (smeltablesDictionary.ContainsKey(objectId)) { smeltablesDictionary[objectId] += item.Stack; } else { smeltablesDictionary.Add(objectId, item.Stack); } } // Now the dictionary consists of ItemID: Amount foreach (KeyValuePair <int, int> kvp in smeltablesDictionary) { SmeltingRule rule = newSmeltingRules.GetSmeltingRuleFromInputID(kvp.Key); if (rule is null) { // This should never be hit, but let's error it just incase... Monitor.Log($"Item with ID {kvp.Key} wasn't in the smelting rules despite being in the input chest!", LogLevel.Error); continue; } if (rule.InputItemAmount == 0) { Monitor.Log($"The input amount for object {kvp.Key} was 0. The result can't be processed so the item will be voided.", LogLevel.Error); } int outputAmount = (kvp.Value / rule.InputItemAmount) * rule.OutputItemAmount; Monitor.Log($"Found {kvp.Value} objects with ID {kvp.Key}. The smelting result is {outputAmount} objects of ID {rule.OutputItemID}."); // Add the result defined by the smelting rule to the output chest // Assumes the value is divisible with the input amount furnace.AddItemsToSmeltedChest(rule.OutputItemID, outputAmount); } for (int i = 0; i < furnace.input.items.Count; i++) { furnace.input.items[i] = null; } furnace.input.clearNulls(); furnace.ChangeCurrentlyOn(false); // Update the texture of the furnace UpdateTexture(furnace.furnace, false); }
/// <summary>Place items to the furnace</summary> /// <param name="furnace">The furnace controller</param> /// <returns>Whether the placement was successful or not</returns> private bool PlaceItemsToTheFurnace(IndustrialFurnaceController furnace) { // Items can be placed only if the furnace is NOT on if (furnace.CurrentlyOn) { DisplayMessage(i18n.Get("message.furnace-running"), 3, "cancel"); return(false); } // Get the current held object, null for tools etc. SObject heldItem = Game1.player.ActiveObject; if (heldItem == null) { return(false); } int objectId = heldItem.ParentSheetIndex; SmeltingRule rule = newSmeltingRules.GetSmeltingRuleFromInputID(objectId); // Check if the object is on the smeltables list if (rule != null) { // Prevent the game from division by 0, even if the player edits the rules if (rule.InputItemAmount == 0) { Monitor.Log($"The smelting rule for object {objectId} had 0 for input amount.", LogLevel.Error); return(false); } int amount = heldItem.Stack; // Check if the player has enough to smelt if (amount >= rule.InputItemAmount) { // Remove multiples of the required input amount int smeltAmount = amount / rule.InputItemAmount; Game1.player.removeItemsFromInventory(objectId, smeltAmount * rule.InputItemAmount); furnace.AddItemsToSmelt(objectId, smeltAmount * rule.InputItemAmount); Monitor.Log($"{Game1.player.Name} placed {smeltAmount * rule.InputItemAmount} {heldItem.Name} to the furnace {furnace.ID}."); return(true); } else { DisplayMessage(i18n.Get("message.need-more-ore", new { oreAmount = rule.InputItemAmount }), 3, "cancel"); return(false); } } // Check if the player tries to put coal in the furnace and start the smelting else if (objectId == SObject.coal && !furnace.CurrentlyOn) { // The input has items to smelt if (furnace.input.items.Count > 0) { if (heldItem.Stack >= config.CoalAmount) { Game1.player.removeItemsFromInventory(objectId, config.CoalAmount); Monitor.Log($"{Game1.player.Name} started the furnace {furnace.ID} with {config.CoalAmount} {heldItem.Name}."); if (config.InstantSmelting) { Monitor.Log("And it finished immediately."); FinishSmelting(furnace); } else { furnace.ChangeCurrentlyOn(true); UpdateTexture(furnace.furnace, true); CreateLight(furnace); } Game1.playSound("furnace"); return(true); } else { DisplayMessage(i18n.Get("message.more-coal", new { coalAmount = config.CoalAmount }), 3, "cancel"); return(false); } } else { DisplayMessage(i18n.Get("message.place-something-first"), 3, "cancel"); return(false); } } else { DisplayMessage(i18n.Get("message.cant-smelt-this"), 3, "cancel"); return(false); } }