コード例 #1
0
        public static void BuildFactorioObjectIcon(this ImGui gui, FactorioObject obj, MilestoneDisplay display = MilestoneDisplay.Normal, float size = 2f)
        {
            if (obj == null)
            {
                gui.BuildIcon(Icon.Empty, size, SchemeColor.BackgroundTextFaint);
                return;
            }

            var color = obj.IsAccessible() ? SchemeColor.Source : SchemeColor.SourceFaint;

            gui.BuildIcon(obj.icon, size, color);
            if (gui.isBuilding && display != MilestoneDisplay.None)
            {
                var contain   = (display & MilestoneDisplay.Contained) != 0;
                var milestone = Milestones.Instance.GetHighest(obj, display >= MilestoneDisplay.All);
                if (milestone != null)
                {
                    var psize         = new Vector2(size / 2f);
                    var delta         = contain ? psize : psize / 2f;
                    var milestoneIcon = new Rect(gui.lastRect.BottomRight - delta, psize);
                    var icon          = milestone == Database.voidEnergy ? DataUtils.HandIcon : milestone.icon;
                    gui.DrawIcon(milestoneIcon, icon, color);
                }
            }
        }
コード例 #2
0
 private void BuildHeader(ImGui gui)
 {
     using (gui.EnterGroup(new Padding(1f, 0.5f), RectAllocator.LeftAlign, spacing: 0f))
     {
         var name = target.text;
         if (extendHeader && !(target is Goods))
         {
             name = name + " (" + target.target.type + ")";
         }
         gui.BuildText(name, Font.header, true);
         var milestoneMask = Milestones.Instance.milestoneResult[target.target];
         if (milestoneMask > 1)
         {
             var spacing = MathF.Min(22f / Milestones.Instance.currentMilestones.Length - 1f, 0f);
             using (gui.EnterRow(spacing))
             {
                 var mask = 2ul;
                 foreach (var milestone in Milestones.Instance.currentMilestones)
                 {
                     if ((milestoneMask & mask) != 0)
                     {
                         gui.BuildIcon(milestone.icon, 1f, SchemeColor.Source);
                     }
                     mask <<= 1;
                 }
             }
         }
     }
     if (gui.isBuilding)
     {
         gui.DrawRectangle(gui.lastRect, SchemeColor.Primary);
     }
 }
コード例 #3
0
        private void BuildRecipePad(ImGui gui, RecipeRow row)
        {
            gui.allocator = RectAllocator.Center;
            gui.spacing   = 0f;
            if (row.subgroup != null)
            {
                if (gui.BuildButton(row.subgroup.expanded ? Icon.ShevronDown : Icon.ShevronRight))
                {
                    row.subgroup.RecordUndo(true).expanded = !row.subgroup.expanded;
                    flatHierarchyBuilder.SetData(model);
                }
            }


            if (row.parameters.warningFlags != 0)
            {
                var  isError = row.parameters.warningFlags >= WarningFlags.EntityNotSpecified;
                bool hover;
                if (isError)
                {
                    hover = gui.BuildRedButton(Icon.Error) == ImGuiUtils.Event.MouseOver;
                }
                else
                {
                    using (gui.EnterGroup(ImGuiUtils.DefaultIconPadding))
                        gui.BuildIcon(Icon.Help);
                    hover = gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey) == ImGuiUtils.Event.MouseOver;
                }
                if (hover)
                {
                    gui.ShowTooltip(g =>
                    {
                        if (isError)
                        {
                            g.boxColor  = SchemeColor.Error;
                            g.textColor = SchemeColor.ErrorText;
                        }
                        foreach (var(flag, text) in WarningsMeaning)
                        {
                            if ((row.parameters.warningFlags & flag) != 0)
                            {
                                g.BuildText(text, wrap: true);
                            }
                        }
                    });
                }
            }
            else
            {
                //gui.BuildText((index+1).ToString()); TODO
            }
        }
コード例 #4
0
 private void DrawRecipeTagSelect(ImGui gui, RecipeRow recipe)
 {
     using (gui.EnterRow())
     {
         for (var i = 0; i < tagIcons.Length; i++)
         {
             var(icon, color) = tagIcons[i];
             var selected = i == recipe.tag;
             gui.BuildIcon(icon, color: selected ? SchemeColor.Background : color);
             if (selected)
             {
                 gui.DrawRectangle(gui.lastRect, color);
             }
             else
             {
                 var evt = gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.BackgroundAlt, SchemeColor.BackgroundAlt);
                 if (evt == ImGuiUtils.Event.Click)
                 {
                     recipe.RecordUndo(true).tag = i;
                 }
             }
         }
     }
 }
