コード例 #1
0
        private void BuildRecipeMenu(ImGui gui, ref bool closed)
        {
            if (gui.BuildButton("Add recipe") && (closed = true))
            {
                SelectObjectPanel.Select(Database.recipes.all, "Select raw recipe", r => AddRecipe(model, r));
            }

            gui.BuildText("Export inputs and outputs to blueprint with constant combinators:", wrap: true);
            using (gui.EnterRow())
            {
                gui.BuildText("Amount per:");
                if (gui.BuildLink("second") && (closed = true))
                {
                    ExportIo(1f);
                }
                if (gui.BuildLink("minute") && (closed = true))
                {
                    ExportIo(60f);
                }
                if (gui.BuildLink("hour") && (closed = true))
                {
                    ExportIo(3600f);
                }
            }
        }
コード例 #2
0
        private void BuildCommon(FactorioObject target, ImGui gui)
        {
            BuildHeader(gui);
            using (gui.EnterGroup(contentPadding))
            {
                if (InputSystem.Instance.control)
                {
                    gui.BuildText(target.typeDotName);
                }

                if (target.locDescr != null)
                {
                    gui.BuildText(target.locDescr, wrap: true);
                }
                if (!target.IsAccessible())
                {
                    gui.BuildText("This " + target.type + " is inaccessible, or it is only accessible through mod or map script. Middle click to open dependency analyser to investigate.", wrap: true);
                }
                else if (!target.IsAutomatable())
                {
                    gui.BuildText("This " + target.type + " cannot be fully automated. This means that it requires either manual crafting, or manual labor such as cutting trees", wrap: true);
                }
                else
                {
                    gui.BuildText(CostAnalysis.GetDisplayCost(target), wrap: true);
                }
            }
        }
コード例 #3
0
        private void DrawEntryList(ImGui gui, List <RecipeEntry> entries, bool production)
        {
            var            footerDrawn         = false;
            var            prevEntryStatus     = EntryStatus.Normal;
            FactorioObject prevLatestMilestone = null;

            foreach (var entry in entries)
            {
                var status = entry.entryStatus;

                if (status < showRecipesRange)
                {
                    DrawEntryFooter(gui, production);
                    footerDrawn = true;
                    gui.BuildText(entry.entryStatus == EntryStatus.Special ? "Show special recipes (barreling / voiding)" :
                                  entry.entryStatus == EntryStatus.NotAccessibleWithCurrentMilestones ? "There are more recipes, but they are locked based on current milestones" :
                                  "There are more recipes but they are inaccessible", wrap: true);
                    if (gui.BuildButton("Show more recipes"))
                    {
                        ChangeShowStatus(status);
                    }
                    break;
                }

                if (status < prevEntryStatus)
                {
                    prevEntryStatus = status;
                    using (gui.EnterRow())
                    {
                        gui.BuildText(status == EntryStatus.Special ? "Special recipes:" : status == EntryStatus.NotAccessibleWithCurrentMilestones ? "Locked recipes:" : "Inaccessible recipes:");
                        if (gui.BuildLink("hide"))
                        {
                            ChangeShowStatus(status + 1);
                        }
                    }
                }

                if (status == EntryStatus.NotAccessibleWithCurrentMilestones)
                {
                    var latest = Milestones.Instance.GetHighest(entry.recipe, false);
                    if (latest != prevLatestMilestone)
                    {
                        gui.BuildFactorioObjectButtonWithText(latest, size: 3f, display: MilestoneDisplay.None);
                        prevLatestMilestone = latest;
                    }
                }

                if (gui.ShouldBuildGroup(entry.recipe, out var group))
                {
                    DrawRecipeEntry(gui, entry, production);
                    group.Complete();
                }
            }
            if (!footerDrawn)
            {
                DrawEntryFooter(gui, production);
            }
            CheckChanging();
        }
