public static void OnInputsInserted(PerformObjectDropInData PODIData, int AugmentorQuantity)
        {
#if LEGACYCODE
            if (MachineInfo.TryGetMachineInfo(PODIData.Machine, out MachineInfo Info))
            {
                if (!Info.AttachableAugmentors.Contains(AugmentorType.Duplication) || AugmentorQuantity <= 0 || !Info.RequiresInput || PODIData.Machine.readyForHarvest)
                {
                    return;
                }

                bool Success = SpawnDuplicate(AugmentorQuantity, PODIData.CurrentMinutesUntilReady, Info.RequiresInput, out double Chance);
                if (Success)
                {
                    if (PODIData.Machine.getOne() is Object Duplicate)
                    {
                        Duplicate.Stack = 1;
                        int SpawnDirection = Randomizer.Next(4);
                        Game1.createItemDebris(Duplicate, Game1.player.getStandingPosition(), SpawnDirection, null, -1);
                    }
                }

                MachineAugmentorsMod.LogTrace(AugmentorType.Duplication, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                              "CreateDuplicate", 0, Chance, Convert.ToInt32(Success), Chance);
            }
#endif
        }
        public static void OnInputsInserted(PerformObjectDropInData PODIData, int AugmentorQuantity)
        {
            if (MachineInfo.TryGetMachineInfo(PODIData.Machine, out MachineInfo Info))
            {
                if (!Info.AttachableAugmentors.Contains(AugmentorType.Efficiency) || AugmentorQuantity <= 0 || !Info.RequiresInput || PODIData.Input == null)
                {
                    return;
                }

                int PreviousAmountInserted = PODIData.PreviousInputQuantity - PODIData.CurrentInputQuantity;

                int    NewAmountInserted;
                double Effect;
                double DesiredNewValue;
                if (PreviousAmountInserted <= 0)
                {
                    //  No clue why, but for some machines the game hasn't actually taken the input yet by the time Object.performObjectDropIn finishes.
                    //  so assume the input amount was = to 1 when computing the refund.
                    NewAmountInserted = ComputeNewValue(AugmentorQuantity, 1, Info.RequiresInput, out Effect, out DesiredNewValue)
                                        - 1 - Math.Abs(PreviousAmountInserted); //  -1 because we assume it required at least 1 input, -PreviousInputQuantityUsed because another augmentor whose effect could have been applied first may have set the quantity to a negative value to allow saving a material
                }
                else
                {
                    NewAmountInserted = ComputeNewValue(AugmentorQuantity, PreviousAmountInserted, Info.RequiresInput, out Effect, out DesiredNewValue);
                }

                int RefundAmt = PreviousAmountInserted - NewAmountInserted;
                if (RefundAmt > 0)
                {
                    bool WasStackDepleted = PODIData.Input.Stack <= 0;
                    PODIData.Input.Stack += RefundAmt;

                    //  If Stack was set to 0 by the game, then the game would have removed it from their inventory, and so they wouldn't be able to receive the refunded quantity
                    if (WasStackDepleted && PODIData.WasInputInInventory && Game1.player.Items[PODIData.InputInventoryIndex.Value] == null)
                    {
                        Game1.player.addItemToInventory(PODIData.Input, PODIData.InputInventoryIndex.Value);
                    }
                }

                //  Refund coal when processing ores
                if (IsOre(PODIData.Input))
                {
                    double Chance          = 1.0 - Effect;
                    int    SpawnedQuantity = WeightedRound(Chance);
                    if (SpawnedQuantity > 0)
                    {
                        Object Coal           = new Object(382, SpawnedQuantity, false, -1, 0);
                        int    SpawnDirection = Randomizer.Next(4);
                        Game1.createItemDebris(Coal, PODIData.Machine.TileLocation * Game1.tileSize, SpawnDirection, null, -1);
                    }
                }

                MachineAugmentorsMod.LogTrace(AugmentorType.Efficiency, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                              "Input.Stack", PreviousAmountInserted, DesiredNewValue, NewAmountInserted, Effect);
            }
        }
        /// <summary>Intended to be invoked whenever the player inserts materials into a machine that requires inputs, such as when placing copper ore into a furnace.</summary>
        private static void OnInputsInserted(PerformObjectDropInData PODIData)
        {
            if (PODIData == null || PODIData.CurrentHeldObject == null || PODIData.Input == null || !Context.IsMainPlayer)
            {
                return;
            }

            SObject Machine = PODIData.Machine;

            if (Machine == null || !Machine.TryGetCombinedQuantity(out int CombinedQuantity))
            {
                return;
            }

            //  Compute the maximum multiplier we can apply to the input and output based on how many more of the inputs the player has
            int    PreviousInputQuantityUsed = PODIData.PreviousInputQuantity - PODIData.CurrentInputQuantity;
            double MaxMultiplier             = PreviousInputQuantityUsed == 0 ? PODIData.CurrentInputQuantity : Math.Abs(PODIData.PreviousInputQuantity * 1.0 / PreviousInputQuantityUsed);

            //  Modify the output
            int PreviousOutputStack = PODIData.CurrentHeldObjectQuantity;
            int NewOutputStack      = ComputeModifiedStack(CombinedQuantity, MaxMultiplier, PreviousOutputStack, out double OutputEffect, out double DesiredNewOutputValue);

            PODIData.CurrentHeldObject.Stack = NewOutputStack;
            Machine.SetHasModifiedOutput(true);
            ModEntry.LogTrace(CombinedQuantity, PODIData.Machine, PODIData.Machine.TileLocation, "HeldObject.Stack", PreviousOutputStack, DesiredNewOutputValue, NewOutputStack, OutputEffect);

            //  Modify the input
            int    CurrentInputQuantityUsed;
            double InputEffect;
            double DesiredNewInputValue;

            if (PreviousInputQuantityUsed <= 0)
            {
                //  No clue why, but for some machines the game hasn't actually taken the input yet by the time Object.performObjectDropIn finishes.
                //  so assume the input amount was = to 1.
                CurrentInputQuantityUsed = ComputeModifiedStack(CombinedQuantity, MaxMultiplier, 1, out InputEffect, out DesiredNewInputValue) - 1 - Math.Abs(PreviousInputQuantityUsed);
            }
            else
            {
                CurrentInputQuantityUsed = ComputeModifiedStack(CombinedQuantity, MaxMultiplier, PreviousInputQuantityUsed, out InputEffect, out DesiredNewInputValue);
            }
            int NewInputStack = PODIData.PreviousInputQuantity - CurrentInputQuantityUsed;

            PODIData.Input.Stack = NewInputStack;
            if (NewInputStack <= 0)
            {
                if (PODIData.WasInputInInventory)
                {
                    PODIData.Farmer.removeItemFromInventory(PODIData.Input);
                }
                else
                {
                    PODIData.Input.Stack = 1; // Just a failsafe to avoid glitched out Items with zero quantity, such as if the input came from a chest due to the Automate mod
                }
            }
        }
        public static void OnInputsInserted(PerformObjectDropInData PODIData, int AugmentorQuantity)
        {
#if LEGACYCODE
            if (MachineInfo.TryGetMachineInfo(PODIData.Machine, out MachineInfo Info))
            {
                if (!Info.AttachableAugmentors.Contains(AugmentorType.Quality) || AugmentorQuantity <= 0 || !Info.RequiresInput)
                {
                    return;
                }

                if (Info.IsFurnace() && Info.TryGetUpgradedQuality(PODIData.CurrentHeldObject, out Object UpgradedObject))
                {
                    double Effect  = ComputeEffect(AugmentorQuantity, Info.RequiresInput);
                    bool   Success = WeightedRound(Effect) == 1;
                    if (Success)
                    {
                        PODIData.Machine.heldObject.Value = UpgradedObject;
                    }

                    MachineAugmentorsMod.LogTrace(AugmentorType.Quality, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                                  "HeldObject.Quality", 0, Effect, Success ? 1 : 0, Effect);
                }
                else if (Info.HasQualityProducts)
                {
                    int PreviousQuality = PODIData.CurrentHeldObject.Quality;
                    int NewQuality      = ComputeNewValue(AugmentorQuantity, PreviousQuality, Info.RequiresInput, out double Effect, out double DesiredNewValue);
                    PODIData.CurrentHeldObject.Quality = NewQuality;

                    MachineAugmentorsMod.LogTrace(AugmentorType.Quality, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                                  "HeldObject.Quality", PreviousQuality, DesiredNewValue, NewQuality, Effect);
                }
            }
#endif
            if (MachineInfo.TryGetMachineInfo(PODIData.Machine, out MachineInfo Info))
            {
                if (!Info.AttachableAugmentors.Contains(AugmentorType.Quality) || AugmentorQuantity <= 0 || !Info.RequiresInput)
                {
                    return;
                }

                if (Info.IsFurnace() && Info.TryGetUpgradedQuality(PODIData.CurrentHeldObject, out Object UpgradedObject))
                {
                    double Effect  = ComputeEffect(AugmentorQuantity, Info.RequiresInput);
                    bool   Success = WeightedRound(Effect) == 1;
                    if (Success)
                    {
                        PODIData.Machine.heldObject.Value = UpgradedObject;
                    }

                    MachineAugmentorsMod.LogTrace(AugmentorType.Quality, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                                  "HeldObject.Quality", 0, Effect, Success ? 1 : 0, Effect);
                }
            }
        }
        public static void OnInputsInserted(PerformObjectDropInData PODIData, int AugmentorQuantity)
        {
#if LEGACYCODE
            if (MachineInfo.TryGetMachineInfo(PODIData.Machine, out MachineInfo Info))
            {
                if (!Info.AttachableAugmentors.Contains(AugmentorType.Speed) || AugmentorQuantity <= 0 || !Info.RequiresInput || PODIData.Machine.readyForHarvest.Value)
                {
                    return;
                }

                int PreviousMinutes = PODIData.CurrentMinutesUntilReady;
                int NewMinutes      = ComputeNewValue(AugmentorQuantity, PreviousMinutes, Info.RequiresInput, out double Effect, out double DesiredNewValue);

                if (PreviousMinutes != NewMinutes)
                {
                    //  Find the GameLocation of the Machine
                    //  (Possible TODO: If using Automate mod, may need to iterate all GameLocations until finding the one where GameLocation.Objects[Machine Tile Location] is the Machine)
                    GameLocation MachineLocation = null;
                    if (Game1.player.currentLocation.Objects.TryGetValue(PODIData.Machine.TileLocation, out Object PlacedMachine) && PlacedMachine == PODIData.Machine)
                    {
                        MachineLocation = Game1.player.currentLocation;
                    }

                    //  There seems to be a bug where there is no product if the machine is instantly done processing.
                    //NewMinutes = Math.Max(10, NewMinutes); // temporary fix - require at least one 10-minute processing cycle
                    //  It looks like Object.checkForAction happens right AFTER Object.performObjectDropIn, and checkForAction is setting Object.heldObject=null if Object.readyForHarvest=true
                    //  So set a flag that tells GamePatches.CheckForAction_Prefix to skip execution
                    if (NewMinutes <= 0)
                    {
                        GamePatches.SkipNextCheckForAction = true;
                    }

                    if (MachineLocation != null)
                    {
                        int Elapsed = PreviousMinutes - NewMinutes;
                        PODIData.Machine.minutesElapsed(Elapsed, MachineLocation);
                    }
                    else
                    {
                        PODIData.Machine.MinutesUntilReady = NewMinutes;
                        if (NewMinutes <= 0)
                        {
                            PODIData.Machine.readyForHarvest.Value = true;
                        }
                    }
                }

                MachineAugmentorsMod.LogTrace(AugmentorType.Speed, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                              "HeldObject.MinutesUntilReady", PreviousMinutes, DesiredNewValue, NewMinutes, Effect);
            }
#endif
        }
        internal void OnInputsInserted(PerformObjectDropInData PODIData)
        {
            if (!PODIData.IsLocalPlayer)
            {
                return;
            }

            //  This point of the code should be reached when placing an input item into a machine that requires inputs,
            //  such as when placing Copper Ore into a furnace
            if (TryFindAugmentedTile(PODIData.Machine, PODIData.Machine.TileLocation, out AugmentedTile AT))
            {
                foreach (KeyValuePair <AugmentorType, int> KVP in GetOrderedEnumerable(AT.Quantities))
                {
                    AugmentorType Type             = KVP.Key;
                    int           AttachedQuantity = KVP.Value;

                    if (AttachedQuantity > 0)
                    {
                        if (Type == AugmentorType.Output)
                        {
                            OutputAugmentor.OnInputsInserted(PODIData, AttachedQuantity);
                        }
                        else if (Type == AugmentorType.Speed)
                        {
                            SpeedAugmentor.OnInputsInserted(PODIData, AttachedQuantity);
                        }
                        else if (Type == AugmentorType.Efficiency)
                        {
                            EfficiencyAugmentor.OnInputsInserted(PODIData, AttachedQuantity);
                        }
                        else if (Type == AugmentorType.Quality)
                        {
                            QualityAugmentor.OnInputsInserted(PODIData, AttachedQuantity);
                        }
                        else if (Type == AugmentorType.Production)
                        {
                            ProductionAugmentor.OnInputsInserted(PODIData, AttachedQuantity);
                        }
                        else if (Type == AugmentorType.Duplication)
                        {
                            DuplicationAugmentor.OnInputsInserted(PODIData, AttachedQuantity);
                        }
                        else
                        {
                            throw new NotImplementedException(string.Format("Unrecognized AugmentorType: {0}", Type.ToString()));
                        }
                    }
                }
            }
        }
        public static void OnInputsInserted(PerformObjectDropInData PODIData, int AugmentorQuantity)
        {
#if LEGACYCODE
            if (MachineInfo.TryGetMachineInfo(PODIData.Machine, out MachineInfo Info))
            {
                if (!Info.AttachableAugmentors.Contains(AugmentorType.Output) || !Info.RequiresInput || PODIData.CurrentHeldObject == null)
                {
                    return;
                }

                int PreviousStack = PODIData.CurrentHeldObjectQuantity;
                int NewStack      = ComputeNewValue(AugmentorQuantity, PreviousStack, Info.RequiresInput, out double Effect, out double DesiredNewValue);
                PODIData.CurrentHeldObject.Stack = NewStack;

                MachineAugmentorsMod.LogTrace(AugmentorType.Output, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                              "HeldObject.Stack", PreviousStack, DesiredNewValue, NewStack, Effect);
            }
#endif
        }
