Beispiel #1
0
        public override void RenderTo(ICoreClientAPI capi, double x, double y)
        {
            float size = (float)GuiElement.scaled(25);
            float pad  = (float)GuiElement.scaled(10);

            if (Texture == null)
            {
                Recompose(capi);
            }

            scissorBounds.fixedX = pad + x / RuntimeEnv.GUIScale - size / 2;
            scissorBounds.fixedY = y / RuntimeEnv.GUIScale - size / 2;
            scissorBounds.CalcWorldBounds();

            if (scissorBounds.InnerWidth <= 0 || scissorBounds.InnerHeight <= 0)
            {
                return;
            }

            capi.Render.PushScissor(scissorBounds, true);
            capi.Render.RenderItemstackToGui(dummySlot, x + pad + size / 2, y + size / 2, 100, size, ColorUtil.WhiteArgb, true, false, false);
            capi.Render.PopScissor();

            capi.Render.Render2DTexturePremultipliedAlpha(
                Texture.TextureId,
                (x + size + GuiElement.scaled(25)),
                y + size / 4 - 3,
                Texture.Width,
                Texture.Height,
                50
                );
        }
Beispiel #2
0
        /// <summary>
        /// Looks at the collectibles handbook groupBy attribute and makes a list of itemstacks from that
        /// </summary>
        /// <param name="itemstackgroup"></param>
        /// <param name="unscaleSize"></param>
        /// <param name="floatType"></param>
        public SlideshowItemstackTextComponent(ICoreClientAPI capi, ItemStack itemstackgroup, List <ItemStack> allstacks, double unscaleSize, EnumFloat floatType, Action <ItemStack> onStackClicked = null) : base(capi)
        {
            initSlot();
            this.onStackClicked = onStackClicked;

            string[] groups = itemstackgroup.Collectible.Attributes?["handbook"]?["groupBy"]?.AsArray <string>(null);

            List <ItemStack> nowGroupedStacks = new List <ItemStack>();
            List <ItemStack> stacks           = new List <ItemStack>();

            nowGroupedStacks.Add(itemstackgroup);
            stacks.Add(itemstackgroup);

            if (allstacks != null)
            {
                if (groups != null)
                {
                    AssetLocation[] groupWildCards = new AssetLocation[groups.Length];
                    for (int i = 0; i < groups.Length; i++)
                    {
                        if (!groups[i].Contains(":"))
                        {
                            groupWildCards[i] = new AssetLocation(itemstackgroup.Collectible.Code.Domain, groups[i]);
                        }
                        else
                        {
                            groupWildCards[i] = new AssetLocation(groups[i]);
                        }
                    }

                    foreach (var val in allstacks)
                    {
                        if (val.Collectible.Attributes?["handbook"]?["isDuplicate"].AsBool(false) == true)
                        {
                            nowGroupedStacks.Add(val);
                            continue;
                        }
                        for (int i = 0; i < groupWildCards.Length; i++)
                        {
                            if (val.Collectible.WildCardMatch(groupWildCards[i]))
                            {
                                stacks.Add(val);
                                nowGroupedStacks.Add(val);
                                break;
                            }
                        }
                    }
                }

                foreach (var val in nowGroupedStacks)
                {
                    allstacks.Remove(val);
                }
            }

            this.Itemstacks    = stacks.ToArray();
            this.Float         = floatType;
            this.BoundsPerLine = new LineRectangled[] { new LineRectangled(0, 0, GuiElement.scaled(unscaleSize), GuiElement.scaled(unscaleSize)) };
        }
Beispiel #3
0
        /// <summary>
        /// Flips through given array of item stacks every second
        /// </summary>
        /// <param name="itemstacks"></param>
        /// <param name="unscaleSize"></param>
        /// <param name="floatType"></param>
        public SlideshowItemstackTextComponent(ICoreClientAPI capi, ItemStack[] itemstacks, double unscaleSize, EnumFloat floatType, Action <ItemStack> onStackClicked = null) : base(capi)
        {
            initSlot();

            this.Itemstacks     = itemstacks;
            this.Float          = floatType;
            this.BoundsPerLine  = new LineRectangled[] { new LineRectangled(0, 0, GuiElement.scaled(unscaleSize), GuiElement.scaled(unscaleSize)) };
            this.onStackClicked = onStackClicked;
        }
