예제 #1
0
        private void ShowEntityDropPown(ImGui imgui, RecipeRow recipe)
        {
            imgui.ShowDropDown((ImGui gui, ref bool closed) =>
            {
                closed = gui.BuildInlineObejctListAndButton(recipe.recipe.crafters, DataUtils.FavouriteCrafter, sel =>
                {
                    if (recipe.entity == sel)
                    {
                        return;
                    }
                    recipe.RecordUndo().entity = sel;
                    if (!sel.energy.fuels.Contains(recipe.fuel))
                    {
                        recipe.fuel = recipe.entity.energy.fuels.AutoSelect(DataUtils.FavouriteFuel);
                    }
                }, "Select crafting entity", extra: x => DataUtils.FormatAmount(x.craftingSpeed, UnitOfMeasure.Percent));

                if (recipe.fixedBuildings > 0f)
                {
                    if (gui.BuildButton("Clear fixed building count") && (closed = true))
                    {
                        recipe.RecordUndo().fixedBuildings = 0f;
                    }
                }
                else
                {
                    if (gui.BuildButton("Set fixed building count") && (closed = true))
                    {
                        recipe.RecordUndo().fixedBuildings = recipe.buildingCount <= 0f ? 1f : recipe.buildingCount;
                    }
                }

                if (recipe.entity != null && gui.BuildButton("Create single building blueprint") && (closed = true))
                {
                    var entity = new BlueprintEntity {
                        index = 1, name = recipe.entity.name
                    };
                    if (!(recipe.recipe is Mechanics))
                    {
                        entity.recipe = recipe.recipe.name;
                    }
                    var modules = recipe.parameters.modules.modules;
                    if (modules != null)
                    {
                        entity.items = new Dictionary <string, int>();
                        foreach (var(module, count) in recipe.parameters.modules.modules)
                        {
                            entity.items[module.name] = count;
                        }
                    }
                    var bp = new BlueprintString {
                        blueprint = { label = recipe.recipe.locName, entities = { entity } }
                    };
                    SDL.SDL_SetClipboardText(bp.ToBpString());
                }
            });
        }
예제 #2
0
 private void BuildRecipeModules(ImGui gui, RecipeRow recipe)
 {
     if (recipe.isOverviewMode)
     {
         return;
     }
     if (recipe.entity != null && recipe.entity.moduleSlots > 0 && gui.BuildFactorioObjectWithAmount(recipe.parameters.modules.module, recipe.parameters.modules.count, UnitOfMeasure.None))
     {
         gui.ShowDropDown((ImGui dropGui, ref bool closed) =>
         {
             dropGui.BuildText("Selecting a fixed module will override auto-module filler!", wrap: true);
             closed = dropGui.BuildInlineObejctListAndButton(recipe.recipe.modules, DataUtils.FavouriteModule, sel =>
             {
                 DataUtils.FavouriteModule.AddToFavourite(sel);
                 if (recipe.module == sel)
                 {
                     return;
                 }
                 recipe.RecordUndo().module = sel;
             }, "Select fixed module", allowNone: recipe.parameters.modules.module != null);
         });
     }
     if (recipe.parameters.modules.beacon != null)
     {
         gui.BuildFactorioObjectWithAmount(recipe.parameters.modules.beacon, recipe.parameters.modules.beaconCount, UnitOfMeasure.None);
     }
 }
