diff --git a/worlds/satisfactory/CriticalPathCalculator.py b/worlds/satisfactory/CriticalPathCalculator.py index 39c09a1122..fa0ea7e0a7 100644 --- a/worlds/satisfactory/CriticalPathCalculator.py +++ b/worlds/satisfactory/CriticalPathCalculator.py @@ -242,7 +242,8 @@ class CriticalPathCalculator: self.tier_0_recipes.add(self.random.choice(("Recipe: Silica", "Recipe: Cheap Silica"))) selected_recipe = self.random.choice( - ("Recipe: Screw", "Recipe: Screw","Recipe: Cast Screw", "Recipe: Cast Screw", "Recipe: Steel Screw")) + ("Recipe: Screw", "Recipe: Screw", "Recipe: Cast Screw", "Recipe: Cast Screw", "Recipe: Steel Screw")) + self.tier_0_recipes.add(selected_recipe) if selected_recipe == "Recipe: Steel Screw": # add Steel Beam and steel Ingot diff --git a/worlds/satisfactory/GameLogic.py b/worlds/satisfactory/GameLogic.py index 40947fcbfe..76f40d3dc6 100644 --- a/worlds/satisfactory/GameLogic.py +++ b/worlds/satisfactory/GameLogic.py @@ -96,7 +96,7 @@ class Building(Recipe): self.implicitly_unlocked = implicitly_unlocked -class MamNode(): +class MamNode: name: str unlock_cost: dict[str, int] """All game items must be submitted to purchase this MamNode""" diff --git a/worlds/satisfactory/Items.py b/worlds/satisfactory/Items.py index 79d59c7497..7afa523cca 100644 --- a/worlds/satisfactory/Items.py +++ b/worlds/satisfactory/Items.py @@ -859,7 +859,7 @@ class Items: "Single: Gas Filter": ItemData(G.Equipment, 1339187, count=0) } - item_names_and_ids: ClassVar[dict[str, int]] = {name: item_data.code for name, item_data in item_data.items()} + item_names_and_ids: ClassVar[dict[str, int]] = {name: data.code for name, data in item_data.items()} filler_items: ClassVar[tuple[str, ...]] = tuple(item for item, details in item_data.items() if details.count > 0 and details.category & (G.Parts | G.Ammo)) @@ -893,7 +893,7 @@ class Items: critical_path: CriticalPathCalculator trap_chance: int - enabled_traps: tuple[str] + enabled_traps: tuple[str, ...] def __init__(self, player: Optional[int], logic: GameLogic, random: Random, options: SatisfactoryOptions, critical_path: CriticalPathCalculator): diff --git a/worlds/satisfactory/Locations.py b/worlds/satisfactory/Locations.py index e91cdd212d..b8abcb60f8 100644 --- a/worlds/satisfactory/Locations.py +++ b/worlds/satisfactory/Locations.py @@ -325,8 +325,8 @@ class Locations(): location_table = self.get_base_location_table(max_tier_for_game) location_table.extend(self.get_hub_locations(False, max_tier_for_game)) - location_table.extend(self.get_hard_drive_locations(False, max_tier_for_game,self.critical_path.required_parts)) - location_table.extend(self.get_logical_event_locations(self.options.final_elevator_package)) + location_table.extend(self.get_hard_drive_locations(False, max_tier_for_game, self.critical_path.required_parts)) + location_table.extend(self.get_logical_event_locations(self.options.final_elevator_package.value)) return location_table @@ -334,8 +334,8 @@ class Locations(): location_table: list[LocationData] = [] number_of_slots_per_milestone_for_game: int - if (for_data_package): - number_of_slots_per_milestone_for_game = self.max_slots + if for_data_package: + number_of_slots_per_milestone_for_game = self.max_slots else: if self.options.final_elevator_package <= 2: number_of_slots_per_milestone_for_game = self.max_slots @@ -363,7 +363,7 @@ class Locations(): location_table: list[LocationData] = [] # for performance plan is to upfront calculated everything we need - # and than create one massive state.has_all for each logical gate (hub tiers, elevator tiers) + # and then create one massive state.has_all for each logical gate (hub tiers, elevator tiers) location_table.extend( ElevatorTier(index, self.state_logic, self.game_logic) @@ -398,7 +398,7 @@ class Locations(): bucket_size = floor((self.drop_pod_location_id_end - self.drop_pod_location_id_start) / max_tier) drop_pod_data: list[DropPodData] = self.game_logic.drop_pods # sort, easily obtainable first, should be deterministic - drop_pod_data.sort(key = lambda data: ("!" if data.item == None else data.item) + str(data.x - data.z)) + drop_pod_data.sort(key=lambda data: ("!" if data.item is None else data.item) + str(data.x - data.z)) for location_id in range(self.drop_pod_location_id_start, self.drop_pod_location_id_end + 1): if for_data_package: @@ -414,4 +414,4 @@ class Locations(): hard_drive_locations.append( HardDrive(data, self.state_logic, location_id, tier, can_hold_progression)) - return hard_drive_locations \ No newline at end of file + return hard_drive_locations diff --git a/worlds/satisfactory/Options.py b/worlds/satisfactory/Options.py index 0d60a80a51..f05eeeaaf9 100644 --- a/worlds/satisfactory/Options.py +++ b/worlds/satisfactory/Options.py @@ -439,6 +439,7 @@ class GoalSelection(OptionSet): """ What will be your goal(s)? Configure them further with other options. + Possible values are "Space Elevator Tier", "AWESOME Sink Points (total)", "AWESOME Sink Points (per minute)", and "Exploration Collectables". """ display_name = "Select your Goals" valid_keys = { diff --git a/worlds/satisfactory/Regions.py b/worlds/satisfactory/Regions.py index 4dbdcaf641..75b180b472 100644 --- a/worlds/satisfactory/Regions.py +++ b/worlds/satisfactory/Regions.py @@ -63,7 +63,7 @@ def create_regions_and_return_locations(multiworld: MultiWorld, options: Satisfa if node.minimal_tier <= options.final_elevator_package: region_names.append(f"{tree_name}: {node.name}") - locations_per_region: dict[str, LocationData] = get_locations_per_region(locations) + locations_per_region: dict[str, list[LocationData]] = get_locations_per_region(locations) regions: dict[str, Region] = create_regions(multiworld, player, locations_per_region, region_names) if __debug__: @@ -135,7 +135,7 @@ def create_regions_and_return_locations(multiworld: MultiWorld, options: Satisfa for building_name, building in game_logic.buildings.items(): if building.can_produce and building_name in critical_path.required_buildings: connect(regions, "Overworld", building_name, - lambda state, building_name=building_name: state_logic.can_build(state, building_name)) + lambda state, name=building_name: state_logic.can_build(state, name)) for tree_name, tree in game_logic.man_trees.items(): connect(regions, "Mam", tree_name) diff --git a/worlds/satisfactory/StateLogic.py b/worlds/satisfactory/StateLogic.py index 01f00dd588..e622b70fc8 100644 --- a/worlds/satisfactory/StateLogic.py +++ b/worlds/satisfactory/StateLogic.py @@ -42,7 +42,7 @@ class StateLogic: return power_level is None or state.has(building_event_prefix + power_level.to_name(), self.player) def can_produce_all(self, state: CollectionState, parts: Optional[Iterable[str]]) -> bool: - return parts is None or \ + return parts is None or \ state.has_all(map(self.to_part_event, parts), self.player) def can_produce_all_allowing_handcrafting(self, state: CollectionState, logic: GameLogic, diff --git a/worlds/satisfactory/__init__.py b/worlds/satisfactory/__init__.py index 06829746f4..5d96027227 100644 --- a/worlds/satisfactory/__init__.py +++ b/worlds/satisfactory/__init__.py @@ -122,12 +122,12 @@ class SatisfactoryWorld(World): for tier, milestones in enumerate(self.game_logic.hub_layout, 1): slot_hub_layout.append([]) for milestone, parts in enumerate(milestones, 1): - slot_hub_layout[tier - 1].append({}) - for part, amount in parts.items(): + slot_hub_layout[tier - 1].append({}) + for part, amount in parts.items(): multiplied_amount = int(max(amount * (self.options.milestone_cost_multiplier / 100), 1)) slot_hub_layout[tier-1][milestone-1][self.item_id_str(part)] = multiplied_amount - starting_recipes: tuple[int] = tuple( + starting_recipes: tuple[int, ...] = tuple( self.item_name_to_id[recipe_name] for recipe_name in self.critical_path.tier_0_recipes ) @@ -176,10 +176,10 @@ class SatisfactoryWorld(World): """Used by Universal Tracker to correctly rebuild state""" slot_data: dict[str, Any] | None = None - if hasattr(self.multiworld, "re_gen_passthrough") \ - and isinstance(self.multiworld.re_gen_passthrough, dict) \ - and "Satisfactory" in self.multiworld.re_gen_passthrough: - slot_data = self.multiworld.re_gen_passthrough["Satisfactory"] + if (hasattr(self.multiworld, "re_gen_passthrough") + and isinstance(self.multiworld.re_gen_passthrough, dict) + and "Satisfactory" in self.multiworld.re_gen_passthrough): + slot_data = self.multiworld.re_gen_passthrough["Satisfactory"] if not slot_data: return