コード例 #4
0
        private void BuildBeltInserterInfo(ImGui gui, float amount, float buildingCount, ref bool closed)
        {
            var prefs    = Project.current.preferences;
            var belt     = prefs.defaultBelt;
            var inserter = prefs.defaultInserter;

            if (belt == null || inserter == null)
            {
                return;
            }

            var beltCount            = amount / belt.beltItemsPerSecond;
            var buildingsPerHalfBelt = belt.beltItemsPerSecond * buildingCount / (amount * 2f);
            var click = false;

            using (gui.EnterRow())
            {
                click |= gui.BuildFactorioObjectButton(belt);
                gui.BuildText(DataUtils.FormatAmount(beltCount, UnitOfMeasure.None));
                if (buildingsPerHalfBelt > 0f)
                {
                    gui.BuildText("(Buildings per half belt: " + DataUtils.FormatAmount(buildingsPerHalfBelt, UnitOfMeasure.None) + ")");
                }
            }

            using (gui.EnterRow())
            {
                var capacity     = prefs.inserterCapacity;
                var inserterBase = inserter.inserterSwingTime * amount / capacity;
                click |= gui.BuildFactorioObjectButton(inserter);
                var text = DataUtils.FormatAmount(inserterBase, UnitOfMeasure.None);
                if (buildingCount > 1)
                {
                    text += " (" + DataUtils.FormatAmount(inserterBase / buildingCount, UnitOfMeasure.None) + "/building)";
                }
                gui.BuildText(text);
                if (capacity > 1)
                {
                    var withBeltSwingTime = inserter.inserterSwingTime + 2f * (capacity - 1.5f) / belt.beltItemsPerSecond;
                    var inserterToBelt    = amount * withBeltSwingTime / capacity;
                    click |= gui.BuildFactorioObjectButton(belt);
                    gui.AllocateSpacing(-1.5f);
                    click |= gui.BuildFactorioObjectButton(inserter);
                    text   = DataUtils.FormatAmount(inserterToBelt, UnitOfMeasure.None, "~");
                    if (buildingCount > 1)
                    {
                        text += " (" + DataUtils.FormatAmount(inserterToBelt / buildingCount, UnitOfMeasure.None) + "/b)";
                    }
                    gui.BuildText(text);
                }
            }

            if (click)
            {
                PreferencesScreen.Show();
                closed = true;
            }
        }
コード例 #5
0
        private void BuildIconRow(ImGui gui, IReadOnlyList <FactorioObject> objects, int maxRows)
        {
            const int itemsPerRow = 9;
            var       count       = objects.Count;

            if (count == 0)
            {
                gui.BuildText("Nothing", color: SchemeColor.BackgroundTextFaint);
                return;
            }

            var arr = new List <FactorioObject>(count);

            arr.AddRange(objects);
            arr.Sort(DataUtils.DefaultOrdering);

            if (count <= maxRows)
            {
                for (var i = 0; i < count; i++)
                {
                    gui.BuildFactorioObjectButtonWithText(arr[i]);
                }
                return;
            }

            var index = 0;

            if (count - 1 < (maxRows - 1) * itemsPerRow)
            {
                gui.BuildFactorioObjectButtonWithText(arr[0]);
                index++;
            }

            var rows = Math.Min(((count - 1 - index) / itemsPerRow) + 1, maxRows);

            for (var i = 0; i < rows; i++)
            {
                using (gui.EnterRow())
                {
                    for (var j = 0; j < itemsPerRow; j++)
                    {
                        if (arr.Count <= index)
                        {
                            return;
                        }
                        gui.BuildFactorioObjectIcon(arr[index++]);
                    }
                }
            }

            if (rows * itemsPerRow < count)
            {
                gui.BuildText("... and " + (count - rows * itemsPerRow) + " more");
            }
        }
コード例 #6
0
        public override void Build(ImGui gui)
        {
            BuildHeader(gui, header);
            var valid = true;

            pages[page](gui, ref valid);
            using (gui.EnterRow(allocator: RectAllocator.RightRow))
            {
                if (gui.BuildButton(page >= pages.Count - 1 ? "Finish" : "Next", active: valid))
                {
                    if (page < pages.Count - 1)
                    {
                        page++;
                    }
                    else
                    {
                        Close();
                        finish();
                    }
                }
                if (page > 0 && gui.BuildButton("Previous"))
                {
                    page--;
                }
                gui.BuildText("Step " + (page + 1) + " of " + pages.Count);
            }
        }
コード例 #7
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);
     }
 }
