コード例 #1
0
        /// <summary>
        /// Draws the icon of a machine upgrade on the machine if it has one.
        /// Adapted from https://github.com/Videogamers0/SDV-MachineAugmentors/blob/master/MachineAugmentors/Items/Augmentor.cs
        /// </summary>
        /// <param name="__instance"></param>
        /// <param name="spriteBatch"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="alpha"></param>
        public static void Draw_Postfix(SObject __instance, SpriteBatch spriteBatch, int x, int y, float alpha)
        {
            try
            {
                if (!string.IsNullOrEmpty(__instance.GetMassProducerKey()) && ModEntry.MPMSettings[__instance.GetMassProducerKey()] != null)
                {
                    int upgradeId = ModEntry.MPMSettings[__instance.GetMassProducerKey()].UpgradeObjectID;

                    float scale           = 0.6f;
                    float drawLayer       = Math.Max(0f, ((y + 1) * 64 - 24) / 10000f) + x * 1E-05f;
                    float drawLayerOffset = 1E-05f; // The SpriteBatch layer depth needs to be slightly larger to avoid z-fighting

                    Vector2 position = Game1.GlobalToLocal(Game1.viewport, new Vector2(x * Game1.tileSize, y * Game1.tileSize));
                    spriteBatch.Draw(Game1.mouseCursors, position, GetPrimaryIconSourceRect(2), Color.White, 0f, Vector2.Zero, 4f * scale, SpriteEffects.None, drawLayer + drawLayerOffset);

                    Vector2 bottomLeftPosition = new Vector2(position.X, position.Y + 64f * scale);

                    Texture2D        spritesheet       = Game1.objectSpriteSheet;
                    Tuple <int, int> spriteCoordinates = ImageHelper.GetObjectSpritesheetIndex(spritesheet.Width, spritesheet.Height, upgradeId);
                    float            iconScale         = 2f;
                    Rectangle        sourceRectangle   = new Rectangle(spriteCoordinates.Item1, spriteCoordinates.Item2, 16, 16);
                    Vector2          spriteDestination = bottomLeftPosition + new Vector2(4f * scale, -4f * scale - sourceRectangle.Height * iconScale * scale);
                    float            spriteLayerDepth  = drawLayer + drawLayerOffset + 1E-04f;

                    spriteBatch.Draw(spritesheet, spriteDestination, sourceRectangle, Color.White * 1f, 0f, new Vector2(0, 0), scale * iconScale, SpriteEffects.None, spriteLayerDepth);
                }
            }
            catch
            { //Ignore errors that come up when first loading a save and can't access __instance.GetMassProducerKey()
            }
        }
コード例 #2
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*/ }
                    }
                }
            }
        }
コード例 #3
0
        [HarmonyPriority(801)] //Just before ProducerFrameworkMod. Can't use HarmonyBefore attribute, that wasn't working for some reason
        internal static bool performDropDownAction_Prefix(SObject __instance, Farmer who, bool __result)
        {
            if (string.IsNullOrEmpty(__instance.GetMassProducerKey()))
            {
                return(true);
            }

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

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

            if (ProducerController.GetProducerConfig(__instance.Name) is ProducerConfig producerConfig)
            {
                try
                {
                    if (!producerConfig.CheckLocationCondition(who.currentLocation))
                    {
                        throw new RestrictionException(ModEntry.Instance.Helper.Translation.Get("Message.Condition.Location"));
                    }
                    if (producerConfig.NoInputStartMode != null)
                    {
                        if (producerConfig.CheckSeasonCondition() && NoInputStartMode.Placement == producerConfig.NoInputStartMode)
                        {
                            if (ProducerController.GetProducerItem(__instance.Name, null) is ProducerRule producerRule)
                            {
                                PFMCompatability.ProduceOutput(producerRule, mpm.Settings, __instance, (i, q) => who.hasItemInInventory(i, q),
                                                               who, who.currentLocation, producerConfig);
                            }
                        }
                        return(__result = false);
                    }
                }
                catch (RestrictionException e)
                {
                    if (e.Message != null && who.IsLocalPlayer)
                    {
                        Game1.showRedMessage(e.Message);
                    }
                    return(__result = false);
                }
            }
            else if (StaticValues.SUPPORTED_VANILLA_MACHINES.ContainsKey(__instance.name) &&
                     StaticValues.SUPPORTED_VANILLA_MACHINES[__instance.name] == InputRequirement.NoInputsOnly)
            {
                IVanillaOverride vanillaOverride = VanillaOverrideList.GetFor(__instance.name);

                if (vanillaOverride != null && vanillaOverride.Manual_PerformDropDownAction(__instance, mpm))
                {
                    return(true);
                }
            }

            return(true);
        }