예제 #3
0
        private void BuildRecipeEntity(ImGui gui, RecipeRow recipe)
        {
            if (recipe.isOverviewMode)
            {
                return;
            }
            if (gui.BuildFactorioObjectWithAmount(recipe.entity, (float)(recipe.recipesPerSecond * recipe.parameters.recipeTime), UnitOfMeasure.None) && recipe.recipe.crafters.Count > 0)
            {
                gui.ShowDropDown(((ImGui dropGui, ref bool closed) =>
                {
                    closed = dropGui.BuildInlineObejctListAndButton(recipe.recipe.crafters, DataUtils.FavouriteCrafter, sel =>
                    {
                        DataUtils.FavouriteCrafter.AddToFavourite(sel);
                        if (recipe.entity == sel)
                        {
                            return;
                        }
                        recipe.RecordUndo().entity = sel;
                        if (!sel.energy.fuels.Contains(recipe.fuel))
                        {
                            recipe.fuel = recipe.entity.energy.fuels.AutoSelect(DataUtils.FavouriteFuel);
                        }
                    }, "Select crafting entity");
                }));
            }

            gui.AllocateSpacing(0.5f);
            BuildGoodsIcon(gui, recipe.fuel, (float)(recipe.parameters.fuelUsagePerSecondPerRecipe * recipe.recipesPerSecond), ProductDropdownType.Fuel, recipe,
                           recipe.linkRoot);
        }
예제 #4
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);
        }
예제 #5
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();
            }
        }
예제 #6
0
        private void BuildRecipeEntity(ImGui gui, RecipeRow recipe)
        {
            if (recipe.isOverviewMode)
            {
                return;
            }
            bool clicked;

            if (recipe.fixedBuildings > 0)
            {
                var evt = gui.BuildFactorioObjectWithEditableAmount(recipe.entity, recipe.fixedBuildings, UnitOfMeasure.None, out var newAmount);
                if (evt == GoodsWithAmountEvent.TextEditing)
                {
                    recipe.RecordUndo().fixedBuildings = newAmount;
                }
                clicked = evt == GoodsWithAmountEvent.ButtonClick;
            }
            else
            {
                clicked = gui.BuildFactorioObjectWithAmount(recipe.entity, recipe.buildingCount, UnitOfMeasure.None) && recipe.recipe.crafters.Count > 0;
            }


            if (clicked)
            {
                ShowEntityDropPown(gui, recipe);
            }

            gui.AllocateSpacing(0.5f);
            if (recipe.fuel != Database.voidEnergy)
            {
                BuildGoodsIcon(gui, recipe.fuel, recipe.links.fuel, (float)(recipe.parameters.fuelUsagePerSecondPerRecipe * recipe.recipesPerSecond), ProductDropdownType.Fuel, recipe, recipe.linkRoot);
            }
            else
            {
                if (recipe.recipe == Database.electricityGeneration && recipe.entity.factorioType == "solar-panel")
                {
                    BuildSolarPanelAccumulatorView(gui, recipe);
                }
            }
        }
예제 #7
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;
                 }
             }
         }
     }
 }
예제 #8
0
 private void ShowModuleDropDown(ImGui gui, RecipeRow recipe)
 {
     if (InputSystem.Instance.control)
     {
         if (recipe.entity != null && ModuleCustomisationScreen.copiedModuleSettings != null)
         {
             var result = JsonUtils.LoadFromJson(ModuleCustomisationScreen.copiedModuleSettings, recipe, recipe.modules);
             foreach (var module in result.list)
             {
                 if (!recipe.recipe.modules.Contains(module.module) && recipe.entity.CanAcceptModule(module.module.module))
                 {
                     MessageBox.Show("Module mismatch", "This module cannot be used: " + module.module.locName, "OK");
                     return;
                 }
             }
             recipe.RecordUndo().modules = JsonUtils.LoadFromJson(ModuleCustomisationScreen.copiedModuleSettings, recipe, recipe.modules);
         }
     }
     else if (recipe.entity?.moduleSlots == 0 || recipe.modules != null && (recipe.modules.list.Count > 1 || recipe.modules.beacon != null))
     {
         ModuleCustomisationScreen.Show(recipe);
     }
     else
     {
         var modules = recipe.recipe.modules.Where(x => recipe.entity?.CanAcceptModule(x.module) ?? false).ToArray();
         gui.ShowDropDown((ImGui dropGui, ref bool closed) =>
         {
             dropGui.BuildText("Selecting a fixed module will override auto-module filler!", wrap: true);
             closed = dropGui.BuildInlineObejctListAndButton(modules, DataUtils.FavouriteModule, recipe.SetFixedModule, "Select fixed module", allowNone: recipe.modules != null);
             if (dropGui.BuildButton("Customize modules") && (closed = true))
             {
                 ModuleCustomisationScreen.Show(recipe);
             }
         });
     }
 }