コード例 #8
0
 public override void Build(ImGui gui)
 {
     BuildHeader(gui, "Milestone editor");
     milestoneList.Build(gui);
     gui.BuildText(
         "Hint: You can reorder milestones. When an object is locked behind a milestone, the first inaccessible milestone will be shown. Also when there is a choice between different milestones, first will be chosen",
         wrap: true, color: SchemeColor.BackgroundTextFaint);
     using (gui.EnterRow())
     {
         if (gui.BuildButton("Auto sort milestones", SchemeColor.Grey))
         {
             var collector = new ErrorCollector();
             Milestones.Instance.ComputeWithParameters(Project.current, collector, Project.current.settings.milestones.ToArray(), true);
             if (collector.severity > ErrorSeverity.None)
             {
                 ErrorListPanel.Show(collector);
             }
             milestoneList.RebuildContents();
         }
         if (gui.BuildButton("Add milestone"))
         {
             if (Project.current.settings.milestones.Count >= 60)
             {
                 MessageBox.Show(null, "Milestone limit reached", "60 milestones is the limit. You may delete some of the milestones you've already reached.", "Ok");
             }
             else
             {
                 SelectObjectPanel.Select(Database.objects.all, "Add new milestone", AddMilestone);
             }
         }
     }
 }
コード例 #9
0
        public override void Build(ImGui gui)
        {
            BuildHeader(gui, "Never Enough Items Explorer");
            using (gui.EnterRow())
            {
                if (recent.Count == 0)
                {
                    gui.AllocateRect(0f, 3f);
                }
                for (var i = recent.Count - 1; i >= 0; i--)
                {
                    var elem = recent[i];
                    if (gui.BuildFactorioObjectButton(elem, 3f))
                    {
                        changing = elem;
                    }
                }
            }
            using (gui.EnterGroup(new Padding(0.5f), RectAllocator.LeftRow))
            {
                gui.spacing = 0.2f;
                gui.BuildFactorioObjectIcon(current, size: 3f);
                gui.BuildText(current.locName, Font.subheader);
                gui.allocator = RectAllocator.RightAlign;
                gui.BuildText(CostAnalysis.GetDisplayCost(current));
                var amount = CostAnalysis.Instance.GetItemAmount(current);
                if (amount != null)
                {
                    gui.BuildText(amount, wrap: true);
                }
            }

            if (gui.BuildFactorioObjectButton(gui.lastRect, current, SchemeColor.Grey))
            {
                SelectObjectPanel.Select(Database.goods.all, "Select item", SetItem);
            }

            using (var split = gui.EnterHorizontalSplit(2))
            {
                split.Next();
                gui.BuildText("Production:", Font.subheader);
                productionList.Build(gui);
                split.Next();
                gui.BuildText("Usages:", Font.subheader);
                usageList.Build(gui);
            }
            CheckChanging();
            using (gui.EnterRow())
            {
                gui.BuildText("Legend:");
                gui.BuildText("This color is flow (Estimated fraction of item production/consumption)");
                gui.DrawRectangle(gui.lastRect, SchemeColor.Primary);
                gui.BuildText("This color is estimated recipe efficiency");
                gui.DrawRectangle(gui.lastRect, SchemeColor.Secondary);
            }
        }
コード例 #10
0
 private void BuildItem(ImGui gui, IFactorioObjectWrapper item)
 {
     using (gui.EnterRow())
     {
         gui.BuildFactorioObjectIcon(item.target);
         gui.BuildText(item.text, wrap: true);
     }
 }
コード例 #11
0
 private void BuildSubHeader(ImGui gui, string text)
 {
     using (gui.EnterGroup(contentPadding))
         gui.BuildText(text, Font.subheader);
     if (gui.isBuilding)
     {
         gui.DrawRectangle(gui.lastRect, SchemeColor.Grey);
     }
 }
コード例 #12
0
        public override void Build(ImGui gui)
        {
            BuildHeader(gui, "Units of measure");
            gui.BuildText("Unit of time:", Font.subheader);
            var prefs = Project.current.preferences;

            using (gui.EnterRow())
            {
                if (gui.BuildRadioButton("Second", prefs.time == 1))
                {
                    prefs.RecordUndo(true).time = 1;
                }
                if (gui.BuildRadioButton("Minute", prefs.time == 60))
                {
                    prefs.RecordUndo(true).time = 60;
                }
                if (gui.BuildRadioButton("Hour", prefs.time == 3600))
                {
                    prefs.RecordUndo(true).time = 3600;
                }
                if (gui.BuildRadioButton("Custom", prefs.time != 1 && prefs.time != 60 && prefs.time != 3600))
                {
                    prefs.RecordUndo(true).time = 0;
                }
                if (gui.BuildTextInput(prefs.time.ToString(), out var newTime, null, delayed: true) && int.TryParse(newTime, out var parsed))
                {
                    prefs.RecordUndo(true).time = parsed;
                }
            }
            gui.AllocateSpacing(1f);
            gui.BuildText("Item production/consumption:", Font.subheader);
            BuildUnitPerTime(gui, false, prefs);
            gui.BuildText("Fluid production/consumption:", Font.subheader);
            BuildUnitPerTime(gui, true, prefs);
            if (gui.BuildButton("Done"))
            {
                Close();
            }
            if (prefs.justChanged)
            {
                MainScreen.Instance.RebuildProjectView();
            }
        }