コード例 #5
0
        private void BuildRecipe(RecipeOrTechnology recipe, ImGui gui)
        {
            BuildCommon(recipe, gui);
            using (gui.EnterGroup(contentPadding, RectAllocator.LeftRow))
            {
                gui.BuildIcon(Icon.Time, 2f, SchemeColor.BackgroundText);
                gui.BuildText(DataUtils.FormatAmount(recipe.time, UnitOfMeasure.Second));
            }

            using (gui.EnterGroup(contentPadding))
            {
                foreach (var ingredient in recipe.ingredients)
                {
                    BuildItem(gui, ingredient);
                }
                if (recipe is Recipe rec)
                {
                    var waste = rec.RecipeWaste();
                    if (waste > 0.01f)
                    {
                        var wasteAmount = MathUtils.Round(waste * 100f);
                        var wasteText   = ". (Wasting " + wasteAmount + "% of YAFC cost)";
                        var color       = wasteAmount < 90 ? SchemeColor.BackgroundText : SchemeColor.Error;
                        if (recipe.products.Length == 1)
                        {
                            gui.BuildText("YAFC analysis: There are better recipes to create " + recipe.products[0].goods.locName + wasteText, wrap: true, color: color);
                        }
                        else if (recipe.products.Length > 0)
                        {
                            gui.BuildText("YAFC analysis: There are better recipes to create each of the products" + wasteText, wrap: true, color: color);
                        }
                        else
                        {
                            gui.BuildText("YAFC analysis: This recipe wastes useful products. Don't do this recipe.", wrap: true, color: color);
                        }
                    }
                }
                if (recipe.flags.HasFlags(RecipeFlags.UsesFluidTemperature))
                {
                    gui.BuildText("Uses fluid temperature");
                }
                if (recipe.flags.HasFlags(RecipeFlags.UsesMiningProductivity))
                {
                    gui.BuildText("Uses mining productivity");
                }
                if (recipe.flags.HasFlags(RecipeFlags.ScaleProductionWithPower))
                {
                    gui.BuildText("Production scaled with power");
                }
            }

            if (recipe.products.Length > 0 && !(recipe.products.Length == 1 && recipe.products[0].IsSimple && recipe.products[0].goods is Item && recipe.products[0].amount == 1f))
            {
                BuildSubHeader(gui, "Products");
                using (gui.EnterGroup(contentPadding))
                    foreach (var product in recipe.products)
                    {
                        BuildItem(gui, product);
                    }
            }

            BuildSubHeader(gui, "Made in");
            using (gui.EnterGroup(contentPadding))
                BuildIconRow(gui, recipe.crafters, 2);

            if (recipe.modules.Length > 0)
            {
                BuildSubHeader(gui, "Allowed modules");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, recipe.modules, 1);
            }

            if (recipe is Recipe lockedRecipe && !lockedRecipe.enabled)
            {
                BuildSubHeader(gui, "Unlocked by");
                using (gui.EnterGroup(contentPadding))
                {
                    if (lockedRecipe.technologyUnlock.Count > 2)
                    {
                        BuildIconRow(gui, lockedRecipe.technologyUnlock, 1);
                    }
                    else
                    {
                        foreach (var technology in lockedRecipe.technologyUnlock)
                        {
                            var ingredient = TechnologyScienceAnalysis.Instance.GetMaxTechnologyIngredient(technology);
                            using (gui.EnterRow(allocator: RectAllocator.RightRow))
                            {
                                gui.spacing = 0f;
                                if (ingredient != null)
                                {
                                    gui.BuildFactorioObjectIcon(ingredient.goods);
                                    gui.BuildText(DataUtils.FormatAmount(ingredient.amount, UnitOfMeasure.None));
                                }

                                gui.allocator = RectAllocator.RemainigRow;
                                gui.BuildFactorioObjectButtonWithText(technology);
                            }
                        }
                    }
                }
            }
        }