예제 #9
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
            {
                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();
                }
            }
        }
예제 #10
0
        private void OpenProductDropdown(ImGui targetGui, Rect rect, Goods goods, ProductDropdownType type, RecipeRow recipe, ProductionTable context)
        {
            context.FindLink(goods, out var link);
            var comparer   = DataUtils.GetRecipeComparerFor(goods);
            var allRecipes = new HashSet <Recipe>(context.recipes.Select(x => x.recipe));
            Predicate <Recipe> recipeExists = rec => allRecipes.Contains(rec);
            Action <Recipe>    addRecipe    = rec =>
            {
                CreateLink(context, goods);
                if (!allRecipes.Contains(rec))
                {
                    AddRecipe(context, rec);
                }
            };
            var selectFuel = type != ProductDropdownType.Fuel ? null : (Action <Goods>)(fuel =>
            {
                recipe.RecordUndo().fuel = fuel;
                DataUtils.FavouriteFuel.AddToFavourite(fuel);
            });

            targetGui.ShowDropDown(rect, DropDownContent, new Padding(1f));

            void DropDownContent(ImGui gui, ref bool close)
            {
                if (type == ProductDropdownType.Fuel && (recipe.entity.energy.fuels.Count > 0))
                {
                    close |= gui.BuildInlineObejctListAndButton(recipe.entity.energy.fuels, DataUtils.FavouriteFuel, selectFuel, "Select fuel");
                }

                if (link != null)
                {
                    if (link.goods.fluid != null)
                    {
                        gui.BuildText("Fluid temperature: " + DataUtils.FormatAmount(link.resultTemperature, UnitOfMeasure.None) + "°");
                    }
                    if (!link.flags.HasFlags(ProductionLink.Flags.HasProduction))
                    {
                        gui.BuildText("This link has no production (Link ignored)", wrap: true, color: SchemeColor.Error);
                    }
                    if (!link.flags.HasFlags(ProductionLink.Flags.HasConsumption))
                    {
                        gui.BuildText("This link has no consumption (Link ignored)", wrap: true, color: SchemeColor.Error);
                    }
                    if (!link.flags.HasFlags(ProductionLink.Flags.HasProductionAndConsumption) && link.owner.owner is RecipeRow recipeRow && recipeRow.FindLink(link.goods, out _))
                    {
                        gui.BuildText("Nested tables have their own set of links that DON'T connect to parent links. To connect this product to the outside, remove this link", wrap: true, color: SchemeColor.Error);
                    }
                    if (link.flags.HasFlags(ProductionLink.Flags.LinkRecursiveNotMatched))
                    {
                        if (link.notMatchedFlow <= 0f)
                        {
                            gui.BuildText("YAFC was unable to satisfy this link (Negative feedback loop). This doesn't mean that this link is the problem, but it is part of the loop.", wrap: true, color: SchemeColor.Error);
                        }
                        else
                        {
                            gui.BuildText("YAFC was unable to satisfy this link (Overproduction). You can allow overproduction for this link to solve the error.", wrap: true, color: SchemeColor.Error);
                        }
                    }
                }

                if (type != ProductDropdownType.Product && goods != null && goods.production.Length > 0)
                {
                    close |= gui.BuildInlineObejctListAndButton(goods.production, comparer, addRecipe, "Add production recipe", 6, true, recipeExists);
                }

                if (type != ProductDropdownType.Fuel && goods != null && type != ProductDropdownType.Ingredient && goods.usages.Length > 0)
                {
                    close |= gui.BuildInlineObejctListAndButton(goods.usages, DataUtils.DefaultRecipeOrdering, addRecipe, "Add consumption recipe", type == ProductDropdownType.Product ? 6 : 3, true, recipeExists);
                }

                if (link != null && gui.BuildCheckBox("Allow overproduction", link.algorithm == LinkAlgorithm.AllowOverProduction, out var newValue))
                {
                    link.RecordUndo().algorithm = newValue ? LinkAlgorithm.AllowOverProduction : LinkAlgorithm.Match;
                }

                if (link != null && link.owner == context)
                {
                    if (link.amount != 0)
                    {
                        gui.BuildText(goods.locName + " is a desired product and cannot be unlinked.", wrap: true);
                    }
                    else
                    {
                        gui.BuildText(goods.locName + " production is currently linked. This means that YAFC will try to match production with consumption.", wrap: true);
                    }
                    if (type == ProductDropdownType.DesiredProduct)
                    {
                        if (gui.BuildButton("Remove desired product"))
                        {
                            link.RecordUndo().amount = 0;
                            close = true;
                        }

                        if (gui.BuildButton("Remove and unlink"))
                        {
                            DestroyLink(context, goods);
                            close = true;
                        }
                    }
                    else if (link.amount == 0 && gui.BuildButton("Unlink"))
                    {
                        DestroyLink(context, goods);
                        close = true;
                    }
                }
                else if (goods != null)
                {
                    if (link != null)
                    {
                        gui.BuildText(goods.locName + " production is currently linked, but the link is outside this nested table. Nested tables can have its own separate set of links", wrap: true);
                    }
                    else
                    {
                        gui.BuildText(goods.locName + " production is currently NOT linked. This means that YAFC will make no attempt to match production with consumption.", wrap: true);
                    }
                    if (gui.BuildButton("Create link"))
                    {
                        CreateLink(context, goods);
                        close = true;
                    }
                }
            }
        }
