예제 #1
0
        public static void MonsterDrop_Postfix(GameLocation __instance, Monster monster, int x, int y, Farmer who)
        {
            try
            {
                if (who == Game1.player)
                {
                    //  Make the monster drop an augmentor if you're lucky
                    double Chance = MachineAugmentorsMod.UserConfig.MonsterLootSettings.GetAugmentorDropChance(__instance, monster,
                                                                                                               out double BaseChance, out double LocationMultiplier, out double ExpMultiplier, out double HPMultiplier);
                    bool   Success = Augmentor.Randomizer.NextDouble() <= Chance;
                    string LogMessage;
                    if (Success)
                    {
                        int           SpawnDirection = Augmentor.Randomizer.Next(4);
                        int           NumTypes       = Enum.GetValues(typeof(AugmentorType)).Length;
                        AugmentorType Type           = (AugmentorType)Augmentor.Randomizer.Next(NumTypes);
                        int           Quantity       = Augmentor.RollDice(0.1) ? 2 : 1;
                        Game1.createItemDebris(Augmentor.CreateInstance(Type, Quantity), Game1.player.getStandingPosition(), SpawnDirection, null, -1);

                        LogMessage = string.Format("Succeeded drop chance: Location = {0}, monster.ExperienceGained = {1}, monster.MaxHealth = {2}\n"
                                                   + "BaseChance = {3} ({4}%), LocationMultiplier = {5} (+{6}%), ExpMultiplier = {7}, HPMultiplier = {8} (+{9}%), TotalChance = {10} ({11}%)",
                                                   __instance.Name, monster.ExperienceGained, monster.MaxHealth,
                                                   BaseChance, (BaseChance * 100.0).ToString("0.##"), LocationMultiplier, ((LocationMultiplier - 1.0) * 100.0).ToString("0.##"),
                                                   ExpMultiplier.ToString("#.####"), HPMultiplier, ((HPMultiplier - 1.0) * 100.0).ToString("0.##"), Chance, (Chance * 100.0).ToString("0.###"));
                    }
                    else
                    {
                        LogMessage = string.Format("Failed drop chance: Location = {0}, monster.ExperienceGained = {1}, monster.MaxHealth = {2}\n"
                                                   + "BaseChance = {3} ({4}%), LocationMultiplier = {5} (+{6}%), ExpMultiplier = {7}, HPMultiplier = {8} (+{9}%), TotalChance = {10} ({11}%)",
                                                   __instance.Name, monster.ExperienceGained, monster.MaxHealth,
                                                   BaseChance, (BaseChance * 100.0).ToString("0.##"), LocationMultiplier, ((LocationMultiplier - 1.0) * 100.0).ToString("0.##"),
                                                   ExpMultiplier.ToString("#.####"), HPMultiplier, ((HPMultiplier - 1.0) * 100.0).ToString("0.##"), Chance, (Chance * 100.0).ToString("0.###"));
                    }
#if DEBUG
                    MachineAugmentorsMod.ModInstance.Monitor.Log(LogMessage, LogLevel.Debug);
#else
                    MachineAugmentorsMod.ModInstance.Monitor.Log(LogMessage, LogLevel.Trace);
#endif
                }
            }
            catch (Exception ex)
            {
                MachineAugmentorsMod.ModInstance.Monitor.Log(string.Format("Unhandled Error in {0}:\n{1}", nameof(MonsterDrop_Postfix), ex), LogLevel.Error);
            }
        }
        private void RegisterConsoleCommands()
        {
            List <string> ValidTypes = Enum.GetValues(typeof(AugmentorType)).Cast <AugmentorType>().Select(x => x.ToString()).ToList();

            //Possible TODO: Add translation support for this command
            string CommandName = "player_addaugmentor";
            string CommandHelp = string.Format("Adds augmentors of the given AugmentorType into your inventory.\n"
                                               + "Arguments: <AugmentorType> <Quantity>\n"
                                               + "Example: {0} EfficiencyAugmentor 6\n\n"
                                               + "Valid values for <AugmentorType>: {1}",
                                               CommandName, string.Join(", ", ValidTypes), string.Join(", ", ValidTypes));

            Helper.ConsoleCommands.Add(CommandName, CommandHelp, (string Name, string[] Args) =>
            {
                if (Game1.player.isInventoryFull())
                {
                    Monitor.Log("Unable to execute command: Inventory is full!", LogLevel.Alert);
                }
                else if (Args.Length < 2)
                {
                    Monitor.Log("Unable to execute command: Required arguments missing!", LogLevel.Alert);
                }
                else
                {
                    string TypeName = Args[0];
                    if (!Enum.TryParse(TypeName, out AugmentorType AugmentorType))
                    {
                        Monitor.Log(string.Format("Unable to execute command: <AugmentorType> \"{0}\" is not valid. Expected valid values: {1}", TypeName, string.Join(", ", ValidTypes)), LogLevel.Alert);
                    }
                    else
                    {
                        if (!int.TryParse(Args[1], out int Quantity))
                        {
                            Monitor.Log(string.Format("Unable to execute command: could not parse an integer from \"{0}\".", Args[1]), LogLevel.Alert);
                        }
                        else
                        {
                            Augmentor SpawnedItem = Augmentor.CreateInstance(AugmentorType, Quantity);
                            Game1.player.addItemToInventory(SpawnedItem);
                        }
                    }
                }
            });
        }
