Skip to content

Commit

Permalink
Add some utilities, add target technology preference
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowTheAge committed Jan 5, 2023
1 parent 9fb0ed8 commit 49ed813
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 33 deletions.
5 changes: 5 additions & 0 deletions YAFC/Windows/PreferencesScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public override void Build(ImGui gui)
}
}
}
ChoiceObject(gui, "Target technology for cost analysis: ", Database.technologies.all, prefs.targetTechnology, x =>
{
prefs.RecordUndo().targetTechnology = x;
gui.Rebuild();
});

if (gui.BuildButton("Done"))
Close();
Expand Down
52 changes: 48 additions & 4 deletions YAFC/Workspace/ProductionTable/ProductionTableView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ public override void BuildElement(ImGui gui, RecipeRow recipe)
gui.BuildText(recipe.recipe.locName, wrap:true);
}

private void RemoveZeroRecipes(ProductionTable productionTable)
{
productionTable.RecordUndo().recipes.RemoveAll(x => x.subgroup == null && x.recipesPerSecond == 0);
foreach (var recipe in productionTable.recipes)
{
if (recipe.subgroup != null)

This comment has been minimized.

Copy link
@DaleStan

DaleStan Jan 5, 2023

Contributor

Unfortunately, this introduces an obnoxious edge case. If a zero-building recipe is the header of a sub-table, the solver can start using that recipe. Usually it ends up generating outputs for free.

If you load the YAFC file I attached to #172 (comment), the ingredients change drastically when removing the zero-building recipes.

RemoveZeroRecipes(recipe.subgroup);
}
}

public override void BuildMenu(ImGui gui)
{
if (gui.BuildButton("Add recipe") && gui.CloseDropdown())
Expand All @@ -170,6 +180,34 @@ public override void BuildMenu(ImGui gui)
if (gui.BuildLink("hour") && gui.CloseDropdown())
ExportIo(3600f);
}

if (gui.BuildButton("Remove all zero-building recipes") && gui.CloseDropdown())
{
RemoveZeroRecipes(view.model);
}

if (gui.BuildRedButton("Clear recipes") && gui.CloseDropdown())
{
view.model.RecordUndo().recipes.Clear();
}

if (InputSystem.Instance.control && gui.BuildButton("Add ALL recipes") && gui.CloseDropdown())
{
foreach (var recipe in Database.recipes.all)
{
if (!recipe.IsAccessible())
continue;
foreach (var ingredient in recipe.ingredients)
{
if (ingredient.goods.production.Length == 0)
goto goodsHaveNoProduction;
}
foreach (var product in recipe.products)
view.CreateLink(view.model, product.goods);
var row = view.AddRecipe(view.model, recipe);
goodsHaveNoProduction:;
}
}
}

private void ExportIo(float multiplier)
Expand Down Expand Up @@ -538,17 +576,20 @@ public override void CreateModelDropdown(ImGui gui, Type type, Project project)
}

private static readonly IComparer<Goods> DefaultVariantOrdering = new DataUtils.FactorioObjectComparer<Goods>((x, y) => (y.ApproximateFlow() / MathF.Abs(y.Cost())).CompareTo(x.ApproximateFlow() / MathF.Abs(x.Cost())));
private void AddRecipe(ProductionTable table, Recipe recipe)
private RecipeRow 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);
if (recipeRow.entity != null)
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));
}

return recipeRow;
}

private enum ProductDropdownType
Expand Down Expand Up @@ -793,9 +834,12 @@ private void BuildTableProducts(ImGui gui, ProductionTable table, ProductionTabl
if (firstProduct < 0)
firstProduct = ~firstProduct;
for (var i = firstProduct; i < flow.Length; i++)
{
{
var amt = flow[i].amount;
if (amt <= 0f)
continue;
grid.Next();
BuildGoodsIcon(gui, flow[i].goods, flow[i].link, flow[i].amount, ProductDropdownType.Product, null, context);
BuildGoodsIcon(gui, flow[i].goods, flow[i].link, amt, ProductDropdownType.Product, null, context);
}
}

Expand Down
2 changes: 1 addition & 1 deletion YAFC/YafcLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public static void RegisterDefaultAnalysis()
{
Analysis.RegisterAnalysis(Milestones.Instance);
Analysis.RegisterAnalysis(AutomationAnalysis.Instance);
Analysis.RegisterAnalysis(TechnologyScienceAnalysis.Instance);
Analysis.RegisterAnalysis(CostAnalysis.Instance);
Analysis.RegisterAnalysis(CostAnalysis.InstanceAtMilestones);
Analysis.RegisterAnalysis(TechnologyScienceAnalysis.Instance);
}
}
}
34 changes: 22 additions & 12 deletions YAFCmodel/Analysis/CostAnalysis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class CostAnalysis : Analysis
public Mapping<Recipe, float> recipeWastePercentage;
public Goods[] importantItems;
private readonly bool onlyCurrentMilestones;
private string itemAmountPrefix;

