Beispiel #1
0
        public bool FillModules(RecipeParameters recipeParams, Recipe recipe, Entity entity, Goods fuel, out ModuleEffects effects, out RecipeParameters.UsedModule used)
        {
            effects = new ModuleEffects();
            var  beaconedModules    = 0;
            var  nonBeaconedModules = 0;
            Item nonBeacon          = null;

            foreach (var module in list)
            {
                float multiplier;
                if (module.inBeacon)
                {
                    if (beacon != null)
                    {
                        beaconedModules += module.fixedCount;
                        multiplier       = beacon.beaconEfficiency * module.fixedCount;
                    }
                    else
                    {
                        multiplier = 0f;
                    }
                }
                else
                {
                    var count = module.fixedCount > 0 ? module.fixedCount : Math.Max(0, entity.moduleSlots - nonBeaconedModules);
                    multiplier          = count;
                    nonBeaconedModules += count;
                    if (nonBeacon == null)
                    {
                        nonBeacon = module.module;
                    }
                }
                effects.AddModules(module.module.module, multiplier);
            }

            used = new RecipeParameters.UsedModule {
                module = nonBeacon, count = nonBeaconedModules
            };
            if (beaconedModules > 0 && beacon != null)
            {
                used.beacon      = beacon;
                used.beaconCount = ((beaconedModules - 1) / beacon.moduleSlots + 1);
            }

            return(list.Count > 0);
        }
        public void GetModulesInfo(RecipeParameters recipeParams, Recipe recipe, Entity entity, Goods fuel, ref ModuleEffects effects, ref RecipeParameters.UsedModule used)
        {
            ModuleFillerParameters filler = null;

            if (modules == null || modules.beacon == null)
            {
                filler = GetModuleFiller();
            }

            if (modules == null)
            {
                filler?.GetModulesInfo(recipeParams, recipe, entity, fuel, ref effects, ref used);
            }
            else
            {
                modules.GetModulesInfo(recipeParams, recipe, entity, fuel, ref effects, ref used, filler);
            }
        }
        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");
                }
            }
        }