Exemplo n.º 8
0
        public static bool Prefix(SObject __instance, Item dropInItem, bool probe, Farmer who, ref bool __result)
        {
            try
            {
                if (probe)
                {
                    PODIData = null;
                }
                else
                {
                    PODIData = new PerformObjectDropInData(who, __instance, dropInItem);
                    //ModEntry.Logger.Log(string.Format("{0} Prefix: {0} ({1})", nameof(PerformObjectDropInActionPatch), dropInItem.DisplayName, dropInItem.Stack), LogLevel.Info);
                }

                return(true);
            }
            catch (Exception ex)
            {
                ModEntry.Logger.Log(string.Format("Unhandled Error in {0}.{1}:\n{2}", nameof(PerformObjectDropInActionPatch), nameof(Prefix), ex), LogLevel.Error);
                PODIData = null;
                return(true);
            }
        }
Exemplo n.º 9
0
        public static bool PerformObjectDropInAction_Prefix(Object __instance, Item dropInItem, bool probe, Farmer who, ref bool __result)
        {
            try
            {
                if (probe)
                {
                    PODIData = null;
                }
                else
                {
                    PODIData = new PerformObjectDropInData(who, __instance, dropInItem);
                    //MachineAugmentorsMod.ModInstance.Monitor.Log(string.Format("Prefix: {0} ({1})", dropInItem.DisplayName, dropInItem.Stack), LogLevel.Info);
                }

                return(true);
            }
            catch (Exception ex)
            {
                MachineAugmentorsMod.ModInstance.Monitor.Log(string.Format("Unhandled Error in {0}:\n{1}", nameof(PerformObjectDropInAction_Prefix), ex), LogLevel.Error);
                PODIData = null;
                return(true);
            }
        }
