diff --git a/worlds/witness/hints.py b/worlds/witness/hints.py index dac7e3fb..82837aed 100644 --- a/worlds/witness/hints.py +++ b/worlds/witness/hints.py @@ -301,11 +301,11 @@ def hint_from_location(world: "WitnessWorld", location: str) -> Optional[Witness def get_item_and_location_names_in_random_order(world: "WitnessWorld", own_itempool: List["WitnessItem"]) -> Tuple[List[str], List[str]]: - prog_item_names_in_this_world = [ + progression_item_names_in_this_world = [ item.name for item in own_itempool if item.advancement and item.code and item.location ] - world.random.shuffle(prog_item_names_in_this_world) + world.random.shuffle(progression_item_names_in_this_world) locations_in_this_world = [ location for location in world.multiworld.get_locations(world.player) @@ -318,22 +318,24 @@ def get_item_and_location_names_in_random_order(world: "WitnessWorld", location_names_in_this_world = [location.name for location in locations_in_this_world] - return prog_item_names_in_this_world, location_names_in_this_world + return progression_item_names_in_this_world, location_names_in_this_world def make_always_and_priority_hints(world: "WitnessWorld", own_itempool: List["WitnessItem"], already_hinted_locations: Set[Location] ) -> Tuple[List[WitnessLocationHint], List[WitnessLocationHint]]: - prog_items_in_this_world, loc_in_this_world = get_item_and_location_names_in_random_order(world, own_itempool) + progression_items_in_this_world, locations_in_this_world = get_item_and_location_names_in_random_order( + world, own_itempool + ) always_items = [ item for item in get_always_hint_items(world) - if item in prog_items_in_this_world + if item in progression_items_in_this_world ] priority_items = [ item for item in get_priority_hint_items(world) - if item in prog_items_in_this_world + if item in progression_items_in_this_world ] if world.options.vague_hints: @@ -341,11 +343,11 @@ def make_always_and_priority_hints(world: "WitnessWorld", own_itempool: List["Wi else: always_locations = [ location for location in get_always_hint_locations(world) - if location in loc_in_this_world + if location in locations_in_this_world ] priority_locations = [ location for location in get_priority_hint_locations(world) - if location in loc_in_this_world + if location in locations_in_this_world ] # Get always and priority location/item hints @@ -376,7 +378,9 @@ def make_always_and_priority_hints(world: "WitnessWorld", own_itempool: List["Wi def make_extra_location_hints(world: "WitnessWorld", hint_amount: int, own_itempool: List["WitnessItem"], already_hinted_locations: Set[Location], hints_to_use_first: List[WitnessLocationHint], unhinted_locations_for_hinted_areas: Dict[str, Set[Location]]) -> List[WitnessWordedHint]: - prog_items_in_this_world, locations_in_this_world = get_item_and_location_names_in_random_order(world, own_itempool) + progression_items_in_this_world, locations_in_this_world = get_item_and_location_names_in_random_order( + world, own_itempool + ) next_random_hint_is_location = world.random.randrange(0, 2) @@ -390,7 +394,7 @@ def make_extra_location_hints(world: "WitnessWorld", hint_amount: int, own_itemp } while len(hints) < hint_amount: - if not prog_items_in_this_world and not locations_in_this_world and not hints_to_use_first: + if not progression_items_in_this_world and not locations_in_this_world and not hints_to_use_first: logging.warning(f"Ran out of items/locations to hint for player {world.player_name}.") break @@ -399,8 +403,8 @@ def make_extra_location_hints(world: "WitnessWorld", hint_amount: int, own_itemp location_hint = hints_to_use_first.pop() elif next_random_hint_is_location and locations_in_this_world: location_hint = hint_from_location(world, locations_in_this_world.pop()) - elif not next_random_hint_is_location and prog_items_in_this_world: - location_hint = hint_from_item(world, prog_items_in_this_world.pop(), own_itempool) + elif not next_random_hint_is_location and progression_items_in_this_world: + location_hint = hint_from_item(world, progression_items_in_this_world.pop(), own_itempool) # The list that the hint was supposed to be taken from was empty. # Try the other list, which has to still have something, as otherwise, all lists would be empty, # which would have triggered the guard condition above. @@ -587,9 +591,11 @@ def make_area_hints(world: "WitnessWorld", amount: int, already_hinted_locations hints = [] for hinted_area in hinted_areas: - hint_string, prog_amount, hunt_panels = word_area_hint(world, hinted_area, items_per_area[hinted_area]) + hint_string, progression_amount, hunt_panels = word_area_hint(world, hinted_area, items_per_area[hinted_area]) - hints.append(WitnessWordedHint(hint_string, None, f"hinted_area:{hinted_area}", prog_amount, hunt_panels)) + hints.append( + WitnessWordedHint(hint_string, None, f"hinted_area:{hinted_area}", progression_amount, hunt_panels) + ) if len(hinted_areas) < amount: logging.warning(f"Was not able to make {amount} area hints for player {world.player_name}. " diff --git a/worlds/witness/player_items.py b/worlds/witness/player_items.py index 3be298eb..831e614f 100644 --- a/worlds/witness/player_items.py +++ b/worlds/witness/player_items.py @@ -55,7 +55,7 @@ class WitnessPlayerItems: name: data for (name, data) in self.item_data.items() if data.classification not in {ItemClassification.progression, ItemClassification.progression_skip_balancing} - or name in player_logic.PROG_ITEMS_ACTUALLY_IN_THE_GAME + or name in player_logic.PROGRESSION_ITEMS_ACTUALLY_IN_THE_GAME } # Downgrade door items @@ -76,7 +76,7 @@ class WitnessPlayerItems: } for item_name, item_data in progression_dict.items(): if isinstance(item_data.definition, ProgressiveItemDefinition): - num_progression = len(self._logic.MULTI_LISTS[item_name]) + num_progression = len(self._logic.PROGRESSIVE_LISTS[item_name]) self._mandatory_items[item_name] = num_progression else: self._mandatory_items[item_name] = 1 diff --git a/worlds/witness/player_logic.py b/worlds/witness/player_logic.py index f8b7db35..fd866798 100644 --- a/worlds/witness/player_logic.py +++ b/worlds/witness/player_logic.py @@ -75,13 +75,15 @@ class WitnessPlayerLogic: self.UNREACHABLE_REGIONS: Set[str] = set() + self.THEORETICAL_BASE_ITEMS: Set[str] = set() self.THEORETICAL_ITEMS: Set[str] = set() - self.THEORETICAL_ITEMS_NO_MULTI: Set[str] = set() - self.MULTI_AMOUNTS: Dict[str, int] = defaultdict(lambda: 1) - self.MULTI_LISTS: Dict[str, List[str]] = {} - self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI: Set[str] = set() - self.PROG_ITEMS_ACTUALLY_IN_THE_GAME: Set[str] = set() + self.BASE_PROGESSION_ITEMS_ACTUALLY_IN_THE_GAME: Set[str] = set() + self.PROGRESSION_ITEMS_ACTUALLY_IN_THE_GAME: Set[str] = set() + + self.PARENT_ITEM_COUNT_PER_BASE_ITEM: Dict[str, int] = defaultdict(lambda: 1) + self.PROGRESSIVE_LISTS: Dict[str, List[str]] = {} self.DOOR_ITEMS_BY_ID: Dict[str, List[str]] = {} + self.STARTING_INVENTORY: Set[str] = set() self.DIFFICULTY = world.options.puzzle_randomization @@ -183,13 +185,13 @@ class WitnessPlayerLogic: # Remove any items that don't actually exist in the settings (e.g. Symbol Shuffle turned off) these_items = frozenset({ - subset.intersection(self.THEORETICAL_ITEMS_NO_MULTI) + subset.intersection(self.THEORETICAL_BASE_ITEMS) for subset in these_items }) # Update the list of "items that are actually being used by any entity" for subset in these_items: - self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI.update(subset) + self.BASE_PROGESSION_ITEMS_ACTUALLY_IN_THE_GAME.update(subset) # Handle door entities (door shuffle) if entity_hex in self.DOOR_ITEMS_BY_ID: @@ -197,7 +199,7 @@ class WitnessPlayerLogic: door_items = frozenset({frozenset([item]) for item in self.DOOR_ITEMS_BY_ID[entity_hex]}) for dependent_item in door_items: - self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI.update(dependent_item) + self.BASE_PROGESSION_ITEMS_ACTUALLY_IN_THE_GAME.update(dependent_item) these_items = logical_and_witness_rules([door_items, these_items]) @@ -299,10 +301,10 @@ class WitnessPlayerLogic: self.THEORETICAL_ITEMS.add(item_name) if isinstance(static_witness_logic.ALL_ITEMS[item_name], ProgressiveItemDefinition): - self.THEORETICAL_ITEMS_NO_MULTI.update(cast(ProgressiveItemDefinition, - static_witness_logic.ALL_ITEMS[item_name]).child_item_names) + self.THEORETICAL_BASE_ITEMS.update(cast(ProgressiveItemDefinition, + static_witness_logic.ALL_ITEMS[item_name]).child_item_names) else: - self.THEORETICAL_ITEMS_NO_MULTI.add(item_name) + self.THEORETICAL_BASE_ITEMS.add(item_name) if static_witness_logic.ALL_ITEMS[item_name].category in [ItemCategory.DOOR, ItemCategory.LASER]: entity_hexes = cast(DoorItemDefinition, static_witness_logic.ALL_ITEMS[item_name]).panel_id_hexes @@ -316,11 +318,11 @@ class WitnessPlayerLogic: self.THEORETICAL_ITEMS.discard(item_name) if isinstance(static_witness_logic.ALL_ITEMS[item_name], ProgressiveItemDefinition): - self.THEORETICAL_ITEMS_NO_MULTI.difference_update( + self.THEORETICAL_BASE_ITEMS.difference_update( cast(ProgressiveItemDefinition, static_witness_logic.ALL_ITEMS[item_name]).child_item_names ) else: - self.THEORETICAL_ITEMS_NO_MULTI.discard(item_name) + self.THEORETICAL_BASE_ITEMS.discard(item_name) if static_witness_logic.ALL_ITEMS[item_name].category in [ItemCategory.DOOR, ItemCategory.LASER]: entity_hexes = cast(DoorItemDefinition, static_witness_logic.ALL_ITEMS[item_name]).panel_id_hexes @@ -843,7 +845,7 @@ class WitnessPlayerLogic: self.REQUIREMENTS_BY_HEX = {} self.USED_EVENT_NAMES_BY_HEX = defaultdict(list) self.CONNECTIONS_BY_REGION_NAME = {} - self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI = set() + self.BASE_PROGESSION_ITEMS_ACTUALLY_IN_THE_GAME = set() # Make independent requirements for entities for entity_hex in self.DEPENDENT_REQUIREMENTS_BY_HEX.keys(): @@ -868,18 +870,18 @@ class WitnessPlayerLogic: """ Finalise which items are used in the world, and handle their progressive versions. """ - for item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI: + for item in self.BASE_PROGESSION_ITEMS_ACTUALLY_IN_THE_GAME: if item not in self.THEORETICAL_ITEMS: progressive_item_name = static_witness_logic.get_parent_progressive_item(item) - self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.add(progressive_item_name) + self.PROGRESSION_ITEMS_ACTUALLY_IN_THE_GAME.add(progressive_item_name) child_items = cast(ProgressiveItemDefinition, static_witness_logic.ALL_ITEMS[progressive_item_name]).child_item_names - multi_list = [child_item for child_item in child_items - if child_item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI] - self.MULTI_AMOUNTS[item] = multi_list.index(item) + 1 - self.MULTI_LISTS[progressive_item_name] = multi_list + progressive_list = [child_item for child_item in child_items + if child_item in self.BASE_PROGESSION_ITEMS_ACTUALLY_IN_THE_GAME] + self.PARENT_ITEM_COUNT_PER_BASE_ITEM[item] = progressive_list.index(item) + 1 + self.PROGRESSIVE_LISTS[progressive_item_name] = progressive_list else: - self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.add(item) + self.PROGRESSION_ITEMS_ACTUALLY_IN_THE_GAME.add(item) def solvability_guaranteed(self, entity_hex: str) -> bool: return not ( diff --git a/worlds/witness/rules.py b/worlds/witness/rules.py index 74ea2aef..323d5943 100644 --- a/worlds/witness/rules.py +++ b/worlds/witness/rules.py @@ -201,10 +201,10 @@ def _has_item(item: str, world: "WitnessWorld", if item == "Theater to Tunnels": return lambda state: _can_do_theater_to_tunnels(state, world) - prog_item = static_witness_logic.get_parent_progressive_item(item) - needed_amount = player_logic.MULTI_AMOUNTS[item] + actual_item = static_witness_logic.get_parent_progressive_item(item) + needed_amount = player_logic.PARENT_ITEM_COUNT_PER_BASE_ITEM[item] - simple_rule: SimpleItemRepresentation = SimpleItemRepresentation(prog_item, needed_amount) + simple_rule: SimpleItemRepresentation = SimpleItemRepresentation(actual_item, needed_amount) return simple_rule