mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-28 02:43:22 -07:00
142 lines
6.1 KiB
Python
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 |