コード例 #4
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);
        }
コード例 #5
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;
                    }
                }
            }
        }
コード例 #6
0
        [HarmonyPriority(801)] //Just before ProducerFrameworkMod. Can't use HarmonyBefore attribute, that wasn't working for some reason
        internal static bool PerformObjectDropInAction(SObject __instance, Item dropInItem, bool probe, Farmer who, ref bool __result)
        {
            if (__instance.isTemporarilyInvisible || !(dropInItem is SObject))
            {
                return(false);
            }

            SObject input = dropInItem as SObject;
            bool    failLocationCondition = false;
            bool    failSeasonCondition   = false;

            MPMSettings upgradeSettings = ModEntry.GetSettingsFromItem(input.name);

            if (upgradeSettings != null)
            {
                if (!probe)
                {
                    //Change the machine's mass producer settings
                    MassProductionMachineDefinition mpm = ModEntry.GetMPMMachine(__instance.name, upgradeSettings.Key);

                    if (mpm == null)
                    {
                        Game1.showRedMessage("This cannot take that upgrade.");
                    }
                    else
                    {
                        string oldProducerKey = __instance.GetMassProducerKey();

                        if (!string.IsNullOrEmpty(oldProducerKey))
                        {
                            string         upgradeItemName = ModEntry.MPMSettings[oldProducerKey].UpgradeObject;
                            JsonAssets.Api jsonAssets      = ModEntry.Instance.Helper.ModRegistry.GetApi("spacechase0.JsonAssets") as JsonAssets.Api;
                            int            upgradeItemId   = jsonAssets.GetObjectId(upgradeItemName);

                            Game1.createItemDebris(new SObject(upgradeItemId, 1), __instance.TileLocation * Game1.tileSize, 0, who.currentLocation);
                        }

                        __instance.SetMassProducerKey(upgradeSettings.Key);
                        input.Stack -= 1;
                        __result     = input.Stack <= 0;

                        return(false);
                    }
                }
            }
            else
            {
                //Check if this is a valid input for the machine's use
                if (string.IsNullOrEmpty(__instance.GetMassProducerKey()))
                {
                    return(true);
                }

                if (__instance.heldObject.Value != null && !__instance.name.Equals("Crystalarium") || input.bigCraftable.Value)
                {
                    return(true);
                }

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

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

                if (StaticValues.SUPPORTED_VANILLA_MACHINES.ContainsKey(__instance.name))
                {
                    IVanillaOverride vanillaOverride = VanillaOverrideList.GetFor(__instance.name);

                    if (vanillaOverride != null)
                    {
                        bool overrideResult = vanillaOverride.Manual_PerformObjectDropInAction(__instance, input, probe, who, mpm);

                        //End early if a result has been found
                        if (overrideResult)
                        {
                            __result = input.Stack <= 0;
                            return(true);
                        }
                    }
                }

                ProducerConfig baseConfig = mpm.GetBaseProducerConfig();
                GameLocation   location   = who.currentLocation;

                if (baseConfig != null)
                {
                    //TOREVIEW: maybe have machines that can break these conditions?
                    if (!baseConfig.CheckLocationCondition(location))
                    {
                        failLocationCondition = true;
                    }
                    if (!baseConfig.CheckSeasonCondition())
                    {
                        failSeasonCondition = true;
                    }
                    if (baseConfig.NoInputStartMode != null)
                    {
                        return(true);
                    }
                }

                if (ProducerController.GetProducerItem(__instance.name, input) is ProducerRule producerRule)
                {
                    if (PFMCompatability.IsInputExcluded(producerRule, mpm, input))
                    {
                        return(true);
                    }

                    if (__instance.bigCraftable.Value && !probe && __instance.heldObject.Value == null)
                    {
                        __instance.scale.X = 5f;
                    }

                    try
                    {
                        if (failLocationCondition)
                        {
                            throw new RestrictionException("Machine can't be used in this location.");
                        }
                        if (failSeasonCondition)
                        {
                            throw new RestrictionException("Machine can't be used in this season.");
                        }

                        List <InputInfo> inputAndFuelInfo = InputInfo.ConvertPFMInputs(producerRule, input);
                        PFMCompatability.ValidateIfInputsLessThanRequired(producerRule, mpm.Settings, inputAndFuelInfo, who);

                        Dictionary <int, int> fuelQuantities = new Dictionary <int, int>();

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

                        Func <int, int, bool> fuelSearch   = (i, q) => who.hasItemInInventory(i, fuelQuantities[i]);
                        OutputConfig          outputConfig = PFMCompatability.ProduceOutput(producerRule, mpm.Settings, __instance,
                                                                                            fuelSearch, who, location, baseConfig, input, mpm.Settings.CalculateInputRequired(inputAndFuelInfo.First()), probe,
                                                                                            inputInfo: inputAndFuelInfo);

                        if (outputConfig != null)
                        {
                            if (!probe)
                            {
                                foreach (InputInfo inputInfo in inputAndFuelInfo)
                                {
                                    if (inputInfo.IsFuel)
                                    {
                                        RemoveItemsFromInventory(who, inputInfo.ID, mpm.Settings.CalculateInputRequired(inputInfo));
                                    }
                                }

                                List <InputInfo> outputConfigFuels = InputInfo.ConvertPFMInputs(outputConfig);

                                foreach (InputInfo fuel in outputConfigFuels)
                                {
                                    RemoveItemsFromInventory(who, fuel.ID, mpm.Settings.CalculateInputRequired(fuel));
                                }

                                input.Stack -= mpm.Settings.CalculateInputRequired(inputAndFuelInfo.First());
                                __result     = input.Stack <= 0;
                            }
                            else
                            {
                                __result = true;
                            }
                        }
                    }
                    catch (RestrictionException e)
                    {
                        __result = false;
                        if (e.Message != null && !probe && who.IsLocalPlayer)
                        {
                            Game1.showRedMessage(e.Message);
                        }
                    }
                    return(false);
                }
            }

            return(!failLocationCondition && !failSeasonCondition);
        }
コード例 #7
0
        public ITrackedStack GetOutput()
        {
            ITrackedStack overrideOutput = OverridingMachine.GetOutput();

            if (overrideOutput != null)
            {
                return(overrideOutput);
            }
            else
            {
                MassProductionMachineDefinition mpm = ModEntry.GetMPMMachine(OriginalMachineObject.name, OriginalMachineObject.GetMassProducerKey());

                if (mpm != null)
                {
                    // Check for special overriding logic, if any is required
                    string originalClassName = OriginalMachine.GetType().FullName;

                    if (VanillaOverrideList.GetFor(originalClassName) != null)
                    {
                        IVanillaOverride vanillaOverride = VanillaOverrideList.GetFor(originalClassName);
                        overrideOutput = vanillaOverride.Automate_GetOutput(mpm, OriginalMachine, OriginalMachineObject);

                        return(overrideOutput);
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    return(OriginalMachine.GetOutput());
                }
            }
        }