Skip to content

Commit

Permalink
More mypy error fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
fenhl committed Mar 27, 2024
1 parent 5528aa1 commit 7f1a7ba
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 22 deletions.
8 changes: 6 additions & 2 deletions HintList.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def get_hint_group(group: str, world: World) -> list[Hint]:
type_append = True
if name_is_location(name, hint.type, world):
location = world.get_location(name)
assert location.item is not None
for i in world.item_added_hint_types[group]:
if i == location.item.name:
hint.type = [group]
Expand All @@ -104,13 +105,15 @@ def get_hint_group(group: str, world: World) -> list[Hint]:
if group in world.item_hint_type_overrides:
if name_is_location(name, hint.type, world):
location = world.get_location(name)
assert location.item is not None
if location.item.name in world.item_hint_type_overrides[group]:
type_override = True
elif name in multiTable.keys():
multi = get_multi(name)
for locationName in multi.locations:
if locationName not in hint_exclusions(world):
location = world.get_location(locationName)
assert location.item is not None
if location.item.name in world.item_hint_type_overrides[group]:
type_override = True

Expand Down Expand Up @@ -148,6 +151,7 @@ def get_upgrade_hint_list(world: World, locations: list[str]) -> list[Hint]:
for locationName in multi.locations:
if locationName not in hint_exclusions(world):
location = world.get_location(locationName)
assert location.item is not None
if location.item.name in world.item_hint_type_overrides[hint_type]:
type_override = True