Beispiel #4
0
        public override bool CalcBounds(TextFlowPath[] flowPath, double currentLineHeight, double lineX, double lineY)
        {
            BoundsPerLine = new LineRectangled[]
            {
                new LineRectangled(lineX, lineY, GuiElement.scaled(font.UnscaledFontsize), GuiElement.scaled(font.UnscaledFontsize))
            };

            return(false);
        }
        public ItemstackTextComponent(ICoreClientAPI capi, ItemStack itemstack, double size, double rightSidePadding = 0, EnumFloat floatType = EnumFloat.Left, Action <ItemStack> onStackClicked = null) : base(capi)
        {
            size = GuiElement.scaled(size);

            slot = new DummySlot(itemstack);
            this.onStackClicked = onStackClicked;
            this.Float          = floatType;
            this.size           = size;
            this.BoundsPerLine  = new LineRectangled[] { new LineRectangled(0, 0, size, size) };
            PaddingRight        = GuiElement.scaled(rightSidePadding);
        }
Beispiel #6
0
        public override void ComposeElements(Context ctx, ImageSurface surface)
        {
            ctx.SetSourceRGBA(1, 1, 1, 0.2);

            for (int x = 0; x < 3; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    ctx.Rectangle(BoundsPerLine[0].X + x * (size + GuiElement.scaled(3)), BoundsPerLine[0].Y + y * (size + GuiElement.scaled(3)), size, size);
                    ctx.Fill();
                }
            }
        }
Beispiel #7
0
        public SkillItem WithLetterIcon(ICoreClientAPI capi, string letter)
        {
            if (capi == null)
            {
                return(this);
            }

            int isize = (int)GuiElement.scaled(48);

            Texture = capi.Gui.Icons.GenTexture(isize, isize, (ctx, surface) =>
            {
                var font = CairoFont.WhiteMediumText().WithColor(new double[] { 1, 1, 1, 1 });
                font.SetupContext(ctx);
                var size = font.GetTextExtents(letter);
                var asc  = font.GetFontExtents().Ascent + GuiElement.scaled(2);
                capi.Gui.Text.DrawTextLine(ctx, font, letter, (isize - size.Width) / 2, (isize - asc) / 2);
            });

            return(this);
        }
Beispiel #8
0
        /// <summary>
        /// Initializes the size and stuff. Return true if you had to enter the next line
        /// </summary>
        /// <param name="flowPath"></param>
        /// <param name="xPos"></param>
        /// <returns>True when longer than 1 line</returns>
        public override bool CalcBounds(TextFlowPath[] flowPath, double currentLineHeight, double lineX, double lineY)
        {
            lines = textUtil.Lineize(font, displayText, flowPath, lineX + GuiElement.scaled(PaddingLeft), lineY);

            BoundsPerLine = new LineRectangled[lines.Length];
            for (int i = 0; i < lines.Length; i++)
            {
                TextLine line = lines[i];
                BoundsPerLine[i] = line.Bounds;
            }

            if (lines.Length > 0)
            {
                lines[0].PaddingLeft = GuiElement.scaled(PaddingLeft);
                lines[lines.Length - 1].PaddingRight  = PaddingRight;
                lines[lines.Length - 1].Bounds.Width += PaddingRight;
            }

            return(lines.Length > 1);
        }
