Skip to content

Commit

Permalink
fix(#276): Unlock fixed recipes with their crafters.
Browse files Browse the repository at this point in the history
This needs to be done recursively, in case a fixed recipe creates a crafter with another fixed recipe.
  • Loading branch information
DaleStan committed Sep 9, 2024
1 parent 547311f commit 3cc5796
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
39 changes: 39 additions & 0 deletions Yafc.Parser/Data/FactorioDataDeserializer_Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,45 @@ private void CalculateMaps(bool netProduction) {
}
}

Queue<EntityCrafter> crafters = new(allObjects.OfType<EntityCrafter>());

while (crafters.TryDequeue(out EntityCrafter? crafter)) {
// If this is a crafter with a fixed recipe with data.raw.recipe["fixed-recipe-name"].enabled = false
// (Exclude Mechanics; they aren't recipes in Factorio's fixed_recipe sense.)
if (recipeCrafters.GetRaw(crafter).SingleOrDefault(s => s.StartsWith(SpecialNames.FixedRecipe), false) != null
&& crafter.recipes.SingleOrDefault(r => r.GetType() == typeof(Recipe), false) is Recipe { enabled: false } fixedRecipe) {

bool addedUnlocks = false;
foreach (Recipe itemRecipe in crafter.itemsToPlace.SelectMany(i => i.production)) {
// and (a recipe that creates an item that places) the crafter is accessible
// from the beginning of the game, the fixed recipe is also accessible.
if (itemRecipe.enabled) {
fixedRecipe.enabled = true;
addedUnlocks = true;
break;
}
// otherwise, the recipe is also unlocked by all technologies that
// unlock (a recipe that creates an item that places) the crafter.
else if (itemRecipe.technologyUnlock.Except(fixedRecipe.technologyUnlock).Any()) {
// Add the missing technology/ies
fixedRecipe.technologyUnlock = [.. fixedRecipe.technologyUnlock.Union(itemRecipe.technologyUnlock)];
addedUnlocks = true;
}
}

if (addedUnlocks) {
// If we added unlocks, and the fixed recipe creates (items that place) crafters,
// queue those crafters for a second check, in case they also have fixed recipes.
Item[] products = [.. fixedRecipe.products.Select(p => p.goods).OfType<Item>()];
foreach (EntityCrafter newCrafter in allObjects.OfType<EntityCrafter>()) {
if (newCrafter.itemsToPlace.Intersect(products).Any()) {
crafters.Enqueue(newCrafter);
}
}
}
}
}

foreach (var mechanic in allMechanics) {
mechanic.locName = mechanic.source.locName + " " + mechanic.locName;
mechanic.locDescr = mechanic.source.locDescr;
Expand Down
5 changes: 5 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
// Internal changes:
// Changes to the code that do not affect the behavior of the program.
----------------------------------------------------------------------------------------------------------------------
Version: 0.10.1
Date:
Bugfixes:
- Fixed recipes now become accessible when their crafter does.
----------------------------------------------------------------------------------------------------------------------
Version: 0.10.0
Date:
Feature:
Expand Down

0 comments on commit 3cc5796

Please sign in to comment.