public CostAnalysis(bool onlyCurrentMilestones)
{
Expand All @@ -57,25 +58,34 @@ public override void Compute(Project project, ErrorCollector warnings)
var constraints = Database.recipes.CreateMapping<Constraint>();

var sciencePackUsage = new Dictionary<Goods, float>();
foreach (var technology in Database.technologies.all)
if (!onlyCurrentMilestones && project.preferences.targetTechnology != null)
{
if (technology.IsAccessible())
itemAmountPrefix = "Estimated amount for "+project.preferences.targetTechnology.locName+": ";
foreach (var spUsage in TechnologyScienceAnalysis.Instance.allSciencePacks[project.preferences.targetTechnology])
sciencePackUsage[spUsage.goods] = spUsage.amount;
}
else
{
itemAmountPrefix = "Estimated amount for all researches: ";
foreach (var technology in Database.technologies.all)
{
foreach (var ingredient in technology.ingredients)
if (technology.IsAccessible())
{
if (ingredient.goods.IsAutomatable())
foreach (var ingredient in technology.ingredients)
{
if (onlyCurrentMilestones && !Milestones.Instance.IsAccessibleAtNextMilestone(ingredient.goods))
continue;
sciencePackUsage.TryGetValue(ingredient.goods, out var prev);
sciencePackUsage[ingredient.goods] = prev + ingredient.amount * technology.count;
if (ingredient.goods.IsAutomatable())
{
if (onlyCurrentMilestones && !Milestones.Instance.IsAccessibleAtNextMilestone(ingredient.goods))
continue;
sciencePackUsage.TryGetValue(ingredient.goods, out var prev);
sciencePackUsage[ingredient.goods] = prev + ingredient.amount * technology.count;
}
}
}
}
}





foreach (var goods in Database.goods.all)
{
if (!ShouldInclude(goods))
Expand Down Expand Up @@ -381,7 +391,7 @@ public string GetItemAmount(Goods goods)
var itemFlow = flow[goods];
if (itemFlow <= 1f)
return null;
return DataUtils.FormatAmount(itemFlow * 1000f, UnitOfMeasure.None, "Estimated amount for all researches: ");
return DataUtils.FormatAmount(itemFlow * 1000f, UnitOfMeasure.None, itemAmountPrefix);
}
}
}
10 changes: 5 additions & 5 deletions YAFCmodel/Model/ProductionTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,10 @@ public override async Task<string> Solve(ProjectPage page)
}

result = solver.Solve();

Console.WriteLine("Solver finished with result "+result);
await Ui.EnterMainThread();

if (result == Solver.ResultStatus.OPTIMAL || result == Solver.ResultStatus.FEASIBLE)
{
var linkList = new List<ProductionLink>();
Expand Down Expand Up @@ -442,10 +446,6 @@ public override async Task<string> Solve(ProjectPage page)
}
}



Console.WriteLine("Solver finished with result "+result);
await Ui.EnterMainThread();
for (var i = 0; i < allLinks.Count; i++)
{
var link = allLinks[i];
Expand All @@ -454,7 +454,7 @@ public override async Task<string> Solve(ProjectPage page)
if (constraint == null)
continue;
var basisStatus = constraint.BasisStatus();
if (basisStatus == Solver.BasisStatus.BASIC || basisStatus == Solver.BasisStatus.FREE)
if ((basisStatus == Solver.BasisStatus.BASIC || basisStatus == Solver.BasisStatus.FREE) && (link.notMatchedFlow != 0 || link.algorithm != LinkAlgorithm.Match))
{
link.flags |= ProductionLink.Flags.LinkNotMatched;
}
Expand Down
1 change: 1 addition & 0 deletions YAFCmodel/Model/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ public ProjectPreferences(Project owner) : base(owner) {}
public int inserterCapacity { get; set; } = 1;
public HashSet<FactorioObject> sourceResources { get; } = new HashSet<FactorioObject>();
public HashSet<FactorioObject> favourites { get; } = new HashSet<FactorioObject>();
public Technology targetTechnology { get; set; }

protected internal override void AfterDeserialize()
{
Expand Down
15 changes: 7 additions & 8 deletions YAFCparser/FactorioDataSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,27 +233,26 @@ public static Project Parse(string factorioPath, string modPath, string projectP

sortedMods.RemoveAll(x => !modsToLoad.Contains(x));
}

if (locale != null)

Console.WriteLine("All mods found! Loading order: " + string.Join(", ", modLoadOrder));

if (locale != "en")
{
foreach (var mod in modLoadOrder)
{
currentLoadingMod = mod;
LoadModLocale(mod, locale);
LoadModLocale(mod, "en");
}
}
// Fill the rest of the locale keys from english
if (locale != "en")
if (locale != null)
{
foreach (var mod in modLoadOrder)
{
currentLoadingMod = mod;
LoadModLocale(mod, "en");
LoadModLocale(mod, locale);
}
}

Console.WriteLine("All mods found! Loading order: " + string.Join(", ", modLoadOrder));

var preprocess = File.ReadAllBytes("Data/Sandbox.lua");
var postprocess = File.ReadAllBytes("Data/Postprocess.lua");
DataUtils.allMods = modLoadOrder;
Expand Down
4 changes: 1 addition & 3 deletions YAFCparser/FactorioLocalization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ public static void Parse(Stream stream)
continue;
var key = line.Substring(0, idx);
var val = line.Substring(idx + 1, line.Length - idx - 1);
var fullKey = category + "." + key;
if (!keys.ContainsKey(fullKey))
keys[fullKey] = CleanupTags(val);
keys[category + "." + key] = CleanupTags(val);
}

}
Expand Down

0 comments on commit 49ed813

Please sign in to comment.