Expand Down Expand Up @@ -1910,8 +1914,8 @@ def hint_exclusions(world: World, clear_cache: bool = False) -> list[str]:
'dual_always']):
multi = get_multi(hint.name)
exclude_hint = False
for location in multi.locations:
if location not in world_location_names or world.get_location(location).locked:
for location_name in multi.locations:
if location_name not in world_location_names or world.get_location(location_name).locked:
exclude_hint = True
if exclude_hint:
HINT_EXCLUSION_CACHE[world.id].append(hint.name)
Expand Down
58 changes: 41 additions & 17 deletions Hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,14 +872,15 @@ def get_specific_item_hint(spoiler: Spoiler, world: World, checked: set[HintArea
all_named_items = set(itertools.chain.from_iterable([w.named_item_pool for w in worlds]))
if "Bottle" in all_named_items and world.settings.hint_dist == "bingo":
all_named_items.update(bingoBottlesForHints)
named_item_locations = [location for w in worlds for location in w.get_filled_locations() if (location.item.name in all_named_items)]
named_item_locations = [location for w in worlds for location in w.get_filled_locations(lambda item: item.name in all_named_items)]
spoiler._cached_named_item_locations = named_item_locations

always_hints = [(hint, w.id) for w in worlds for hint in get_hint_group('always', w)]
always_locations = []
for hint, id in always_hints:
location = worlds[id].get_location(hint.name)
assert location.item is not None
assert location.item.world is not None
if location.item.name in bingoBottlesForHints and world.settings.hint_dist == 'bingo':
always_item = 'Bottle'
else:
Expand Down Expand Up @@ -929,6 +930,7 @@ def get_specific_item_hint(spoiler: Spoiler, world: World, checked: set[HintArea

location = random.choice(locations)
assert location.item is not None
assert location.world is not None
checked.add(location.name)
item_text = get_hint(get_item_generic_name(location.item), world.settings.clearer_hints).text

Expand Down Expand Up @@ -999,6 +1001,7 @@ def get_specific_hint(spoiler: Spoiler, world: World, checked: set[HintArea | st
return get_specific_multi_hint(spoiler, world, checked, hint)

location = world.get_location(hint.name)
assert location.item is not None
checked.add(location.name)

if location.name in world.hint_text_overrides:
Expand Down Expand Up @@ -1080,7 +1083,7 @@ def get_specific_multi_hint(spoiler: Spoiler, world: World, checked: set[HintAre
else:
gossip_string = gossip_string + '#%s# '

items = [location.item for location in locations]
items = [location.item for location in locations if location.item is not None]
text_segments = [multi_text] + [get_hint(get_item_generic_name(item), world.settings.clearer_hints).text for item in items]
return GossipText(gossip_string % tuple(text_segments), colors, [location.name for location in locations], [item.name for item in items]), locations

Expand All @@ -1097,9 +1100,12 @@ def get_entrance_hint(spoiler: Spoiler, world: World, checked: set[HintArea | st
shuffled_entrance_hints = list(filter(lambda entrance_hint: world.get_entrance(entrance_hint.name).shuffled, entrance_hints))

regions_with_hint = [hint.name for hint in get_hint_group('region', world)]
valid_entrance_hints = list(filter(lambda entrance_hint:
(world.get_entrance(entrance_hint.name).connected_region.name in regions_with_hint or
world.get_entrance(entrance_hint.name).connected_region.dungeon), shuffled_entrance_hints))
valid_entrance_hints = []
for entrance_hint in shuffled_entrance_hints:
entrance = world.get_entrance(entrance_hint.name)
assert entrance.connected_region is not None
if entrance.connected_region.name in regions_with_hint or entrance.connected_region.dungeon:
valid_entrance_hints.append(entrance_hint)

if not valid_entrance_hints:
return None
Expand All @@ -1114,7 +1120,8 @@ def get_entrance_hint(spoiler: Spoiler, world: World, checked: set[HintArea | st
entrance_text = '#%s#' % entrance_text

connected_region = entrance.connected_region
if connected_region.dungeon:
assert connected_region is not None
if connected_region.dungeon is not None:
region_text = get_hint(connected_region.dungeon.name, world.settings.clearer_hints).text
else:
region_text = get_hint(connected_region.name, world.settings.clearer_hints).text
Expand Down Expand Up @@ -1256,6 +1263,7 @@ def build_bingo_hint_list(board_url: str) -> list[str]:

def always_named_item(world: World, locations: Iterable[Location]):
for location in locations:
assert location.item is not None
if location.item.name in bingoBottlesForHints and world.settings.hint_dist == 'bingo':
always_item = 'Bottle'
else:
Expand All @@ -1269,21 +1277,25 @@ def build_gossip_hints(spoiler: Spoiler, worlds: list[World]) -> None:
# Add misc. item hint locations to "checked" locations if the respective hint is reachable without the hinted item.
for world in worlds:
for location in world.hinted_dungeon_reward_locations.values():
assert location.item is not None
if 'altar' in world.settings.misc_hints and not world.settings.enhance_map_compass and can_reach_hint(worlds, world.get_location('ToT Child Altar Hint' if location.item.info.stone else 'ToT Adult Altar Hint'), location):
item_world = location.world
assert item_world is not None
if item_world.id not in checked_locations:
checked_locations[item_world.id] = set()
checked_locations[item_world.id].add(location.name)
for hint_type, location in world.misc_hint_item_locations.items():
if hint_type in world.settings.misc_hints and can_reach_hint(worlds, world.get_location(misc_item_hint_table[hint_type]['hint_location']), location):
item_world = location.world
assert item_world is not None
if item_world.id not in checked_locations:
checked_locations[item_world.id] = set()
checked_locations[item_world.id].add(location.name)
for hint_type in world.misc_hint_location_items.keys():
location = world.get_location(misc_location_hint_table[hint_type]['item_location'])
if hint_type in world.settings.misc_hints and can_reach_hint(worlds, world.get_location(misc_location_hint_table[hint_type]['hint_location']), location):
item_world = location.world
assert item_world is not None
if item_world.id not in checked_locations:
checked_locations[item_world.id] = set()
checked_locations[item_world.id].add(location.name)
Expand All @@ -1307,7 +1319,7 @@ def build_world_gossip_hints(spoiler: Spoiler, world: World, checked_locations:

if checked_locations is None:
checked_locations = set()
checked_always_locations = set()
checked_always_locations: set[HintArea | str] = set()

stone_ids = list(gossipLocations.keys())

Expand All @@ -1325,7 +1337,9 @@ def build_world_gossip_hints(spoiler: Spoiler, world: World, checked_locations:
raise ValueError(f'Gossip stone location "{stone_name}" is not valid')
if stone_id in stone_ids:
stone_ids.remove(stone_id)
(gossip_text, _) = get_junk_hint(spoiler, world, checked_locations)
hint_return = get_junk_hint(spoiler, world, checked_locations)
assert hint_return is not None
gossip_text, _ = hint_return
spoiler.hints[world.id][stone_id] = gossip_text

stone_groups = []
Expand Down Expand Up @@ -1425,7 +1439,9 @@ def build_world_gossip_hints(spoiler: Spoiler, world: World, checked_locations:
for hint in always_duals:
multi = get_multi(hint.name)
first_location = world.get_location(multi.locations[0])
assert first_location.item is not None
second_location = world.get_location(multi.locations[1])
assert second_location.item is not None
checked_always_locations.add(first_location.name)
checked_always_locations.add(second_location.name)

Expand All @@ -1444,10 +1460,14 @@ def build_world_gossip_hints(spoiler: Spoiler, world: World, checked_locations:

# Add required location hints, only if hint copies > 0
if hint_dist['always'][1] > 0:
always_locations = list(filter(lambda hint: is_not_checked([world.get_location(hint.name)], checked_always_locations),
get_hint_group('always', world)))
always_locations = [
hint
for hint in get_hint_group('always', world)
if is_not_checked([world.get_location(hint.name)], checked_always_locations)
]
for hint in always_locations:
location = world.get_location(hint.name)
assert location.item is not None
checked_always_locations.add(hint.name)

always_named_item(world, [location])
Expand All @@ -1468,6 +1488,7 @@ def build_world_gossip_hints(spoiler: Spoiler, world: World, checked_locations:
for entrance_hint in always_entrances:
entrance = world.get_entrance(entrance_hint.name)
connected_region = entrance.connected_region
assert connected_region is not None
if entrance.shuffled and (connected_region.dungeon or any(hint.name == connected_region.name for hint in
get_hint_group('region', world))):
checked_always_locations.add(entrance.name)
Expand Down Expand Up @@ -1516,18 +1537,21 @@ def build_world_gossip_hints(spoiler: Spoiler, world: World, checked_locations:
# Assumes that a "wasted" hint is desired since Light Arrows have to be added
# explicitly to the list for named item hints.
filtered_checked = set(checked_locations | checked_always_locations)
for location in (checked_locations | checked_always_locations):
for checked_location_name in (checked_locations | checked_always_locations):
try:
if world.get_location(location).item.name == 'Light Arrows':
filtered_checked.remove(location)
checked_location = world.get_location(checked_location_name)
except KeyError:
pass # checked_always_locations can also contain entrances from entrance_always hints, ignore those here
else:
assert checked_location.item is not None
if checked_location.item.name == 'Light Arrows':
filtered_checked.remove(checked_location_name)
for i in range(0, len(world.named_item_pool)):
hint = get_specific_item_hint(spoiler, world, filtered_checked)
if hint:
hint_return = get_specific_item_hint(spoiler, world, filtered_checked)
if hint_return is not None:
checked_locations.update(filtered_checked - checked_always_locations)
gossip_text, location = hint
place_ok = add_hint(spoiler, world, stone_groups, gossip_text, hint_dist['named-item'][1], location, hint_type='named-item')
gossip_text, locations = hint_return
place_ok = add_hint(spoiler, world, stone_groups, gossip_text, hint_dist['named-item'][1], locations, hint_type='named-item')
if not place_ok:
raise Exception('Not enough gossip stones for user-provided item hints')

Expand Down
6 changes: 3 additions & 3 deletions World.py
Original file line number Diff line number Diff line change
Expand Up @@ -1138,13 +1138,13 @@ def get_locations(self) -> list[Location]:
self._cached_locations.extend(region.locations)
return self._cached_locations

def get_unfilled_locations(self) -> Iterable[Location]:
def get_unfilled_locations(self) -> Iterator[Location]:
return filter(Location.has_no_item, self.get_locations())

def get_filled_locations(self, item_filter: Callable[[Item], bool] = lambda item: True) -> Iterable[Location]:
def get_filled_locations(self, item_filter: Callable[[Item], bool] = lambda item: True) -> Iterator[Location]:
return filter(lambda loc: loc.item is not None and item_filter(loc.item), self.get_locations())

def get_progression_locations(self) -> Iterable[Location]:
def get_progression_locations(self) -> Iterator[Location]:
return filter(Location.has_progression_item, self.get_locations())

def get_entrances(self) -> list[Entrance]:
Expand Down

0 comments on commit 7f1a7ba

Please sign in to comment.