Esempio n. 1
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);
        }
Esempio n. 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);
     }
 }
Esempio n. 3
0
        private void AddRecipe(ProductionTable table, Recipe recipe)
        {
            var recipeRow = new RecipeRow(table, recipe);

            table.RecordUndo().recipes.Add(recipeRow);
            recipeRow.entity = recipe.crafters.AutoSelect(DataUtils.FavouriteCrafter);
            recipeRow.fuel   = recipeRow.entity.energy.fuels.AutoSelect(DataUtils.FavouriteFuel);
        }
Esempio n. 4
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());
                }
            });
        }
Esempio n. 5
0
        private void BuildSolarPanelAccumulatorView(ImGui gui, RecipeRow recipe)
        {
            var accumulator          = recipe.GetVariant(Database.allAccumulators);
            var requiredMj           = recipe.entity.craftingSpeed * recipe.buildingCount * (70 / 0.7f); // 70 seconds of charge time to last through the night
            var requiredAccumulators = requiredMj / accumulator.accumulatorCapacity;

            if (gui.BuildFactorioObjectWithAmount(accumulator, requiredAccumulators, UnitOfMeasure.None))
            {
                ShowAccumulatorDropdown(gui, recipe, accumulator);
            }
        }
Esempio n. 6
0
    void AddRow(ItemType inputA, ItemType inputB, ItemType output)
    {
        GameObject go = Instantiate(recipeRowTemplatePrefab, transform.position, Quaternion.identity);

        go.transform.SetParent(transform);

        RecipeRow recipeRow = go.GetComponent <RecipeRow>();

        recipeRow.SetItems(inputA, inputB, output);
        recipeRow.transform.localScale = Vector3.one;
    }
Esempio n. 7
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;
         }
     });
 }
Esempio n. 8
0
        private List <RecipeRow> GetRecipesRecursive(RecipeRow recipeRoot)
        {
            var list = new List <RecipeRow> {
                recipeRoot
            };

            if (recipeRoot.subgroup != null)
            {
                FillRecipeList(recipeRoot.subgroup, list);
            }
            return(list);
        }
        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
            }
        }
Esempio n. 10
0
        public static Recipe ToRecipe(this RecipeRow row, IReferenceBookService referenceBook)
        {
            if (row == null)
            {
                throw new ArgumentNullException(nameof(row));
            }
            if (referenceBook == null)
            {
                throw new ArgumentNullException(nameof(referenceBook));
            }
            var recipe = row.Recipe.ToRecipe(referenceBook);

            recipe.Id = row.Id;
            return(recipe);
        }
Esempio n. 11
0
        private void AddRecipe(ProductionTable table, Recipe recipe)
        {
            var recipeRow = new RecipeRow(table, recipe);

            table.RecordUndo().recipes.Add(recipeRow);
            recipeRow.entity = recipe.crafters.AutoSelect(DataUtils.FavouriteCrafter);
            recipeRow.fuel   = recipeRow.entity.energy.fuels.AutoSelect(DataUtils.FavouriteFuel);
            foreach (var ingr in recipeRow.recipe.ingredients)
            {
                if (ingr.variants != null)
                {
                    recipeRow.variants.Add(ingr.variants.AutoSelect(DefaultVariantOrdering));
                }
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Add the recipe in the define row
        /// </summary>
        /// <param name="recipeRow"></param>
        /// <param name="recipe"></param>
        private void AddRecipe(RecipeRow recipeRow, Recipe recipe)
        {
            switch (recipeRow)
            {
            case RecipeRow.cheaper:
                CheaperRecipeStackPanel.Children.Add(GetButton(recipe));
                break;

            case RecipeRow.rated:
                BestRatedStackPanel.Children.Add(GetButton(recipe));
                break;

            case RecipeRow.trending:
                TrendingStackPanel.Children.Add(GetButton(recipe));
                break;
            }
        }
Esempio n. 13
0
        private void BuildRecipeProducts(ImGui gui, RecipeRow recipe)
        {
            var grid = gui.EnterInlineGrid(3f, 1f);

            if (recipe.isOverviewMode)
            {
                BuildTableProducts(gui, recipe.subgroup, recipe.owner, ref grid);
            }
            else
            {
                foreach (var product in recipe.recipe.products)
                {
                    grid.Next();
                    BuildGoodsIcon(gui, product.goods, (float)(product.amount * recipe.recipesPerSecond * recipe.parameters.productionMultiplier), ProductDropdownType.Product, recipe, recipe.linkRoot);
                }
            }
            grid.Dispose();
        }
Esempio n. 14
0
        public Recipe FindRecipe(int id)
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(nameof(RecipePersistenceService));
            }
            if (id <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(id));
            }
            RecipeRow row = null;

            using (_connection.Lock())
            {
                row = _connection.Get <RecipeRow>(x => x.Id == id);
            }
            return(row?.ToRecipe(_referenceBook));
        }