コード例 #13
0
        private void BuildUnitPerTime(ImGui gui, bool fluid, ProjectPreferences preferences)
        {
            var unit    = fluid ? preferences.fluidUnit : preferences.itemUnit;
            var newUnit = unit;

            if (gui.BuildRadioButton("Simple Amount" + preferences.GetPerTimeUnit().suffix, unit == 0f))
            {
                newUnit = 0f;
            }
            using (gui.EnterRow())
            {
                if (gui.BuildRadioButton("Custom: 1 unit equals", unit != 0f))
                {
                    newUnit = 1f;
                }
                gui.AllocateSpacing();
                gui.allocator = RectAllocator.RightRow;
                if (!fluid)
                {
                    if (gui.BuildButton("Set from belt"))
                    {
                        gui.ShowDropDown((ImGui dropGui, ref bool closed) =>
                        {
                            closed = dropGui.BuildInlineObejctListAndButton <Entity>(Database.entities.all.Where(x => x.beltItemsPerSecond > 0f).ToArray(), DataUtils.DefaultOrdering, setBelt =>
                            {
                                preferences.RecordUndo(true);
                                preferences.itemUnit = setBelt.beltItemsPerSecond;
                            }, "Select belt", extra: b => DataUtils.FormatAmount(b.beltItemsPerSecond, UnitOfMeasure.PerSecond));
                            gui.Rebuild();
                        });
                    }
                }
                gui.BuildText("per second");
                if (gui.BuildTextInput(DataUtils.FormatAmount(unit, UnitOfMeasure.None), out var updated, null, Icon.None, true) &&
                    DataUtils.TryParseAmount(updated, out var parsed, UnitOfMeasure.None))
                {
                    newUnit = parsed;
                }
            }
            gui.AllocateSpacing(1f);

            if (newUnit != unit)
            {
                preferences.RecordUndo(true);
                if (fluid)
                {
                    preferences.fluidUnit = newUnit;
                }
                else
                {
                    preferences.itemUnit = newUnit;
                }
            }
        }
コード例 #14
0
 private void ChoiceObject <T>(ImGui gui, string text, T[] list, T current, Action <T> select) where T : FactorioObject
 {
     using (gui.EnterRow())
     {
         gui.BuildText(text, topOffset: 0.5f);
         if (gui.BuildFactorioObjectButtonWithText(current))
         {
             gui.BuildObjectSelectDropDown(list, DataUtils.DefaultOrdering, select, text);
         }
     }
 }
コード例 #15
0
        public override void Build(ImGui gui)
        {
            BuildHeader(gui, "Module customisation");
            if (recipe.modules == null)
            {
                if (gui.BuildButton("Enable custom modules"))
                {
                    recipe.RecordUndo().modules = new CustomModules(recipe);
                }
            }
            else
            {
                gui.BuildText("Internal modules:", Font.subheader);
                gui.BuildText("Leave zero amount to fill the remainings slots");
                DrawRecipeModules(gui, null);
                gui.BuildText("Beacon modules:", Font.subheader);
                if (recipe.modules.beacon == null)
                {
                    gui.BuildText("Use default parameters");
                    if (gui.BuildButton("Override beacons as well"))
                    {
                        gui.ShowDropDown(SelectBeacon);
                    }
                }
                else
                {
                    if (gui.BuildFactorioObjectButtonWithText(recipe.modules.beacon))
                    {
                        gui.ShowDropDown(SelectBeacon);
                    }
                    gui.BuildText("Input the amount of modules, not the amount of beacons. Single beacon can hold " + recipe.modules.beacon.moduleSlots + " modules.", wrap: true);
                    DrawRecipeModules(gui, recipe.modules.beacon);
                }
            }

            gui.AllocateSpacing(3f);
            if (gui.BuildButton("Done"))
            {
                Close();
            }
        }
