From 91655a855decbe6961246e55cd2da10182c4f54d Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 25 Jun 2021 01:31:48 +0200 Subject: [PATCH] Factorio: exclude science packs and rocket-part from free samples --- FactorioClientGUI.py | 2 +- data/factorio/mod_template/control.lua | 46 ++++++++++++++------------ worlds/factorio/Mod.py | 5 +-- worlds/factorio/Technologies.py | 20 +++++++---- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/FactorioClientGUI.py b/FactorioClientGUI.py index b33f6a49..d985c5d3 100644 --- a/FactorioClientGUI.py +++ b/FactorioClientGUI.py @@ -59,7 +59,7 @@ class FactorioManager(App): super(FactorioManager, self).__init__() self.ctx = ctx self.commandprocessor = ctx.command_processor(ctx) - self.icon = "data/icon.png" + self.icon = r"data/icon.png" def build(self): self.grid = GridLayout() diff --git a/data/factorio/mod_template/control.lua b/data/factorio/mod_template/control.lua index 47e97fe0..d38e44c3 100644 --- a/data/factorio/mod_template/control.lua +++ b/data/factorio/mod_template/control.lua @@ -6,6 +6,7 @@ require "util" FREE_SAMPLES = {{ free_samples }} SLOT_NAME = "{{ slot_name }}" SEED_NAME = "{{ seed_name }}" +FREE_SAMPLE_BLACKLIST = {{ dict_to_lua(free_sample_blacklist) }} {% if not imported_blueprints -%} function set_permissions() @@ -152,29 +153,32 @@ script.on_event(defines.events.on_research_finished, function(event) local technology = event.research if technology.researched and string.find(technology.name, "ap%-") == 1 then dumpInfo(technology.force) --is sendable - end - if FREE_SAMPLES == 0 then - return -- Nothing else to do - end - if not technology.effects then - return -- No technology effects, so nothing to do. - end - for _, effect in pairs(technology.effects) do - if effect.type == "unlock-recipe" then - local recipe = game.recipe_prototypes[effect.recipe] - for _, result in pairs(recipe.products) do - if result.type == "item" and result.amount then - local name = result.name - local count - if FREE_SAMPLES == 1 then - count = result.amount - else - count = get_any_stack_size(result.name) - if FREE_SAMPLES == 2 then - count = math.ceil(count / 2) + else + if FREE_SAMPLES == 0 then + return -- Nothing else to do + end + if not technology.effects then + return -- No technology effects, so nothing to do. + end + for _, effect in pairs(technology.effects) do + if effect.type == "unlock-recipe" then + local recipe = game.recipe_prototypes[effect.recipe] + for _, result in pairs(recipe.products) do + if result.type == "item" and result.amount then + local name = result.name + if FREE_SAMPLE_BLACKLIST[name] ~= 1 then + local count + if FREE_SAMPLES == 1 then + count = result.amount + else + count = get_any_stack_size(result.name) + if FREE_SAMPLES == 2 then + count = math.ceil(count / 2) + end + end + add_samples(technology.force, name, count) end end - add_samples(technology.force, name, count) end end end diff --git a/worlds/factorio/Mod.py b/worlds/factorio/Mod.py index c68f7102..6d5a3d9e 100644 --- a/worlds/factorio/Mod.py +++ b/worlds/factorio/Mod.py @@ -11,7 +11,7 @@ import Utils import shutil import Options from BaseClasses import MultiWorld -from .Technologies import tech_table, rocket_recipes, recipes +from .Technologies import tech_table, rocket_recipes, recipes, free_sample_blacklist template_env: Optional[jinja2.Environment] = None @@ -76,7 +76,8 @@ def generate_mod(world: MultiWorld, player: int): "slot_name": world.player_names[player][0], "seed_name": world.seed_name, "starting_items": world.starting_items[player], "recipes": recipes, "random": world.slot_seeds[player], "static_nodes": world.worlds[player].static_nodes, - "recipe_time_scale": recipe_time_scales[world.recipe_time[player].value]} + "recipe_time_scale": recipe_time_scales[world.recipe_time[player].value], + "free_sample_blacklist": {item : 1 for item in free_sample_blacklist}} for factorio_option in Options.factorio_options: template_data[factorio_option] = getattr(world, factorio_option)[player].value diff --git a/worlds/factorio/Technologies.py b/worlds/factorio/Technologies.py index 6754f5aa..06e265b6 100644 --- a/worlds/factorio/Technologies.py +++ b/worlds/factorio/Technologies.py @@ -99,6 +99,7 @@ class Machine(FactorioElement): self.name: str = name self.categories: set = categories + # recipes and technologies can share names in Factorio for technology_name in sorted(raw): data = raw[technology_name] @@ -125,7 +126,8 @@ for recipe_name, recipe_data in raw_recipes.items(): recipe = Recipe(recipe_name, recipe_data["category"], set(recipe_data["ingredients"]), set(recipe_data["products"])) recipes[recipe_name] = Recipe - if recipe.products.isdisjoint(recipe.ingredients) and "empty-barrel" not in recipe.products: # prevents loop recipes like uranium centrifuging + if recipe.products.isdisjoint( + recipe.ingredients) and "empty-barrel" not in recipe.products: # prevents loop recipes like uranium centrifuging for product_name in recipe.products: all_product_sources.setdefault(product_name, set()).add(recipe) @@ -153,6 +155,7 @@ def unlock_just_tech(recipe: Recipe, _done) -> Set[Technology]: current_technologies |= recursively_get_unlocking_technologies(ingredient_name, _done) return current_technologies + def unlock(recipe: Recipe, _done) -> Set[Technology]: current_technologies = set() current_technologies |= recipe.unlocking_technologies @@ -162,7 +165,9 @@ def unlock(recipe: Recipe, _done) -> Set[Technology]: return current_technologies -def recursively_get_unlocking_technologies(ingredient_name, _done=None, unlock_func=unlock_just_tech) -> Set[Technology]: + +def recursively_get_unlocking_technologies(ingredient_name, _done=None, unlock_func=unlock_just_tech) -> Set[ + Technology]: if _done: if ingredient_name in _done: return set() @@ -180,7 +185,6 @@ def recursively_get_unlocking_technologies(ingredient_name, _done=None, unlock_f return current_technologies - required_machine_technologies: Dict[str, FrozenSet[Technology]] = {} for ingredient_name in machines: required_machine_technologies[ingredient_name] = frozenset(recursively_get_unlocking_technologies(ingredient_name)) @@ -192,14 +196,14 @@ for machine in machines.values(): if machine != pot_source_machine \ and machine.categories.issuperset(pot_source_machine.categories) \ and required_machine_technologies[machine.name].issuperset( - required_machine_technologies[pot_source_machine.name]): + required_machine_technologies[pot_source_machine.name]): logically_useful = False break if logically_useful: logical_machines[machine.name] = machine -del(required_machine_technologies) +del (required_machine_technologies) machines_per_category: Dict[str: Set[Machine]] = {} for machine in logical_machines.values(): @@ -219,11 +223,11 @@ for ingredient_name in all_ingredient_names: required_technologies[ingredient_name] = frozenset( recursively_get_unlocking_technologies(ingredient_name, unlock_func=unlock)) - advancement_technologies: Set[str] = set() for technologies in required_technologies.values(): advancement_technologies |= {technology.name for technology in technologies} + @functools.lru_cache(10) def get_rocket_requirements(ingredients: Set[str]) -> Set[str]: techs = recursively_get_unlocking_technologies("rocket-silo") @@ -232,6 +236,8 @@ def get_rocket_requirements(ingredients: Set[str]) -> Set[str]: return {tech.name for tech in techs} +free_sample_blacklist = all_ingredient_names | {"rocket-part"} + rocket_recipes = { Options.MaxSciencePack.option_space_science_pack: {"rocket-control-unit": 10, "low-density-structure": 10, "rocket-fuel": 10}, @@ -247,4 +253,4 @@ rocket_recipes = { {"electronic-circuit": 10, "stone-brick": 10, "coal": 10}, Options.MaxSciencePack.option_automation_science_pack: {"copper-cable": 10, "iron-plate": 10, "wood": 10} -} \ No newline at end of file +}