Exemplo n.º 10
0
        public static void OnInputsInserted(PerformObjectDropInData PODIData, int AugmentorQuantity)
        {
            if (MachineInfo.TryGetMachineInfo(PODIData.Machine, out MachineInfo Info))
            {
                if (!Info.AttachableAugmentors.Contains(AugmentorType.Production) || AugmentorQuantity <= 0 || !Info.RequiresInput || PODIData.CurrentHeldObject == null || PODIData.Input == null)
                {
                    return;
                }

                //  Compute the maximum multiplier we can apply to the input and output based on how many more of the inputs the player has
                int    PreviousInputQuantityUsed = PODIData.PreviousInputQuantity - PODIData.CurrentInputQuantity;
                double MaxMultiplier             = PreviousInputQuantityUsed == 0 ? int.MaxValue : Math.Abs(PODIData.PreviousInputQuantity * 1.0 / PreviousInputQuantityUsed);

                //  Modify the output
                int PreviousOutputStack = PODIData.CurrentHeldObjectQuantity;
                int NewOutputStack      = ComputeNewValue(AugmentorQuantity, MaxMultiplier, PreviousOutputStack, Info.RequiresInput, out double OutputEffect, out double DesiredNewOutputValue);
                PODIData.CurrentHeldObject.Stack = NewOutputStack;
                MachineAugmentorsMod.LogTrace(AugmentorType.Production, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                              "HeldObject.Stack", PreviousOutputStack, DesiredNewOutputValue, NewOutputStack, OutputEffect);

                //  Modify the input
                int    CurrentInputQuantityUsed;
                double InputEffect;
                double DesiredNewInputValue;
                if (PreviousInputQuantityUsed <= 0)
                {
                    //  No clue why, but for some machines the game hasn't actually taken the input yet by the time Object.performObjectDropIn finishes.
                    //  so assume the input amount was = to 1.
                    CurrentInputQuantityUsed = ComputeNewValue(AugmentorQuantity, MaxMultiplier, 1, Info.RequiresInput, out InputEffect, out DesiredNewInputValue)
                                               - 1 - Math.Abs(PreviousInputQuantityUsed); //  -1 because we assume it required at least 1 input, -PreviousInputQuantityUsed because EfficiencyAugmentor may have set the quantity to a negative value to allow saving a material
                }
                else
                {
                    CurrentInputQuantityUsed = ComputeNewValue(AugmentorQuantity, MaxMultiplier, PreviousInputQuantityUsed, Info.RequiresInput, out InputEffect, out DesiredNewInputValue);
                }
                int NewInputStack = PODIData.PreviousInputQuantity - CurrentInputQuantityUsed;
                PODIData.Input.Stack = NewInputStack;
                if (NewInputStack <= 0)
                {
                    if (PODIData.WasInputInInventory)
                    {
                        Game1.player.removeItemFromInventory(PODIData.Input);
                    }
                    else
                    {
                        PODIData.Input.Stack = 1; // Just a failsafe to avoid glitched out Items with zero quantity, such as if the input came from a chest due to the Automate mod
                    }
                }

                ////  Modify the input
                //int CurrentInputQuantityUsed = ComputeNewValue(AugmentorQuantity, MaxMultiplier, PreviousInputQuantityUsed, Info.RequiresInput, out double InputEffect, out double DesiredNewInputValue);
                //int NewInputStack = PODIData.PreviousInputQuantity - CurrentInputQuantityUsed;
                //PODIData.Input.Stack = NewInputStack;
                //if (NewInputStack <= 0)
                //{
                //    if (PODIData.WasInputInInventory)
                //        Game1.player.removeItemFromInventory(PODIData.Input);
                //    else
                //    {
                //        PODIData.Input.Stack = 1; // Just a failsafe to avoid glitched out Items with zero quantity, such as if the input came from a chest due to the Automate mod
                //    }
                //}

                MachineAugmentorsMod.LogTrace(AugmentorType.Production, AugmentorQuantity, PODIData.Machine, Info.RequiresInput, PODIData.Machine.TileLocation,
                                              "Input-UsedAmount", PreviousInputQuantityUsed, DesiredNewInputValue, CurrentInputQuantityUsed, InputEffect);
            }
        }