コード例 #16
0
 private void BuildModulesMenu(ImGui gui, ref bool closed)
 {
     if (model.modules == null)
     {
         model.RecordUndo(true).modules = new ModuleFillerParameters(model);
     }
     gui.BuildText("Auto modules", Font.subheader);
     ModuleFillerParametersScreen.BuildSimple(gui, model.modules);
     if (gui.BuildButton("More settings"))
     {
         ModuleFillerParametersScreen.Show(model.modules);
         closed = true;
     }
 }
コード例 #17
0
 public override void Build(ImGui gui)
 {
     gui.spacing = 1f;
     BuildHeader(gui, "Milestones");
     gui.BuildText("Please select objects that you already have access to:");
     gui.AllocateSpacing(2f);
     MilestonesWidget.Instance.Build(gui);
     gui.AllocateSpacing(2f);
     gui.BuildText("For your convinience, YAFC will show objects you DON'T have access to based on this selection", wrap: true);
     gui.BuildText("These are called 'Milestones'. By default all science packs are added as milestones, but this does not have to be this way! " +
                   "You can define your own milestones: Any item, recipe, entity or technology may be added as a milestone. For example you can add advanced " +
                   "electronic circuits as a milestone, and YAFC will display everything that is locked behind those circuits", wrap: true);
     using (gui.EnterRow())
     {
         if (gui.BuildButton("Edit milestones", SchemeColor.Grey))
         {
             MilestonesEditor.Show();
         }
         if (gui.RemainingRow().BuildButton("Done"))
         {
             Close();
         }
     }
 }
コード例 #18
0
        public static void BuildSimple(ImGui gui, ModuleFillerParameters modules)
        {
            var payback    = modules.autoFillPayback;
            var modulesLog = MathUtils.LogarithmicToLinear(payback, ModulesMinPayback, ModulesMaxPayback);

            if (gui.BuildSlider(modulesLog, out var newValue))
            {
                payback = MathUtils.LinearToLogarithmic(newValue, ModulesMinPayback, ModulesMaxPayback, 0f, float.MaxValue); // JSON can't handle infinities
                modules.RecordUndo().autoFillPayback = payback;
            }

            if (payback <= 0f)
            {
                gui.BuildText("Use no modules");
            }
            else if (payback >= float.MaxValue)
            {
                gui.BuildText("Use best modules");
            }
            else
            {
                gui.BuildText("Modules payback estimate: " + DataUtils.FormatTime(payback), wrap: true);
            }
        }
コード例 #19
0
 protected void BuildHeader(ImGui gui, string text, bool closeButton = true)
 {
     gui.BuildText(text, Font.header, false, RectAlignment.Middle);
     if (closeButton)
     {
         var closeButtonRect = new Rect(width - 3f, 0f, 3f, 2f);
         if (gui.isBuilding)
         {
             var isOver            = gui.IsMouseOver(closeButtonRect);
             var closeButtonCenter = Rect.Square(closeButtonRect.Center, 1f);
             gui.DrawIcon(closeButtonCenter, Icon.Close, isOver ? SchemeColor.ErrorText : SchemeColor.BackgroundText);
         }
         if (gui.BuildButton(closeButtonRect, SchemeColor.None, SchemeColor.Error) == ImGuiUtils.Event.Click)
         {
             Close(false);
         }
     }
 }
コード例 #20
0
 public override void Build(ImGui gui)
 {
     BuildHeader(gui, "Milestone editor");
     milestoneList.Build(gui);
     gui.BuildText(
         "Hint: You can reorder milestones. When an object is locked behind a milestone, the first inaccessible milestone will be shown. Also when there is a choice between different milestones, first will be chosen",
         wrap: true, color: SchemeColor.BackgroundTextFaint);
     if (gui.BuildButton("Add milestone"))
     {
         if (Project.current.settings.milestones.Count >= 60)
         {
             MessageBox.Show(null, "Milestone limit reached", "60 milestones is the limit. You may delete some of the milestones you've already reached.", "Ok");
         }
         else
         {
             SelectObjectPanel.Select(Database.objects.all, "Add new milestone", AddMilestone);
         }
     }
 }