예제 #3
0
 public static void Draw_Postfix(Object __instance, SpriteBatch spriteBatch, int x, int y, float alpha)
 {
     try
     {
         //  Draw the augmentors that are attached to this machine, if any
         if (PlacedAugmentorsManager.Instance != null)
         {
             if (PlacedAugmentorsManager.Instance.TryFindAugmentedTile(__instance, x, y, out AugmentedTile AT))
             {
                 List <AugmentorType> Types = AT.GetAugmentorQuantities().Where(KVP => KVP.Value > 0).Select(KVP => KVP.Key).ToList();
                 Augmentor.DrawIconsOnTile(spriteBatch, Types, x, y, 0.6f);
             }
         }
     }
     catch (Exception ex)
     {
         MachineAugmentorsMod.ModInstance.Monitor.Log(string.Format("Unhandled Error in {0}:\n{1}", nameof(Draw_Postfix), ex), LogLevel.Error);
     }
 }
예제 #4
0
        private void Display_RenderedWorld(object sender, StardewModdingAPI.Events.RenderedWorldEventArgs e)
        {
            if (Game1.activeClickableMenu == null && PlacedAugmentorsManager.Instance != null)
            {
                GameLocation CurrentLocation = Game1.player.currentLocation;

                bool IsHoveringPlacedObject = CurrentLocation.Objects.TryGetValue(HoveredTile, out Object HoveredObject);
                if (IsHoveringPlacedObject)
                {
                    Dictionary <AugmentorType, int> AttachedAugmentors = PlacedAugmentorsManager.Instance.GetAugmentorQuantities(CurrentLocation.NameOrUniqueName, HoveredTile);
                    bool HasAttachedAugmentors = AttachedAugmentors.Any(x => x.Value > 0);
                    if (MachineInfo.TryGetMachineInfo(HoveredObject, out MachineInfo MI))
                    {
                        SpriteFont DefaultFont = Game1.dialogueFont;

                        //  Draw a tooltip showing what effects the held item will have when attached to this machine
                        if (Game1.player.CurrentItem is Augmentor HeldAugmentor && HeldAugmentor.IsAugmentable(HoveredObject))
                        {
                            AttachedAugmentors.TryGetValue(HeldAugmentor.AugmentorType, out int CurrentAttachedQuantity);

                            double CurrentEffect = CurrentAttachedQuantity <= 0 ?
                                                   Augmentor.GetDefaultEffect(HeldAugmentor.AugmentorType) : Augmentor.ComputeEffect(HeldAugmentor.AugmentorType, CurrentAttachedQuantity, MI.RequiresInput);
                            double NewEffectSingle = Augmentor.ComputeEffect(HeldAugmentor.AugmentorType, CurrentAttachedQuantity + 1, MI.RequiresInput);
                            double NewEffectAll    = Augmentor.ComputeEffect(HeldAugmentor.AugmentorType, CurrentAttachedQuantity + HeldAugmentor.Stack, MI.RequiresInput);

                            //  Example of desired tooltip:
                            //        -------------------------------------------
                            //        |          [Icon] Time to process:        |
                            //        |-----------------------------------------|
                            //        |  Current Effect: 95.5%                  |
                            //        |      New Effect: 92.2% (1) / 81.1% (4)  |
                            //        -------------------------------------------

                            int   Padding         = 28;
                            int   MarginAfterIcon = 10;
                            float LabelTextScale  = 0.75f;
                            float ValueTextScale  = 1.0f;

                            //  Compute sizes of each row so we know how big the tooltip is, and can horizontally center the header and other rows

                            //  Compute size of header
                            int HeaderHorizontalPadding = 4;
                            Augmentor.TryGetIconDetails(HeldAugmentor.AugmentorType, out Texture2D IconTexture, out Rectangle IconSourcePosition, out float IconScale, out SpriteEffects IconEffects);
                            Vector2 IconSize        = new Vector2(IconSourcePosition.Width * IconScale, IconSourcePosition.Height * IconScale);
                            string  HeaderText      = string.Format("{0}:", HeldAugmentor.GetEffectDescription());
                            Vector2 HeaderTextSize  = DefaultFont.MeasureString(HeaderText) * LabelTextScale;
                            float   HeaderRowWidth  = IconSize.X + MarginAfterIcon + HeaderTextSize.X + HeaderHorizontalPadding * 2;
                            float   HeaderRowHeight = Math.Max(IconSize.Y, HeaderTextSize.Y);

                            //  Compute size of horizontal separator
                            int HorizontalSeparatorHeight = 6;
                            int HorizontalSeparatorMargin = 8;

                            //  Compute size of the labels before the effect values
                            int     MarginAfterLabel       = 8;
                            string  CurrentEffectLabel     = string.Format("{0}:", Translate("CurrentEffectLabel"));
                            Vector2 CurrentEffectLabelSize = DefaultFont.MeasureString(CurrentEffectLabel) * LabelTextScale;
                            string  NewEffectLabel         = string.Format("{0}:", Translate("NewEffectLabel"));
                            Vector2 NewEffectLabelSize     = DefaultFont.MeasureString(NewEffectLabel) * LabelTextScale;
                            float   EffectLabelWidth       = Math.Max(CurrentEffectLabelSize.X, NewEffectLabelSize.X);
                            Vector2 EffectLabelSize        = new Vector2(EffectLabelWidth, CurrentEffectLabelSize.Y + NewEffectLabelSize.Y);

                            //  Compute size of the effect values
                            string  CurrentEffectValue     = string.Format("{0}% ({1})", (CurrentEffect * 100.0).ToString("0.##"), CurrentAttachedQuantity);
                            Vector2 CurrentEffectValueSize = DrawHelpers.MeasureStringWithSpecialNumbers(CurrentEffectValue, ValueTextScale, 0.0f);
                            string  NewEffectValue;
                            if (HeldAugmentor.Stack > 1)
                            {
                                NewEffectValue = string.Format("{0}% ({1}) / {2}% ({3})",
                                                               (NewEffectSingle * 100.0).ToString("0.##"), (CurrentAttachedQuantity + 1), (NewEffectAll * 100.0).ToString("0.##"), (CurrentAttachedQuantity + HeldAugmentor.Stack));
                            }
                            else
                            {
                                NewEffectValue = string.Format("{0}% ({1})", (NewEffectSingle * 100.0).ToString("0.##"), (CurrentAttachedQuantity + 1));
                            }
                            Vector2 NewEffectValueSize = DrawHelpers.MeasureStringWithSpecialNumbers(NewEffectValue, ValueTextScale, 0.0f);

                            Vector2 EffectContentSize = new Vector2(EffectLabelWidth + MarginAfterLabel + Math.Max(CurrentEffectValueSize.X, NewEffectValueSize.X),
                                                                    Math.Max(CurrentEffectLabelSize.Y, CurrentEffectValueSize.Y) + Math.Max(NewEffectLabelSize.Y, NewEffectValueSize.Y));

                            //  Compute total size of tooltip, draw the background
                            Vector2 ToolTipSize    = new Vector2(Padding * 2 + Math.Max(HeaderRowWidth, EffectContentSize.X), Padding + HeaderRowHeight + HorizontalSeparatorMargin + HorizontalSeparatorHeight + HorizontalSeparatorMargin + EffectContentSize.Y + Padding);
                            Point   ToolTipTopleft = DrawHelpers.GetTopleftPosition(new Point((int)ToolTipSize.X, (int)ToolTipSize.Y), MouseScreenPosition, 100);
                            DrawHelpers.DrawBox(e.SpriteBatch, new Rectangle(ToolTipTopleft.X, ToolTipTopleft.Y, (int)ToolTipSize.X, (int)ToolTipSize.Y));
                            float CurrentY = ToolTipTopleft.Y + Padding;

                            //  Draw the header
                            float   HeaderStartX = ToolTipTopleft.X + (ToolTipSize.X - HeaderRowWidth) / 2.0f;
                            Vector2 IconPosition = new Vector2(HeaderStartX, CurrentY + (HeaderRowHeight - IconSize.Y) / 2.0f);
                            e.SpriteBatch.Draw(IconTexture, IconPosition, IconSourcePosition, Color.White, 0f, Vector2.Zero, IconScale, IconEffects, 1f);
                            Vector2 HeaderTextPosition = new Vector2(HeaderStartX + IconSize.X + MarginAfterIcon, CurrentY + (HeaderRowHeight - HeaderTextSize.Y) / 2.0f);
                            e.SpriteBatch.DrawString(DefaultFont, HeaderText, HeaderTextPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f);
                            CurrentY += HeaderRowHeight + HorizontalSeparatorMargin;

                            //  Draw the horizontal separator
                            DrawHelpers.DrawHorizontalSeparator(e.SpriteBatch, ToolTipTopleft.X + Padding, (int)CurrentY, (int)(ToolTipSize.X - 2 * Padding), HorizontalSeparatorHeight);
                            CurrentY += HorizontalSeparatorHeight + HorizontalSeparatorMargin;

                            //  Draw the current effect
                            Vector2 CurrentEffectLabelPosition = new Vector2(ToolTipTopleft.X + Padding + (EffectLabelWidth - CurrentEffectLabelSize.X), CurrentY);
                            Vector2 CurrentEffectValuePosition = new Vector2(ToolTipTopleft.X + Padding + EffectLabelWidth + MarginAfterLabel, CurrentY);
                            e.SpriteBatch.DrawString(DefaultFont, CurrentEffectLabel, CurrentEffectLabelPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f);
                            DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, CurrentEffectValuePosition, CurrentEffectValue, ValueTextScale, Color.White);
                            CurrentY += Math.Max(CurrentEffectLabelSize.Y, CurrentEffectValueSize.Y);

                            //  Draw the new effect
                            Vector2 NewEffectLabelPosition = new Vector2(ToolTipTopleft.X + Padding + (EffectLabelWidth - NewEffectLabelSize.X), CurrentY);
                            Vector2 NewEffectValuePosition = new Vector2(ToolTipTopleft.X + Padding + EffectLabelWidth + MarginAfterLabel, CurrentY);
                            e.SpriteBatch.DrawString(DefaultFont, NewEffectLabel, NewEffectLabelPosition, Color.Black, 0.0f, Vector2.Zero, LabelTextScale, SpriteEffects.None, 1.0f);
                            DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, NewEffectValuePosition, NewEffectValue, ValueTextScale, Color.White);
                        }
                        //  Draw a tooltip showing what effects are currently applied to this machine
                        else if (HasAttachedAugmentors)
                        {
                            int Padding         = 28;
                            int MarginAfterIcon = 10;

                            //  Compute the size of each icon
                            Dictionary <AugmentorType, Vector2> IconSizes = new Dictionary <AugmentorType, Vector2>();
                            foreach (KeyValuePair <AugmentorType, int> KVP in AttachedAugmentors.Where(x => x.Value > 0))
                            {
                                Augmentor.TryGetIconDetails(KVP.Key, out Texture2D IconTexture, out Rectangle IconSourcePosition, out float IconScale, out SpriteEffects IconEffects);
                                Vector2 IconSize = new Vector2(IconSourcePosition.Width * IconScale, IconSourcePosition.Height * IconScale);
                                IconSizes.Add(KVP.Key, IconSize);
                            }
                            float IconColumnWidth = IconSizes.Values.Max(x => x.Y);

                            //  Compute the size of each row (each row shows the effect of a type of augmentor that has been applied to this machine)
                            Dictionary <AugmentorType, Vector2> RowSizes = new Dictionary <AugmentorType, Vector2>();
                            foreach (KeyValuePair <AugmentorType, int> KVP in AttachedAugmentors.Where(x => x.Value > 0))
                            {
                                double  CurrentEffect = Augmentor.ComputeEffect(KVP.Key, KVP.Value, MI.RequiresInput);
                                string  Text          = string.Format("{0}% ({1})", (CurrentEffect * 100.0).ToString("0.#"), KVP.Value);
                                Vector2 TextSize      = DrawHelpers.MeasureStringWithSpecialNumbers(Text, 1.0f, 4.0f);

                                float RowWidth  = IconColumnWidth + MarginAfterIcon + TextSize.X;
                                float RowHeight = Math.Max(IconSizes[KVP.Key].Y, TextSize.Y);
                                RowSizes.Add(KVP.Key, new Vector2(RowWidth, RowHeight));
                            }

                            //  Compute total size of tooltip, draw the background
                            Vector2 ToolTipSize    = new Vector2(Padding * 2 + RowSizes.Values.Max(x => x.X), Padding * 2 + RowSizes.Values.Sum(x => x.Y));
                            Point   ToolTipTopleft = DrawHelpers.GetTopleftPosition(new Point((int)ToolTipSize.X, (int)ToolTipSize.Y), MouseScreenPosition, 100);
                            DrawHelpers.DrawBox(e.SpriteBatch, new Rectangle(ToolTipTopleft.X, ToolTipTopleft.Y, (int)ToolTipSize.X, (int)ToolTipSize.Y));
                            float CurrentY = ToolTipTopleft.Y + Padding;

                            //  Draw each row
                            float RowStartX = ToolTipTopleft.X + Padding;
                            foreach (KeyValuePair <AugmentorType, int> KVP in AttachedAugmentors.Where(x => x.Value > 0))
                            {
                                float CurrentX  = RowStartX;
                                float RowHeight = RowSizes[KVP.Key].Y;

                                //  Draw the icon
                                Augmentor.TryGetIconDetails(KVP.Key, out Texture2D IconTexture, out Rectangle IconSourcePosition, out float IconScale, out SpriteEffects IconEffects);
                                Vector2 IconSize     = IconSizes[KVP.Key];
                                Vector2 IconPosition = new Vector2(CurrentX + (IconColumnWidth - IconSize.X) / 2.0f, CurrentY + (RowHeight - IconSize.Y) / 2.0f);
                                e.SpriteBatch.Draw(IconTexture, IconPosition, IconSourcePosition, Color.White, 0f, Vector2.Zero, IconScale, IconEffects, 1f);
                                CurrentX += IconColumnWidth + MarginAfterIcon;

                                //  Draw the value
                                double  CurrentEffect = Augmentor.ComputeEffect(KVP.Key, KVP.Value, MI.RequiresInput);
                                string  Text          = string.Format("{0}% ({1})", (CurrentEffect * 100.0).ToString("0.#"), KVP.Value);
                                Vector2 TextSize      = DrawHelpers.MeasureStringWithSpecialNumbers(Text, 1.0f, 0.0f);
                                Vector2 TextPosition  = new Vector2(CurrentX, CurrentY + (RowHeight - TextSize.Y) / 2.0f);
                                DrawHelpers.DrawStringWithSpecialNumbers(e.SpriteBatch, TextPosition, Text, 1.0f, Color.White);

                                CurrentY += RowHeight;
                            }

                            //Maybe also show MinutesUntilReady if it's not ReadyForHarvest?
                        }
                    }
                }
            }