예제 #11
0
        private void OpenProductDropdown(ImGui targetGui, Rect rect, Goods goods, float amount, ProductionLink link, ProductDropdownType type, RecipeRow recipe, ProductionTable context, Goods[] variants = null)
        {
            if (InputSystem.Instance.control)
            {
                Project.current.preferences.SetSourceResource(goods, !goods.IsSourceResource());
                targetGui.Rebuild();
                return;
            }

            var comparer   = DataUtils.GetRecipeComparerFor(goods);
            var allRecipes = new HashSet <Recipe>(context.recipes.Select(x => x.recipe));
            Predicate <Recipe> recipeExists = rec => allRecipes.Contains(rec);
            Action <Recipe>    addRecipe    = async rec =>
            {
                if (variants == null)
                {
                    CreateLink(context, goods);
                }
                else
                {
                    foreach (var variant in variants)
                    {
                        if (rec.GetProduction(variant) > 0f)
                        {
                            CreateLink(context, variant);
                            if (variant != goods)
                            {
                                recipe.RecordUndo().ChangeVariant(goods, variant);
                            }
                            break;
                        }
                    }
                }
                if (!allRecipes.Contains(rec) || (await MessageBox.Show("Recipe already exists", "Add a second copy?", "Add a copy", "Cancel")).choice)
                {
                    AddRecipe(context, rec);
                }
            };
            var selectFuel = type != ProductDropdownType.Fuel ? null : (Action <Goods>)(fuel =>
            {
                recipe.RecordUndo().fuel = fuel;
            });
            var allProduction = goods == null?Array.Empty <Recipe>() : variants == null ? goods.production : variants.SelectMany(x => x.production).Distinct().ToArray();

            var fuelDisplayFunc = recipe?.entity?.energy.type == EntityEnergyType.FluidHeat
                ? (Func <Goods, string>)(g => DataUtils.FormatAmount(g.fluid?.heatValue ?? 0, UnitOfMeasure.Megajoule))
                : g => DataUtils.FormatAmount(g.fuelValue, UnitOfMeasure.Megajoule);

            targetGui.ShowDropDown(rect, DropDownContent, new Padding(1f), 25f);

            void DropDownContent(ImGui gui, ref bool close)
            {
                if (type == ProductDropdownType.Fuel && recipe?.entity != null && recipe.entity.energy.fuels.Count > 1)
                {
                    close |= gui.BuildInlineObejctListAndButton(recipe.entity.energy.fuels, DataUtils.FavouriteFuel, selectFuel, "Select fuel", extra: fuelDisplayFunc);
                }

                if (variants != null)
                {
                    gui.BuildText("Accepted fluid variants:");
                    using (var grid = gui.EnterInlineGrid(3f))
                    {
                        foreach (var variant in variants)
                        {
                            grid.Next();
                            if (gui.BuildFactorioObjectButton(variant, 3f, MilestoneDisplay.Contained, variant == goods ? SchemeColor.Primary : SchemeColor.None) &&
                                variant != goods)
                            {
                                recipe.RecordUndo().ChangeVariant(goods, variant);
                                close = true;
                            }
                        }
                    }

                    gui.allocator = RectAllocator.Stretch;
                }

                if (link != null)
                {
                    if (!link.flags.HasFlags(ProductionLink.Flags.HasProduction))
                    {
                        gui.BuildText("This link has no production (Link ignored)", wrap: true, color: SchemeColor.Error);
                    }
                    if (!link.flags.HasFlags(ProductionLink.Flags.HasConsumption))
                    {
                        gui.BuildText("This link has no consumption (Link ignored)", wrap: true, color: SchemeColor.Error);
                    }
                    if (link.flags.HasFlags(ProductionLink.Flags.ChildNotMatched))
                    {
                        gui.BuildText("Nested table link have unmatched production/consumption. These unmatched products are not captured by this link.", wrap: true, color: SchemeColor.Error);
                    }
                    if (!link.flags.HasFlags(ProductionLink.Flags.HasProductionAndConsumption) && link.owner.owner is RecipeRow recipeRow && recipeRow.FindLink(link.goods, out _))
                    {
                        gui.BuildText("Nested tables have their own set of links that DON'T connect to parent links. To connect this product to the outside, remove this link", wrap: true, color: SchemeColor.Error);
                    }
                    if (link.flags.HasFlags(ProductionLink.Flags.LinkRecursiveNotMatched))
                    {
                        if (link.notMatchedFlow <= 0f)
                        {
                            gui.BuildText("YAFC was unable to satisfy this link (Negative feedback loop). This doesn't mean that this link is the problem, but it is part of the loop.", wrap: true, color: SchemeColor.Error);
                        }
                        else
                        {
                            gui.BuildText("YAFC was unable to satisfy this link (Overproduction). You can allow overproduction for this link to solve the error.", wrap: true, color: SchemeColor.Error);
                        }
                    }
                }

                if (type != ProductDropdownType.Product && goods != null && allProduction.Length > 0)
                {
                    close |= gui.BuildInlineObejctListAndButton(allProduction, comparer, addRecipe, "Add production recipe", 6, true, recipeExists);
                }

                if (type != ProductDropdownType.Fuel && goods != null && type != ProductDropdownType.Ingredient && goods.usages.Length > 0)
                {
                    close |= gui.BuildInlineObejctListAndButton(goods.usages, DataUtils.DefaultRecipeOrdering, addRecipe, "Add consumption recipe", type == ProductDropdownType.Product ? 6 : 3, true, recipeExists);
                }

                if (type == ProductDropdownType.Product && goods != null && allProduction.Length > 0)
                {
                    close |= gui.BuildInlineObejctListAndButton(allProduction, comparer, addRecipe, "Add production recipe", 1, true, recipeExists);
                }

                if (link != null && gui.BuildCheckBox("Allow overproduction", link.algorithm == LinkAlgorithm.AllowOverProduction, out var newValue))
                {
                    link.RecordUndo().algorithm = newValue ? LinkAlgorithm.AllowOverProduction : LinkAlgorithm.Match;
                }

                if (link != null && gui.BuildButton("View link summary") && (close = true))
                {
                    ProductionLinkSummaryScreen.Show(link);
                }

                if (link != null && link.owner == context)
                {
                    if (link.amount != 0)
                    {
                        gui.BuildText(goods.locName + " is a desired product and cannot be unlinked.", wrap: true);
                    }
                    else
                    {
                        gui.BuildText(goods.locName + " production is currently linked. This means that YAFC will try to match production with consumption.", wrap: true);
                    }
                    if (type == ProductDropdownType.DesiredProduct)
                    {
                        if (gui.BuildButton("Remove desired product"))
                        {
                            link.RecordUndo().amount = 0;
                            close = true;
                        }

                        if (gui.BuildButton("Remove and unlink"))
                        {
                            DestroyLink(link);
                            close = true;
                        }
                    }
                    else if (link.amount == 0 && gui.BuildButton("Unlink"))
                    {
                        DestroyLink(link);
                        close = true;
                    }
                }
                else if (goods != null)
                {
                    if (link != null)
                    {
                        gui.BuildText(goods.locName + " production is currently linked, but the link is outside this nested table. Nested tables can have its own separate set of links", wrap: true);
                    }
                    else
                    {
                        gui.BuildText(goods.locName + " production is currently NOT linked. This means that YAFC will make no attempt to match production with consumption.", wrap: true);
                    }
                    if (gui.BuildButton("Create link"))
                    {
                        CreateLink(context, goods);
                        close = true;
                    }
                }

                if (goods is Item)
                {
                    BuildBeltInserterInfo(gui, amount, recipe?.buildingCount ?? 0, ref close);
                }
            }
        }