コード例 #21
0
        private void BuildRecipeName(ImGui gui, RecipeRow recipe)
        {
            gui.spacing = 0.5f;
            if (gui.BuildFactorioObjectButton(recipe.recipe, 3f))
            {
                gui.ShowDropDown(delegate(ImGui imgui, ref bool closed)
                {
                    if (recipe.subgroup == null && imgui.BuildButton("Create nested table"))
                    {
                        recipe.RecordUndo().subgroup = new ProductionTable(recipe);
                        closed = true;
                    }

                    if (recipe.subgroup != null && imgui.BuildButton("Unpack nested table"))
                    {
                        var evacuate = recipe.subgroup.recipes;
                        recipe.subgroup.RecordUndo();
                        recipe.RecordUndo().subgroup = null;
                        var index = recipe.owner.recipes.IndexOf(recipe);
                        foreach (var evacRecipe in evacuate)
                        {
                            evacRecipe.SetOwner(recipe.owner);
                        }
                        recipe.owner.RecordUndo().recipes.InsertRange(index + 1, evacuate);
                        closed = true;
                    }

                    if (recipe.subgroup != null && imgui.BuildRedButton("Remove nested table") == ImGuiUtils.Event.Click)
                    {
                        recipe.owner.RecordUndo().recipes.Remove(recipe);
                        closed = true;
                    }

                    if (recipe.subgroup == null && imgui.BuildRedButton("Delete recipe") == ImGuiUtils.Event.Click)
                    {
                        recipe.owner.RecordUndo().recipes.Remove(recipe);
                        closed = true;
                    }
                });
            }
            gui.BuildText(recipe.recipe.locName, wrap: true);
        }
コード例 #22
0
 private void MilestoneDrawer(ImGui gui, FactorioObject element, int index)
 {
     using (gui.EnterRow())
     {
         var settings = Project.current.settings;
         gui.BuildFactorioObjectIcon(element, MilestoneDisplay.None, 3f);
         gui.BuildText(element.locName);
         gui.allocator = RectAllocator.RightRow;
         if (gui.BuildButton(Icon.Close, size: 1f))
         {
             settings.RecordUndo().milestones.Remove(element);
             Rebuild();
             milestoneList.data = settings.milestones;
         }
     }
     if (gui.DoListReordering(gui.lastRect, gui.lastRect, index, out var moveFrom))
     {
         Project.current.settings.RecordUndo().milestones.MoveListElementIndex(moveFrom, index);
     }
 }
コード例 #23
0
 private void DrawEntryList(ImGui gui, List <RecipeEntry> entries, bool production)
 {
     foreach (var entry in entries)
     {
         if (entry.entryStatus < showRecipesRange)
         {
             gui.BuildText(entry.entryStatus == EntryStatus.Wasteful ? "There are more recipes, but they are wasteful" :
                           entry.entryStatus == EntryStatus.NotAccessibleWithCurrentMilestones ? "There are more recipes, but they are locked based on current milestones" :
                           "There are more recipes but they are inaccessible", wrap: true);
             if (gui.BuildButton("Show more recipes"))
             {
                 showRecipesRange = entry.entryStatus;
                 Rebuild();
             }
             break;
         }
         DrawRecipeEntry(gui, entry, production);
     }
     CheckChanging();
 }
コード例 #24
0
 public override void Build(ImGui gui)
 {
     BuildHeader(gui, title);
     if (message != null)
     {
         gui.BuildText(message, wrap: true);
     }
     gui.AllocateSpacing(2f);
     using (gui.EnterRow(allocator: RectAllocator.RightRow))
     {
         if (gui.BuildButton(yes))
         {
             CloseWithResult(true);
         }
         if (no != null && gui.BuildButton(no, SchemeColor.Grey))
         {
             CloseWithResult(false);
         }
     }
 }
コード例 #25
0
        private void BuildTechnology(Technology technology, ImGui gui)
        {
            BuildRecipe(technology, gui);
            if (technology.hidden && !technology.enabled)
            {
                using (gui.EnterGroup(contentPadding))
                    gui.BuildText("This technology is hidden from the list and cannot be researched.", wrap: true);
            }

            if (technology.prerequisites.Length > 0)
            {
                BuildSubHeader(gui, "Prerequisites");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, technology.prerequisites, 1);
            }

            if (technology.unlockRecipes.Length > 0)
            {
                BuildSubHeader(gui, "Unlocks recipes");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, technology.unlockRecipes, 2);
            }

            var packs = TechnologyScienceAnalysis.Instance.allSciencePacks[technology];

            if (packs.Length > 0)
            {
                BuildSubHeader(gui, "Total science required");
                using (gui.EnterGroup(contentPadding))
                {
                    using (var grid = gui.EnterInlineGrid(3f))
                    {
                        foreach (var pack in packs)
                        {
                            grid.Next();
                            gui.BuildFactorioObjectWithAmount(pack.goods, pack.amount, UnitOfMeasure.None);
                        }
                    }
                }
            }
        }
