diff --git a/Hints.py b/Hints.py index 3817f5384..309cd4444 100644 --- a/Hints.py +++ b/Hints.py @@ -1270,6 +1270,9 @@ 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(): + if location is None: + # ignore starting items + continue if world.settings.enhance_map_compass: if world.entrance_rando_reward_hints: # In these settings, there is not necessarily one dungeon reward in each dungeon, @@ -1700,7 +1703,11 @@ def build_boss_string(reward: str, color: str, world: World) -> str: text = GossipText(f"\x08\x13{item_icon}One in #@'s pocket#...", [color], prefix='') else: location = world.hinted_dungeon_reward_locations[reward] - location_text = HintArea.at(location).text(world.settings.clearer_hints, preposition=True, world=None if location.world.id == world.id else location.world.id + 1) + if location is None: + hint_area = HintArea.ROOT + else: + hint_area = HintArea.at(location) + location_text = hint_area.text(world.settings.clearer_hints, preposition=True, world=None if location.world.id == world.id else location.world.id + 1) text = GossipText(f"\x08\x13{item_icon}One {location_text}...", [color], prefix='') return str(text) + '\x04' diff --git a/Patches.py b/Patches.py index e2fbec405..fad571bb5 100644 --- a/Patches.py +++ b/Patches.py @@ -2000,7 +2000,10 @@ def update_scrub_text(message: bytearray, text_replacement: list[str], default_p if world.entrance_rando_reward_hints: vanilla_reward = world.get_location(dungeon.vanilla_boss_name).vanilla_item vanilla_reward_location = world.hinted_dungeon_reward_locations[vanilla_reward] - area = HintArea.at(vanilla_reward_location) + if vanilla_reward_location is None: + area = HintArea.ROOT + else: + area = HintArea.at(vanilla_reward_location) area = GossipText(area.text(world.settings.clearer_hints, preposition=True, use_2nd_person=True), [area.color], prefix='', capitalize=False) compass_message = f"\x13\x75\x08You found the \x05\x41Compass\x05\x40\x01for {dungeon_name}\x05\x40!\x01The {vanilla_reward} can be found\x01{area}!\x09" else: @@ -2781,10 +2784,13 @@ def configure_dungeon_info(rom: Rom, world: World) -> None: if world.dungeon_rewards_hinted: for reward in REWARD_COLORS: location = world.hinted_dungeon_reward_locations[reward] - area = HintArea.at(location) + if location is None: + area = HintArea.ROOT + else: + area = HintArea.at(location) dungeon_reward_areas += area.short_name.encode('ascii').ljust(0x16) + b'\0' - dungeon_reward_worlds.append(location.world.id + 1) - if location.world.id == world.id and area.is_dungeon: + dungeon_reward_worlds.append((world.id if location is None else location.world.id) + 1) + if location is not None and location.world.id == world.id and area.is_dungeon: dungeon_rewards[codes.index(area.dungeon_name)] = boss_reward_index(location.item) dungeon_is_mq = [1 if world.dungeon_mq.get(c) else 0 for c in codes] diff --git a/README.md b/README.md index 8685c26f2..61a79a92a 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ issue. You should always Hard Reset to avoid this issue entirely. * Fix an error in the easy bite fishing hack. * The randomizer no longer ignores errors when decompressing the base rom or compressing the randomized rom. * Trade quest items from skipped locations are no longer lost when another trade item is found. +* Fix a crash when dungeon rewards are directly selected as starting items. #### New Speedups * The first text box from each carpenter in the Thieves' Hideout is skipped. diff --git a/Spoiler.py b/Spoiler.py index 59721ea3e..09f381eec 100644 --- a/Spoiler.py +++ b/Spoiler.py @@ -301,7 +301,7 @@ def create_playthrough(self) -> None: for w, sw in zip(worlds, self.worlds): # But the actual location saved here may be in a different world for item_name, item_location in w.hinted_dungeon_reward_locations.items(): - sw.hinted_dungeon_reward_locations[item_name] = self.worlds[item_location.world.id].get_location(item_location.name) + sw.hinted_dungeon_reward_locations[item_name] = None if item_location is None else self.worlds[item_location.world.id].get_location(item_location.name) for hint_type, item_location in w.misc_hint_item_locations.items(): sw.misc_hint_item_locations[hint_type] = self.worlds[item_location.world.id].get_location(item_location.name) diff --git a/World.py b/World.py index effd18d28..759c30de4 100644 --- a/World.py +++ b/World.py @@ -14,6 +14,7 @@ from HintList import get_required_hints, misc_item_hint_table, misc_location_hint_table from Hints import HintArea, hint_dist_keys, hint_dist_files from Item import Item, ItemFactory, ItemInfo, make_event_item +from ItemList import REWARD_COLORS from ItemPool import reward_list from Location import Location, LocationFactory from LocationList import business_scrubs, location_groups, location_table @@ -41,7 +42,12 @@ def __init__(self, world_id: int, settings: Settings, resolve_randomized_setting self.shop_prices: dict[str, int] = {} self.scrub_prices: dict[int, int] = {} self.maximum_wallets: int = 0 - self.hinted_dungeon_reward_locations: dict[str, Location] = {} + self.hinted_dungeon_reward_locations: dict[str, Optional[Location]] = { + name: None + for name, count in settings.starting_items.items() + if name in REWARD_COLORS + and count.count > 0 + } self.misc_hint_item_locations: dict[str, Location] = {} self.misc_hint_location_items: dict[str, Item] = {} self.triforce_count: int = 0 diff --git a/version.py b/version.py index 8d99e54ca..62b51910c 100644 --- a/version.py +++ b/version.py @@ -1,4 +1,4 @@ -__version__ = '8.2.40' +__version__ = '8.2.41' # This is a supplemental version number for branches based off of main dev. supplementary_version = 0