Beispiel #9
0
        /// <summary>
        /// Takes a texture and applies some text to it.
        /// </summary>
        /// <param name="text">The text to texture.</param>
        /// <param name="font">The font of the text.</param>
        /// <param name="loadedTexture">The texture to be loaded on to.</param>
        /// <param name="background">The background of the text. (default: none/null)</param>
        public void GenOrUpdateTextTexture(string text, CairoFont font, ref LoadedTexture loadedTexture, TextBackground background = null)
        {
            if (background == null)
            {
                background = defaultBackground.Clone();
                if (font.StrokeWidth > 0)
                {
                    background.Padding = (int)Math.Ceiling(font.StrokeWidth);
                }
            }

            ElementBounds bounds = new ElementBounds();

            font.AutoBoxSize(text, bounds);


            int width  = (int)Math.Ceiling(GuiElement.scaled(bounds.fixedWidth + 1 + 2 * background.Padding));
            int height = (int)Math.Ceiling(GuiElement.scaled(bounds.fixedHeight + 1 + 2 * background.Padding));

            GenOrUpdateTextTexture(text, font, width, height, ref loadedTexture, background);
        }
Beispiel #10
0
        public override void RenderTo(ICoreClientAPI capi, double x, double y)
        {
            float size = (float)GuiElement.scaled(25);
            float pad  = (float)GuiElement.scaled(10);

            //capi.Render.RenderItemstackToGui(Stack, x + pad + size / 2, y + size / 2, 100, size, ColorUtil.WhiteArgb, true, false, false);

            if (Texture == null)
            {
                Recompose(capi);
            }

            capi.Render.Render2DTexturePremultipliedAlpha(
                Texture.TextureId,
                (x + pad),
                y + size / 4 - 3,
                Texture.Width,
                Texture.Height,
                50
                );
        }
Beispiel #11
0
        /// <summary>
        /// Sets up the context. Must be executed in the main thread, as it is not thread safe.
        /// </summary>
        /// <param name="ctx">The context to set up the CairoFont with.</param>
        public void SetupContext(Context ctx)
        {
            ctx.SetFontSize(GuiElement.scaled(UnscaledFontsize));
            ctx.SelectFontFace(Fontname, Slant, FontWeight);
            CairoFontOptions = new FontOptions();

            //Antialias.Best does not work on Linux it completely borks the font
            CairoFontOptions.Antialias = Antialias.Subpixel;
            ctx.FontOptions            = CairoFontOptions;

            if (Color != null)
            {
                if (Color.Length == 3)
                {
                    ctx.SetSourceRGB(Color[0], Color[1], Color[2]);
                }
                if (Color.Length == 4)
                {
                    ctx.SetSourceRGBA(Color[0], Color[1], Color[2], Color[3]);
                }
            }
        }
