Streamlined handle craftable logic by using itterable rather then tuple

Removed dict.keys as the dict itzelf already enumerates over keys
This commit is contained in:
Jarno Westhof
2025-08-31 22:05:46 +02:00
parent 5c7435e631
commit 8dc2a5606a
7 changed files with 16 additions and 18 deletions

View File

@@ -41,7 +41,7 @@ class CriticalPathCalculator:
self.configure_implicitly_unlocked_and_handcraftable_parts()
self.select_minimal_required_parts_for(
self.logic.space_elevator_tiers[self.final_elevator_package-1].keys())
self.logic.space_elevator_tiers[self.final_elevator_package-1])
for tree in self.logic.man_trees.values():
self.select_minimal_required_parts_for(tree.access_items)
@@ -50,7 +50,7 @@ class CriticalPathCalculator:
if node.minimal_tier > self.final_elevator_package:
continue
self.select_minimal_required_parts_for(node.unlock_cost.keys())
self.select_minimal_required_parts_for(node.unlock_cost)
self.select_minimal_required_parts_for_building("MAM")
self.select_minimal_required_parts_for_building("AWESOME Sink")

View File

@@ -588,8 +588,6 @@ class GameLogic:
#For exclusion logic
"Hoverpack": (
Recipe("Hoverpack", "Equipment Workshop", ("Motor", "Heavy Modular Frame", "Computer", "Alclad Aluminum Sheet")), ),
"Rifle Ammo": (
Recipe("Rifle Ammo", "Assembler", ("Copper Sheet", "Smokeless Powder"), minimal_belt_speed=2), ),
"Turbo Rifle Ammo": (
Recipe("Turbo Rifle Ammo", "Blender", ("Rifle Ammo", "Aluminum Casing", "Turbofuel"), minimal_belt_speed=3),
Recipe("Turbo Rifle Ammo (Packaged)", "Manufacturer", ("Rifle Ammo", "Aluminum Casing", "Packaged Turbofuel"), minimal_belt_speed=2, minimal_tier=2)),

View File

@@ -93,7 +93,7 @@ class ElevatorTier(LocationData):
def __init__(self, tier: int, state_logic: StateLogic, game_logic: GameLogic):
super().__init__("Overworld", f"Elevator Tier {tier + 1}", EventId,
rule = lambda state: state_logic.can_build(state, "Space Elevator") and \
state_logic.can_produce_all(state, game_logic.space_elevator_tiers[tier].keys()))
state_logic.can_produce_all(state, game_logic.space_elevator_tiers[tier]))
class HubSlot(LocationData):

View File

@@ -26,7 +26,7 @@ class PlacementLogic(Choice, metaclass=PlacementLogicMeta):
class ChoiceMapMeta(AssembleOptions):
def __new__(mcs, name: str, bases: tuple[type], attrs: dict[Any, Any]) -> "ChoiceMapMeta":
if "choices" in attrs:
for index, choice in enumerate(attrs["choices"].keys()):
for index, choice in enumerate(attrs["choices"]):
option_name = "option_" + choice.replace(' ', '_')
attrs[option_name] = index
@@ -40,10 +40,9 @@ class ChoiceMap(Choice, metaclass=ChoiceMapMeta):
choices: ClassVar[dict[str, list[str]]]
def get_selected_list(self) -> list[str]:
for index, choice in enumerate(self.choices.keys()):
for index, choice in enumerate(self.choices):
if index == self.value:
return self.choices[choice]
class ElevatorTier(NamedRange):
"""
Put these Shipments to Space Elevator packages in logic.

View File

@@ -67,7 +67,7 @@ def create_regions_and_return_locations(multiworld: MultiWorld, options: Satisfa
regions: dict[str, Region] = create_regions(multiworld, player, locations_per_region, region_names)
if __debug__:
throwIfAnyLocationIsNotAssignedToARegion(regions, locations_per_region.keys())
throwIfAnyLocationIsNotAssignedToARegion(regions, locations_per_region)
multiworld.regions += regions.values()
@@ -130,7 +130,7 @@ def create_regions_and_return_locations(multiworld: MultiWorld, options: Satisfa
for milestone, parts_per_milestone in enumerate(milestones_per_hub_tier, 1):
connect(regions, f"Hub Tier {hub_tier}", f"Hub {hub_tier}-{milestone}",
can_produce_all_allowing_handcrafting(parts_per_milestone.keys()))
can_produce_all_allowing_handcrafting(parts_per_milestone))
for building_name, building in game_logic.buildings.items():
if building.can_produce and building_name in critical_path.required_buildings:
@@ -146,19 +146,20 @@ def create_regions_and_return_locations(multiworld: MultiWorld, options: Satisfa
if not node.depends_on:
connect(regions, tree_name, f"{tree_name}: {node.name}",
lambda state, parts=node.unlock_cost.keys(): state_logic.can_produce_all(state, parts))
lambda state, parts=node.unlock_cost: state_logic.can_produce_all(state, parts))
else:
for parent in node.depends_on:
if f"{tree_name}: {parent}" in region_names:
connect(regions, f"{tree_name}: {parent}", f"{tree_name}: {node.name}",
lambda state, parts=node.unlock_cost.keys(): state_logic.can_produce_all(state, parts))
lambda state, parts=node.unlock_cost: state_logic.can_produce_all(state, parts))
def throwIfAnyLocationIsNotAssignedToARegion(regions: dict[str, Region], regionNames: set[str]):
existingRegions = set(regions.keys())
def throwIfAnyLocationIsNotAssignedToARegion(regions: dict[str, Region], regionNames: dict[str, LocationData]):
existingRegions = set(regions)
existingRegionNames = set(regionNames)
if (regionNames - existingRegions):
raise Exception(f"Satisfactory: the following regions are used in locations: {regionNames - existingRegions}, but no such region exists")
if (existingRegionNames - existingRegions):
raise Exception(f"Satisfactory: the following regions are used in locations: {existingRegionNames - existingRegions}, but no such region exists")
def create_region(multiworld: MultiWorld, player: int,

View File

@@ -46,7 +46,7 @@ class StateLogic:
state.has_all(map(self.to_part_event, parts), self.player)
def can_produce_all_allowing_handcrafting(self, state: CollectionState, logic: GameLogic,
parts: Optional[tuple[str, ...]]) -> bool:
parts: Optional[Iterable[str]]) -> bool:
def can_handcraft_part(part: str) -> bool:
if self.can_produce(state, part):

View File

@@ -93,7 +93,7 @@ class SatisfactoryWorld(World):
resource_sink_goal: bool = "AWESOME Sink Points (total)" in self.options.goal_selection \
or "AWESOME Sink Points (per minute)" in self.options.goal_selection
required_parts = set(self.game_logic.space_elevator_tiers[self.options.final_elevator_package.value - 1].keys())
required_parts = set(self.game_logic.space_elevator_tiers[self.options.final_elevator_package.value - 1])
if resource_sink_goal:
required_parts.union(self.game_logic.buildings["AWESOME Sink"].inputs)