internal void Reset(Item item)
 {
     ProducerRuleController.ClearProduction(_machine, Location);
     if (ProducerController.GetProducerConfig(_machine.Name) is ProducerConfig producerConfig)
     {
         if (producerConfig.NoInputStartMode != null || producerConfig.IncrementStatsOnOutput.Count > 0)
         {
             producerConfig.IncrementStats(item);
             if (producerConfig.NoInputStartMode == NoInputStartMode.Placement)
             {
                 if (ProducerController.GetProducerItem(_machine.Name, null) is ProducerRule producerRule)
                 {
                     try
                     {
                         if (producerConfig.CheckLocationCondition(Location) && producerConfig.CheckSeasonCondition())
                         {
                             ProducerRuleController.ProduceOutput(producerRule, _machine, (i, q) => true, null, Location, producerConfig);
                         }
                     }
                     catch (RestrictionException) { /*No action needed*/ }
                 }
             }
         }
     }
 }
Ejemplo n.º 2
0
        [HarmonyPriority(Priority.First + 1)] //Just before ProducerFrameworkMod. Can't use HarmonyBefore attribute, that wasn't working for some reason
        public static bool DayUpdate_Prefix(SObject __instance, GameLocation location)
        {
            if (__instance == null || string.IsNullOrEmpty(__instance.GetMassProducerKey()))
            {
                return(true);
            }

            MassProductionMachineDefinition mpm = ModEntry.GetMPMMachine(__instance.name, __instance.GetMassProducerKey());

            if (mpm == null)
            {
                return(true);
            }

            if (__instance.bigCraftable.Value)
            {
                if (ProducerController.GetProducerConfig(__instance.Name) is ProducerConfig producerConfig)
                {
                    if (producerConfig != null)
                    {
                        if (ProducerController.GetProducerItem(__instance.Name, null) is ProducerRule producerRule)
                        {
                            if (!producerConfig.CheckSeasonCondition() || !producerConfig.CheckLocationCondition(location))
                            {
                                ProducerRuleController.ClearProduction(__instance, location);
                                return(false);
                            }
                            else if (producerConfig.NoInputStartMode != null)
                            {
                                if (producerConfig.NoInputStartMode == NoInputStartMode.DayUpdate || producerConfig.NoInputStartMode == NoInputStartMode.Placement)
                                {
                                    if (__instance.heldObject.Value == null)
                                    {
                                        try
                                        {
                                            Farmer who = Game1.getFarmer((long)__instance.owner);
                                            PFMCompatability.ProduceOutput(producerRule, mpm.Settings, __instance,
                                                                           (i, q) => who.hasItemInInventory(i, q), who, who.currentLocation, producerConfig);
                                        }
                                        catch (RestrictionException)
                                        {
                                            //Does not show the restriction error since the machine is auto-starting.
                                        }
                                    }
                                }
                                return(false);
                            }
                        }
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 3
0
        public bool SetInput(IStorage input)
        {
            foreach (ITrackedStack trackedStack in input.GetItems())
            {
                if (trackedStack.Sample is SObject objectInput &&
                    !objectInput.bigCraftable.Value &&
                    ProducerController.GetProducerItem(_machine.Name, objectInput) is ProducerRule producerRule &&
                    !ProducerRuleController.IsInputExcluded(producerRule, objectInput))
                {
                    ProducerConfig producerConfig = ProducerController.GetProducerConfig(_machine.Name);

                    if (producerConfig == null || (producerConfig.CheckLocationCondition(Location) && producerConfig.CheckSeasonCondition(Location)))
                    {
                        if (input.TryGetIngredient(objectInput.ParentSheetIndex, producerRule.InputStack,
                                                   out IConsumable inputConsumable))
                        {
                            objectInput = inputConsumable.Sample as SObject;
                            List <IConsumable> requiredFuels = GetRequiredFuels(producerRule, input);
                            if (requiredFuels != null)
                            {
                                try
                                {
                                    if (objectInput != null)
                                    {
                                        objectInput.Stack = inputConsumable.Consumables.Count;
                                    }
                                    OutputConfig outputConfig = ProducerRuleController.ProduceOutput(producerRule, _machine,
                                                                                                     (i, q) => input.TryGetIngredient(i, q, out IConsumable fuel), null, Location,
                                                                                                     producerConfig, objectInput, noSoundAndAnimation: true);
                                    if (outputConfig != null)
                                    {
                                        if (outputConfig.RequiredInputStack.HasValue)
                                        {
                                            inputConsumable.Consumables.Reduce(outputConfig.RequiredInputStack.Value);
                                        }
                                        else
                                        {
                                            inputConsumable.Reduce();
                                        }
                                        requiredFuels.ForEach(f => f.Reduce());
                                        List <IConsumable> outputRequiredFuels = GetRequiredFuels(outputConfig, input);
                                        outputRequiredFuels.ForEach(f => f.Reduce());
                                        return(true);
                                    }
                                }
                                catch (RestrictionException) { /* No action needed */ }
                            }
                        }
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Adapted from https://github.com/Digus/StardewValleyMods/blob/master/PFMAutomate/Automate/CustomProducerMachine.cs
        /// </summary>
        /// <param name="item"></param>
        internal void Reset(Item item)
        {
            PFMCompatability.ClearProduction(Machine, Location);
            MassProductionMachineDefinition mpm = null;
            ProducerConfig producerConfig;

            if (IsMassProducer)
            {
                mpm            = ModEntry.GetMPMMachine(Machine.name, Machine.GetMassProducerKey());
                producerConfig = ProducerController.GetProducerConfig(mpm.BaseProducerName);
            }
            else
            {
                producerConfig = ProducerController.GetProducerConfig(Machine.name);
            }

            if (producerConfig == null)
            {
                return;
            }
            else if (producerConfig.NoInputStartMode != null || producerConfig.IncrementStatsOnOutput.Count > 0)
            {
                producerConfig.IncrementStats(item);
                if (producerConfig.NoInputStartMode == NoInputStartMode.Placement)
                {
                    if (ProducerController.GetProducerItem(Machine.Name, null) is ProducerRule producerRule)
                    {
                        try
                        {
                            if (producerConfig.CheckLocationCondition(Location) && producerConfig.CheckSeasonCondition())
                            {
                                if (mpm != null)
                                {
                                    PFMCompatability.ProduceOutput(producerRule, mpm.Settings, Machine, (i, q) => true, null, Location, producerConfig);
                                }
                                else
                                {
                                    ProducerRuleController.ProduceOutput(producerRule, Machine, (i, q) => true, null, Location, producerConfig);
                                }
                            }
                        }
                        catch (RestrictionException) { /*No action needed*/ }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        public bool SetInput(IStorage input)
        {
            foreach (ITrackedStack trackedStack in input.GetItems())
            {
                if (trackedStack.Sample is SObject objectInput &&
                    !objectInput.bigCraftable.Value &&
                    ProducerController.GetProducerItem(_machine.Name, objectInput) is ProducerRule producerRule &&
                    !ProducerRuleController.IsInputExcluded(producerRule, objectInput))
                {
                    if (input.TryGetIngredient(objectInput.ParentSheetIndex, producerRule.InputStack, out IConsumable inputConsumable))
                    {
                        objectInput = inputConsumable.Sample as SObject;
                        List <IConsumable> requiredFuels = GetRequiredFuels(producerRule, input);
                        if (requiredFuels != null)
                        {
                            Random       random       = ProducerRuleController.GetRandomForProducing(_machine.TileLocation);
                            OutputConfig outputConfig = OutputConfigController.ChooseOutput(producerRule.OutputConfigs, random);
                            SObject      output       = OutputConfigController.CreateOutput(outputConfig, objectInput, random);
                            _machine.heldObject.Value = output;
                            OutputConfigController.LoadOutputName(outputConfig, output, objectInput);

                            _machine.MinutesUntilReady = producerRule.MinutesUntilReady;

                            if (ProducerController.GetProducerConfig(_machine.Name) is ProducerConfig producerConfig)
                            {
                                _machine.showNextIndex.Value = producerConfig.AlternateFrameProducing;
                            }

                            _machine.initializeLightSource(_machine.TileLocation, false);

                            producerRule.IncrementStatsOnInput.ForEach(s => StatsController.IncrementStardewStats(s, producerRule.InputStack));

                            inputConsumable.Take();
                            requiredFuels.ForEach(f => f.Reduce());
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Makes the machine produce an appropriate output.
        /// Adapted from https://github.com/Digus/StardewValleyMods/blob/master/ProducerFrameworkMod/OutputConfigController.cs
        /// </summary>
        /// <param name="producerRule"></param>
        /// <param name="settings"></param>
        /// <param name="producer"></param>
        /// <param name="fuelSearch"></param>
        /// <param name="who"></param>
        /// <param name="location"></param>
        /// <param name="producerConfig"></param>
        /// <param name="input"></param>
        /// <param name="probe"></param>
        /// <param name="noSoundAndAnimation"></param>
        /// <returns>Base output config - no values altered for mass production machine</returns>
        public static OutputConfig ProduceOutput(ProducerRule producerRule, MPMSettings settings, SObject producer, Func <int, int, bool> fuelSearch, Farmer who, GameLocation location,
                                                 ProducerConfig producerConfig = null, SObject input = null, int inputQuantity = 0, bool probe = false, bool noSoundAndAnimation = false,
                                                 List <InputInfo> inputInfo    = null)
        {
            if (who == null)
            {
                who = Game1.getFarmer((long)producer.owner);
            }

            if (inputInfo == null)
            {
                inputInfo = new List <InputInfo>();
            }

            Vector2      tileLocation = producer.TileLocation;
            Random       random       = ProducerRuleController.GetRandomForProducing(tileLocation);
            OutputConfig outputConfig = OutputConfigController.ChooseOutput(producerRule.OutputConfigs, random, fuelSearch, location, input);

            if (outputConfig != null)
            {
                SObject output = producerRule.LookForInputWhenReady == null?OutputConfigController.CreateOutput(outputConfig, input, random) : new SObject(outputConfig.OutputIndex, 1);

                output.Stack = settings.CalculateOutputProduced(output.Stack, inputInfo.ToArray());

                if (settings.Quality.HasValue)
                {
                    if (settings.Quality == QualitySetting.KeepInput)
                    {
                        output.Quality = input.Quality;
                    }
                    else
                    {
                        output.Quality = settings.GetOutputQuality();
                    }
                }

                producer.heldObject.Value = output;

                if (!probe)
                {
                    if (producerRule.LookForInputWhenReady == null)
                    {
                        OutputConfigController.LoadOutputName(outputConfig, producer.heldObject.Value, input, who);
                    }

                    //if (!noSoundAndAnimation)
                    //{
                    //    SoundUtil.PlaySound(producerRule.Sounds, location);
                    //    SoundUtil.PlayDelayedSound(producerRule.DelayedSounds, location);
                    //}

                    int minutesUntilReadyBase = outputConfig.MinutesUntilReady ?? producerRule.MinutesUntilReady;
                    int minutesUntilReady     = settings.CalculateTimeRequired(minutesUntilReadyBase, inputInfo.ToArray());

                    producer.minutesUntilReady.Value = minutesUntilReady;
                    if (producerRule.SubtractTimeOfDay)
                    {
                        producer.minutesUntilReady.Value = Math.Max(producer.minutesUntilReady.Value - Game1.timeOfDay, 1);
                    }

                    if (producerConfig != null)
                    {
                        producer.showNextIndex.Value = producerConfig.AlternateFrameProducing;
                    }

                    //if (producerRule.PlacingAnimation.HasValue && !noSoundAndAnimation)
                    //{
                    //    AnimationController.DisplayAnimation(producerRule.PlacingAnimation.Value,
                    //        producerRule.PlacingAnimationColor, location, tileLocation,
                    //        new Vector2(producerRule.PlacingAnimationOffsetX, producerRule.PlacingAnimationOffsetY));
                    //}

                    if (location.hasLightSource(LightSourceConfigController.GenerateIdentifier(tileLocation)))
                    {
                        location.removeLightSource(LightSourceConfigController.GenerateIdentifier(tileLocation));
                    }
                    producer.initializeLightSource(tileLocation, false);

                    int statsIncrement = inputQuantity;
                    producerRule.IncrementStatsOnInput.ForEach(s => StatsController.IncrementStardewStats(s, statsIncrement));
                }
            }
            return(outputConfig);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Adapted from https://github.com/Digus/StardewValleyMods/blob/master/ProducerFrameworkMod/ProducerRuleController.cs
        /// </summary>
        /// <param name="producer"></param>
        /// <param name="location"></param>
        /// <param name="who"></param>
        public static void PrepareOutput(SObject producer, GameLocation location, Farmer who)
        {
            if (string.IsNullOrEmpty(producer.GetMassProducerKey()))
            {
                return;
            }

            MassProductionMachineDefinition mpm = ModEntry.GetMPMMachine(producer.name, producer.GetMassProducerKey());

            if (mpm == null)
            {
                return;
            }

            foreach (ProducerRule producerRule in ProducerController.GetProducerRules(mpm.BaseProducerName))
            {
                if (producerRule.LookForInputWhenReady is InputSearchConfig inputSearchConfig)
                {
                    if (producerRule.OutputConfigs.Find(o => o.OutputIndex == producer.heldObject.Value.ParentSheetIndex) is OutputConfig outputConfig)
                    {
                        SObject          input     = SearchInput(location, producer.tileLocation, inputSearchConfig);
                        List <InputInfo> inputInfo = InputInfo.ConvertPFMInputs(producerRule, input);
                        SObject          output    = OutputConfigController.CreateOutput(outputConfig, input, ProducerRuleController.GetRandomForProducing(producer.tileLocation));

                        output.Stack = mpm.Settings.CalculateOutputProduced(output.stack, inputInfo.ToArray());

                        if (mpm.Settings.Quality.HasValue)
                        {
                            if (mpm.Settings.Quality == QualitySetting.KeepInput)
                            {
                                output.Quality = input.Quality;
                            }
                            else
                            {
                                output.Quality = mpm.Settings.GetOutputQuality();
                            }
                        }

                        producer.heldObject.Value = output;
                        OutputConfigController.LoadOutputName(outputConfig, producer.heldObject.Value, input, who);
                        break;
                    }
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Adapted from https://github.com/Digus/StardewValleyMods/blob/master/PFMAutomate/Automate/CustomProducerMachine.cs
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public bool SetInput(IStorage input)
        {
            if (IsMassProducer)
            {
                MassProductionMachineDefinition mpm = ModEntry.GetMPMMachine(Machine.name, Machine.GetMassProducerKey());

                foreach (ITrackedStack trackedStack in input.GetItems())
                {
                    if (trackedStack.Sample is SObject objectInput && !objectInput.bigCraftable.Value &&
                        ProducerController.GetProducerItem(Machine.Name, objectInput) is ProducerRule producerRule &&
                        !PFMCompatability.IsInputExcluded(producerRule, mpm, objectInput))
                    {
                        ProducerConfig producerConfig = mpm.GetBaseProducerConfig();

                        if (producerConfig == null || (producerConfig.CheckLocationCondition(Location) && producerConfig.CheckSeasonCondition()))
                        {
                            List <InputInfo> inputsRequired = InputInfo.ConvertPFMInputs(producerRule, objectInput);

                            if (inputsRequired.Count > 0 &&
                                input.TryGetIngredient(objectInput.ParentSheetIndex, mpm.Settings.CalculateInputRequired(inputsRequired.First()), out IConsumable inputConsumable))
                            {
                                objectInput = inputConsumable.Sample as SObject;
                                List <IConsumable> requiredFuels = GetRequiredFuels(inputsRequired, mpm.Settings, input);

                                if (requiredFuels != null)
                                {
                                    try
                                    {
                                        Dictionary <int, int> fuelQuantities = new Dictionary <int, int>();

                                        foreach (InputInfo inputInfo in inputsRequired)
                                        {
                                            if (inputInfo.IsFuel)
                                            {
                                                fuelQuantities.Add(inputInfo.ID, mpm.Settings.CalculateInputRequired(inputInfo));
                                            }
                                        }

                                        Func <int, int, bool> fuelSearch   = (i, q) => input.TryGetIngredient(i, fuelQuantities[i], out IConsumable fuel);
                                        OutputConfig          outputConfig = PFMCompatability.ProduceOutput(producerRule, mpm.Settings, Machine, fuelSearch, null, Location, producerConfig,
                                                                                                            objectInput, inputQuantity: mpm.Settings.CalculateInputRequired(inputsRequired.First()), noSoundAndAnimation: true,
                                                                                                            inputInfo: inputsRequired);

                                        if (outputConfig != null)
                                        {
                                            inputConsumable.Take();
                                            requiredFuels.ForEach(f => f.Reduce());
                                            List <IConsumable> outputRequiredFuels = GetRequiredFuels(InputInfo.ConvertPFMInputs(outputConfig), mpm.Settings, input);
                                            outputRequiredFuels.ForEach(f => f.Reduce());
                                            return(true);
                                        }
                                    }
                                    catch (RestrictionException) { /* No action needed */ }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (ITrackedStack trackedStack in input.GetItems())
                {
                    if (trackedStack.Sample is SObject objectInput && !objectInput.bigCraftable.Value &&
                        ProducerController.GetProducerItem(Machine.Name, objectInput) is ProducerRule producerRule &&
                        !ProducerRuleController.IsInputExcluded(producerRule, objectInput))
                    {
                        ProducerConfig producerConfig = ProducerController.GetProducerConfig(Machine.name);

                        if (producerConfig == null || (producerConfig.CheckLocationCondition(Location) && producerConfig.CheckSeasonCondition()))
                        {
                            if (input.TryGetIngredient(objectInput.ParentSheetIndex, producerRule.InputStack, out IConsumable inputConsumable))
                            {
                                objectInput = inputConsumable.Sample as SObject;
                                List <IConsumable> requiredFuels = GetRequiredFuels(InputInfo.ConvertPFMInputs(producerRule, objectInput), null, input);

                                if (requiredFuels != null)
                                {
                                    try
                                    {
                                        Func <int, int, bool> fuelSearch   = (i, q) => input.TryGetIngredient(i, q, out IConsumable fuel);
                                        OutputConfig          outputConfig = ProducerRuleController.ProduceOutput(producerRule, Machine, fuelSearch, null, Location, producerConfig,
                                                                                                                  objectInput, noSoundAndAnimation: true);

                                        if (outputConfig != null)
                                        {
                                            inputConsumable.Take();
                                            requiredFuels.ForEach(f => f.Reduce());
                                            List <IConsumable> outputRequiredFuels = GetRequiredFuels(InputInfo.ConvertPFMInputs(outputConfig), null, input);
                                            outputRequiredFuels.ForEach(f => f.Reduce());
                                            return(true);
                                        }
                                    }
                                    catch (RestrictionException) { /* No action needed */ }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        public ITrackedStack GetOutput()
        {
            ProducerRuleController.PrepareOutput(_machine, this.Location, Game1.getFarmer((long)_machine.owner));

            return(new TrackedItem(_machine.heldObject.Value, onEmpty: Reset));
        }