コード例 #6
0
        private void DrawRecipeEntry(ImGui gui, RecipeEntry entry, bool production)
        {
            var textcolor  = SchemeColor.BackgroundText;
            var bgColor    = SchemeColor.Background;
            var isBuilding = gui.isBuilding;
            var recipe     = entry.recipe;
            var waste      = recipe.RecipeWaste();

            if (isBuilding)
            {
                if (entry.entryStatus == EntryStatus.NotAccessible)
                {
                    bgColor   = SchemeColor.None;
                    textcolor = SchemeColor.BackgroundTextFaint;
                }
                else if (entry.flow > 0f)
                {
                    bgColor   = SchemeColor.Secondary;
                    textcolor = SchemeColor.SecondaryText;
                }
                else if (waste > 0.95f)
                {
                    bgColor   = SchemeColor.Error;
                    textcolor = SchemeColor.ErrorText;
                }
            }
            using (gui.EnterGroup(new Padding(0.5f), production ? RectAllocator.LeftRow : RectAllocator.RightRow, textcolor))
            {
                using (gui.EnterFixedPositioning(4f, 0f, default))
                {
                    gui.allocator = RectAllocator.Stretch;
                    gui.spacing   = 0f;
                    gui.BuildFactorioObjectButton(entry.recipe, 4f, MilestoneDisplay.Contained);
                    gui.BuildText(DataUtils.FormatAmount(recipe.Cost(), UnitOfMeasure.None, "¥"), align: RectAlignment.Middle);
                }
                gui.AllocateSpacing();
                gui.allocator = production ? RectAllocator.LeftAlign : RectAllocator.RightAlign;
                gui.BuildText(recipe.locName, wrap: true);
                if (recipe.ingredients.Length + recipe.products.Length <= 8)
                {
                    using (gui.EnterRow())
                    {
                        DrawIngredients(gui, entry.recipe);
                        gui.allocator = RectAllocator.RightRow;
                        DrawProducts(gui, entry.recipe);
                        if (recipe.products.Length < 3 && recipe.ingredients.Length < 5)
                        {
                            gui.AllocateSpacing((3 - entry.recipe.products.Length) * 3f);
                        }
                        else if (recipe.products.Length < 3)
                        {
                            gui.allocator = RectAllocator.RemainigRow;
                        }
                        gui.BuildIcon(Icon.ArrowRight, 3f);
                    }
                }
                else
                {
                    using (gui.EnterRow())
                        DrawIngredients(gui, entry.recipe);

                    using (gui.EnterRow())
                    {
                        gui.BuildIcon(Icon.ArrowDownRight, 3f);
                        gui.allocator = RectAllocator.RightRow;
                        DrawProducts(gui, entry.recipe);
                    }
                }
                var importance = CostAnalysis.Instance.GetBuildingAmount(recipe, entry.recipeFlow);
                if (importance != null)
                {
                    gui.BuildText(importance, wrap: true);
                }
            }

            if (isBuilding)
            {
                var rect = gui.lastRect;
                if (entry.flow > 0f)
                {
                    var percentFlow = MathUtils.Clamp(entry.flow / currentFlow, 0f, 1f);
                    rect.Width *= percentFlow;
                    gui.DrawRectangle(rect, SchemeColor.Primary);
                }
                else if (waste <= 0f)
                {
                    bgColor = SchemeColor.Secondary;
                }
                else
                {
                    rect.Width *= (1f - entry.recipe.RecipeWaste());
                    gui.DrawRectangle(rect, SchemeColor.Secondary);
                }
                gui.DrawRectangle(gui.lastRect, bgColor);
            }
        }
コード例 #7
0
        private void BuildRecipe(RecipeOrTechnology recipe, ImGui gui)
        {
            BuildCommon(recipe, gui);
            using (gui.EnterGroup(contentPadding, RectAllocator.LeftRow))
            {
                gui.BuildIcon(Icon.Time, 2f, SchemeColor.BackgroundText);
                gui.BuildText(recipe.time.ToString(CultureInfo.InvariantCulture));
            }

            using (gui.EnterGroup(contentPadding))
            {
                foreach (var ingredient in recipe.ingredients)
                {
                    BuildItem(gui, ingredient);
                }
                if (recipe is Recipe rec)
                {
                    var waste = rec.RecipeWaste();
                    if (waste > 0.01f)
                    {
                        var wasteAmount = MathUtils.Round(waste * 100f);
                        var wasteText   = ". (Wasting " + wasteAmount + "% of YAFC cost)";
                        var color       = wasteAmount < 90 ? SchemeColor.BackgroundText : SchemeColor.Error;
                        if (recipe.products.Length == 1)
                        {
                            gui.BuildText("YAFC analysis: There are better recipes to create " + recipe.products[0].goods.locName + wasteText, wrap: true, color: color);
                        }
                        else if (recipe.products.Length > 0)
                        {
                            gui.BuildText("YAFC analysis: There are better recipes to create each of the products" + wasteText, wrap: true, color: color);
                        }
                        else
                        {
                            gui.BuildText("YAFC analysis: This recipe wastes useful products. Don't do this recipe.", wrap: true, color: color);
                        }
                    }
                }
                if (recipe.flags.HasFlags(RecipeFlags.UsesFluidTemperature))
                {
                    gui.BuildText("Uses fluid temperature");
                }
                if (recipe.flags.HasFlags(RecipeFlags.UsesMiningProductivity))
                {
                    gui.BuildText("Uses mining productivity");
                }
                if (recipe.flags.HasFlags(RecipeFlags.ScaleProductionWithPower))
                {
                    gui.BuildText("Production scaled with power");
                }
            }

            if (recipe.products.Length > 0 && !(recipe.products.Length == 1 && recipe.products[0].rawAmount == 1 && recipe.products[0].goods is Item && recipe.products[0].probability == 1f))
            {
                BuildSubHeader(gui, "Products");
                using (gui.EnterGroup(contentPadding))
                    foreach (var product in recipe.products)
                    {
                        BuildItem(gui, product);
                    }
            }

            BuildSubHeader(gui, "Made in");
            using (gui.EnterGroup(contentPadding))
                BuildIconRow(gui, recipe.crafters, 2);

            if (recipe.modules.Length > 0)
            {
                BuildSubHeader(gui, "Allowed modules");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, recipe.modules, 1);
            }

            if (!recipe.enabled)
            {
                BuildSubHeader(gui, "Unlocked by");
                using (gui.EnterGroup(contentPadding))
                {
                    BuildIconRow(gui, recipe.technologyUnlock, 1);
                }
            }
        }