Beispiel #12
0
        public override void RenderTo(ICoreClientAPI capi, double x, double y)
        {
            float size = (float)GuiElement.scaled(25);
            float pad  = (float)GuiElement.scaled(10);

            int index = (int)((capi.ElapsedMilliseconds / 1000) % Stacks.Count);

            dummySlot.Itemstack = Stacks[index];
            capi.Render.RenderItemstackToGui(dummySlot, x + pad + size / 2, y + size / 2, 100, size, ColorUtil.WhiteArgb, true, false, false);

            if (Texture == null)
            {
                Texture = new TextTextureUtil(capi).GenTextTexture(Name, CairoFont.WhiteSmallText());
            }

            capi.Render.Render2DTexturePremultipliedAlpha(
                Texture.TextureId,
                (x + size + GuiElement.scaled(25)),
                y + size / 4 - 3,
                Texture.Width,
                Texture.Height,
                50
                );
        }
        public void CalcHeightAndPositions()
        {
            Bounds.CalcWorldBounds();

            if (DebugLogging)
            {
                api.Logger.VerboseDebug("GuiElementRichtext: before bounds: {0}/{1}  w/h = {2},{3}", Bounds.absX, Bounds.absY, Bounds.OuterWidth, Bounds.OuterHeight);
            }

            double posX = 0;
            double posY = 0;

            List <int>          currentLine  = new List <int>();
            List <TextFlowPath> flowPathList = new List <TextFlowPath>();

            flowPathList.Add(new TextFlowPath(Bounds.InnerWidth));

            double lineHeight          = 0;
            double ascentHeight        = 0;
            RichTextComponentBase comp = null;

            for (int i = 0; i < Components.Length; i++)
            {
                comp = Components[i];

                bool didLineBreak = comp.CalcBounds(flowPathList.ToArray(), lineHeight, posX, posY);

                if (DebugLogging)
                {
                    api.Logger.VerboseDebug("GuiElementRichtext, add comp {0}, posY={1}, lineHeight={2}", i, posY, lineHeight);
                    api.Logger.VerboseDebug("GuiElementRichtext, Comp bounds 0 w/h: {0}/{1}", comp.BoundsPerLine[0].Width, comp.BoundsPerLine[0].Height);
                }


                posX += scaled(comp.PaddingLeft);

                if (comp.Float == EnumFloat.None)
                {
                    posX  = 0;
                    posY += Math.Max(lineHeight, comp.BoundsPerLine[0].Height) + (didLineBreak ? GuiElement.scaled(comp.UnscaledMarginTop) : 0);
                    posY  = Math.Ceiling(posY);

                    currentLine.Clear();
                    lineHeight   = 0;
                    ascentHeight = 0;
                    continue;
                }

                if (didLineBreak)
                {
                    lineHeight   = Math.Ceiling(Math.Max(lineHeight, comp.BoundsPerLine[0].Height));
                    ascentHeight = Math.Ceiling(Math.Max(ascentHeight, comp.BoundsPerLine[0].AscentOrHeight));

                    // All previous elements in this line might need to have their Y pos adjusted due to a larger element in the line
                    foreach (int index in currentLine)
                    {
                        RichTextComponentBase lineComp       = Components[index];
                        Rectangled            lastLineBounds = lineComp.BoundsPerLine[lineComp.BoundsPerLine.Length - 1];

                        if (lineComp.VerticalAlign == EnumVerticalAlign.Bottom)
                        {
                            lastLineBounds.Y = Math.Ceiling(lastLineBounds.Y + ascentHeight - lineComp.BoundsPerLine[lineComp.BoundsPerLine.Length - 1].AscentOrHeight);
                        }
                        if (lineComp.VerticalAlign == EnumVerticalAlign.Middle)
                        {
                            lastLineBounds.Y = Math.Ceiling(lastLineBounds.Y + ascentHeight - lineComp.BoundsPerLine[lineComp.BoundsPerLine.Length - 1].AscentOrHeight / 2);
                        }
                    }

                    // The current element that was still on the same line as well
                    // Offset all lines by the gained y-offset on the first line
                    if (comp.VerticalAlign == EnumVerticalAlign.Bottom)
                    {
                        foreach (var val in comp.BoundsPerLine)
                        {
                            val.Y = Math.Ceiling(val.Y + ascentHeight - comp.BoundsPerLine[0].AscentOrHeight);
                        }
                    }
                    if (comp.VerticalAlign == EnumVerticalAlign.Middle)
                    {
                        foreach (var val in comp.BoundsPerLine)
                        {
                            val.Y = Math.Ceiling(val.Y + ascentHeight - comp.BoundsPerLine[0].AscentOrHeight / 2);
                        }
                    }

                    currentLine.Clear();
                    currentLine.Add(i);


                    posY += lineHeight;
                    for (int k = 1; k < comp.BoundsPerLine.Length - 1; k++)
                    {
                        posY += comp.BoundsPerLine[k].Height;
                    }
                    posY += scaled(comp.UnscaledMarginTop);
                    posY  = Math.Ceiling(posY);


                    posX = comp.BoundsPerLine[comp.BoundsPerLine.Length - 1].Width; // + GuiElement.scaled(comp.PaddingLeft); - this adds too much padding when there is a line break inside a rich text compoment and afterwards there comes a link
                    if (comp.BoundsPerLine[comp.BoundsPerLine.Length - 1].Width > 0)
                    {
                        lineHeight   = comp.BoundsPerLine[comp.BoundsPerLine.Length - 1].Height;
                        ascentHeight = comp.BoundsPerLine[comp.BoundsPerLine.Length - 1].AscentOrHeight;
                    }
                    else
                    {
                        lineHeight   = 0;
                        ascentHeight = 0;
                    }
                }
                else
                {
                    if (comp.Float == EnumFloat.Inline && comp.BoundsPerLine.Length > 0)
                    {
                        posX        += comp.BoundsPerLine[0].Width;
                        lineHeight   = Math.Max(comp.BoundsPerLine[0].Height, lineHeight);
                        ascentHeight = Math.Max(comp.BoundsPerLine[0].AscentOrHeight, ascentHeight);
                        currentLine.Add(i);
                    }
                }

                if (comp.Float != EnumFloat.Inline)
                {
                    ConstrainTextFlowPath(flowPathList, posY, comp);
                }
            }


            if (DebugLogging)
            {
                api.Logger.VerboseDebug("GuiElementRichtext: after loop. posY = {0}", posY);
            }


            if (comp != null && posX > 0 && comp.BoundsPerLine.Length > 0)
            {
                posY += lineHeight;
            }

            Bounds.fixedHeight = (posY + 1) / RuntimeEnv.GUIScale;


            double maxHeight = 0;

            foreach (int index in currentLine)
            {
                RichTextComponentBase lineComp       = Components[index];
                Rectangled            lastLineBounds = lineComp.BoundsPerLine[lineComp.BoundsPerLine.Length - 1];
                maxHeight = Math.Max(maxHeight, lastLineBounds.Height);
            }

            foreach (int index in currentLine)
            {
                RichTextComponentBase lineComp       = Components[index];
                Rectangled            lastLineBounds = lineComp.BoundsPerLine[lineComp.BoundsPerLine.Length - 1];

                if (lineComp.VerticalAlign == EnumVerticalAlign.Bottom)
                {
                    lastLineBounds.Y = Math.Ceiling(lastLineBounds.Y + ascentHeight - lineComp.BoundsPerLine[lineComp.BoundsPerLine.Length - 1].AscentOrHeight);
                }
                if (lineComp.VerticalAlign == EnumVerticalAlign.Middle)
                {
                    lastLineBounds.Y = (maxHeight - lastLineBounds.Height) / 2f;
                }
            }

            this.flowPath = flowPathList.ToArray();

            if (DebugLogging)
            {
                api.Logger.VerboseDebug("GuiElementRichtext: after bounds: {0}/{1}  w/h = {2},{3}", Bounds.absX, Bounds.absY, Bounds.OuterWidth, Bounds.OuterHeight);
                api.Logger.VerboseDebug("GuiElementRichtext: posY = {0}", posY);

                api.Logger.VerboseDebug("GuiElementRichtext: framewidth/height: {0}/{1}", api.Render.FrameWidth, api.Render.FrameHeight);
            }
        }
