Example #1
0
        public void Draw(SpriteBatch b)
        {
            //b.Draw(TextureHelpers.GetSolidColorTexture(Game1.graphics.GraphicsDevice, Color.Red), ContentsBounds, Color.White);

            if (HorizontalSeparatorPosition.HasValue)
            {
                DrawHelpers.DrawHorizontalSeparator(b, HorizontalSeparatorPosition.Value);
            }
            GroupedOptions.Draw(b);
            UngroupedOptions.Draw(b);
        }
Example #2
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?
                        }
                    }
                }
            }
Example #3
0
        public void DrawToolTips(SpriteBatch b)
        {
            if (IsEmptyMenu)
            {
                return;
            }

            //  Draw tooltip over hovered item
            if (HoveredSlot.HasValue)
            {
                //  Get the hovered Item Id and ColumnType
                int?       ItemId = null;
                ColumnType?Column = null;
                foreach (var KVP in SlotBounds)
                {
                    foreach (var KVP2 in KVP.Value)
                    {
                        if (KVP2.Value == HoveredSlot.Value)
                        {
                            ItemId = KVP.Key;
                            Column = KVP2.Key;
                            break;
                        }
                    }

                    if (ItemId.HasValue && Column.HasValue)
                    {
                        break;
                    }
                }

                if (ItemId.HasValue && Column.HasValue)
                {
                    if (Column == ColumnType.RowValue)
                    {
                        List <Object> Items            = Placeholders[ItemId.Value].Values.ToList();
                        List <int>    Quantities       = Items.Select(x => x.Stack).ToList();
                        List <int>    SingleValues     = Items.Select(x => ItemBag.GetSingleItemPrice(x)).ToList();
                        List <int>    MultipliedValues = Items.Select(x => x.Stack * ItemBag.GetSingleItemPrice(x)).ToList();

                        //  Compute how many digits each column needs so that we can align each number properly by making each number take up the maximum size of other numbers in the same column
                        int   SingleValueColumnDigits     = SingleValues.Max(x => DrawHelpers.GetNumDigits(x));
                        int   QuantityColumnDigits        = Quantities.Max(x => DrawHelpers.GetNumDigits(x));
                        int   MultipliedValueColumnDigits = MultipliedValues.Max(x => DrawHelpers.GetNumDigits(x));
                        float DigitScale                 = 3.0f;
                        float SingleValueColumnWidth     = SingleValueColumnDigits * DigitScale * DrawHelpers.TinyDigitBaseWidth;
                        float QuantityColumnWidth        = QuantityColumnDigits * DigitScale * DrawHelpers.TinyDigitBaseWidth;
                        float MultipliedValueColumnWidth = MultipliedValueColumnDigits * DigitScale * DrawHelpers.TinyDigitBaseWidth;

                        //  Compute how big the tooltip needs to be
                        int   Margin     = 32;
                        int   LineHeight = 28;
                        int   HorizontalSeparatorHeight = 6;
                        int   SeparatorMargin           = 4;
                        float PlusCharacterWidth        = Game1.tinyFont.MeasureString("+").X;
                        float MultiplyCharacterWidth    = Game1.tinyFont.MeasureString("*").X;
                        float EqualsCharacterWidth      = Game1.tinyFont.MeasureString("=").X;
                        float SpaceWidth  = 7f;
                        int   TotalWidth  = (int)(Margin + PlusCharacterWidth + SpaceWidth + SingleValueColumnWidth + SpaceWidth + MultiplyCharacterWidth + SpaceWidth + QuantityColumnWidth + SpaceWidth + EqualsCharacterWidth + SpaceWidth + MultipliedValueColumnWidth + Margin);
                        int   TotalHeight = (int)(Margin + Items.Count * LineHeight + SeparatorMargin + HorizontalSeparatorHeight + SeparatorMargin + LineHeight + Margin);

                        //  Ensure tooltip is fully visible on screen
                        Rectangle ToolTipLocation = new Rectangle(HoveredSlot.Value.Right, HoveredSlot.Value.Top, TotalWidth, TotalHeight);
                        if (ToolTipLocation.Right > Game1.viewport.Size.Width)
                        {
                            ToolTipLocation = new Rectangle(HoveredSlot.Value.Left - TotalWidth, HoveredSlot.Value.Top, TotalWidth, TotalHeight);
                        }

                        //  Draw background
                        DrawHelpers.DrawBox(b, ToolTipLocation);

                        //  Draw each row of values
                        int ShadowOffset     = 2;
                        int CurrentYPosition = ToolTipLocation.Y + Margin;
                        for (int i = 0; i < Items.Count; i++)
                        {
                            float CurrentXPosition = ToolTipLocation.X + Margin;
                            if (i != 0)
                            {
                                DrawHelpers.DrawStringWithShadow(b, Game1.tinyFont, "+", CurrentXPosition, CurrentYPosition, Color.White, Color.Black, ShadowOffset, ShadowOffset);
                            }
                            CurrentXPosition += PlusCharacterWidth + SpaceWidth;
                            Utility.drawTinyDigits(SingleValues[i], b, new Vector2(CurrentXPosition + SingleValueColumnWidth - DrawHelpers.MeasureNumber(SingleValues[i], DigitScale), CurrentYPosition), DigitScale, 1.0f, Color.White);
                            CurrentXPosition += SingleValueColumnWidth + SpaceWidth;
                            DrawHelpers.DrawStringWithShadow(b, Game1.tinyFont, "*", CurrentXPosition, CurrentYPosition + LineHeight / 4, Color.White, Color.Black, ShadowOffset, ShadowOffset);
                            CurrentXPosition += MultiplyCharacterWidth + SpaceWidth;
                            Utility.drawTinyDigits(Quantities[i], b, new Vector2(CurrentXPosition + QuantityColumnWidth - DrawHelpers.MeasureNumber(Quantities[i], DigitScale), CurrentYPosition), DigitScale, 1.0f, Color.White);
                            CurrentXPosition += QuantityColumnWidth + SpaceWidth;
                            DrawHelpers.DrawStringWithShadow(b, Game1.tinyFont, "=", CurrentXPosition, CurrentYPosition - LineHeight / 6, Color.White, Color.Black, ShadowOffset, ShadowOffset);
                            CurrentXPosition += EqualsCharacterWidth + SpaceWidth;
                            Utility.drawTinyDigits(MultipliedValues[i], b, new Vector2(CurrentXPosition + MultipliedValueColumnWidth - DrawHelpers.MeasureNumber(MultipliedValues[i], DigitScale), CurrentYPosition), DigitScale, 1.0f, Color.White);

                            CurrentYPosition += LineHeight;
                        }

                        //  Draw separator
                        CurrentYPosition += SeparatorMargin;
                        DrawHelpers.DrawHorizontalSeparator(b, ToolTipLocation.X + Margin, CurrentYPosition, TotalWidth - Margin * 2, HorizontalSeparatorHeight);
                        CurrentYPosition += HorizontalSeparatorHeight + SeparatorMargin;

                        //  Draw total value
                        int       SummedValue         = MultipliedValues.Sum();
                        float     SummedValueWidth    = DrawHelpers.MeasureNumber(SummedValue, DigitScale) + GoldIconSourceRect.Width * 2f + 8;
                        Vector2   SummedValuePosition = new Vector2(ToolTipLocation.X + ((ToolTipLocation.Width - SummedValueWidth) / 2), CurrentYPosition + 6);
                        Rectangle IconDestination     = new Rectangle((int)SummedValuePosition.X, (int)(SummedValuePosition.Y + (DrawHelpers.TinyDigitBaseHeight * DigitScale - GoldIconSourceRect.Height * 2) / 2), GoldIconSourceRect.Width * 2, GoldIconSourceRect.Height * 2);
                        b.Draw(GoldIconTexture, IconDestination, GoldIconSourceRect, Color.White);
                        Utility.drawTinyDigits(SummedValue, b, new Vector2(SummedValuePosition.X + GoldIconSourceRect.Width * 2f + 8, SummedValuePosition.Y), DigitScale, 1.0f, GetValueColor(SummedValue));
                    }
                    else
                    {
                        Object    HoveredItem = Placeholders[ItemId.Value][ConvertColumnTypeToObjectQuality(Column.Value)];
                        Rectangle Location;
                        if (IsNavigatingWithGamepad)
                        {
                            Location = HoveredSlot.Value; //new Rectangle(HoveredSlot.Value.Right, HoveredSlot.Value.Bottom, 1, 1);
                        }
                        else
                        {
                            Location = new Rectangle(Game1.getMouseX() - 8, Game1.getMouseY() + 36, 8 + 36, 1);
                        }
                        DrawHelpers.DrawToolTipInfo(b, Location, HoveredItem, true, true, true, true, true, true, Bag.MaxStackSize);
                    }
                }
            }
        }