From 722af0a3caaa4bc9327365265ab631c91625c6a7 Mon Sep 17 00:00:00 2001 From: CaitSith2 Date: Thu, 25 Nov 2021 09:44:01 -0800 Subject: [PATCH] Now possible for randomized science packs/silo/satellite recipe to use fluids. --- worlds/factorio/Mod.py | 5 ++- worlds/factorio/Technologies.py | 7 ++-- worlds/factorio/__init__.py | 42 +++++++++++++++++-- .../data/mod_template/data-final-fixes.lua | 3 +- worlds/factorio/data/mod_template/macros.lua | 4 +- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/worlds/factorio/Mod.py b/worlds/factorio/Mod.py index 3a5dc569..46d0a455 100644 --- a/worlds/factorio/Mod.py +++ b/worlds/factorio/Mod.py @@ -12,7 +12,7 @@ import shutil from . import Options from BaseClasses import MultiWorld from .Technologies import tech_table, rocket_recipes, recipes, free_sample_blacklist, progressive_technology_table, \ - base_tech_table, tech_to_progressive_lookup, progressive_tech_table + base_tech_table, tech_to_progressive_lookup, progressive_tech_table, liquids template_env: Optional[jinja2.Environment] = None @@ -108,7 +108,8 @@ def generate_mod(world, output_directory: str): "progressive_technology_table": {tech.name : tech.progressive for tech in progressive_technology_table.values()}, "custom_recipes": world.custom_recipes, - "max_science_pack": multiworld.max_science_pack[player].value} + "max_science_pack": multiworld.max_science_pack[player].value, + "liquids": liquids} for factorio_option in Options.factorio_options: template_data[factorio_option] = getattr(multiworld, factorio_option)[player].value diff --git a/worlds/factorio/Technologies.py b/worlds/factorio/Technologies.py index 89f50b84..343fa451 100644 --- a/worlds/factorio/Technologies.py +++ b/worlds/factorio/Technologies.py @@ -458,9 +458,8 @@ rel_cost = { "used-up-uranium-fuel-cell": 1000 } -# forbid liquids for now, TODO: allow a single liquid per assembler -blacklist: Set[str] = all_ingredient_names | {"rocket-part", "crude-oil", "water", "sulfuric-acid", "petroleum-gas", - "light-oil", "heavy-oil", "lubricant", "steam"} +blacklist: Set[str] = all_ingredient_names | {"rocket-part"} +liquids: Set[str] = {"crude-oil", "water", "sulfuric-acid", "petroleum-gas", "light-oil", "heavy-oil", "lubricant", "steam"} @Utils.cache_argsless @@ -484,6 +483,8 @@ def get_science_pack_pools() -> Dict[str, Set[str]]: current |= set(recipe.products) if science_pack == "automation-science-pack": current |= {"iron-ore", "copper-ore", "coal", "stone"} + elif science_pack == "logistic-science-pack": + current |= {"water", "steam", "crude-oil"} current -= already_taken already_taken |= current current_difficulty *= 2 diff --git a/worlds/factorio/__init__.py b/worlds/factorio/__init__.py index e502ddb5..e9174209 100644 --- a/worlds/factorio/__init__.py +++ b/worlds/factorio/__init__.py @@ -7,7 +7,8 @@ from BaseClasses import Region, Entrance, Location, Item from .Technologies import base_tech_table, recipe_sources, base_technology_table, \ all_ingredient_names, all_product_sources, required_technologies, get_rocket_requirements, rocket_recipes, \ progressive_technology_table, common_tech_table, tech_to_progressive_lookup, progressive_tech_table, \ - get_science_pack_pools, Recipe, recipes, technology_table, tech_table, factorio_base_id, useless_technologies + get_science_pack_pools, Recipe, recipes, technology_table, tech_table, factorio_base_id, useless_technologies, \ + liquids from .Shapes import get_shapes from .Mod import generate_mod from .Options import factorio_options, MaxSciencePack, Silo, Satellite, TechTreeInformation @@ -194,6 +195,8 @@ class Factorio(World): remaining_energy = target_energy remaining_num_ingredients = target_num_ingredients fallback_pool = [] + liquids_used = 0 + category = original.category # fill all but one slot with random ingredients, last with a good match while remaining_num_ingredients > 0 and pool: @@ -225,11 +228,19 @@ class Factorio(World): if min_num > max_num: fallback_pool.append(ingredient) continue # can't use that ingredient + if liquids_used == 2 and ingredient in liquids: + continue # can't use this ingredient as we already have a liquid in our recipe. num = self.world.random.randint(min_num, max_num) new_ingredients[ingredient] = num remaining_raw -= num * ingredient_raw remaining_energy -= num * ingredient_energy remaining_num_ingredients -= 1 + if ingredient in liquids: + if liquids_used == 0: + category = "crafting-with-fluid" + elif liquids_used == 1: + category = "chemistry" + liquids_used += 1 # fill failed slots with whatever we got pool = fallback_pool @@ -245,15 +256,23 @@ class Factorio(World): num_energy = remaining_energy / ingredient_energy / remaining_num_ingredients num = int(min(num_raw, num_energy)) if num < 1: continue + if liquids_used == 2 and ingredient in liquids: + continue # can't use this ingredient as we already have a liquid in our recipe. new_ingredients[ingredient] = num remaining_raw -= num * ingredient_raw remaining_energy -= num * ingredient_energy remaining_num_ingredients -= 1 + if ingredient in liquids: + if liquids_used == 0: + category = "crafting-with-fluid" + elif liquids_used == 1: + category = "chemistry" + liquids_used += 1 if remaining_num_ingredients > 1: logging.warning("could not randomize recipe") - return Recipe(original.name, original.category, new_ingredients, original.products, original.energy) + return Recipe(original.name, category, new_ingredients, original.products, original.energy) def set_custom_technologies(self): custom_technologies = {} @@ -267,6 +286,8 @@ class Factorio(World): science_pack_pools = get_science_pack_pools() valid_pool = sorted(science_pack_pools[self.world.max_science_pack[self.player].get_max_pack()]) self.world.random.shuffle(valid_pool) + while any([valid_pool[x] in liquids for x in range(3)]): + self.world.random.shuffle(valid_pool) self.custom_recipes = {"rocket-part": Recipe("rocket-part", original_rocket_part.category, {valid_pool[x]: 10 for x in range(3)}, original_rocket_part.products, @@ -280,9 +301,22 @@ class Factorio(World): if pack in recipes: # skips over space science pack original = recipes[pack] new_ingredients = {} + liquids_used = 0 + category = original.category for _ in original.ingredients: - new_ingredients[valid_pool.pop()] = 1 - new_recipe = Recipe(pack, original.category, new_ingredients, original.products, original.energy) + new_ingredient = valid_pool.pop() + if new_ingredient in liquids: + while liquids_used == 2 and new_ingredient in liquids: + valid_pool.append(new_ingredient) + self.world.random.shuffle(valid_pool) + new_ingredient = valid_pool.pop() + if liquids_used == 0: + category = "crafting-with-fluid" + elif liquids_used == 1: + category = "chemistry" + liquids_used += 1 + new_ingredients[new_ingredient] = 1 + new_recipe = Recipe(pack, category, new_ingredients, original.products, original.energy) self.custom_recipes[pack] = new_recipe if self.world.silo[self.player].value == Silo.option_randomize_recipe \ diff --git a/worlds/factorio/data/mod_template/data-final-fixes.lua b/worlds/factorio/data/mod_template/data-final-fixes.lua index be55d2dc..c07b6970 100644 --- a/worlds/factorio/data/mod_template/data-final-fixes.lua +++ b/worlds/factorio/data/mod_template/data-final-fixes.lua @@ -3,7 +3,8 @@ require('lib') {%- for recipe_name, recipe in custom_recipes.items() %} -data.raw["recipe"]["{{recipe_name}}"].ingredients = {{ dict_to_recipe(recipe.ingredients) }} +data.raw["recipe"]["{{recipe_name}}"].category = "{{recipe.category}}" +data.raw["recipe"]["{{recipe_name}}"].ingredients = {{ dict_to_recipe(recipe.ingredients, liquids) }} {%- endfor %} local technologies = data.raw["technology"] diff --git a/worlds/factorio/data/mod_template/macros.lua b/worlds/factorio/data/mod_template/macros.lua index 8ae030a7..c81ddc5f 100644 --- a/worlds/factorio/data/mod_template/macros.lua +++ b/worlds/factorio/data/mod_template/macros.lua @@ -20,10 +20,10 @@ {%- else -%} {{ value | safe }} {%- endif -%} {%- endmacro -%} -{% macro dict_to_recipe(dict) -%} +{% macro dict_to_recipe(dict, liquids) -%} { {%- for key, value in dict.items() -%} - {"{{ key }}", {{ value | safe }}}{% if not loop.last %},{% endif %} + {type = {% if key in liquids %}"fluid"{% else %}"item"{% endif %}, name = "{{ key }}", amount = {{ value | safe }}}{% if not loop.last %},{% endif %} {% endfor -%} } {%- endmacro %} \ No newline at end of file