Beispiel #14
0
        public override void RenderInteractiveElements(float deltaTime, double renderX, double renderY)
        {
            LineRectangled bounds = BoundsPerLine[0];

            GridRecipeAndUnnamedIngredients recipeunin = GridRecipesAndUnIn[curItemIndex];

            if ((secondsVisible -= deltaTime) <= 0)
            {
                secondsVisible = 1;
                curItemIndex   = (curItemIndex + 1) % GridRecipesAndUnIn.Length;
                secondCounter++;
            }

            LoadedTexture extraTextTexture;

            if (extraTexts.TryGetValue(curItemIndex, out extraTextTexture))
            {
                capi.Render.Render2DTexturePremultipliedAlpha(extraTextTexture.TextureId, (float)(renderX + bounds.X), (float)(renderY + bounds.Y + 3 * (size + 3)), extraTextTexture.Width, extraTextTexture.Height);
            }

            int    mx = api.Input.MouseX;
            int    my = api.Input.MouseY;
            double rx = 0, ry = 0;



            for (int x = 0; x < 3; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    int index = recipeunin.Recipe.GetGridIndex(y, x, recipeunin.Recipe.resolvedIngredients, recipeunin.Recipe.Width);

                    CraftingRecipeIngredient ingred = recipeunin.Recipe.GetElementInGrid(y, x, recipeunin.Recipe.resolvedIngredients, recipeunin.Recipe.Width);


                    if (ingred == null)
                    {
                        continue;
                    }

                    rx = renderX + bounds.X + x * (size + GuiElement.scaled(3));
                    ry = renderY + bounds.Y + y * (size + GuiElement.scaled(3));

                    ItemStack[] unnamedWildcardStacklist = null;
                    if (recipeunin.unnamedIngredients?.TryGetValue(index, out unnamedWildcardStacklist) == true)
                    {
                        dummyslot.Itemstack           = unnamedWildcardStacklist[secondCounter % unnamedWildcardStacklist.Length];
                        dummyslot.Itemstack.StackSize = ingred.Quantity;
                    }
                    else
                    {
                        dummyslot.Itemstack = ingred.ResolvedItemstack.Clone();
                    }

                    var           scale         = RuntimeEnv.GUIScale;
                    ElementBounds scissorBounds = ElementBounds.Fixed(rx / scale, ry / scale, size / scale, size / scale).WithEmptyParent();
                    scissorBounds.CalcWorldBounds();
                    api.Render.PushScissor(scissorBounds, true);

                    // 1.16.0: Fugly (but backwards compatible) hack: We temporarily store the ingredient code in an unused field of ItemSlot so that OnHandbookRecipeRender() has access to that number. Proper solution would be to alter the method signature to pass on this value.
                    dummyslot.BackgroundIcon = index + "";
                    dummyslot.Itemstack.Collectible.OnHandbookRecipeRender(capi, recipeunin.Recipe, dummyslot, rx + size * 0.5f, ry + size * 0.5f, size);
                    dummyslot.BackgroundIcon = null;


                    api.Render.PopScissor();

                    // Super weird coordinates, no idea why
                    double dx = mx - rx + 1;
                    double dy = my - ry + 2;

                    if (dx >= 0 && dx < size && dy >= 0 && dy < size)
                    {
                        RenderItemstackTooltip(dummyslot, rx + dx, ry + dy, deltaTime);
                    }
                }
            }
        }