예제 #12
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)
                {
                    DrawRecipeTagSelect(imgui, recipe);

                    if (recipe.subgroup == null && imgui.BuildButton("Create nested table"))
                    {
                        recipe.RecordUndo().subgroup = new ProductionTable(recipe);
                        closed = true;
                    }

                    if (recipe.subgroup != null && imgui.BuildButton("Add nested desired product"))
                    {
                        AddDesiredProductAtLevel(recipe.subgroup);
                        closed = true;
                    }

                    if (recipe.subgroup != null && imgui.BuildButton("Add raw recipe"))
                    {
                        SelectObjectPanel.Select(Database.recipes.all, "Select raw recipe", r => AddRecipe(recipe.subgroup, r));
                        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.BuildButton("ShoppingList"))
                    {
                        BuildShoppngList(recipe);
                        closed = true;
                    }

                    if (imgui.BuildCheckBox("Enabled", recipe.enabled, out var newEnabled))
                    {
                        recipe.RecordUndo().enabled = newEnabled;
                    }

                    if (recipe.subgroup != null && imgui.BuildRedButton("Delete 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.textColor = recipe.hierarchyEnabled ? SchemeColor.BackgroundText : SchemeColor.BackgroundTextFaint;
            gui.BuildText(recipe.recipe.locName, wrap: true);
        }
예제 #13
0
 private void ShowAccumulatorDropdown(ImGui gui, RecipeRow recipe, Entity accumulator)
 {
     gui.ShowDropDown((ImGui imGui, ref bool closed) =>
     {
         if (imGui.BuildInlineObejctListAndButton <EntityAccumulator>(Database.allAccumulators, DataUtils.DefaultOrdering,
                                                                      accum => recipe.RecordUndo().ChangeVariant(accumulator, accum), "Select accumulator",
                                                                      extra: x => DataUtils.FormatAmount(x.accumulatorCapacity, UnitOfMeasure.Megajoule)))
         {
             closed = true;
         }
     });
 }