clean up technology handling a bit
This commit is contained in:
parent
0eca0b2209
commit
635897574f
|
@ -142,7 +142,7 @@ async def factorio_server_watcher(ctx: FactorioContext):
|
|||
while ctx.send_index < len(ctx.items_received):
|
||||
item_id = ctx.items_received[ctx.send_index].item
|
||||
if item_id not in lookup_id_to_name:
|
||||
logging.error(f"Unknown item ID: {item_id}")
|
||||
logging.error(f"Cannot send unknown item ID: {item_id}")
|
||||
else:
|
||||
item_name = lookup_id_to_name[item_id]
|
||||
factorio_server_logger.info(f"Sending {item_name} to Nauvis.")
|
||||
|
|
|
@ -9,6 +9,7 @@ from .alttp.Items import lookup_id_to_name as alttp
|
|||
from .hk.Items import lookup_id_to_name as hk
|
||||
from .factorio import Technologies
|
||||
lookup_any_item_id_to_name = {**alttp, **hk, **Technologies.lookup_id_to_name}
|
||||
assert len(alttp) + len(hk) + len(Technologies.lookup_id_to_name) == len(lookup_any_item_id_to_name)
|
||||
lookup_any_item_name_to_id = {name: id for id, name in lookup_any_item_id_to_name.items()}
|
||||
|
||||
|
||||
|
@ -16,6 +17,8 @@ from .alttp import Regions
|
|||
from .hk import Locations
|
||||
lookup_any_location_id_to_name = {**Regions.lookup_id_to_name, **Locations.lookup_id_to_name,
|
||||
**Technologies.lookup_id_to_name}
|
||||
assert len(Regions.lookup_id_to_name) + len(Locations.lookup_id_to_name) + len(Technologies.lookup_id_to_name) == \
|
||||
len(lookup_any_location_id_to_name)
|
||||
lookup_any_location_name_to_id = {name: id for id, name in lookup_any_location_id_to_name.items()}
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# Factorio technologies are imported from a .json document in /data
|
||||
from typing import Dict
|
||||
import os
|
||||
from typing import Dict, Set
|
||||
import json
|
||||
|
||||
import Utils
|
||||
|
||||
factorio_id = 2 ** 17
|
||||
|
@ -12,33 +10,49 @@ source_file = Utils.local_path("data", "factorio", "techs.json")
|
|||
with open(source_file) as f:
|
||||
raw = json.load(f)
|
||||
tech_table = {}
|
||||
technology_table = {}
|
||||
requirements = {} # tech_name -> Set[required_technologies]
|
||||
|
||||
requirements = {}
|
||||
ingredients = {}
|
||||
all_ingredients = set()
|
||||
|
||||
# TODO: export this dynamically, or filter it during export
|
||||
starting_ingredient_recipes = {"automation-science-pack"}
|
||||
class Technology(): # maybe make subclass of Location?
|
||||
def __init__(self, name, ingredients):
|
||||
self.name = name
|
||||
global factorio_id
|
||||
self.factorio_id = factorio_id
|
||||
factorio_id += 1
|
||||
self.ingredients = ingredients
|
||||
|
||||
def get_required_technologies(self):
|
||||
requirements = set()
|
||||
for ingredient in self.ingredients:
|
||||
if ingredient in recipe_sources: # no source likely means starting item
|
||||
requirements |= recipe_sources[ingredient] # technically any, not all, need to improve later
|
||||
return requirements
|
||||
|
||||
def __hash__(self):
|
||||
return self.factorio_id
|
||||
|
||||
|
||||
# recipes and technologies can share names in Factorio
|
||||
for technology in sorted(raw):
|
||||
data = raw[technology]
|
||||
tech_table[technology] = factorio_id
|
||||
factorio_id += 1
|
||||
if data["requires"]:
|
||||
requirements[technology] = set(data["requires"])
|
||||
current_ingredients = set(data["ingredients"])-starting_ingredient_recipes
|
||||
if current_ingredients:
|
||||
all_ingredients |= current_ingredients
|
||||
ingredients[technology] = {"recipe-"+ingredient for ingredient in current_ingredients}
|
||||
for technology_name in sorted(raw):
|
||||
data = raw[technology_name]
|
||||
|
||||
recipe_sources = {}
|
||||
factorio_id += 1
|
||||
# not used yet
|
||||
# if data["requires"]:
|
||||
# requirements[technology] = set(data["requires"])
|
||||
current_ingredients = set(data["ingredients"])
|
||||
technology = Technology(technology_name, current_ingredients)
|
||||
tech_table[technology_name] = technology.factorio_id
|
||||
technology_table[technology_name] = technology
|
||||
|
||||
|
||||
recipe_sources = {} # recipe_name -> technology source
|
||||
|
||||
for technology, data in raw.items():
|
||||
recipe_source = all_ingredients & set(data["unlocks"])
|
||||
for recipe in recipe_source:
|
||||
recipe_sources["recipe-"+recipe] = technology
|
||||
for recipe in data["unlocks"]:
|
||||
recipe_sources.setdefault(recipe, set()).add(technology)
|
||||
|
||||
|
||||
all_ingredients_recipe = {"recipe-"+ingredient for ingredient in all_ingredients}
|
||||
del (raw)
|
||||
lookup_id_to_name: Dict[int, str] = {item_id: item_name for item_name, item_id in tech_table.items()}
|
|
@ -2,7 +2,7 @@ import logging
|
|||
|
||||
from BaseClasses import Region, Entrance, Location, MultiWorld, Item
|
||||
|
||||
from .Technologies import tech_table, requirements, ingredients, all_ingredients, recipe_sources, all_ingredients_recipe
|
||||
from .Technologies import tech_table, requirements, recipe_sources, technology_table
|
||||
|
||||
static_nodes = {"automation", "logistics"}
|
||||
|
||||
|
@ -30,11 +30,6 @@ def factorio_create_regions(world: MultiWorld, player: int):
|
|||
tech = Location(player, tech_name, tech_id, nauvis)
|
||||
nauvis.locations.append(tech)
|
||||
tech.game = "Factorio"
|
||||
for ingredient in all_ingredients_recipe: # register science packs as events
|
||||
ingredient_location = Location(player, ingredient, 0, nauvis)
|
||||
ingredient_location.item = Item(ingredient, True, 0, player)
|
||||
ingredient_location.event = ingredient_location.locked = True
|
||||
menu.locations.append(ingredient_location)
|
||||
crash.connect(nauvis)
|
||||
world.regions += [menu, nauvis]
|
||||
|
||||
|
@ -42,18 +37,13 @@ def factorio_create_regions(world: MultiWorld, player: int):
|
|||
def set_rules(world: MultiWorld, player: int):
|
||||
if world.logic[player] != 'nologic':
|
||||
from worlds.generic import Rules
|
||||
for tech_name in tech_table:
|
||||
# vanilla layout, to be implemented
|
||||
# rules = requirements.get(tech_name, set()) | ingredients.get(tech_name, set())
|
||||
for tech_name, technology in technology_table.items():
|
||||
# loose nodes
|
||||
rules = ingredients.get(tech_name, set())
|
||||
rules = technology.get_required_technologies()
|
||||
if rules:
|
||||
location = world.get_location(tech_name, player)
|
||||
Rules.set_rule(location, lambda state, rules=rules: all(state.has(rule, player) for rule in rules))
|
||||
|
||||
for recipe, technology in recipe_sources.items():
|
||||
Rules.set_rule(world.get_location(recipe, player), lambda state, tech=technology: state.has(tech, player))
|
||||
|
||||
|
||||
world.completion_condition[player] = lambda state: all(state.has(ingredient, player)
|
||||
for ingredient in all_ingredients_recipe)
|
||||
# get all technologies
|
||||
world.completion_condition[player] = lambda state: all(state.has(technology, player)
|
||||
for technology in tech_table)
|
||||
|
|
Loading…
Reference in New Issue