Factorio: fix impossible recipes requiring stacking non-stacking items
Factorio: speedup load time
This commit is contained in:
parent
2045905c9b
commit
a5d516e179
|
@ -1,25 +1,33 @@
|
|||
from __future__ import annotations
|
||||
# Factorio technologies are imported from a .json document in /data
|
||||
from typing import Dict, Set, FrozenSet, Tuple, Union, List
|
||||
from collections import Counter
|
||||
import os
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import string
|
||||
from collections import Counter
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from typing import Dict, Set, FrozenSet, Tuple, Union, List
|
||||
|
||||
import Utils
|
||||
import logging
|
||||
|
||||
from . import Options
|
||||
|
||||
factorio_id = factorio_base_id = 2 ** 17
|
||||
# Factorio technologies are imported from a .json document in /data
|
||||
source_folder = os.path.join(os.path.dirname(__file__), "data")
|
||||
|
||||
with open(os.path.join(source_folder, "techs.json")) as f:
|
||||
raw = json.load(f)
|
||||
with open(os.path.join(source_folder, "recipes.json")) as f:
|
||||
raw_recipes = json.load(f)
|
||||
with open(os.path.join(source_folder, "machines.json")) as f:
|
||||
raw_machines = json.load(f)
|
||||
pool = ThreadPoolExecutor(1)
|
||||
|
||||
|
||||
def load_json_data(data_name: str) -> dict:
|
||||
with open(os.path.join(source_folder, f"{data_name}.json")) as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
techs_future = pool.submit(load_json_data, "techs")
|
||||
recipes_future = pool.submit(load_json_data, "recipes")
|
||||
machines_future = pool.submit(load_json_data, "machines")
|
||||
items_future = pool.submit(load_json_data, "items")
|
||||
|
||||
tech_table: Dict[str, int] = {}
|
||||
technology_table: Dict[str, Technology] = {}
|
||||
|
||||
|
@ -177,8 +185,7 @@ class Machine(FactorioElement):
|
|||
recipe_sources: Dict[str, Set[str]] = {} # recipe_name -> technology source
|
||||
|
||||
# recipes and technologies can share names in Factorio
|
||||
for technology_name in sorted(raw):
|
||||
data = raw[technology_name]
|
||||
for technology_name, data in sorted(techs_future.result().items()):
|
||||
current_ingredients = set(data["ingredients"])
|
||||
technology = Technology(technology_name, current_ingredients, factorio_id,
|
||||
has_modifier=data["has_modifier"], unlocks=set(data["unlocks"]))
|
||||
|
@ -188,11 +195,14 @@ for technology_name in sorted(raw):
|
|||
for recipe_name in technology.unlocks:
|
||||
recipe_sources.setdefault(recipe_name, set()).add(technology_name)
|
||||
|
||||
del (raw)
|
||||
del techs_future
|
||||
|
||||
recipes = {}
|
||||
all_product_sources: Dict[str, Set[Recipe]] = {"character": set()}
|
||||
# add uranium mining to logic graph. TODO: add to automatic extractor for mod support
|
||||
raw_recipes = recipes_future.result()
|
||||
del recipes_future
|
||||
|
||||
raw_recipes["uranium-ore"] = {
|
||||
"ingredients": {"sulfuric-acid": 1},
|
||||
"products": {"uranium-ore": 1},
|
||||
|
@ -225,11 +235,10 @@ for recipe_name, recipe_data in raw_recipes.items():
|
|||
for product_name in recipe.products:
|
||||
all_product_sources.setdefault(product_name, set()).add(recipe)
|
||||
|
||||
del (raw_recipes)
|
||||
|
||||
machines: Dict[str, Machine] = {}
|
||||
|
||||
for name, categories in raw_machines.items():
|
||||
for name, categories in machines_future.result().items():
|
||||
machine = Machine(name, set(categories))
|
||||
machines[name] = machine
|
||||
|
||||
|
@ -238,7 +247,8 @@ machines["electric-mining-drill"] = Machine("electric-mining-drill", {"mining"})
|
|||
machines["pumpjack"] = Machine("pumpjack", {"basic-fluid"})
|
||||
machines["assembling-machine-1"].categories.add("crafting-with-fluid") # mod enables this
|
||||
machines["character"].categories.add("basic-crafting") # somehow this is implied and not exported
|
||||
del (raw_machines)
|
||||
|
||||
del machines_future
|
||||
|
||||
# build requirements graph for all technology ingredients
|
||||
|
||||
|
@ -504,3 +514,12 @@ def get_science_pack_pools() -> Dict[str, Set[str]]:
|
|||
already_taken |= current
|
||||
current_difficulty *= 2
|
||||
return science_pack_pools
|
||||
|
||||
|
||||
item_stack_sizes: Dict[str, int] = items_future.result()
|
||||
non_stacking_items: Set[str] = {item for item, stack in item_stack_sizes.items() if stack == 1}
|
||||
stacking_items: Set[str] = set(item_stack_sizes) - non_stacking_items
|
||||
|
||||
# cleanup async helpers
|
||||
pool.shutdown()
|
||||
del pool
|
||||
|
|
|
@ -8,7 +8,7 @@ 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, \
|
||||
liquids
|
||||
liquids, stacking_items
|
||||
from .Shapes import get_shapes
|
||||
from .Mod import generate_mod
|
||||
from .Options import factorio_options, MaxSciencePack, Silo, Satellite, TechTreeInformation, Goal
|
||||
|
@ -226,11 +226,14 @@ class Factorio(World):
|
|||
return Recipe(original.name, self.get_category(original.category, liquids_used), new_ingredients,
|
||||
original.products, original.energy)
|
||||
|
||||
def make_balanced_recipe(self, original: Recipe, pool: list, factor: float = 1, allow_liquids: int = 2) -> \
|
||||
Recipe:
|
||||
def make_balanced_recipe(self, original: Recipe, pool: typing.Set[str], factor: float = 1,
|
||||
allow_liquids: int = 2) -> Recipe:
|
||||
"""Generate a recipe from pool with time and cost similar to original * factor"""
|
||||
new_ingredients = {}
|
||||
pool = sorted(pool, key=lambda x: self.world.random.random())
|
||||
# have to first sort for determinism, while filtering out non-stacking items
|
||||
pool: typing.List[str] = sorted(pool & stacking_items)
|
||||
# then sort with random data to shuffle
|
||||
self.world.random.shuffle(pool)
|
||||
target_raw = int(sum((count for ingredient, count in original.base_cost.items())) * factor)
|
||||
target_energy = original.total_energy * factor
|
||||
target_num_ingredients = len(original.ingredients)
|
||||
|
@ -346,9 +349,9 @@ class Factorio(World):
|
|||
|
||||
if self.world.silo[self.player].value == Silo.option_randomize_recipe \
|
||||
or self.world.satellite[self.player].value == Satellite.option_randomize_recipe:
|
||||
valid_pool = []
|
||||
valid_pool = set()
|
||||
for pack in sorted(self.world.max_science_pack[self.player].get_allowed_packs()):
|
||||
valid_pool += sorted(science_pack_pools[pack])
|
||||
valid_pool |= science_pack_pools[pack]
|
||||
|
||||
if self.world.silo[self.player].value == Silo.option_randomize_recipe:
|
||||
new_recipe = self.make_balanced_recipe(recipes["rocket-silo"], valid_pool,
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"wooden-chest":50,"iron-chest":50,"steel-chest":50,"storage-tank":50,"transport-belt":100,"fast-transport-belt":100,"express-transport-belt":100,"underground-belt":50,"fast-underground-belt":50,"express-underground-belt":50,"splitter":50,"fast-splitter":50,"express-splitter":50,"loader":50,"fast-loader":50,"express-loader":50,"burner-inserter":50,"inserter":50,"long-handed-inserter":50,"fast-inserter":50,"filter-inserter":50,"stack-inserter":50,"stack-filter-inserter":50,"small-electric-pole":50,"medium-electric-pole":50,"big-electric-pole":50,"substation":50,"pipe":100,"pipe-to-ground":50,"pump":50,"rail":100,"train-stop":10,"rail-signal":50,"rail-chain-signal":50,"locomotive":5,"cargo-wagon":5,"fluid-wagon":5,"artillery-wagon":5,"car":1,"tank":1,"spidertron":1,"spidertron-remote":1,"logistic-robot":50,"construction-robot":50,"logistic-chest-active-provider":50,"logistic-chest-passive-provider":50,"logistic-chest-storage":50,"logistic-chest-buffer":50,"logistic-chest-requester":50,"roboport":10,"small-lamp":50,"red-wire":200,"green-wire":200,"arithmetic-combinator":50,"decider-combinator":50,"constant-combinator":50,"power-switch":50,"programmable-speaker":50,"stone-brick":100,"concrete":100,"hazard-concrete":100,"refined-concrete":100,"refined-hazard-concrete":100,"landfill":100,"cliff-explosives":20,"dummy-steel-axe":1,"repair-pack":100,"blueprint":1,"deconstruction-planner":1,"upgrade-planner":1,"blueprint-book":1,"copy-paste-tool":1,"cut-paste-tool":1,"boiler":50,"steam-engine":10,"solar-panel":50,"accumulator":50,"nuclear-reactor":10,"heat-pipe":50,"heat-exchanger":50,"steam-turbine":10,"burner-mining-drill":50,"electric-mining-drill":50,"offshore-pump":20,"pumpjack":20,"stone-furnace":50,"steel-furnace":50,"electric-furnace":50,"assembling-machine-1":50,"assembling-machine-2":50,"assembling-machine-3":50,"oil-refinery":10,"chemical-plant":10,"centrifuge":50,"lab":10,"beacon":10,"speed-module":50,"speed-module-2":50,"speed-module-3":50,"effectivity-module":50,"effectivity-module-2":50,"effectivity-module-3":50,"productivity-module":50,"productivity-module-2":50,"productivity-module-3":50,"rocket-silo":1,"satellite":1,"wood":100,"coal":50,"stone":50,"iron-ore":50,"copper-ore":50,"uranium-ore":50,"raw-fish":100,"iron-plate":100,"copper-plate":100,"solid-fuel":50,"steel-plate":100,"plastic-bar":100,"sulfur":50,"battery":200,"explosives":50,"crude-oil-barrel":10,"heavy-oil-barrel":10,"light-oil-barrel":10,"lubricant-barrel":10,"petroleum-gas-barrel":10,"sulfuric-acid-barrel":10,"water-barrel":10,"copper-cable":200,"iron-stick":100,"iron-gear-wheel":100,"empty-barrel":10,"electronic-circuit":200,"advanced-circuit":200,"processing-unit":100,"engine-unit":50,"electric-engine-unit":50,"flying-robot-frame":50,"rocket-control-unit":10,"low-density-structure":10,"rocket-fuel":10,"rocket-part":5,"nuclear-fuel":1,"uranium-235":100,"uranium-238":100,"uranium-fuel-cell":50,"used-up-uranium-fuel-cell":50,"automation-science-pack":200,"logistic-science-pack":200,"military-science-pack":200,"chemical-science-pack":200,"production-science-pack":200,"utility-science-pack":200,"space-science-pack":2000,"coin":100000,"pistol":5,"submachine-gun":5,"tank-machine-gun":1,"vehicle-machine-gun":1,"tank-flamethrower":1,"shotgun":5,"combat-shotgun":5,"rocket-launcher":5,"flamethrower":5,"land-mine":100,"artillery-wagon-cannon":1,"spidertron-rocket-launcher-1":1,"spidertron-rocket-launcher-2":1,"spidertron-rocket-launcher-3":1,"spidertron-rocket-launcher-4":1,"tank-cannon":1,"firearm-magazine":200,"piercing-rounds-magazine":200,"uranium-rounds-magazine":200,"shotgun-shell":200,"piercing-shotgun-shell":200,"cannon-shell":200,"explosive-cannon-shell":200,"uranium-cannon-shell":200,"explosive-uranium-cannon-shell":200,"artillery-shell":1,"rocket":200,"explosive-rocket":200,"atomic-bomb":10,"flamethrower-ammo":100,"grenade":100,"cluster-grenade":100,"poison-capsule":100,"slowdown-capsule":100,"defender-capsule":100,"distractor-capsule":100,"destroyer-capsule":100,"light-armor":1,"heavy-armor":1,"modular-armor":1,"power-armor":1,"power-armor-mk2":1,"solar-panel-equipment":20,"fusion-reactor-equipment":20,"battery-equipment":20,"battery-mk2-equipment":20,"belt-immunity-equipment":20,"exoskeleton-equipment":20,"personal-roboport-equipment":20,"personal-roboport-mk2-equipment":20,"night-vision-equipment":20,"energy-shield-equipment":20,"energy-shield-mk2-equipment":20,"personal-laser-defense-equipment":20,"discharge-defense-equipment":20,"discharge-defense-remote":1,"stone-wall":100,"gate":50,"gun-turret":50,"laser-turret":50,"flamethrower-turret":50,"artillery-turret":10,"artillery-targeting-remote":1,"radar":50,"player-port":50,"item-unknown":1,"electric-energy-interface":50,"linked-chest":10,"heat-interface":20,"linked-belt":10,"infinity-chest":10,"infinity-pipe":10,"selection-tool":1,"item-with-inventory":1,"item-with-label":1,"item-with-tags":1,"simple-entity-with-force":50,"simple-entity-with-owner":50,"burner-generator":10}
|
|
@ -0,0 +1 @@
|
|||
{"iron-ore":{"minable":true,"infinite":false,"category":"basic-solid","mining_time":1,"products":{"iron-ore":{"name":"iron-ore","amount":1}}},"copper-ore":{"minable":true,"infinite":false,"category":"basic-solid","mining_time":1,"products":{"copper-ore":{"name":"copper-ore","amount":1}}},"stone":{"minable":true,"infinite":false,"category":"basic-solid","mining_time":1,"products":{"stone":{"name":"stone","amount":1}}},"coal":{"minable":true,"infinite":false,"category":"basic-solid","mining_time":1,"products":{"coal":{"name":"coal","amount":1}}},"uranium-ore":{"minable":true,"infinite":false,"category":"basic-solid","mining_time":2,"required_fluid":"sulfuric-acid","fluid_amount":10,"products":{"uranium-ore":{"name":"uranium-ore","amount":1}}},"crude-oil":{"minable":true,"infinite":true,"infinite_depletion":10,"category":"basic-fluid","mining_time":1,"products":{"crude-oil":{"name":"crude-oil","amount":10}}}}
|
Loading…
Reference in New Issue