예제 #5
0
        private void RegisterConsoleCommands()
        {
            List <string> ValidTypes = Enum.GetValues(typeof(AugmentorType)).Cast <AugmentorType>().Select(x => x.ToString()).ToList();

            //Possible TODO: Add translation support for this command
            string CommandName = "player_addaugmentor";
            string CommandHelp = string.Format("Adds augmentors of the given AugmentorType into your inventory.\n"
                                               + "Arguments: <AugmentorType> <Quantity>\n"
                                               + "Example: {0} EfficiencyAugmentor 6\n\n"
                                               + "Valid values for <AugmentorType>: {1}",
                                               CommandName, string.Join(", ", ValidTypes), string.Join(", ", ValidTypes));

            Helper.ConsoleCommands.Add(CommandName, CommandHelp, (string Name, string[] Args) =>
            {
                if (Game1.player.isInventoryFull())
                {
                    Monitor.Log("Unable to execute command: Inventory is full!", LogLevel.Alert);
                }
                else if (Args.Length < 2)
                {
                    Monitor.Log("Unable to execute command: Required arguments missing!", LogLevel.Alert);
                }
                else
                {
                    string TypeName = Args[0];
                    if (!Enum.TryParse(TypeName, out AugmentorType AugmentorType))
                    {
                        Monitor.Log(string.Format("Unable to execute command: <AugmentorType> \"{0}\" is not valid. Expected valid values: {1}", TypeName, string.Join(", ", ValidTypes)), LogLevel.Alert);
                    }
                    else
                    {
                        if (!int.TryParse(Args[1], out int Quantity))
                        {
                            Monitor.Log(string.Format("Unable to execute command: could not parse an integer from \"{0}\".", Args[1]), LogLevel.Alert);
                        }
                        else
                        {
                            Augmentor SpawnedItem = Augmentor.CreateInstance(AugmentorType, Quantity);
                            Game1.player.addItemToInventory(SpawnedItem);
                        }
                    }
                }
            });

            //Possible TODO: Add translation support for this command
            CommandName = "machine_augmentors_reload_config";
            CommandHelp = "Reloads configuration settings from this mod's config.json file. Normally this file's settings are only loaded once when the game is started."
                          + " Use this command if you've made changes to the config during this game session.";
            Helper.ConsoleCommands.Add(CommandName, CommandHelp, (string Name, string[] Args) =>
            {
                try
                {
                    LoadUserConfig();
                    Monitor.Log("config.json settings were successfully reloaded.", LogLevel.Alert);
                }
                catch (Exception ex)
                {
                    Monitor.Log(string.Format("Machine Augmentors: Unhandled error while executing command: {0}", ex.Message), LogLevel.Error);
                }
            });
        }
