diff --git a/CommandLineToolExample/Program.cs b/CommandLineToolExample/Program.cs index e1d4adf5..516b02bd 100644 --- a/CommandLineToolExample/Program.cs +++ b/CommandLineToolExample/Program.cs @@ -29,7 +29,7 @@ public static void Main(string[] args) // Empty project path loads default project (with one empty page). // Project is irrelevant if you just need data, but you need it to perform sheet calculations // Set to not render any icons - project = FactorioDataSource.Parse(factorioPath, "", "", false, new ConsoleProgressReport(), errorCollector, "en", false); + project = FactorioDataSource.Parse(factorioPath, "", "", false, false, new ConsoleProgressReport(), errorCollector, "en", false); } catch (Exception ex) { diff --git a/YAFC/Utils/Preferences.cs b/YAFC/Utils/Preferences.cs index 9b2c13f0..3c664cb0 100644 --- a/YAFC/Utils/Preferences.cs +++ b/YAFC/Utils/Preferences.cs @@ -52,10 +52,10 @@ public void Save() public string language { get; set; } = "en"; public string overrideFont { get; set; } - public void AddProject(string path, string dataPath, string modsPath, bool expensiveRecipes) + public void AddProject(string path, string dataPath, string modsPath, bool expensiveRecipes, bool netProduction) { recentProjects = recentProjects.Where(x => string.Compare(path, x.path, StringComparison.InvariantCultureIgnoreCase) != 0) - .Prepend(new RecentProject {path = path, modsPath = modsPath, dataPath = dataPath, expensive = expensiveRecipes}).ToArray(); + .Prepend(new RecentProject {path = path, modsPath = modsPath, dataPath = dataPath, expensive = expensiveRecipes, netProduction = netProduction}).ToArray(); Save(); } } @@ -66,5 +66,6 @@ public struct RecentProject public string dataPath { get; set; } public string modsPath { get; set; } public bool expensive { get; set; } + public bool netProduction { get; set; } } } \ No newline at end of file diff --git a/YAFC/Windows/MainScreen.cs b/YAFC/Windows/MainScreen.cs index 45668085..64b013bc 100644 --- a/YAFC/Windows/MainScreen.cs +++ b/YAFC/Windows/MainScreen.cs @@ -551,7 +551,7 @@ private async Task SaveProjectAs() if (path != null) { project.Save(path); - Preferences.Instance.AddProject(path, DataUtils.dataPath, DataUtils.modsPath, DataUtils.expensiveRecipes); + Preferences.Instance.AddProject(path, DataUtils.dataPath, DataUtils.modsPath, DataUtils.expensiveRecipes, DataUtils.netProduction); return true; } diff --git a/YAFC/Windows/WelcomeScreen.cs b/YAFC/Windows/WelcomeScreen.cs index c0cbfb8d..cba99ccc 100644 --- a/YAFC/Windows/WelcomeScreen.cs +++ b/YAFC/Windows/WelcomeScreen.cs @@ -16,6 +16,7 @@ public class WelcomeScreen : WindowUtility, IProgress<(string, string)> private string currentLoad1, currentLoad2; private string path = "", dataPath = "", modsPath = ""; private bool expensive; + private bool netProduction; private string createText; private bool canCreate; private readonly VerticalScrollCustom errorScroll; @@ -134,6 +135,9 @@ protected override void BuildContents(ImGui gui) gui.BuildText("In-game objects language:"); } + using (gui.EnterRow()) + gui.BuildCheckBox("Use net production/consumption when analyzing recipes", netProduction, out netProduction); + using (gui.EnterRow()) { if (Preferences.Instance.recentProjects.Length > 1) @@ -270,6 +274,7 @@ private void BuildPathSelect(ImGui gui, ref string path, string description, str private void SetProject(RecentProject project) { + netProduction = project.netProduction; expensive = project.expensive; modsPath = project.modsPath ?? ""; path = project.path ?? ""; @@ -290,7 +295,7 @@ private async void LoadProject() try { var (dataPath, modsPath, projectPath, expensiveRecipes) = (this.dataPath, this.modsPath, path, expensive); - Preferences.Instance.AddProject(projectPath, dataPath, modsPath, expensiveRecipes); + Preferences.Instance.AddProject(projectPath, dataPath, modsPath, expensiveRecipes, netProduction); Preferences.Instance.Save(); tip = tips.Length > 0 ? tips[DataUtils.random.Next(tips.Length)] : ""; @@ -299,7 +304,7 @@ private async void LoadProject() await Ui.ExitMainThread(); var collector = new ErrorCollector(); - var project = FactorioDataSource.Parse(dataPath, modsPath, projectPath, expensiveRecipes, this, collector, Preferences.Instance.language); + var project = FactorioDataSource.Parse(dataPath, modsPath, projectPath, expensiveRecipes, netProduction, this, collector, Preferences.Instance.language); await Ui.EnterMainThread(); Console.WriteLine("Opening main screen"); new MainScreen(displayIndex, project); diff --git a/YAFCmodel/Data/DataUtils.cs b/YAFCmodel/Data/DataUtils.cs index 016b3de0..c23d60af 100644 --- a/YAFCmodel/Data/DataUtils.cs +++ b/YAFCmodel/Data/DataUtils.cs @@ -76,7 +76,9 @@ public static ulong GetMilestoneOrder(FactorioId id) public static string dataPath { get; internal set; } public static string modsPath { get; internal set; } public static bool expensiveRecipes { get; internal set; } + public static bool netProduction { get; internal set; } public static string[] allMods { get; internal set; } + public static readonly Random random = new Random(); public static bool SelectSingle(this T[] list, out T element) where T:FactorioObject diff --git a/YAFCparser/Data/FactorioDataDeserializer.cs b/YAFCparser/Data/FactorioDataDeserializer.cs index 9fb01cc6..7c1c9d03 100644 --- a/YAFCparser/Data/FactorioDataDeserializer.cs +++ b/YAFCparser/Data/FactorioDataDeserializer.cs @@ -78,7 +78,7 @@ private void AddTemperatureToFluidIcon(Fluid fluid) fluid.iconSpec = fluid.iconSpec.Concat(iconStr.Take(4).Select((x, n) => new FactorioIconPart {path = "__.__/"+x, y=-16, x = n*7-12, scale = 0.28f})).ToArray(); } - public Project LoadData(string projectPath, LuaTable data, LuaTable prototypes, IProgress<(string, string)> progress, ErrorCollector errorCollector, bool renderIcons) + public Project LoadData(string projectPath, LuaTable data, LuaTable prototypes, bool netProduction, IProgress<(string, string)> progress, ErrorCollector errorCollector, bool renderIcons) { progress.Report(("Loading", "Loading items")); raw = (LuaTable)data["raw"]; @@ -107,7 +107,7 @@ public Project LoadData(string projectPath, LuaTable data, LuaTable prototypes, var iconRenderTask = renderIcons ? Task.Run(RenderIcons) : Task.CompletedTask; UpdateRecipeIngredientFluids(); UpdateRecipeCatalysts(); - CalculateMaps(); + CalculateMaps(netProduction); ExportBuiltData(); progress.Report(("Post-processing", "Calculating dependencies")); Dependencies.Calculate(); diff --git a/YAFCparser/Data/FactorioDataDeserializer_Context.cs b/YAFCparser/Data/FactorioDataDeserializer_Context.cs index 5727a4c0..d6a4f3b9 100644 --- a/YAFCparser/Data/FactorioDataDeserializer_Context.cs +++ b/YAFCparser/Data/FactorioDataDeserializer_Context.cs @@ -181,7 +181,7 @@ private bool IsBarrelingRecipe(Recipe barreling, Recipe unbarreling) return true; } - private void CalculateMaps() + private void CalculateMaps(bool netProduction) { var itemUsages = new DataBucket(); var itemProduction = new DataBucket(); @@ -208,15 +208,21 @@ private void CalculateMaps() allRecipes.Add(recipe); foreach (var product in recipe.products) { - if (product.amount > 0) + float inputAmount = netProduction ? (recipe.ingredients.FirstOrDefault(i => i.goods == product.goods)?.amount ?? 0) : 0; + float outputAmount = ((IFactorioObjectWrapper)product).amount; + if (outputAmount > inputAmount) itemProduction.Add(product.goods, recipe); } foreach (var ingredient in recipe.ingredients) { - if (ingredient.variants == null) + float inputAmount = ingredient.amount; + IFactorioObjectWrapper outputData = recipe.products.FirstOrDefault(p => p.goods == ingredient.goods || p.goods == ingredient.variants?[0]); + float outputAmount = netProduction ? (outputData?.amount ?? 0) : 0; + + if (ingredient.variants == null && inputAmount > outputAmount) itemUsages.Add(ingredient.goods, recipe); - else + else if (ingredient.variants != null) { ingredient.goods = ingredient.variants[0]; foreach (var variant in ingredient.variants) diff --git a/YAFCparser/FactorioDataSource.cs b/YAFCparser/FactorioDataSource.cs index 87c97072..86bbdd8c 100644 --- a/YAFCparser/FactorioDataSource.cs +++ b/YAFCparser/FactorioDataSource.cs @@ -128,7 +128,7 @@ private static void FindMods(string directory, IProgress<(string, string)> progr } } - public static Project Parse(string factorioPath, string modPath, string projectPath, bool expensive, IProgress<(string, string)> progress, ErrorCollector errorCollector, string locale, bool renderIcons = true) + public static Project Parse(string factorioPath, string modPath, string projectPath, bool expensive, bool netProduction, IProgress<(string, string)> progress, ErrorCollector errorCollector, string locale, bool renderIcons = true) { LuaContext dataContext = null; try @@ -261,6 +261,7 @@ public static Project Parse(string factorioPath, string modPath, string projectP DataUtils.dataPath = factorioPath; DataUtils.modsPath = modPath; DataUtils.expensiveRecipes = expensive; + DataUtils.netProduction = netProduction; dataContext = new LuaContext(); @@ -287,7 +288,7 @@ public static Project Parse(string factorioPath, string modPath, string projectP currentLoadingMod = null; var deserializer = new FactorioDataDeserializer(expensive, factorioVersion ?? defaultFactorioVersion); - var project = deserializer.LoadData(projectPath, dataContext.data, dataContext.defines["prototypes"] as LuaTable, progress, errorCollector, renderIcons); + var project = deserializer.LoadData(projectPath, dataContext.data, dataContext.defines["prototypes"] as LuaTable, netProduction, progress, errorCollector, renderIcons); Console.WriteLine("Completed!"); progress.Report(("Completed!", "")); return project;