Beispiel #15
0
 public override void ComposeElements(Context ctx, ImageSurface surface)
 {
     capi.Gui.Icons.DrawIcon(ctx, iconName, BoundsPerLine[0].X, BoundsPerLine[0].Y, GuiElement.scaled(font.UnscaledFontsize), GuiElement.scaled(font.UnscaledFontsize), font.Color);
 }
        public override void RenderInteractiveElements(float deltaTime)
        {
            if (text == null || text.Length == 0)
            {
                return;
            }

            if (api.Render.ScissorStack.Count > 0)
            {
                api.Render.GlScissorFlag(false);
            }

            int mouseX = api.Input.MouseX;
            int mouseY = api.Input.MouseY;

            isnowshown = false;

            if ((autoDisplay && IsPositionInside(mouseX, mouseY)) || visible)
            {
                isnowshown = true;
                // Compose on demand only
                if (hoverTexture.TextureId == 0 && !hoverTexture.Disposed)
                {
                    Recompose();
                }

                int pad = (int)scaled(padding);

                double x = Bounds.renderX;
                double y = Bounds.renderY;

                if (followMouse)
                {
                    x = mouseX + GuiElement.scaled(10);
                    y = mouseY + GuiElement.scaled(15);
                }

                if (x + hoverWidth > api.Render.FrameWidth)
                {
                    x -= (x + hoverWidth) - api.Render.FrameWidth;
                }

                if (y + hoverHeight > api.Render.FrameHeight)
                {
                    y -= (y + hoverHeight) - api.Render.FrameHeight;
                }

                api.Render.Render2DTexture(hoverTexture.TextureId, (int)x + (int)Bounds.absPaddingX, (int)y + (int)Bounds.absPaddingY, (int)hoverWidth + 1, (int)hoverHeight + 1, zPosition, RenderColor);

                Bounds.renderOffsetX           = x - Bounds.renderX + pad;
                Bounds.renderOffsetY           = y - Bounds.renderY + pad;
                descriptionElement.RenderColor = rendercolor;
                descriptionElement.RenderAsPremultipliedAlpha = RenderAsPremultipliedAlpha;
                descriptionElement.RenderInteractiveElements(deltaTime);
                Bounds.renderOffsetX = 0;
                Bounds.renderOffsetY = 0;
            }

            if (api.Render.ScissorStack.Count > 0)
            {
                api.Render.GlScissorFlag(true);
            }
        }