コード例 #26
0
 private void DrawEntryFooter(ImGui gui, bool production)
 {
     if (!production && current.fuelFor.Length > 0)
     {
         using (gui.EnterGroup(new Padding(0.5f), RectAllocator.LeftAlign))
         {
             gui.BuildText(current.fuelValue > 0f ? "Fuel value " + DataUtils.FormatAmount(current.fuelValue, UnitOfMeasure.Megajoule) + " can be used for:" : "Can be used to fuel:");
             using (var grid = gui.EnterInlineGrid(3f))
             {
                 foreach (var fuelUsage in current.fuelFor)
                 {
                     grid.Next();
                     gui.BuildFactorioObjectButton(fuelUsage, 3f, MilestoneDisplay.Contained);
                 }
             }
         }
         if (gui.isBuilding)
         {
             gui.DrawRectangle(gui.lastRect, SchemeColor.Primary);
         }
     }
 }
コード例 #27
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);
            }
        }
コード例 #28
0
        private void BuildGoods(Goods goods, ImGui gui)
        {
            BuildCommon(goods, gui);
            using (gui.EnterGroup(contentPadding))
                gui.BuildText("Middle mouse button to open Never Enough Items Explorer for this " + goods.type, wrap: true);
            if (goods.production.Length > 0)
            {
                BuildSubHeader(gui, "Made with");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, goods.production, 2);
            }

            if (goods.miscSources.Length > 0)
            {
                BuildSubHeader(gui, "Sources");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, goods.miscSources, 2);
            }

            if (goods.usages.Length > 0)
            {
                BuildSubHeader(gui, "Needs for");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, goods.usages, 4);
            }

            if (goods.fuelFor.Length > 0)
            {
                if (goods.fuelValue > 0f)
                {
                    BuildSubHeader(gui, "Fuel value " + DataUtils.FormatAmount(goods.fuelValue, UnitOfMeasure.Megajoule) + " used for:");
                }
                else
                {
                    BuildSubHeader(gui, "Can be used as fuel for:");
                }
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, goods.fuelFor, 2);
            }

            if (goods is Item item)
            {
                if (goods.fuelValue > 0f && item.fuelResult != null)
                {
                    using (gui.EnterGroup(contentPadding))
                        BuildItem(gui, item.fuelResult);
                }
                if (item.placeResult != null)
                {
                    BuildSubHeader(gui, "Place result");
                    using (gui.EnterGroup(contentPadding))
                        BuildItem(gui, item.placeResult);
                }

                if (item.module != null)
                {
                    BuildSubHeader(gui, "Module parameters");
                    using (gui.EnterGroup(contentPadding))
                    {
                        if (item.module.productivity != 0f)
                        {
                            gui.BuildText(DataUtils.FormatAmount(item.module.productivity, UnitOfMeasure.Percent, "Productivity: "));
                        }
                        if (item.module.speed != 0f)
                        {
                            gui.BuildText(DataUtils.FormatAmount(item.module.speed, UnitOfMeasure.Percent, "Speed: "));
                        }
                        if (item.module.consumption != 0f)
                        {
                            gui.BuildText(DataUtils.FormatAmount(item.module.consumption, UnitOfMeasure.Percent, "Consumption: "));
                        }
                        if (item.module.pollution != 0f)
                        {
                            gui.BuildText(DataUtils.FormatAmount(item.module.consumption, UnitOfMeasure.Percent, "Pollution: "));
                        }
                    }
                    if (item.module.limitation != null)
                    {
                        BuildSubHeader(gui, "Module limitation");
                        using (gui.EnterGroup(contentPadding))
                            BuildIconRow(gui, item.module.limitation, 2);
                    }
                }

                using (gui.EnterGroup(contentPadding))
                    gui.BuildText("Stack size: " + item.stackSize);
            }
        }
