Skip to content

Commit

Permalink
WIP: Better detection of barreling recipes.
Browse files Browse the repository at this point in the history
This handles deadlock_stacked_recipes better and combines the Barreling/Barreled/Unbarreling status into a single special type.
  • Loading branch information
DaleStan committed May 23, 2024
1 parent a58c9b9 commit 586ac9a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 24 deletions.
9 changes: 2 additions & 7 deletions Yafc.Model/Data/DataClasses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,11 @@ public bool CanFit(int itemInputs, int fluidInputs, Goods[] slots) {

public enum FactorioObjectSpecialType {
Normal,
FilledBarrel,
Barreling,
Voiding,
Unbarreling,
Barreling,
Stacking,
StackedItem,
Unstacking,
Pressurization,
PressurizedFluid,
Depressurization,
Crating,
}

public class Recipe : RecipeOrTechnology {
Expand Down
46 changes: 29 additions & 17 deletions Yafc.Parser/Data/FactorioDataDeserializer_Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,22 @@ private static bool AreInverseRecipes(Recipe packing, Recipe unpacking) {
return false;
}

float ratio = 0;
Recipe larger = null;

// Check for 'packing.ingredients == unpacking.products'.
if (!checkRatios(packing, unpacking, ref ratio, ref larger)) {
float ratio = 0;
Recipe largerRecipe = null;
if (!checkRatios(packing, unpacking, ref ratio, ref largerRecipe)) {
return false;
}

// Check for 'unpacking.ingredients == packing.products'.
if (!checkRatios(unpacking, packing, ref ratio, ref larger)) {
if (!checkRatios(unpacking, packing, ref ratio, ref largerRecipe)) {
return false;
}

if ((unpacking.crafters.OfType<EntityWithModules>().Any(c => c.moduleSlots > 0) && unpacking.IsProductivityAllowed())
|| (packing.crafters.OfType<EntityWithModules>().Any(c => c.moduleSlots > 0) && packing.IsProductivityAllowed())) {
// Some mods add productivity permissions to the recipies, but not to the crafters; still allow these to be matched as inverses.
// TODO: Consider removing this check entirely?
if ((unpacking.crafters.OfType<EntityWithModules>().Any(c => c.moduleSlots > 0 && c.allowedEffects.HasFlag(AllowedEffects.Productivity)) && unpacking.IsProductivityAllowed())
|| (packing.crafters.OfType<EntityWithModules>().Any(c => c.moduleSlots > 0 && c.allowedEffects.HasFlag(AllowedEffects.Productivity)) && packing.IsProductivityAllowed())) {
return false;
}

Expand Down Expand Up @@ -397,7 +398,7 @@ private void CalculateMaps() {
}

Goods packed = recipe.products[0].goods;
if (packed.usages.Length != 1 && packed.production.Length != 1) {
if (countNonDsrRecipes(packed.usages) != 1 && countNonDsrRecipes(packed.production) != 1) {
continue;
}

Expand All @@ -410,29 +411,36 @@ private void CalculateMaps() {
if (AreInverseRecipes(recipe, unpacking)) {
if (packed is Fluid && unpacking.products.All(p => p.goods is Fluid)) {
recipe.specialType = FactorioObjectSpecialType.Pressurization;
unpacking.specialType = FactorioObjectSpecialType.Depressurization;
packed.specialType = FactorioObjectSpecialType.PressurizedFluid;
unpacking.specialType = FactorioObjectSpecialType.Pressurization;
packed.specialType = FactorioObjectSpecialType.Pressurization;
}
else if (packed is Item && unpacking.products.All(p => p.goods is Item)) {
if (unpacking.products.Length == 1) {
recipe.specialType = FactorioObjectSpecialType.Stacking;
unpacking.specialType = FactorioObjectSpecialType.Unstacking;
packed.specialType = FactorioObjectSpecialType.StackedItem;
unpacking.specialType = FactorioObjectSpecialType.Stacking;
packed.specialType = FactorioObjectSpecialType.Stacking;
}
else {
recipe.specialType = FactorioObjectSpecialType.Crating;
unpacking.specialType = FactorioObjectSpecialType.Crating;
packed.specialType = FactorioObjectSpecialType.Crating;
}
}
else if (packed is Item && unpacking.products.Any(p => p.goods is Item) && unpacking.products.Any(p => p.goods is Fluid)) {
recipe.specialType = FactorioObjectSpecialType.Barreling;
unpacking.specialType = FactorioObjectSpecialType.Unbarreling;
packed.specialType = FactorioObjectSpecialType.FilledBarrel;
unpacking.specialType = FactorioObjectSpecialType.Barreling;
packed.specialType = FactorioObjectSpecialType.Barreling;
}
else { continue; }

// The packed good is used in other recipes or is fuel, constructs a building, or is a module. Only the unpacking recipe should be flagged as special.
if (packed.usages.Length != 1 || (packed is Item item && (item.fuelValue != 0 || item.placeResult != null || item.module != null))) {
if (countNonDsrRecipes(packed.usages) != 1 || (packed is Item item && (item.fuelValue != 0 || item.placeResult != null || item.module != null))) {
recipe.specialType = FactorioObjectSpecialType.Normal;
packed.specialType = FactorioObjectSpecialType.Normal;
}

// The packed good can be mined, or an unpacked good can only be produced by unpacking. Only the packing recipe should be flagged as special.
if (packed.miscSources.Length != 0 || (packed.production.Length > 1 && unpacking.products.Any(p => p.goods.production.Length == 1 && p.goods.miscSources.Length == 0))) {
// The packed good can be mined or has a non-packing source. Only the packing recipe should be flagged as special.
if (packed.miscSources.OfType<Entity>().Any() || countNonDsrRecipes(packed.production) > 1) {
unpacking.specialType = FactorioObjectSpecialType.Normal;
packed.specialType = FactorioObjectSpecialType.Normal;
}
Expand All @@ -450,6 +458,10 @@ private void CalculateMaps() {
}
}

// The recipes added by deadlock_stacked_recipes (with CompressedFluids, if present) need to be filtered out to get decent results.
static int countNonDsrRecipes(IEnumerable<Recipe> recipes) {
return recipes.Count(r => !r.name.Contains("StackedRecipe-") && !r.name.Contains("DSR_HighPressure-"));
}
}

private Recipe CreateSpecialRecipe(FactorioObject production, string category, string hint) {
Expand Down

0 comments on commit 586ac9a

Please sign in to comment.