コード例 #8
0
        private void DrawRecipeEntry(ImGui gui, RecipeEntry entry, bool production)
        {
            var textcolor  = SchemeColor.BackgroundText;
            var bgColor    = SchemeColor.Background;
            var isBuilding = gui.isBuilding;
            var recipe     = entry.recipe;
            var waste      = recipe.RecipeWaste(atCurrentMilestones);

            if (isBuilding)
            {
                if (entry.entryStatus == EntryStatus.NotAccessible)
                {
                    bgColor   = SchemeColor.None;
                    textcolor = SchemeColor.BackgroundTextFaint;
                }
                else if (entry.flow > 0f)
                {
                    bgColor   = SchemeColor.Secondary;
                    textcolor = SchemeColor.SecondaryText;
                }
            }
            using (gui.EnterGroup(new Padding(0.5f), production ? RectAllocator.LeftRow : RectAllocator.RightRow, textcolor))
            {
                using (gui.EnterFixedPositioning(4f, 0f, default))
                {
                    gui.allocator = RectAllocator.Stretch;
                    gui.BuildFactorioObjectButton(entry.recipe, 4f, MilestoneDisplay.Contained);
                    using (gui.EnterRow())
                    {
                        gui.BuildIcon(Icon.Time);
                        gui.BuildText(DataUtils.FormatAmount(entry.recipe.time, UnitOfMeasure.Second), align: RectAlignment.Middle);
                    }
                    var bh = CostAnalysis.Instance.GetBuildingHours(recipe, entry.recipeFlow);
                    if (bh > 20)
                    {
                        gui.BuildText(DataUtils.FormatAmount(bh, UnitOfMeasure.None, suffix: "bh"), align: RectAlignment.Middle);
                        if (gui.BuildButton(gui.lastRect, SchemeColor.None, SchemeColor.Grey) == ImGuiUtils.Event.MouseOver)
                        {
                            gui.ShowTooltip(g => g.BuildText("Building-hours.\nAmount of building-hours required for all researches", wrap: true));
                        }
                    }
                }
                gui.AllocateSpacing();
                gui.allocator = production ? RectAllocator.LeftAlign : RectAllocator.RightAlign;
                gui.BuildText(recipe.locName, wrap: true);
                if (recipe.ingredients.Length + recipe.products.Length <= 8)
                {
                    using (gui.EnterRow())
                    {
                        DrawIngredients(gui, entry.recipe);
                        gui.allocator = RectAllocator.RightRow;
                        DrawProducts(gui, entry.recipe);
                        if (recipe.products.Length < 3 && recipe.ingredients.Length < 5)
                        {
                            gui.AllocateSpacing((3 - entry.recipe.products.Length) * 3f);
                        }
                        else if (recipe.products.Length < 3)
                        {
                            gui.allocator = RectAllocator.RemainigRow;
                        }
                        gui.BuildIcon(Icon.ArrowRight, 3f);
                    }
                }
                else
                {
                    using (gui.EnterRow())
                        DrawIngredients(gui, entry.recipe);

                    using (gui.EnterRow())
                    {
                        gui.BuildIcon(Icon.ArrowDownRight, 3f);
                        gui.allocator = RectAllocator.RightRow;
                        DrawProducts(gui, entry.recipe);
                    }
                }
            }

            if (isBuilding)
            {
                var rect = gui.lastRect;
                if (entry.flow > 0f)
                {
                    var percentFlow = MathUtils.Clamp(entry.flow / currentFlow, 0f, 1f);
                    rect.Width *= percentFlow;
                    gui.DrawRectangle(rect, SchemeColor.Primary);
                }
                else if (waste <= 0f)
                {
                    bgColor = SchemeColor.Secondary;
                }
                else
                {
                    rect.Width *= (1f - waste);
                    gui.DrawRectangle(rect, SchemeColor.Secondary);
                }
                gui.DrawRectangle(gui.lastRect, bgColor);
            }
        }