コード例 #29
0
        private void BuildEntity(Entity entity, ImGui gui)
        {
            BuildCommon(entity, gui);

            if (entity.loot.Length > 0)
            {
                BuildSubHeader(gui, "Loot");
                using (gui.EnterGroup(contentPadding))
                {
                    foreach (var product in entity.loot)
                    {
                        BuildItem(gui, product);
                    }
                }
            }

            if (entity.mapGenerated)
            {
                using (gui.EnterGroup(contentPadding))
                    gui.BuildText("Generates on map (estimated density: " + (entity.mapGenDensity <= 0f ? "unknown" : DataUtils.FormatAmount(entity.mapGenDensity, UnitOfMeasure.None)) + ")", wrap: true);
            }

            if (!entity.recipes.empty)
            {
                BuildSubHeader(gui, "Crafts");
                using (gui.EnterGroup(contentPadding))
                {
                    BuildIconRow(gui, entity.recipes, 2);
                    if (entity.craftingSpeed != 1f)
                    {
                        gui.BuildText(DataUtils.FormatAmount(entity.craftingSpeed, UnitOfMeasure.Percent, "Crafting speed: "));
                    }
                    if (entity.productivity != 0f)
                    {
                        gui.BuildText(DataUtils.FormatAmount(entity.productivity, UnitOfMeasure.Percent, "Crafting productivity: "));
                    }
                    if (entity.allowedEffects != AllowedEffects.None)
                    {
                        gui.BuildText("Module slots: " + entity.moduleSlots);
                        if (entity.allowedEffects != AllowedEffects.All)
                        {
                            gui.BuildText("Only allowed effects: " + entity.allowedEffects, wrap: true);
                        }
                    }
                }
            }

            if (entity.inputs != null)
            {
                BuildSubHeader(gui, "Allowed inputs:");
                using (gui.EnterGroup(contentPadding))
                    BuildIconRow(gui, entity.inputs, 2);
            }

            if (entity.energy != null)
            {
                BuildSubHeader(gui, EnergyDescriptions[entity.energy.type] + DataUtils.FormatAmount(entity.power, UnitOfMeasure.Megawatt));
                using (gui.EnterGroup(contentPadding))
                {
                    if (entity.energy.type == EntityEnergyType.FluidFuel || entity.energy.type == EntityEnergyType.SolidFuel || entity.energy.type == EntityEnergyType.FluidHeat)
                    {
                        BuildIconRow(gui, entity.energy.fuels, 2);
                    }
                    if (entity.energy.emissions != 0f)
                    {
                        var emissionColor = SchemeColor.BackgroundText;
                        if (entity.energy.emissions < 0f)
                        {
                            emissionColor = SchemeColor.Green;
                            gui.BuildText("This building absorbs pollution", color: emissionColor);
                        }
                        else if (entity.energy.emissions >= 20f)
                        {
                            emissionColor = SchemeColor.Error;
                            gui.BuildText("This building contributes to global warning!", color: emissionColor);
                        }
                        gui.BuildText("Emissions: " + DataUtils.FormatAmount(entity.energy.emissions, UnitOfMeasure.None), color: emissionColor);
                    }
                }
            }

            string miscText = null;

            switch (entity)
            {
            case EntityBelt belt:
                miscText = "Belt throughput (Items): " + DataUtils.FormatAmount(belt.beltItemsPerSecond, UnitOfMeasure.PerSecond);
                break;

            case EntityInserter inserter:
                miscText = "Swing time: " + DataUtils.FormatAmount(inserter.inserterSwingTime, UnitOfMeasure.Second);
                break;

            case EntityBeacon beacon:
                miscText = "Beacon efficiency: " + DataUtils.FormatAmount(beacon.beaconEfficiency, UnitOfMeasure.Percent);
                break;

            case EntityAccumulator accumulator:
                miscText = "Accumulator charge: " + DataUtils.FormatAmount(accumulator.accumulatorCapacity, UnitOfMeasure.Megajoule);
                break;

            default:
            {
                if (entity.craftingSpeed > 0f && entity.factorioType == "solar-panel")
                {
                    miscText = "Power production (average): " + DataUtils.FormatAmount(entity.craftingSpeed, UnitOfMeasure.Megawatt);
                }
                break;
            }
            }

            if (miscText != null)
            {
                using (gui.EnterGroup(contentPadding))
                    gui.BuildText(miscText);
            }
        }
コード例 #30
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);
                            }
                        }
                    }
                }
            }
        }