Beispiel #17
0
        /// <summary>
        /// Flips through given array of grid recipes every second
        /// </summary>
        /// <param name="capi"></param>
        /// <param name="gridrecipes"></param>
        /// <param name="size"></param>
        /// <param name="floatType"></param>
        /// <param name="onStackClicked"></param>
        /// <param name="allStacks">If set, will resolve wildcards based on this list, otherwise will search all available blocks/items</param>
        public SlideshowGridRecipeTextComponent(ICoreClientAPI capi, GridRecipe[] gridrecipes, double size, EnumFloat floatType, Action <ItemStack> onStackClicked = null, ItemStack[] allStacks = null) : base(capi)
        {
            size = GuiElement.scaled(size);

            this.onStackClicked = onStackClicked;
            this.Float          = floatType;
            this.BoundsPerLine  = new LineRectangled[] { new LineRectangled(0, 0, 3 * (size + 3), 3 * (size + 3)) };
            this.size           = size;

            Random fixedRand = new Random(123);

            // Expand wild cards
            List <GridRecipeAndUnnamedIngredients> resolvedGridRecipes = new List <GridRecipeAndUnnamedIngredients>();
            Queue <GridRecipe> halfResolvedRecipes = new Queue <GridRecipe>(gridrecipes);

            bool allResolved = false;

            while (!allResolved)
            {
                allResolved = true;

                int cnt = halfResolvedRecipes.Count;

                while (cnt-- > 0)
                {
                    GridRecipe toTestRecipe = halfResolvedRecipes.Dequeue();
                    Dictionary <int, ItemStack[]> unnamedIngredients = null;

                    bool thisResolved = true;

                    for (int j = 0; j < toTestRecipe.resolvedIngredients.Length; j++)
                    {
                        CraftingRecipeIngredient ingred = toTestRecipe.resolvedIngredients[j];

                        if (ingred != null && ingred.IsWildCard)
                        {
                            allResolved  = false;
                            thisResolved = false;
                            ItemStack[] stacks = ResolveWildCard(capi.World, ingred, allStacks);

                            if (ingred.Name == null)
                            {
                                if (unnamedIngredients == null)
                                {
                                    unnamedIngredients = new Dictionary <int, ItemStack[]>();
                                }
                                unnamedIngredients[j] = ((ItemStack[])stacks.Clone()).Shuffle(fixedRand);
                                thisResolved          = true;
                                continue;
                            }

                            if (stacks.Length == 0)
                            {
                                throw new ArgumentException("Attempted to resolve the recipe ingredient wildcard " + ingred.Type + " " + ingred.Code + " but there are no such items/blocks!");
                            }

                            for (int k = 0; k < stacks.Length; k++)
                            {
                                GridRecipe cloned = toTestRecipe.Clone();

                                for (int m = 0; m < cloned.resolvedIngredients.Length; m++)
                                {
                                    CraftingRecipeIngredient clonedingred = cloned.resolvedIngredients[m];
                                    if (clonedingred != null && clonedingred.Code.Equals(ingred.Code))
                                    {
                                        clonedingred.Code              = stacks[k].Collectible.Code;
                                        clonedingred.IsWildCard        = false;
                                        clonedingred.ResolvedItemstack = stacks[k];
                                    }
                                }

                                halfResolvedRecipes.Enqueue(cloned);
                            }

                            break;
                        }
                    }

                    if (thisResolved)
                    {
                        resolvedGridRecipes.Add(new GridRecipeAndUnnamedIngredients()
                        {
                            Recipe = toTestRecipe, unnamedIngredients = unnamedIngredients
                        });
                    }
                }
            }

            resolveCache.Clear();
            this.GridRecipesAndUnIn = resolvedGridRecipes.ToArray();


            this.GridRecipesAndUnIn.Shuffle(fixedRand);

            for (int i = 0; i < GridRecipesAndUnIn.Length; i++)
            {
                string trait = GridRecipesAndUnIn[i].Recipe.RequiresTrait;
                if (trait != null)
                {
                    extraTexts[i] = capi.Gui.TextTexture.GenTextTexture(Lang.Get("* Requires {0} trait", trait), CairoFont.WhiteDetailText());
                }
            }

            if (GridRecipesAndUnIn.Length == 0)
            {
                throw new ArgumentException("Could not resolve any of the supplied grid recipes?");
            }
        }
        public override void RenderInteractiveElements(float deltaTime, double renderX, double renderY)
        {
            LineRectangled bounds = BoundsPerLine[0];

            ElementBounds scibounds = ElementBounds.FixedSize((int)(bounds.Width / API.Config.RuntimeEnv.GUIScale), (int)(bounds.Height / API.Config.RuntimeEnv.GUIScale));

            scibounds.ParentBounds = capi.Gui.WindowBounds;

            scibounds.CalcWorldBounds();
            scibounds.absFixedX = renderX + bounds.X;
            scibounds.absFixedY = renderY + bounds.Y + offY;

            api.Render.PushScissor(scibounds, true);

            api.Render.RenderItemstackToGui(
                slot, renderX + bounds.X + bounds.Width * 0.5f + offX, renderY + bounds.Y + bounds.Height * 0.5f + offY, GuiElement.scaled(100), (float)size * 0.58f, ColorUtil.WhiteArgb, true, false, false);

            api.Render.PopScissor();


            int relx = (int)(api.Input.MouseX - renderX);
            int rely = (int)(api.Input.MouseY - renderY);

            if (bounds.PointInside(relx, rely))
            {
                RenderItemstackTooltip(slot, renderX + relx + offX, renderY + rely + offY, deltaTime);
            }
        }