Exemplo n.º 11
0
        /// <summary>Intended to be invoked whenever the player inserts materials into a machine that requires inputs, such as when placing copper ore into a furnace.</summary>
        private static void OnInputsInserted(PerformObjectDropInData PODIData)
        {
            if (PODIData == null || PODIData.CurrentHeldObject == null || PODIData.Input == null)
            {
                return;
            }

            bool IsCurrentPlayer = (!Context.IsMultiplayer && !Context.IsSplitScreen) || PODIData.Farmer.UniqueMultiplayerID == Game1.player.UniqueMultiplayerID;

            if (!IsCurrentPlayer)
            {
                return;
            }

            SObject Machine = PODIData.Machine;

            if (!ModEntry.UserConfig.ShouldModifyInputsAndOutputs(Machine) || !Machine.TryGetCombinedQuantity(out int CombinedQuantity))
            {
                return;
            }

            int SecondaryInputQuantityAvailable = int.MaxValue;

            if (PODIData.Input.IsOre() && PODIData.Farmer != null && ModEntry.UserConfig.FurnaceMultiplyCoalInputs)
            {
                SecondaryInputQuantityAvailable = PODIData.Farmer.Items.Where(x => x != null && x.IsCoal()).Sum(x => x.Stack);
            }

            //  Compute the maximum multiplier we can apply to the input and output based on how many more of the inputs the player has
            int    PreviousInputQuantityUsed = PODIData.PreviousInputQuantity - PODIData.CurrentInputQuantity;
            double MaxMultiplier             = Math.Min(SecondaryInputQuantityAvailable, PreviousInputQuantityUsed == 0 ?
                                                        PODIData.CurrentInputQuantity :
                                                        Math.Abs(PODIData.PreviousInputQuantity * 1.0 / PreviousInputQuantityUsed));

            //  Modify the output
            int PreviousOutputStack = PODIData.CurrentHeldObjectQuantity;
            int NewOutputStack      = ComputeModifiedStack(CombinedQuantity, MaxMultiplier, PreviousOutputStack, out double OutputEffect, out double DesiredNewOutputValue);

            PODIData.CurrentHeldObject.Stack = NewOutputStack;
            Machine.SetHasModifiedOutput(true);
            ModEntry.LogTrace(CombinedQuantity, PODIData.Machine, PODIData.Machine.TileLocation, "HeldObject.Stack", PreviousOutputStack, DesiredNewOutputValue, NewOutputStack, OutputEffect);

            //  Modify the input
            int    CurrentInputQuantityUsed;
            double InputEffect;
            double DesiredNewInputValue;

            if (PreviousInputQuantityUsed <= 0)
            {
                //  No clue why, but for some machines the game hasn't actually taken the input yet by the time Object.performObjectDropIn finishes.
                //  so assume the input amount was = to 1.
                CurrentInputQuantityUsed = ComputeModifiedStack(CombinedQuantity, MaxMultiplier, 1, out InputEffect, out DesiredNewInputValue) - 1 - Math.Abs(PreviousInputQuantityUsed);
            }
            else
            {
                CurrentInputQuantityUsed = ComputeModifiedStack(CombinedQuantity, MaxMultiplier, PreviousInputQuantityUsed, out InputEffect, out DesiredNewInputValue);
            }
            int NewInputStack = PODIData.PreviousInputQuantity - CurrentInputQuantityUsed;

            PODIData.Input.Stack = NewInputStack;
            if (NewInputStack <= 0)
            {
                if (PODIData.WasInputInInventory)
                {
                    PODIData.Farmer.removeItemFromInventory(PODIData.Input);
                }
                else
                {
                    PODIData.Input.Stack = 1; // Just a failsafe to avoid glitched out Items with zero quantity, such as if the input came from a chest due to the Automate mod
                }
            }

            if (PODIData.Input.IsOre() && PODIData.Farmer != null && ModEntry.UserConfig.FurnaceMultiplyCoalInputs)
            {
                int RemainingCoalToConsume = RNGHelpers.WeightedRound(OutputEffect) - 1; // 1 coal was already automatically consumed by the vanilla function
                for (int i = 0; i < PODIData.Farmer.Items.Count; i++)
                {
                    Item CurrentItem = PODIData.Farmer.Items[i];
                    if (CurrentItem != null && CurrentItem.IsCoal())
                    {
                        int AmountToConsume = Math.Min(CurrentItem.Stack, RemainingCoalToConsume);
                        CurrentItem.Stack      -= AmountToConsume;
                        RemainingCoalToConsume -= AmountToConsume;

                        if (CurrentItem.Stack <= 0)
                        {
                            PODIData.Farmer.removeItemFromInventory(i);
                        }

                        if (RemainingCoalToConsume <= 0)
                        {
                            break;
                        }
                    }
                }
            }
        }