Esempio n. 15
0
        private void BuildRecipeIngredients(ImGui gui, RecipeRow recipe)
        {
            var grid = gui.EnterInlineGrid(3f, 1f);

            if (recipe.isOverviewMode)
            {
                BuildTableIngredients(gui, recipe.subgroup, recipe.owner, ref grid);
            }
            else
            {
                foreach (var ingredient in recipe.recipe.ingredients)
                {
                    grid.Next();
                    BuildGoodsIcon(gui, ingredient.goods, (float)(ingredient.amount * recipe.recipesPerSecond), ProductDropdownType.Ingredient, recipe, recipe.linkRoot);
                }
            }
            grid.Dispose();
        }
Esempio n. 16
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);
        }
Esempio n. 17
0
        private void BuildRecipeProducts(ImGui gui, RecipeRow recipe)
        {
            var grid = gui.EnterInlineGrid(3f, 1f);

            if (recipe.isOverviewMode)
            {
                BuildTableProducts(gui, recipe.subgroup, recipe.owner, ref grid);
            }
            else
            {
                for (var i = 0; i < recipe.recipe.products.Length; i++)
                {
                    var product = recipe.recipe.products[i];
                    grid.Next();
                    BuildGoodsIcon(gui, product.goods, recipe.links.products[i], (float)(recipe.recipesPerSecond * product.GetAmount(recipe.parameters.productivity)), ProductDropdownType.Product,
                                   recipe, recipe.linkRoot);
                }
            }
            grid.Dispose();
        }
Esempio n. 18
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);
                }
            }
        }
Esempio n. 19
0
        private void BuildRecipeModules(ImGui gui, RecipeRow recipe)
        {
            if (recipe.isOverviewMode)
            {
                return;
            }
            using (var grid = gui.EnterInlineGrid(3f))
            {
                if (recipe.entity != null && recipe.entity.allowedEffects != AllowedEffects.None)
                {
                    if (recipe.parameters.modules.modules == null || recipe.parameters.modules.modules.Length == 0)
                    {
                        grid.Next();
                        if (gui.BuildFactorioObjectWithAmount(null, 0, UnitOfMeasure.None))
                        {
                            ShowModuleDropDown(gui, recipe);
                        }
                    }
                    else
                    {
                        foreach (var(module, count) in recipe.parameters.modules.modules)
                        {
                            grid.Next();
                            if (gui.BuildFactorioObjectWithAmount(module, count, UnitOfMeasure.None))
                            {
                                ShowModuleDropDown(gui, recipe);
                            }
                        }
                    }
                }

                if (recipe.parameters.modules.beacon != null)
                {
                    grid.Next();
                    if (gui.BuildFactorioObjectWithAmount(recipe.parameters.modules.beacon, recipe.parameters.modules.beaconCount, UnitOfMeasure.None))
                    {
                        ModuleCustomisationScreen.Show(recipe);
                    }
                }
            }
        }
Esempio n. 20
0
        private void BuildRecipeIngredients(ImGui gui, RecipeRow recipe)
        {
            var grid = gui.EnterInlineGrid(3f, 1f);

            if (recipe.isOverviewMode)
            {
                BuildTableIngredients(gui, recipe.subgroup, recipe.owner, ref grid);
            }
            else
            {
                for (var i = 0; i < recipe.recipe.ingredients.Length; i++)
                {
                    var ingredient = recipe.recipe.ingredients[i];
                    var link       = recipe.links.ingredients[i];
                    var goods      = recipe.links.ingredientGoods[i];
                    grid.Next();
                    BuildGoodsIcon(gui, goods, link, (float)(ingredient.amount * recipe.recipesPerSecond), ProductDropdownType.Ingredient, recipe, recipe.linkRoot, ingredient.variants);
                }
            }
            grid.Dispose();
        }