Beispiel #19
0
        public override bool CalcBounds(TextFlowPath[] flowPath, double currentLineHeight, double lineX, double lineY)
        {
            TextFlowPath curfp            = GetCurrentFlowPathSection(flowPath, lineY);
            bool         requireLinebreak = lineX + BoundsPerLine[0].Width > curfp.X2;

            this.BoundsPerLine[0].X = requireLinebreak ? 0 : lineX;
            this.BoundsPerLine[0].Y = lineY + (requireLinebreak ? currentLineHeight + GuiElement.scaled(UnscaledMarginTop) : 0);

            return(requireLinebreak);
        }
Beispiel #20
0
        public override void ComposeElements(Context ctxStatic, ImageSurface surfaceStatic)
        {
            insideBounds = new ElementBounds().WithFixedPadding(unscaledCellSpacing).WithEmptyParent();
            insideBounds.CalcWorldBounds();
            CalcTotalHeight();
            Bounds.CalcWorldBounds();

            ImageSurface surface = new ImageSurface(Format.Argb32, (int)Bounds.InnerWidth, (int)GuiElement.scaled(unscaledCellHeight));
            Context      ctx     = new Context(surface);

            ctx.SetSourceRGBA(1, 1, 1, 0.5);
            ctx.Paint();

            generateTexture(surface, ref hoverOverlayTexture);

            ctx.Dispose();
            surface.Dispose();
        }