예제 #6
0
        private void Display_MenuChanged(object sender, StardewModdingAPI.Events.MenuChangedEventArgs e)
        {
            //  Add Augmentors items to the shop's stock
            if (e.NewMenu is ShopMenu NewShop && IsTravellingMerchantShop(NewShop))
            {
                if (TodaysStock == null)
                {
                    TodaysStock = new Dictionary <ISalable, int[]>();

                    //  Pick the Augmentor types that will be sold today
                    int NumTypes = Augmentor.WeightedRound(UserConfig.ShopSettings.NumAugmentorTypesInShop);
                    List <AugmentorConfig> ChosenTypes    = new List <AugmentorConfig>();
                    List <AugmentorConfig> RemainingTypes = new List <AugmentorConfig>(UserConfig.AugmentorConfigs);
                    while (ChosenTypes.Count < NumTypes && RemainingTypes.Any())
                    {
                        int TotalWeight  = RemainingTypes.Sum(x => x.ShopAppearanceWeight);
                        int ChosenWeight = Augmentor.Randomizer.Next(TotalWeight);

                        //  EX: If the remaining types had weights = { 3, 6, 2 }, picks random number from 0 to 10 inclusive.
                        //  Then the first is selected if ChosenWeight is 0-2 (3/11 chance), second is selected if 3-8 (6/11 chance), third is selected if 9-10 (2/11 chance)
                        int CurrentSum = 0;
                        for (int i = 0; i < RemainingTypes.Count; i++)
                        {
                            AugmentorConfig CurrentConfig = RemainingTypes[i];
                            CurrentSum += CurrentConfig.ShopAppearanceWeight;
                            if (ChosenWeight < CurrentSum)
                            {
                                ChosenTypes.Add(CurrentConfig);
                                RemainingTypes.RemoveAt(i);
                                break;
                            }
                        }
                    }

                    //  Add each type to today's stock
                    foreach (AugmentorConfig Config in ChosenTypes)
                    {
                        //  Compute price
                        double BasePrice = Config.BasePrice * UserConfig.GlobalPriceMultiplier;
                        double Price     = BasePrice;
                        if (UserConfig.ShopSettings.PriceDeviationRolls > 0)
                        {
                            double MinMultiplier = 1.0 - UserConfig.ShopSettings.PriceDeviation;
                            double MaxMultiplier = 1.0 + UserConfig.ShopSettings.PriceDeviation;
                            double Multiplier    = Enumerable.Range(0, UserConfig.ShopSettings.PriceDeviationRolls).Select(x => Augmentor.GetRandomNumber(MinMultiplier, MaxMultiplier)).Average();
                            Price = Math.Round(BasePrice * Multiplier, MidpointRounding.AwayFromZero);
                        }

                        //  Compute quantity
                        double BaseQuantityInStock = UserConfig.ShopSettings.BaseQuantityInStock;
                        double YearMultiplier      = 1.0 + (UserConfig.ShopSettings.YearShopStockMultiplierBonus * (Game1.Date.Year - 1));
                        double DesiredValue        = BaseQuantityInStock * Config.ShopStockMultiplier * YearMultiplier;
                        int    QuantityInStock     = Math.Max(1, Augmentor.WeightedRound(DesiredValue));

                        Augmentor SellableInstance = Augmentor.CreateInstance(Config.AugmentorType, 1);
                        TodaysStock.Add(SellableInstance, new int[] { (int)Price, QuantityInStock });
                    }
                }

                //  Add today's stock to the shop
                if (TodaysStock.Any())
                {
                    Dictionary <ISalable, int[]> Stock = NewShop.itemPriceAndStock;
                    foreach (KeyValuePair <ISalable, int[]> Item in TodaysStock)
                    {
                        if (Item.Value[1] > 0 && !Stock.ContainsKey(Item.Key))
                        {
                            Stock.Add(Item.Key, Item.Value);
                        }
                    }

                    NewShop.setItemPriceAndStock(Stock);
                }
            }
        }