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); } }
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); } } } }
private void BuildEntityMenu(ImGui gui, ref bool closed) { if (gui.BuildButton("Mass set assembler") && (closed = true)) { SelectObjectPanel.Select(Database.entities.all.Where(x => x.recipes.Count > 0), "Set assembler for all recipes", set => { DataUtils.FavouriteCrafter.AddToFavourite(set, 10); foreach (var recipe in GetRecipesRecursive()) { if (recipe.recipe.crafters.Contains(set)) { recipe.RecordUndo().entity = set; if (!set.energy.fuels.Contains(recipe.fuel)) { recipe.fuel = recipe.entity.energy.fuels.AutoSelect(DataUtils.FavouriteFuel); } } } }, DataUtils.FavouriteCrafter, false); } if (gui.BuildButton("Mass set fuel") && (closed = true)) { SelectObjectPanel.Select(Database.goods.all.Where(x => x.fuelValue > 0), "Set fuel for all recipes", set => { DataUtils.FavouriteFuel.AddToFavourite(set, 10); foreach (var recipe in GetRecipesRecursive()) { if (recipe.entity != null && recipe.entity.energy.fuels.Contains(set)) { recipe.RecordUndo().fuel = set; } } }, DataUtils.FavouriteFuel, false); } if (gui.BuildButton("Shopping list") && (closed = true)) { var shopList = new Dictionary <FactorioObject, int>(); foreach (var recipe in GetRecipesRecursive()) { if (recipe.entity != null) { shopList.TryGetValue(recipe.entity, out var prev); var count = MathUtils.Ceil(recipe.buildingCount); shopList[recipe.entity] = prev + count; if (recipe.parameters.modules.module != null) { shopList.TryGetValue(recipe.parameters.modules.module, out prev); shopList[recipe.parameters.modules.module] = prev + count * recipe.parameters.modules.count; } } } ShoppingListScreen.Show(shopList); } }
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 } }
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); } } }
public static bool BuildFactorioObjectButton(this ImGui gui, Rect rect, FactorioObject obj, SchemeColor bgColor = SchemeColor.None, bool extendHeader = false) { var overColor = bgColor == SchemeColor.None ? SchemeColor.Grey : bgColor + 1; var evt = gui.BuildButton(rect, bgColor, overColor, button: 0); if (evt == ImGuiUtils.Event.MouseOver && obj != null) { MainScreen.Instance.ShowTooltip(obj, gui, rect, extendHeader); } else if (evt == ImGuiUtils.Event.Click) { if (gui.actionParameter == SDL.SDL_BUTTON_MIDDLE && obj != null) { if (obj is Goods goods && obj.IsAccessible()) { NeverEnoughItemsPanel.Show(goods, null); } else { DependencyExplorer.Show(obj); } } else if (gui.actionParameter == SDL.SDL_BUTTON_LEFT) { return(true); } }
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(); }
public override void Build(ImGui gui) { gui.spacing = 3f; BuildHeader(gui, editingPage == null ? "Create new page" : "Edit page icon and name"); Build(gui, ref name, icon, s => { icon = s; Rebuild(); }); using (gui.EnterRow(0.5f, RectAllocator.RightRow)) { if (editingPage == null && gui.BuildButton("Create", active: !string.IsNullOrEmpty(name))) { callback?.Invoke(name, icon); Close(); } if (editingPage != null && gui.BuildButton("OK", active: !string.IsNullOrEmpty(name))) { if (editingPage.name != name || editingPage.icon != icon) { editingPage.RecordUndo(true).name = name; editingPage.icon = icon; } Close(); } if (gui.BuildButton("Cancel", SchemeColor.Grey)) { Close(); } if (editingPage != null && gui.BuildButton("Other tools", SchemeColor.Grey, active: !string.IsNullOrEmpty(name))) { gui.ShowDropDown(OtherToolsDropdown); } gui.allocator = RectAllocator.LeftRow; if (editingPage != null && gui.BuildRedButton("Delete page") == ImGuiUtils.Event.Click) { Project.current.RecordUndo().pages.Remove(editingPage); Close(); } } }
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); } } }
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; } } }
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(); } }
private void BuildEntityMenu(ImGui gui, ref bool closed) { if (gui.BuildButton("Mass set assembler") && (closed = true)) { SelectObjectPanel.Select(Database.entities.all.Where(x => x.recipes.Count > 0), "Set assembler for all recipes", set => { DataUtils.FavouriteCrafter.AddToFavourite(set, 10); foreach (var recipe in GetRecipesRecursive()) { if (recipe.recipe.crafters.Contains(set)) { recipe.RecordUndo().entity = set; if (!set.energy.fuels.Contains(recipe.fuel)) { recipe.fuel = recipe.entity.energy.fuels.AutoSelect(DataUtils.FavouriteFuel); } } } }, DataUtils.FavouriteCrafter, false); } if (gui.BuildButton("Mass set fuel") && (closed = true)) { SelectObjectPanel.Select(Database.goods.all.Where(x => x.fuelValue > 0), "Set fuel for all recipes", set => { DataUtils.FavouriteFuel.AddToFavourite(set, 10); foreach (var recipe in GetRecipesRecursive()) { if (recipe.entity != null && recipe.entity.energy.fuels.Contains(set)) { recipe.RecordUndo().fuel = set; } } }, DataUtils.FavouriteFuel, false); } if (gui.BuildButton("Shopping list") && (closed = true)) { BuildShoppngList(null); } }
private void DrawRecipeModules(ImGui gui, Entity beacon) { using (var grid = gui.EnterInlineGrid(3f, 1f)) { foreach (var module in recipe.modules.list) { if (module.inBeacon != (beacon != null)) { continue; } grid.Next(); var evt = gui.BuildFactorioGoodsWithEditableAmount(module.module, module.fixedCount, UnitOfMeasure.None, out var newAmount); if (evt == GoodsWithAmountEvent.ButtonClick) { SelectObjectPanel.Select(GetModules(beacon), "Select module", sel => { if (sel == null) { recipe.modules.RecordUndo().list.Remove(module); } else { module.module = sel; } gui.Rebuild(); }, DataUtils.FavouriteModule, true); } else if (evt == GoodsWithAmountEvent.TextEditing) { var amountInt = MathUtils.Floor(newAmount); if (amountInt < 0) { amountInt = 0; } module.fixedCount = amountInt; } } grid.Next(); if (gui.BuildButton(Icon.Plus, SchemeColor.Primary, SchemeColor.PrimalyAlt, size: 2.5f)) { SelectObjectPanel.Select(GetModules(beacon), "Select module", sel => { recipe.modules.RecordUndo().list.Add(new RecipeRowCustomModule(recipe.modules, sel) { inBeacon = beacon != null }); gui.Rebuild(); }, DataUtils.FavouriteModule, false); } } }
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; } }
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); } } }
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); } } }
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(); } }
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(); }
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); } }
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) { if (gui.BuildRedButton(Icon.Error) == ImGuiUtils.Event.MouseOver) { gui.ShowTooltip(g => { 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 } }
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(); } } }
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; } } } } }
public override void Build(ImGui gui) { BuildHeader(gui, "Preferences"); 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); ChoiceObject(gui, "Default belt:", Database.allBelts, prefs.defaultBelt, s => { prefs.RecordUndo().defaultBelt = s; gui.Rebuild(); }); ChoiceObject(gui, "Default inserter:", Database.allInserters, prefs.defaultInserter, s => { prefs.RecordUndo().defaultInserter = s; gui.Rebuild(); }); using (gui.EnterRow()) { gui.BuildText("Inserter capacity:", topOffset: 0.5f); if (gui.BuildTextInput(prefs.inserterCapacity.ToString(), out var newText2, null, Icon.None, true) && int.TryParse(newText2, out var capacity2)) { prefs.RecordUndo().inserterCapacity = capacity2; } } if (gui.BuildButton("Done")) { Close(); } if (prefs.justChanged) { MainScreen.Instance.RebuildProjectView(); } }
public override void Build(ImGui gui) { gui.spacing = 3f; BuildHeader(gui, editingPage == null ? "Create new page" : "Edit page icon and name"); Build(gui, ref name, icon, s => { icon = s; Rebuild(); }); using (gui.EnterRow(0.5f, RectAllocator.RightRow)) { if (editingPage == null && gui.BuildButton("Create", active: !string.IsNullOrEmpty(name))) { callback?.Invoke(name, icon); Close(); } if (editingPage != null && gui.BuildButton("OK", active: !string.IsNullOrEmpty(name))) { if (editingPage.name != name || editingPage.icon != icon) { editingPage.RecordUndo(true).name = name; editingPage.icon = icon; } Close(); } if (gui.BuildButton("Cancel", SchemeColor.Grey)) { Close(); } if (editingPage != null && gui.BuildButton("Duplicate page", SchemeColor.Grey, active: !string.IsNullOrEmpty(name))) { var project = editingPage.owner; var collector = new ErrorCollector(); var serializedCopy = JsonUtils.Copy(editingPage, project, collector); if (collector.severity > ErrorSeverity.None) { ErrorListPanel.Show(collector); } if (serializedCopy != null) { serializedCopy.GenerateNewGuid(); serializedCopy.icon = icon; serializedCopy.name = name; project.RecordUndo().pages.Add(serializedCopy); MainScreen.Instance.SetActivePage(serializedCopy); Close(); } } gui.allocator = RectAllocator.LeftRow; if (editingPage != null && gui.BuildRedButton("Delete page") == ImGuiUtils.Event.Click) { Project.current.RecordUndo().pages.Remove(editingPage); Close(); } } }
private void BuildSummary(ImGui gui, ProductionTable table) { var isRoot = table == model; if (!isRoot && !table.containsDesiredProducts) { return; } var elementsPerRow = MathUtils.Floor((flatHierarchyBuilder.width - 2f) / 4f); gui.spacing = 1f; var pad = new Padding(1f, 0.2f); using (gui.EnterGroup(pad)) { gui.BuildText("Desired products and amounts (Use negative for input goal):"); using (var grid = gui.EnterInlineGrid(3f, 1f, elementsPerRow)) { foreach (var link in table.links) { if (link.amount != 0f) { grid.Next(); DrawDesiredProduct(gui, link); } } grid.Next(); if (gui.BuildButton(Icon.Plus, SchemeColor.Primary, SchemeColor.PrimalyAlt, size: 2.5f)) { AddDesiredProductAtLevel(table); } } } if (gui.isBuilding) { gui.DrawRectangle(gui.lastRect, SchemeColor.Background, RectangleBorder.Thin); } if (table.flow.Length > 0 && table.flow[0].amount < -1e-5f) { using (gui.EnterGroup(pad)) { gui.BuildText(isRoot ? "Summary ingredients:" : "Import ingredients:"); var grid = gui.EnterInlineGrid(3f, 1f, elementsPerRow); BuildTableIngredients(gui, table, table, ref grid); grid.Dispose(); } if (gui.isBuilding) { gui.DrawRectangle(gui.lastRect, SchemeColor.Background, RectangleBorder.Thin); } } if (table.flow.Length > 0 && table.flow[table.flow.Length - 1].amount > 1e-5f) { using (gui.EnterGroup(pad)) { gui.BuildText(isRoot ? "Extra products:" : "Export products:"); var grid = gui.EnterInlineGrid(3f, 1f, elementsPerRow); BuildTableProducts(gui, table, table, ref grid); grid.Dispose(); } if (gui.isBuilding) { gui.DrawRectangle(gui.lastRect, SchemeColor.Background, RectangleBorder.Thin); } } }
public override void Build(ImGui gui) { BuildHeader(gui, "Module autofill parameters"); BuildSimple(gui, modules); if (gui.BuildCheckBox("Fill modules in miners", modules.fillMiners, out var newFill)) { modules.RecordUndo().fillMiners = newFill; } gui.AllocateSpacing(); gui.BuildText("Filler module:", Font.subheader); gui.BuildText("Use this module when aufofill doesn't add anything (for example when productivity modules doesn't fit)", wrap: true); if (gui.BuildFactorioObjectButtonWithText(modules.fillerModule)) { SelectObjectPanel.Select(Database.allModules, "Select filler module", select => { modules.RecordUndo().fillerModule = select; }, true); } gui.AllocateSpacing(); gui.BuildText("Beacons & beacon modules:", Font.subheader); if (gui.BuildFactorioObjectButtonWithText(modules.beacon)) { SelectObjectPanel.Select(Database.allBeacons, "Select beacon", select => { modules.RecordUndo(); modules.beacon = select; if (modules.beaconModule != null && (modules.beacon == null || !modules.beacon.CanAcceptModule(modules.beaconModule.module))) { modules.beaconModule = null; } gui.Rebuild(); }, true); } if (gui.BuildFactorioObjectButtonWithText(modules.beaconModule)) { SelectObjectPanel.Select(Database.allModules.Where(x => modules.beacon?.CanAcceptModule(x.module) ?? false), "Select module for beacon", select => { modules.RecordUndo().beaconModule = select; }, true); } using (gui.EnterRow()) { gui.BuildText("Beacons per building: "); if (gui.BuildTextInput(modules.beaconsPerBuilding.ToString(), out var newText, null, Icon.None, true, new Padding(0.5f, 0f)) && int.TryParse(newText, out var newAmount) && newAmount > 0) { modules.RecordUndo().beaconsPerBuilding = newAmount; } } gui.BuildText("Please note that beacons themself are not part of the calculation", wrap: true); using (gui.EnterRow()) { gui.BuildText("Mining productivity bonus (project-wide setting): "); if (gui.BuildTextInput(DataUtils.FormatAmount(Project.current.settings.miningProductivity, UnitOfMeasure.Percent), out var newText, null, Icon.None, true, new Padding(0.5f, 0f)) && DataUtils.TryParseAmount(newText, out var newAmount, UnitOfMeasure.Percent)) { Project.current.settings.RecordUndo().miningProductivity = newAmount; } } if (gui.BuildButton("Done")) { Close(); } }
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 { var effects = new ModuleEffects(); if (recipe.entity?.moduleSlots > 0) { gui.BuildText("Internal modules:", Font.subheader); gui.BuildText("Leave zero amount to fill the remainings slots"); DrawRecipeModules(gui, null, ref effects); } else { gui.BuildText("This building doesn't have module slots, but can be affected by beacons"); } gui.BuildText("Beacon modules:", Font.subheader); if (recipe.modules.beacon == null) { gui.BuildText("Use default parameters"); if (gui.BuildButton("Override beacons as well")) { SelectBeacon(gui); } var defaultFiller = recipe.GetModuleFiller(); if (defaultFiller != null && defaultFiller.beacon != null && defaultFiller.beaconModule != null) { effects.AddModules(defaultFiller.beaconModule.module, defaultFiller.beacon.beaconEfficiency * defaultFiller.beacon.moduleSlots * defaultFiller.beaconsPerBuilding); } } else { if (gui.BuildFactorioObjectButtonWithText(recipe.modules.beacon)) { SelectBeacon(gui); } 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, ref effects); } gui.BuildText("Current effects:", Font.subheader); gui.BuildText("Productivity bonus: " + DataUtils.FormatAmount(effects.productivity, UnitOfMeasure.Percent)); gui.BuildText("Speed bonus: " + DataUtils.FormatAmount(effects.speedMod, UnitOfMeasure.Percent) + " (Crafting speed: " + DataUtils.FormatAmount((recipe.entity?.craftingSpeed ?? 1f) * (1f + effects.speedMod), UnitOfMeasure.None) + ")"); var energyUsageLine = "Energy usage: " + DataUtils.FormatAmount(effects.energyUsageMod, UnitOfMeasure.Percent); if (!recipe.recipe.flags.HasFlagAny(RecipeFlags.UsesFluidTemperature | RecipeFlags.ScaleProductionWithPower) && recipe.entity != null) { energyUsageLine += " (" + DataUtils.FormatAmount(effects.energyUsageMod * recipe.entity.power / recipe.entity.energy.effectivity, UnitOfMeasure.Megawatt) + " per building)"; } gui.BuildText(energyUsageLine); } gui.AllocateSpacing(3f); using (gui.EnterRow(allocator: RectAllocator.RightRow)) { if (gui.BuildButton("Done")) { Close(); } if (recipe.modules != null && gui.BuildButton("Copy settings", SchemeColor.Grey)) { if (copiedModuleSettings == null) { MessageBox.Show("Info", "Use ctrl+click on module slot to paste settings", "Ok"); } copiedModuleSettings = JsonUtils.SaveToJson(recipe.modules); } gui.allocator = RectAllocator.LeftRow; if (recipe.modules != null && gui.BuildRedButton("Remove module customisation") == ImGuiUtils.Event.Click) { recipe.RecordUndo().modules = null; Close(); } } }
private void DrawRecipeModules(ImGui gui, EntityBeacon beacon, ref ModuleEffects effects) { var remainingModules = recipe.entity?.moduleSlots ?? 0; using (var grid = gui.EnterInlineGrid(3f, 1f)) { var list = beacon != null ? recipe.modules.beaconList : recipe.modules.list; foreach (var module in list) { grid.Next(); var evt = gui.BuildFactorioObjectWithEditableAmount(module.module, module.fixedCount, UnitOfMeasure.None, out var newAmount); if (evt == GoodsWithAmountEvent.ButtonClick) { SelectObjectPanel.Select(GetModules(beacon), "Select module", sel => { if (sel == null) { recipe.modules.RecordUndo().list.Remove(module); } else { module.RecordUndo().module = sel; } gui.Rebuild(); }, DataUtils.FavouriteModule, true); } else if (evt == GoodsWithAmountEvent.TextEditing) { var amountInt = MathUtils.Floor(newAmount); if (amountInt < 0) { amountInt = 0; } module.RecordUndo().fixedCount = amountInt; } if (beacon == null) { var count = Math.Min(remainingModules, module.fixedCount > 0 ? module.fixedCount : int.MaxValue); if (count > 0) { effects.AddModules(module.module.module, count); remainingModules -= count; } } else { effects.AddModules(module.module.module, module.fixedCount * beacon.beaconEfficiency); } } grid.Next(); if (gui.BuildButton(Icon.Plus, SchemeColor.Primary, SchemeColor.PrimalyAlt, size: 2.5f)) { gui.BuildObjectSelectDropDown(GetModules(beacon), DataUtils.FavouriteModule, sel => { recipe.modules.RecordUndo(); list.Add(new RecipeRowCustomModule(recipe.modules, sel)); gui.Rebuild(); }, "Select module"); } } }
protected override void BuildContent(ImGui gui) { if (model == null) { return; } var elementsPerRow = MathUtils.Floor((flatHierarchyBuilder.width - 2f) / 4f); gui.spacing = 1f; var pad = new Padding(1f, 0.2f); using (gui.EnterGroup(pad)) { gui.BuildText("Desired products and amounts:"); using (var grid = gui.EnterInlineGrid(3f, 1f, elementsPerRow)) { foreach (var link in model.links) { if (link.amount != 0f) { grid.Next(); DrawDesiredProduct(gui, link); } } grid.Next(); if (gui.BuildButton(Icon.Plus, SchemeColor.Primary, SchemeColor.PrimalyAlt, size: 2.5f)) { SelectObjectPanel.Select(Database.goods.all, "Add desired product", product => { if (model.linkMap.TryGetValue(product, out var existing)) { if (existing.amount != 0) { return; } existing.RecordUndo().amount = 1f; } else { model.RecordUndo().links.Add(new ProductionLink(model, product) { amount = 1f }); } }); } } } if (gui.isBuilding) { gui.DrawRectangle(gui.lastRect, SchemeColor.Background, RectangleBorder.Thin); } if (model.flow.Length > 0 && model.flow[0].amount < -1e-5f) { using (gui.EnterGroup(pad)) { gui.BuildText("Summary ingredients:"); var grid = gui.EnterInlineGrid(3f, 1f, elementsPerRow); BuildTableIngredients(gui, model, model, ref grid); grid.Dispose(); } if (gui.isBuilding) { gui.DrawRectangle(gui.lastRect, SchemeColor.Background, RectangleBorder.Thin); } } if (model.flow.Length > 0 && model.flow[model.flow.Length - 1].amount > 1e-5f) { using (gui.EnterGroup(pad)) { gui.BuildText("Extra products:"); var grid = gui.EnterInlineGrid(3f, 1f, elementsPerRow); BuildTableProducts(gui, model, model, ref grid); grid.Dispose(); } if (gui.isBuilding) { gui.DrawRectangle(gui.lastRect, SchemeColor.Background, RectangleBorder.Thin); } } gui.AllocateSpacing(); flatHierarchyBuilder.Build(gui); gui.SetMinWidth(flatHierarchyBuilder.width); }
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); } }