Files
Archipelago/worlds/satisfactory/CriticalPathCalculator.py
2025-03-11 23:14:40 +01:00

142 lines
6.1 KiB
Python

from random import Random
from typing import Optional
from collections.abc import Iterable
from .GameLogic import GameLogic, Recipe
from .Options import SatisfactoryOptions
from .Options import SatisfactoryOptions
class CriticalPathCalculator:
logic: GameLogic
random: Random
potential_required_parts: set[str]
potential_required_buildings: set[str]
potential_required_belt_speed: int
potential_required_pipes: bool
potential_required_radioactive: bool
potential_required_power: int
potential_required_recipes_names: set[str]
def __init__(self, logic: GameLogic, random: Random, options: SatisfactoryOptions):
self.logic = logic
self.random = random
self.options = options
self.potential_required_parts = set()
self.potential_required_buildings = set()
self.potential_required_belt_speed = 1
self.potential_required_pipes = False
self.potential_required_radioactive = False
self.potential_required_power: int = 1
selected_power_infrastructure: dict[int, Recipe] = {}
self.select_minimal_required_parts_for(self.logic.space_elevator_tiers[options.final_elevator_package-1].keys())
for tree in self.logic.man_trees.values():
self.select_minimal_required_parts_for(tree.access_items)
for node in tree.nodes:
# Bullet Guidance System - Rifle Ammo
# Stun Rebar - Iron Rebar
# Radar Technology - Heavy Modular Frame
# Turbo Rifle Ammo - Packaged Turbofuel, Rifle Ammo
# Nuclear Deterrent Development - Encased Uranium Cell
# Rocket Fuel - Packaged Turbofuel
# Ionized Fuel - Ionized Fuel
if node.name == "Hostile Organism Detection":
Debug = True
if node.minimal_tier > options.final_elevator_package:
continue
self.select_minimal_required_parts_for(node.unlock_cost.keys())
self.select_minimal_required_parts_for_building("MAM")
self.select_minimal_required_parts_for_building("AWESOME Sink")
self.select_minimal_required_parts_for_building("AWESOME Shop")
self.select_minimal_required_parts_for_building("Space Elevator")
self.select_minimal_required_parts_for_building("Conveyor Splitter")
self.select_minimal_required_parts_for_building("Conveyor Merger")
self.select_minimal_required_parts_for_building("Equipment Workshop")
self.select_minimal_required_parts_for_building("Foundation")
self.select_minimal_required_parts_for_building("Walls Orange")
self.select_minimal_required_parts_for_building("Power Storage")
for i in range(1, self.potential_required_belt_speed + 1):
self.select_minimal_required_parts_for_building(f"Conveyor Mk.{i}")
if self.potential_required_pipes:
self.select_minimal_required_parts_for_building("Pipes Mk.1")
self.select_minimal_required_parts_for_building("Pipeline Pump Mk.1")
if self.potential_required_radioactive:
self.select_minimal_required_parts_for(self.logic.recipes["Hazmat Suit"][0].inputs)
self.select_minimal_required_parts_for(self.logic.recipes["Iodine Infused Filter"][0].inputs)
for i in range(1, self.potential_required_power + 1):
power_recipe = random.choice(self.logic.requirement_per_powerlevel[i])
selected_power_infrastructure[i] = power_recipe
self.select_minimal_required_parts_for(power_recipe.inputs)
self.select_minimal_required_parts_for_building(power_recipe.building)
self.potential_required_recipes_names = set(
recipe.name
for part in self.potential_required_parts
for recipe in self.logic.recipes[part]
if recipe.minimal_tier <= self.options.final_elevator_package
)
self.potential_required_recipes_names.update(
"Building: "+ building
for building in self.potential_required_buildings
)
debug = True
def select_minimal_required_parts_for_building(self, building: str) -> None:
self.select_minimal_required_parts_for(self.logic.buildings[building].inputs)
self.potential_required_buildings.add(building)
def select_minimal_required_parts_for(self, parts: Optional[Iterable[str]]) -> None:
if parts is None:
return
for part in parts:
if part in self.potential_required_parts:
continue
if part == "Radio Control Unit":
Debug = True
self.potential_required_parts.add(part)
for recipe in self.logic.recipes[part]:
if part == "Fuel":
Debug = True
if recipe.minimal_tier > self.options.final_elevator_package:
continue
if recipe.minimal_belt_speed == 5:
Debug = True
self.potential_required_belt_speed = \
max(self.potential_required_belt_speed, recipe.minimal_belt_speed)
self.select_minimal_required_parts_for(recipe.inputs)
if recipe.needs_pipes:
self.potential_required_pipes = True
if recipe.is_radio_active:
self.potential_required_radioactive = True
if recipe.building:
if recipe.building == "Blender":
debug = True
self.select_minimal_required_parts_for(self.logic.buildings[recipe.building].inputs)
self.potential_required_buildings.add(recipe.building)
if self.logic.buildings[recipe.building].power_requirement:
self.potential_required_power = \
max(self.potential_required_power,
self.logic.buildings[recipe.building].power_requirement)
debug = True