Esempio n. 21
0
        private void BuildRecipePad(ImGui gui, RecipeRow row)
        {
            gui.allocator = RectAllocator.Center;
            gui.spacing   = 0f;
            if (row.subgroup != null)
            {
                if (gui.BuildButton(row.subgroup.expanded ? Icon.ShevronDown : Icon.ShevronRight))
                {
                    row.subgroup.RecordUndo(true).expanded = !row.subgroup.expanded;
                    flatHierarchyBuilder.SetData(model);
                }
            }


            if (row.parameters.warningFlags != 0)
            {
                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
            }
        }
Esempio n. 22
0
        private void BuildShoppngList(RecipeRow recipeRoot)
        {
            var shopList = new Dictionary <FactorioObject, int>();
            var recipes  = recipeRoot == null?GetRecipesRecursive() : GetRecipesRecursive(recipeRoot);

            foreach (var recipe in recipes)
            {
                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.modules != null)
                    {
                        foreach (var module in recipe.parameters.modules.modules)
                        {
                            shopList.TryGetValue(module.module, out prev);
                            shopList[module.module] = prev + count * module.count;
                        }
                    }
                }
            }
            ShoppingListScreen.Show(shopList);
        }
Esempio n. 23
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);
             }
         });
     }
 }
Esempio n. 24
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;
                 }
             }
         }
     }
 }
Esempio n. 25
0
 public static void Show(RecipeRow recipe)
 {
     Instance.recipe = recipe;
     MainScreen.Instance.ShowPseudoScreen(Instance);
 }
Esempio n. 26
0
        private void BuildGoodsIcon(ImGui gui, Goods goods, ProductionLink link, float amount, ProductDropdownType dropdownType, RecipeRow recipe, ProductionTable context, Goods[] variants = null)
        {
            var linkIsError   = link != null && ((link.flags & (ProductionLink.Flags.HasProductionAndConsumption | ProductionLink.Flags.LinkRecursiveNotMatched | ProductionLink.Flags.ChildNotMatched)) != ProductionLink.Flags.HasProductionAndConsumption);
            var linkIsForeign = link != null && link.owner != context;

            if (gui.BuildFactorioObjectWithAmount(goods, amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None, link != null ? linkIsError ? SchemeColor.Error : linkIsForeign?SchemeColor.Secondary : SchemeColor.Primary: goods.IsSourceResource() ? SchemeColor.Green : SchemeColor.None) && goods != Database.voidEnergy)
            {
                OpenProductDropdown(gui, gui.lastRect, goods, amount, link, dropdownType, recipe, context, variants);
            }
        }
Esempio n. 27
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;
                    }
                }
            }
        }
Esempio n. 28
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);
        }
Esempio n. 29
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);
                }
            }
        }
Esempio n. 30
0
        private void BuildGoodsIcon(ImGui gui, Goods goods, float amount, ProductDropdownType dropdownType, RecipeRow recipe, ProductionTable context)
        {
            var hasLink       = context.FindLink(goods, out var link);
            var linkIsError   = hasLink && ((link.flags & (ProductionLink.Flags.HasProductionAndConsumption | ProductionLink.Flags.LinkRecursiveNotMatched)) != ProductionLink.Flags.HasProductionAndConsumption);
            var linkIsForeign = hasLink && link.owner != context;

            if (gui.BuildFactorioObjectWithAmount(goods, amount, goods?.flowUnitOfMeasure ?? UnitOfMeasure.None, hasLink ? linkIsError ? SchemeColor.Error : linkIsForeign?SchemeColor.Secondary : SchemeColor.Primary: SchemeColor.None) && goods != Database.voidEnergy)
            {
                OpenProductDropdown(gui, gui.lastRect, goods, dropdownType, recipe, context);
            }
        }