From dfb9ebfbdb64015a58326d6dc2827ba6b3e6b956 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 22 Mar 2022 16:13:31 -0600 Subject: [PATCH 001/146] Customizer main work --- BaseClasses.py | 8 +- Bosses.py | 21 + CLI.py | 25 +- DoorShuffle.py | 264 +- DungeonGenerator.py | 8 + EntranceShuffle.py | 521 +-- Fill.py | 2 +- Gui.py | 2 +- ItemList.py | 139 +- Main.py | 51 +- Mystery.py | 6 +- RELEASENOTES.md | 9 + Rom.py | 108 +- RoomData.py | 12 + Rules.py | 2 +- docs/Customizer.md | 182 + docs/customizer_example.yaml | 108 + docs/multi_mystery_example.yaml | 17 + docs/player1.yml | 19 + docs/player2.yml | 16 + docs/player3.yml | 25 + resources/app/cli/args.json | 8 +- resources/app/cli/lang/en.json | 1 + resources/app/gui/lang/en.json | 7 +- .../app/gui/randomize/entrando/widgets.json | 6 +- .../gui/randomize/generation/checkboxes.json | 1 + source/classes/CustomSettings.py | 329 ++ source/classes/constants.py | 1 + source/gui/randomize/generation.py | 42 + source/overworld/EntranceShuffle2.py | 3003 +++++++++++++++++ source/{test => overworld}/__init__.py | 0 source/tools/MysteryUtils.py | 190 ++ {source/test => test}/MysteryTestSuite.py | 0 test/stats/EntranceShuffleStats.py | 154 + test/stats/__init__.py | 0 35 files changed, 4599 insertions(+), 688 deletions(-) create mode 100644 docs/Customizer.md create mode 100644 docs/customizer_example.yaml create mode 100644 docs/multi_mystery_example.yaml create mode 100644 docs/player1.yml create mode 100644 docs/player2.yml create mode 100644 docs/player3.yml create mode 100644 source/classes/CustomSettings.py create mode 100644 source/overworld/EntranceShuffle2.py rename source/{test => overworld}/__init__.py (100%) create mode 100644 source/tools/MysteryUtils.py rename {source/test => test}/MysteryTestSuite.py (100%) create mode 100644 test/stats/EntranceShuffleStats.py create mode 100644 test/stats/__init__.py diff --git a/BaseClasses.py b/BaseClasses.py index e997054c..b1b58cd9 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -113,7 +113,7 @@ class World(object): set_player_attr('can_access_trock_front', None) set_player_attr('can_access_trock_big_chest', None) set_player_attr('can_access_trock_middle', None) - set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'nologic'] or shuffle[player] in ['crossed', 'insanity', 'madness_legacy']) + set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'nologic'] or shuffle[player] in ['crossed', 'insanity']) set_player_attr('mapshuffle', False) set_player_attr('compassshuffle', False) set_player_attr('keyshuffle', False) @@ -2733,8 +2733,8 @@ class Pot(object): # byte 0: DDDE EEEE (DR, ER) dr_mode = {"basic": 1, "crossed": 2, "vanilla": 0} -er_mode = {"vanilla": 0, "simple": 1, "restricted": 2, "full": 3, "crossed": 4, "insanity": 5, "restricted_legacy": 8, - "full_legacy": 9, "madness_legacy": 10, "insanity_legacy": 11, "dungeonsfull": 7, "dungeonssimple": 6} +er_mode = {"vanilla": 0, "simple": 1, "restricted": 2, "full": 3, "crossed": 4, "insanity": 5, 'lite': 8, + 'lean': 9, "dungeonsfull": 7, "dungeonssimple": 6} # byte 1: LLLW WSSR (logic, mode, sword, retro) logic_mode = {"noglitches": 0, "minorglitches": 1, "nologic": 2, "owglitches": 3, "majorglitches": 4} @@ -2753,7 +2753,7 @@ mixed_travel_mode = {"prevent": 0, "allow": 1, "force": 2} # new byte 4: ?DDD PPPP (unused, drop, pottery) # dropshuffle reserves 2 bits, pottery needs 2 but reserves 2 for future modes) -pottery_mode = {"none": 0, "shuffle": 1, "keys": 2, "lottery": 3, 'dungeon': 4, 'cave': 5} +pottery_mode = {"none": 0, "shuffle": 1, "keys": 2, 'lottery': 3, 'dungeon': 4, 'cave': 5} # byte 5: CCCC CTTX (crystals gt, ctr2, experimental) counter_mode = {"default": 0, "off": 1, "on": 2, "pickup": 3} diff --git a/Bosses.py b/Bosses.py index 53393d5f..16ff4f4d 100644 --- a/Bosses.py +++ b/Bosses.py @@ -165,6 +165,22 @@ def place_bosses(world, player): all_bosses = sorted(boss_table.keys()) #s orted to be deterministic on older pythons placeable_bosses = [boss for boss in all_bosses if boss not in ['Agahnim', 'Agahnim2', 'Ganon']] + used_bosses = [] + + if world.customizer and world.customizer.get_bosses(): + custom_bosses = world.customizer.get_bosses() + if player in custom_bosses: + for location, boss in custom_bosses[player].items(): + level = None + if '(' in location: + i = location.find('(') + level = location[i+1:location.find(')')] + location = location[:i-1] + if can_place_boss(world, player, boss, location, level): + loc_text = location + (' ('+level+')' if level else '') + place_boss(boss, level, location, loc_text, world, player) + boss_locations.remove([location, level]) + used_bosses.append((boss, level)) # temporary hack for swordless kholdstare: if world.boss_shuffle[player] in ["simple", "full", "unique"]: @@ -179,6 +195,8 @@ def place_bosses(world, player): bosses = placeable_bosses + ['Armos Knights', 'Lanmolas', 'Moldorm'] else: # all bosses present, the three duplicates chosen at random bosses = placeable_bosses + random.sample(placeable_bosses, 3) + for u, level in used_bosses: + placeable_bosses.remove(u) logging.getLogger('').debug('Bosses chosen %s', bosses) @@ -202,6 +220,9 @@ def place_bosses(world, player): place_boss(boss, level, loc, loc_text, world, player) elif world.boss_shuffle[player] == 'unique': bosses = list(placeable_bosses) + for u, level in used_bosses: + if not level: + bosses.remove(u) for [loc, level] in boss_locations: loc_text = loc + (' ('+level+')' if level else '') diff --git a/CLI.py b/CLI.py index a6a88d23..9a2914de 100644 --- a/CLI.py +++ b/CLI.py @@ -9,6 +9,7 @@ import sys from source.classes.BabelFish import BabelFish from Utils import update_deprecated_args +from source.classes.CustomSettings import CustomSettings class ArgumentDefaultsHelpFormatter(argparse.RawTextHelpFormatter): @@ -32,11 +33,25 @@ def parse_cli(argv, no_defaults=False): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--settingsfile', help="input json file of settings", type=str) parser.add_argument('--multi', default=defval(settings["multi"]), type=lambda value: min(max(int(value), 1), 255)) + parser.add_argument('--customizer', help='input yaml file for customizations', type=str) + parser.add_argument('--print_custom_yaml', help='print example yaml for current settings', + default=False, action="store_true") + parser.add_argument('--mystery', dest="mystery", default=False, action="store_true") + multiargs, _ = parser.parse_known_args(argv) if multiargs.settingsfile: settings = apply_settings_file(settings, multiargs.settingsfile) + player_num = multiargs.multi + if multiargs.customizer: + custom = CustomSettings() + custom.load_yaml(multiargs.customizer) + cp = custom.determine_players() + if cp: + player_num = cp + + parser = argparse.ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) # get args @@ -78,9 +93,11 @@ def parse_cli(argv, no_defaults=False): parser.add_argument('--securerandom', default=defval(settings["securerandom"]), action='store_true') parser.add_argument('--teams', default=defval(1), type=lambda value: max(int(value), 1)) parser.add_argument('--settingsfile', dest="filename", help="input json file of settings", type=str) + parser.add_argument('--customizer', dest="customizer", help='input yaml file for customizations', type=str) + parser.add_argument('--print_custom_yaml', dest="print_custom_yaml", default=False, action="store_true") - if multiargs.multi: - for player in range(1, multiargs.multi + 1): + if player_num: + for player in range(1, player_num + 1): parser.add_argument(f'--p{player}', default=defval(''), help=argparse.SUPPRESS) ret = parser.parse_args(argv) @@ -92,9 +109,9 @@ def parse_cli(argv, no_defaults=False): ret.dropshuffle = True ret.pottery = 'keys' if ret.pottery == 'none' else ret.pottery - if multiargs.multi: + if player_num: defaults = copy.deepcopy(ret) - for player in range(1, multiargs.multi + 1): + for player in range(1, player_num + 1): playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True) for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', diff --git a/DoorShuffle.py b/DoorShuffle.py index f4ee9cfa..a182304e 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -256,9 +256,23 @@ def convert_key_doors(k_doors, world, player): def connect_custom(world, player): - if hasattr(world, 'custom_doors') and world.custom_doors[player]: - for entrance, ext in world.custom_doors[player]: - connect_two_way(world, entrance, ext, player) + if world.customizer and world.customizer.get_doors(): + custom_doors = world.customizer.get_doors() + if player not in custom_doors: + return + custom_doors = custom_doors[player] + if 'doors' not in custom_doors: + return + for door, dest in custom_doors['doors'].items(): + d = world.get_door(door, player) + if d.type not in [DoorType.Interior, DoorType.Logical]: + if isinstance(dest, str): + connect_two_way(world, door, dest, player) + elif 'dest' in dest: + if 'one-way' in dest and dest['one-way']: + connect_one_way(world, door, dest['dest'], player) + else: + connect_two_way(world, door, dest['dest'], player) def connect_simple_door(world, exit_name, region_name, player): @@ -422,6 +436,9 @@ def choose_portals(world, player): master_door_list = [x for x in world.doors if x.player == player and x.portalAble] portal_assignment = defaultdict(list) shuffled_info = list(info_map.items()) + + custom = customizer_portals(master_door_list, world, player) + if cross_flag: random.shuffle(shuffled_info) for dungeon, info in shuffled_info: @@ -436,17 +453,17 @@ def choose_portals(world, player): info.required_passage[target_region] = [x for x in possible_portals if x != sanc.name] info.required_passage = {x: y for x, y in info.required_passage.items() if len(y) > 0} for target_region, possible_portals in info.required_passage.items(): - candidates = find_portal_candidates(master_door_list, dungeon, need_passage=True, crossed=cross_flag, - bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) - choice, portal = assign_portal(candidates, possible_portals, world, player) + candidates = find_portal_candidates(master_door_list, dungeon, custom, need_passage=True, + crossed=cross_flag, bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) + choice, portal = assign_portal(candidates, possible_portals, custom, world, player) portal.destination = True clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals) dead_end_choices = info.total - 1 - len(portal_assignment[dungeon]) for i in range(0, dead_end_choices): - candidates = find_portal_candidates(master_door_list, dungeon, dead_end_allowed=True, + candidates = find_portal_candidates(master_door_list, dungeon, custom, dead_end_allowed=True, crossed=cross_flag, bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) possible_portals = outstanding_portals if not info.sole_entrance else [x for x in outstanding_portals if x != info.sole_entrance] - choice, portal = assign_portal(candidates, possible_portals, world, player) + choice, portal = assign_portal(candidates, possible_portals, custom, world, player) if choice.deadEnd: if choice.passage: portal.destination = True @@ -455,9 +472,9 @@ def choose_portals(world, player): clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals) the_rest = info.total - len(portal_assignment[dungeon]) for i in range(0, the_rest): - candidates = find_portal_candidates(master_door_list, dungeon, crossed=cross_flag, + candidates = find_portal_candidates(master_door_list, dungeon, custom, crossed=cross_flag, bk_shuffle=bk_shuffle, standard=hc_flag, rupee_bow=rupee_bow_flag) - choice, portal = assign_portal(candidates, outstanding_portals, world, player) + choice, portal = assign_portal(candidates, outstanding_portals, custom, world, player) clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals) for portal in world.dungeon_portals[player]: @@ -495,6 +512,29 @@ def choose_portals(world, player): world.swamp_patch_required[player] = True +def customizer_portals(master_door_list, world, player): + custom_portals = {} + assigned_doors = set() + if world.customizer and world.customizer.get_doors(): + custom_doors = world.customizer.get_doors()[player] + if custom_doors and 'lobbies' in custom_doors: + for portal, assigned_door in custom_doors['lobbies'].items(): + door = next(x for x in master_door_list if x.name == assigned_door) + custom_portals[portal] = door + assigned_doors.add(door) + if custom_doors and 'doors' in custom_doors: + for src_door, dest in custom_doors['doors'].items(): + door = world.get_door(src_door, player) + assigned_doors.add(door) + if isinstance(dest, str): + door = world.get_door(dest, player) + assigned_doors.add(door) + else: + door = world.get_door(dest['dest'], player) + assigned_doors.add(door) + return custom_portals, assigned_doors + + def analyze_portals(world, player): info_map = {} for dungeon, portal_list in dungeon_portals.items(): @@ -576,9 +616,14 @@ def disconnect_portal(portal, world, player): chosen_door.entranceFlag = False -def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False, +def find_portal_candidates(door_list, dungeon, custom, need_passage=False, dead_end_allowed=False, crossed=False, bk_shuffle=False, standard=False, rupee_bow=False): - ret = [x for x in door_list if bk_shuffle or not x.bk_shuffle_req] + custom_portals, assigned_doors = custom + if assigned_doors: + ret = [x for x in door_list if x not in assigned_doors] + else: + ret = door_list + ret = [x for x in ret if bk_shuffle or not x.bk_shuffle_req] if crossed: ret = [x for x in ret if not x.dungeonLink or x.dungeonLink == dungeon or x.dungeonLink.startswith('link')] else: @@ -594,9 +639,13 @@ def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allo return ret -def assign_portal(candidates, possible_portals, world, player): - candidate = random.choice(candidates) +def assign_portal(candidates, possible_portals, custom, world, player): + custom_portals, assigned_doors = custom portal_choice = random.choice(possible_portals) + if portal_choice in custom_portals: + candidate = custom_portals[portal_choice] + else: + candidate = random.choice(candidates) portal = world.get_portal(portal_choice, player) while candidate.lw_restricted and not portal.light_world: candidates.remove(candidate) @@ -723,6 +772,7 @@ def within_dungeon(world, player): paths = determine_required_paths(world, player) check_required_paths(paths, world, player) + setup_custom_door_types(world, player) # shuffle_key_doors for dungeons logging.getLogger('').info(world.fish.translate("cli", "cli", "shuffling.keydoors")) start = time.process_time() @@ -994,6 +1044,7 @@ def cross_dungeon(world, player): at.dungeon_items.append(ItemFactory('Compass (Agahnims Tower)', player)) at.dungeon_items.append(ItemFactory('Map (Agahnims Tower)', player)) + setup_custom_door_types(world, player) assign_cross_keys(dungeon_builders, world, player) all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items)) target_items = 34 @@ -1058,6 +1109,29 @@ def cross_dungeon(world, player): refine_boss_exits(world, player) +def filter_key_door_pool(pool, selected_custom): + new_pool = [] + for cand in pool: + found = False + for custom in selected_custom: + if isinstance(cand, Door): + if isinstance(custom, Door): + found = cand.name == custom.name + else: + found = cand.name == custom[0].name or cand.name == custom[1].name + else: + if isinstance(custom, Door): + found = cand[0].name == custom.name or cand[1].name == custom.name + else: + found = (cand[0].name == custom[0].name or cand[0].name == custom[1].name + or cand[1].name == custom[0].name or cand[1].name == custom[1].name) + if found: + break + if not found: + new_pool.append(cand) + return new_pool + + def assign_cross_keys(dungeon_builders, world, player): logging.getLogger('').info(world.fish.translate("cli", "cli", "shuffling.keydoors")) start = time.process_time() @@ -1069,9 +1143,13 @@ def assign_cross_keys(dungeon_builders, world, player): remaining += 19 else: remaining = len(list(x for dgn in world.dungeons if dgn.player == player for x in dgn.small_keys)) - total_keys = remaining total_candidates = 0 start_regions_map = {} + if player in world.custom_door_types: + custom_key_doors = world.custom_door_types[player]['Key Door'] + else: + custom_key_doors = defaultdict(list) + key_door_pool, key_doors_assigned = {}, {} # Step 1: Find Small Key Door Candidates for name, builder in dungeon_builders.items(): dungeon = world.get_dungeon(name, player) @@ -1081,22 +1159,27 @@ def assign_cross_keys(dungeon_builders, world, player): dungeon.big_key = ItemFactory(dungeon_bigs[name], player) start_regions = convert_regions(builder.path_entrances, world, player) find_small_key_door_candidates(builder, start_regions, world, player) - builder.key_doors_num = max(0, len(builder.candidates) - builder.key_drop_cnt) + key_door_pool[name] = list(builder.candidates) + if custom_key_doors[name]: + key_door_pool[name] = filter_key_door_pool(key_door_pool[name], custom_key_doors[name]) + remaining -= len(custom_key_doors[name]) + builder.key_doors_num = max(0, len(key_door_pool[name]) - builder.key_drop_cnt) total_candidates += builder.key_doors_num start_regions_map[name] = start_regions + total_keys = remaining # Step 2: Initial Key Number Assignment & Calculate Flexibility for name, builder in dungeon_builders.items(): calculated = int(round(builder.key_doors_num*total_keys/total_candidates)) - max_keys = builder.location_cnt - calc_used_dungeon_items(builder) - cand_len = max(0, len(builder.candidates) - builder.key_drop_cnt) + max_keys = max(0, builder.location_cnt - calc_used_dungeon_items(builder, world, player)) + cand_len = max(0, len(key_door_pool[name]) - builder.key_drop_cnt) limit = min(max_keys, cand_len) suggested = min(calculated, limit) - combo_size = ncr(len(builder.candidates), suggested + builder.key_drop_cnt) + combo_size = ncr(len(key_door_pool[name]), suggested + builder.key_drop_cnt) while combo_size > 500000 and suggested > 0: suggested -= 1 - combo_size = ncr(len(builder.candidates), suggested + builder.key_drop_cnt) - builder.key_doors_num = suggested + builder.key_drop_cnt + combo_size = ncr(len(key_door_pool[name]), suggested + builder.key_drop_cnt) + builder.key_doors_num = suggested + builder.key_drop_cnt + len(custom_key_doors[name]) remaining -= suggested builder.combo_size = combo_size if suggested < limit: @@ -1104,7 +1187,7 @@ def assign_cross_keys(dungeon_builders, world, player): # Step 3: Initial valid combination find - reduce flex if needed for name, builder in dungeon_builders.items(): - suggested = builder.key_doors_num - builder.key_drop_cnt + suggested = builder.key_doors_num - builder.key_drop_cnt - len(custom_key_doors[name]) builder.total_keys = builder.key_doors_num find_valid_combination(builder, start_regions_map[name], world, player) actual_chest_keys = builder.key_doors_num - builder.key_drop_cnt @@ -1161,7 +1244,7 @@ def reassign_boss(boss_region, boss_key, builder, gt, world, player): def check_entrance_fixes(world, player): # I believe these modes will be fine - if world.shuffle[player] not in ['insanity', 'insanity_legacy', 'madness_legacy']: + if world.shuffle[player] not in ['insanity']: checks = { 'Palace of Darkness': 'pod', 'Skull Woods Final Section': 'sw', @@ -1402,6 +1485,39 @@ def valid_region_to_explore(region, world, player): or (region.name == 'Hyrule Castle Ledge' and world.mode[player] == 'standard')) +def setup_custom_door_types(world, player): + if not hasattr(world, 'custom_door_types'): + world.custom_door_types = defaultdict(dict) + if world.customizer and world.customizer.get_doors(): + # type_conv = {'Bomb Door': DoorKind.Bombable , 'Dash Door', DoorKind.Dashable, 'Key Door', DoorKind.SmallKey} + custom_doors = world.customizer.get_doors() + if player not in custom_doors: + return + custom_doors = custom_doors[player] + if 'doors' not in custom_doors: + return + world.custom_door_types[player] = type_map = {'Key Door': defaultdict(list), 'Dash Door': [], 'Bomb Door': []} + for door, dest in custom_doors['doors'].items(): + if isinstance(dest, dict): + if 'type' in dest: + door_kind = dest['type'] + d = world.get_door(door, player) + dungeon = d.entrance.parent_region.dungeon + if d.type == DoorType.SpiralStairs: + type_map[door_kind][dungeon.name].append(d) + elif door_kind == 'Key Door': + # check if the + if d.dest.type in [DoorType.Interior, DoorType.Normal]: + type_map[door_kind][dungeon.name].append((d, d.dest)) + else: + type_map[door_kind][dungeon.name].append(d) + else: + if d.dest.type in [DoorType.Interior, DoorType.Normal]: + type_map[door_kind].append((d, d.dest)) + else: + type_map[door_kind].append(d) + + def shuffle_key_doors(builder, world, player): start_regions = convert_regions(builder.path_entrances, world, player) # count number of key doors - this could be a table? @@ -1458,34 +1574,44 @@ def find_small_key_door_candidates(builder, start_regions, world, player): builder.candidates = paired_candidates -def calc_used_dungeon_items(builder): - base = 4 - if builder.bk_required and not builder.bk_provided: +def calc_used_dungeon_items(builder, world, player): + base = 2 + if not world.bigkeyshuffle[player]: + if builder.bk_required and not builder.bk_provided: + base += 1 + if not world.compassshuffle[player]: + base += 1 + if not world.mapshuffle[player]: base += 1 - # if builder.name == 'Hyrule Castle': - # base -= 1 # Missing compass/map - # if builder.name == 'Agahnims Tower': - # base -= 2 # Missing both compass/map - # gt can lose map once compasses work return base def find_valid_combination(builder, start_regions, world, player, drop_keys=True): logger = logging.getLogger('') + key_door_pool = list(builder.candidates) # can these be a set? + key_doors_needed = builder.key_doors_num + if player in world.custom_door_types: + custom_key_doors = world.custom_door_types[player]['Key Door'][builder.name] + else: + custom_key_doors = [] + if custom_key_doors: # could validate that each custom item is in the candidates + key_door_pool = filter_key_door_pool(key_door_pool, custom_key_doors) + key_doors_needed -= len(custom_key_doors) + # find valid combination of candidates - if len(builder.candidates) < builder.key_doors_num: + if len(key_door_pool) < key_doors_needed: if not drop_keys: logger.info('No valid layouts for %s with %s doors', builder.name, builder.key_doors_num) return False - builder.key_doors_num = len(builder.candidates) # reduce number of key doors - logger.info('%s: %s', world.fish.translate("cli","cli","lowering.keys.candidates"), builder.name) - combinations = ncr(len(builder.candidates), builder.key_doors_num) + builder.key_doors_num -= key_doors_needed - len(key_door_pool) # reduce number of key doors + logger.info('%s: %s', world.fish.translate("cli", "cli", "lowering.keys.candidates"), builder.name) + combinations = ncr(len(key_door_pool), key_doors_needed) itr = 0 start = time.process_time() sample_list = list(range(0, int(combinations))) random.shuffle(sample_list) - proposal = kth_combination(sample_list[itr], builder.candidates, builder.key_doors_num) - + proposal = kth_combination(sample_list[itr], key_door_pool, key_doors_needed) + proposal.extend(custom_key_doors) # eliminate start region if portal marked as destination excluded = {} for region in start_regions: @@ -1509,14 +1635,16 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True return False logger.info('%s: %s', world.fish.translate("cli","cli","lowering.keys.layouts"), builder.name) builder.key_doors_num -= 1 + key_doors_needed -= 1 if builder.key_doors_num < 0: - raise Exception('Bad dungeon %s - 0 key doors not valid' % builder.name) - combinations = ncr(len(builder.candidates), builder.key_doors_num) + raise Exception('Bad dungeon %s - less than 0 key doors not valid' % builder.name) + combinations = ncr(len(key_door_pool), max(0, key_doors_needed)) sample_list = list(range(0, int(combinations))) random.shuffle(sample_list) itr = 0 start = time.process_time() # reset time since itr reset - proposal = kth_combination(sample_list[itr], builder.candidates, builder.key_doors_num) + proposal = kth_combination(sample_list[itr], key_door_pool, key_doors_needed) + proposal.extend(custom_key_doors) key_layout.reset(proposal, builder, world, player) if (itr+1) % 1000 == 0: mark = time.process_time()-start @@ -1710,15 +1838,31 @@ def change_door_to_small_key(d, world, player): d.smallKey = True room = world.get_room(d.roomIndex, player) if room.doorList[d.doorListPos][1] != DoorKind.SmallKey: + verify_door_list_pos(d, room, world, player) room.change(d.doorListPos, DoorKind.SmallKey) +def verify_door_list_pos(d, room, world, player): + if d.doorListPos >= 4: + new_index = room.next_free() + if new_index is not None: + room.swap(new_index, d.doorListPos) + other = next(x for x in world.doors if x.player == player and x.roomIndex == d.roomIndex + and x.doorListPos == new_index) + other.doorListPos = d.doorListPos + d.doorListPos = new_index + else: + raise Exception(f'Invalid stateful door: {d.name}. Only 4 stateful doors per supertile') + + def smooth_door_pairs(world, player): all_doors = [x for x in world.doors if x.player == player] skip = set() bd_candidates = defaultdict(list) for door in all_doors: if door.type in [DoorType.Normal, DoorType.Interior] and door not in skip and not door.entranceFlag: + if not door.dest: + continue partner = door.dest skip.add(partner) room_a = world.get_room(door.roomIndex, player) @@ -1791,15 +1935,33 @@ def stateful_door(door, kind): return False +def custom_door_kind(custom_key, kind, bd_candidates, counts, world, player): + if custom_key in world.custom_door_types[player]: + for door_a, door_b in world.custom_door_types[player][custom_key]: + change_pair_type(door_a, kind, world, player) + d_name = door_a.entrance.parent_region.dungeon.name + bd_list = next(bd_list for dungeon, bd_list in bd_candidates.items() if dungeon.name == d_name) + if door_a in bd_list: + bd_list.remove(door_a) + if door_b in bd_list: + bd_list.remove(door_b) + counts[d_name] += 1 + + def shuffle_bombable_dashable(bd_candidates, world, player): + dash_counts = defaultdict(int) + bomb_counts = defaultdict(int) + if world.custom_door_types[player]: + custom_door_kind('Dash Door', DoorKind.Dashable, bd_candidates, dash_counts, world, player) + custom_door_kind('Bomb Door', DoorKind.Bombable, bd_candidates, bomb_counts, world, player) if world.doorShuffle[player] == 'basic': for dungeon, candidates in bd_candidates.items(): - diff = bomb_dash_counts[dungeon.name][1] + diff = bomb_dash_counts[dungeon.name][1] - dash_counts[dungeon.name] if diff > 0: for chosen in random.sample(candidates, min(diff, len(candidates))): change_pair_type(chosen, DoorKind.Dashable, world, player) candidates.remove(chosen) - diff = bomb_dash_counts[dungeon.name][0] + diff = bomb_dash_counts[dungeon.name][0] - bomb_counts[dungeon.name] if diff > 0: for chosen in random.sample(candidates, min(diff, len(candidates))): change_pair_type(chosen, DoorKind.Bombable, world, player) @@ -1808,21 +1970,27 @@ def shuffle_bombable_dashable(bd_candidates, world, player): remove_pair_type_if_present(excluded, world, player) elif world.doorShuffle[player] == 'crossed': all_candidates = sum(bd_candidates.values(), []) - for chosen in random.sample(all_candidates, min(8, len(all_candidates))): - change_pair_type(chosen, DoorKind.Dashable, world, player) - all_candidates.remove(chosen) - for chosen in random.sample(all_candidates, min(12, len(all_candidates))): - change_pair_type(chosen, DoorKind.Bombable, world, player) - all_candidates.remove(chosen) + desired_dashables = 8 - sum(dash_counts.values(), 0) + desired_bombables = 12 - sum(bomb_counts.values(), 0) + if desired_dashables > 0: + for chosen in random.sample(all_candidates, min(desired_dashables, len(all_candidates))): + change_pair_type(chosen, DoorKind.Dashable, world, player) + all_candidates.remove(chosen) + if desired_bombables > 0: + for chosen in random.sample(all_candidates, min(desired_bombables, len(all_candidates))): + change_pair_type(chosen, DoorKind.Bombable, world, player) + all_candidates.remove(chosen) for excluded in all_candidates: remove_pair_type_if_present(excluded, world, player) def change_pair_type(door, new_type, world, player): room_a = world.get_room(door.roomIndex, player) + verify_door_list_pos(door, room_a, world, player) room_a.change(door.doorListPos, new_type) if door.type != DoorType.Interior: room_b = world.get_room(door.dest.roomIndex, player) + verify_door_list_pos(door.dest, room_b, world, player) room_b.change(door.dest.doorListPos, new_type) add_pair(door, door.dest, world, player) spoiler_type = 'Bomb Door' if new_type == DoorKind.Bombable else 'Dash Door' diff --git a/DungeonGenerator.py b/DungeonGenerator.py index f0038f45..38d47230 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1286,6 +1286,10 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, complete_dungeons = {x: y for x, y in dungeon_map.items() if sum(len(sector.outstanding_doors) for sector in y.sectors) <= 0} [dungeon_map.pop(key) for key in complete_dungeons.keys()] + if not dungeon_map: + dungeon_map.update(complete_dungeons) + return dungeon_map + # categorize sectors identify_destination_sectors(accessible_sectors, reverse_d_map, dungeon_map, connections, dungeon_entrances, split_dungeon_entrances) @@ -1398,6 +1402,8 @@ def identify_destination_sectors(accessible_sectors, reverse_d_map, dungeon_map, explored = False else: d_name = reverse_d_map[sector] + if d_name not in dungeon_map: + return if d_name not in split_dungeon_entrances: for r_name in dungeon_entrances[d_name]: ent_sector = find_sector(r_name, dungeon_map[d_name].sectors) @@ -2953,6 +2959,8 @@ def split_dungeon_builder(builder, split_list, builder_info): sub_builder.all_entrances = list(split_entrances) for r_name in split_entrances: assign_sector(find_sector(r_name, candidate_sectors), sub_builder, candidate_sectors, global_pole) + if len(candidate_sectors) == 0: + return dungeon_map comb_w_replace = len(dungeon_map) ** len(candidate_sectors) return balance_split(candidate_sectors, dungeon_map, global_pole, builder_info) except (GenerationException, NeutralizingException): diff --git a/EntranceShuffle.py b/EntranceShuffle.py index d1bfdbb8..0d3f502b 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -245,61 +245,6 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, doors, door_targets, player) - elif world.shuffle[player] == 'restricted_legacy': - simple_shuffle_dungeons(world, player) - - lw_entrances = list(LW_Entrances) - dw_entrances = list(DW_Entrances) - dw_must_exits = list(DW_Entrances_Must_Exit) - old_man_entrances = list(Old_Man_Entrances) - caves = list(Cave_Exits) - three_exit_caves = list(Cave_Three_Exits) - single_doors = list(Single_Cave_Doors) - bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors) - blacksmith_doors = list(Blacksmith_Single_Cave_Doors) - door_targets = list(Single_Cave_Targets) - - # only use two exit caves to do mandatory dw connections - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) - # add three exit doors to pool for remainder - caves.extend(three_exit_caves) - - # place old man, has limited options - # exit has to come from specific set of doors, the entrance is free to move about - random.shuffle(old_man_entrances) - old_man_exit = old_man_entrances.pop() - lw_entrances.extend(old_man_entrances) - random.shuffle(lw_entrances) - old_man_entrance = lw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) - - # place Old Man House in Light World - connect_caves(world, lw_entrances, [], Old_Man_House, player) - - # connect rest. There's 2 dw entrances remaining, so we will not run into parity issue placing caves - connect_caves(world, lw_entrances, dw_entrances, caves, player) - - # scramble holes - scramble_holes(world, player) - - # place blacksmith, has limited options - random.shuffle(blacksmith_doors) - blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) - bomb_shop_doors.extend(blacksmith_doors) - - # place dam and pyramid fairy, have limited options - random.shuffle(bomb_shop_doors) - bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) - single_doors.extend(bomb_shop_doors) - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - # place remaining doors - connect_doors(world, single_doors, door_targets, player) elif world.shuffle[player] == 'full': skull_woods_shuffle(world, player) @@ -532,324 +477,6 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, entrances, door_targets, player) - elif world.shuffle[player] == 'full_legacy': - skull_woods_shuffle(world, player) - - lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances) - dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances) - dw_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit) - lw_must_exits = list(LW_Dungeon_Entrances_Must_Exit) - old_man_entrances = list(Old_Man_Entrances + ['Tower of Hera']) - caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) # don't need to consider three exit caves, have one exit caves to avoid parity issues - single_doors = list(Single_Cave_Doors) - bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors) - blacksmith_doors = list(Blacksmith_Single_Cave_Doors) - door_targets = list(Single_Cave_Targets) - - if world.mode[player] == 'standard': - # must connect front of hyrule castle to do escape - connect_two_way(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - else: - caves.append(tuple(random.sample(['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'],3))) - lw_entrances.append('Hyrule Castle Entrance (South)') - - if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) - else: - dw_entrances.append('Ganons Tower') - caves.append('Ganons Tower Exit') - - # we randomize which world requirements we fulfill first so we get better dungeon distribution - if random.randint(0, 1) == 0: - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) - else: - connect_mandatory_exits(world, dw_entrances, caves, dw_must_exits, player) - connect_mandatory_exits(world, lw_entrances, caves, lw_must_exits, player) - if world.mode[player] == 'standard': - # rest of hyrule castle must be in light world - connect_caves(world, lw_entrances, [], [('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')], player) - - # place old man, has limited options - # exit has to come from specific set of doors, the entrance is free to move about - old_man_entrances = [door for door in old_man_entrances if door in lw_entrances] - random.shuffle(old_man_entrances) - old_man_exit = old_man_entrances.pop() - lw_entrances.remove(old_man_exit) - - random.shuffle(lw_entrances) - old_man_entrance = lw_entrances.pop() - connect_two_way(world, old_man_entrance, 'Old Man Cave Exit (West)', player) - connect_two_way(world, old_man_exit, 'Old Man Cave Exit (East)', player) - - # place Old Man House in Light World - connect_caves(world, lw_entrances, [], list(Old_Man_House), player) #need this to avoid badness with multiple seeds - - # now scramble the rest - connect_caves(world, lw_entrances, dw_entrances, caves, player) - - # scramble holes - scramble_holes(world, player) - - # place blacksmith, has limited options - random.shuffle(blacksmith_doors) - blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) - bomb_shop_doors.extend(blacksmith_doors) - - # place bomb shop, has limited options - random.shuffle(bomb_shop_doors) - bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) - single_doors.extend(bomb_shop_doors) - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - # place remaining doors - connect_doors(world, single_doors, door_targets, player) - elif world.shuffle[player] == 'madness_legacy': - # here lie dragons, connections are no longer two way - lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances) - dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances) - dw_entrances_must_exits = list(DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit) - - lw_doors = list(LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit) + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', - 'Lumberjack Tree Cave'] + list(Old_Man_Entrances) - dw_doors = list(DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit) + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] - - random.shuffle(lw_doors) - random.shuffle(dw_doors) - - dw_entrances_must_exits.append('Skull Woods Second Section Door (West)') - dw_entrances.append('Skull Woods Second Section Door (East)') - dw_entrances.append('Skull Woods First Section Door') - - lw_entrances.extend(['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave']) - - lw_entrances_must_exits = list(LW_Dungeon_Entrances_Must_Exit) - - old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera'] - - mandatory_light_world = ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)'] - mandatory_dark_world = [] - caves = list(Cave_Exits + Dungeon_Exits + Cave_Three_Exits) - - # shuffle up holes - - lw_hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave'] - dw_hole_entrances = ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] - - hole_targets = [('Kakariko Well Exit', 'Kakariko Well (top)'), - ('Bat Cave Exit', 'Bat Cave (right)'), - ('North Fairy Cave Exit', 'North Fairy Cave'), - ('Lost Woods Hideout Exit', 'Lost Woods Hideout (top)'), - ('Lumberjack Tree Exit', 'Lumberjack Tree (top)'), - (('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Back Drop')] - - if world.mode[player] == 'standard': - # cannot move uncle cave - connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) - connect_exit(world, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player) - connect_entrance(world, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player) - else: - lw_hole_entrances.append('Hyrule Castle Secret Entrance Drop') - hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance')) - lw_doors.append('Hyrule Castle Secret Entrance Stairs') - lw_entrances.append('Hyrule Castle Secret Entrance Stairs') - - if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) - connect_two_way(world, 'Pyramid Entrance', 'Pyramid Exit', player) - connect_entrance(world, 'Pyramid Hole', 'Pyramid', player) - else: - dw_entrances.append('Ganons Tower') - caves.append('Ganons Tower Exit') - dw_hole_entrances.append('Pyramid Hole') - hole_targets.append(('Pyramid Exit', 'Pyramid')) - dw_entrances_must_exits.append('Pyramid Entrance') - dw_doors.extend(['Ganons Tower', 'Pyramid Entrance']) - - random.shuffle(lw_hole_entrances) - random.shuffle(dw_hole_entrances) - random.shuffle(hole_targets) - - # decide if skull woods first section should be in light or dark world - sw_light = random.randint(0, 1) == 0 - if sw_light: - sw_hole_pool = lw_hole_entrances - mandatory_light_world.append('Skull Woods First Section Exit') - else: - sw_hole_pool = dw_hole_entrances - mandatory_dark_world.append('Skull Woods First Section Exit') - for target in ['Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle']: - connect_entrance(world, sw_hole_pool.pop(), target, player) - - # sanctuary has to be in light world - connect_entrance(world, lw_hole_entrances.pop(), 'Sewer Drop', player) - mandatory_light_world.append('Sanctuary Exit') - - # fill up remaining holes - for hole in dw_hole_entrances: - exits, target = hole_targets.pop() - mandatory_dark_world.append(exits) - connect_entrance(world, hole, target, player) - - for hole in lw_hole_entrances: - exits, target = hole_targets.pop() - mandatory_light_world.append(exits) - connect_entrance(world, hole, target, player) - - # hyrule castle handling - if world.mode[player] == 'standard': - # must connect front of hyrule castle to do escape - connect_entrance(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - connect_exit(world, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player) - mandatory_light_world.append(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) - else: - lw_doors.append('Hyrule Castle Entrance (South)') - lw_entrances.append('Hyrule Castle Entrance (South)') - caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) - - # now let's deal with mandatory reachable stuff - def extract_reachable_exit(cavelist): - random.shuffle(cavelist) - candidate = None - for cave in cavelist: - if isinstance(cave, tuple) and len(cave) > 1: - # special handling: TRock and Spectracle Rock cave have two entries that we should consider entrance only - # ToDo this should be handled in a more sensible manner - if cave[0] in ['Turtle Rock Exit (Front)', 'Spectacle Rock Cave Exit (Peak)'] and len(cave) == 2: - continue - candidate = cave - break - if candidate is None: - raise RuntimeError('No suitable cave.') - cavelist.remove(candidate) - return candidate - - def connect_reachable_exit(entrance, general, worldspecific, worldoors): - # select which one is the primary option - if random.randint(0, 1) == 0: - primary = general - secondary = worldspecific - else: - primary = worldspecific - secondary = general - - try: - cave = extract_reachable_exit(primary) - except RuntimeError: - cave = extract_reachable_exit(secondary) - - exit = cave[-1] - cave = cave[:-1] - connect_exit(world, exit, entrance, player) - connect_entrance(world, worldoors.pop(), exit, player) - # rest of cave now is forced to be in this world - worldspecific.append(cave) - - # we randomize which world requirements we fulfill first so we get better dungeon distribution - if random.randint(0, 1) == 0: - for entrance in lw_entrances_must_exits: - connect_reachable_exit(entrance, caves, mandatory_light_world, lw_doors) - for entrance in dw_entrances_must_exits: - connect_reachable_exit(entrance, caves, mandatory_dark_world, dw_doors) - else: - for entrance in dw_entrances_must_exits: - connect_reachable_exit(entrance, caves, mandatory_dark_world, dw_doors) - for entrance in lw_entrances_must_exits: - connect_reachable_exit(entrance, caves, mandatory_light_world, lw_doors) - - # place old man, has limited options - # exit has to come from specific set of doors, the entrance is free to move about - old_man_entrances = [entrance for entrance in old_man_entrances if entrance in lw_entrances] - random.shuffle(old_man_entrances) - old_man_exit = old_man_entrances.pop() - lw_entrances.remove(old_man_exit) - - connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit, player) - connect_entrance(world, lw_doors.pop(), 'Old Man Cave Exit (East)', player) - mandatory_light_world.append('Old Man Cave Exit (West)') - - # we connect up the mandatory associations we have found - for mandatory in mandatory_light_world: - if not isinstance(mandatory, tuple): - mandatory = (mandatory,) - for exit in mandatory: - # point out somewhere - connect_exit(world, exit, lw_entrances.pop(), player) - # point in from somewhere - connect_entrance(world, lw_doors.pop(), exit, player) - - for mandatory in mandatory_dark_world: - if not isinstance(mandatory, tuple): - mandatory = (mandatory,) - for exit in mandatory: - # point out somewhere - connect_exit(world, exit, dw_entrances.pop(), player) - # point in from somewhere - connect_entrance(world, dw_doors.pop(), exit, player) - - # handle remaining caves - while caves: - # connect highest exit count caves first, prevent issue where we have 2 or 3 exits across worlds left to fill - cave_candidate = (None, 0) - for i, cave in enumerate(caves): - if isinstance(cave, str): - cave = (cave,) - if len(cave) > cave_candidate[1]: - cave_candidate = (i, len(cave)) - cave = caves.pop(cave_candidate[0]) - - place_lightworld = random.randint(0, 1) == 0 - if place_lightworld: - target_doors = lw_doors - target_entrances = lw_entrances - else: - target_doors = dw_doors - target_entrances = dw_entrances - - if isinstance(cave, str): - cave = (cave,) - - # check if we can still fit the cave into our target group - if len(target_doors) < len(cave): - if not place_lightworld: - target_doors = lw_doors - target_entrances = lw_entrances - else: - target_doors = dw_doors - target_entrances = dw_entrances - - for exit in cave: - connect_exit(world, exit, target_entrances.pop(), player) - connect_entrance(world, target_doors.pop(), exit, player) - - # handle simple doors - - single_doors = list(Single_Cave_Doors) - bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors) - blacksmith_doors = list(Blacksmith_Single_Cave_Doors) - door_targets = list(Single_Cave_Targets) - - # place blacksmith, has limited options - random.shuffle(blacksmith_doors) - blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) - bomb_shop_doors.extend(blacksmith_doors) - - # place dam and pyramid fairy, have limited options - random.shuffle(bomb_shop_doors) - bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) - single_doors.extend(bomb_shop_doors) - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - # place remaining doors - connect_doors(world, single_doors, door_targets, player) elif world.shuffle[player] == 'insanity': # beware ye who enter here @@ -1023,149 +650,6 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, doors, door_targets, player) - elif world.shuffle[player] == 'insanity_legacy': - world.fix_fake_world[player] = False - # beware ye who enter here - - entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] - entrances_must_exits = DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + LW_Dungeon_Entrances_Must_Exit + ['Skull Woods Second Section Door (West)'] - - doors = LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] + Old_Man_Entrances +\ - DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] - - random.shuffle(doors) - - old_man_entrances = list(Old_Man_Entrances) + ['Tower of Hera'] - - caves = Cave_Exits + Dungeon_Exits + Cave_Three_Exits + ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)', 'Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)', - 'Kakariko Well Exit', 'Bat Cave Exit', 'North Fairy Cave Exit', 'Lost Woods Hideout Exit', 'Lumberjack Tree Exit', 'Sanctuary Exit'] - - # shuffle up holes - - hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', - 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] - - hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Back Drop', - 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle'] - - if world.mode[player] == 'standard': - # cannot move uncle cave - connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player) - connect_exit(world, 'Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance Stairs', player) - connect_entrance(world, 'Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', player) - else: - hole_entrances.append('Hyrule Castle Secret Entrance Drop') - hole_targets.append('Hyrule Castle Secret Entrance') - doors.append('Hyrule Castle Secret Entrance Stairs') - entrances.append('Hyrule Castle Secret Entrance Stairs') - caves.append('Hyrule Castle Secret Entrance Exit') - - if not world.shuffle_ganon: - connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player) - connect_two_way(world, 'Pyramid Entrance', 'Pyramid Exit', player) - connect_entrance(world, 'Pyramid Hole', 'Pyramid', player) - else: - entrances.append('Ganons Tower') - caves.extend(['Ganons Tower Exit', 'Pyramid Exit']) - hole_entrances.append('Pyramid Hole') - hole_targets.append('Pyramid') - entrances_must_exits.append('Pyramid Entrance') - doors.extend(['Ganons Tower', 'Pyramid Entrance']) - - random.shuffle(hole_entrances) - random.shuffle(hole_targets) - random.shuffle(entrances) - - # fill up holes - for hole in hole_entrances: - connect_entrance(world, hole, hole_targets.pop(), player) - - # hyrule castle handling - if world.mode[player] == 'standard': - # must connect front of hyrule castle to do escape - connect_entrance(world, 'Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', player) - connect_exit(world, 'Hyrule Castle Exit (South)', 'Hyrule Castle Entrance (South)', player) - caves.append(('Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) - else: - doors.append('Hyrule Castle Entrance (South)') - entrances.append('Hyrule Castle Entrance (South)') - caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)')) - - # now let's deal with mandatory reachable stuff - def extract_reachable_exit(cavelist): - random.shuffle(cavelist) - candidate = None - for cave in cavelist: - if isinstance(cave, tuple) and len(cave) > 1: - # special handling: TRock has two entries that we should consider entrance only - # ToDo this should be handled in a more sensible manner - if cave[0] in ['Turtle Rock Exit (Front)', 'Spectacle Rock Cave Exit (Peak)'] and len(cave) == 2: - continue - candidate = cave - break - if candidate is None: - raise RuntimeError('No suitable cave.') - cavelist.remove(candidate) - return candidate - - def connect_reachable_exit(entrance, caves, doors): - cave = extract_reachable_exit(caves) - - exit = cave[-1] - cave = cave[:-1] - connect_exit(world, exit, entrance, player) - connect_entrance(world, doors.pop(), exit, player) - # rest of cave now is forced to be in this world - caves.append(cave) - - # connect mandatory exits - for entrance in entrances_must_exits: - connect_reachable_exit(entrance, caves, doors) - - # place old man, has limited options - # exit has to come from specific set of doors, the entrance is free to move about - old_man_entrances = [entrance for entrance in old_man_entrances if entrance in entrances] - random.shuffle(old_man_entrances) - old_man_exit = old_man_entrances.pop() - entrances.remove(old_man_exit) - - connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit, player) - connect_entrance(world, doors.pop(), 'Old Man Cave Exit (East)', player) - caves.append('Old Man Cave Exit (West)') - - # handle remaining caves - for cave in caves: - if isinstance(cave, str): - cave = (cave,) - - for exit in cave: - connect_exit(world, exit, entrances.pop(), player) - connect_entrance(world, doors.pop(), exit, player) - - # handle simple doors - - single_doors = list(Single_Cave_Doors) - bomb_shop_doors = list(Bomb_Shop_Single_Cave_Doors) - blacksmith_doors = list(Blacksmith_Single_Cave_Doors) - door_targets = list(Single_Cave_Targets) - - # place blacksmith, has limited options - random.shuffle(blacksmith_doors) - blacksmith_hut = blacksmith_doors.pop() - connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) - bomb_shop_doors.extend(blacksmith_doors) - - # place dam and pyramid fairy, have limited options - random.shuffle(bomb_shop_doors) - bomb_shop = bomb_shop_doors.pop() - connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) - single_doors.extend(bomb_shop_doors) - - # tavern back door cannot be shuffled yet - connect_doors(world, ['Tavern North'], ['Tavern'], player) - - # place remaining doors - connect_doors(world, single_doors, door_targets, player) else: raise NotImplementedError('Shuffling not supported yet') @@ -1326,7 +810,7 @@ def link_inverted_entrances(world, player): 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave (Bottom)', 'Old Man Cave (East)', 'Death Mountain Return Cave (East)', 'Spiral Cave', 'Old Man House (Top)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)'] - + # place old man, bumper cave bottom to DDM entrances not in east bottom random.shuffle(old_man_entrances) @@ -3059,7 +2543,8 @@ Inverted_Must_Exit_Invalid_Connections = defaultdict(set, { }) -# these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions +# these are connections that cannot be shuffled and always exist. +# They link together separate parts of the world we need to divide into regions mandatory_connections = [('Links House S&Q', 'Links House'), ('Sanctuary S&Q', 'Sanctuary'), ('Old Man S&Q', 'Old Man House'), diff --git a/Fill.py b/Fill.py index 3645e5d9..43a3abc0 100644 --- a/Fill.py +++ b/Fill.py @@ -11,7 +11,7 @@ from source.item.FillUtil import filter_pot_locations, valid_pot_items def get_dungeon_item_pool(world): - return [item for dungeon in world.dungeons for item in dungeon.all_items] + return [item for dungeon in world.dungeons for item in dungeon.all_items if item.location is None] def promote_dungeon_items(world): diff --git a/Gui.py b/Gui.py index 032cce90..9eab4aac 100755 --- a/Gui.py +++ b/Gui.py @@ -179,7 +179,7 @@ def guiMain(args=None): self.pages["startinventory"].content.pack(side=TOP, fill=BOTH, expand=True) # Custom Controls - self.pages["custom"].content = custom_page(self,self.pages["custom"]) + self.pages["custom"].content = custom_page(self, self.pages["custom"]) self.pages["custom"].content.pack(side=TOP, fill=BOTH, expand=True) def validation(P): diff --git a/ItemList.py b/ItemList.py index ea35dd59..da01706f 100644 --- a/ItemList.py +++ b/ItemList.py @@ -6,7 +6,7 @@ import RaceRandom as random from BaseClasses import Region, RegionType, Shop, ShopType, Location, CollectionState, PotItem from EntranceShuffle import connect_entrance from Regions import shop_to_location_table, retro_shops, shop_table_by_location, valid_pot_location -from Fill import FillError, fill_restrictive, fast_fill, get_dungeon_item_pool +from Fill import FillError, fill_restrictive, get_dungeon_item_pool, is_dungeon_item from PotShuffle import vanilla_pots from Items import ItemFactory @@ -254,7 +254,9 @@ def generate_itempool(world, player): world.get_location('Zelda Drop Off', player).locked = True # set up item pool - if world.custom: + if world.customizer and world.customizer.get_item_pool(): + (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = make_customizer_pool(world, player) + elif world.custom: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray) world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) else: @@ -352,7 +354,9 @@ def generate_itempool(world, player): # rather than making all hearts/heart pieces progression items (which slows down generation considerably) # We mark one random heart container as an advancement item (or 4 heart pieces in expert mode) if world.difficulty[player] in ['normal', 'hard'] and not (world.custom and world.customitemarray[player]["heartcontainer"] == 0): - next(item for item in items if item.name == 'Boss Heart Container').advancement = True + container = next((item for item in items if item.name == 'Boss Heart Container'), None) + if container: + container.advancement = True elif world.difficulty[player] in ['expert'] and not (world.custom and world.customitemarray[player]["heartpiece"] < 4): adv_heart_pieces = (item for item in items if item.name == 'Piece of Heart') for i in range(4): @@ -372,8 +376,19 @@ def generate_itempool(world, player): world.itempool += [beemizer(item) for item in items] # shuffle medallions - mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] - tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] + mm_medallion, tr_medallion = None, None + if world.customizer and world.customizer.get_medallions() and player in world.customizer.get_medallions(): + medal_map = world.customizer.get_medallions() + if player in medal_map: + custom_medallions = medal_map[player] + if 'Misery Mire' in custom_medallions: + mm_medallion = custom_medallions['Misery Mire'] + if 'Turtle Rock' in custom_medallions: + tr_medallion = custom_medallions['Turtle Rock'] + if not mm_medallion: + mm_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] + if not tr_medallion: + tr_medallion = ['Ether', 'Quake', 'Bombos'][random.randint(0, 2)] world.required_medallions[player] = (mm_medallion, tr_medallion) # shuffle bottle refills @@ -797,12 +812,8 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, lamps_needed_for_dark_rooms = 1 - # insanity shuffle doesn't have fake LW/DW logic so for now guaranteed Mirror and Moon Pearl at the start - if shuffle == 'insanity_legacy': - place_item('Link\'s House', 'Magic Mirror') - place_item('Sanctuary', 'Moon Pearl') - else: - pool.extend(['Magic Mirror', 'Moon Pearl']) + # old insanity shuffle didn't have fake LW/DW logic so this used to be conditional + pool.extend(['Magic Mirror', 'Moon Pearl']) if timer == 'display': clock_mode = 'stopwatch' @@ -993,15 +1004,8 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s pool.extend(['Fighter Sword'] * customitemarray["sword1"]) pool.extend(['Progressive Sword'] * customitemarray["progressivesword"]) - - if shuffle == 'insanity_legacy': - place_item('Link\'s House', 'Magic Mirror') - place_item('Sanctuary', 'Moon Pearl') - pool.extend(['Magic Mirror'] * max((customitemarray["mirror"] -1 ), 0)) - pool.extend(['Moon Pearl'] * max((customitemarray["pearl"] - 1), 0)) - else: - pool.extend(['Magic Mirror'] * customitemarray["mirror"]) - pool.extend(['Moon Pearl'] * customitemarray["pearl"]) + pool.extend(['Magic Mirror'] * customitemarray["mirror"]) + pool.extend(['Moon Pearl'] * customitemarray["pearl"]) if retro: itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in Retro Mode @@ -1012,6 +1016,39 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) + +def make_customizer_pool(world, player): + pool = [] + placed_items = {} + precollected_items = [] + clock_mode = None + + def place_item(loc, item): + assert loc not in placed_items + placed_items[loc] = item + + diff = difficulties[world.difficulty[player]] + for item_name, amount in world.customizer.get_item_pool()[player].items(): + if isinstance(amount, int): + if item_name == 'Bottle (Random)': + for _ in range(amount): + pool.append(random.choice(diff.bottles)) + else: + pool.extend([item_name] * amount) + + timer = world.timer[player] + if timer in ['display', 'timed', 'timed-countdown']: + clock_mode = 'countdown' if timer == 'timed-countdown' else 'stopwatch' + elif timer == 'timed-ohko': + clock_mode = 'countdown-ohko' + elif timer == 'ohko': + clock_mode = 'ohko' + + if world.goal[player] == 'pedestal': + place_item('Master Sword Pedestal', 'Triforce') + + return pool, placed_items, precollected_items, clock_mode, 1 + # A quick test to ensure all combinations generate the correct amount of items. def test(): for difficulty in ['normal', 'hard', 'expert']: @@ -1020,7 +1057,7 @@ def test(): for mode in ['open', 'standard', 'inverted', 'retro']: for swords in ['random', 'assured', 'swordless', 'vanilla']: for progressive in ['on', 'off']: - for shuffle in ['full', 'insanity_legacy']: + for shuffle in ['full']: for logic in ['noglitches', 'minorglitches', 'owglitches', 'nologic']: for retro in [True, False]: for bombbag in [True, False]: @@ -1044,24 +1081,48 @@ if __name__ == '__main__': def fill_specific_items(world): - keypool = [item for item in world.itempool if item.smallkey] - cage = world.get_location('Tower of Hera - Basement Cage', 1) - c_dungeon = cage.parent_region.dungeon - key_item = next(x for x in keypool if c_dungeon.name in x.name or (c_dungeon.name == 'Hyrule Castle' and 'Escape' in x.name)) - world.itempool.remove(key_item) - all_state = world.get_all_state(True) - fill_restrictive(world, all_state, [cage], [key_item]) - - location = world.get_location('Tower of Hera - Map Chest', 1) - key_item = next(x for x in world.itempool if 'Byrna' in x.name) - world.itempool.remove(key_item) - fast_fill(world, [key_item], [location]) + if world.customizer: + placements = world.customizer.get_placements() + dungeon_pool = get_dungeon_item_pool(world) + prize_pool = [] + prize_set = {'Red Pendant', 'Blue Pendant', 'Green Pendant', 'Crystal 1', 'Crystal 2', + 'Crystal 3', 'Crystal 4', 'Crystal 7', 'Crystal 5', 'Crystal 6'} + for p in range(1, world.players + 1): + prize_pool.extend(prize_set) + if placements: + for player, placement_list in placements.items(): + for location, item in placement_list.items(): + loc = world.get_location(location, player) + item_parts = item.split('#') + item_player = player if len(item_parts) < 2 else int(item_parts[1]) + item_name = item_parts[0] + event_flag = False + if is_dungeon_item(item_name, world, item_player): + item_to_place = next(x for x in dungeon_pool + if x.name == item_name and x.player == item_player) + dungeon_pool.remove(item_to_place) + event_flag = True + elif item_name in prize_set: + item_player = player # prizes must be for that player + item_to_place = ItemFactory(item_name, item_player) + prize_pool.remove(item_name) + event_flag = True + else: + item_to_place = next((x for x in world.itempool + if x.name == item_name and x.player == item_player), None) + if item_to_place is None: + item_to_place = ItemFactory(item_name, player) + else: + world.itempool.remove(item_to_place) + world.push_item(loc, item_to_place, False) + # track_outside_keys(item_to_place, spot_to_fill, world) + # track_dungeon_items(item_to_place, spot_to_fill, world) + loc.event = event_flag or item_to_place.advancement - # somaria = next(item for item in world.itempool if item.name == 'Cane of Somaria') - # shooter = world.get_location('Palace of Darkness - Shooter Room', 1) - # world.itempool.remove(somaria) - # all_state = world.get_all_state(True) - # fill_restrictive(world, all_state, [shooter], [somaria]) - +def is_dungeon_item(item, world, player): + return ((item.startswith('Small Key') and not world.keyshuffle[player]) + or (item.startswith('Big Key') and not world.bigkeyshuffle[player]) + or (item.startswith('Compass') and not world.compassshuffle[player]) + or (item.startswith('Map') and not world.mapshuffle[player])) diff --git a/Main.py b/Main.py index d9212380..e06d434b 100644 --- a/Main.py +++ b/Main.py @@ -25,11 +25,13 @@ from Rules import set_rules from Dungeons import create_dungeons from Fill import distribute_items_restrictive, promote_dungeon_items, fill_dungeons_restrictive, ensure_good_pots from Fill import sell_potions, sell_keys, balance_multiworld_progression, balance_money_progression, lock_shop_locations -from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops +from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops, fill_specific_items from Utils import output_path, parse_player_names from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config +from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data +from source.classes.CustomSettings import CustomSettings __version__ = '1.0.1.11v' @@ -57,22 +59,32 @@ def main(args, seed=None, fish=None): if args.securerandom: random.use_secure() - + seeded = False # initialize the world if args.code: for player, code in args.code.items(): if code: Settings.adjust_args_from_code(code, player, args) + customized = None + if args.customizer: + customized = CustomSettings() + customized.load_yaml(args.customizer) + seed = customized.determine_seed() + if seed: + seeded = True + customized.adjust_args(args) world = World(args.multi, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, args.accessibility, args.shuffleganon, args.retro, args.custom, args.customitemarray, args.hints) + world.customizer = customized if customized else None logger = logging.getLogger('') if seed is None: random.seed(None) world.seed = random.randint(0, 999999999) else: world.seed = int(seed) - random.seed(world.seed) + if not seeded: + random.seed(world.seed) if args.securerandom: world.seed = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(9)) @@ -128,6 +140,8 @@ def main(args, seed=None, fish=None): for player, name in enumerate(team, 1): world.player_names[player].append(name) logger.info('') + world.settings = CustomSettings() + world.settings.create_from_world(world) for player in range(1, world.players + 1): world.difficulty_requirements[player] = difficulties[world.difficulty[player]] @@ -156,6 +170,15 @@ def main(args, seed=None, fish=None): adjust_locations(world, player) place_bosses(world, player) + if world.customizer and world.customizer.get_start_inventory(): + for p, inv_list in world.customizer.get_start_inventory().items(): + for inv_item in inv_list: + item = ItemFactory(inv_item.strip(), p) + if item: + world.push_precollected(item) + if args.print_custom_yaml: + world.settings.record_info(world) + if any(world.potshuffle.values()): logger.info(world.fish.translate("cli", "cli", "shuffling.pots")) for player in range(1, world.players + 1): @@ -168,15 +191,20 @@ def main(args, seed=None, fish=None): logger.info(world.fish.translate("cli","cli","shuffling.world")) for player in range(1, world.players + 1): - if world.mode[player] != 'inverted': - link_entrances(world, player) + if world.experimental[player] or (world.customizer and world.customizer.get_entrances()): + link_entrances_new(world, player) else: - link_inverted_entrances(world, player) + if world.mode[player] != 'inverted': + link_entrances(world, player) + else: + link_inverted_entrances(world, player) logger.info(world.fish.translate("cli", "cli", "shuffling.prep")) for player in range(1, world.players + 1): link_doors_prep(world, player) + if args.print_custom_yaml: + world.settings.record_entrances(world) create_item_pool_config(world) logger.info(world.fish.translate("cli", "cli", "shuffling.dungeons")) @@ -187,6 +215,8 @@ def main(args, seed=None, fish=None): mark_light_world_regions(world, player) else: mark_dark_world_regions(world, player) + if args.print_custom_yaml: + world.settings.record_doors(world) logger.info(world.fish.translate("cli", "cli", "generating.itempool")) for player in range(1, world.players + 1): @@ -207,13 +237,13 @@ def main(args, seed=None, fish=None): lock_shop_locations(world, player) massage_item_pool(world) + if args.print_custom_yaml: + world.settings.record_item_pool(world) + fill_specific_items(world) logger.info(world.fish.translate("cli", "cli", "placing.dungeon.prizes")) fill_prizes(world) - # used for debugging - # fill_specific_items(world) - logger.info(world.fish.translate("cli","cli","placing.dungeon.items")) if args.algorithm != 'equitable': @@ -258,6 +288,9 @@ def main(args, seed=None, fish=None): ensure_good_pots(world, True) outfilebase = f'DR_{args.outputname if args.outputname else world.seed}' + if args.print_custom_yaml: + world.settings.record_item_placements(world) + world.settings.write_to_file(output_path(f'{outfilebase}_custom.yaml')) rom_names = [] jsonout = {} diff --git a/Mystery.py b/Mystery.py index c8d4da4a..3a33dad2 100644 --- a/Mystery.py +++ b/Mystery.py @@ -1,15 +1,15 @@ import argparse import logging import RaceRandom as random -import urllib.request -import urllib.parse -import yaml from DungeonRandomizer import parse_cli from Main import main as DRMain from source.classes.BabelFish import BabelFish from yaml.constructor import SafeConstructor +from source.tools.MysteryUtils import roll_settings, get_weights + + def add_bool(self, node): return self.construct_scalar(node) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b67ae9bf..4d7688c0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -35,6 +35,15 @@ The old "Pot Shuffle" option is still available under "Pot Shuffle (Legacy)" or The sram locations for pots and sprite drops are not yet final, please reach out for assistance or investigate the rom changes. +## Customizer + +Please refer to [the documentation](docs/Customizer.md) and examples of customizer [here](docs/customizer_example.yaml) and [here](docs/multi_mystery_example.yaml) +note that entrance customization is only available with experimental features turned on. + +## Experimental Entrance Shuffle + +To support customizer and future entrance shuffle modes (perhaps even customizable ones), the entrance shuffle algorithm has been re-written. It is currently in an unstable state, and will use the old method unless you turn experimental features on. I'm currently in the process of evaluating most modes with different combinations of settings and checking the distribution of entrances. Entrance customization is only supported with this new experimental entrance shuffle. The experimental entrance shuffle includes prototypes of Lean and Lite entrance shuffles from the OWR branch. + ## Restricted Item Placement Algorithm diff --git a/Rom.py b/Rom.py index 2b376e56..2069bb7f 100644 --- a/Rom.py +++ b/Rom.py @@ -681,7 +681,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # Thanks to Zarby89 for originally finding these values # todo fix screen scrolling - if world.shuffle[player] not in ['insanity', 'insanity_legacy', 'madness_legacy'] and \ + if world.shuffle[player] not in ['insanity'] and \ exit.name in ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Ice Palace Exit', 'Misery Mire Exit', 'Palace of Darkness Exit', 'Swamp Palace Exit', 'Ganons Tower Exit', 'Desert Palace Exit (North)', 'Agahnims Tower Exit', 'Spiral Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)', 'Turtle Rock Ledge Exit (East)']: @@ -790,8 +790,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x13f030+offset, layout.max_chests) builder = world.dungeon_layouts[player][name] valid_cnt = len(valid_loc_by_dungeon[name]) - if valid_cnt > 99: - logging.getLogger('').warning(f'{name} exceeds 99 in locations ({valid_cnt})') + if valid_cnt > 256: + logging.getLogger('').warning(f'{name} exceeds 256 in locations ({valid_cnt})') rom.write_byte(0x13f080+offset, valid_cnt % 10) rom.write_byte(0x13f090+offset, valid_cnt // 10) rom.write_byte(0x13f0a0+offset, valid_cnt) @@ -1644,7 +1644,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0x02F539, [0xEA, 0xEA, 0xEA, 0xEA, 0xEA] if world.powder_patch_required[player] else [0xAD, 0xBF, 0x0A, 0xF0, 0x4F]) # allow smith into multi-entrance caves in appropriate shuffles - if world.shuffle[player] in ['restricted', 'full', 'crossed', 'insanity'] or (world.shuffle[player] == 'simple' and world.mode[player] == 'inverted'): + if world.shuffle[player] in ['restricted', 'full', 'lite', 'lean', 'crossed', 'insanity'] or (world.shuffle[player] == 'simple' and world.mode[player] == 'inverted'): rom.write_byte(0x18004C, 0x01) # set correct flag for hera basement item @@ -2133,7 +2133,7 @@ def write_strings(rom, world, player, team): entrances_to_hint.update({'Inverted Ganons Tower': 'The sealed castle door'}) else: entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'}) - if world.shuffle[player] in ['simple', 'restricted', 'restricted_legacy']: + if world.shuffle[player] in ['simple', 'restricted']: for entrance in all_entrances: if entrance.name in entrances_to_hint: this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(entrance.connected_region) + '.' @@ -2144,22 +2144,22 @@ def write_strings(rom, world, player, team): entrances_to_hint.update(InconvenientOtherEntrances) if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: hint_count = 0 - elif world.shuffle[player] in ['simple', 'restricted', 'restricted_legacy']: + elif world.shuffle[player] in ['simple', 'restricted']: hint_count = 2 else: hint_count = 4 for entrance in all_entrances: - if entrance.name in entrances_to_hint: - if hint_count > 0: + if hint_count > 0: + if entrance.name in entrances_to_hint: this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(entrance.connected_region) + '.' tt[hint_locations.pop(0)] = this_hint entrances_to_hint.pop(entrance.name) hint_count -= 1 - else: - break + else: + break #Next we handle hints for randomly selected other entrances, curating the selection intelligently based on shuffle. - if world.shuffle[player] not in ['simple', 'restricted', 'restricted_legacy']: + if world.shuffle[player] not in ['simple', 'restricted']: entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(DungeonEntrances) if world.mode[player] == 'inverted': @@ -2168,7 +2168,17 @@ def write_strings(rom, world, player, team): entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) elif world.shuffle[player] == 'restricted': entrances_to_hint.update(ConnectorEntrances) - entrances_to_hint.update(OtherEntrances) + entrances_to_hint.update(ItemEntrances) + if world.shuffle[player] not in ['lite', 'lean']: + entrances_to_hint.update(ShopEntrances) + entrances_to_hint.update(OtherEntrances) + elif world.shopsanity[player]: + entrances_to_hint.update(ShopEntrances) + if world.shufflelinks[player] and world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + if world.mode[player] == 'inverted': + entrances_to_hint.update({'Inverted Links House': 'The hero\'s old residence'}) + else: + entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) if world.mode[player] == 'inverted': entrances_to_hint.update({'Inverted Dark Sanctuary': 'The dark sanctuary cave'}) entrances_to_hint.update({'Inverted Big Bomb Shop': 'The old hero\'s dark home'}) @@ -2176,7 +2186,7 @@ def write_strings(rom, world, player, team): else: entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'}) entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) - if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']: + if world.shuffle[player] in ['insanity']: entrances_to_hint.update(InsanityEntrances) if world.shuffle_ganon: if world.mode[player] == 'inverted': @@ -2802,16 +2812,45 @@ DungeonEntrances = {'Eastern Palace': 'Eastern Palace', 'Desert Palace Entrance (North)': 'The northmost cave in the desert' } -OtherEntrances = {'Blinds Hideout': 'Blind\'s old house', - 'Lake Hylia Fairy': 'A cave NE of Lake Hylia', +ItemEntrances = {'Blinds Hideout': 'Blind\'s old house', + 'Chicken House': 'The chicken lady\'s house', + 'Aginahs Cave': 'The open desert cave', + 'Sahasrahlas Hut': 'The house near armos', + 'Blacksmiths Hut': 'The old smithery', + 'Sick Kids House': 'The central house in Kakariko', + 'Mini Moldorm Cave': 'The cave south of Lake Hylia', + 'Ice Rod Cave': 'The sealed cave SE Lake Hylia', + 'Library': 'The old library', + 'Potion Shop': 'The witch\'s building', + 'Dam': 'The old dam', + 'Waterfall of Wishing': 'Going behind the waterfall', + 'Bonk Rock Cave': 'The rock pile near Sanctuary', + 'Graveyard Cave': 'The graveyard ledge', + 'Checkerboard Cave': 'The NE desert ledge', + 'Cave 45': 'The ledge south of haunted grove', + 'Kings Grave': 'The northeastmost grave', + 'C-Shaped House': 'The NE house in Village of Outcasts', + 'Mire Shed': 'The western hut in the mire', + 'Spike Cave': 'The ledge cave on west dark DM', + 'Hype Cave': 'The cave south of the old bomb shop', + 'Brewery': 'The Village of Outcasts building with no door', + 'Chest Game': 'The westmost building in the Village of Outcasts', + } + +ShopEntrances = {'Cave Shop (Lake Hylia)': 'The cave NW Lake Hylia', + 'Kakariko Shop': 'The old Kakariko shop', + 'Capacity Upgrade': 'The cave on the island', + 'Dark Lake Hylia Shop': 'The building NW dark Lake Hylia', + 'Dark World Shop': 'The hammer sealed building', + 'Red Shield Shop': 'The fenced in building', + 'Cave Shop (Dark Death Mountain)': 'The base of east dark DM', + 'Dark World Potion Shop': 'The building near the catfish', + 'Dark World Lumberjack Shop': 'The northmost Dark World building' + } + +OtherEntrances = {'Lake Hylia Fairy': 'A cave NE of Lake Hylia', 'Light Hype Fairy': 'The cave south of your house', 'Desert Fairy': 'The cave near the desert', - 'Chicken House': 'The chicken lady\'s house', - 'Aginahs Cave': 'The open desert cave', - 'Sahasrahlas Hut': 'The house near armos', - 'Cave Shop (Lake Hylia)': 'The cave NW Lake Hylia', - 'Blacksmiths Hut': 'The old smithery', - 'Sick Kids House': 'The central house in Kakariko', 'Lost Woods Gamble': 'A tree trunk door', 'Fortune Teller (Light)': 'A building NE of Kakariko', 'Snitch Lady (East)': 'A house guarded by a snitch', @@ -2819,49 +2858,24 @@ OtherEntrances = {'Blinds Hideout': 'Blind\'s old house', 'Bush Covered House': 'A house with an uncut lawn', 'Tavern (Front)': 'A building with a backdoor', 'Light World Bomb Hut': 'A Kakariko building with no door', - 'Kakariko Shop': 'The old Kakariko shop', - 'Mini Moldorm Cave': 'The cave south of Lake Hylia', 'Long Fairy Cave': 'The eastmost portal cave', 'Good Bee Cave': 'The open cave SE Lake Hylia', '20 Rupee Cave': 'The rock SE Lake Hylia', '50 Rupee Cave': 'The rock near the desert', - 'Ice Rod Cave': 'The sealed cave SE Lake Hylia', - 'Library': 'The old library', - 'Potion Shop': 'The witch\'s building', - 'Dam': 'The old dam', 'Lumberjack House': 'The lumberjack house', 'Lake Hylia Fortune Teller': 'The building NW Lake Hylia', 'Kakariko Gamble Game': 'The old Kakariko gambling den', - 'Waterfall of Wishing': 'Going behind the waterfall', - 'Capacity Upgrade': 'The cave on the island', - 'Bonk Rock Cave': 'The rock pile near Sanctuary', - 'Graveyard Cave': 'The graveyard ledge', - 'Checkerboard Cave': 'The NE desert ledge', - 'Cave 45': 'The ledge south of haunted grove', - 'Kings Grave': 'The northeastmost grave', 'Bonk Fairy (Light)': 'The rock pile near your home', 'Hookshot Fairy': 'The left paired cave on east DM', - 'Bonk Fairy (Dark)': 'The rock pile near the old bomb shop', + 'Bonk Fairy (Dark)': 'The rock pile near the old bomb shop', 'Dark Lake Hylia Fairy': 'The cave NE dark Lake Hylia', - 'C-Shaped House': 'The NE house in Village of Outcasts', 'Dark Death Mountain Fairy': 'The SW cave on dark DM', - 'Dark Lake Hylia Shop': 'The building NW dark Lake Hylia', - 'Dark World Shop': 'The hammer sealed building', - 'Red Shield Shop': 'The fenced in building', - 'Mire Shed': 'The western hut in the mire', 'East Dark World Hint': 'The dark cave near the eastmost portal', 'Dark Desert Hint': 'The cave east of the mire', - 'Spike Cave': 'The ledge cave on west dark DM', 'Palace of Darkness Hint': 'The building south of Kiki', 'Dark Lake Hylia Ledge Spike Cave': 'The rock SE dark Lake Hylia', - 'Cave Shop (Dark Death Mountain)': 'The base of east dark DM', - 'Dark World Potion Shop': 'The building near the catfish', 'Archery Game': 'The old archery game', - 'Dark World Lumberjack Shop': 'The northmost Dark World building', - 'Hype Cave': 'The cave south of the old bomb shop', - 'Brewery': 'The Village of Outcasts building with no door', 'Dark Lake Hylia Ledge Hint': 'The open cave SE dark Lake Hylia', - 'Chest Game': 'The westmost building in the Village of Outcasts', 'Dark Desert Fairy': 'The eastern hut in the mire', 'Dark Lake Hylia Ledge Fairy': 'The sealed cave SE dark Lake Hylia', 'Fortune Teller (Dark)': 'The building NE the Village of Outcasts' diff --git a/RoomData.py b/RoomData.py index f3c82576..e3f432d0 100644 --- a/RoomData.py +++ b/RoomData.py @@ -316,6 +316,18 @@ class Room(object): byte_array.append(kind.value) return byte_array + def next_free(self): + for i, door in enumerate(self.doorList): + if i >= 4: + return None + pos, kind = door + if kind not in [DoorKind.SmallKey, DoorKind.Dashable, DoorKind.Bombable, DoorKind.TrapTriggerable, + DoorKind.Trap, DoorKind.Trap2, DoorKind.TrapTriggerableLow, DoorKind.TrapLowE3, + DoorKind.BigKey, DoorKind.StairKey, DoorKind.StairKey2, DoorKind.StairKeyLow, + DoorKind.BlastWall, DoorKind.BombableEntrance]: + return i + return None + def __str__(self): return str(self.__unicode__()) diff --git a/Rules.py b/Rules.py index e96a483a..81b419a1 100644 --- a/Rules.py +++ b/Rules.py @@ -63,7 +63,7 @@ def set_rules(world, player): if world.mode[player] != 'inverted': set_big_bomb_rules(world, player) - if world.logic[player] == 'owglitches' and world.shuffle[player] not in ('insanity', 'insanity_legacy'): + if world.logic[player] == 'owglitches' and world.shuffle[player] != 'insanity': path_to_courtyard = mirrorless_path_to_castle_courtyard(world, player) add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.world.get_entrance('Dark Death Mountain Offset Mirror', player).can_reach(state) and all(rule(state) for rule in path_to_courtyard), 'or') else: diff --git a/docs/Customizer.md b/docs/Customizer.md new file mode 100644 index 00000000..af9ae7ed --- /dev/null +++ b/docs/Customizer.md @@ -0,0 +1,182 @@ +## Customizer Files + +A customizer file is [yaml file](https://yaml.org/) with different settings. This documentation is intended to be read with an [example customizer file](customizer_example.yaml). + +This can also be used to roll a mystery or mutli-mystery seed via the GUI. [Example](multi_mystery_example.yaml) + +The cli includes a couple arguments to help: + +`--print_custom_yaml` will create a yaml file based on the seed rolled. Treat it like a spoiler. + +`--customizer` takes a file as an argument. + +Present on the GUI as `Print Customizer File` and `Customizer File` on the Generation Setup tab. + +### meta + +Supported values: + +* `players`: number of players +* `seed`: you can set the seed number for a set experience on things that are randomized instead of specified +* `algorithm`: fill algorithm +* `names`: for naming mutliworld players + +###### Not Yet Implemented + +* `mystery`: indicates the seed should be treated as a mystery (hides total collection_rate) (This may end up player specific) + +### settings + +This must be defined by player. Each player number should be listed with the appropriate settings. + +in each player section you can set up default settings for that player or you can specify a mystery yaml file. + +``` +1: player1.yaml +2: + shuffle: crossed + door_shuffle: basic +``` + +Player 1's settings will be determined by rolling the mystery weights and player 2's setting will be default except for those two specified in his section. Each settings should be consistent with the CLI arguments. + +Start inventory is not supported here. It has a separate section. + +###### Not Yet Implemented + +Rom/Adjust flags like sprite, quickswap are not outputing with the print_custom_yaml settings + +### item_pool + +This must be defined by player. Each player number should be listed with the appropriate pool. + +Then each player can have the entire item pool defined. The name of item should be followed by the number of that item in the pool. All key items need to be listed here for now. + +`Bottle (Random)` is supported to randomize bottle contents according to those allowed by difficulty. Pendants and crystals are supported here. + + +##### Known Issues + +1. Dungeon items amount can be increased but not eliminated (as the amount of each dungeon item is either pre-determined or calculated by door rando) and these extra items may not be confined to the dungeon +2. Door rando removes Red Rupees from the pool to make room for extra dungeon items as needed. +3. Shopsanity appends extra shop items to the pool. +4. Beemizer runs after pool creation changing junk items into bees +5. Retro + Shopsanity adds more items to the pool +6. Retro + either of dropshuffle or pottery adds keys to the pool +7. Most pottery settings add a large amount of junk items to the pool + +### placements + +This must be defined by player. Each player number should be listed with the appropriate placement list. + +You may list each location for a player and the item you wish to place there. A location name requires to be enclosed by single quotes if the location name contains a `#` (Most pot locations have the `#`). (Currently no location names have both a `'` and a `#` so you don't need to worry about escaping the `'`) + + For multiworld you can specify which player the item is for using this syntax: + +`#` + + Example: + `Pegasus Boots#3` means the boots for player 3. + + +### entrances + +This must be defined by player. Each player number should be listed with the appropriate sections. This section has three primary subsections: `entrances`, `exits`, and `two-way`. + +#### two-way + +`two-way` should be used for connectors, dungeons that you wish to couple. (as opposite to decoupled in the insanity shuffle). Links house should be placed using this method as is can be decoupled logically. (Haven't tested to see if it works in game). The overworld entrance is listed first, followed by the interior exit that it leads to. (The exit will then be linked to exit at that entrance). + +`50 Rupee Cave: Desert Palace Exit (North)` The 50 Rupee entrance leads to Desert North entrance, and leaving there will spit you out at the same place. + +#### exits + +`exits` is used for the Chris Houlihan Room Exit and connectors and dungeons that you wish to be decoupled from their entrances. Perhaps counter-intuitively, the exit is listed after the entrance from which it emerges. + +`Light Hype Fairy: Chris Houlihan Room Exit` leaving Chris Houlihan Room will spit you out at the Light Hype Fairy. + +(I can easily switch this syntax around if people would like me too) + +#### entrances + +`entrances` is used for single entrances caves, houses, shops, etc. and drops. Single entrance caves always exit to where you enter, they cannot be decoupled. Dungeons and connectors which are decoupled can also be listed here. + +`Chicken House: Kakariko Shop` if you walk into Chicken House door, you will in the Kakariko Shop. + +##### Known Issues + +Chris Houlihan and Links House should be specified together or not at all. + +### doors + +This must be defined by player. Each player number should be listed with the appropriate sections. This section has three primary subsections: `lobbies` and `doors`. + +`lobbies` lists the doors by which each dungeon is entered + +`: ` Ex. `Turtle Rock Chest: TR Lava Escape SE` + +`doors` lists pairs of doors. The first door name is listed is the key. The value of this object may be the paired door name or optionally it can have two properties: `dest` and `type`. If you want a type, you must use the second option. + +The destination door is listed under `dest` +Supported `type`s are `Key Door`, `Bomb Door`, and `Dash Door` + +Here are the two examples of the syntax: + +```Hyrule Dungeon Guardroom Abyss Edge: Hyrule Castle Lobby W``` +``` +Sewers Rat Path WS: + dest: Sewers Secret Room ES + two-way: true + type: Key Door +``` + +You'll note that sub-tile door do not need to be listed, but if you want them to be key doors you will have to list them. + + ###### Not Yet Implemented + + `one-way` to indicate decoupled doors + + ##### Known Issue + + If you specify a door type and those doors cannot be a stateful door due to the nature of the supertile (or you've placed too many on the supertile) an exception is thrown. + +### medallions + +This must be defined by player. Each player number should be listed with the appropriate info. + +Example: +``` +Misery Mire: Ether +Turtle Rock: Quake +``` + +Leave blank or omit if you wish it to be random. + +### bosses + +This must be defined by player. Each player number should be listed with the appropriate boss list. + +This is done as `: ` + +E.g. `Skull Woods: Helmasaur King` for helmacopter. Be sure to turn on at least one enemizer setting for the bosses to actually be randomized. + +### startinventory + +This must be defined by player. Each player number should be listed with a list of items to start with. + +This is a yaml list (note the hyphens): + +``` +startinventory: + 1: + - Pegasus Boots + - Progressive Sword +``` + +To start with multiple copies of progressive items, list them more than once. + +##### Known Issue + +This conflicts with the mystery yaml, if specified. These start inventory items will be added after those are added. + + diff --git a/docs/customizer_example.yaml b/docs/customizer_example.yaml new file mode 100644 index 00000000..3100e6c2 --- /dev/null +++ b/docs/customizer_example.yaml @@ -0,0 +1,108 @@ +meta: + algorithm: balanced + players: 1 + seed: 42 + names: Lonk +settings: + 1: + door_shuffle: basic + dropshuffle: true + experimental: true + goal: ganon + hints: true + intensity: 3 + overworld_map: compass + pseudoboots: true + pottery: keys + shopsanity: true + shuffle: crossed + shufflelinks: true + shufflebosses: unique +item_pool: + 1: + Blue Boomerang: 3 + Bombos: 3 + Book of Mudora: 3 + Boss Heart Container: 30 + Bottle (Random): 12 + Bug Catching Net: 3 + Cane of Byrna: 3 + Cane of Somaria: 3 + Cape: 3 + Ether: 3 + Fire Rod: 3 + Flippers: 3 + Hammer: 3 + Hookshot: 3 + Ice Rod: 3 + Lamp: 3 + Magic Mirror: 3 + Magic Powder: 3 + Magic Upgrade (1/2): 3 + Moon Pearl: 3 + Mushroom: 3 + Ocarina: 3 + Pegasus Boots: 3 + Piece of Heart: 24 + Progressive Armor: 6 + Progressive Bow: 6 + Progressive Glove: 6 + Progressive Shield: 9 + Progressive Sword: 12 + Quake: 3 + Red Boomerang: 3 + Rupees (300): 10 + Bombs (3): 20 + Sanctuary Heart Container: 3 + Shovel: 3 + Single Arrow: 1 +placements: + 1: + Palace of Darkness - Big Chest: Hammer + Capacity Upgrade - Left: Moon Pearl + Turtle Rock - Pokey 2 Key Drop: Ice Rod +entrances: + 1: + entrances: + Bat Cave Drop: Pyramid + Dam: Chicken House + Snitch Lady (West): Cave 45 + exits: + Misery Mire: Chris Houlihan Room Exit + two-way: + Bat Cave Cave: Pyramid Exit + Bumper Cave (Bottom): Bumper Cave Exit (Bottom) + Bumper Cave (Top): Bumper Cave Exit (Top) + Skull Woods Final Section: Ganons Tower Exit + Misery Mire: Links House Exit +doors: + 1: + lobbies: + Sanctuary: Sewers Pull Switch S + Skull 2 East: Skull 1 Lobby S + Skull 3: Skull 2 West Lobby S + Turtle Rock Lazy Eyes: TR Roller Room SW + doors: + Hyrule Dungeon Guardroom Abyss Edge: Hyrule Castle Lobby W + Sewers Rat Path WS: + dest: Sewers Secret Room ES + type: Key Door + Sewers Rat Path WN: + dest: Sewers Secret Room EN + type: Key Door + Tower Pacifist Run WS: + dest: Tower Circle of Pots ES + type: Key Door + Hera Lobby Up Stairs: Hera 4F Down Stairs +medallions: + 1: + Misery Mire: Bombos +bosses: + 1: + Palace of Darkness: Arrghus + Thieves Town: Blind + Ganons Tower (top): Vitreous +startinventory: + 1: + - Pegasus Boots + diff --git a/docs/multi_mystery_example.yaml b/docs/multi_mystery_example.yaml new file mode 100644 index 00000000..74d6b755 --- /dev/null +++ b/docs/multi_mystery_example.yaml @@ -0,0 +1,17 @@ +meta: + algorithm: balanced + players: 3 + seed: 722495389 + names: Link,Zelda,Ganon +settings: + 1: player1.yml + 2: player2.yml + 3: player3.yml +start_inventory: + 1: + - Progressive Sword + - Pegasus Boots + 2: + - Lamp + 3: + - Flippers \ No newline at end of file diff --git a/docs/player1.yml b/docs/player1.yml new file mode 100644 index 00000000..6c41d350 --- /dev/null +++ b/docs/player1.yml @@ -0,0 +1,19 @@ +description: I like my keysanity distributed weirdly, but no doors please +door_shuffle: vanilla +dungeon_items: + standard: 12 + m: 3 + c: 3 + s: 3 + b: 3 + mc: 2 + ms: 2 + mb: 2 + cs: 2 + cb: 2 + sb: 2 + mcs: 3 + mcb: 3 + msb: 3 + csb: 3 + full: 12 diff --git a/docs/player2.yml b/docs/player2.yml new file mode 100644 index 00000000..a57d1403 --- /dev/null +++ b/docs/player2.yml @@ -0,0 +1,16 @@ +description: Some sort of er with unknown goals +door_shuffle: basic +entrance_shuffle: + dungeonssimple: 3 + dungeonsfull: 2 + simple: 2 + restricted: 2 + full: 2 + crossed: 3 + insanity: 1 +goals: + ganon: 2 + fast_ganon: 2 + dungeons: 1 + pedestal: 2 + triforce-hunt: 1 \ No newline at end of file diff --git a/docs/player3.yml b/docs/player3.yml new file mode 100644 index 00000000..52ab32d3 --- /dev/null +++ b/docs/player3.yml @@ -0,0 +1,25 @@ +description: Door feature fan +door_shuffle: crossed +world_state: + standard: 2 + open: 2 + inverted: 1 +intensity: + 1: 1 + 2: 1 + 3: 2 +keydropshuffle: + on: 1 + off: 1 +shopsanity: + on: 1 + off: 4 +restrict_boss_items: + none: 1 + dungeon: 1 +boss_shuffle: + none: 4 + simple: 1 + full: 1 + unique: 1 + random: 1 \ No newline at end of file diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 70bf5ab0..b2769bbf 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -132,12 +132,10 @@ "full", "crossed", "insanity", - "restricted_legacy", - "full_legacy", - "madness_legacy", - "insanity_legacy", "dungeonsfull", - "dungeonssimple" + "dungeonssimple", + "lite", + "lean" ] }, "door_shuffle": { diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index 6ae45ea5..d815cb6d 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -281,6 +281,7 @@ "bombbag": ["Start with 0 bomb capacity. Two capacity upgrades (+10) are added to the pool (default: %(default)s)" ], "startinventory": [ "Specifies a list of items that will be in your starting inventory (separated by commas). (default: %(default)s)" ], "usestartinventory": [ "Toggle usage of Starting Inventory." ], + "customizer": ["Path to a customizer file."], "custom": [ "Not supported." ], "customitemarray": [ "Not supported." ], "accessibility": [ diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index e18f7304..c81dcb61 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -131,15 +131,13 @@ "randomizer.entrance.entranceshuffle": "Entrance Shuffle", "randomizer.entrance.entranceshuffle.vanilla": "Vanilla", + "randomizer.entrance.entranceshuffle.lite": "Lite", + "randomizer.entrance.entranceshuffle.lean": "Lean", "randomizer.entrance.entranceshuffle.simple": "Simple", "randomizer.entrance.entranceshuffle.restricted": "Restricted", "randomizer.entrance.entranceshuffle.full": "Full", "randomizer.entrance.entranceshuffle.crossed": "Crossed", "randomizer.entrance.entranceshuffle.insanity": "Insanity", - "randomizer.entrance.entranceshuffle.restricted_legacy": "Restricted (Legacy)", - "randomizer.entrance.entranceshuffle.full_legacy": "Full (Legacy)", - "randomizer.entrance.entranceshuffle.madness_legacy": "Madness (Legacy)", - "randomizer.entrance.entranceshuffle.insanity_legacy": "Insanity (Legacy)", "randomizer.entrance.entranceshuffle.dungeonsfull": "Dungeons + Full", "randomizer.entrance.entranceshuffle.dungeonssimple": "Dungeons + Simple", @@ -192,6 +190,7 @@ "randomizer.generation.createspoiler": "Create Spoiler Log", "randomizer.generation.createrom": "Create Patched ROM", "randomizer.generation.calcplaythrough": "Calculate Playthrough", + "randomizer.generation.print_custom_yaml": "Print Customizer File", "randomizer.generation.usestartinventory": "Use Starting Inventory", "randomizer.generation.usecustompool": "Use Custom Item Pool", diff --git a/resources/app/gui/randomize/entrando/widgets.json b/resources/app/gui/randomize/entrando/widgets.json index ba9b7fd7..c7dde4f6 100644 --- a/resources/app/gui/randomize/entrando/widgets.json +++ b/resources/app/gui/randomize/entrando/widgets.json @@ -6,15 +6,13 @@ "type": "selectbox", "options": [ "vanilla", + "lite", + "lean", "simple", "restricted", "full", "crossed", "insanity", - "restricted_legacy", - "full_legacy", - "madness_legacy", - "insanity_legacy", "dungeonsfull", "dungeonssimple" ] diff --git a/resources/app/gui/randomize/generation/checkboxes.json b/resources/app/gui/randomize/generation/checkboxes.json index ef37e0c1..9c196402 100644 --- a/resources/app/gui/randomize/generation/checkboxes.json +++ b/resources/app/gui/randomize/generation/checkboxes.json @@ -4,6 +4,7 @@ "bps": { "type": "checkbox" }, "createspoiler": { "type": "checkbox" }, "calcplaythrough": { "type": "checkbox" }, + "print_custom_yaml": { "type": "checkbox" }, "usestartinventory": { "type": "checkbox" }, "usecustompool": { "type": "checkbox" } } diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py new file mode 100644 index 00000000..3b05f7bf --- /dev/null +++ b/source/classes/CustomSettings.py @@ -0,0 +1,329 @@ +import os +import urllib.request +import urllib.parse +import yaml +from yaml.representer import Representer +from collections import defaultdict + +import RaceRandom as random +from BaseClasses import LocationType, DoorType +from source.tools.MysteryUtils import roll_settings, get_weights + + +class CustomSettings(object): + + def __init__(self): + self.file_source = None + self.relative_dir = None + self.world_rep = {} + self.player_range = None + + def load_yaml(self, file): + self.file_source = load_yaml(file) + head, filename = os.path.split(file) + self.relative_dir = head + + def determine_seed(self): + if 'meta' not in self.file_source: + return None + meta = defaultdict(lambda: None, self.file_source['meta']) + seed = meta['seed'] + if seed: + random.seed(seed) + return seed + return None + + def determine_players(self): + if 'meta' not in self.file_source: + return None + meta = defaultdict(lambda: None, self.file_source['meta']) + return meta['players'] + + def adjust_args(self, args): + def get_setting(value, default): + if value: + return value + return default + if 'meta' in self.file_source: + meta = defaultdict(lambda: None, self.file_source['meta']) + args.multi = get_setting(meta['players'], args.multi) + args.algorithm = get_setting(meta['algorithm'], args.algorithm) + args.outputname = get_setting(meta['name'], args.outputname) + args.bps = get_setting(meta['bps'], args.bps) + args.suppress_rom = get_setting(meta['suppress_rom'], args.suppress_rom) + args.names = get_setting(meta['names'], args.names) + self.player_range = range(1, args.multi + 1) + if 'settings' in self.file_source: + for p in self.player_range: + player_setting = self.file_source['settings'][p] + if isinstance(player_setting, str): + weights = get_weights(os.path.join(self.relative_dir, player_setting)) + settings = defaultdict(lambda: None, vars(roll_settings(weights))) + else: + settings = defaultdict(lambda: None, player_setting) + args.shuffle[p] = get_setting(settings['shuffle'], args.shuffle[p]) + args.door_shuffle[p] = get_setting(settings['door_shuffle'], args.door_shuffle[p]) + args.logic[p] = get_setting(settings['logic'], args.logic[p]) + args.mode[p] = get_setting(settings['mode'], args.mode[p]) + args.swords[p] = get_setting(settings['swords'], args.swords[p]) + args.item_functionality[p] = get_setting(settings['item_functionality'], args.item_functionality[p]) + args.goal[p] = get_setting(settings['goal'], args.goal[p]) + args.difficulty[p] = get_setting(settings['difficulty'], args.difficulty[p]) + args.accessibility[p] = get_setting(settings['accessibility'], args.accessibility[p]) + args.retro[p] = get_setting(settings['retro'], args.retro[p]) + args.hints[p] = get_setting(settings['hints'], args.hints[p]) + args.shopsanity[p] = get_setting(settings['shopsanity'], args.shopsanity[p]) + args.dropshuffle[p] = get_setting(settings['dropshuffle'], args.dropshuffle[p]) + args.pottery[p] = get_setting(settings['pottery'], args.pottery[p]) + args.mixed_travel[p] = get_setting(settings['mixed_travel'], args.mixed_travel[p]) + args.standardize_palettes[p] = get_setting(settings['standardize_palettes'], + args.standardize_palettes[p]) + args.intensity[p] = get_setting(settings['intensity'], args.intensity[p]) + args.dungeon_counters[p] = get_setting(settings['dungeon_counters'], args.dungeon_counters[p]) + args.crystals_gt[p] = get_setting(settings['crystals_gt'], args.crystals_gt[p]) + args.crystals_ganon[p] = get_setting(settings['crystals_ganon'], args.crystals_ganon[p]) + args.experimental[p] = get_setting(settings['experimental'], args.experimental[p]) + args.openpyramid[p] = get_setting(settings['openpyramid'], args.openpyramid[p]) + args.bigkeyshuffle[p] = get_setting(settings['bigkeyshuffle'], args.bigkeyshuffle[p]) + args.keyshuffle[p] = get_setting(settings['keyshuffle'], args.keyshuffle[p]) + args.mapshuffle[p] = get_setting(settings['mapshuffle'], args.mapshuffle[p]) + args.compassshuffle[p] = get_setting(settings['compassshuffle'], args.compassshuffle[p]) + args.shufflebosses[p] = get_setting(settings['shufflebosses'], args.shufflebosses[p]) + args.shuffleenemies[p] = get_setting(settings['shuffleenemies'], args.shuffleenemies[p]) + args.enemy_health[p] = get_setting(settings['enemy_health'], args.enemy_health[p]) + args.enemy_damage[p] = get_setting(settings['enemy_damage'], args.enemy_damage[p]) + args.shufflepots[p] = get_setting(settings['shufflepots'], args.shufflepots[p]) + args.bombbag[p] = get_setting(settings['bombbag'], args.bombbag[p]) + args.shufflelinks[p] = get_setting(settings['shufflelinks'], args.shufflelinks[p]) + args.restrict_boss_items[p] = get_setting(settings['restrict_boss_items'], args.restrict_boss_items[p]) + args.overworld_map[p] = get_setting(settings['overworld_map'], args.overworld_map[p]) + args.pseudoboots[p] = get_setting(settings['pseudoboots'], args.pseudoboots[p]) + args.triforce_goal[p] = get_setting(settings['triforce_goal'], args.triforce_goal[p]) + args.triforce_pool[p] = get_setting(settings['triforce_pool'], args.triforce_pool[p]) + args.beemizer[p] = get_setting(settings['beemizer'], args.beemizer[p]) + + # mystery usage + args.usestartinventory[p] = get_setting(settings['usestartinventory'], args.usestartinventory[p]) + args.startinventory[p] = get_setting(settings['startinventory'], args.startinventory[p]) + + # rom adjust stuff + args.sprite[p] = get_setting(settings['sprite'], args.sprite[p]) + args.disablemusic[p] = get_setting(settings['disablemusic'], args.disablemusic[p]) + args.quickswap[p] = get_setting(settings['quickswap'], args.quickswap[p]) + args.reduce_flashing[p] = get_setting(settings['reduce_flashing'], args.reduce_flashing[p]) + args.fastmenu[p] = get_setting(settings['fastmenu'], args.fastmenu[p]) + args.heartcolor[p] = get_setting(settings['heartcolor'], args.heartcolor[p]) + args.heartbeep[p] = get_setting(settings['heartbeep'], args.heartbeep[p]) + args.ow_palettes[p] = get_setting(settings['ow_palettes'], args.ow_palettes[p]) + args.uw_palettes[p] = get_setting(settings['uw_palettes'], args.uw_palettes[p]) + args.shuffle_sfx[p] = get_setting(settings['shuffle_sfx'], args.shuffle_sfx[p]) + + def get_item_pool(self): + if 'item_pool' in self.file_source: + return self.file_source['item_pool'] + return None + + def get_placements(self): + if 'placements' in self.file_source: + return self.file_source['placements'] + return None + + def get_entrances(self): + if 'entrances' in self.file_source: + return self.file_source['entrances'] + return None + + def get_doors(self): + if 'doors' in self.file_source: + return self.file_source['doors'] + return None + + def get_bosses(self): + if 'bosses' in self.file_source: + return self.file_source['bosses'] + return None + + def get_start_inventory(self): + if 'start_inventory' in self.file_source: + return self.file_source['start_inventory'] + return None + + def get_medallions(self): + if 'medallions' in self.file_source: + return self.file_source['medallions'] + return None + + def create_from_world(self, world): + self.player_range = range(1, world.players + 1) + settings_dict, meta_dict = {}, {} + self.world_rep['meta'] = meta_dict + meta_dict['players'] = world.players + meta_dict['algorithm'] = world.algorithm + meta_dict['seed'] = world.seed + self.world_rep['settings'] = settings_dict + for p in self.player_range: + settings_dict[p] = {} + settings_dict[p]['shuffle'] = world.shuffle[p] + settings_dict[p]['door_shuffle'] = world.doorShuffle[p] + settings_dict[p]['intensity'] = world.intensity[p] + settings_dict[p]['logic'] = world.logic[p] + settings_dict[p]['mode'] = world.mode[p] + settings_dict[p]['swords'] = world.swords[p] + settings_dict[p]['difficulty'] = world.difficulty[p] + settings_dict[p]['goal'] = world.goal[p] + settings_dict[p]['accessibility'] = world.accessibility[p] + settings_dict[p]['item_functionality'] = world.difficulty_adjustments[p] + settings_dict[p]['retro'] = world.retro[p] + settings_dict[p]['hints'] = world.hints[p] + settings_dict[p]['shopsanity'] = world.shopsanity[p] + settings_dict[p]['dropshuffle'] = world.dropshuffle[p] + settings_dict[p]['pottery'] = world.pottery[p] + settings_dict[p]['mixed_travel'] = world.mixed_travel[p] + settings_dict[p]['standardize_palettes'] = world.standardize_palettes[p] + settings_dict[p]['dungeon_counters'] = world.dungeon_counters[p] + settings_dict[p]['crystals_gt'] = world.crystals_gt_orig[p] + settings_dict[p]['crystals_ganon'] = world.crystals_ganon_orig[p] + settings_dict[p]['experimental'] = world.experimental[p] + settings_dict[p]['openpyramid'] = world.open_pyramid[p] + settings_dict[p]['bigkeyshuffle'] = world.bigkeyshuffle[p] + settings_dict[p]['keyshuffle'] = world.keyshuffle[p] + settings_dict[p]['mapshuffle'] = world.mapshuffle[p] + settings_dict[p]['compassshuffle'] = world.compassshuffle[p] + settings_dict[p]['shufflebosses'] = world.boss_shuffle[p] + settings_dict[p]['shuffleenemies'] = world.enemy_shuffle[p] + settings_dict[p]['enemy_health'] = world.enemy_health[p] + settings_dict[p]['enemy_damage'] = world.enemy_damage[p] + settings_dict[p]['shufflepots'] = world.potshuffle[p] + settings_dict[p]['bombbag'] = world.bombbag[p] + settings_dict[p]['shufflelinks'] = world.shufflelinks[p] + settings_dict[p]['overworld_map'] = world.overworld_map[p] + settings_dict[p]['pseudoboots'] = world.pseudoboots[p] + settings_dict[p]['triforce_goal'] = world.treasure_hunt_count[p] + settings_dict[p]['triforce_pool'] = world.treasure_hunt_total[p] + settings_dict[p]['beemizer'] = world.beemizer[p] + + # rom adjust stuff + # settings_dict[p]['sprite'] = world.sprite[p] + # settings_dict[p]['disablemusic'] = world.disablemusic[p] + # settings_dict[p]['quickswap'] = world.quickswap[p] + # settings_dict[p]['reduce_flashing'] = world.reduce_flashing[p] + # settings_dict[p]['fastmenu'] = world.fastmenu[p] + # settings_dict[p]['heartcolor'] = world.heartcolor[p] + # settings_dict[p]['heartbeep'] = world.heartbeep[p] + # settings_dict[p]['ow_palettes'] = world.ow_palettes[p] + # settings_dict[p]['uw_palettes'] = world.uw_palettes[p] + # settings_dict[p]['shuffle_sfx'] = world.shuffle_sfx[p] + # more settings? + + def record_info(self, world): + self.world_rep['bosses'] = bosses = {} + self.world_rep['start_inventory'] = start_inv = {} + for p in self.player_range: + bosses[p] = {} + start_inv[p] = [] + for dungeon in world.dungeons: + for level, boss in dungeon.bosses.items(): + location = dungeon.name if level is None else f'{dungeon.name} ({level})' + if boss and 'Agahnim' not in boss.name: + bosses[dungeon.player][location] = boss.name + for item in world.precollected_items: + start_inv[item.player].append(item.name) + + def record_item_pool(self, world): + self.world_rep['item_pool'] = item_pool = {} + self.world_rep['medallions'] = medallions = {} + for p in self.player_range: + item_pool[p] = defaultdict(int) + medallions[p] = {} + for item in world.itempool: + item_pool[item.player][item.name] += 1 + for p, req_medals in world.required_medallions.items(): + medallions[p]['Misery Mire'] = req_medals[0] + medallions[p]['Turtle Rock'] = req_medals[1] + + def record_item_placements(self, world): + self.world_rep['placements'] = placements = {} + for p in self.player_range: + placements[p] = {} + for location in world.get_locations(): + if location.type != LocationType.Logical and not location.skip: + if location.player != location.item.player: + placements[location.player][location.name] = f'{location.item.name}#{location.item.player}' + else: + placements[location.player][location.name] = location.item.name + + def record_entrances(self, world): + self.world_rep['entrances'] = entrances = {} + world.custom_entrances = {} + for p in self.player_range: + connections = entrances[p] = {} + connections['entrances'] = {} + connections['exits'] = {} + connections['two-way'] = {} + for key, data in world.spoiler.entrances.items(): + player = data['player'] if 'player' in data else 1 + connections = entrances[player] + sub = 'two-way' if data['direction'] == 'both' else 'exits' if data['direction'] == 'exit' else 'entrances' + connections[sub][data['entrance']] = data['exit'] + + def record_doors(self, world): + self.world_rep['doors'] = doors = {} + for p in self.player_range: + meta_doors = doors[p] = {} + lobbies = meta_doors['lobbies'] = {} + door_map = meta_doors['doors'] = {} + for portal in world.dungeon_portals[p]: + lobbies[portal.name] = portal.door.name + door_types = {DoorType.Normal, DoorType.SpiralStairs, DoorType.Interior} + if world.intensity[p] > 1: + door_types.update([DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]) + door_kinds, skip = {}, set() + for key, info in world.spoiler.doorTypes.items(): + if key[1] == p: + if ' <-> ' in info['doorNames']: + dns = info['doorNames'].split(' <-> ') + for dn in dns: + door_kinds[dn] = info['type'] # Key Door, Bomb Door, Dash Door + else: + door_kinds[info['doorNames']] = info['type'] + for door in world.doors: + if door.player == p and not door.entranceFlag and door.type in door_types and door not in skip: + if door.type == DoorType.Interior: + if door.name in door_types: + door_value = {'type': door_kinds[door.name]} + door_map[door.name] = door_value # intra-tile note + skip.add(door.dest) + elif door.dest: + if door.dest.dest == door: + door_value = door.dest.name + skip.add(door.dest) + if door.name in door_kinds: + door_value = {'dest': door_value, 'type': door_kinds[door.name]} + if door.name not in door_kinds and door.dest.name in door_kinds: + # tricky swap thing + door_value = {'dest': door.name, 'type': door_kinds[door.dest.name]} + door = door.dest # this is weird + elif door.name in door_kinds: + door_value = {'dest': door.dest.name, 'one-way': True, 'type': door_kinds[door.name]} + else: + door_value = {'dest': door.dest.name, 'one-way': True} + door_map[door.name] = door_value + + def record_medallions(self): + pass + + def write_to_file(self, destination): + yaml.add_representer(defaultdict, Representer.represent_dict) + with open(destination, 'w') as file: + yaml.dump(self.world_rep, file) + + +def load_yaml(path): + try: + if urllib.parse.urlparse(path).scheme: + return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) + with open(path, 'r', encoding='utf-8') as f: + return yaml.load(f, Loader=yaml.SafeLoader) + except Exception as e: + raise Exception(f'Failed to read customizer file: {e}') + diff --git a/source/classes/constants.py b/source/classes/constants.py index 9199b47a..ca065229 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -122,6 +122,7 @@ SETTINGSTOPROCESS = { "createspoiler": "create_spoiler", "createrom": "create_rom", "calcplaythrough": "calc_playthrough", + "print_custom_yaml": "print_custom_yaml", "usestartinventory": "usestartinventory", "usecustompool": "custom", "saveonexit": "saveonexit" diff --git a/source/gui/randomize/generation.py b/source/gui/randomize/generation.py index ea09767f..c66eceb6 100644 --- a/source/gui/randomize/generation.py +++ b/source/gui/randomize/generation.py @@ -79,6 +79,48 @@ def generation_page(parent,settings): # frame: pack self.widgets[widget].pieces["frame"].pack(fill=X) + + self.frames["customizer"] = Frame(self) + self.frames["customizer"].pack(anchor=W, fill=X) + ## Customizer file + # This one's more-complicated, build it and stuff it + # widget ID + widget = "customizer" + + # Empty object + self.widgets[widget] = Empty() + # pieces + self.widgets[widget].pieces = {} + + # frame + self.widgets[widget].pieces["frame"] = Frame(self.frames["customizer"]) + # frame: label + self.widgets[widget].pieces["frame"].label = Label(self.widgets[widget].pieces["frame"], text='Customizer File: ') + # storage var + self.widgets[widget].storageVar = StringVar() + # textbox + self.widgets[widget].pieces["textbox"] = Entry(self.widgets[widget].pieces["frame"], + textvariable=self.widgets[widget].storageVar) + self.widgets[widget].storageVar.set(settings["customizer"]) + + # FIXME: Translate these + def FileSelect(): + file = filedialog.askopenfilename(filetypes=[("Yaml Files", (".yaml", ".yml")), ("All Files", "*")], + initialdir=os.path.join(".")) + self.widgets["customizer"].storageVar.set(file) + # dialog button + self.widgets[widget].pieces["button"] = Button(self.widgets[widget].pieces["frame"], + text='Select File', command=FileSelect) + + # frame label: pack + self.widgets[widget].pieces["frame"].label.pack(side=LEFT) + # textbox: pack + self.widgets[widget].pieces["textbox"].pack(side=LEFT, fill=X, expand=True) + # button: pack + self.widgets[widget].pieces["button"].pack(side=LEFT) + # frame: pack + self.widgets[widget].pieces["frame"].pack(fill=X) + ## Run Diagnostics # This one's more-complicated, build it and stuff it # widget ID diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py new file mode 100644 index 00000000..b46e05e0 --- /dev/null +++ b/source/overworld/EntranceShuffle2.py @@ -0,0 +1,3003 @@ +import RaceRandom as random +import logging +import copy + +from collections import defaultdict + + +class EntrancePool(object): + def __init__(self, world, player): + self.entrances = set() + self.exits = set() + self.inverted = False + self.coupled = True + self.default_map = {} + self.one_way_map = {} + self.skull_handled = False + self.links_on_mountain = False + self.decoupled_entrances = [] + self.decoupled_exits = [] + + self.world = world + self.player = player + + def is_standard(self): + return self.world.mode[self.player] == 'standard' + + +class Restrictions(object): + def __init__(self): + self.size = None + self.must_exit_to_lw = False + self.fixed = False + # must_exit_to_dw = False + # same_world = False + + +def link_entrances_new(world, player): + avail_pool = EntrancePool(world, player) + i_drop_map = {x: y for x, y in drop_map.items() if not x.startswith('Inverted')} + i_entrance_map = {x: y for x, y in entrance_map.items() if not x.startswith('Inverted')} + i_single_ent_map = {x: y for x, y in single_entrance_map.items() if not x.startswith('Inverted')} + + avail_pool.entrances = set(i_drop_map.keys()).union(i_entrance_map.keys()).union(i_single_ent_map.keys()) + avail_pool.exits = set(i_entrance_map.values()).union(i_drop_map.values()).union(i_single_ent_map.values()) + avail_pool.exits.add('Chris Houlihan Room Exit') + avail_pool.inverted = world.mode[player] == 'inverted' + if avail_pool.inverted: + avail_pool.exits.add('Inverted Dark Sanctuary Exit') + inverted_substitution(avail_pool, avail_pool.entrances, True, True) + inverted_substitution(avail_pool, avail_pool.exits, False, True) + default_map = {} + default_map.update(entrance_map) + one_way_map = {} + one_way_map.update(drop_map) + one_way_map.update(single_entrance_map) + if avail_pool.inverted: + default_map['Old Man Cave (West)'] = 'Bumper Cave Exit (Bottom)' + default_map['Death Mountain Return Cave (West)'] = 'Bumper Cave Exit (Top)' + default_map['Bumper Cave (Bottom)'] = 'Old Man Cave Exit (West)' + default_map['Dark Death Mountain Fairy'] = 'Old Man Cave Exit (East)' + del one_way_map['Dark Death Mountain Fairy'] + default_map['Old Man Cave (East)'] = 'Death Mountain Return Cave Exit (West)' + one_way_map['Bumper Cave (Top)'] = 'Dark Death Mountain Healer Fairy' + del default_map['Bumper Cave (Top)'] + avail_pool.default_map = default_map + avail_pool.one_way_map = one_way_map + + # setup mandatory connections + if not avail_pool.inverted: + for exit_name, region_name in mandatory_connections: + connect_simple(world, exit_name, region_name, player) + else: + for exit_name, region_name in inverted_mandatory_connections: + connect_simple(world, exit_name, region_name, player) + + # not randomized at this time + connect_simple(world, 'Tavern North', 'Tavern', player) + + connect_custom(avail_pool, world, player) + + if world.shuffle[player] == 'vanilla': + do_vanilla_connections(avail_pool) + else: + mode = world.shuffle[player] + if mode not in modes: + raise RuntimeError(f'Shuffle mode {mode} is not yet supported') + mode_cfg = copy.deepcopy(modes[mode]) + if avail_pool.is_standard(): + do_standard_connections(avail_pool) + pool_list = mode_cfg['pools'] if 'pools' in mode_cfg else {} + for pool_name, pool in pool_list.items(): + special_shuffle = pool['special'] if 'special' in pool else None + if special_shuffle == 'drops': + holes, targets = find_entrances_and_targets_drops(avail_pool, pool['entrances']) + connect_random(holes, targets, avail_pool) + elif special_shuffle == 'fixed_shuffle': + do_fixed_shuffle(avail_pool, pool['entrances']) + elif special_shuffle == 'same_world': + do_same_world_shuffle(avail_pool, pool) + elif special_shuffle == 'simple_connector': + do_connector_shuffle(avail_pool, pool) + elif special_shuffle == 'old_man_cave_east': + exits = [x for x in pool['entrances'] if x in avail_pool.exits] + cross_world = mode_cfg['cross_world'] == 'on' if 'cross_world' in mode_cfg else False + do_old_man_cave_exit(set(avail_pool.entrances), exits, avail_pool, cross_world) + elif special_shuffle == 'inverted_fixed': + if avail_pool.inverted: + connect_two_way(pool['entrance'], pool['exit'], avail_pool) + elif special_shuffle == 'limited': + do_limited_shuffle(pool, avail_pool) + elif special_shuffle == 'limited_lw': + do_limited_shuffle_exclude_drops(pool, avail_pool) + elif special_shuffle == 'limited_dw': + do_limited_shuffle_exclude_drops(pool, avail_pool, False) + elif special_shuffle == 'vanilla': + do_vanilla_connect(pool, avail_pool) + elif special_shuffle == 'skull': + entrances, exits = find_entrances_and_exits(avail_pool, pool['entrances']) + connect_random(entrances, exits, avail_pool, True) + avail_pool.skull_handled = True + else: + entrances, exits = find_entrances_and_exits(avail_pool, pool['entrances']) + do_main_shuffle(entrances, exits, avail_pool, mode_cfg) + undefined_behavior = mode_cfg['undefined'] + if undefined_behavior == 'vanilla': + do_vanilla_connections(avail_pool) + elif undefined_behavior == 'shuffle': + do_main_shuffle(set(avail_pool.entrances), set(avail_pool.exits), avail_pool, mode_cfg) + + # afterward + + # check for swamp palace fix + if (world.get_entrance('Dam', player).connected_region.name != 'Dam' + or world.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Portal'): + world.swamp_patch_required[player] = True + + # check for potion shop location + if world.get_entrance('Potion Shop', player).connected_region.name != 'Potion Shop': + world.powder_patch_required[player] = True + + # check for ganon location + pyramid_hole = 'Inverted Pyramid Hole' if avail_pool.inverted else 'Pyramid Hole' + if world.get_entrance(pyramid_hole, player).connected_region.name != 'Pyramid': + world.ganon_at_pyramid[player] = False + + # check for Ganon's Tower location + gt = 'Inverted Ganons Tower' if avail_pool.inverted else 'Ganons Tower' + if world.get_entrance(gt, player).connected_region.name != 'Ganons Tower Portal': + world.ganonstower_vanilla[player] = False + + +def do_vanilla_connections(avail_pool): + if 'Chris Houlihan Room Exit' in avail_pool.exits: + lh = 'Inverted Links House' if avail_pool.inverted else 'Links House' + connect_exit('Chris Houlihan Room Exit', lh, avail_pool) + for ent in list(avail_pool.entrances): + if ent in avail_pool.default_map and avail_pool.default_map[ent] in avail_pool.exits: + connect_vanilla_two_way(ent, avail_pool.default_map[ent], avail_pool) + if ent in avail_pool.one_way_map and avail_pool.one_way_map[ent] in avail_pool.exits: + connect_vanilla(ent, avail_pool.one_way_map[ent], avail_pool) + + +def do_main_shuffle(entrances, exits, avail, mode_def): + # drops and holes + cross_world = mode_def['cross_world'] == 'on' if 'cross_world' in mode_def else False + keep_together = mode_def['keep_drops_together'] == 'on' if 'keep_drops_together' in mode_def else True + avail.coupled = mode_def['decoupled'] != 'on' if 'decoupled' in mode_def else True + do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_together) + + if not avail.coupled: + avail.decoupled_entrances.extend(entrances) + avail.decoupled_exits.extend(exits) + + if not avail.world.shuffle_ganon: + if avail.inverted and 'Inverted Ganons Tower' in entrances: + connect_two_way('Inverted Ganons Tower', 'Inverted Ganons Tower Exit', avail) + entrances.remove('Inverted Ganons Tower') + exits.remove('Inverted Ganons Tower Exit') + if not avail.coupled: + avail.decoupled_entrances.remove('Inverted Ganons Tower') + avail.decoupled_exits.remove('Inverted Ganons Tower Exit') + elif 'Ganons Tower' in entrances: + connect_two_way('Ganons Tower', 'Ganons Tower Exit', avail) + entrances.remove('Ganons Tower') + exits.remove('Ganons Tower Exit') + if not avail.coupled: + avail.decoupled_entrances.remove('Ganons Tower') + avail.decoupled_exits.remove('Ganons Tower Exit') + + # links house / houlihan + do_links_house(entrances, exits, avail, cross_world) + + # inverted sanc + if avail.inverted and 'Inverted Dark Sanctuary Exit' in exits: + choices = [e for e in Inverted_Dark_Sanctuary_Doors if e in entrances] + choice = random.choice(choices) + entrances.remove(choice) + exits.remove('Inverted Dark Sanctuary Exit') + connect_entrance(choice, 'Inverted Dark Sanctuary', avail) + ext = avail.world.get_entrance('Inverted Dark Sanctuary Exit', avail.player) + ext.connect(avail.world.get_entrance(choice, avail.player).parent_region) + if not avail.coupled: + avail.decoupled_entrances.remove(choice) + + # mandatory exits + rem_entrances, rem_exits = set(), set() + if not cross_world: + mand_exits = figure_out_must_exits_same_world(entrances, exits, avail) + must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves, hyrule_forced = mand_exits + if hyrule_forced: + do_mandatory_connections(avail, lw_entrances, hyrule_forced, must_exit_lw) + else: + do_mandatory_connections(avail, lw_entrances, multi_exit_caves, must_exit_lw) + # remove old man house as connector - not valid for dw must_exit if it is a spawn point + if not avail.inverted: + new_mec = [] + for cave_option in multi_exit_caves: + if any('Old Man House' in cave for cave in cave_option): + rem_exits.update([item for item in cave_option]) + else: + new_mec.append(cave_option) + multi_exit_caves = new_mec + do_mandatory_connections(avail, dw_entrances, multi_exit_caves, must_exit_dw) + rem_entrances.update(lw_entrances) + rem_entrances.update(dw_entrances) + else: + # cross world mandantory + entrance_list = list(entrances) + must_exit, multi_exit_caves = figure_out_must_exits_cross_world(entrances, exits, avail) + do_mandatory_connections(avail, entrance_list, multi_exit_caves, must_exit) + rem_entrances.update(entrance_list) + + rem_exits.update([x for item in multi_exit_caves for x in item]) + rem_exits.update(exits) + + # old man cave + do_old_man_cave_exit(rem_entrances, rem_exits, avail, cross_world) + + # blacksmith + if 'Blacksmiths Hut' in rem_exits: + blacksmith_options = [x for x in Blacksmith_Options if x in rem_entrances] + blacksmith_choice = random.choice(blacksmith_options) + connect_entrance(blacksmith_choice, 'Blacksmiths Hut', avail) + rem_entrances.remove(blacksmith_choice) + if not avail.coupled: + avail.decoupled_exits.remove('Blacksmiths Hut') + rem_exits.remove('Blacksmiths Hut') + + # bomb shop + bomb_shop = 'Inverted Big Bomb Shop' if avail.inverted else 'Big Bomb Shop' + if bomb_shop in rem_exits: + bomb_shop_options = Inverted_Bomb_Shop_Options if avail.inverted else Bomb_Shop_Options + bomb_shop_options = [x for x in bomb_shop_options if x in rem_entrances] + bomb_shop_choice = random.choice(bomb_shop_options) + connect_entrance(bomb_shop_choice, bomb_shop, avail) + rem_entrances.remove(bomb_shop_choice) + if not avail.coupled: + avail.decoupled_exits.remove(bomb_shop) + rem_exits.remove(bomb_shop) + + def bonk_fairy_exception(x): # (Bonk Fairy not eligible in standard) + return not avail.is_standard() or x != 'Bonk Fairy (Light)' + if not cross_world: + # OM Cave entrance in lw/dw if cross_world off + if 'Old Man Cave Exit (West)' in rem_exits: + world_limiter = DW_Entrances if avail.inverted else LW_Entrances + om_cave_options = [x for x in rem_entrances if x in world_limiter and bonk_fairy_exception(x)] + om_cave_choice = random.choice(om_cave_options) + if not avail.coupled: + connect_exit('Old Man Cave Exit (West)', om_cave_choice, avail) + avail.decoupled_entrances.remove(om_cave_choice) + else: + connect_two_way(om_cave_choice, 'Old Man Cave Exit (West)', avail) + rem_entrances.remove(om_cave_choice) + rem_exits.remove('Old Man Cave Exit (West)') + # OM House in lw/dw if cross_world off + om_house = ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)'] + if not avail.inverted: # we don't really care where this ends up in inverted? + for ext in om_house: + if ext in rem_exits: + om_house_options = [x for x in rem_entrances if x in LW_Entrances and bonk_fairy_exception(x)] + om_house_choice = random.choice(om_house_options) + if not avail.coupled: + connect_exit(ext, om_house_choice, avail) + avail.decoupled_entrances.remove(om_house_choice) + else: + connect_two_way(om_house_choice, ext, avail) + rem_entrances.remove(om_house_choice) + rem_exits.remove(ext) + + # the rest of the caves + multi_exit_caves = figure_out_true_exits(rem_exits, avail) + unused_entrances = set() + if not cross_world: + lw_entrances, dw_entrances = [], [] + for x in rem_entrances: + if bonk_fairy_exception(x): + lw_entrances.append(x) if x in LW_Entrances else dw_entrances.append(x) + do_same_world_connectors(lw_entrances, dw_entrances, multi_exit_caves, avail) + unused_entrances.update(lw_entrances) + unused_entrances.update(dw_entrances) + else: + entrance_list = [x for x in rem_entrances if bonk_fairy_exception(x)] + do_cross_world_connectors(entrance_list, multi_exit_caves, avail) + unused_entrances.update(entrance_list) + + if avail.is_standard() and 'Bonk Fairy (Light)' in rem_entrances: + rem_entrances = list(unused_entrances) + ['Bonk Fairy (Light)'] + else: + rem_entrances = list(unused_entrances) + rem_entrances.sort() + rem_exits = list(rem_exits if avail.coupled else avail.decoupled_exits) + rem_exits.sort() + random.shuffle(rem_entrances) + random.shuffle(rem_exits) + placing = min(len(rem_entrances), len(rem_exits)) + for door, target in zip(rem_entrances, rem_exits): + connect_entrance(door, target, avail) + rem_entrances[:] = rem_entrances[placing:] + rem_exits[:] = rem_exits[placing:] + if rem_entrances or rem_exits: + logging.getLogger('').warning(f'Unplaced entrances/exits: {", ".join(rem_entrances + rem_exits)}') + + +def do_old_man_cave_exit(entrances, exits, avail, cross_world): + if 'Old Man Cave Exit (East)' in exits: + om_cave_options = Inverted_Old_Man_Entrances if avail.inverted else Old_Man_Entrances + if avail.inverted and cross_world: + om_cave_options = Inverted_Old_Man_Entrances + Old_Man_Entrances + om_cave_options = [x for x in om_cave_options if x in entrances] + om_cave_choice = random.choice(om_cave_options) + if not avail.coupled: + connect_exit('Old Man Cave Exit (East)', om_cave_choice, avail) + avail.decoupled_entrances.remove(om_cave_choice) + else: + connect_two_way(om_cave_choice, 'Old Man Cave Exit (East)', avail) + entrances.remove(om_cave_choice) + exits.remove('Old Man Cave Exit (East)') + + +def do_standard_connections(avail): + connect_two_way('Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', avail) + # cannot move uncle cave + connect_two_way('Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', avail) + connect_entrance('Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', avail) + connect_two_way('Links House', 'Links House Exit', avail) + connect_exit('Chris Houlihan Room Exit', 'Links House', avail) + + +def remove_from_list(t_list, removals): + for r in removals: + t_list.remove(r) + + +def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_together): + holes_to_shuffle = [x for x in entrances if x in drop_map] + + if not avail.world.shuffle_ganon: + if avail.inverted and 'Inverted Pyramid Hole' in holes_to_shuffle: + connect_entrance('Inverted Pyramid Hole', 'Pyramid', avail) + connect_two_way('Pyramid Entrance', 'Pyramid Exit', avail) + holes_to_shuffle.remove('Inverted Pyramid Hole') + remove_from_list(entrances, ['Inverted Pyramid Hole', 'Pyramid Entrance']) + remove_from_list(exits, ['Pyramid', 'Pyramid Exit']) + elif 'Pyramid Hole' in holes_to_shuffle: + connect_entrance('Pyramid Hole', 'Pyramid', avail) + connect_two_way('Pyramid Entrance', 'Pyramid Exit', avail) + holes_to_shuffle.remove('Pyramid Hole') + remove_from_list(entrances, ['Pyramid Hole', 'Pyramid Entrance']) + remove_from_list(exits, ['Pyramid', 'Pyramid Exit']) + + if not keep_together: + targets = [avail.one_way_map[x] for x in holes_to_shuffle] + connect_random(holes_to_shuffle, targets, avail) + remove_from_list(entrances, holes_to_shuffle) + remove_from_list(exits, targets) + return # we're done here + + hole_entrances, hole_targets = [], [] + for hole in drop_map: + if hole in entrances and hole in linked_drop_map: + linked_entrance = linked_drop_map[hole] + if hole in entrances and linked_entrance in entrances: + hole_entrances.append((linked_entrance, hole)) + target_exit = avail.default_map[linked_entrance] + target_drop = avail.one_way_map[hole] + if target_exit in exits and target_drop in exits: + hole_targets.append((target_exit, target_drop)) + + random.shuffle(hole_entrances) + if not cross_world and 'Sanctuary Grave' in holes_to_shuffle: + lw_entrance = next(entrance for entrance in hole_entrances if entrance[0] in LW_Entrances) + hole_entrances.remove(lw_entrance) + sanc_interior = next(target for target in hole_targets if target[0] == 'Sanctuary Exit') + hole_targets.remove(sanc_interior) + connect_two_way(lw_entrance[0], sanc_interior[0], avail) # two-way exit + connect_entrance(lw_entrance[1], sanc_interior[1], avail) # hole + remove_from_list(entrances, [lw_entrance[0], lw_entrance[1]]) + remove_from_list(exits, [sanc_interior[0], sanc_interior[1]]) + + random.shuffle(hole_targets) + for entrance, drop in hole_entrances: + ext, target = hole_targets.pop() + connect_two_way(entrance, ext, avail) + connect_entrance(drop, target, avail) + remove_from_list(entrances, [entrance, drop]) + remove_from_list(exits, [ext, target]) + + +def do_links_house(entrances, exits, avail, cross_world): + lh_exit = 'Inverted Links House Exit' if avail.inverted else 'Links House Exit' + if lh_exit in exits: + if not avail.world.shufflelinks[avail.player]: + links_house = 'Inverted Links House' if avail.inverted else 'Links House' + else: + forbidden = list(Isolated_LH_Doors_Inv + Inverted_Dark_Sanctuary_Doors + if avail.inverted else Isolated_LH_Doors_Open) + # simple shuffle - + if avail.world.shuffle[avail.player] == 'simple': + avail.links_on_mountain = True # taken care of by the logic below + if avail.inverted: # in inverted, links house cannot be on the mountain + forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy', 'Hookshot Fairy']) + else: + # links house cannot be on dm if there's no way off the mountain + ent = avail.world.get_entrance('Death Mountain Return Cave (West)', avail.player) + if ent.connected_region.name in Simple_DM_Non_Connectors: + forbidden.append('Hookshot Fairy') + # other cases it is fine + # can't have links house on eddm in restricted because Inverted Aga Tower isn't available + # todo: inverted full may have the same problem if both links house and a mandatory connector is chosen + # from the 3 inverted options + if avail.world.shuffle[avail.player] in ['restricted'] and avail.inverted: + avail.links_on_mountain = True + forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy']) + + # lobby shuffle means you ought to keep links house in the same world + sanc_spawn_can_be_dark = (not avail.inverted and avail.world.doorShuffle[avail.player] == 'crossed' + and avail.world.intensity[avail.player] >= 3) + entrance_pool = entrances if avail.coupled else avail.decoupled_entrances + if cross_world and not sanc_spawn_can_be_dark: + possible = [e for e in entrance_pool if e not in forbidden] + else: + world_list = LW_Entrances if not avail.inverted else DW_Entrances + possible = [e for e in entrance_pool if e in world_list and e not in forbidden] + possible.sort() + links_house = random.choice(possible) + connect_two_way(links_house, lh_exit, avail) + entrances.remove(links_house) + connect_exit('Chris Houlihan Room Exit', links_house, avail) # should match link's house + exits.remove(lh_exit) + exits.remove('Chris Houlihan Room Exit') + if not avail.coupled: + avail.decoupled_entrances.remove(links_house) + avail.decoupled_exits.remove('Links House Exit') + avail.decoupled_exits.remove('Chris Houlihan Room Exit') + # links on dm + dm_spots = LH_DM_Connector_List.union(LH_DM_Exit_Forbidden) + if links_house in dm_spots: + if avail.links_on_mountain: + return # connector is fine + multi_exit_caves = figure_out_connectors(exits) + entrance_pool = entrances if avail.coupled else avail.decoupled_entrances + if cross_world: + possible_dm_exits = [e for e in entrances if e in LH_DM_Connector_List] + possible_exits = [e for e in entrance_pool if e not in dm_spots] + else: + world_list = LW_Entrances if not avail.inverted else DW_Entrances + possible_dm_exits = [e for e in entrances if e in LH_DM_Connector_List and e in world_list] + possible_exits = [e for e in entrance_pool if e not in dm_spots and e in world_list] + chosen_cave = random.choice(multi_exit_caves) + shuffle_connector_exits(chosen_cave) + possible_dm_exits.sort() + possible_exits.sort() + chosen_dm_escape = random.choice(possible_dm_exits) + chosen_landing = random.choice(possible_exits) + if avail.coupled: + connect_two_way(chosen_dm_escape, chosen_cave.pop(0), avail) + connect_two_way(chosen_landing, chosen_cave.pop(), avail) + entrances.remove(chosen_dm_escape) + entrances.remove(chosen_landing) + else: + connect_entrance(chosen_dm_escape, chosen_cave.pop(0), avail) + connect_exit(chosen_cave.pop(), chosen_landing, avail) + entrances.remove(chosen_dm_escape) + avail.decoupled_entrances.remove(chosen_landing) + if len(chosen_cave): + exits.update([x for x in chosen_cave]) + exits.update([x for item in multi_exit_caves for x in item]) + + +def figure_out_connectors(exits): + multi_exit_caves = [] + for item in Connector_List: + if all(x in exits for x in item): + remove_from_list(exits, item) + multi_exit_caves.append(list(item)) + return multi_exit_caves + + +def figure_out_true_exits(exits, avail): + multi_exit_caves = [] + for item in Connector_List: + if all(x in exits for x in item): + remove_from_list(exits, item) + multi_exit_caves.append(list(item)) + for item in avail.default_map.values(): + if item in exits: + multi_exit_caves.append(item) + exits.remove(item) + return multi_exit_caves + + +# todo: figure out hyrule forced better +def figure_out_must_exits_same_world(entrances, exits, avail): + lw_entrances, dw_entrances = [], [] + hyrule_forced = None + check_for_hc = (avail.is_standard() or avail.world.doorShuffle[avail.player] != 'vanilla') + + for x in entrances: + lw_entrances.append(x) if x in LW_Entrances else dw_entrances.append(x) + multi_exit_caves = figure_out_connectors(exits) + if check_for_hc: + for option in multi_exit_caves: + if any(x in option for x in ['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (East)', + 'Hyrule Castle Exit (West)']): + hyrule_forced = [option] + if hyrule_forced: + remove_from_list(multi_exit_caves, hyrule_forced) + + must_exit_lw, must_exit_dw = must_exits_helper(avail, lw_entrances, dw_entrances) + + return must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves, hyrule_forced + + +def must_exits_helper(avail, lw_entrances, dw_entrances): + must_exit_lw = Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit + must_exit_dw = Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit + if not avail.inverted and not avail.skull_handled: + must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) + must_exit_lw = must_exit_filter(avail, must_exit_lw, lw_entrances) + must_exit_dw = must_exit_filter(avail, must_exit_dw, dw_entrances) + return must_exit_lw, must_exit_dw + + +def figure_out_must_exits_cross_world(entrances, exits, avail): + multi_exit_caves = figure_out_connectors(exits) + + must_exit_lw = Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit + must_exit_dw = Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit + if not avail.inverted and not avail.skull_handled: + must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) + must_exit = must_exit_filter(avail, must_exit_lw + must_exit_dw, entrances) + + return must_exit, multi_exit_caves + + +def do_same_world_connectors(lw_entrances, dw_entrances, caves, avail): + random.shuffle(lw_entrances) + random.shuffle(dw_entrances) + random.shuffle(caves) + while caves: + # connect highest exit count caves first, prevent issue where we have 2 or 3 exits across worlds left to fill + cave_candidate = (None, 0) + for i, cave in enumerate(caves): + if isinstance(cave, str): + cave = (cave,) + if len(cave) > cave_candidate[1]: + cave_candidate = (i, len(cave)) + cave = caves.pop(cave_candidate[0]) + + target = lw_entrances if random.randint(0, 1) == 0 else dw_entrances + if isinstance(cave, str): + cave = (cave,) + + # check if we can still fit the cave into our target group + if len(target) < len(cave): + # need to use other set + target = lw_entrances if target is dw_entrances else dw_entrances + + for ext in cave: + # todo: for decoupled, need to split the avail decoupled entrances into lw/dw + # if decoupled: + # choice = random.choice(avail.decoupled_entrances) + # connect_exit(ext, choice, avail) + # avail.decoupled_entrances.remove() + # else: + connect_two_way(target.pop(), ext, avail) + + +def do_cross_world_connectors(entrances, caves, avail): + random.shuffle(entrances) + random.shuffle(caves) + while caves: + cave_candidate = (None, 0) + for i, cave in enumerate(caves): + if isinstance(cave, str): + cave = (cave,) + if len(cave) > cave_candidate[1]: + cave_candidate = (i, len(cave)) + cave = caves.pop(cave_candidate[0]) + + if isinstance(cave, str): + cave = (cave,) + + for ext in cave: + if not avail.coupled: + choice = random.choice(avail.decoupled_entrances) + connect_exit(ext, choice, avail) + avail.decoupled_entrances.remove(choice) + else: + connect_two_way(entrances.pop(), ext, avail) + + +def do_fixed_shuffle(avail, entrance_list): + max_size = 0 + options = {} + for i, entrance_set in enumerate(entrance_list): + entrances, targets = find_entrances_and_exits(avail, entrance_set) + size = min(len(entrances), len(targets)) + max_size = max(max_size, size) + rules = Restrictions() + rules.size = size + if ('Hyrule Castle Entrance (South)' in entrances and + avail.world.doorShuffle[avail.player] in ['basic', 'crossed']): + rules.must_exit_to_lw = True + if 'Inverted Ganons Tower' in entrances and not avail.world.shuffle_ganon: + rules.fixed = True + option = (i, entrances, targets, rules) + options[i] = option + choices = dict(options) + for i, option in options.items(): + key, entrances, targets, rules = option + if rules.size and rules.size < max_size: + choice = choices[i] + elif rules.fixed: + choice = choices[i] + elif rules.must_exit_to_lw: + filtered_choices = {i: opt for i, opt in choices.items() if all(t in default_lw for t in opt[2])} + index, choice = random.choice(list(filtered_choices.items())) + else: + index, choice = random.choice(list(choices.items())) + del choices[choice[0]] + for t, entrance in enumerate(entrances): + target = choice[2][t] + connect_two_way(entrance, target, avail) + + +def do_same_world_shuffle(avail, pool_def): + single_exit = pool_def['entrances'] + multi_exit = pool_def['connectors'] + # complete_entrance_set = set() + lw_entrances, dw_entrances, multi_exits_caves, other_exits = [], [], [], [] + hyrule_forced = None + check_for_hc = avail.is_standard() or avail.world.doorShuffle[avail.player] != 'vanilla' + + single_entrances, single_exits = find_entrances_and_exits(avail, single_exit) + other_exits.extend(single_exits) + for x in single_entrances: + (dw_entrances, lw_entrances)[x in LW_Entrances].append(x) + # complete_entrance_set.update(single_entrances) + for option in multi_exit: + multi_entrances, multi_exits = find_entrances_and_exits(avail, option) + # complete_entrance_set.update(multi_entrances) + if check_for_hc and any(x in multi_entrances for x in ['Hyrule Castle Entrance (South)', + 'Hyrule Castle Entrance (East)', + 'Hyrule Castle Entrance (West)']): + hyrule_forced = [multi_exits] + else: + multi_exits_caves.append(multi_exits) + for x in multi_entrances: + (dw_entrances, lw_entrances)[x in LW_Entrances].append(x) + + must_exit_lw = Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit + must_exit_dw = Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit + must_exit_lw = must_exit_filter(avail, must_exit_lw, lw_entrances) + must_exit_dw = must_exit_filter(avail, must_exit_dw, dw_entrances) + + if hyrule_forced: + do_mandatory_connections(avail, lw_entrances, hyrule_forced, must_exit_lw) + else: + do_mandatory_connections(avail, lw_entrances, multi_exits_caves, must_exit_lw) + do_mandatory_connections(avail, dw_entrances, multi_exits_caves, must_exit_dw) + + # connect caves + random.shuffle(lw_entrances) + random.shuffle(dw_entrances) + random.shuffle(multi_exits_caves) + while multi_exits_caves: + cave_candidate = (None, 0) + for i, cave in enumerate(multi_exits_caves): + if len(cave) > cave_candidate[1]: + cave_candidate = (i, len(cave)) + cave = multi_exits_caves.pop(cave_candidate[0]) + + target = lw_entrances if random.randint(0, 1) == 0 else dw_entrances + if len(target) < len(cave): # swap because we ran out of entrances in that world + target = lw_entrances if target is dw_entrances else dw_entrances + + for ext in cave: + connect_two_way(target.pop(), ext, avail) + # finish the rest + connect_random(lw_entrances+dw_entrances, single_exits, avail, True) + + +def do_connector_shuffle(avail, pool_def): + directional_list = pool_def['directional_inv' if avail.inverted else 'directional'] + connector_list = pool_def['connectors_inv' if avail.inverted else 'connectors'] + option_list = pool_def['options'] + + for connector in directional_list: + chosen_option = random.choice(option_list) + ignored_ent, chosen_exits = find_entrances_and_exits(avail, chosen_option) + if not chosen_exits: + continue # nothing available + # this shuffle ensures directionality + shuffle_connector_exits(chosen_exits) + connector_ent, ignored_exits = find_entrances_and_exits(avail, connector) + for i, ent in enumerate(connector_ent): + connect_two_way(ent, chosen_exits[i], avail) + option_list.remove(chosen_option) + + for connector in connector_list: + chosen_option = random.choice(option_list) + ignored_ent, chosen_exits = find_entrances_and_exits(avail, chosen_option) + # directionality need not be preserved + random.shuffle(chosen_exits) + connector_ent, ignored_exits = find_entrances_and_exits(avail, connector) + for i, ent in enumerate(connector_ent): + connect_two_way(ent, chosen_exits[i], avail) + option_list.remove(chosen_option) + + +def do_limited_shuffle(pool_def, avail): + entrance_pool, ignored_exits = find_entrances_and_exits(avail, pool_def['entrances']) + exit_pool = [x for x in pool_def['options'] if x in avail.exits] + random.shuffle(exit_pool) + for entrance in entrance_pool: + chosen_exit = exit_pool.pop() + connect_two_way(entrance, chosen_exit, avail) + + +def do_limited_shuffle_exclude_drops(pool_def, avail, lw=True): + ignored_entrances, exits = find_entrances_and_exits(avail, pool_def['entrances']) + reserved_drops = set(linked_drop_map.values()) + must_exit_lw, must_exit_dw = must_exits_helper(avail, LW_Entrances, DW_Entrances) + must_exit = set(must_exit_lw if lw else must_exit_dw) + base_set = LW_Entrances if lw else DW_Entrances + entrance_pool = [x for x in base_set if x in avail.entrances and x not in reserved_drops] + random.shuffle(entrance_pool) + for next_exit in exits: + if next_exit not in Connector_Exit_Set: + reduced_pool = [x for x in entrance_pool if x not in must_exit] + chosen_entrance = reduced_pool.pop() + entrance_pool.remove(chosen_entrance) + else: + chosen_entrance = entrance_pool.pop() + connect_two_way(chosen_entrance, next_exit, avail) + + +def do_vanilla_connect(pool_def, avail): + if pool_def['condition'] == 'shopsanity': + if avail.world.shopsanity[avail.player]: + return + defaults = inverted_default_connections if avail.inverted else default_connections + for entrance in pool_def['entrances']: + if entrance in avail.entrances: + target = defaults[entrance] + connect_simple(avail.world, entrance, target, avail.player) + avail.entrances.remove(entrance) + avail.exits.remove(target) + + +def do_mandatory_connections(avail, entrances, cave_options, must_exit): + if len(must_exit) == 0: + return + if not avail.coupled: + do_mandatory_connections_decoupled(avail, cave_options, must_exit) + return + + # Keeps track of entrances that cannot be used to access each exit / cave + if avail.inverted: + invalid_connections = Inverted_Must_Exit_Invalid_Connections.copy() + else: + invalid_connections = Must_Exit_Invalid_Connections.copy() + invalid_cave_connections = defaultdict(set) + + if avail.world.logic[avail.player] in ['owglitches', 'nologic']: + import OverworldGlitchRules + for entrance in OverworldGlitchRules.get_non_mandatory_exits(avail.inverted): + invalid_connections[entrance] = set() + if entrance in must_exit: + must_exit.remove(entrance) + entrances.append(entrance) + entrances.sort() # sort these for consistency + random.shuffle(entrances) + random.shuffle(cave_options) + + if avail.inverted: + at = avail.world.get_region('Agahnims Tower Portal', avail.player) + for entrance in invalid_connections: + if avail.world.get_entrance(entrance, avail.player).connected_region == at: + for ext in invalid_connections[entrance]: + invalid_connections[ext] = invalid_connections[ext].union({'Inverted Ganons Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}) + break + + used_caves = [] + required_entrances = 0 # Number of entrances reserved for used_caves + while must_exit: + exit = must_exit.pop() + # find multi exit cave + candidates = [] + for candidate in cave_options: + if not isinstance(candidate, str) and (candidate in used_caves + or len(candidate) < len(entrances) - required_entrances): + candidates.append(candidate) + cave = random.choice(candidates) + if cave is None: + raise RuntimeError('No more caves left. Should not happen!') + + # all caves are sorted so that the last exit is always reachable + rnd_cave = list(cave) + shuffle_connector_exits(rnd_cave) # should be the same as unbiasing some entrances... + entrances.remove(exit) + connect_two_way(exit, rnd_cave[-1], avail) + if len(cave) == 2: + entrance = next(e for e in entrances[::-1] if e not in invalid_connections[exit] + and e not in invalid_cave_connections[tuple(cave)] and e not in must_exit) + entrances.remove(entrance) + connect_two_way(entrance, rnd_cave[0], avail) + if cave in used_caves: + required_entrances -= 2 + used_caves.remove(cave) + if entrance in invalid_connections: + for exit2 in invalid_connections[entrance]: + invalid_connections[exit2] = invalid_connections[exit2].union(invalid_connections[exit]).union(invalid_cave_connections[tuple(cave)]) + elif cave[-1] == 'Spectacle Rock Cave Exit': # Spectacle rock only has one exit + cave_entrances = [] + for cave_exit in rnd_cave[:-1]: + entrance = next(e for e in entrances[::-1] if e not in invalid_connections[exit] and e not in must_exit) + cave_entrances.append(entrance) + entrances.remove(entrance) + connect_two_way(entrance, cave_exit, avail) + if entrance not in invalid_connections: + invalid_connections[exit] = set() + if all(entrance in invalid_connections for entrance in cave_entrances): + new_invalid_connections = invalid_connections[cave_entrances[0]].intersection(invalid_connections[cave_entrances[1]]) + for exit2 in new_invalid_connections: + invalid_connections[exit2] = invalid_connections[exit2].union(invalid_connections[exit]) + else: # save for later so we can connect to multiple exits + if cave in used_caves: + required_entrances -= 1 + used_caves.remove(cave) + else: + required_entrances += len(cave)-1 + cave_options.append(rnd_cave[0:-1]) + random.shuffle(cave_options) + used_caves.append(rnd_cave[0:-1]) + invalid_cave_connections[tuple(rnd_cave[0:-1])] = invalid_cave_connections[tuple(cave)].union(invalid_connections[exit]) + cave_options.remove(cave) + for cave in used_caves: + if cave in cave_options: # check if we placed multiple entrances from this 3 or 4 exit + for cave_exit in cave: + entrance = next(e for e in entrances[::-1] if e not in invalid_cave_connections[tuple(cave)]) + invalid_cave_connections[tuple(cave)] = set() + entrances.remove(entrance) + connect_two_way(entrance, cave_exit, avail) + cave_options.remove(cave) + + +def do_mandatory_connections_decoupled(avail, cave_options, must_exit): + for next_entrance in must_exit: + random.shuffle(cave_options) + candidate = None + for cave in cave_options: + if len(cave) < 2 or (len(cave) == 2 and ('Spectacle Rock Cave Exit (Peak)' in cave + or 'Turtle Rock Ledge Exit (East)' in cave)): + continue + candidate = cave + break + if candidate is None: + raise RuntimeError('No suitable cave.') + cave_options.remove(candidate) + + # all caves are sorted so that the last exit is always reachable + shuffle_connector_exits(candidate) # should be the same as un-biasing some entrances... + chosen_exit = candidate[-1] + cave = candidate[:-1] + connect_exit(chosen_exit, next_entrance, avail) + cave_options.append(cave) + avail.decoupled_entrances.remove(next_entrance) + + +def must_exit_filter(avail, candidates, shuffle_pool): + filtered_list = [] + for cand in candidates: + if isinstance(cand, tuple): + candidates = [x for x in cand if x in avail.entrances and x in shuffle_pool] + if len(candidates) > 1: + filtered_list.append(random.choice(candidates)) + elif len(candidates) == 1: + filtered_list.append(candidates[0]) + elif cand in avail.entrances and cand in shuffle_pool: + filtered_list.append(cand) + return filtered_list + + +def shuffle_connector_exits(connector_choices): + random.shuffle(connector_choices) + # the order matter however, because we assume the last choice is exit-able from the other ways to get in + # the first one is the one where you can assume you access the entire cave from + if 'Paradox Cave Exit (Bottom)' == connector_choices[0]: # Paradox bottom is exit only + i = random.randint(1, len(connector_choices) - 1) + connector_choices[0], connector_choices[i] = connector_choices[i], connector_choices[0] + # east ledge can't fulfill a must_exit condition + if 'Turtle Rock Ledge Exit (East)' in connector_choices and 'Turtle Rock Ledge Exit (East)' != connector_choices[0]: + i = connector_choices.index('Turtle Rock Ledge Exit (East)') + connector_choices[0], connector_choices[i] = connector_choices[i], connector_choices[0] + # these only have one exit (one-way nature) + if 'Spectacle Rock Cave Exit' in connector_choices and connector_choices[-1] != 'Spectacle Rock Cave Exit': + i = connector_choices.index('Spectacle Rock Cave Exit') + connector_choices[-1], connector_choices[i] = connector_choices[i], connector_choices[-1] + if 'Superbunny Cave Exit (Top)' in connector_choices and connector_choices[-1] != 'Superbunny Cave Exit (Top)': + connector_choices[-1], connector_choices[0] = connector_choices[0], connector_choices[-1] + if 'Spiral Cave Exit' in connector_choices and connector_choices[-1] != 'Spiral Cave Exit': + connector_choices[-1], connector_choices[0] = connector_choices[0], connector_choices[-1] + + +def find_entrances_and_targets_drops(avail_pool, drop_pool): + holes, targets = [], [] + inverted_substitution(avail_pool, drop_pool, True) + for item in drop_pool: + if item in avail_pool.entrances: + holes.append(item) + if drop_map[item] in avail_pool.exits: + targets.append(drop_map[item]) + return holes, targets + + +def find_entrances_and_exits(avail_pool, entrance_pool): + entrances, targets = [], [] + inverted_substitution(avail_pool, entrance_pool, True) + for item in entrance_pool: + if item in avail_pool.entrances: + entrances.append(item) + if 'Links House' in item: + targets.append('Chris Houlihan Room Exit') + if item in entrance_map and entrance_map[item] in avail_pool.exits: + targets.append(entrance_map[item]) + elif item in single_entrance_map and single_entrance_map[item] in avail_pool.exits: + targets.append(single_entrance_map[item]) + return entrances, targets + + +inverted_sub_table = { + 'Ganons Tower': 'Inverted Agahnims Tower', + 'Agahnims Tower': 'Inverted Ganons Tower', + 'Dark Sanctuary Hint': 'Inverted Dark Sanctuary', + 'Big Bomb Shop': 'Inverted Links House', + 'Links House': 'Inverted Big Bomb Shop', + 'Pyramid Hole': 'Inverted Pyramid Hole', + 'Pyramid Entrance': 'Inverted Pyramid Entrance' +} + +inverted_exit_sub_table = { + 'Ganons Tower Exit': 'Inverted Agahnims Tower Exit', + 'Agahnims Tower Exit': 'Inverted Ganons Tower Exit', + 'Dark Sanctuary Hint': 'Inverted Dark Sanctuary Exit', + 'Big Bomb Shop': 'Inverted Links House Exit', + 'Links House Exit': 'Inverted Big Bomb Shop', +} + + +def inverted_substitution(avail_pool, collection, is_entrance, is_set=False): + if avail_pool.inverted: + sub_table = inverted_sub_table if is_entrance else inverted_exit_sub_table + for area, sub in sub_table.items(): + if is_set: + if area in collection: + collection.remove(area) + collection.add(sub) + else: + try: + idx = collection.index(area) + collection[idx] = sub + except ValueError: + pass + + +def connect_random(exitlist, targetlist, avail, two_way=False): + targetlist = list(targetlist) + random.shuffle(targetlist) + + for exit, target in zip(exitlist, targetlist): + if two_way: + connect_two_way(exit, target, avail) + else: + connect_entrance(exit, target, avail) + + +def connect_custom(avail_pool, world, player): + if world.customizer and world.customizer.get_entrances(): + custom_entrances = world.customizer.get_entrances() + player_key = player + for ent_name, exit_name in custom_entrances[player_key]['two-way'].items(): + connect_two_way(ent_name, exit_name, avail_pool) + for ent_name, exit_name in custom_entrances[player_key]['entrances'].items(): + connect_entrance(ent_name, exit_name, avail_pool) + for ent_name, exit_name in custom_entrances[player_key]['exits'].items(): + connect_exit(exit_name, ent_name, avail_pool) + + +def connect_simple(world, exit_name, region_name, player): + world.get_entrance(exit_name, player).connect(world.get_region(region_name, player)) + + +def connect_vanilla(exit_name, region_name, avail): + world, player = avail.world, avail.player + world.get_entrance(exit_name, player).connect(world.get_region(region_name, player)) + avail.entrances.remove(exit_name) + avail.exits.remove(region_name) + + +def connect_vanilla_two_way(entrancename, exit_name, avail): + world, player = avail.world, avail.player + + entrance = world.get_entrance(entrancename, player) + exit = world.get_entrance(exit_name, player) + + # if these were already connected somewhere, remove the backreference + if entrance.connected_region is not None: + entrance.connected_region.entrances.remove(entrance) + if exit.connected_region is not None: + exit.connected_region.entrances.remove(exit) + + entrance.connect(exit.parent_region) + exit.connect(entrance.parent_region) + avail.entrances.remove(entrancename) + avail.exits.remove(exit_name) + + +def connect_entrance(entrancename, exit_name, avail): + world, player = avail.world, avail. player + entrance = world.get_entrance(entrancename, player) + # check if we got an entrance or a region to connect to + try: + region = world.get_region(exit_name, player) + exit = None + except RuntimeError: + exit = world.get_entrance(exit_name, player) + region = exit.parent_region + + # if this was already connected somewhere, remove the backreference + if entrance.connected_region is not None: + entrance.connected_region.entrances.remove(entrance) + + target = exit_ids[exit.name][0] if exit is not None else exit_ids.get(region.name, None) + addresses = door_addresses[entrance.name][0] + + entrance.connect(region, addresses, target) + if entrancename != 'Tavern North': + avail.entrances.remove(entrancename) + if avail.coupled: + if exit_name == 'Inverted Dark Sanctuary': + avail.exits.remove('Inverted Dark Sanctuary Exit') + else: + avail.exits.remove(exit_name) + world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) + logging.getLogger('').debug(f'Connected (entr) {entrance.name} to {exit.name if exit is not None else region.name}') + + +def connect_exit(exit_name, entrancename, avail): + world, player = avail.world, avail. player + entrance = world.get_entrance(entrancename, player) + exit = world.get_entrance(exit_name, player) + + # if this was already connected somewhere, remove the backreference + if exit.connected_region is not None: + exit.connected_region.entrances.remove(exit) + + exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) + if exit_name != 'Chris Houlihan Room Exit' and avail.coupled: + avail.entrances.remove(entrancename) + avail.exits.remove(exit_name) + world.spoiler.set_entrance(entrance.name, exit.name, 'exit', player) + logging.getLogger('').debug(f'Connected (exit) {entrance.name} to {exit.name}') + + +def connect_two_way(entrancename, exit_name, avail): + world, player = avail.world, avail.player + + entrance = world.get_entrance(entrancename, player) + exit = world.get_entrance(exit_name, player) + + # if these were already connected somewhere, remove the backreference + if entrance.connected_region is not None: + entrance.connected_region.entrances.remove(entrance) + if exit.connected_region is not None: + exit.connected_region.entrances.remove(exit) + + entrance.connect(exit.parent_region, door_addresses[entrance.name][0], exit_ids[exit.name][0]) + exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) + avail.entrances.remove(entrancename) + avail.exits.remove(exit_name) + world.spoiler.set_entrance(entrance.name, exit.name, 'both', player) + logging.getLogger('').debug(f'Connected (2-way) {entrance.name} to {exit.name}') + + +modes = { + 'dungeonssimple': { + 'undefined': 'vanilla', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + 'single_entrance_dungeon': { + 'entrances': ['Eastern Palace', 'Tower of Hera', 'Thieves Town', 'Skull Woods Final Section', + 'Palace of Darkness', 'Ice Palace', 'Misery Mire', 'Swamp Palace', 'Ganons Tower'] + }, + 'multi_entrance_dungeon': { + 'special': 'fixed_shuffle', + 'entrances': [['Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (East)', + 'Hyrule Castle Entrance (West)', 'Agahnims Tower'], + ['Desert Palace Entrance (South)', 'Desert Palace Entrance (East)', + 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'], + ['Turtle Rock', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)']] + }, + } + }, + 'dungeonsfull': { + 'undefined': 'vanilla', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + 'dungeon': { + 'special': 'same_world', + 'sanc_flag': 'light_world', # always light world flag + 'entrances': ['Eastern Palace', 'Tower of Hera', 'Thieves Town', 'Skull Woods Final Section', + 'Agahnims Tower', 'Palace of Darkness', 'Ice Palace', 'Misery Mire', 'Swamp Palace', + 'Ganons Tower'], + 'connectors': [['Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (East)', + 'Hyrule Castle Entrance (West)'], + ['Desert Palace Entrance (South)', 'Desert Palace Entrance (East)', + 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'], + ['Turtle Rock', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)']] + }, + } + }, + 'lite': { + 'undefined': 'shuffle', + 'keep_drops_together': 'on', + 'cross_world': 'off', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + 'fixed_non_items': { + 'special': 'vanilla', + 'condition': '', + 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Dark Desert Hint', 'Archery Game', + 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Bonk Fairy (Dark)', + 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop', + 'Palace of Darkness Hint', 'East Dark World Hint', 'Hookshot Fairy', '50 Rupee Cave', + 'Kakariko Gamble Game', '20 Rupee Cave', 'Good Bee Cave', 'Long Fairy Cave', + 'Light World Bomb Hut', 'Tavern (Front)', 'Bush Covered House', 'Snitch Lady (West)', + 'Snitch Lady (East)', 'Fortune Teller (Light)', 'Lost Woods Gamble', 'Desert Fairy', + 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', + 'Lumberjack House', 'Inverted Dark Sanctuary'], + }, + 'fixed_shops': { + 'special': 'vanilla', + 'condition': 'shopsanity', + 'entrances': ['Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', + 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', + 'Cave Shop (Lake Hylia)'], + }, + 'item_caves': { # shuffles shops if they weren't fixed in the last one + 'entrances': ['Mimic Cave', 'Spike Cave', 'Mire Shed', 'Dark World Hammer Peg Cave', 'Chest Game', + 'C-Shaped House', 'Brewery', 'Hype Cave', 'Big Bomb Shop', 'Pyramid Fairy', + 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', + 'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut', + 'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout', + 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', + 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', + 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', + 'Links House', 'Inverted Links House'] + }, + 'old_man_cave': { # have to do old man cave first so lw dungeon don't use up everything + 'special': 'old_man_cave_east', + 'entrances': ['Old Man Cave Exit (East)'], + }, + 'lw_dungeons': { + 'special': 'limited_lw', + 'entrances': ['Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (East)', + 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Eastern Palace', 'Tower of Hera', + 'Desert Palace Entrance (South)', 'Desert Palace Entrance (East)', + 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'], + }, + 'dw_dungeons': { + 'special': 'limited_dw', + 'entrances': ['Ice Palace', 'Misery Mire', 'Ganons Tower', 'Turtle Rock', + 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)'], + }, + } + }, + 'lean': { + 'undefined': 'shuffle', + 'keep_drops_together': 'on', + 'cross_world': 'on', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + 'fixed_non_items': { + 'special': 'vanilla', + 'condition': '', + 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Dark Desert Hint', 'Archery Game', + 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Bonk Fairy (Dark)', + 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop', + 'Palace of Darkness Hint', 'East Dark World Hint', 'Hookshot Fairy', '50 Rupee Cave', + 'Kakariko Gamble Game', '20 Rupee Cave', 'Good Bee Cave', 'Long Fairy Cave', + 'Light World Bomb Hut', 'Tavern (Front)', 'Bush Covered House', 'Snitch Lady (West)', + 'Snitch Lady (East)', 'Fortune Teller (Light)', 'Lost Woods Gamble', 'Desert Fairy', + 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', + 'Lumberjack House', 'Inverted Dark Sanctuary'], + }, + 'fixed_shops': { + 'special': 'vanilla', + 'condition': 'shopsanity', + 'entrances': ['Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', + 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', + 'Cave Shop (Lake Hylia)'], + }, + 'item_caves': { # shuffles shops if they weren't fixed in the last one + 'entrances': ['Mimic Cave', 'Spike Cave', 'Mire Shed', 'Dark World Hammer Peg Cave', 'Chest Game', + 'C-Shaped House', 'Brewery', 'Hype Cave', 'Big Bomb Shop', 'Pyramid Fairy', + 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', + 'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut', + 'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout', + 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', + 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', + 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', + 'Links House', 'Inverted Links House'] + } + } + }, + 'simple': { + 'undefined': 'shuffle', + 'keep_drops_together': 'on', + 'cross_world': 'off', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + 'single_entrance_dungeon': { + 'entrances': ['Eastern Palace', 'Tower of Hera', 'Thieves Town', 'Skull Woods Final Section', + 'Palace of Darkness', 'Ice Palace', 'Misery Mire', 'Swamp Palace', 'Ganons Tower'] + }, + 'multi_entrance_dungeon': { + 'special': 'fixed_shuffle', + 'entrances': [['Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (East)', + 'Hyrule Castle Entrance (West)', 'Agahnims Tower'], + ['Desert Palace Entrance (South)', 'Desert Palace Entrance (East)', + 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'], + ['Turtle Rock', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)']] + }, + 'two_way_entrances': { + 'special': 'simple_connector', + 'directional': [ + ['Bumper Cave (Bottom)', 'Bumper Cave (Top)'], + ['Hookshot Cave', 'Hookshot Cave Back Entrance'], + ], + 'connectors': [ + ['Elder House (East)', 'Elder House (West)'], + ['Two Brothers House (East)', 'Two Brothers House (West)'], + ['Superbunny Cave (Bottom)', 'Superbunny Cave (Top)'] + ], + 'directional_inv': [ + ['Old Man Cave (West)', 'Death Mountain Return Cave (West)'], + ['Two Brothers House (East)', 'Two Brothers House (West)'], + ], + 'connectors_inv': [ + ['Elder House (East)', 'Elder House (West)'], + ['Superbunny Cave (Bottom)', 'Superbunny Cave (Top)'], + ['Hookshot Cave', 'Hookshot Cave Back Entrance'] + ], + 'options': [ + ['Bumper Cave (Bottom)', 'Bumper Cave (Top)'], + ['Hookshot Cave', 'Hookshot Cave Back Entrance'], + ['Elder House (East)', 'Elder House (West)'], + ['Two Brothers House (East)', 'Two Brothers House (West)'], + ['Superbunny Cave (Bottom)', 'Superbunny Cave (Top)'], + ['Death Mountain Return Cave (West)', 'Death Mountain Return Cave (East)'], + ['Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)'], + ['Spiral Cave (Bottom)', 'Spiral Cave'] + ] + }, + 'old_man_cave': { + 'special': 'old_man_cave_east', + 'entrances': ['Old Man Cave Exit (East)'], + }, + 'old_man_cave_inverted': { + 'special': 'inverted_fixed', + 'entrance': 'Bumper Cave (Bottom)', + 'exit': 'Old Man Cave Exit (West)' + }, + 'light_death_mountain': { + 'special': 'limited', + 'entrances': ['Old Man Cave (West)', 'Old Man Cave (East)', 'Old Man House (Bottom)', + 'Old Man House (Top)', 'Death Mountain Return Cave (East)', + 'Death Mountain Return Cave (West)', 'Fairy Ascension Cave (Bottom)', + 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', + 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave', + 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)'], + 'options': ['Elder House Exit (East)', 'Elder House Exit (West)', 'Two Brothers House Exit (East)', + 'Two Brothers House Exit (West)', 'Old Man Cave Exit (West)', 'Old Man House Exit (Bottom)', + 'Old Man House Exit (Top)', 'Death Mountain Return Cave Exit (East)', + 'Death Mountain Return Cave Exit (West)', 'Fairy Ascension Cave Exit (Bottom)', + 'Fairy Ascension Cave Exit (Top)', 'Spiral Cave Exit (Top)', 'Spiral Cave Exit', + 'Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)', 'Hookshot Cave Front Exit', + 'Hookshot Cave Back Exit', 'Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)', + 'Spectacle Rock Cave Exit (Peak)', 'Spectacle Rock Cave Exit', + 'Spectacle Rock Cave Exit (Top)', 'Paradox Cave Exit (Bottom)', + 'Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)'] + } + } + }, + 'restricted': { + 'undefined': 'shuffle', + 'keep_drops_together': 'on', + 'cross_world': 'off', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + 'single_entrance_dungeon': { + 'entrances': ['Eastern Palace', 'Tower of Hera', 'Thieves Town', 'Skull Woods Final Section', + 'Palace of Darkness', 'Ice Palace', 'Misery Mire', 'Swamp Palace', 'Ganons Tower'] + }, + 'multi_entrance_dungeon': { + 'special': 'fixed_shuffle', + 'entrances': [['Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (East)', + 'Hyrule Castle Entrance (West)', 'Agahnims Tower'], + ['Desert Palace Entrance (South)', 'Desert Palace Entrance (East)', + 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'], + ['Turtle Rock', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)']] + }, + } + }, + 'full': { + 'undefined': 'shuffle', + 'keep_drops_together': 'on', + 'cross_world': 'off', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + } + }, + 'crossed': { + 'undefined': 'shuffle', + 'keep_drops_together': 'on', + 'cross_world': 'on', + 'pools': { + 'skull_drops': { + 'special': 'drops', + 'entrances': ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', + 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] + }, + 'skull_doors': { + 'special': 'skull', + 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)'] + }, + } + }, + 'insanity': { + 'undefined': 'shuffle', + 'keep_drops_together': 'off', + 'cross_world': 'on', + 'decoupled': 'on', + 'pools': {} + } +} + +drop_map = { + 'Skull Woods First Section Hole (East)': 'Skull Pinball', + 'Skull Woods First Section Hole (West)': 'Skull Left Drop', + 'Skull Woods First Section Hole (North)': 'Skull Pot Circle', + 'Skull Woods Second Section Hole': 'Skull Back Drop', + + 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance', + 'Kakariko Well Drop': 'Kakariko Well (top)', + 'Bat Cave Drop': 'Bat Cave (right)', + 'North Fairy Cave Drop': 'North Fairy Cave', + 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', + 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', + 'Sanctuary Grave': 'Sewer Drop', + 'Pyramid Hole': 'Pyramid', + 'Inverted Pyramid Hole': 'Pyramid' +} + +linked_drop_map = { + 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance Stairs', + 'Kakariko Well Drop': 'Kakariko Well Cave', + 'Bat Cave Drop': 'Bat Cave Cave', + 'North Fairy Cave Drop': 'North Fairy Cave', + 'Lost Woods Hideout Drop': 'Lost Woods Hideout Stump', + 'Lumberjack Tree Tree': 'Lumberjack Tree Cave', + 'Sanctuary Grave': 'Sanctuary', + 'Pyramid Hole': 'Pyramid Entrance', + 'Inverted Pyramid Hole': 'Inverted Pyramid Entrance' +} + +entrance_map = { + 'Desert Palace Entrance (South)': 'Desert Palace Exit (South)', + 'Desert Palace Entrance (West)': 'Desert Palace Exit (West)', + 'Desert Palace Entrance (North)': 'Desert Palace Exit (North)', + 'Desert Palace Entrance (East)': 'Desert Palace Exit (East)', + + 'Eastern Palace': 'Eastern Palace Exit', + 'Tower of Hera': 'Tower of Hera Exit', + + 'Hyrule Castle Entrance (South)': 'Hyrule Castle Exit (South)', + 'Hyrule Castle Entrance (West)': 'Hyrule Castle Exit (West)', + 'Hyrule Castle Entrance (East)': 'Hyrule Castle Exit (East)', + 'Agahnims Tower': 'Agahnims Tower Exit', + 'Inverted Agahnims Tower': 'Inverted Agahnims Tower Exit', + + 'Thieves Town': 'Thieves Town Exit', + 'Skull Woods First Section Door': 'Skull Woods First Section Exit', + 'Skull Woods Second Section Door (East)': 'Skull Woods Second Section Exit (East)', + 'Skull Woods Second Section Door (West)': 'Skull Woods Second Section Exit (West)', + 'Skull Woods Final Section': 'Skull Woods Final Section Exit', + 'Ice Palace': 'Ice Palace Exit', + 'Misery Mire': 'Misery Mire Exit', + 'Palace of Darkness': 'Palace of Darkness Exit', + 'Swamp Palace': 'Swamp Palace Exit', + + 'Turtle Rock': 'Turtle Rock Exit (Front)', + 'Dark Death Mountain Ledge (West)': 'Turtle Rock Ledge Exit (West)', + 'Dark Death Mountain Ledge (East)': 'Turtle Rock Ledge Exit (East)', + 'Turtle Rock Isolated Ledge Entrance': 'Turtle Rock Isolated Ledge Exit', + 'Ganons Tower': 'Ganons Tower Exit', + 'Inverted Ganons Tower': 'Inverted Ganons Tower Exit', + + 'Links House': 'Links House Exit', + 'Inverted Links House': 'Inverted Links House Exit', + + + 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance Exit', + 'Kakariko Well Cave': 'Kakariko Well Exit', + 'Bat Cave Cave': 'Bat Cave Exit', + 'North Fairy Cave': 'North Fairy Cave Exit', + 'Lost Woods Hideout Stump': 'Lost Woods Hideout Exit', + 'Lumberjack Tree Cave': 'Lumberjack Tree Exit', + 'Sanctuary': 'Sanctuary Exit', + 'Pyramid Entrance': 'Pyramid Exit', + 'Inverted Pyramid Entrance': 'Pyramid Exit', + + 'Elder House (East)': 'Elder House Exit (East)', + 'Elder House (West)': 'Elder House Exit (West)', + 'Two Brothers House (East)': 'Two Brothers House Exit (East)', + 'Two Brothers House (West)': 'Two Brothers House Exit (West)', + 'Old Man Cave (West)': 'Old Man Cave Exit (West)', + 'Old Man Cave (East)': 'Old Man Cave Exit (East)', + 'Old Man House (Bottom)': 'Old Man House Exit (Bottom)', + 'Old Man House (Top)': 'Old Man House Exit (Top)', + 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave Exit (East)', + 'Death Mountain Return Cave (West)': 'Death Mountain Return Cave Exit (West)', + 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave Exit (Bottom)', + 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave Exit (Top)', + 'Spiral Cave': 'Spiral Cave Exit (Top)', + 'Spiral Cave (Bottom)': 'Spiral Cave Exit', + 'Bumper Cave (Bottom)': 'Bumper Cave Exit (Bottom)', + 'Bumper Cave (Top)': 'Bumper Cave Exit (Top)', + 'Hookshot Cave': 'Hookshot Cave Front Exit', + 'Hookshot Cave Back Entrance': 'Hookshot Cave Back Exit', + 'Superbunny Cave (Top)': 'Superbunny Cave Exit (Top)', + 'Superbunny Cave (Bottom)': 'Superbunny Cave Exit (Bottom)', + + 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave Exit (Peak)', + 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave Exit', + 'Spectacle Rock Cave': 'Spectacle Rock Cave Exit (Top)', + 'Paradox Cave (Bottom)': 'Paradox Cave Exit (Bottom)', + 'Paradox Cave (Middle)': 'Paradox Cave Exit (Middle)', + 'Paradox Cave (Top)': 'Paradox Cave Exit (Top)', +} + + +single_entrance_map = { + 'Mimic Cave': 'Mimic Cave', 'Dark Death Mountain Fairy': 'Dark Death Mountain Healer Fairy', + 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', 'Spike Cave': 'Spike Cave', + 'Dark Desert Fairy': 'Dark Desert Healer Fairy', 'Dark Desert Hint': 'Dark Desert Hint', 'Mire Shed': 'Mire Shed', + 'Archery Game': 'Archery Game', 'Dark World Potion Shop': 'Dark World Potion Shop', + 'Dark World Lumberjack Shop': 'Dark World Lumberjack Shop', 'Dark World Shop': 'Village of Outcasts Shop', + 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', 'Dark Sanctuary Hint': 'Dark Sanctuary Hint', + 'Red Shield Shop': 'Red Shield Shop', 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', + 'Chest Game': 'Chest Game', 'C-Shaped House': 'C-Shaped House', 'Brewery': 'Brewery', + 'Bonk Fairy (Dark)': 'Bonk Fairy (Dark)', 'Hype Cave': 'Hype Cave', + 'Dark Lake Hylia Ledge Hint': 'Dark Lake Hylia Ledge Hint', + 'Dark Lake Hylia Ledge Spike Cave': 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Fairy': 'Dark Lake Hylia Ledge Healer Fairy', + 'Dark Lake Hylia Fairy': 'Dark Lake Hylia Healer Fairy', + 'Dark Lake Hylia Shop': 'Dark Lake Hylia Shop', 'Big Bomb Shop': 'Big Bomb Shop', + 'Palace of Darkness Hint': 'Palace of Darkness Hint', 'East Dark World Hint': 'East Dark World Hint', + 'Pyramid Fairy': 'Pyramid Fairy', 'Hookshot Fairy': 'Hookshot Fairy', '50 Rupee Cave': '50 Rupee Cave', + 'Ice Rod Cave': 'Ice Rod Cave', 'Bonk Rock Cave': 'Bonk Rock Cave', 'Library': 'Library', + 'Kakariko Gamble Game': 'Kakariko Gamble Game', 'Potion Shop': 'Potion Shop', '20 Rupee Cave': '20 Rupee Cave', + 'Good Bee Cave': 'Good Bee Cave', 'Long Fairy Cave': 'Long Fairy Cave', 'Mini Moldorm Cave': 'Mini Moldorm Cave', + 'Checkerboard Cave': 'Checkerboard Cave', 'Graveyard Cave': 'Graveyard Cave', 'Cave 45': 'Cave 45', + 'Kakariko Shop': 'Kakariko Shop', 'Light World Bomb Hut': 'Light World Bomb Hut', + 'Tavern (Front)': 'Tavern (Front)', 'Bush Covered House': 'Bush Covered House', + 'Snitch Lady (West)': 'Snitch Lady (West)', 'Snitch Lady (East)': 'Snitch Lady (East)', + 'Fortune Teller (Light)': 'Fortune Teller (Light)', 'Lost Woods Gamble': 'Lost Woods Gamble', + 'Sick Kids House': 'Sick Kids House', 'Blacksmiths Hut': 'Blacksmiths Hut', 'Capacity Upgrade': 'Capacity Upgrade', + 'Cave Shop (Lake Hylia)': 'Cave Shop (Lake Hylia)', 'Sahasrahlas Hut': 'Sahasrahlas Hut', + 'Aginahs Cave': 'Aginahs Cave', 'Chicken House': 'Chicken House', 'Kings Grave': 'Kings Grave', + 'Desert Fairy': 'Desert Healer Fairy', 'Light Hype Fairy': 'Swamp Healer Fairy', + 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', + 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', 'Lumberjack House': 'Lumberjack House', 'Dam': 'Dam', + 'Blinds Hideout': 'Blinds Hideout', 'Waterfall of Wishing': 'Waterfall of Wishing', + 'Inverted Bomb Shop': 'Inverted Bomb Shop', 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary', +} + +default_dw = { + 'Thieves Town Exit', 'Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', + 'Skull Woods Second Section Exit (West)', 'Skull Woods Final Section Exit', 'Ice Palace Exit', 'Misery Mire Exit', + 'Palace of Darkness Exit', 'Swamp Palace Exit', 'Turtle Rock Exit (Front)', 'Turtle Rock Ledge Exit (West)', + 'Turtle Rock Ledge Exit (East)', 'Turtle Rock Isolated Ledge Exit', 'Bumper Cave Exit (Top)', + 'Bumper Cave Exit (Bottom)', 'Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)', + 'Hookshot Cave Front Exit', 'Hookshot Cave Back Exit', 'Ganons Tower Exit', 'Pyramid Exit', + 'Dark Lake Hylia Healer Fairy', 'Dark Lake Hylia Ledge Healer Fairy', 'Dark Desert Healer Fairy', + 'Dark Death Mountain Healer Fairy', 'Cave Shop (Dark Death Mountain)', 'Pyramid Fairy', 'East Dark World Hint', + 'Palace of Darkness Hint', 'Big Bomb Shop', 'Village of Outcasts Shop', 'Dark Lake Hylia Shop', + 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Brewery', 'C-Shaped House', 'Chest Game', 'Dark World Hammer Peg Cave', + 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', + 'Spike Cave', 'Skull Back Drop', 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle', 'Pyramid', + 'Inverted Agahnims Tower Exit', 'Inverted Dark Sanctuary Exit', 'Inverted Links House Exit' +} + +default_lw = { + 'Links House Exit', 'Desert Palace Exit (South)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', + 'Desert Palace Exit (North)', 'Eastern Palace Exit', 'Tower of Hera Exit', 'Hyrule Castle Exit (South)', + 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Agahnims Tower Exit', + 'Hyrule Castle Secret Entrance Exit', 'Kakariko Well Exit', 'Bat Cave Exit', 'Elder House Exit (East)', + 'Elder House Exit (West)', 'North Fairy Cave Exit', 'Lost Woods Hideout Exit', 'Lumberjack Tree Exit', + 'Two Brothers House Exit (East)', 'Two Brothers House Exit (West)', 'Sanctuary Exit', 'Old Man Cave Exit (East)', + 'Old Man Cave Exit (West)', 'Old Man House Exit (Bottom)', 'Old Man House Exit (Top)', + 'Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)', 'Spectacle Rock Cave Exit', + 'Spectacle Rock Cave Exit (Top)', 'Spectacle Rock Cave Exit (Peak)', 'Paradox Cave Exit (Bottom)', + 'Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Fairy Ascension Cave Exit (Bottom)', + 'Fairy Ascension Cave Exit (Top)', 'Spiral Cave Exit', 'Spiral Cave Exit (Top)', 'Waterfall of Wishing', 'Dam', + 'Blinds Hideout', 'Lumberjack House', 'Bonk Fairy (Light)', 'Bonk Fairy (Dark)', 'Lake Hylia Healer Fairy', + 'Swamp Healer Fairy', 'Desert Healer Fairy', 'Fortune Teller (Light)', 'Lake Hylia Fortune Teller', 'Kings Grave', + 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Capacity Upgrade', 'Blacksmiths Hut', + 'Sick Kids House', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', + 'Tavern (Front)', 'Light World Bomb Hut', 'Kakariko Shop', 'Cave 45', 'Graveyard Cave', 'Checkerboard Cave', + 'Mini Moldorm Cave', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', '50 Rupee Cave', 'Ice Rod Cave', + 'Bonk Rock Cave', 'Library', 'Kakariko Gamble Game', 'Potion Shop', 'Hookshot Fairy', 'Mimic Cave', + 'Kakariko Well (top)', 'Hyrule Castle Secret Entrance', 'Bat Cave (right)', 'North Fairy Cave', + 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Inverted Ganons Tower Exit', + 'Inverted Big Bomb Shop' +} + +LW_Entrances = ['Elder House (East)', 'Elder House (West)', 'Two Brothers House (East)', 'Two Brothers House (West)', + 'Old Man Cave (West)', 'Old Man House (Bottom)', 'Death Mountain Return Cave (West)', + 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', + 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', + 'Desert Palace Entrance (South)', 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', + 'Desert Palace Entrance (East)', 'Eastern Palace', 'Tower of Hera', 'Hyrule Castle Entrance (West)', + 'Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (South)', 'Agahnims Tower', 'Blinds Hideout', + 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Chicken House', 'Aginahs Cave', + 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Blacksmiths Hut', 'Sick Kids House', 'Lost Woods Gamble', + 'Fortune Teller (Light)', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', + 'Tavern (Front)', 'Light World Bomb Hut', 'Kakariko Shop', 'Mini Moldorm Cave', 'Long Fairy Cave', + 'Good Bee Cave', '20 Rupee Cave', '50 Rupee Cave', 'Ice Rod Cave', 'Library', 'Potion Shop', 'Dam', + 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Waterfall of Wishing', + 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', 'Kings Grave', + 'Bonk Fairy (Light)', 'Hookshot Fairy', 'Mimic Cave', 'Links House', 'Old Man Cave (East)', + 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', + 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Hyrule Castle Secret Entrance Stairs', + 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Lost Woods Hideout Stump', + 'Lumberjack Tree Cave', 'Sanctuary', + 'Inverted Ganons Tower', 'Inverted Big Bomb Shop', 'Inverted Pyramid Entrance'] + +DW_Entrances = ['Bumper Cave (Bottom)', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', 'Hookshot Cave', + 'Thieves Town', 'Skull Woods Final Section', 'Ice Palace', 'Misery Mire', 'Palace of Darkness', + 'Swamp Palace', 'Turtle Rock', 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', + 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', + 'Bonk Fairy (Dark)', 'Dark Sanctuary Hint', 'Dark Lake Hylia Fairy', 'C-Shaped House', 'Big Bomb Shop', + 'Dark Death Mountain Fairy', 'Dark Lake Hylia Shop', 'Dark World Shop', 'Red Shield Shop', 'Mire Shed', + 'East Dark World Hint', 'Dark Desert Hint', 'Spike Cave', 'Palace of Darkness Hint', + 'Dark Lake Hylia Ledge Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', + 'Pyramid Fairy', 'Archery Game', 'Dark World Lumberjack Shop', 'Hype Cave', 'Brewery', + 'Dark Lake Hylia Ledge Hint', 'Chest Game', 'Dark Desert Fairy', 'Dark Lake Hylia Ledge Fairy', + 'Fortune Teller (Dark)', 'Dark World Hammer Peg Cave', 'Pyramid Entrance', + 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)', + 'Inverted Dark Sanctuary', 'Inverted Links House', 'Inverted Agahnims Tower'] + +LW_Must_Exit = ['Desert Palace Entrance (East)'] + +DW_Must_Exit = [('Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)'), + 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', + 'Pyramid Entrance'] + +Inverted_LW_Must_Exit = [('Desert Palace Entrance (North)', 'Desert Palace Entrance (West)'), + 'Desert Palace Entrance (East)', 'Death Mountain Return Cave (West)', + 'Two Brothers House (West)', + ('Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower')] + +Inverted_DW_Must_Exit = [] + +Isolated_LH_Doors_Open = ['Mimic Cave', 'Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', + 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', + 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', + 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', + 'Dark World Shop', 'Dark World Potion Shop'] + +Isolated_LH_Doors_Inv = ['Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', + 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', + 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', + 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', + 'Dark World Shop', 'Dark World Potion Shop'] + +# inverted doesn't like really like - Paradox Top or Tower of Hera +LH_DM_Connector_List = { + 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', + 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', + 'Tower of Hera', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave', + 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Hookshot Fairy', 'Spike Cave', + 'Dark Death Mountain Fairy', 'Inverted Agahnims Tower', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', + 'Hookshot Cave', 'Cave Shop (Dark Death Mountain)', 'Turtle Rock'} + +LH_DM_Exit_Forbidden = { + 'Turtle Rock Isolated Ledge Entrance', 'Mimic Cave', 'Hookshot Cave Back Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', 'Desert Palace Entrance (South)', + 'Ice Palace', 'Waterfall of Wishing', 'Kings Grave', 'Dark World Hammer Peg Cave', 'Capacity Upgrade', + 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)' +} # omissions from Isolated Starts: 'Desert Palace Entrance (North)', 'Dark World Shop', 'Dark World Potion Shop' + +# in inverted we put dark sanctuary in west dark world for now +Inverted_Dark_Sanctuary_Doors = [ + 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', + 'Dark World Lumberjack Shop', 'Red Shield Shop', 'Bumper Cave (Bottom)', 'Bumper Cave (Top)', 'Thieves Town' +] + +Connector_List = [['Elder House Exit (East)', 'Elder House Exit (West)'], + ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)'], + ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)'], + ['Fairy Ascension Cave Exit (Bottom)', 'Fairy Ascension Cave Exit (Top)'], + ['Bumper Cave Exit (Top)', 'Bumper Cave Exit (Bottom)'], + ['Hookshot Cave Back Exit', 'Hookshot Cave Front Exit'], + ['Superbunny Cave Exit (Bottom)', 'Superbunny Cave Exit (Top)'], + ['Spiral Cave Exit (Top)', 'Spiral Cave Exit'], + ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)'], + ['Spectacle Rock Cave Exit (Peak)', 'Spectacle Rock Cave Exit (Top)', + 'Spectacle Rock Cave Exit'], + ['Paradox Cave Exit (Top)', 'Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Bottom)'], + ['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', + 'Hyrule Castle Exit (East)'], + ['Desert Palace Exit (South)', 'Desert Palace Exit (East)', + 'Desert Palace Exit (West)'], + ['Turtle Rock Exit (Front)', 'Turtle Rock Isolated Ledge Exit', + 'Turtle Rock Ledge Exit (West)', 'Turtle Rock Ledge Exit (East)']] + +Connector_Exit_Set = { + 'Elder House Exit (East)', 'Elder House Exit (West)', 'Two Brothers House Exit (East)', + 'Two Brothers House Exit (West)', 'Death Mountain Return Cave Exit (West)', + 'Death Mountain Return Cave Exit (East)', 'Fairy Ascension Cave Exit (Bottom)', 'Fairy Ascension Cave Exit (Top)', + 'Bumper Cave Exit (Top)', 'Bumper Cave Exit (Bottom)', 'Hookshot Cave Back Exit', 'Hookshot Cave Front Exit', + 'Superbunny Cave Exit (Top)', 'Spiral Cave Exit', 'Old Man House Exit (Bottom)', 'Old Man House Exit (Top)', + 'Spectacle Rock Cave Exit', 'Paradox Cave Exit (Bottom)', + 'Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', + 'Desert Palace Exit (South)', 'Desert Palace Exit (East)', 'Desert Palace Exit (West)', 'Turtle Rock Exit (Front)', + 'Turtle Rock Isolated Ledge Exit', 'Turtle Rock Ledge Exit (West)' +} + +# Entrances that cannot be used to access a must_exit entrance - symmetrical to allow reverse lookups +Must_Exit_Invalid_Connections = defaultdict(set, { + 'Dark Death Mountain Ledge (East)': {'Dark Death Mountain Ledge (West)', 'Mimic Cave'}, + 'Dark Death Mountain Ledge (West)': {'Dark Death Mountain Ledge (East)', 'Mimic Cave'}, + 'Mimic Cave': {'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)'}, + 'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'}, + 'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'}, + 'Skull Woods Second Section Door (West)': {'Skull Woods Final Section'}, + 'Skull Woods Final Section': {'Skull Woods Second Section Door (West)'}, +}) +Inverted_Must_Exit_Invalid_Connections = defaultdict(set, { + 'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'}, + 'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'}, + 'Desert Palace Entrance (North)': {'Desert Palace Entrance (West)'}, + 'Desert Palace Entrance (West)': {'Desert Palace Entrance (North)'}, + 'Inverted Ganons Tower': {'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}, + 'Hyrule Castle Entrance (West)': {'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower'}, + 'Hyrule Castle Entrance (East)': {'Hyrule Castle Entrance (West)', 'Inverted Ganons Tower'}, +}) + +Old_Man_Entrances = ['Old Man Cave (East)', + 'Old Man House (Top)', + 'Death Mountain Return Cave (East)', + 'Spectacle Rock Cave', + 'Spectacle Rock Cave Peak', + 'Spectacle Rock Cave (Bottom)', + 'Tower of Hera'] + +Inverted_Old_Man_Entrances = ['Dark Death Mountain Fairy', 'Spike Cave', 'Inverted Agahnims Tower'] + +Simple_DM_Non_Connectors = {'Old Man Cave Ledge', 'Spiral Cave (Top)', 'Superbunny Cave (Bottom)', + 'Spectacle Rock Cave (Peak)', 'Spectacle Rock Cave (Top)'} + +Blacksmith_Options = [ + 'Blinds Hideout', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Chicken House', 'Aginahs Cave', + 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Blacksmiths Hut', 'Sick Kids House', 'Lost Woods Gamble', + 'Fortune Teller (Light)', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', 'Tavern (Front)', + 'Light World Bomb Hut', 'Kakariko Shop', 'Mini Moldorm Cave', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', + '50 Rupee Cave', 'Ice Rod Cave', 'Library', 'Potion Shop', 'Dam', 'Lumberjack House', 'Lake Hylia Fortune Teller', + 'Kakariko Gamble Game', 'Eastern Palace', 'Elder House (East)', 'Elder House (West)', 'Two Brothers House (East)', + 'Old Man Cave (West)', 'Sanctuary', 'Lumberjack Tree Cave', 'Lost Woods Hideout Stump', 'North Fairy Cave', + 'Bat Cave Cave', 'Kakariko Well Cave', 'Inverted Big Bomb Shop', 'Links House'] + +Bomb_Shop_Options = [ + 'Waterfall of Wishing', 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', + 'Kings Grave', 'Bonk Fairy (Light)', 'Hookshot Fairy', 'East Dark World Hint', 'Palace of Darkness Hint', + 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Bonk Fairy (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', + 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Shop', + 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', + 'Dark Desert Fairy', 'Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy', 'Mimic Cave', + 'Big Bomb Shop', 'Dark Lake Hylia Shop', 'Bumper Cave (Top)', 'Links House', + 'Hyrule Castle Entrance (South)', 'Misery Mire', 'Thieves Town', 'Bumper Cave (Bottom)', 'Swamp Palace', + 'Hyrule Castle Secret Entrance Stairs', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', 'Ice Palace', 'Turtle Rock', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', 'Superbunny Cave (Top)', + 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Ganons Tower', 'Desert Palace Entrance (South)', 'Tower of Hera', + 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', + 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', + 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Fairy Ascension Cave (Bottom)', + 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Palace of Darkness', + 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower', + 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', + 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)', 'Two Brothers House (West)'] + Blacksmith_Options + +Inverted_Bomb_Shop_Options = [ + 'Waterfall of Wishing', 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', + 'Kings Grave', 'Bonk Fairy (Light)', 'Hookshot Fairy', 'East Dark World Hint', 'Palace of Darkness Hint', + 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Bonk Fairy (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', + 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Fortune Teller (Dark)', 'Dark World Shop', + 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', + 'Dark Desert Fairy', 'Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy', 'Mimic Cave', + 'Dark Lake Hylia Shop', 'Bumper Cave (Top)', + 'Hyrule Castle Entrance (South)', 'Misery Mire', 'Thieves Town', 'Bumper Cave (Bottom)', 'Swamp Palace', + 'Hyrule Castle Secret Entrance Stairs', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', + 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', 'Ice Palace', 'Turtle Rock', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', 'Superbunny Cave (Top)', + 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Desert Palace Entrance (South)', 'Tower of Hera', + 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', + 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', + 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Fairy Ascension Cave (Bottom)', + 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Palace of Darkness', + 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', + 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', + 'Inverted Ganons Tower', 'Inverted Agahnims Tower', 'Inverted Dark Sanctuary', 'Inverted Links House', + 'Inverted Big Bomb Shop'] + Blacksmith_Options + + +# these are connections that cannot be shuffled and always exist. +# They link together separate parts of the world we need to divide into regions +mandatory_connections = [('Links House S&Q', 'Links House'), + ('Sanctuary S&Q', 'Sanctuary'), + ('Old Man S&Q', 'Old Man House'), + ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), + ('Lake Hylia Central Island Teleporter', 'Dark Lake Hylia Central Island'), + ('Zoras River', 'Zoras River'), + ('Kings Grave Outer Rocks', 'Kings Grave Area'), + ('Kings Grave Inner Rocks', 'Light World'), + ('Kings Grave Mirror Spot', 'Kings Grave Area'), + ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), + ('Kakariko Well (top to back)', 'Kakariko Well (back)'), + ('Master Sword Meadow', 'Master Sword Meadow'), + ('Hobo Bridge', 'Hobo Bridge'), + ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), + ('Bat Cave Door', 'Bat Cave (left)'), + ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), + ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), + ('Blinds Hideout N', 'Blinds Hideout (Top)'), + ('Desert Palace Stairs', 'Desert Palace Stairs'), + ('Desert Palace Stairs Drop', 'Light World'), + ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), + ('Desert Ledge Return Rocks', 'Desert Ledge'), + ('Hyrule Castle Ledge Courtyard Drop', 'Hyrule Castle Courtyard'), + ('Hyrule Castle Main Gate', 'Hyrule Castle Courtyard'), + ('Sewer Drop', 'Sewers Rat Path'), + ('Flute Spot 1', 'Death Mountain'), + ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), + ('Death Mountain Entrance Drop', 'Light World'), + ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), + ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), + ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), + ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), + ('Death Mountain Return Ledge Drop', 'Light World'), + ('Old Man Cave Dropdown', 'Old Man Cave'), + ('Old Man House Front to Back', 'Old Man House Back'), + ('Old Man House Back to Front', 'Old Man House'), + ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), + ('Broken Bridge (East)', 'Death Mountain'), + ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), + ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), + ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), + ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), + ('East Death Mountain (Top)', 'East Death Mountain (Top)'), + ('Death Mountain (Top)', 'Death Mountain (Top)'), + ('Death Mountain Drop', 'Death Mountain'), + ('Spectacle Rock Drop', 'Death Mountain (Top)'), + + ('Top of Pyramid', 'East Dark World'), + ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), + ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), + ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), + ('Dark Lake Hylia Ledge', 'Dark Lake Hylia Ledge'), + ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), + ('East Dark World Pier', 'East Dark World'), + ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), + ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), + ('Hyrule Castle Ledge Mirror Spot', 'Hyrule Castle Ledge'), + ('South Dark World Bridge', 'South Dark World'), + ('East Dark World Bridge', 'East Dark World'), + ('Maze Race Mirror Spot', 'Maze Race Ledge'), + ('Village of Outcasts Heavy Rock', 'West Dark World'), + ('Village of Outcasts Drop', 'South Dark World'), + ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), + ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), + ('Peg Area Rocks', 'West Dark World'), + ('Grassy Lawn Pegs', 'West Dark World'), + ('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'), + ('East Dark World River Pier', 'East Dark World'), + ('West Dark World Gap', 'West Dark World'), + ('East Dark World Broken Bridge Pass', 'East Dark World'), + ('Catfish Exit Rock', 'Northeast Dark World'), + ('Catfish Entrance Rock', 'Catfish'), + ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), + ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), + ('Bumper Cave Entrance Drop', 'West Dark World'), + ('Bumper Cave Entrance Mirror Spot', 'Death Mountain Entrance'), + ('Bumper Cave Ledge Drop', 'West Dark World'), + ('Bumper Cave Ledge Mirror Spot', 'Death Mountain Return Ledge'), + ('Skull Woods Forest', 'Skull Woods Forest'), + ('Desert Ledge Mirror Spot', 'Desert Ledge'), + ('Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge (Northeast)'), + ('Desert Palace Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), + ('Dark Desert Teleporter', 'Dark Desert'), + ('Desert Palace Stairs Mirror Spot', 'Desert Palace Stairs'), + ('East Hyrule Teleporter', 'East Dark World'), + ('South Hyrule Teleporter', 'South Dark World'), + ('Kakariko Teleporter', 'West Dark World'), + ('Death Mountain Teleporter', 'Dark Death Mountain (West Bottom)'), + ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), + ('Paradox Cave Push Block', 'Paradox Cave Front'), + ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), + ('Paradox Cave Bomb Jump', 'Paradox Cave'), + ('Paradox Cave Drop', 'Paradox Cave Chest Area'), + ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), + ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), + ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), + ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), + ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), + ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), + ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), + ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), + ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), + ('Spectacle Rock Mirror Spot', 'Spectacle Rock'), + ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), + ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), + ('East Death Mountain (Top) Mirror Spot', 'East Death Mountain (Top)'), + ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), + ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), + ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), + ('Hookshot Cave Middle to Back', 'Hookshot Cave (Back)'), + ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), + ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), + ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), + ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), + ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), + ('Floating Island Drop', 'Dark Death Mountain (Top)'), + ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'), + ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), + ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), + ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), + ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), + ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), + ('Bombos Tablet Mirror Spot', 'Bombos Tablet Ledge'), + ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), + ('Ganon Drop', 'Bottom of Pyramid'), + ('Pyramid Drop', 'East Dark World'), + ('Maze Race Ledge Drop', 'Light World'), + ('Graveyard Ledge Drop', 'Light World'), + ('Cave 45 Ledge Drop', 'Light World'), + ('Checkerboard Ledge Drop', 'Light World'), + ('Desert Ledge Drop', 'Light World'), + ('Hyrule Castle Main Gate (North)', 'Light World'), + ('Hyrule Castle Ledge Drop', 'Light World'), + ] + +inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), + ('Dark Sanctuary S&Q', 'Inverted Dark Sanctuary'), + ('Old Man S&Q', 'Old Man House'), + ('Castle Ledge S&Q', 'Hyrule Castle Ledge'), + ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), + ('Lake Hylia Island Pier', 'Lake Hylia Island'), + ('Lake Hylia Warp', 'Northeast Light World'), + ('Northeast Light World Warp', 'Light World'), + ('Zoras River', 'Zoras River'), + ('Waterfall of Wishing Cave', 'Waterfall of Wishing Cave'), + ('Northeast Light World Return', 'Northeast Light World'), + ('Kings Grave Outer Rocks', 'Kings Grave Area'), + ('Kings Grave Inner Rocks', 'Light World'), + ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), + ('Kakariko Well (top to back)', 'Kakariko Well (back)'), + ('Master Sword Meadow', 'Master Sword Meadow'), + ('Hobo Bridge', 'Hobo Bridge'), + ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), + ('Bat Cave Door', 'Bat Cave (left)'), + ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), + ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), + ('Blinds Hideout N', 'Blinds Hideout (Top)'), + ('Desert Palace Stairs', 'Desert Palace Stairs'), + ('Desert Palace Stairs Drop', 'Light World'), + ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), + ('Desert Ledge Return Rocks', 'Desert Ledge'), + ('Sewer Drop', 'Sewers Rat Path'), + ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), + ('Death Mountain Entrance Drop', 'Light World'), + ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), + ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), + ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), + ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), + ('Death Mountain Return Ledge Drop', 'Light World'), + ('Old Man Cave Dropdown', 'Old Man Cave'), + ('Old Man House Front to Back', 'Old Man House Back'), + ('Old Man House Back to Front', 'Old Man House'), + ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), + ('Broken Bridge (East)', 'Death Mountain'), + ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), + ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), + ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), + ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), + ('East Death Mountain (Top)', 'East Death Mountain (Top)'), + ('Death Mountain (Top)', 'Death Mountain (Top)'), + ('Death Mountain Drop', 'Death Mountain'), + ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), + ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), + ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), + ('Dark Lake Hylia Ledge Pier', 'Dark Lake Hylia Ledge'), + ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), + ('Ice Palace Missing Wall', 'Dark Lake Hylia Central Island'), + ('Dark Lake Hylia Shallows', 'Dark Lake Hylia'), + ('East Dark World Pier', 'East Dark World'), + ('South Dark World Bridge', 'South Dark World'), + ('East Dark World Bridge', 'East Dark World'), + ('Village of Outcasts Heavy Rock', 'West Dark World'), + ('Village of Outcasts Drop', 'South Dark World'), + ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), + ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), + ('Peg Area Rocks', 'West Dark World'), + ('Grassy Lawn Pegs', 'West Dark World'), + ('East Dark World River Pier', 'Northeast Dark World'), + ('West Dark World Gap', 'West Dark World'), + ('East Dark World Broken Bridge Pass', 'East Dark World'), + ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), + ('Catfish Exit Rock', 'Northeast Dark World'), + ('Catfish Entrance Rock', 'Catfish'), + ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), + ('Bumper Cave Entrance Drop', 'West Dark World'), + ('Bumper Cave Ledge Drop', 'West Dark World'), + ('Skull Woods Forest', 'Skull Woods Forest'), + ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), + ('Paradox Cave Push Block', 'Paradox Cave Front'), + ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), + ('Paradox Cave Bomb Jump', 'Paradox Cave'), + ('Paradox Cave Drop', 'Paradox Cave Chest Area'), + ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), + ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), + ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), + ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), + ('Fairy Ascension Ledge Access', 'Fairy Ascension Ledge'), + ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), + ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), + ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), + ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), + ('Ganon Drop', 'Bottom of Pyramid'), + ('Pyramid Drop', 'East Dark World'), + ('Post Aga Teleporter', 'Light World'), + ('Secret Passage Inner Bushes', 'Light World'), + ('Secret Passage Outer Bushes', 'Hyrule Castle Secret Entrance Area'), + ('Potion Shop Inner Bushes', 'Light World'), + ('Potion Shop Outer Bushes', 'Potion Shop Area'), + ('Potion Shop Inner Rock', 'Northeast Light World'), + ('Potion Shop Outer Rock', 'Potion Shop Area'), + ('Potion Shop River Drop', 'River'), + ('Graveyard Cave Inner Bushes', 'Light World'), + ('Graveyard Cave Outer Bushes', 'Graveyard Cave Area'), + ('Graveyard Cave Mirror Spot', 'West Dark World'), + ('Light World River Drop', 'River'), + ('Light World Pier', 'Light World'), + ('Potion Shop Pier', 'Potion Shop Area'), + ('Hyrule Castle Ledge Courtyard Drop', 'Light World'), + ('Mimic Cave Ledge Access', 'Mimic Cave Ledge'), + ('Mimic Cave Ledge Drop', 'East Death Mountain (Bottom)'), + ('Turtle Rock Tail Drop', 'Turtle Rock (Top)'), + ('Turtle Rock Drop', 'Dark Death Mountain'), + ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), + ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), + ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), + ('Hookshot Cave Middle to Back', 'Hookshot Cave (Back)'), + ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), + ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), + ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), + ('Desert Ledge Drop', 'Light World'), + ('Floating Island Drop', 'Dark Death Mountain'), + ('Dark Lake Hylia Central Island Teleporter', 'Lake Hylia Central Island'), + ('Dark Desert Teleporter', 'Light World'), + ('East Dark World Teleporter', 'Light World'), + ('South Dark World Teleporter', 'Light World'), + ('West Dark World Teleporter', 'Light World'), + ('Dark Death Mountain Teleporter (West)', 'Death Mountain'), + ('Dark Death Mountain Teleporter (East)', 'East Death Mountain (Top)'), + ('Dark Death Mountain Teleporter (East Bottom)', 'East Death Mountain (Bottom)'), + ('Mire Mirror Spot', 'Dark Desert'), + ('Dark Desert Drop', 'Dark Desert'), + ('Desert Palace Stairs Mirror Spot', 'Dark Desert'), + ('Desert Palace North Mirror Spot', 'Dark Desert'), + ('Maze Race Mirror Spot', 'West Dark World'), + ('Lake Hylia Central Island Mirror Spot', 'Dark Lake Hylia Central Island'), + ('Hammer Peg Area Mirror Spot', 'Hammer Peg Area'), + ('Bumper Cave Ledge Mirror Spot', 'Bumper Cave Ledge'), + ('Bumper Cave Entrance Mirror Spot', 'Bumper Cave Entrance'), + ('Death Mountain Mirror Spot', 'Dark Death Mountain'), + ('East Death Mountain Mirror Spot (Top)', 'Dark Death Mountain'), + ('East Death Mountain Mirror Spot (Bottom)', 'Dark Death Mountain (East Bottom)'), + ('Death Mountain (Top) Mirror Spot', 'Dark Death Mountain'), + ('Dark Death Mountain Ledge Mirror Spot (East)', 'Dark Death Mountain Ledge'), + ('Dark Death Mountain Ledge Mirror Spot (West)', 'Dark Death Mountain Ledge'), + ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Dark World)'), + ('Laser Bridge Mirror Spot', 'Dark Death Mountain Isolated Ledge'), + ('East Dark World Mirror Spot', 'East Dark World'), + ('West Dark World Mirror Spot', 'West Dark World'), + ('South Dark World Mirror Spot', 'South Dark World'), + ('Potion Shop Mirror Spot', 'Northeast Dark World'), + ('Catfish Mirror Spot', 'Catfish'), + ('Shopping Mall Mirror Spot', 'Dark Lake Hylia Ledge'), + ('Skull Woods Mirror Spot', 'Skull Woods Forest (West)'), + ('DDM Flute', 'The Sky'), + ('DDM Landing', 'Dark Death Mountain'), + ('NEDW Flute', 'The Sky'), + ('NEDW Landing', 'Northeast Dark World'), + ('WDW Flute', 'The Sky'), + ('WDW Landing', 'West Dark World'), + ('SDW Flute', 'The Sky'), + ('SDW Landing', 'South Dark World'), + ('EDW Flute', 'The Sky'), + ('EDW Landing', 'East Dark World'), + ('DLHL Flute', 'The Sky'), + ('DLHL Landing', 'Dark Lake Hylia Ledge'), + ('DD Flute', 'The Sky'), + ('DD Landing', 'Dark Desert Ledge'), + ('EDDM Flute', 'The Sky'), + ('Dark Grassy Lawn Flute', 'The Sky'), + ('Hammer Peg Area Flute', 'The Sky'), + ('Bush Covered Lawn Inner Bushes', 'Light World'), + ('Bush Covered Lawn Outer Bushes', 'Bush Covered Lawn'), + ('Bush Covered Lawn Mirror Spot', 'Dark Grassy Lawn'), + ('Bomb Hut Inner Bushes', 'Light World'), + ('Bomb Hut Outer Bushes', 'Bomb Hut Area'), + ('Bomb Hut Mirror Spot', 'West Dark World'), + ('Maze Race Ledge Drop', 'Light World')] + +# non-shuffled entrance links +default_connections = {'Links House': 'Links House', + 'Links House Exit': 'Light World', + 'Waterfall of Wishing': 'Waterfall of Wishing', + 'Blinds Hideout': 'Blinds Hideout', + 'Dam': 'Dam', + 'Lumberjack House': 'Lumberjack House', + 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance', + 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance', + 'Hyrule Castle Secret Entrance Exit': 'Hyrule Castle Courtyard', + 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', + 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', + 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', + 'Light Hype Fairy': 'Swamp Healer Fairy', + 'Desert Fairy': 'Desert Healer Fairy', + 'Kings Grave': 'Kings Grave', + 'Tavern North': 'Tavern', + 'Chicken House': 'Chicken House', + 'Aginahs Cave': 'Aginahs Cave', + 'Sahasrahlas Hut': 'Sahasrahlas Hut', + 'Cave Shop (Lake Hylia)': 'Cave Shop (Lake Hylia)', + 'Capacity Upgrade': 'Capacity Upgrade', + 'Kakariko Well Drop': 'Kakariko Well (top)', + 'Kakariko Well Cave': 'Kakariko Well (bottom)', + 'Kakariko Well Exit': 'Light World', + 'Blacksmiths Hut': 'Blacksmiths Hut', + 'Bat Cave Drop': 'Bat Cave (right)', + 'Bat Cave Cave': 'Bat Cave (left)', + 'Bat Cave Exit': 'Light World', + 'Sick Kids House': 'Sick Kids House', + 'Elder House (East)': 'Elder House', + 'Elder House (West)': 'Elder House', + 'Elder House Exit (East)': 'Light World', + 'Elder House Exit (West)': 'Light World', + 'North Fairy Cave Drop': 'North Fairy Cave', + 'North Fairy Cave': 'North Fairy Cave', + 'North Fairy Cave Exit': 'Light World', + 'Lost Woods Gamble': 'Lost Woods Gamble', + 'Fortune Teller (Light)': 'Fortune Teller (Light)', + 'Snitch Lady (East)': 'Snitch Lady (East)', + 'Snitch Lady (West)': 'Snitch Lady (West)', + 'Bush Covered House': 'Bush Covered House', + 'Tavern (Front)': 'Tavern (Front)', + 'Light World Bomb Hut': 'Light World Bomb Hut', + 'Kakariko Shop': 'Kakariko Shop', + 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', + 'Lost Woods Hideout Stump': 'Lost Woods Hideout (bottom)', + 'Lost Woods Hideout Exit': 'Light World', + 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', + 'Lumberjack Tree Cave': 'Lumberjack Tree (bottom)', + 'Lumberjack Tree Exit': 'Light World', + 'Cave 45': 'Cave 45', + 'Graveyard Cave': 'Graveyard Cave', + 'Checkerboard Cave': 'Checkerboard Cave', + 'Mini Moldorm Cave': 'Mini Moldorm Cave', + 'Long Fairy Cave': 'Long Fairy Cave', # near East Light World Teleporter + 'Good Bee Cave': 'Good Bee Cave', + '20 Rupee Cave': '20 Rupee Cave', + '50 Rupee Cave': '50 Rupee Cave', + 'Ice Rod Cave': 'Ice Rod Cave', + 'Bonk Rock Cave': 'Bonk Rock Cave', + 'Library': 'Library', + 'Kakariko Gamble Game': 'Kakariko Gamble Game', + 'Potion Shop': 'Potion Shop', + 'Two Brothers House (East)': 'Two Brothers House', + 'Two Brothers House (West)': 'Two Brothers House', + 'Two Brothers House Exit (East)': 'Light World', + 'Two Brothers House Exit (West)': 'Maze Race Ledge', + + 'Sanctuary': 'Sanctuary Portal', + 'Sanctuary Grave': 'Sewer Drop', + 'Sanctuary Exit': 'Light World', + + 'Old Man Cave (West)': 'Old Man Cave Ledge', + 'Old Man Cave (East)': 'Old Man Cave', + 'Old Man Cave Exit (West)': 'Light World', + 'Old Man Cave Exit (East)': 'Death Mountain', + 'Old Man House (Bottom)': 'Old Man House', + 'Old Man House Exit (Bottom)': 'Death Mountain', + 'Old Man House (Top)': 'Old Man House Back', + 'Old Man House Exit (Top)': 'Death Mountain', + 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', + 'Death Mountain Return Cave (West)': 'Death Mountain Return Cave (left)', + 'Death Mountain Return Cave Exit (West)': 'Death Mountain Return Ledge', + 'Death Mountain Return Cave Exit (East)': 'Death Mountain', + 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', + 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', + 'Spectacle Rock Cave': 'Spectacle Rock Cave (Top)', + 'Spectacle Rock Cave Exit': 'Death Mountain', + 'Spectacle Rock Cave Exit (Top)': 'Death Mountain', + 'Spectacle Rock Cave Exit (Peak)': 'Death Mountain', + 'Paradox Cave (Bottom)': 'Paradox Cave Front', + 'Paradox Cave (Middle)': 'Paradox Cave', + 'Paradox Cave (Top)': 'Paradox Cave', + 'Paradox Cave Exit (Bottom)': 'East Death Mountain (Bottom)', + 'Paradox Cave Exit (Middle)': 'East Death Mountain (Bottom)', + 'Paradox Cave Exit (Top)': 'East Death Mountain (Top)', + 'Hookshot Fairy': 'Hookshot Fairy', + 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave (Bottom)', + 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave (Top)', + 'Fairy Ascension Cave Exit (Bottom)': 'Fairy Ascension Plateau', + 'Fairy Ascension Cave Exit (Top)': 'Fairy Ascension Ledge', + 'Spiral Cave': 'Spiral Cave (Top)', + 'Spiral Cave (Bottom)': 'Spiral Cave (Bottom)', + 'Spiral Cave Exit': 'East Death Mountain (Bottom)', + 'Spiral Cave Exit (Top)': 'Spiral Cave Ledge', + + 'Pyramid Fairy': 'Pyramid Fairy', + 'East Dark World Hint': 'East Dark World Hint', + 'Palace of Darkness Hint': 'Palace of Darkness Hint', + 'Big Bomb Shop': 'Big Bomb Shop', + 'Dark Lake Hylia Shop': 'Dark Lake Hylia Shop', + 'Dark Lake Hylia Fairy': 'Dark Lake Hylia Healer Fairy', + 'Dark Lake Hylia Ledge Fairy': 'Dark Lake Hylia Ledge Healer Fairy', + 'Dark Lake Hylia Ledge Spike Cave': 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Hint': 'Dark Lake Hylia Ledge Hint', + 'Hype Cave': 'Hype Cave', + 'Bonk Fairy (Dark)': 'Bonk Fairy (Dark)', + 'Brewery': 'Brewery', + 'C-Shaped House': 'C-Shaped House', + 'Chest Game': 'Chest Game', + 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', + 'Bumper Cave (Bottom)': 'Bumper Cave', + 'Bumper Cave (Top)': 'Bumper Cave', + 'Red Shield Shop': 'Red Shield Shop', + 'Dark Sanctuary Hint': 'Dark Sanctuary Hint', + 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', + 'Dark World Shop': 'Village of Outcasts Shop', + 'Dark World Lumberjack Shop': 'Dark World Lumberjack Shop', + 'Dark World Potion Shop': 'Dark World Potion Shop', + 'Archery Game': 'Archery Game', + 'Bumper Cave Exit (Top)': 'Bumper Cave Ledge', + 'Bumper Cave Exit (Bottom)': 'West Dark World', + 'Mire Shed': 'Mire Shed', + 'Dark Desert Hint': 'Dark Desert Hint', + 'Dark Desert Fairy': 'Dark Desert Healer Fairy', + 'Spike Cave': 'Spike Cave', + 'Hookshot Cave': 'Hookshot Cave (Front)', + 'Superbunny Cave (Top)': 'Superbunny Cave (Top)', + 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', + 'Dark Death Mountain Fairy': 'Dark Death Mountain Healer Fairy', + 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', + 'Superbunny Cave Exit (Top)': 'Dark Death Mountain (Top)', + 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', + 'Hookshot Cave Front Exit': 'Dark Death Mountain (Top)', + 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', + 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', + 'Mimic Cave': 'Mimic Cave', + + 'Pyramid Hole': 'Pyramid', + 'Pyramid Exit': 'Pyramid Ledge', + 'Pyramid Entrance': 'Bottom of Pyramid'} + +inverted_default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', + 'Blinds Hideout': 'Blinds Hideout', + 'Dam': 'Dam', + 'Lumberjack House': 'Lumberjack House', + 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance', + 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance', + 'Hyrule Castle Secret Entrance Exit': 'Light World', + 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', + 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', + 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', + 'Light Hype Fairy': 'Swamp Healer Fairy', + 'Desert Fairy': 'Desert Healer Fairy', + 'Kings Grave': 'Kings Grave', + 'Tavern North': 'Tavern', + 'Chicken House': 'Chicken House', + 'Aginahs Cave': 'Aginahs Cave', + 'Sahasrahlas Hut': 'Sahasrahlas Hut', + 'Cave Shop (Lake Hylia)': 'Cave Shop (Lake Hylia)', + 'Capacity Upgrade': 'Capacity Upgrade', + 'Kakariko Well Drop': 'Kakariko Well (top)', + 'Kakariko Well Cave': 'Kakariko Well (bottom)', + 'Kakariko Well Exit': 'Light World', + 'Blacksmiths Hut': 'Blacksmiths Hut', + 'Bat Cave Drop': 'Bat Cave (right)', + 'Bat Cave Cave': 'Bat Cave (left)', + 'Bat Cave Exit': 'Light World', + 'Sick Kids House': 'Sick Kids House', + 'Elder House (East)': 'Elder House', + 'Elder House (West)': 'Elder House', + 'Elder House Exit (East)': 'Light World', + 'Elder House Exit (West)': 'Light World', + 'North Fairy Cave Drop': 'North Fairy Cave', + 'North Fairy Cave': 'North Fairy Cave', + 'North Fairy Cave Exit': 'Light World', + 'Lost Woods Gamble': 'Lost Woods Gamble', + 'Fortune Teller (Light)': 'Fortune Teller (Light)', + 'Snitch Lady (East)': 'Snitch Lady (East)', + 'Snitch Lady (West)': 'Snitch Lady (West)', + 'Bush Covered House': 'Bush Covered House', + 'Tavern (Front)': 'Tavern (Front)', + 'Light World Bomb Hut': 'Light World Bomb Hut', + 'Kakariko Shop': 'Kakariko Shop', + 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', + 'Lost Woods Hideout Stump': 'Lost Woods Hideout (bottom)', + 'Lost Woods Hideout Exit': 'Light World', + 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', + 'Lumberjack Tree Cave': 'Lumberjack Tree (bottom)', + 'Lumberjack Tree Exit': 'Light World', + 'Cave 45': 'Cave 45', + 'Graveyard Cave': 'Graveyard Cave', + 'Checkerboard Cave': 'Checkerboard Cave', + 'Mini Moldorm Cave': 'Mini Moldorm Cave', + 'Long Fairy Cave': 'Long Fairy Cave', + 'Good Bee Cave': 'Good Bee Cave', + '20 Rupee Cave': '20 Rupee Cave', + '50 Rupee Cave': '50 Rupee Cave', + 'Ice Rod Cave': 'Ice Rod Cave', + 'Bonk Rock Cave': 'Bonk Rock Cave', + 'Library': 'Library', + 'Kakariko Gamble Game': 'Kakariko Gamble Game', + 'Potion Shop': 'Potion Shop', + 'Two Brothers House (East)': 'Two Brothers House', + 'Two Brothers House (West)': 'Two Brothers House', + 'Two Brothers House Exit (East)': 'Light World', + 'Two Brothers House Exit (West)': 'Maze Race Ledge', + 'Sanctuary': 'Sanctuary Portal', + 'Sanctuary Grave': 'Sewer Drop', + 'Sanctuary Exit': 'Light World', + 'Old Man House (Bottom)': 'Old Man House', + 'Old Man House Exit (Bottom)': 'Death Mountain', + 'Old Man House (Top)': 'Old Man House Back', + 'Old Man House Exit (Top)': 'Death Mountain', + 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', + 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', + 'Spectacle Rock Cave': 'Spectacle Rock Cave (Top)', + 'Spectacle Rock Cave Exit': 'Death Mountain', + 'Spectacle Rock Cave Exit (Top)': 'Death Mountain', + 'Spectacle Rock Cave Exit (Peak)': 'Death Mountain', + 'Paradox Cave (Bottom)': 'Paradox Cave Front', + 'Paradox Cave (Middle)': 'Paradox Cave', + 'Paradox Cave (Top)': 'Paradox Cave', + 'Paradox Cave Exit (Bottom)': 'East Death Mountain (Bottom)', + 'Paradox Cave Exit (Middle)': 'East Death Mountain (Bottom)', + 'Paradox Cave Exit (Top)': 'East Death Mountain (Top)', + 'Hookshot Fairy': 'Hookshot Fairy', + 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave (Bottom)', + 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave (Top)', + 'Fairy Ascension Cave Exit (Bottom)': 'Fairy Ascension Plateau', + 'Fairy Ascension Cave Exit (Top)': 'Fairy Ascension Ledge', + 'Spiral Cave': 'Spiral Cave (Top)', + 'Spiral Cave (Bottom)': 'Spiral Cave (Bottom)', + 'Spiral Cave Exit': 'East Death Mountain (Bottom)', + 'Spiral Cave Exit (Top)': 'Spiral Cave Ledge', + 'Pyramid Fairy': 'Pyramid Fairy', + 'East Dark World Hint': 'East Dark World Hint', + 'Palace of Darkness Hint': 'Palace of Darkness Hint', + 'Dark Lake Hylia Shop': 'Dark Lake Hylia Shop', + 'Dark Lake Hylia Fairy': 'Dark Lake Hylia Healer Fairy', + 'Dark Lake Hylia Ledge Fairy': 'Dark Lake Hylia Ledge Healer Fairy', + 'Dark Lake Hylia Ledge Spike Cave': 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Lake Hylia Ledge Hint': 'Dark Lake Hylia Ledge Hint', + 'Hype Cave': 'Hype Cave', + 'Bonk Fairy (Dark)': 'Bonk Fairy (Dark)', + 'Brewery': 'Brewery', + 'C-Shaped House': 'C-Shaped House', + 'Chest Game': 'Chest Game', + 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', + 'Red Shield Shop': 'Red Shield Shop', + 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', + 'Dark World Shop': 'Village of Outcasts Shop', + 'Dark World Lumberjack Shop': 'Dark World Lumberjack Shop', + 'Dark World Potion Shop': 'Dark World Potion Shop', + 'Archery Game': 'Archery Game', + 'Mire Shed': 'Mire Shed', + 'Dark Desert Hint': 'Dark Desert Hint', + 'Dark Desert Fairy': 'Dark Desert Healer Fairy', + 'Spike Cave': 'Spike Cave', + 'Hookshot Cave': 'Hookshot Cave (Front)', + 'Superbunny Cave (Top)': 'Superbunny Cave (Top)', + 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', + 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', + 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', + 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', + 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', + 'Mimic Cave': 'Mimic Cave', + 'Inverted Pyramid Hole': 'Pyramid', + 'Inverted Links House': 'Inverted Links House', + 'Inverted Links House Exit': 'South Dark World', + 'Inverted Big Bomb Shop': 'Inverted Big Bomb Shop', + 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary', + 'Inverted Dark Sanctuary Exit': 'West Dark World', + 'Old Man Cave (West)': 'Bumper Cave', + 'Old Man Cave (East)': 'Death Mountain Return Cave (left)', + 'Old Man Cave Exit (West)': 'West Dark World', + 'Old Man Cave Exit (East)': 'Dark Death Mountain', + 'Dark Death Mountain Fairy': 'Old Man Cave', + 'Bumper Cave (Bottom)': 'Old Man Cave Ledge', + 'Bumper Cave (Top)': 'Dark Death Mountain Healer Fairy', + 'Bumper Cave Exit (Top)': 'Death Mountain Return Ledge', + 'Bumper Cave Exit (Bottom)': 'Light World', + 'Death Mountain Return Cave (West)': 'Bumper Cave', + 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', + 'Death Mountain Return Cave Exit (West)': 'Death Mountain', + 'Death Mountain Return Cave Exit (East)': 'Death Mountain', + 'Hookshot Cave Front Exit': 'Dark Death Mountain', + 'Superbunny Cave Exit (Top)': 'Dark Death Mountain', + 'Pyramid Exit': 'Light World', + 'Inverted Pyramid Entrance': 'Bottom of Pyramid'} + +# non shuffled dungeons +default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), + ('Desert Palace Entrance (West)', 'Desert West Portal'), + ('Desert Palace Entrance (North)', 'Desert Back Portal'), + ('Desert Palace Entrance (East)', 'Desert East Portal'), + ('Desert Palace Exit (South)', 'Desert Palace Stairs'), + ('Desert Palace Exit (West)', 'Desert Ledge'), + ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), + ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), + + ('Eastern Palace', 'Eastern Portal'), + ('Eastern Palace Exit', 'Light World'), + ('Tower of Hera', 'Hera Portal'), + ('Tower of Hera Exit', 'Death Mountain (Top)'), + + ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), + ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), + ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), + ('Hyrule Castle Exit (South)', 'Hyrule Castle Courtyard'), + ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), + ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), + ('Agahnims Tower', 'Agahnims Tower Portal'), + ('Agahnims Tower Exit', 'Hyrule Castle Ledge'), + + ('Thieves Town', 'Thieves Town Portal'), + ('Thieves Town Exit', 'West Dark World'), + ('Skull Woods First Section Hole (East)', 'Skull Pinball'), + ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), + ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), + ('Skull Woods First Section Door', 'Skull 1 Portal'), + ('Skull Woods First Section Exit', 'Skull Woods Forest'), + ('Skull Woods Second Section Hole', 'Skull Back Drop'), + ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), + ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), + ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), + ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), + ('Skull Woods Final Section', 'Skull 3 Portal'), + ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), + ('Ice Palace', 'Ice Portal'), + ('Ice Palace Exit', 'Dark Lake Hylia Central Island'), + ('Misery Mire', 'Mire Portal'), + ('Misery Mire Exit', 'Dark Desert'), + ('Palace of Darkness', 'Palace of Darkness Portal'), + ('Palace of Darkness Exit', 'East Dark World'), + ('Swamp Palace', 'Swamp Portal'), # requires additional patch for flooding moat if moved + ('Swamp Palace Exit', 'South Dark World'), + + ('Turtle Rock', 'Turtle Rock Main Portal'), + ('Turtle Rock Exit (Front)', 'Dark Death Mountain (Top)'), + ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), + ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), + ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), + ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), + ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), + ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), + + ('Ganons Tower', 'Ganons Tower Portal'), + ('Ganons Tower Exit', 'Dark Death Mountain (Top)') + ] + +inverted_default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), + ('Desert Palace Entrance (West)', 'Desert West Portal'), + ('Desert Palace Entrance (North)', 'Desert Back Portal'), + ('Desert Palace Entrance (East)', 'Desert East Portal'), + ('Desert Palace Exit (South)', 'Desert Palace Stairs'), + ('Desert Palace Exit (West)', 'Desert Ledge'), + ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), + ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), + ('Eastern Palace', 'Eastern Portal'), + ('Eastern Palace Exit', 'Light World'), + ('Tower of Hera', 'Hera Portal'), + ('Tower of Hera Exit', 'Death Mountain (Top)'), + ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), + ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), + ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), + ('Hyrule Castle Exit (South)', 'Light World'), + ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), + ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), + ('Thieves Town', 'Thieves Town Portal'), + ('Thieves Town Exit', 'West Dark World'), + ('Skull Woods First Section Hole (East)', 'Skull Pinball'), + ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), + ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), + ('Skull Woods First Section Door', 'Skull 1 Portal'), + ('Skull Woods First Section Exit', 'Skull Woods Forest'), + ('Skull Woods Second Section Hole', 'Skull Back Drop'), + ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), + ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), + ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), + ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), + ('Skull Woods Final Section', 'Skull 3 Portal'), + ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), + ('Ice Palace', 'Ice Portal'), + ('Misery Mire', 'Mire Portal'), + ('Misery Mire Exit', 'Dark Desert'), + ('Palace of Darkness', 'Palace of Darkness Portal'), + ('Palace of Darkness Exit', 'East Dark World'), + # requires additional patch for flooding moat if moved + ('Swamp Palace', 'Swamp Portal'), + ('Swamp Palace Exit', 'South Dark World'), + ('Turtle Rock', 'Turtle Rock Main Portal'), + ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), + ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), + ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), + ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), + ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), + ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), + ('Inverted Ganons Tower', 'Ganons Tower Portal'), + ('Inverted Ganons Tower Exit', 'Hyrule Castle Ledge'), + ('Inverted Agahnims Tower', 'Agahnims Tower Portal'), + ('Inverted Agahnims Tower Exit', 'Dark Death Mountain'), + ('Turtle Rock Exit (Front)', 'Dark Death Mountain'), + ('Ice Palace Exit', 'Dark Lake Hylia') + ] + +indirect_connections = { + 'Turtle Rock (Top)': 'Turtle Rock', + 'East Dark World': 'Pyramid Fairy', + 'Big Bomb Shop': 'Pyramid Fairy', + 'Dark Desert': 'Pyramid Fairy', + 'West Dark World': 'Pyramid Fairy', + 'South Dark World': 'Pyramid Fairy', + 'Light World': 'Pyramid Fairy', + 'Old Man Cave': 'Old Man S&Q' +} +# format: +# Key=Name +# addr = (door_index, exitdata) # multiexit +# | ([addr], None) # holes +# exitdata = (room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2) + +# ToDo somehow merge this with creation of the locations +door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), + 'Inverted Big Bomb Shop': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), + 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000)), + 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000)), + 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000)), + 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000)), + 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), + 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000)), + 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be)), + 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124)), + 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158)), + 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x0418, 0x0679, 0x06b4, 0x06c6, 0x0728, 0x06e6, 0x0733, 0x07, 0xf9, 0x0000, 0x0000)), + 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), + 'Inverted Ganons Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), + 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000)), + 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000)), + 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000)), + 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000)), + 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000)), + 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000)), + 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000)), + 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), + 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000)), + 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000)), + 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000)), + 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), + 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), + 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000)), + 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000)), + 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000)), + 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000)), + 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000)), + 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000)), + 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000)), + 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000)), + 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000)), + 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000)), + 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa)), + 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000)), + 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000)), + 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000)), + 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000)), + 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000)), + 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), + 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), + 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), + 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000)), + 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), + 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), + 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), + 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), + 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000)), + 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000)), + 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000)), + 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), + 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000)), + 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), + 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), + 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000)), + 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000)), + 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)), + 'Inverted Agahnims Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)), + 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000)), + 'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None), + 'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None), + 'Skull Woods First Section Hole (North)': ([0xDB84C], None), + 'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None), + 'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None), + 'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None), + 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), + 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000)), + 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000)), + 'Hyrule Castle Secret Entrance Drop': ([0xDB858], None), + 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000)), + 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), + 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000)), + 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x08f9, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), # do not use, buggy + 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000)), + 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000)), + 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000)), + 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None), + 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000)), + 'Bat Cave Drop': ([0xDB859, 0xDB85A], None), + 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000)), + 'North Fairy Cave Drop': ([0xDB857], None), + 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000)), + 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000)), + 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000)), + 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000)), + 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000)), + 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000)), + 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000)), + 'Lost Woods Hideout Drop': ([0xDB853], None), + 'Lumberjack Tree Tree': ([0xDB85B], None), + 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000)), + 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000)), + 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000)), + 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000)), + 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), + 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), + '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000)), + '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000)), + 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), + 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000)), + 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000)), + 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000)), + 'Sanctuary Grave': ([0xDB85E], None), + 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), + 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000)), + 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), + 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), + 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), + 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000)), + 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), + 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000)), + 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000)), + 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000)), + 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000)), + 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000)), + 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000)), + 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000)), + 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), + 'Inverted Dark Sanctuary': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), + 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000)), + 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000)), + 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000)), + 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000)), + 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000)), + 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), + 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000)), + 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), + 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), + 'Inverted Links House': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), + 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), + 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000)), + 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), + 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000))} + +# format: +# Key=Name +# value = entrance # +# | (entrance #, exit #) +exit_ids = {'Links House Exit': (0x01, 0x00), + 'Inverted Links House Exit': (0x01, 0x00), + 'Chris Houlihan Room Exit': (None, 0x3D), + 'Desert Palace Exit (South)': (0x09, 0x0A), + 'Desert Palace Exit (West)': (0x0B, 0x0C), + 'Desert Palace Exit (East)': (0x0A, 0x0B), + 'Desert Palace Exit (North)': (0x0C, 0x0D), + 'Eastern Palace Exit': (0x08, 0x09), + 'Tower of Hera Exit': (0x33, 0x2D), + 'Hyrule Castle Exit (South)': (0x04, 0x03), + 'Hyrule Castle Exit (West)': (0x03, 0x02), + 'Hyrule Castle Exit (East)': (0x05, 0x04), + 'Agahnims Tower Exit': (0x24, 0x25), + 'Inverted Agahnims Tower Exit': (0x24, 0x25), + 'Thieves Town Exit': (0x34, 0x35), + 'Skull Woods First Section Exit': (0x2A, 0x2B), + 'Skull Woods Second Section Exit (East)': (0x29, 0x2A), + 'Skull Woods Second Section Exit (West)': (0x28, 0x29), + 'Skull Woods Final Section Exit': (0x2B, 0x2C), + 'Ice Palace Exit': (0x2D, 0x2E), + 'Misery Mire Exit': (0x27, 0x28), + 'Palace of Darkness Exit': (0x26, 0x27), + 'Swamp Palace Exit': (0x25, 0x26), + 'Turtle Rock Exit (Front)': (0x35, 0x34), + 'Turtle Rock Ledge Exit (West)': (0x15, 0x16), + 'Turtle Rock Ledge Exit (East)': (0x19, 0x1A), + 'Turtle Rock Isolated Ledge Exit': (0x18, 0x19), + 'Hyrule Castle Secret Entrance Exit': (0x32, 0x33), + 'Kakariko Well Exit': (0x39, 0x3A), + 'Bat Cave Exit': (0x11, 0x12), + 'Elder House Exit (East)': (0x0E, 0x0F), + 'Elder House Exit (West)': (0x0D, 0x0E), + 'North Fairy Cave Exit': (0x38, 0x39), + 'Lost Woods Hideout Exit': (0x2C, 0x36), + 'Lumberjack Tree Exit': (0x12, 0x13), + 'Two Brothers House Exit (East)': (0x10, 0x11), + 'Two Brothers House Exit (West)': (0x0F, 0x10), + 'Sanctuary Exit': (0x02, 0x01), + 'Old Man Cave Exit (East)': (0x07, 0x08), + 'Old Man Cave Exit (West)': (0x06, 0x07), + 'Old Man House Exit (Bottom)': (0x30, 0x31), + 'Old Man House Exit (Top)': (0x31, 0x32), + 'Death Mountain Return Cave Exit (West)': (0x2E, 0x2F), + 'Death Mountain Return Cave Exit (East)': (0x2F, 0x30), + 'Spectacle Rock Cave Exit': (0x21, 0x22), + 'Spectacle Rock Cave Exit (Top)': (0x22, 0x23), + 'Spectacle Rock Cave Exit (Peak)': (0x23, 0x24), + 'Paradox Cave Exit (Bottom)': (0x1E, 0x1F), + 'Paradox Cave Exit (Middle)': (0x1F, 0x20), + 'Paradox Cave Exit (Top)': (0x20, 0x21), + 'Fairy Ascension Cave Exit (Bottom)': (0x1A, 0x1B), + 'Fairy Ascension Cave Exit (Top)': (0x1B, 0x1C), + 'Spiral Cave Exit': (0x1C, 0x1D), + 'Spiral Cave Exit (Top)': (0x1D, 0x1E), + 'Bumper Cave Exit (Top)': (0x17, 0x18), + 'Bumper Cave Exit (Bottom)': (0x16, 0x17), + 'Superbunny Cave Exit (Top)': (0x14, 0x15), + 'Superbunny Cave Exit (Bottom)': (0x13, 0x14), + 'Hookshot Cave Front Exit': (0x3A, 0x3B), + 'Hookshot Cave Back Exit': (0x3B, 0x3C), + 'Ganons Tower Exit': (0x37, 0x38), + 'Inverted Ganons Tower Exit': (0x37, 0x38), + 'Pyramid Exit': (0x36, 0x37), + 'Waterfall of Wishing': 0x5C, + 'Dam': 0x4E, + 'Blinds Hideout': 0x61, + 'Lumberjack House': 0x6B, + 'Bonk Fairy (Light)': 0x71, + 'Bonk Fairy (Dark)': 0x71, + 'Lake Hylia Healer Fairy': 0x5E, + 'Swamp Healer Fairy': 0x5E, + 'Desert Healer Fairy': 0x5E, + 'Dark Lake Hylia Healer Fairy': 0x5E, + 'Dark Lake Hylia Ledge Healer Fairy': 0x5E, + 'Dark Desert Healer Fairy': 0x5E, + 'Dark Death Mountain Healer Fairy': 0x5E, + 'Fortune Teller (Light)': 0x65, + 'Lake Hylia Fortune Teller': 0x65, + 'Kings Grave': 0x5B, + 'Tavern': 0x43, + 'Chicken House': 0x4B, + 'Aginahs Cave': 0x4D, + 'Sahasrahlas Hut': 0x45, + 'Cave Shop (Lake Hylia)': 0x58, + 'Cave Shop (Dark Death Mountain)': 0x58, + 'Capacity Upgrade': 0x5D, + 'Blacksmiths Hut': 0x64, + 'Sick Kids House': 0x40, + 'Lost Woods Gamble': 0x3C, + 'Snitch Lady (East)': 0x3E, + 'Snitch Lady (West)': 0x3F, + 'Bush Covered House': 0x44, + 'Tavern (Front)': 0x42, + 'Light World Bomb Hut': 0x4A, + 'Kakariko Shop': 0x46, + 'Cave 45': 0x51, + 'Graveyard Cave': 0x52, + 'Checkerboard Cave': 0x72, + 'Mini Moldorm Cave': 0x6C, + 'Long Fairy Cave': 0x55, + 'Good Bee Cave': 0x56, + '20 Rupee Cave': 0x6F, + '50 Rupee Cave': 0x6D, + 'Ice Rod Cave': 0x84, + 'Bonk Rock Cave': 0x6E, + 'Library': 0x49, + 'Kakariko Gamble Game': 0x67, + 'Potion Shop': 0x4C, + 'Hookshot Fairy': 0x50, + 'Pyramid Fairy': 0x63, + 'East Dark World Hint': 0x69, + 'Palace of Darkness Hint': 0x68, + 'Big Bomb Shop': 0x53, + 'Inverted Big Bomb Shop': 0x53, + 'Village of Outcasts Shop': 0x60, + 'Dark Lake Hylia Shop': 0x60, + 'Dark World Lumberjack Shop': 0x60, + 'Dark World Potion Shop': 0x60, + 'Dark Lake Hylia Ledge Spike Cave': 0x70, + 'Dark Lake Hylia Ledge Hint': 0x6A, + 'Hype Cave': 0x3D, + 'Brewery': 0x48, + 'C-Shaped House': 0x54, + 'Chest Game': 0x47, + 'Dark World Hammer Peg Cave': 0x83, + 'Red Shield Shop': 0x57, + 'Dark Sanctuary Hint': 0x5A, + 'Inverted Dark Sanctuary': 0x5A, + 'Fortune Teller (Dark)': 0x66, + 'Archery Game': 0x59, + 'Mire Shed': 0x5F, + 'Dark Desert Hint': 0x62, + 'Spike Cave': 0x41, + 'Mimic Cave': 0x4F, + 'Kakariko Well (top)': 0x80, + 'Hyrule Castle Secret Entrance': 0x7D, + 'Bat Cave (right)': 0x7E, + 'North Fairy Cave': 0x7C, + 'Lost Woods Hideout (top)': 0x7A, + 'Lumberjack Tree (top)': 0x7F, + 'Sewer Drop': 0x81, + 'Skull Back Drop': 0x79, + 'Skull Left Drop': 0x77, + 'Skull Pinball': 0x78, + 'Skull Pot Circle': 0x76, + 'Pyramid': 0x7B} + +ow_prize_table = {'Links House': (0x8b1, 0xb2d), 'Inverted Big Bomb Shop': (0x8b1, 0xb2d), + 'Desert Palace Entrance (South)': (0x108, 0xd70), 'Desert Palace Entrance (West)': (0x031, 0xca0), + 'Desert Palace Entrance (North)': (0x0e1, 0xba0), 'Desert Palace Entrance (East)': (0x191, 0xca0), + 'Eastern Palace': (0xf31, 0x620), 'Tower of Hera': (0x8D0, 0x080), + 'Hyrule Castle Entrance (South)': (0x7b0, 0x730), 'Hyrule Castle Entrance (West)': (0x700, 0x640), + 'Hyrule Castle Entrance (East)': (0x8a0, 0x640), 'Inverted Pyramid Entrance': (0x720, 0x700), + 'Agahnims Tower': (0x7e0, 0x640), 'Inverted Ganons Tower': (0x7e0, 0x640), + 'Thieves Town': (0x1d0, 0x780), 'Skull Woods First Section Door': (0x240, 0x280), + 'Skull Woods Second Section Door (East)': (0x1a0, 0x240), + 'Skull Woods Second Section Door (West)': (0x0c0, 0x1c0), 'Skull Woods Final Section': (0x082, 0x0b0), + 'Ice Palace': (0xca0, 0xda0), + 'Misery Mire': (0x100, 0xca0), + 'Palace of Darkness': (0xf40, 0x620), 'Swamp Palace': (0x759, 0xED0), + 'Turtle Rock': (0xf11, 0x103), + 'Dark Death Mountain Ledge (West)': (0xb80, 0x180), + 'Dark Death Mountain Ledge (East)': (0xc80, 0x180), + 'Turtle Rock Isolated Ledge Entrance': (0xc00, 0x240), + 'Hyrule Castle Secret Entrance Stairs': (0x850, 0x700), + 'Kakariko Well Cave': (0x060, 0x680), + 'Bat Cave Cave': (0x540, 0x8f0), + 'Elder House (East)': (0x2b0, 0x6a0), + 'Elder House (West)': (0x230, 0x6a0), + 'North Fairy Cave': (0xa80, 0x440), + 'Lost Woods Hideout Stump': (0x240, 0x280), + 'Lumberjack Tree Cave': (0x4e0, 0x004), + 'Two Brothers House (East)': (0x200, 0x0b60), + 'Two Brothers House (West)': (0x180, 0x0b60), + 'Sanctuary': (0x720, 0x4a0), + 'Old Man Cave (West)': (0x580, 0x2c0), + 'Old Man Cave (East)': (0x620, 0x2c0), + 'Old Man House (Bottom)': (0x720, 0x320), + 'Old Man House (Top)': (0x820, 0x220), + 'Death Mountain Return Cave (East)': (0x600, 0x220), + 'Death Mountain Return Cave (West)': (0x500, 0x1c0), + 'Spectacle Rock Cave Peak': (0x720, 0x0a0), + 'Spectacle Rock Cave': (0x790, 0x1a0), + 'Spectacle Rock Cave (Bottom)': (0x710, 0x0a0), + 'Paradox Cave (Bottom)': (0xd80, 0x180), + 'Paradox Cave (Middle)': (0xd80, 0x380), + 'Paradox Cave (Top)': (0xd80, 0x020), + 'Fairy Ascension Cave (Bottom)': (0xcc8, 0x2a0), + 'Fairy Ascension Cave (Top)': (0xc00, 0x240), + 'Spiral Cave': (0xb80, 0x180), + 'Spiral Cave (Bottom)': (0xb80, 0x2c0), + 'Bumper Cave (Bottom)': (0x580, 0x2c0), + 'Bumper Cave (Top)': (0x500, 0x1c0), + 'Superbunny Cave (Top)': (0xd80, 0x020), + 'Superbunny Cave (Bottom)': (0xd00, 0x180), + 'Hookshot Cave': (0xc80, 0x0c0), + 'Hookshot Cave Back Entrance': (0xcf0, 0x004), + 'Ganons Tower': (0x8D0, 0x080), + 'Inverted Agahnims Tower': (0x8D0, 0x080), + 'Pyramid Entrance': (0x640, 0x7c0), + 'Skull Woods First Section Hole (West)': None, + 'Skull Woods First Section Hole (East)': None, + 'Skull Woods First Section Hole (North)': None, + 'Skull Woods Second Section Hole': None, + 'Pyramid Hole': None, + 'Inverted Pyramid Hole': None, + 'Waterfall of Wishing': (0xe80, 0x280), + 'Dam': (0x759, 0xED0), + 'Blinds Hideout': (0x190, 0x6c0), + 'Hyrule Castle Secret Entrance Drop': None, + 'Bonk Fairy (Light)': (0x740, 0xa80), + 'Lake Hylia Fairy': (0xd40, 0x9f0), + 'Light Hype Fairy': (0x940, 0xc80), + 'Desert Fairy': (0x420, 0xe00), + 'Kings Grave': (0x920, 0x520), + 'Tavern North': None, # can't mark this one technically + 'Chicken House': (0x120, 0x880), + 'Aginahs Cave': (0x2e0, 0xd00), + 'Sahasrahlas Hut': (0xcf0, 0x6c0), + 'Cave Shop (Lake Hylia)': (0xbc0, 0xc00), + 'Capacity Upgrade': (0xca0, 0xda0), + 'Kakariko Well Drop': None, + 'Blacksmiths Hut': (0x4a0, 0x880), + 'Bat Cave Drop': None, + 'Sick Kids House': (0x220, 0x880), + 'North Fairy Cave Drop': None, + 'Lost Woods Gamble': (0x240, 0x080), + 'Fortune Teller (Light)': (0x2c0, 0x4c0), + 'Snitch Lady (East)': (0x310, 0x7a0), + 'Snitch Lady (West)': (0x800, 0x7a0), + 'Bush Covered House': (0x2e0, 0x880), + 'Tavern (Front)': (0x270, 0x980), + 'Light World Bomb Hut': (0x070, 0x980), + 'Kakariko Shop': (0x170, 0x980), + 'Lost Woods Hideout Drop': None, + 'Lumberjack Tree Tree': None, + 'Cave 45': (0x440, 0xca0), 'Graveyard Cave': (0x8f0, 0x430), + 'Checkerboard Cave': (0x260, 0xc00), + 'Mini Moldorm Cave': (0xa40, 0xe80), + 'Long Fairy Cave': (0xf60, 0xb00), + 'Good Bee Cave': (0xec0, 0xc00), + '20 Rupee Cave': (0xe80, 0xca0), + '50 Rupee Cave': (0x4d0, 0xed0), + 'Ice Rod Cave': (0xe00, 0xc00), + 'Bonk Rock Cave': (0x5f0, 0x460), + 'Library': (0x270, 0xaa0), + 'Potion Shop': (0xc80, 0x4c0), + 'Sanctuary Grave': None, + 'Hookshot Fairy': (0xd00, 0x180), + 'Pyramid Fairy': (0x740, 0x740), + 'East Dark World Hint': (0xf60, 0xb00), + 'Palace of Darkness Hint': (0xd60, 0x7c0), + 'Dark Lake Hylia Fairy': (0xd40, 0x9f0), + 'Dark Lake Hylia Ledge Fairy': (0xe00, 0xc00), + 'Dark Lake Hylia Ledge Spike Cave': (0xe80, 0xca0), + 'Dark Lake Hylia Ledge Hint': (0xec0, 0xc00), + 'Hype Cave': (0x940, 0xc80), + 'Bonk Fairy (Dark)': (0x740, 0xa80), + 'Brewery': (0x170, 0x980), 'C-Shaped House': (0x310, 0x7a0), 'Chest Game': (0x800, 0x7a0), + 'Dark World Hammer Peg Cave': (0x4c0, 0x940), + 'Red Shield Shop': (0x500, 0x680), + 'Dark Sanctuary Hint': (0x720, 0x4a0), + 'Inverted Dark Sanctuary': (0x720, 0x4a0), + 'Fortune Teller (Dark)': (0x2c0, 0x4c0), + 'Dark World Shop': (0x2e0, 0x880), + 'Dark World Lumberjack Shop': (0x4e0, 0x0d0), + 'Dark World Potion Shop': (0xc80, 0x4c0), + 'Archery Game': (0x2f0, 0xaf0), + 'Mire Shed': (0x060, 0xc90), + 'Dark Desert Hint': (0x2e0, 0xd00), + 'Dark Desert Fairy': (0x1c0, 0xc90), + 'Spike Cave': (0x860, 0x180), + 'Cave Shop (Dark Death Mountain)': (0xd80, 0x180), + 'Dark Death Mountain Fairy': (0x620, 0x2c0), + 'Mimic Cave': (0xc80, 0x180), + 'Big Bomb Shop': (0x8b1, 0xb2d), 'Inverted Links House': (0x8b1, 0xb2d), + 'Dark Lake Hylia Shop': (0xa40, 0xc40), + 'Lumberjack House': (0x4e0, 0x0d0), + 'Lake Hylia Fortune Teller': (0xa40, 0xc40), + 'Kakariko Gamble Game': (0x2f0, 0xaf0)} diff --git a/source/test/__init__.py b/source/overworld/__init__.py similarity index 100% rename from source/test/__init__.py rename to source/overworld/__init__.py diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py new file mode 100644 index 00000000..6cc1d4ff --- /dev/null +++ b/source/tools/MysteryUtils.py @@ -0,0 +1,190 @@ +import argparse +import RaceRandom as random + +import urllib.request +import urllib.parse +import yaml + + +def get_weights(path): + try: + if urllib.parse.urlparse(path).scheme: + return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) + with open(path, 'r', encoding='utf-8') as f: + return yaml.load(f, Loader=yaml.SafeLoader) + except Exception as e: + raise Exception(f'Failed to read weights file: {e}') + + +def roll_settings(weights): + def get_choice(option, root=None): + root = weights if root is None else root + if option not in root: + return None + if type(root[option]) is not dict: + return root[option] + if not root[option]: + return None + return random.choices(list(root[option].keys()), weights=list(map(int, root[option].values())))[0] + + def get_choice_default(option, root=weights, default=None): + choice = get_choice(option, root) + if choice is None and default is not None: + return default + return choice + + while True: + subweights = weights.get('subweights', {}) + if len(subweights) == 0: + break + chances = ({k: int(v['chance']) for (k, v) in subweights.items()}) + subweight_name = random.choices(list(chances.keys()), weights=list(chances.values()))[0] + subweights = weights.get('subweights', {}).get(subweight_name, {}).get('weights', {}) + subweights['subweights'] = subweights.get('subweights', {}) + weights = {**weights, **subweights} + + ret = argparse.Namespace() + + ret.algorithm = get_choice('algorithm') + ret.mystery = get_choice_default('mystery', default=True) + + glitch_map = {'none': 'noglitches', 'no_logic': 'nologic', 'owglitches': 'owglitches', + 'minorglitches': 'minorglitches'} + glitches_required = get_choice('glitches_required') + if glitches_required is not None: + if glitches_required not in glitch_map.keys(): + print(f'Logic did not match one of: {", ".join(glitch_map.keys())}') + glitches_required = 'none' + ret.logic = glitch_map[glitches_required] + + # item_placement = get_choice('item_placement') + # not supported in ER + + dungeon_items = get_choice('dungeon_items') + dungeon_items = '' if dungeon_items == 'standard' or dungeon_items is None else dungeon_items + dungeon_items = 'mcsb' if dungeon_items == 'full' else dungeon_items + ret.mapshuffle = get_choice('map_shuffle') == 'on' if 'map_shuffle' in weights else 'm' in dungeon_items + ret.compassshuffle = get_choice('compass_shuffle') == 'on' if 'compass_shuffle' in weights else 'c' in dungeon_items + ret.keyshuffle = get_choice('smallkey_shuffle') == 'on' if 'smallkey_shuffle' in weights else 's' in dungeon_items + ret.bigkeyshuffle = get_choice('bigkey_shuffle') == 'on' if 'bigkey_shuffle' in weights else 'b' in dungeon_items + + ret.accessibility = get_choice('accessibility') + ret.restrict_boss_items = get_choice('restrict_boss_items') + + entrance_shuffle = get_choice('entrance_shuffle') + ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla' + overworld_map = get_choice('overworld_map') + ret.overworld_map = overworld_map if overworld_map != 'default' else 'default' + door_shuffle = get_choice('door_shuffle') + ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla' + ret.intensity = get_choice('intensity') + ret.experimental = get_choice('experimental') == 'on' + ret.collection_rate = get_choice('collection_rate') == 'on' + + ret.dungeon_counters = get_choice('dungeon_counters') if 'dungeon_counters' in weights else 'default' + if ret.dungeon_counters == 'default': + ret.dungeon_counters = 'pickup' if ret.door_shuffle != 'vanilla' or ret.compassshuffle == 'on' else 'off' + + ret.shufflelinks = get_choice('shufflelinks') == 'on' + ret.pseudoboots = get_choice('pseudoboots') == 'on' + ret.shopsanity = get_choice('shopsanity') == 'on' + keydropshuffle = get_choice('keydropshuffle') == 'on' + ret.dropshuffle = get_choice('dropshuffle') == 'on' or keydropshuffle + ret.pottery = get_choice('pottery') if 'pottery' in weights else 'none' + ret.pottery = 'keys' if ret.pottery == 'none' and keydropshuffle else ret.pottery + ret.shufflepots = get_choice('pot_shuffle') == 'on' + ret.mixed_travel = get_choice('mixed_travel') if 'mixed_travel' in weights else 'prevent' + ret.standardize_palettes = (get_choice('standardize_palettes') if 'standardize_palettes' in weights + else 'standardize') + + goal = get_choice('goals') + if goal is not None: + ret.goal = {'ganon': 'ganon', + 'fast_ganon': 'crystals', + 'dungeons': 'dungeons', + 'pedestal': 'pedestal', + 'triforce-hunt': 'triforcehunt' + }[goal] + ret.openpyramid = goal == 'fast_ganon' if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False + + ret.crystals_gt = get_choice('tower_open') + + ret.crystals_ganon = get_choice('ganon_open') + + goal_min = get_choice_default('triforce_goal_min', default=20) + goal_max = get_choice_default('triforce_goal_max', default=20) + pool_min = get_choice_default('triforce_pool_min', default=30) + pool_max = get_choice_default('triforce_pool_max', default=30) + ret.triforce_goal = random.randint(int(goal_min), int(goal_max)) + min_diff = get_choice_default('triforce_min_difference', default=10) + ret.triforce_pool = random.randint(max(int(pool_min), ret.triforce_goal + int(min_diff)), int(pool_max)) + + ret.mode = get_choice('world_state') + if ret.mode == 'retro': + ret.mode = 'open' + ret.retro = True + ret.retro = get_choice('retro') == 'on' # this overrides world_state if used + + ret.bombbag = get_choice('bombbag') == 'on' + + ret.hints = get_choice('hints') == 'on' + + swords = get_choice('weapons') + if swords is not None: + ret.swords = {'randomized': 'random', + 'assured': 'assured', + 'vanilla': 'vanilla', + 'swordless': 'swordless' + }[swords] + + ret.difficulty = get_choice('item_pool') + + ret.item_functionality = get_choice('item_functionality') + + old_style_bosses = {'basic': 'simple', + 'normal': 'full', + 'chaos': 'random'} + boss_choice = get_choice('boss_shuffle') + if boss_choice in old_style_bosses.keys(): + boss_choice = old_style_bosses[boss_choice] + ret.shufflebosses = boss_choice + + enemy_choice = get_choice('enemy_shuffle') + if enemy_choice == 'chaos': + enemy_choice = 'random' + ret.shuffleenemies = enemy_choice + + old_style_damage = {'none': 'default', + 'chaos': 'random'} + damage_choice = get_choice('enemy_damage') + if damage_choice in old_style_damage: + damage_choice = old_style_damage[damage_choice] + ret.enemy_damage = damage_choice + + ret.enemy_health = get_choice('enemy_health') + + ret.beemizer = get_choice('beemizer') if 'beemizer' in weights else '0' + + inventoryweights = weights.get('startinventory', {}) + startitems = [] + for item in inventoryweights.keys(): + if get_choice(item, inventoryweights) == 'on': + startitems.append(item) + ret.startinventory = ','.join(startitems) + if len(startitems) > 0: + ret.usestartinventory = True + + if 'rom' in weights: + romweights = weights['rom'] + ret.sprite = get_choice('sprite', romweights) + ret.disablemusic = get_choice('disablemusic', romweights) == 'on' + ret.quickswap = get_choice('quickswap', romweights) == 'on' + ret.reduce_flashing = get_choice('reduce_flashing', romweights) == 'on' + ret.fastmenu = get_choice('menuspeed', romweights) + ret.heartcolor = get_choice('heartcolor', romweights) + ret.heartbeep = get_choice('heartbeep', romweights) + ret.ow_palettes = get_choice('ow_palettes', romweights) + ret.uw_palettes = get_choice('uw_palettes', romweights) + ret.shuffle_sfx = get_choice('shuffle_sfx', romweights) == 'on' + + return ret diff --git a/source/test/MysteryTestSuite.py b/test/MysteryTestSuite.py similarity index 100% rename from source/test/MysteryTestSuite.py rename to test/MysteryTestSuite.py diff --git a/test/stats/EntranceShuffleStats.py b/test/stats/EntranceShuffleStats.py new file mode 100644 index 00000000..2be02071 --- /dev/null +++ b/test/stats/EntranceShuffleStats.py @@ -0,0 +1,154 @@ +import RaceRandom as random +import logging +import time + +from collections import Counter, defaultdict + +from source.overworld.EntranceShuffle2 import link_entrances_new +from EntranceShuffle import link_entrances, link_inverted_entrances +from BaseClasses import World +from Regions import create_regions, create_dungeon_regions +from InvertedRegions import create_inverted_regions + + +# tested: open + crossed (lh) Mar. 17 (made changes) +# tested: open + simple (lh) Mar. 22 + +def run_stats(): + # logging.basicConfig(format='%(message)s', level=logging.DEBUG) + random.seed(None) + tests = 10000 + + for main_mode in ['open', 'standard', 'inverted']: + for shuffle_mode in ['dungeonssimple', 'dungeonsfull', + 'simple', 'restricted', 'full', 'crossed']: + for ls in [True, False]: + if ls and (main_mode == 'standard' or shuffle_mode in ['dungeonssimple', 'dungeonsfull']): + continue + + def runner_new(world): + link_entrances_new(world, 1) + + def runner_old(world): + if main_mode == 'inverted': + link_inverted_entrances(world, 1) + else: + link_entrances(world, 1) + compare_tests(tests, shuffle_mode, main_mode, ls, runner_old, runner_new) + + +def run_test_stats(): + # logging.basicConfig(format='%(message)s', level=logging.DEBUG) + random.seed(None) + tests = 10000 + + for main_mode in ['open']: + for shuffle_mode in [#'dungeonssimple', 'dungeonsfull', + 'simple']:#, 'restricted', 'full', 'crossed']: + for ls in [True, False]: + if ls and (main_mode == 'standard' or shuffle_mode in ['dungeonssimple', 'dungeonsfull']): + continue + + def runner_new(world): + link_entrances_new(world, 1) + + run_tests(tests, shuffle_mode, main_mode, ls, runner_new) + + +def run_old_stats(): + # logging.basicConfig(format='%(message)s', level=logging.DEBUG) + random.seed(None) + tests = 10000 + + for main_mode in ['open']: + for shuffle_mode in [#'dungeonssimple', 'dungeonsfull', + 'simple']:#, 'restricted', 'full', 'crossed']: + for ls in [True, False]: + if ls and (main_mode == 'standard' or shuffle_mode in ['dungeonssimple', 'dungeonsfull']): + continue + + def runner(world): + if main_mode == 'inverted': + link_inverted_entrances(world, 1) + else: + link_entrances(world, 1) + run_tests(tests, shuffle_mode, main_mode, ls, runner) + + +def compare_tests(tests, shuffle_mode, main_mode, links=False, runner_old=None, runner_new=None): + print(f'Testing {shuffle_mode} {main_mode}') + entrance_set = set() + exit_set = set() + ctr = defaultdict(Counter) + start = time.time() + test_loop(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links, runner_old) + print(f'Old test took {time.time() - start}s') + start = time.time() + test_loop(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links, runner_new, -1) + # test_loop(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links, runner_new) + print(f'New test took {time.time() - start}s') + dump_file(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links) + + +def run_tests(tests, shuffle_mode, main_mode, links=False, runner=None): + print(f'Testing {shuffle_mode} {main_mode}') + entrance_set = set() + exit_set = set() + ctr = defaultdict(Counter) + test_loop(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links, runner) + + +def test_loop(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links, runner, value=1): + for i in range(0, tests): + if i % 1000 == 0: + print(f'Test {i}') + seed = random.randint(0, 999999999) + # seed = 635441530 + random.seed(seed) + world = World(1, {1: shuffle_mode}, {1: 'vanilla'}, {1: 'noglitches'}, {1: main_mode}, {}, {}, {}, + {}, {}, {}, {}, {}, True, {}, {}, [], {}) + world.customizer = False + world.shufflelinks = {1: links} + if world.mode[1] != 'inverted': + create_regions(world, 1) + else: + create_inverted_regions(world, 1) + create_dungeon_regions(world, 1) + # print(f'Linking seed {seed}') + # try: + runner(world) + # except Exception as e: + # print(f'Failure during seed {seed} with {e}') + for data in world.spoiler.entrances.values(): + ent = data['entrance'] + ext = data['exit'] + # drc = data['direction'] + entrance_set.add(ent) + exit_set.add(ext) + ctr[ent][ext] += value + + +def dump_file(tests, entrance_set, exit_set, ctr, shuffle_mode, main_mode, links): + columns = sorted(list(exit_set)) + rows = sorted(list(entrance_set)) + filename = f'er_stats_{shuffle_mode}_{main_mode}_{"ls" if links else "v"}.csv' + with open(filename, 'w') as stat_file: + stat_file.write(',') + stat_file.write(','.join(columns)) + stat_file.write('\n') + for r in rows: + stat_file.write(f'{r},') + formatted = [] + for c in columns: + occurance = ctr[r][c] / tests + formatted.append(f'{occurance:.5%}') + stat_file.write(','.join(formatted)) + stat_file.write('\n') + + +if __name__ == "__main__": + # logging.basicConfig(format='%(message)s', level=logging.DEBUG) + # run_tests(1, 'restricted', 'inverted', True, lambda world: link_entrances_new(world, 1)) + # run_test_stats() + # run_old_stats() + run_stats() diff --git a/test/stats/__init__.py b/test/stats/__init__.py new file mode 100644 index 00000000..e69de29b From 5e07e49798bd67ac9e8fdd132844109a4c677001 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 25 Mar 2022 08:43:11 -0600 Subject: [PATCH 002/146] Fix documentation and example Fix msu_resume issue Fix empty locations Throw error on unknown items --- Fill.py | 2 + Items.py | 3 +- Main.py | 2 +- Rom.py | 2 +- docs/Customizer.md | 4 +- docs/SuperTrueIceRodHunt.yaml | 125 +++++++++++++++++++++++++++ docs/customizer_example.yaml | 2 +- source/gui/adjust/overview.py | 1 + source/overworld/EntranceShuffle2.py | 6 +- 9 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 docs/SuperTrueIceRodHunt.yaml diff --git a/Fill.py b/Fill.py index 43a3abc0..03fb6fed 100644 --- a/Fill.py +++ b/Fill.py @@ -451,6 +451,8 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None def ensure_good_pots(world, write_skips=False): for loc in world.get_locations(): + if loc.item is None: + loc.item = ItemFactory('Nothing', loc.player) # convert Arrows 5 and Nothing when necessary if (loc.item.name in {'Arrows (5)', 'Nothing'} and (loc.type != LocationType.Pot or loc.item.player != loc.player)): diff --git a/Items.py b/Items.py index 757fc8e5..7f6c5054 100644 --- a/Items.py +++ b/Items.py @@ -14,8 +14,7 @@ def ItemFactory(items, player): advancement, priority, type, code, price, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text = item_table[item] ret.append(Item(item, advancement, priority, type, code, price, pedestal_hint, pedestal_credit, sickkid_credit, zora_credit, witch_credit, fluteboy_credit, hint_text, player)) else: - logging.getLogger('').warning('Unknown Item: %s', item) - return None + raise RuntimeError(f'Unknown Item: {item}') if singleton: return ret[0] diff --git a/Main.py b/Main.py index 147f4ca6..07adc036 100644 --- a/Main.py +++ b/Main.py @@ -33,7 +33,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.0.1.12v' +__version__ = '1.0.1.12w' from source.classes.BabelFish import BabelFish diff --git a/Rom.py b/Rom.py index 398a7c1b..4a228d79 100644 --- a/Rom.py +++ b/Rom.py @@ -2268,7 +2268,7 @@ def write_strings(rom, world, player, team): random.shuffle(items_to_hint) hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 8 hint_count += 2 if world.doorShuffle[player] == 'crossed' else 0 - while hint_count > 0: + while hint_count > 0 and len(items_to_hint) > 0: this_item = items_to_hint.pop(0) this_location = world.find_items_not_key_only(this_item, player) random.shuffle(this_location) diff --git a/docs/Customizer.md b/docs/Customizer.md index af9ae7ed..047deefe 100644 --- a/docs/Customizer.md +++ b/docs/Customizer.md @@ -160,14 +160,14 @@ This is done as `: ` E.g. `Skull Woods: Helmasaur King` for helmacopter. Be sure to turn on at least one enemizer setting for the bosses to actually be randomized. -### startinventory +### start_inventory This must be defined by player. Each player number should be listed with a list of items to start with. This is a yaml list (note the hyphens): ``` -startinventory: +start_inventory: 1: - Pegasus Boots - Progressive Sword diff --git a/docs/SuperTrueIceRodHunt.yaml b/docs/SuperTrueIceRodHunt.yaml new file mode 100644 index 00000000..3b644bf9 --- /dev/null +++ b/docs/SuperTrueIceRodHunt.yaml @@ -0,0 +1,125 @@ +meta: + algorithm: balanced + players: 1 +settings: + 1: + door_shuffle: vanilla + dropshuffle: true + experimental: true + goal: ganon + hints: false + intensity: 1 + pseudoboots: false + pottery: lottery + shopsanity: false + shuffle: vanilla + shufflelinks: false + shufflebosses: false +item_pool: + 1: + Ice Rod: 1 + Progressive Sword: 1 +placements: + 1: + Turtle Rock - Boss: Triforce +start_inventory: + 1: + - Progressive Bow + - Progressive Bow + - Blue Boomerang + - Red Boomerang + - Hookshot + - Mushroom + - Magic Powder + - Fire Rod + - Bombos + - Ether + - Quake + - Lamp + - Hammer + - Ocarina + - Bug Catching Net + - Book of Mudora + - Shovel + - Cane of Somaria + - Cane of Byrna + - Cape + - Magic Mirror + - Moon Pearl + - Titans Mitts + - Tempered Sword + - Pegasus Boots + - Flippers + - Red Mail + - Progressive Shield + - Progressive Shield + - Bottle (Red Potion) + - Bottle (Green Potion) + - Bottle (Blue Potion) + - Bottle (Fairy) + - Magic Upgrade (1/2) + - Magic Upgrade (1/2) + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Arrows (10) + - Arrows (10) + - Arrows (10) + - Bombs (10) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (300) + - Rupees (50) + - Rupees (20) + - Rupees (20) + - Rupees (5) + - Rupee (1) + - Rupee (1) + - Rupee (1) + - Rupee (1) + + \ No newline at end of file diff --git a/docs/customizer_example.yaml b/docs/customizer_example.yaml index 3100e6c2..3d0c7624 100644 --- a/docs/customizer_example.yaml +++ b/docs/customizer_example.yaml @@ -102,7 +102,7 @@ bosses: Palace of Darkness: Arrghus Thieves Town: Blind Ganons Tower (top): Vitreous -startinventory: +start_inventory: 1: - Pegasus Boots diff --git a/source/gui/adjust/overview.py b/source/gui/adjust/overview.py index 7ab7f474..607c16b1 100644 --- a/source/gui/adjust/overview.py +++ b/source/gui/adjust/overview.py @@ -158,6 +158,7 @@ def adjust_page(top, parent, settings): "nobgm": "disablemusic", "reduce_flashing": "reduce_flashing", "shuffle_sfx": "shuffle_sfx", + "msu_resume": "msu_resume", } guiargs = Namespace() for option in options: diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index b46e05e0..f69a475f 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -17,6 +17,8 @@ class EntrancePool(object): self.links_on_mountain = False self.decoupled_entrances = [] self.decoupled_exits = [] + self.original_entrances = set() + self.original_exits = set() self.world = world self.player = player @@ -48,6 +50,8 @@ def link_entrances_new(world, player): avail_pool.exits.add('Inverted Dark Sanctuary Exit') inverted_substitution(avail_pool, avail_pool.entrances, True, True) inverted_substitution(avail_pool, avail_pool.exits, False, True) + avail_pool.original_entrances.update(avail_pool.entrances) + avail_pool.original_exits.update(avail_pool.exits) default_map = {} default_map.update(entrance_map) one_way_map = {} @@ -378,7 +382,7 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe hole_entrances, hole_targets = [], [] for hole in drop_map: - if hole in entrances and hole in linked_drop_map: + if hole in avail.original_entrances and hole in linked_drop_map: linked_entrance = linked_drop_map[hole] if hole in entrances and linked_entrance in entrances: hole_entrances.append((linked_entrance, hole)) From b5684cbf7dddcf09c7e4794a3af935ce6359a323 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 29 Mar 2022 12:13:19 -0600 Subject: [PATCH 003/146] Minor bug with ER customization --- source/overworld/EntranceShuffle2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index f69a475f..20578cc5 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -946,9 +946,9 @@ def find_entrances_and_exits(avail_pool, entrance_pool): for item in entrance_pool: if item in avail_pool.entrances: entrances.append(item) - if 'Links House' in item: - targets.append('Chris Houlihan Room Exit') if item in entrance_map and entrance_map[item] in avail_pool.exits: + if item in ['Links House Exit', 'Inverted Links House Exit']: + targets.append('Chris Houlihan Room Exit') targets.append(entrance_map[item]) elif item in single_entrance_map and single_entrance_map[item] in avail_pool.exits: targets.append(single_entrance_map[item]) From cf227aafc03be29b650dd5d3ea7041748409c87c Mon Sep 17 00:00:00 2001 From: aerinon Date: Mon, 4 Apr 2022 13:37:07 -0600 Subject: [PATCH 004/146] Trinity goal --- BaseClasses.py | 7 ++- CLI.py | 4 +- Fill.py | 5 +- ItemList.py | 57 ++++++++++++------- Mystery.py | 3 + Rom.py | 12 ++-- Rules.py | 6 +- mystery_example.yml | 7 +++ resources/app/cli/args.json | 1 + resources/app/cli/lang/en.json | 4 +- resources/app/gui/lang/en.json | 1 + resources/app/gui/randomize/item/widgets.json | 1 + source/tools/MysteryUtils.py | 7 ++- 13 files changed, 78 insertions(+), 37 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index b1b58cd9..1c057b1c 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2532,7 +2532,7 @@ class Spoiler(object): outfile.write('Retro: %s\n' % ('Yes' if self.metadata['retro'][player] else 'No')) outfile.write('Swords: %s\n' % self.metadata['weapons'][player]) outfile.write('Goal: %s\n' % self.metadata['goal'][player]) - if self.metadata['goal'][player] == 'triforcehunt': + if self.metadata['goal'][player] in ['triforcehunt', 'trinity']: outfile.write('Triforce Pieces Required: %s\n' % self.metadata['triforcegoal'][player]) outfile.write('Triforce Pieces Total: %s\n' % self.metadata['triforcepool'][player]) outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player]) @@ -2548,7 +2548,8 @@ class Spoiler(object): outfile.write('Crystals required for GT: %s\n' % (str(self.metadata['gt_crystals'][player]) + addition)) addition = ' (Random)' if self.world.crystals_ganon_orig[player] == 'random' else '' outfile.write('Crystals required for Ganon: %s\n' % (str(self.metadata['ganon_crystals'][player]) + addition)) - outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No')) + if self.metadata['goal'][player] != 'trinity': + outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No')) outfile.write('Accessibility: %s\n' % self.metadata['accessibility'][player]) outfile.write(f"Restricted Boss Items: {self.metadata['restricted_boss_items'][player]}\n") outfile.write('Map shuffle: %s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No')) @@ -2742,7 +2743,7 @@ world_mode = {"open": 0, "standard": 1, "inverted": 2} sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3} # byte 2: GGGD DFFH (goal, diff, item_func, hints) -goal_mode = {"ganon": 0, "pedestal": 1, "dungeons": 2, "triforcehunt": 3, "crystals": 4} +goal_mode = {'ganon': 0, 'pedestal': 1, 'dungeons': 2, 'triforcehunt': 3, 'crystals': 4, 'trinity': 5} diff_mode = {"normal": 0, "hard": 1, "expert": 2} func_mode = {"normal": 0, "hard": 1, "expert": 2} diff --git a/CLI.py b/CLI.py index 9a2914de..6a04e4c9 100644 --- a/CLI.py +++ b/CLI.py @@ -195,8 +195,8 @@ def parse_settings(): "mixed_travel": "prevent", "standardize_palettes": "standardize", - "triforce_pool": 30, - "triforce_goal": 20, + "triforce_pool": 0, + "triforce_goal": 0, "triforce_pool_min": 0, "triforce_pool_max": 0, "triforce_goal_min": 0, diff --git a/Fill.py b/Fill.py index 663ce09f..7199c1af 100644 --- a/Fill.py +++ b/Fill.py @@ -392,7 +392,10 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None else: max_trash = gt_count scaled_trash = math.floor(max_trash * scale_factor) - gftower_trash_count = (random.randint(scaled_trash, max_trash) if world.goal[player] == 'triforcehunt' else random.randint(0, scaled_trash)) + if world.goal[player] in ['triforcehunt', 'trinity']: + gftower_trash_count = random.randint(scaled_trash, max_trash) + else: + gftower_trash_count = random.randint(0, scaled_trash) gtower_locations = [location for location in fill_locations if location.parent_region.dungeon and location.parent_region.dungeon.name == 'Ganons Tower' and location.player == player] diff --git a/ItemList.py b/ItemList.py index a489f9fb..3884efc0 100644 --- a/ItemList.py +++ b/ItemList.py @@ -180,7 +180,7 @@ def get_custom_array_key(item): def generate_itempool(world, player): - if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'] + if (world.difficulty[player] not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'trinity', 'crystals'] or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']): raise NotImplementedError('Not supported yet') @@ -192,8 +192,8 @@ def generate_itempool(world, player): else: world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False) - if world.goal[player] in ['triforcehunt']: - region = world.get_region('Light World',player) + if world.goal[player] in ['triforcehunt', 'trinity']: + region = world.get_region('Light World', player) loc = Location(player, "Murahdahla", parent=region) region.locations.append(loc) world.dynamic_locations.append(loc) @@ -338,14 +338,11 @@ def generate_itempool(world, player): if clock_mode is not None: world.clock_mode = clock_mode - if world.goal[player] == 'triforcehunt': - if world.treasure_hunt_count[player] == 0: - world.treasure_hunt_count[player] = 20 - if world.treasure_hunt_total[player] == 0: - world.treasure_hunt_total[player] = 30 + goal = world.goal[player] + if goal in ['triforcehunt', 'trinity']: + g, t = set_default_triforce(goal, world.treasure_hunt_count[player], world.treasure_hunt_total[player]) + world.treasure_hunt_count[player], world.treasure_hunt_total[player] = g, t world.treasure_hunt_icon[player] = 'Triforce Piece' - if world.custom: - world.treasure_hunt_count[player] = treasure_hunt_count world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player and ((item.smallkey and world.keyshuffle[player]) @@ -412,7 +409,6 @@ def generate_itempool(world, player): if world.pottery[player] not in ['none', 'cave']: world.itempool += [ItemFactory('Small Key (Universal)', player)] * 19 - create_dynamic_shop_locations(world, player) if world.pottery[player] not in ['none', 'keys']: @@ -788,9 +784,9 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, placed_items = {} precollected_items = [] clock_mode = None - if goal == 'triforcehunt': + if goal in ['triforcehunt', 'trinity']: if treasure_hunt_total == 0: - treasure_hunt_total = 30 + treasure_hunt_total = 30 if goal == 'triforcehunt' else 10 triforcepool = ['Triforce Piece'] * int(treasure_hunt_total) pool.extend(alwaysitems) @@ -866,7 +862,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, place_item('Link\'s Uncle', swords_to_use.pop()) place_item('Blacksmith', swords_to_use.pop()) place_item('Pyramid Fairy - Left', swords_to_use.pop()) - if goal != 'pedestal': + if goal not in ['pedestal', 'trinity']: place_item('Master Sword Pedestal', swords_to_use.pop()) else: place_item('Master Sword Pedestal', 'Triforce') @@ -888,7 +884,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, elif timer == 'timed-ohko': pool.extend(diff.timedohko) clock_mode = 'countdown-ohko' - if goal == 'triforcehunt': + if goal in ['triforcehunt', 'trinity']: pool.extend(triforcepool) for extra in diff.extras: @@ -896,7 +892,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, # note: massage item pool now handles shrinking the pool appropriately - if goal == 'pedestal' and swords != 'vanilla': + if goal in ['pedestal', 'trinity'] and swords != 'vanilla': place_item('Master Sword Pedestal', 'Triforce') if retro: pool = [item.replace('Single Arrow','Rupees (5)') for item in pool] @@ -945,6 +941,11 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s if customitemarray["triforce"] > total_items_to_place: customitemarray["triforce"] = total_items_to_place + # Triforce Pieces + if goal in ['triforcehunt', 'trinity']: + g, t = set_default_triforce(goal, customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"]) + customitemarray["triforcepiecesgoal"], customitemarray["triforcepieces"] = g, t + itemtotal = 0 # Bow to Silver Arrows Upgrade, including Generic Keys & Rupoors for x in [*range(0, 66 + 1), 68, 69]: @@ -979,7 +980,8 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s treasure_hunt_count = max(min(customitemarray["triforcepiecesgoal"], 254), 1) treasure_hunt_icon = 'Triforce Piece' # Ensure game is always possible to complete here, force sufficient pieces if the player is unwilling. - if (customitemarray["triforcepieces"] < treasure_hunt_count) and (goal == 'triforcehunt') and (customitemarray["triforce"] == 0): + if ((customitemarray["triforcepieces"] < treasure_hunt_count) and (goal in ['triforcehunt', 'trinity']) + and (customitemarray["triforce"] == 0)): extrapieces = treasure_hunt_count - customitemarray["triforcepieces"] pool.extend(['Triforce Piece'] * extrapieces) itemtotal = itemtotal + extrapieces @@ -991,7 +993,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s elif timer == 'ohko': clock_mode = 'ohko' - if goal == 'pedestal': + if goal in ['pedestal', 'trinity']: place_item('Master Sword Pedestal', 'Triforce') itemtotal = itemtotal + 1 @@ -1052,10 +1054,25 @@ def make_customizer_pool(world, player): return pool, placed_items, precollected_items, clock_mode, 1 + +# To display, count must be between 1 and 254 - larger values are not yet supported +def set_default_triforce(goal, custom_goal, custom_total): + triforce_goal, triforce_total = 0, 0 + if goal == 'triforcehunt': + triforce_goal, triforce_total = 20, 30 + elif goal == 'trinity': + triforce_goal, triforce_total = 8, 10 + if custom_goal > 0: + triforce_goal = max(min(custom_goal, 254), 1) + if custom_total > 0: + triforce_total = max(min(custom_total, 254), triforce_goal) + return triforce_goal, triforce_total + + # A quick test to ensure all combinations generate the correct amount of items. def test(): for difficulty in ['normal', 'hard', 'expert']: - for goal in ['ganon', 'triforcehunt', 'pedestal']: + for goal in ['ganon', 'triforcehunt', 'pedestal', 'trinity']: for timer in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown']: for mode in ['open', 'standard', 'inverted', 'retro']: for swords in ['random', 'assured', 'swordless', 'vanilla']: @@ -1069,7 +1086,7 @@ def test(): count = len(out[0]) + len(out[1]) correct_count = total_items_to_place - if goal == 'pedestal' and swords != 'vanilla': + if goal in ['pedestal', 'trinity'] and swords != 'vanilla': # pedestal goals generate one extra item correct_count += 1 if retro: diff --git a/Mystery.py b/Mystery.py index 593e9516..bc6351af 100644 --- a/Mystery.py +++ b/Mystery.py @@ -1,6 +1,9 @@ import argparse import logging import RaceRandom as random +import urllib.request +import urllib.parse +import yaml from DungeonRandomizer import parse_cli from Main import main as DRMain diff --git a/Rom.py b/Rom.py index 2cf72cfb..87ae5f46 100644 --- a/Rom.py +++ b/Rom.py @@ -719,7 +719,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal if world.doorShuffle[player] == 'crossed': dr_flags |= DROptions.Map_Info - if world.collection_rate[player] and world.goal[player] != 'triforcehunt': + if world.collection_rate[player] and world.goal[player] not in ['triforcehunt', 'trinity']: dr_flags |= DROptions.Debug if world.doorShuffle[player] == 'crossed' and world.logic[player] != 'nologic'\ and world.mixed_travel[player] == 'prevent': @@ -1234,7 +1234,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # set up goals for treasure hunt rom.write_bytes(0x180165, [0x0E, 0x28] if world.treasure_hunt_icon[player] == 'Triforce Piece' else [0x0D, 0x28]) - if world.goal[player] == 'triforcehunt': + if world.goal[player] in ['triforcehunt', 'trinity']: rom.write_byte(0x180167, int(world.treasure_hunt_count[player]) % 256) rom.write_byte(0x180194, 1) # Must turn in triforced pieces (instant win not enabled) @@ -1261,7 +1261,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0x50563, [0x3F, 0x14]) # disable below ganon chest rom.write_byte(0x50599, 0x00) # disable below ganon chest rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest - rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] else 0x00) # pre-open Pyramid Hole + rom.write_byte(0x18008B, 0x01 if world.open_pyramid[player] or world.goal[player] == 'trinity' else 0x00) # pre-open Pyramid Hole rom.write_byte(0x18008C, 0x01 if world.crystals_needed_for_gt[player] == 0 else 0x00) # GT pre-opened if crystal requirement is 0 rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable @@ -1447,7 +1447,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x18003E, 0x01) # make ganon invincible elif world.goal[player] in ['dungeons']: rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat - elif world.goal[player] in ['crystals']: + elif world.goal[player] in ['crystals', 'trinity']: rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals else: rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected @@ -2414,6 +2414,10 @@ def write_strings(rom, world, player, team): tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.' tt['sign_ganon'] = 'You need to get to the pedestal... Ganon is invincible!' else: + if world.goal[player] == 'trinity': + trinity_crystal_text = ('%d crystal to beat Ganon.' if world.crystals_needed_for_ganon[player] == 1 else '%d crystals to beat Ganon.') % world.crystals_needed_for_ganon[player] + tt['sign_ganon'] = 'Three ways to victory! %s Get to it!' % trinity_crystal_text + tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % int(world.treasure_hunt_count[player]) tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)] tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!' tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!' diff --git a/Rules.py b/Rules.py index 5268b409..0ab4fd9b 100644 --- a/Rules.py +++ b/Rules.py @@ -58,7 +58,7 @@ def set_rules(world, player): elif world.goal[player] == 'ganon': # require aga2 to beat ganon add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player)) - elif world.goal[player] == 'triforcehunt': + elif world.goal[player] in ['triforcehunt', 'trinity']: add_rule(world.get_location('Murahdahla', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player])) if world.mode[player] != 'inverted': @@ -873,7 +873,7 @@ def default_rules(world, player): set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has_Pearl(player) and state.has_sword(player) and state.has_turtle_rock_medallion(player) and state.can_reach('Turtle Rock (Top)', 'Region', player)) # sword required to cast magic (!) - set_rule(world.get_entrance('Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) + set_rule(world.get_entrance('Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player)) if world.swords[player] == 'swordless': swordless_rules(world, player) @@ -1025,7 +1025,7 @@ def inverted_rules(world, player): set_rule(world.get_entrance('Dark Grassy Lawn Flute', player), lambda state: state.can_flute(player)) set_rule(world.get_entrance('Hammer Peg Area Flute', player), lambda state: state.can_flute(player)) - set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: state.has('Beat Agahnim 2', player) or world.open_pyramid[player]) + set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: world.open_pyramid[player] or world.goal[player] == 'trinity' or state.has('Beat Agahnim 2', player)) if world.swords[player] == 'swordless': swordless_rules(world, player) diff --git a/mystery_example.yml b/mystery_example.yml index abd46ee5..a7f26ddb 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -1,4 +1,10 @@ description: Example door rando weights + algorithm: + balanced: 12 + vanilla_fill: 1 + major_only: 1 + dungeon_only: 1 + district: 1 door_shuffle: vanilla: 0 basic: 2 @@ -52,6 +58,7 @@ dungeons: 1 pedestal: 2 triforce-hunt: 2 + trinity: 2 triforce_goal_min: 10 triforce_goal_max: 30 triforce_pool_min: 20 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index b2769bbf..ad971548 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -43,6 +43,7 @@ "pedestal", "dungeons", "triforcehunt", + "trinity", "crystals" ] }, diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index d815cb6d..40bf1a70 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -104,7 +104,9 @@ "All Dungeons: Collect all crystals, pendants, beat both", " Agahnim fights and then defeat Ganon.", "Triforce Hunt: Places 30 Triforce Pieces in the world, collect", - " 20 of them to beat the game." + " 20 of them to beat the game.", + "Trinity: Can beat the game by defeating Ganon, pulling", + " Pedestal, or delivering Triforce Pieces." ], "difficulty": [ "Select game difficulty. Affects available itempool. (default: %(default)s)", diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index c81dcb61..dc31d613 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -226,6 +226,7 @@ "randomizer.item.goal.pedestal": "Master Sword Pedestal", "randomizer.item.goal.dungeons": "All Dungeons", "randomizer.item.goal.triforcehunt": "Triforce Hunt", + "randomizer.item.goal.trinity": "Trinity", "randomizer.item.goal.crystals": "Crystals", "randomizer.item.crystals_gt": "Crystals to open GT", diff --git a/resources/app/gui/randomize/item/widgets.json b/resources/app/gui/randomize/item/widgets.json index 2177335b..76537817 100644 --- a/resources/app/gui/randomize/item/widgets.json +++ b/resources/app/gui/randomize/item/widgets.json @@ -35,6 +35,7 @@ "pedestal", "dungeons", "triforcehunt", + "trinity", "crystals" ] }, diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index 6cc1d4ff..6e456ff8 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -49,7 +49,7 @@ def roll_settings(weights): ret.mystery = get_choice_default('mystery', default=True) glitch_map = {'none': 'noglitches', 'no_logic': 'nologic', 'owglitches': 'owglitches', - 'minorglitches': 'minorglitches'} + 'owg': 'owglitches', 'minorglitches': 'minorglitches'} glitches_required = get_choice('glitches_required') if glitches_required is not None: if glitches_required not in glitch_map.keys(): @@ -103,9 +103,10 @@ def roll_settings(weights): 'fast_ganon': 'crystals', 'dungeons': 'dungeons', 'pedestal': 'pedestal', - 'triforce-hunt': 'triforcehunt' + 'triforce-hunt': 'triforcehunt', + 'trinity': 'trinity' }[goal] - ret.openpyramid = goal == 'fast_ganon' if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False + ret.openpyramid = goal in ['fast_ganon', 'trinity'] if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False ret.crystals_gt = get_choice('tower_open') From 52a0e88d12d274a4c222a28b81ec247a6493f84a Mon Sep 17 00:00:00 2001 From: aerinon Date: Mon, 4 Apr 2022 14:29:40 -0600 Subject: [PATCH 005/146] Minor ohko fix --- DoorShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index df97441f..676546b4 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1967,7 +1967,7 @@ ohko_forbidden = { def filter_dashable_candidates(candidates, world): - forbidden_set = dashable_forbidden if world.can_take_damage else ohko_forbidden + forbidden_set = dashable_forbidden if world.timer in ['ohko', 'timed-ohko'] else ohko_forbidden return [x for x in candidates if x not in forbidden_set and x.dest not in forbidden_set] From 833b570af6f9d939ec6cd27e9cd006a86c286a06 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 13 Apr 2022 13:22:15 -0600 Subject: [PATCH 006/146] Customizer item_pool updates --- ItemList.py | 149 +++++++++++++++++++++++++++---- RELEASENOTES.md | 4 + docs/Customizer.md | 12 +-- source/classes/CustomSettings.py | 13 +++ 4 files changed, 154 insertions(+), 24 deletions(-) diff --git a/ItemList.py b/ItemList.py index 3884efc0..f43a935d 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1,4 +1,4 @@ -from collections import namedtuple +from collections import namedtuple, defaultdict import logging import math import RaceRandom as random @@ -257,15 +257,17 @@ def generate_itempool(world, player): world.get_location('Zelda Drop Off', player).locked = True # set up item pool + skip_pool_adjustments = False if world.customizer and world.customizer.get_item_pool(): (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = make_customizer_pool(world, player) + skip_pool_adjustments = True elif world.custom: (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray) world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) else: (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player]) - if player in world.pool_adjustment.keys(): + if player in world.pool_adjustment.keys() and not skip_pool_adjustments: amt = world.pool_adjustment[player] if amt < 0: trash_options = [x for x in pool if x in trash_items] @@ -311,7 +313,7 @@ def generate_itempool(world, player): world.get_location(location, player).event = True world.get_location(location, player).locked = True - if world.shopsanity[player]: + if world.shopsanity[player] and not skip_pool_adjustments: for shop in world.shops[player]: if shop.region.name in shop_to_location_table: for index, slot in enumerate(shop.inventory): @@ -373,7 +375,10 @@ def generate_itempool(world, player): return item if not choice else ItemFactory("Bee Trap", player) if choice == 'trap' else ItemFactory("Bee", player) return item - world.itempool += [beemizer(item) for item in items] + if not skip_pool_adjustments: + world.itempool += [beemizer(item) for item in items] + else: + world.itempool += items # shuffle medallions mm_medallion, tr_medallion = None, None @@ -403,15 +408,15 @@ def generate_itempool(world, player): set_up_shops(world, player) if world.retro[player]: - set_up_take_anys(world, player) - if world.dropshuffle[player]: + set_up_take_anys(world, player, skip_pool_adjustments) + if world.dropshuffle[player] and not skip_pool_adjustments: world.itempool += [ItemFactory('Small Key (Universal)', player)] * 13 - if world.pottery[player] not in ['none', 'cave']: + if world.pottery[player] not in ['none', 'cave'] and not skip_pool_adjustments: world.itempool += [ItemFactory('Small Key (Universal)', player)] * 19 create_dynamic_shop_locations(world, player) - if world.pottery[player] not in ['none', 'keys']: + if world.pottery[player] not in ['none', 'keys'] and not skip_pool_adjustments: add_pot_contents(world, player) @@ -426,7 +431,7 @@ take_any_locations = [ 'Dark Lake Hylia Ledge Spike Cave', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Dark Desert Hint'] -def set_up_take_anys(world, player): +def set_up_take_anys(world, player, skip_adjustments=False): if world.mode[player] == 'inverted': if 'Dark Sanctuary Hint' in take_any_locations: take_any_locations.remove('Dark Sanctuary Hint') @@ -450,12 +455,13 @@ def set_up_take_anys(world, player): sword = next((item for item in world.itempool if item.type == 'Sword' and item.player == player), None) if sword: - world.itempool.append(ItemFactory('Rupees (20)', player)) - if not world.shopsanity[player]: - world.itempool.remove(sword) + if not skip_adjustments: + world.itempool.append(ItemFactory('Rupees (20)', player)) + if not world.shopsanity[player]: + world.itempool.remove(sword) old_man_take_any.shop.add_inventory(0, sword.name, 0, 0, create_location=True) else: - if world.shopsanity[player]: + if world.shopsanity[player] and not skip_adjustments: world.itempool.append(ItemFactory('Rupees (300)', player)) old_man_take_any.shop.add_inventory(0, 'Rupees (300)', 0, 0, create_location=world.shopsanity[player]) @@ -473,7 +479,7 @@ def set_up_take_anys(world, player): world.shops[player].append(take_any.shop) take_any.shop.add_inventory(0, 'Blue Potion', 0, 0, create_location=world.shopsanity[player]) take_any.shop.add_inventory(1, 'Boss Heart Container', 0, 0, create_location=world.shopsanity[player]) - if world.shopsanity[player]: + if world.shopsanity[player] and not skip_adjustments: world.itempool.append(ItemFactory('Blue Potion', player)) world.itempool.append(ItemFactory('Boss Heart Container', player)) @@ -1032,12 +1038,62 @@ def make_customizer_pool(world, player): assert loc not in placed_items placed_items[loc] = item + dungeon_locations, dungeon_count = defaultdict(set), defaultdict(int) + for l in world.get_unfilled_locations(player): + if l.parent_region.dungeon: + dungeon = l.parent_region.dungeon + dungeon_locations[dungeon.name].add(l) + if dungeon.name not in dungeon_count: + d_count = 1 if dungeon.big_key else 0 + d_count += len(dungeon.small_keys) + len(dungeon.dungeon_items) + dungeon_count[dungeon.name] = d_count + diff = difficulties[world.difficulty[player]] for item_name, amount in world.customizer.get_item_pool()[player].items(): if isinstance(amount, int): if item_name == 'Bottle (Random)': for _ in range(amount): pool.append(random.choice(diff.bottles)) + elif item_name.startswith('Small Key') and item_name != 'Small Key (Universal)': + d_item = ItemFactory(item_name, player) + if not world.keyshuffle[player]: + d_name = d_item.dungeon + dungeon = world.get_dungeon(d_name, player) + target_amount = max(amount, len(dungeon.small_keys)) + additional_amount = target_amount - len(dungeon.small_keys) + possible_fit = min(additional_amount, len(dungeon_locations[d_name])-dungeon_count[d_name]) + if possible_fit > 0: + dungeon_count[d_name] += possible_fit + dungeon.small_keys.extend([d_item] * amount) + additional_amount -= possible_fit + if additional_amount > 0: + pool.extend([item_name] * amount) + else: + dungeon = world.get_dungeon(d_item.dungeon, player) + target_amount = max(amount, len(dungeon.small_keys)) + additional_amount = target_amount - len(dungeon.small_keys) + dungeon.small_keys.extend([d_item] * additional_amount) + elif item_name.startswith('Big Key') or item_name.startswith('Map') or item_name.startswith('Compass'): + d_item = ItemFactory(item_name, player) + if ((d_item.bigkey and not world.bigkeyshuffle[player]) + or (d_item.compass and not world.compassshuffle[player]) + or (d_item.map and not world.mapshuffle[player])): + d_name = d_item.dungeon + dungeon = world.get_dungeon(d_name, player) + current_amount = 1 if d_item == dungeon.big_key or d_item in dungeon.dungeon_items else 0 + additional_amount = amount - current_amount + possible_fit = min(additional_amount, len(dungeon_locations[d_name])-dungeon_count[d_name]) + if possible_fit > 0: + dungeon_count[d_name] += possible_fit + dungeon.dungeon_items.extend([d_item] * amount) + additional_amount -= possible_fit + if additional_amount > 0: + pool.extend([item_name] * amount) + else: + dungeon = world.get_dungeon(d_item.dungeon, player) + current_amount = 1 if d_item == dungeon.big_key or d_item in dungeon.dungeon_items else 0 + additional_amount = amount - current_amount + dungeon.dungeon_items.extend([d_item] * additional_amount) else: pool.extend([item_name] * amount) @@ -1049,12 +1105,75 @@ def make_customizer_pool(world, player): elif timer == 'ohko': clock_mode = 'ohko' - if world.goal[player] == 'pedestal': + if world.goal[player] in ['pedestal', 'trinity']: place_item('Master Sword Pedestal', 'Triforce') + guaranteed_items = alwaysitems + ['Magic Mirror', 'Moon Pearl'] + if world.shopsanity[player]: + guaranteed_items.extend(['Blue Potion', 'Green Potion', 'Red Potion']) + if world.retro[player]: + guaranteed_items.append('Small Key (Universal)') + for item in guaranteed_items: + if item not in pool: + pool.append(item) + + glove_count = sum(1 for i in pool if i == 'Progressive Glove') + glove_count = 2 if next((i for i in pool if i == 'Titans Glove'), None) is not None else glove_count + for i in range(glove_count, 2): + pool.append('Progressive Glove') + + if world.bombbag[player]: + if 'Bomb Upgrade (+10)' not in pool: + pool.append('Bomb Upgrade (+10)') + + if world.swords[player] != 'swordless': + beam_swords = {'Master Sword', 'Tempered Sword', 'Golden Sword'} + sword_count = sum(1 for i in pool if i in 'Progressive Sword') + sword_count = 2 if next((i for i in pool if i in beam_swords), None) is not None else sword_count + for i in range(sword_count, 2): + pool.append('Progressive Sword') + + bow_found = next((i for i in pool if i in {'Bow', 'Progressive Bow'}), None) + if not bow_found: + pool.append('Progressive Bow') + + heart_found = next((i for i in pool if i in {'Boss Heart Container', 'Sanctuary Heart Container'}), None) + if heart_found is None: + pool.append('Boss Heart Container') + + g, t = set_default_triforce(world.goal[player], world.treasure_hunt_count[player], + world.treasure_hunt_total[player]) + if t != 0: + pieces = sum(1 for i in pool if i == 'Triforce Piece') + if pieces < t: + pool.extend(['Triforce Piece'] * (t - pieces)) + + ttl_locations = sum(1 for x in world.get_unfilled_locations(player) if '- Prize' not in x.name) + pool_size = len(get_player_dungeon_item_pool(world, player)) + len(pool) + + if pool_size < ttl_locations: + amount_to_add = ttl_locations - pool_size + pool.extend(random.choices(list(filler_items.keys()), filler_items.values(), k=amount_to_add)) + return pool, placed_items, precollected_items, clock_mode, 1 +filler_items = { + 'Arrows (10)': 12, + 'Bombs (3)': 16, + 'Rupees (300)': 5, + 'Rupees (100)': 1, + 'Rupees (50)': 7, + 'Rupees (20)': 28, + 'Rupees (5)': 4, +} + + +def get_player_dungeon_item_pool(world, player): + return [item for dungeon in world.dungeons for item in dungeon.all_items + if dungeon.player == player and item.location is None] + + # To display, count must be between 1 and 254 - larger values are not yet supported def set_default_triforce(goal, custom_goal, custom_total): triforce_goal, triforce_total = 0, 0 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 206232df..f3acda80 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -154,6 +154,10 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o ## Notes and Bug Fixes +#### Customizer + +* Fixed up the item_pool section to skip a lot of pool manipulations. Key item will be added to the bow if not detected. Extra dungeon items can be added to the pool and will be confined to the dungeon if possible (and not shuffled). If the pool isn't full, junk items are added to the pool to fill it out. + #### Volatile * 1.0.1.12 diff --git a/docs/Customizer.md b/docs/Customizer.md index 047deefe..cb951fed 100644 --- a/docs/Customizer.md +++ b/docs/Customizer.md @@ -50,20 +50,14 @@ Rom/Adjust flags like sprite, quickswap are not outputing with the print_custom_ This must be defined by player. Each player number should be listed with the appropriate pool. -Then each player can have the entire item pool defined. The name of item should be followed by the number of that item in the pool. All key items need to be listed here for now. +Then each player can have the entire item pool defined. The name of item should be followed by the number of that item in the pool. Many key items will be added to the pool if not detected. `Bottle (Random)` is supported to randomize bottle contents according to those allowed by difficulty. Pendants and crystals are supported here. -##### Known Issues +##### Caveat -1. Dungeon items amount can be increased but not eliminated (as the amount of each dungeon item is either pre-determined or calculated by door rando) and these extra items may not be confined to the dungeon -2. Door rando removes Red Rupees from the pool to make room for extra dungeon items as needed. -3. Shopsanity appends extra shop items to the pool. -4. Beemizer runs after pool creation changing junk items into bees -5. Retro + Shopsanity adds more items to the pool -6. Retro + either of dropshuffle or pottery adds keys to the pool -7. Most pottery settings add a large amount of junk items to the pool +Dungeon items amount can be increased (but not decreased as the minimum of each dungeon item is either pre-determined or calculated by door rando) if the type of dungeon item is not shuffled then it is attempted to be placed in the dungeon. Extra item beyond dungeon capacity not be confined to the dungeon. ### placements diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 3b05f7bf..7aef1796 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -75,6 +75,12 @@ class CustomSettings(object): args.shopsanity[p] = get_setting(settings['shopsanity'], args.shopsanity[p]) args.dropshuffle[p] = get_setting(settings['dropshuffle'], args.dropshuffle[p]) args.pottery[p] = get_setting(settings['pottery'], args.pottery[p]) + + if get_setting(settings['keydropshuffle'], args.keydropshuffle[p]): + args.dropshuffle[p] = True + if args.pottery[p] == 'none': + args.pottery[p] = 'keys' + args.mixed_travel[p] = get_setting(settings['mixed_travel'], args.mixed_travel[p]) args.standardize_palettes[p] = get_setting(settings['standardize_palettes'], args.standardize_palettes[p]) @@ -88,6 +94,13 @@ class CustomSettings(object): args.keyshuffle[p] = get_setting(settings['keyshuffle'], args.keyshuffle[p]) args.mapshuffle[p] = get_setting(settings['mapshuffle'], args.mapshuffle[p]) args.compassshuffle[p] = get_setting(settings['compassshuffle'], args.compassshuffle[p]) + + if get_setting(settings['keysanity'], args.keysanity): + args.bigkeyshuffle[p] = True + args.keyshuffle[p] = True + args.mapshuffle[p] = True + args.compassshuffle[p] = True + args.shufflebosses[p] = get_setting(settings['shufflebosses'], args.shufflebosses[p]) args.shuffleenemies[p] = get_setting(settings['shuffleenemies'], args.shuffleenemies[p]) args.enemy_health[p] = get_setting(settings['enemy_health'], args.enemy_health[p]) From b3c9f1cf03d4ae7c79940b4d84177157607dde59 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 14 Apr 2022 10:16:51 -0600 Subject: [PATCH 007/146] List nearly everything in custom yaml (spoiler skip and shuffled not the same right now) --- source/classes/CustomSettings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 7aef1796..0145c319 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -259,7 +259,7 @@ class CustomSettings(object): for p in self.player_range: placements[p] = {} for location in world.get_locations(): - if location.type != LocationType.Logical and not location.skip: + if location.type != LocationType.Logical: if location.player != location.item.player: placements[location.player][location.name] = f'{location.item.name}#{location.item.player}' else: From 6076441fbfcbc9c143547856bfe181a8139fe81a Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 4 Mar 2022 16:45:51 -0700 Subject: [PATCH 008/146] Fix some interior doors during key door identification as missing one reachable side --- DoorShuffle.py | 15 ++++++++++----- Main.py | 2 +- RELEASENOTES.md | 2 ++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 3d3a6eda..8c0b8e25 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -14,6 +14,7 @@ from RoomData import DoorKind, PairedDoor, reset_rooms from DungeonGenerator import ExplorationState, convert_regions, generate_dungeon, pre_validate, determine_required_paths, drop_entrances from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances from DungeonGenerator import dungeon_portals, dungeon_drops, GenerationException +from DungeonGenerator import valid_region_to_explore as valid_region_to_explore_lim from KeyDoorShuffle import analyze_dungeon, build_key_layout, validate_key_layout, determine_prize_lock from Utils import ncr, kth_combination @@ -1368,6 +1369,8 @@ def combine_layouts(recombinant_builders, dungeon_builders, entrances_map): dungeon_builders[recombine.name] = recombine +# todo: this allows cross-dungeon exploring via HC Ledge or Inaccessible Regions +# todo: @deprecated def valid_region_to_explore(region, world, player): return region and (region.type == RegionType.Dungeon or region.name in world.inaccessible_regions[player] @@ -1559,7 +1562,7 @@ okay_normals = [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind. def find_key_door_candidates(region, checked, world, player): - dungeon = region.dungeon + dungeon_name = region.dungeon.name candidates = [] checked_doors = list(checked) queue = deque([(region, None, None)]) @@ -1569,14 +1572,16 @@ def find_key_door_candidates(region, checked, world, player): d = ext.door if d and d.controller: d = d.controller - if d and not d.blocked and not d.entranceFlag and d.dest is not last_door and d.dest is not last_region and d not in checked_doors: + if d and not d.blocked and d.dest is not last_door and d.dest is not last_region and d not in checked_doors: valid = False - if 0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal, DoorType.SpiralStairs]: + if (0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal, DoorType.SpiralStairs] + and not d.entranceFlag): room = world.get_room(d.roomIndex, player) position, kind = room.doorList[d.doorListPos] - if d.type == DoorType.Interior: valid = kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable] + if valid and d.dest not in candidates: # interior doors are not separable yet + candidates.append(d.dest) elif d.type == DoorType.SpiralStairs: valid = kind in [DoorKind.StairKey, DoorKind.StairKey2, DoorKind.StairKeyLow] elif d.type == DoorType.Normal: @@ -1595,7 +1600,7 @@ def find_key_door_candidates(region, checked, world, player): if valid and d not in candidates: candidates.append(d) connected = ext.connected_region - if connected and (connected.type != RegionType.Dungeon or connected.dungeon == dungeon): + if valid_region_to_explore_lim(connected, dungeon_name, world, player): queue.append((ext.connected_region, d, current)) if d is not None: checked_doors.append(d) diff --git a/Main.py b/Main.py index 573f935f..7dc012e7 100644 --- a/Main.py +++ b/Main.py @@ -29,7 +29,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops from Utils import output_path, parse_player_names -__version__ = '1.0.0-dev' +__version__ = '1.0.1-dev' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7a224c7c..b59df407 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -15,6 +15,8 @@ CLI: ```--bombbag``` # Bug Fixes and Notes. +* 1.0.1 + * Fixed a bug with key doors not detecting one side of an interior door * 0.5.1.7 * Baserom update * Fix for Inverted Mode: Dark Lake Hylia shop defaults to selling a blue potion From 481516cc4c2af6644560d8a8cef6f7bee568ef80 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 24 Feb 2022 14:39:45 -0700 Subject: [PATCH 009/146] SSL not verified for alttpr.com/sprites --- source/classes/SpriteSelector.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/classes/SpriteSelector.py b/source/classes/SpriteSelector.py index cb76e64c..9a18cacd 100644 --- a/source/classes/SpriteSelector.py +++ b/source/classes/SpriteSelector.py @@ -4,6 +4,7 @@ import json import os import random import shutil +import ssl from urllib.parse import urlparse from urllib.request import urlopen import webbrowser @@ -149,7 +150,7 @@ class SpriteSelector(object): try: task.update_status("Downloading official sprites list") - with urlopen('https://alttpr.com/sprites') as response: + with urlopen('https://alttpr.com/sprites', context=ssl._create_unverified_context()) as response: sprites_arr = json.loads(response.read().decode("utf-8")) except Exception as e: resultmessage = "Error getting list of official sprites. Sprites not updated.\n\n%s: %s" % (type(e).__name__, e) From f9fdd6ede92c22b3b672b474f545c392331f0c3b Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 4 Mar 2022 16:46:46 -0700 Subject: [PATCH 010/146] Note for fix --- RELEASENOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b59df407..4c3ec552 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -17,6 +17,7 @@ CLI: ```--bombbag``` * 1.0.1 * Fixed a bug with key doors not detecting one side of an interior door + * Sprite selector fix for systems with SSL issues * 0.5.1.7 * Baserom update * Fix for Inverted Mode: Dark Lake Hylia shop defaults to selling a blue potion From 3df1072f0aa8cb8d70b5580d097a2bc83367f8ff Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 21 Jan 2022 16:15:51 -0700 Subject: [PATCH 011/146] Fix bombbag bug --- RELEASENOTES.md | 2 ++ Rules.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4c3ec552..28e4f5d7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -15,6 +15,8 @@ CLI: ```--bombbag``` # Bug Fixes and Notes. +* 1.0.0.1 + * Add Light Hype Fairy to bombbag mode as needing bombs * 1.0.1 * Fixed a bug with key doors not detecting one side of an interior door * Sprite selector fix for systems with SSL issues diff --git a/Rules.py b/Rules.py index 83a2175b..c2bb27ca 100644 --- a/Rules.py +++ b/Rules.py @@ -568,7 +568,7 @@ def bomb_rules(world, player): bonkable_doors = ['Two Brothers House Exit (West)', 'Two Brothers House Exit (East)'] # Technically this is incorrectly defined, but functionally the same as what is intended. bombable_doors = ['Ice Rod Cave', 'Light World Bomb Hut', 'Light World Death Mountain Shop', 'Mini Moldorm Cave', 'Hookshot Cave Back to Middle', 'Hookshot Cave Front to Middle', 'Hookshot Cave Middle to Front','Hookshot Cave Middle to Back', - 'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery'] + 'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery', 'Light Hype Fairy'] for entrance in bonkable_doors: add_rule(world.get_entrance(entrance, player), lambda state: state.can_use_bombs(player) or state.has_Boots(player)) for entrance in bombable_doors: From 42c6e18655e1076ea1f50a647e459aa1f1713aa0 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 24 May 2022 09:36:52 -0600 Subject: [PATCH 012/146] Mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) create mode 100644 .mailmap diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000..d8857508 --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ + \ No newline at end of file From 752c063a9abba5aaf3b20d52d266b8160fb5fe45 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 24 May 2022 10:00:40 -0600 Subject: [PATCH 013/146] Mailmap fix --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index d8857508..9f3cc0db 100644 --- a/.mailmap +++ b/.mailmap @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 8d5fe3088917ca9fff460f1be8c0c0f193856912 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 21 Apr 2022 11:26:24 -0600 Subject: [PATCH 014/146] Fix wording --- RELEASENOTES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 35e9c5d4..424e4c45 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -12,7 +12,7 @@ New pottery option that control which pots (and large blocks) are in the locatio not include key pots. * CaveKeys: Both non-dungeon pots and pots that used to have keys are in the pool. * Reduced: Same as CaveKeys but also roughly a quarter of dungeon pots are added to the location pool picked at random. This is a dynamic mode so pots in the pool will be colored. Pots out of the pool will have vanilla contents. -* Clustered: LIke reduced but pot are grouped by logical sets and roughly 50% of pots are chosen from those group. This is a dynamic mode like the above. +* Clustered: Like reduced but pots are grouped by logical sets and roughly 50% of pots are chosen from those group. This is a dynamic mode like the above. * Nonempty: All pots that had some sort of objects under them are chosen to be in the location pool. This excludes most large blocks and some pots out of dungeons. * Dungeon Pots: The pots that are in dungeons are in the pool. (Includes serveral large blocks) * Lottery: All pots and large blocks are in the pool @@ -166,7 +166,7 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o #### Customizer -* Fixed up the item_pool section to skip a lot of pool manipulations. Key item will be added to the bow if not detected. Extra dungeon items can be added to the pool and will be confined to the dungeon if possible (and not shuffled). If the pool isn't full, junk items are added to the pool to fill it out. +* Fixed up the item_pool section to skip a lot of pool manipulations. Key items will be added (like the bow) if not detected. Extra dungeon items can be added to the pool and will be confined to the dungeon if possible (and not shuffled). If the pool isn't full, junk items are added to the pool to fill it out. #### Volatile From dbb69359aa64b44e62f589998a0ba6adb348c9a2 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 12 May 2022 14:38:53 -0600 Subject: [PATCH 015/146] Fix customizer GUI yaml selection --- RELEASENOTES.md | 1 + source/gui/bottom.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 424e4c45..d91029d8 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -166,6 +166,7 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o #### Customizer +* Fixed up the GUI selection of the customizer file. * Fixed up the item_pool section to skip a lot of pool manipulations. Key items will be added (like the bow) if not detected. Extra dungeon items can be added to the pool and will be confined to the dungeon if possible (and not shuffled). If the pool isn't full, junk items are added to the pool to fill it out. #### Volatile diff --git a/source/gui/bottom.py b/source/gui/bottom.py index 5efeeac3..b887e1ac 100644 --- a/source/gui/bottom.py +++ b/source/gui/bottom.py @@ -220,6 +220,11 @@ def create_guiargs(parent): # Get baserom path guiargs.rom = parent.pages["randomizer"].pages["generation"].widgets["rom"].storageVar.get() + # Get customizer path + customizer_value = parent.pages["randomizer"].pages["generation"].widgets["customizer"].storageVar.get() + if customizer_value and customizer_value != 'None': + guiargs.customizer = customizer_value + # Get if we're using the Custom Item Pool guiargs.custom = bool(parent.pages["randomizer"].pages["generation"].widgets["usecustompool"].storageVar.get()) From 9a6b7c624d8d45f8f2b2cae75eb1d6ac6491d13f Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 18 May 2022 15:16:09 -0600 Subject: [PATCH 016/146] Minor fix for mystery --- source/classes/CustomSettings.py | 1 + source/tools/MysteryUtils.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 0145c319..2a8a39f6 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -59,6 +59,7 @@ class CustomSettings(object): if isinstance(player_setting, str): weights = get_weights(os.path.join(self.relative_dir, player_setting)) settings = defaultdict(lambda: None, vars(roll_settings(weights))) + args.mystery = True else: settings = defaultdict(lambda: None, player_setting) args.shuffle[p] = get_setting(settings['shuffle'], args.shuffle[p]) diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index 51c6c153..3fbbbf8d 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -46,7 +46,6 @@ def roll_settings(weights): ret = argparse.Namespace() ret.algorithm = get_choice('algorithm') - ret.mystery = get_choice_default('mystery', default=True) glitch_map = {'none': 'noglitches', 'no_logic': 'nologic', 'owglitches': 'owglitches', 'owg': 'owglitches', 'minorglitches': 'minorglitches'} From 041443be3d72bcf9e95673f0a3c3674499d3b47c Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 19 May 2022 10:28:19 -0600 Subject: [PATCH 017/146] Fix windows absolute path parsing --- source/classes/CustomSettings.py | 12 +++++++----- source/tools/MysteryUtils.py | 13 ++++++++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 2a8a39f6..c31e628f 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -4,6 +4,7 @@ import urllib.parse import yaml from yaml.representer import Representer from collections import defaultdict +from pathlib import Path import RaceRandom as random from BaseClasses import LocationType, DoorType @@ -334,10 +335,11 @@ class CustomSettings(object): def load_yaml(path): try: - if urllib.parse.urlparse(path).scheme: + return yaml.load(path, Loader=yaml.SafeLoader) + except yaml.YAMLError as exc: + if os.path.exists(Path(path)): + with open(path, "r", encoding="utf-8") as f: + return yaml.load(f, Loader=yaml.SafeLoader) + elif urllib.parse.urlparse(path).scheme in ['http', 'https']: return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) - with open(path, 'r', encoding='utf-8') as f: - return yaml.load(f, Loader=yaml.SafeLoader) - except Exception as e: - raise Exception(f'Failed to read customizer file: {e}') diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index 3fbbbf8d..9df4eca4 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -1,5 +1,7 @@ import argparse import RaceRandom as random +import os +from pathlib import Path import urllib.request import urllib.parse @@ -8,12 +10,13 @@ import yaml def get_weights(path): try: - if urllib.parse.urlparse(path).scheme: + return yaml.load(path, Loader=yaml.SafeLoader) + except yaml.YAMLError as exc: + if os.path.exists(Path(path)): + with open(path, "r", encoding="utf-8") as f: + return yaml.load(f, Loader=yaml.SafeLoader) + elif urllib.parse.urlparse(path).scheme in ['http', 'https']: return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) - with open(path, 'r', encoding='utf-8') as f: - return yaml.load(f, Loader=yaml.SafeLoader) - except Exception as e: - raise Exception(f'Failed to read weights file: {e}') def roll_settings(weights): From e40c4290c9f4d14cad6283a761dda2585ff85f1c Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 19 May 2022 12:20:30 -0600 Subject: [PATCH 018/146] Fix yaml parsing --- source/classes/CustomSettings.py | 13 +++++-------- source/tools/MysteryUtils.py | 13 +++++-------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index c31e628f..016b3b64 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -334,12 +334,9 @@ class CustomSettings(object): def load_yaml(path): - try: - return yaml.load(path, Loader=yaml.SafeLoader) - except yaml.YAMLError as exc: - if os.path.exists(Path(path)): - with open(path, "r", encoding="utf-8") as f: - return yaml.load(f, Loader=yaml.SafeLoader) - elif urllib.parse.urlparse(path).scheme in ['http', 'https']: - return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) + if os.path.exists(Path(path)): + with open(path, "r", encoding="utf-8") as f: + return yaml.load(f, Loader=yaml.SafeLoader) + elif urllib.parse.urlparse(path).scheme in ['http', 'https']: + return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index 9df4eca4..415433c0 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -9,14 +9,11 @@ import yaml def get_weights(path): - try: - return yaml.load(path, Loader=yaml.SafeLoader) - except yaml.YAMLError as exc: - if os.path.exists(Path(path)): - with open(path, "r", encoding="utf-8") as f: - return yaml.load(f, Loader=yaml.SafeLoader) - elif urllib.parse.urlparse(path).scheme in ['http', 'https']: - return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) + if os.path.exists(Path(path)): + with open(path, "r", encoding="utf-8") as f: + return yaml.load(f, Loader=yaml.SafeLoader) + elif urllib.parse.urlparse(path).scheme in ['http', 'https']: + return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) def roll_settings(weights): From ac651253fe22a6b4242b46b4ebb6ba8aae7b4690 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 12 May 2022 14:21:05 -0600 Subject: [PATCH 019/146] Fix a couple bugs on generation --- DoorShuffle.py | 6 ++++-- TestSuite.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 88b489f3..7b47c1ee 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -207,8 +207,9 @@ def vanilla_key_logic(world, player): world.dungeon_layouts[player][builder.name] = builder add_inaccessible_doors(world, player) + entrances_map, potentials, connections = determine_entrance_list(world, player) for builder in builders: - origin_list = find_accessible_entrances(world, player, builder) + origin_list = entrances_map[builder.name] start_regions = convert_regions(origin_list, world, player) doors = convert_key_doors(default_small_key_doors[builder.name], world, player) key_layout = build_key_layout(builder, start_regions, doors, world, player) @@ -1723,6 +1724,7 @@ def find_key_door_candidates(region, checked, world, player): current, last_door, last_region = queue.pop() for ext in current.exits: d = ext.door + controlled = d if d and d.controller: d = d.controller if d and not d.blocked and d.dest is not last_door and d.dest is not last_region and d not in checked_doors: @@ -1754,7 +1756,7 @@ def find_key_door_candidates(region, checked, world, player): candidates.append(d) connected = ext.connected_region if valid_region_to_explore_lim(connected, dungeon_name, world, player): - queue.append((ext.connected_region, d, current)) + queue.append((ext.connected_region, controlled, current)) if d is not None: checked_doors.append(d) return candidates, checked_doors diff --git a/TestSuite.py b/TestSuite.py index 062cb2eb..ede5ae53 100644 --- a/TestSuite.py +++ b/TestSuite.py @@ -45,7 +45,7 @@ def main(args=None): test("Vanilla ", "--shuffle vanilla") test("Retro ", "--retro --shuffle vanilla") - test("Keysanity ", "--shuffle vanilla --keydropshuffle drops_only --keysanity") + test("Keysanity ", "--shuffle vanilla --keydropshuffle --keysanity") test("Shopsanity", "--shuffle vanilla --shopsanity") test("Simple ", "--shuffle simple") test("Full ", "--shuffle full") From 3052bd75858428884edc8920e9b1e72daf7498f1 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 25 May 2022 10:28:15 -0600 Subject: [PATCH 020/146] Spelling --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 9f3cc0db..1aecc0db 100644 --- a/.mailmap +++ b/.mailmap @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 14571508ae8fabc0318080e77067261988552e5b Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 24 May 2022 11:29:41 -0600 Subject: [PATCH 021/146] Init work on decoupling doors --- BaseClasses.py | 10 +- CLI.py | 3 +- DoorShuffle.py | 75 +- Main.py | 1 + mystery_example.yml | 1 + resources/app/cli/args.json | 4 + resources/app/cli/lang/en.json | 1 + resources/app/gui/lang/en.json | 1 + .../app/gui/randomize/dungeon/widgets.json | 1 + source/classes/CustomSettings.py | 2 + source/classes/constants.py | 1 + source/dungeon/DungeonStitcher.py | 848 ++++++++++++++++++ source/tools/MysteryUtils.py | 1 + 13 files changed, 916 insertions(+), 33 deletions(-) create mode 100644 source/dungeon/DungeonStitcher.py diff --git a/BaseClasses.py b/BaseClasses.py index 2b56d39f..7c040640 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -142,6 +142,7 @@ class World(object): set_player_attr('collection_rate', False) set_player_attr('colorizepots', False) set_player_attr('pot_pool', {}) + set_player_attr('decoupledoors', False) set_player_attr('shopsanity', False) set_player_attr('mixed_travel', 'prevent') @@ -2462,6 +2463,7 @@ class Spoiler(object): 'shufflelinks': self.world.shufflelinks, 'door_shuffle': self.world.doorShuffle, 'intensity': self.world.intensity, + 'decoupledoors': self.world.decoupledoors, 'item_pool': self.world.difficulty, 'item_functionality': self.world.difficulty_adjustments, 'gt_crystals': self.world.crystals_needed_for_gt, @@ -2544,6 +2546,7 @@ class Spoiler(object): outfile.write(f"Link's House Shuffled: {yn(self.metadata['shufflelinks'])}\n") outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player]) outfile.write('Intensity: %s\n' % self.metadata['intensity'][player]) + outfile.write(f"Decouple Doors: {yn(self.metadata['decoupledoors'][player])}\n") outfile.write(f"Drop Shuffle: {yn(self.metadata['dropshuffle'][player])}\n") outfile.write(f"Pottery Mode: {self.metadata['pottery'][player]}\n") outfile.write(f"Pot Shuffle (Legacy): {yn(self.metadata['potshuffle'][player])}\n") @@ -2759,7 +2762,7 @@ goal_mode = {'ganon': 0, 'pedestal': 1, 'dungeons': 2, 'triforcehunt': 3, 'cryst diff_mode = {"normal": 0, "hard": 1, "expert": 2} func_mode = {"normal": 0, "hard": 1, "expert": 2} -# byte 3: S?MM PIII (shop, unused, mixed, palettes, intensity) +# byte 3: SDMM PIII (shop, decouple doors, mixed, palettes, intensity) # keydrop now has it's own byte mixed_travel_mode = {"prevent": 0, "allow": 1, "force": 2} # intensity is 3 bits (reserves 4-7 levels) @@ -2813,7 +2816,8 @@ class Settings(object): (goal_mode[w.goal[p]] << 5) | (diff_mode[w.difficulty[p]] << 3) | (func_mode[w.difficulty_adjustments[p]] << 1) | (1 if w.hints[p] else 0), - (0x80 if w.shopsanity[p] else 0) | (mixed_travel_mode[w.mixed_travel[p]] << 4) + (0x80 if w.shopsanity[p] else 0) | (0x40 if w.decoupledoors[p] else 0) + | (mixed_travel_mode[w.mixed_travel[p]] << 4) | (0x8 if w.standardize_palettes[p] == "original" else 0) | (0 if w.intensity[p] == "random" else w.intensity[p]), @@ -2861,7 +2865,7 @@ class Settings(object): args.retro[p] = True if settings[1] & 0x01 else False args.hints[p] = True if settings[2] & 0x01 else False args.shopsanity[p] = True if settings[3] & 0x80 else False - # args.keydropshuffle[p] = True if settings[3] & 0x40 else False + args.decoupledoors[p] = True if settings[3] & 0x40 else False args.mixed_travel[p] = r(mixed_travel_mode)[(settings[3] & 0x30) >> 4] args.standardize_palettes[p] = "original" if settings[3] & 0x8 else "standardize" intensity = settings[3] & 0x7 diff --git a/CLI.py b/CLI.py index c659d3b5..77b020b4 100644 --- a/CLI.py +++ b/CLI.py @@ -125,7 +125,7 @@ def parse_cli(argv, no_defaults=False): 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle', 'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx', - 'msu_resume', 'collection_rate', 'colorizepots']: + 'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors']: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) @@ -192,6 +192,7 @@ def parse_settings(): "keysanity": False, "door_shuffle": "basic", "intensity": 2, + 'decoupledoors': False, "experimental": False, "dungeon_counters": "default", "mixed_travel": "prevent", diff --git a/DoorShuffle.py b/DoorShuffle.py index 7b47c1ee..56a4594b 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -12,9 +12,11 @@ from Dungeons import dungeon_regions, region_starts, standard_starts, split_regi from Dungeons import dungeon_bigs, dungeon_hints from Items import ItemFactory from RoomData import DoorKind, PairedDoor, reset_rooms -from DungeonGenerator import ExplorationState, convert_regions, generate_dungeon, pre_validate, determine_required_paths, drop_entrances +from source.dungeon.DungeonStitcher import GenerationException, generate_dungeon +# from DungeonGenerator import generate_dungeon +from DungeonGenerator import ExplorationState, convert_regions, pre_validate, determine_required_paths, drop_entrances from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances -from DungeonGenerator import dungeon_portals, dungeon_drops, GenerationException +from DungeonGenerator import dungeon_portals, dungeon_drops from DungeonGenerator import valid_region_to_explore as valid_region_to_explore_lim from KeyDoorShuffle import analyze_dungeon, build_key_layout, validate_key_layout, determine_prize_lock from Utils import ncr, kth_combination @@ -780,7 +782,8 @@ def within_dungeon(world, player): for builder in world.dungeon_layouts[player].values(): shuffle_key_doors(builder, world, player) logging.getLogger('').info('%s: %s', world.fish.translate("cli", "cli", "keydoor.shuffle.time"), time.process_time()-start) - smooth_door_pairs(world, player) + if not world.decoupledoors[player]: + smooth_door_pairs(world, player) if world.intensity[player] >= 3: portal = world.get_portal('Sanctuary', player) @@ -1059,7 +1062,8 @@ def cross_dungeon(world, player): target_items += 19 # 19 pot keys d_items = target_items - all_dungeon_items_cnt world.pool_adjustment[player] = d_items - smooth_door_pairs(world, player) + if not world.decoupledoors[player]: + smooth_door_pairs(world, player) # Re-assign dungeon bosses gt = world.get_dungeon('Ganons Tower', player) @@ -1567,8 +1571,9 @@ def find_small_key_door_candidates(builder, start_regions, world, player): checked_doors.update(checked) flat_candidates = [] for candidate in candidates: - # not valid if: Normal and Pair in is Checked and Pair is not in Candidates - if candidate.type != DoorType.Normal or candidate.dest not in checked_doors or candidate.dest in candidates: + # not valid if: Normal Coupled and Pair in is Checked and Pair is not in Candidates + if (world.decoupledoors[player] or candidate.type != DoorType.Normal + or candidate.dest not in checked_doors or candidate.dest in candidates): flat_candidates.append(candidate) paired_candidates = build_pair_list(flat_candidates) @@ -1609,8 +1614,7 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True combinations = ncr(len(key_door_pool), key_doors_needed) itr = 0 start = time.process_time() - sample_list = list(range(0, int(combinations))) - random.shuffle(sample_list) + sample_list = build_sample_list(combinations) proposal = kth_combination(sample_list[itr], key_door_pool, key_doors_needed) proposal.extend(custom_key_doors) # eliminate start region if portal marked as destination @@ -1625,12 +1629,7 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True determine_prize_lock(key_layout, world, player) while not validate_key_layout(key_layout, world, player): itr += 1 - stop_early = False - if itr % 1000 == 0: - mark = time.process_time()-start - if (mark > 10 and itr*100/combinations > 50) or (mark > 20 and itr*100/combinations > 25) or mark > 30: - stop_early = True - if itr >= combinations or stop_early: + if itr >= len(sample_list): if not drop_keys: logger.info('No valid layouts for %s with %s doors', builder.name, builder.key_doors_num) return False @@ -1640,8 +1639,7 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True if builder.key_doors_num < 0: raise Exception('Bad dungeon %s - less than 0 key doors not valid' % builder.name) combinations = ncr(len(key_door_pool), max(0, key_doors_needed)) - sample_list = list(range(0, int(combinations))) - random.shuffle(sample_list) + sample_list = build_sample_list(combinations) itr = 0 start = time.process_time() # reset time since itr reset proposal = kth_combination(sample_list[itr], key_door_pool, key_doors_needed) @@ -1660,6 +1658,20 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True return True +def build_sample_list(combinations): + if combinations <= 1000000: + sample_list = list(range(0, int(combinations))) + + else: + num_set = set() + while len(num_set) < 1000000: + num_set.add(random.randint(0, combinations)) + sample_list = list(num_set) + sample_list.sort() + random.shuffle(sample_list) + return sample_list + + def log_key_logic(d_name, key_logic): logger = logging.getLogger('') if logger.isEnabledFor(logging.DEBUG): @@ -1693,7 +1705,8 @@ def build_pair_list(flat_list): queue = deque(flat_list) while len(queue) > 0: d = queue.pop() - if d.dest in queue and d.type != DoorType.SpiralStairs: + paired = d.dest.dest == d + if d.dest in queue and d.type != DoorType.SpiralStairs and paired: paired_list.append((d, d.dest)) queue.remove(d.dest) else: @@ -1716,6 +1729,7 @@ okay_normals = [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind. def find_key_door_candidates(region, checked, world, player): + decoupled = world.decoupledoors[player] dungeon_name = region.dungeon.name candidates = [] checked_doors = list(checked) @@ -1730,7 +1744,7 @@ def find_key_door_candidates(region, checked, world, player): if d and not d.blocked and d.dest is not last_door and d.dest is not last_region and d not in checked_doors: valid = False if (0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal, DoorType.SpiralStairs] - and not d.entranceFlag): + and not d.entranceFlag): room = world.get_room(d.roomIndex, player) position, kind = room.doorList[d.doorListPos] if d.type == DoorType.Interior: @@ -1740,18 +1754,21 @@ def find_key_door_candidates(region, checked, world, player): elif d.type == DoorType.SpiralStairs: valid = kind in [DoorKind.StairKey, DoorKind.StairKey2, DoorKind.StairKeyLow] elif d.type == DoorType.Normal: - d2 = d.dest - if d2 not in candidates: - if d2.type == DoorType.Normal: - room_b = world.get_room(d2.roomIndex, player) - pos_b, kind_b = room_b.doorList[d2.doorListPos] - valid = kind in okay_normals and kind_b in okay_normals and valid_key_door_pair(d, d2) - else: - valid = kind in okay_normals - if valid and 0 <= d2.doorListPos < 4: - candidates.append(d2) + if decoupled: + valid = kind in okay_normals else: - valid = True + d2 = d.dest + if d2 not in candidates: + if d2.type == DoorType.Normal: + room_b = world.get_room(d2.roomIndex, player) + pos_b, kind_b = room_b.doorList[d2.doorListPos] + valid = kind in okay_normals and kind_b in okay_normals and valid_key_door_pair(d, d2) + else: + valid = kind in okay_normals + if valid and 0 <= d2.doorListPos < 4: + candidates.append(d2) + else: + valid = True if valid and d not in candidates: candidates.append(d) connected = ext.connected_region diff --git a/Main.py b/Main.py index 1c2357bb..87289631 100644 --- a/Main.py +++ b/Main.py @@ -443,6 +443,7 @@ def copy_world(world): ret.enemy_damage = world.enemy_damage.copy() ret.beemizer = world.beemizer.copy() ret.intensity = world.intensity.copy() + ret.decoupledoors = world.decoupledoors.copy() ret.experimental = world.experimental.copy() ret.shopsanity = world.shopsanity.copy() ret.dropshuffle = world.dropshuffle.copy() diff --git a/mystery_example.yml b/mystery_example.yml index b51c58c5..8363d05d 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -17,6 +17,7 @@ 1: 2 2: 2 3: 4 + decoupledoors: off dropshuffle: on: 1 off: 1 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 7c438cbf..8b971856 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -164,6 +164,10 @@ "3", "2", "1", "random" ] }, + "deoupledoors": { + "action": "store_true", + "type": "bool" + }, "experimental": { "action": "store_true", "type": "bool" diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index 4e805b12..599915b4 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -215,6 +215,7 @@ "3: And shuffles dungeon lobbies", "random: Picks one of those at random" ], + "decoupledoors" : [ "Door entrances and exits are decoupled" ], "experimental": [ "Enable experimental features. (default: %(default)s)" ], "dungeon_counters": [ "Enable dungeon chest counters. (default: %(default)s)" ], "crystals_ganon": [ diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index c0ab9367..8e3f0f8d 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -55,6 +55,7 @@ "randomizer.dungeon.smallkeyshuffle": "Small Keys", "randomizer.dungeon.bigkeyshuffle": "Big Keys", "randomizer.dungeon.keydropshuffle": "Key Drop Shuffle (Legacy)", + "randomizer.dungeon.decoupledoors": "Decouple Doors", "randomizer.dungeon.dropshuffle": "Shuffle Enemy Key Drops", "randomizer.dungeon.potshuffle": "Pot Shuffle (Legacy)", "randomizer.dungeon.pottery": "Pottery", diff --git a/resources/app/gui/randomize/dungeon/widgets.json b/resources/app/gui/randomize/dungeon/widgets.json index 2a99ea1a..b45df12f 100644 --- a/resources/app/gui/randomize/dungeon/widgets.json +++ b/resources/app/gui/randomize/dungeon/widgets.json @@ -22,6 +22,7 @@ "width": 45 } }, + "decoupledoors": { "type": "checkbox" }, "keydropshuffle": { "type": "checkbox" }, "pottery": { "type": "selectbox", diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 016b3b64..57f9cf7e 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -87,6 +87,7 @@ class CustomSettings(object): args.standardize_palettes[p] = get_setting(settings['standardize_palettes'], args.standardize_palettes[p]) args.intensity[p] = get_setting(settings['intensity'], args.intensity[p]) + args.decoupledoors[p] = get_setting(settings['decoupledoors'], args.decoupledoors[p]) args.dungeon_counters[p] = get_setting(settings['dungeon_counters'], args.dungeon_counters[p]) args.crystals_gt[p] = get_setting(settings['crystals_gt'], args.crystals_gt[p]) args.crystals_ganon[p] = get_setting(settings['crystals_ganon'], args.crystals_ganon[p]) @@ -181,6 +182,7 @@ class CustomSettings(object): settings_dict[p]['shuffle'] = world.shuffle[p] settings_dict[p]['door_shuffle'] = world.doorShuffle[p] settings_dict[p]['intensity'] = world.intensity[p] + settings_dict[p]['decoupledoors'] = world.decoupledoors[p] settings_dict[p]['logic'] = world.logic[p] settings_dict[p]['mode'] = world.mode[p] settings_dict[p]['swords'] = world.swords[p] diff --git a/source/classes/constants.py b/source/classes/constants.py index 4de4ac13..677e163b 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -95,6 +95,7 @@ SETTINGSTOPROCESS = { "bigkeyshuffle": "bigkeyshuffle", "dungeondoorshuffle": "door_shuffle", "dungeonintensity": "intensity", + "decoupledoors": "decoupledoors", "keydropshuffle": "keydropshuffle", "dropshuffle": "dropshuffle", "pottery": "pottery", diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py new file mode 100644 index 00000000..e16b449d --- /dev/null +++ b/source/dungeon/DungeonStitcher.py @@ -0,0 +1,848 @@ +import RaceRandom as random +import collections +import logging +import time + +from BaseClasses import CrystalBarrier, DoorType, Hook, RegionType, Sector +from BaseClasses import hook_from_door, flooded_keys +from Regions import dungeon_events, flooded_keys_reverse + + +def pre_validate(builder, entrance_region_names, split_dungeon, world, player): + pass + # todo: determine the part of check_valid that are necessary here + + +def generate_dungeon(builder, entrance_region_names, split_dungeon, world, player): + if builder.valid_proposal: # we made this earlier in gen, just use it + proposed_map = builder.valid_proposal + else: + proposed_map = generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon, world, player) + builder.valid_proposal = proposed_map + queue = collections.deque(proposed_map.items()) + while len(queue) > 0: + a, b = queue.popleft() + if world.decoupledoors[player]: + connect_doors_one_way(a, b) + else: + connect_doors(a, b) + queue.remove((b, a)) + if len(builder.sectors) == 0: + return Sector() + available_sectors = list(builder.sectors) + master_sector = available_sectors.pop() + for sub_sector in available_sectors: + master_sector.regions.extend(sub_sector.regions) + master_sector.outstanding_doors.clear() + master_sector.r_name_set = None + return master_sector + + +def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon, world, player): + logger = logging.getLogger('') + name = builder.name + logger.debug(f'Generating Dungeon: {name}') + entrance_regions = convert_regions(entrance_region_names, world, player) + excluded = {} + for region in entrance_regions: + portal = next((x for x in world.dungeon_portals[player] if x.door.entrance.parent_region == region), None) + if portal: + if portal.destination: + excluded[region] = None + elif len(entrance_regions) > 1: + p_region = portal.door.entrance.connected_region + access_region = next(x.parent_region for x in p_region.entrances + if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld]) + if (access_region.name in world.inaccessible_regions[player] and + region.name not in world.enabled_entrances[player]): + excluded[region] = None + elif len(region.entrances) == 1: # for holes + access_region = next(x.parent_region for x in region.entrances + if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld] + or x.parent_region.name == 'Sewer Drop') + if access_region.name == 'Sewer Drop': + access_region = next(x.parent_region for x in access_region.entrances) + if (access_region.name in world.inaccessible_regions[player] and + region.name not in world.enabled_entrances[player]): + excluded[region] = None + entrance_regions = [x for x in entrance_regions if x not in excluded.keys()] + doors_to_connect, idx = {}, 0 + all_regions = set() + bk_special = False + for sector in builder.sectors: + for door in sector.outstanding_doors: + doors_to_connect[door.name] = door, idx + idx += 1 + all_regions.update(sector.regions) + bk_special |= check_for_special(sector.regions) + bk_needed = False + for sector in builder.sectors: + bk_needed |= determine_if_bk_needed(sector, split_dungeon, bk_special, world, player) + finished = False + # flag if standard and this is hyrule castle + paths = determine_paths_for_dungeon(world, player, all_regions, name) + proposed_map = create_random_proposal(doors_to_connect, world, player) + itr = 0 + hash_code = proposal_hash(doors_to_connect, proposed_map) + hash_code_set = set() + start = time.time() + while not finished: + if itr > 1000: + elasped = time.time() - start + raise GenerationException(f'Generation taking too long. {elasped}. Ref {name}') + if hash_code in hash_code_set: + proposed_map = create_random_proposal(doors_to_connect, world, player) + hash_code = proposal_hash(doors_to_connect, proposed_map) + if hash_code not in hash_code_set: + hash_code_set.add(hash_code) + explored_state = explore_proposal(name, entrance_regions, all_regions, proposed_map, doors_to_connect, + bk_needed, bk_special, world, player) + if check_valid(name, explored_state, proposed_map, doors_to_connect, all_regions, + bk_needed, bk_special, paths, entrance_regions, world, player): + finished = True + else: + proposed_map, hash_code = modify_proposal(proposed_map, explored_state, doors_to_connect, + hash_code_set, world, player) + itr += 1 + return proposed_map + + +def create_random_proposal(doors_to_connect, world, player): + logger = logging.getLogger('') + hooks = [Hook.North, Hook.South, Hook.East, Hook.West, Hook.Stairs] + primary_bucket = collections.defaultdict(list) + secondary_bucket = collections.defaultdict(list) + for name, door in doors_to_connect.items(): + door, idx = door + primary_bucket[hook_from_door(door)].append(door) + secondary_bucket[hook_from_door(door)].append(door) + proposal = {} + while True: + hooks_left, left = [], 0 + for hook in hooks: + hook_len = len(primary_bucket[hook]) + if hook_len > 0: + hooks_left.append(hook) + left += hook_len + if left == 0: + return proposal + next_hook = random.choice(hooks_left) + primary_door = random.choice(primary_bucket[next_hook]) + opp_hook, secondary_door = type_map[next_hook], None + while (secondary_door is None or secondary_door == primary_door + or decouple_check(primary_bucket[next_hook], secondary_bucket[opp_hook], + primary_door, secondary_door, world, player)): + secondary_door = random.choice(secondary_bucket[opp_hook]) + proposal[primary_door] = secondary_door + primary_bucket[next_hook].remove(primary_door) + secondary_bucket[opp_hook].remove(secondary_door) + if not world.decoupledoors[player]: + proposal[secondary_door] = primary_door + primary_bucket[opp_hook].remove(secondary_door) + secondary_bucket[next_hook].remove(primary_door) + logger.debug(f'Linking {primary_door.name} <-> {secondary_door.name}') + else: + logger.debug(f'Linking {primary_door.name} -> {secondary_door.name}') + + +def decouple_check(primary_list, secondary_list, primary_door, secondary_door, world, player): + if world.decoupledoors[player] and len(primary_list) == 2 and len(secondary_list) == 2: + primary_alone = next(d for d in primary_list if d != primary_door) + secondary_alone = next(d for d in secondary_list if d != secondary_door) + return primary_alone == secondary_alone + return False + + +def proposal_hash(doors_to_connect, proposed_map): + hash_code = '' + for name, door_pair in doors_to_connect.items(): + door, idx = door_pair + hash_code += str(idx) + str(doors_to_connect[proposed_map[door].name][1]) + return hash_code + + +def modify_proposal(proposed_map, explored_state, doors_to_connect, hash_code_set, world, player): + logger = logging.getLogger('') + hash_code, itr = None, 0 + while hash_code is None or hash_code in hash_code_set: + if itr > 10: + proposed_map = create_random_proposal(doors_to_connect, world, player) + hash_code = proposal_hash(doors_to_connect, proposed_map) + return proposed_map, hash_code + visited_bucket = collections.defaultdict(list) + unvisted_bucket = collections.defaultdict(list) + visited_choices = [] + unvisted_count = 0 + for door_one, door_two in proposed_map.items(): + if door_one in explored_state.visited_doors: + visited_bucket[hook_from_door(door_one)].append(door_one) + visited_choices.append(door_one) + else: + unvisted_bucket[hook_from_door(door_one)].append(door_one) + unvisted_count += 1 + if unvisted_count == 0: + # something is wrong beyond connectedness, crystal switch puzzle or bk layout - reshuffle + proposed_map = create_random_proposal(doors_to_connect, world, player) + hash_code = proposal_hash(doors_to_connect, proposed_map) + return proposed_map, hash_code + + attempt, opp_hook = None, None + opp_hook_len = 0 + while opp_hook_len == 0: + attempt = random.choice(visited_choices) + opp_hook = type_map[hook_from_door(attempt)] + opp_hook_len = len(unvisted_bucket[opp_hook]) + unvisted_bucket[opp_hook].sort(key=lambda d: d.name) + new_door = random.choice(unvisted_bucket[opp_hook]) + old_target = proposed_map[attempt] + proposed_map[attempt] = new_door + if not world.decoupledoors[player]: + old_attempt = proposed_map[new_door] + else: + old_attempt = next(x for x in proposed_map if proposed_map[x] == new_door) + proposed_map[old_attempt] = old_target + if not world.decoupledoors[player]: + proposed_map[old_target] = old_attempt + proposed_map[new_door] = attempt + hash_code = proposal_hash(doors_to_connect, proposed_map) + itr += 1 + + if not world.decoupledoors[player]: + logger.debug(f'Re-linking {attempt.name} <-> {new_door.name}') + logger.debug(f'Re-linking {old_attempt.name} <-> {old_target.name}') + else: + logger.debug(f'Re-Linking {attempt.name} -> {new_door.name}') + logger.debug(f'Re-Linking {old_attempt.name} -> {old_target.name}') + hash_code_set.add(hash_code) + return proposed_map, hash_code + + +def explore_proposal(name, entrance_regions, all_regions, proposed_map, valid_doors, + bk_needed, bk_special, world, player): + start = ExplorationState(dungeon=name) + start.big_key_special = bk_special + + bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed + + def exception(d): + return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS' + original_state = extend_reachable_state_improved(entrance_regions, start, proposed_map, all_regions, + valid_doors, bk_flag, world, player, exception) + return original_state + + +def check_valid(name, exploration_state, proposed_map, doors_to_connect, all_regions, + bk_needed, bk_special, paths, entrance_regions, world, player): + all_visited = set() + all_visited.update(exploration_state.visited_blue) + all_visited.update(exploration_state.visited_orange) + if len(all_regions.difference(all_visited)) > 0: + return False + if not valid_paths(name, paths, entrance_regions, doors_to_connect, all_regions, proposed_map, + bk_needed, bk_special, world, player): + return False + return True + + +def determine_if_bk_needed(sector, split_dungeon, bk_special, world, player): + if not split_dungeon or bk_special: + for region in sector.regions: + for ext in region.exits: + door = world.check_for_door(ext.name, player) + if door is not None and door.bigKey: + return True + return False + + +def check_for_special(regions): + for region in regions: + for loc in region.locations: + if loc.forced_big_key(): + return True + return False + + +def valid_paths(name, paths, entrance_regions, valid_doors, all_regions, proposed_map, + bk_needed, bk_special, world, player): + for path in paths: + if type(path) is tuple: + target = path[1] + start_regions = [] + for region in all_regions: + if path[0] == region.name: + start_regions.append(region) + break + else: + target = path + start_regions = entrance_regions + if not valid_path(name, start_regions, target, valid_doors, proposed_map, all_regions, + bk_needed, bk_special, world, player): + return False + return True + + +def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_regions, + bk_needed, bk_special, world, player): + target_regions = set() + if type(target) is not list: + for region in all_regions: + if target == region.name: + target_regions.add(region) + break + else: + for region in all_regions: + if region.name in target: + target_regions.add(region) + + start = ExplorationState(dungeon=name) + start.big_key_special = bk_special + bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed + + def exception(d): + return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS' + original_state = extend_reachable_state_improved(starting_regions, start, proposed_map, all_regions, + valid_doors, bk_flag, world, player, exception) + + for exp_door in original_state.unattached_doors: + if not exp_door.door.blocked: + return True # outstanding connection possible + for target in target_regions: + if original_state.visited_at_all(target): + return True + return False # couldn't find an outstanding door or the target + + +boss_path_checks = ['Eastern Boss', 'Desert Boss', 'Hera Boss', 'Tower Agahnim 1', 'PoD Boss', 'Swamp Boss', + 'Skull Boss', 'Ice Boss', 'Mire Boss', 'TR Boss', 'GT Agahnim 2'] + +# pinball is allowed to orphan you +drop_path_checks = ['Skull Pot Circle', 'Skull Left Drop', 'Skull Back Drop', 'Sewers Rat Path'] + + +def determine_paths_for_dungeon(world, player, all_regions, name): + all_r_names = set(x.name for x in all_regions) + paths = [] + non_hole_portals = [] + for portal in world.dungeon_portals[player]: + if portal.door.entrance.parent_region in all_regions: + non_hole_portals.append(portal.door.entrance.parent_region.name) + if portal.destination: + paths.append(portal.door.entrance.parent_region.name) + if world.mode[player] == 'standard' and name == 'Hyrule Castle': + paths.append('Hyrule Dungeon Cellblock') + paths.append(('Hyrule Dungeon Cellblock', 'Sanctuary')) + if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town': + paths.append('Thieves Attic Window') + elif 'Thieves Attic Window' in all_r_names: + paths.append('Thieves Attic Window') + for boss in boss_path_checks: + if boss in all_r_names: + paths.append(boss) + if 'Thieves Boss' in all_r_names: + paths.append('Thieves Boss') + if world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind': + paths.append(('Thieves Blind\'s Cell', 'Thieves Boss')) + for drop_check in drop_path_checks: + if drop_check in all_r_names: + paths.append((drop_check, non_hole_portals)) + return paths + + +def convert_regions(region_names, world, player): + region_list = [] + for name in region_names: + region_list.append(world.get_region(name, player)) + return region_list + + +type_map = { + Hook.Stairs: Hook.Stairs, + Hook.North: Hook.South, + Hook.South: Hook.North, + Hook.West: Hook.East, + Hook.East: Hook.West +} + + +def connect_doors(a, b): + # Return on unsupported types. + if a.type in [DoorType.Hole, DoorType.Warp, DoorType.Interior, DoorType.Logical]: + return + # Connect supported types + if a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]: + if a.blocked: + connect_one_way(b.entrance, a.entrance) + elif b.blocked: + connect_one_way(a.entrance, b.entrance) + else: + connect_two_way(a.entrance, b.entrance) + dep_doors, target = [], None + if len(a.dependents) > 0: + dep_doors, target = a.dependents, b + elif len(b.dependents) > 0: + dep_doors, target = b.dependents, a + if target is not None: + target_region = target.entrance.parent_region + for dep in dep_doors: + connect_simple_door(dep, target_region) + return + # If we failed to account for a type, panic + raise RuntimeError('Unknown door type ' + a.type.name) + + +def connect_doors_one_way(a, b): + # Return on unsupported types. + if a.type in [DoorType.Hole, DoorType.Warp, DoorType.Interior, DoorType.Logical]: + return + # Connect supported types + if a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]: + if not a.blocked: + connect_one_way(a.entrance, b.entrance) + dep_doors, target = [], None + if len(a.dependents) > 0: + dep_doors, target = a.dependents, b + if target is not None: + target_region = target.entrance.parent_region + for dep in dep_doors: + connect_simple_door(dep, target_region) + return + # If we failed to account for a type, panic + raise RuntimeError('Unknown door type ' + a.type.name) + + +def connect_two_way(entrance, ext): + + # if these were already connected somewhere, remove the backreference + if entrance.connected_region is not None: + entrance.connected_region.entrances.remove(entrance) + if ext.connected_region is not None: + ext.connected_region.entrances.remove(ext) + + entrance.connect(ext.parent_region) + ext.connect(entrance.parent_region) + if entrance.parent_region.dungeon: + ext.parent_region.dungeon = entrance.parent_region.dungeon + x = entrance.door + y = ext.door + if x is not None: + x.dest = y + if y is not None: + y.dest = x + + +def connect_one_way(entrance, ext): + + # if these were already connected somewhere, remove the backreference + if entrance.connected_region is not None: + entrance.connected_region.entrances.remove(entrance) + + entrance.connect(ext.parent_region) + if entrance.parent_region.dungeon: + ext.parent_region.dungeon = entrance.parent_region.dungeon + x = entrance.door + if x is not None: + x.dest = ext.door + + +def connect_simple_door(exit_door, region): + exit_door.entrance.connect(region) + exit_door.dest = region + + +special_big_key_doors = ['Hyrule Dungeon Cellblock Door', "Thieves Blind's Cell Door"] + + +class ExplorationState(object): + + def __init__(self, init_crystal=CrystalBarrier.Orange, dungeon=None): + + self.unattached_doors = [] + self.avail_doors = [] + self.event_doors = [] + + self.visited_orange = [] + self.visited_blue = [] + self.visited_doors = set() + self.events = set() + self.crystal = init_crystal + + # key region stuff + self.door_krs = {} + + # key validation stuff + self.small_doors = [] + self.big_doors = [] + self.opened_doors = [] + self.big_key_opened = False + self.big_key_special = False + + self.found_locations = [] + self.ttl_locations = 0 + self.used_locations = 0 + self.key_locations = 0 + self.used_smalls = 0 + self.bk_found = set() + + self.non_door_entrances = [] + self.dungeon = dungeon + self.pinball_used = False + + self.prize_door_set = {} + self.prize_doors = [] + self.prize_doors_opened = False + + def copy(self): + ret = ExplorationState(dungeon=self.dungeon) + ret.unattached_doors = list(self.unattached_doors) + ret.avail_doors = list(self.avail_doors) + ret.event_doors = list(self.event_doors) + ret.visited_orange = list(self.visited_orange) + ret.visited_blue = list(self.visited_blue) + ret.events = set(self.events) + ret.crystal = self.crystal + ret.door_krs = self.door_krs.copy() + + ret.small_doors = list(self.small_doors) + ret.big_doors = list(self.big_doors) + ret.opened_doors = list(self.opened_doors) + ret.big_key_opened = self.big_key_opened + ret.big_key_special = self.big_key_special + ret.ttl_locations = self.ttl_locations + ret.key_locations = self.key_locations + ret.used_locations = self.used_locations + ret.used_smalls = self.used_smalls + ret.found_locations = list(self.found_locations) + ret.bk_found = set(self.bk_found) + + ret.non_door_entrances = list(self.non_door_entrances) + ret.dungeon = self.dungeon + ret.pinball_used = self.pinball_used + + ret.prize_door_set = dict(self.prize_door_set) + ret.prize_doors = list(self.prize_doors) + ret.prize_doors_opened = self.prize_doors_opened + return ret + + def next_avail_door(self): + self.avail_doors.sort(key=lambda x: 0 if x.flag else 1 if x.door.bigKey else 2) + exp_door = self.avail_doors.pop() + self.crystal = exp_door.crystal + return exp_door + + def visit_region(self, region, key_region=None, key_checks=False, bk_flag=False): + if region.type != RegionType.Dungeon: + self.crystal = CrystalBarrier.Orange + if self.crystal == CrystalBarrier.Either: + if region not in self.visited_blue: + self.visited_blue.append(region) + if region not in self.visited_orange: + self.visited_orange.append(region) + elif self.crystal == CrystalBarrier.Orange: + self.visited_orange.append(region) + elif self.crystal == CrystalBarrier.Blue: + self.visited_blue.append(region) + if region.type == RegionType.Dungeon: + for location in region.locations: + if key_checks and location not in self.found_locations: + if location.forced_item and 'Small Key' in location.item.name: + self.key_locations += 1 + if location.name not in dungeon_events and '- Prize' not in location.name and location.name not in ['Agahnim 1', 'Agahnim 2']: + self.ttl_locations += 1 + if location not in self.found_locations: # todo: special logic for TT Boss? + self.found_locations.append(location) + if not bk_flag: + self.bk_found.add(location) + if location.name in dungeon_events and location.name not in self.events: + if self.flooded_key_check(location): + self.perform_event(location.name, key_region) + if location.name in flooded_keys_reverse.keys() and self.location_found( + flooded_keys_reverse[location.name]): + self.perform_event(flooded_keys_reverse[location.name], key_region) + if '- Prize' in location.name: + self.prize_received = True + + def flooded_key_check(self, location): + if location.name not in flooded_keys.keys(): + return True + return flooded_keys[location.name] in [x.name for x in self.found_locations] + + def location_found(self, location_name): + for l in self.found_locations: + if l.name == location_name: + return True + return False + + def perform_event(self, location_name, key_region): + self.events.add(location_name) + queue = collections.deque(self.event_doors) + while len(queue) > 0: + exp_door = queue.popleft() + if exp_door.door.req_event == location_name: + self.avail_doors.append(exp_door) + self.event_doors.remove(exp_door) + if key_region is not None: + d_name = exp_door.door.name + if d_name not in self.door_krs.keys(): + self.door_krs[d_name] = key_region + + def add_all_entrance_doors_check_unattached(self, region, world, player): + door_list = [x for x in get_doors(world, region, player) if x.type in [DoorType.Normal, DoorType.SpiralStairs]] + door_list.extend(get_entrance_doors(world, region, player)) + for door in door_list: + if self.can_traverse(door): + if door.dest is None and not self.in_door_list_ic(door, self.unattached_doors): + self.append_door_to_list(door, self.unattached_doors) + elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, + self.event_doors): + self.append_door_to_list(door, self.event_doors) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors) + for entrance in region.entrances: + door = world.check_for_door(entrance.name, player) + if door is None: + self.non_door_entrances.append(entrance) + + def add_all_doors_check_unattached(self, region, world, player): + for door in get_doors(world, region, player): + if self.can_traverse(door): + if door.controller is not None: + door = door.controller + if door.dest is None and not self.in_door_list_ic(door, self.unattached_doors): + self.append_door_to_list(door, self.unattached_doors) + elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, + self.event_doors): + self.append_door_to_list(door, self.event_doors) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors) + + def add_all_doors_check_proposed(self, region, proposed_map, valid_doors, flag, world, player, exception): + for door in get_doors(world, region, player): + if door in proposed_map and door.name in valid_doors: + self.visited_doors.add(door) + if door.blocked and exception(door): + self.pinball_used = True + if self.can_traverse(door, exception): + if door.controller is not None: + door = door.controller + if door.dest is None and door not in proposed_map.keys() and door.name in valid_doors: + if not self.in_door_list_ic(door, self.unattached_doors): + self.append_door_to_list(door, self.unattached_doors, flag) + else: + other = self.find_door_in_list(door, self.unattached_doors) + if self.crystal != other.crystal: + other.crystal = CrystalBarrier.Either + elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, + self.event_doors): + self.append_door_to_list(door, self.event_doors, flag) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors, flag) + + def add_all_doors_check_key_region(self, region, key_region, world, player): + for door in get_doors(world, region, player): + if self.can_traverse(door): + if door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, + self.event_doors): + self.append_door_to_list(door, self.event_doors) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors) + if door.name not in self.door_krs.keys(): + self.door_krs[door.name] = key_region + else: + if door.name not in self.door_krs.keys(): + self.door_krs[door.name] = key_region + + def add_all_doors_check_keys(self, region, key_door_proposal, world, player): + for door in get_doors(world, region, player): + if self.can_traverse(door): + if door.controller: + door = door.controller + if door in key_door_proposal and door not in self.opened_doors: + if not self.in_door_list(door, self.small_doors): + self.append_door_to_list(door, self.small_doors) + elif (door.bigKey or door.name in special_big_key_doors) and not self.big_key_opened: + if not self.in_door_list(door, self.big_doors): + self.append_door_to_list(door, self.big_doors) + elif door.req_event is not None and door.req_event not in self.events: + if not self.in_door_list(door, self.event_doors): + self.append_door_to_list(door, self.event_doors) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors) + + def visited(self, region): + if self.crystal == CrystalBarrier.Either: + return region in self.visited_blue and region in self.visited_orange + elif self.crystal == CrystalBarrier.Orange: + return region in self.visited_orange + elif self.crystal == CrystalBarrier.Blue: + return region in self.visited_blue + return False + + def visited_at_all(self, region): + return region in self.visited_blue or region in self.visited_orange + + def found_forced_bk(self): + for location in self.found_locations: + if location.forced_big_key(): + return True + return False + + def can_traverse(self, door, exception=None): + if door.blocked: + return exception(door) if exception else False + if door.crystal not in [CrystalBarrier.Null, CrystalBarrier.Either]: + return self.crystal == CrystalBarrier.Either or door.crystal == self.crystal + return True + + def count_locations_exclude_specials(self, world, player): + return count_locations_exclude_big_chest(self.found_locations, world, player) + + def validate(self, door, region, world, player): + return self.can_traverse(door) and not self.visited(region) and valid_region_to_explore(region, self.dungeon, + world, player) + + def in_door_list(self, door, door_list): + for d in door_list: + if d.door == door and d.crystal == self.crystal: + return True + return False + + @staticmethod + def in_door_list_ic(door, door_list): + for d in door_list: + if d.door == door: + return True + return False + + @staticmethod + def find_door_in_list(door, door_list): + for d in door_list: + if d.door == door: + return d + return None + + def append_door_to_list(self, door, door_list, flag=False): + if door.crystal == CrystalBarrier.Null: + door_list.append(ExplorableDoor(door, self.crystal, flag)) + else: + door_list.append(ExplorableDoor(door, door.crystal, flag)) + + def key_door_sort(self, d): + if d.door.smallKey: + if d.door in self.opened_doors: + return 1 + else: + return 0 + return 2 + + +def count_locations_exclude_big_chest(locations, world, player): + cnt = 0 + for loc in locations: + if ('- Big Chest' not in loc.name and not loc.forced_item and not reserved_location(loc, world, player) + and not prize_or_event(loc) and not blind_boss_unavail(loc, locations, world, player)): + cnt += 1 + return cnt + + +def prize_or_event(loc): + return loc.name in dungeon_events or '- Prize' in loc.name or loc.name in ['Agahnim 1', 'Agahnim 2'] + + +def reserved_location(loc, world, player): + return hasattr(world, 'item_pool_config') and loc.name in world.item_pool_config.reserved_locations[player] + + +def blind_boss_unavail(loc, locations, world, player): + if loc.name == "Thieves' Town - Boss": + return (loc.parent_region.dungeon.boss.name == 'Blind' and + (not any(x for x in locations if x.name == 'Suspicious Maiden') or + (world.get_region('Thieves Attic Window', player).dungeon.name == 'Thieves Town' and + not any(x for x in locations if x.name == 'Attic Cracked Floor')))) + return False + + +class ExplorableDoor(object): + + def __init__(self, door, crystal, flag): + self.door = door + self.crystal = crystal + self.flag = flag + + def __str__(self): + return str(self.__unicode__()) + + def __unicode__(self): + return '%s (%s)' % (self.door.name, self.crystal.name) + + +def extend_reachable_state_improved(search_regions, state, proposed_map, all_regions, valid_doors, bk_flag, world, player, exception): + local_state = state.copy() + for region in search_regions: + local_state.visit_region(region) + local_state.add_all_doors_check_proposed(region, proposed_map, valid_doors, False, world, player, exception) + while len(local_state.avail_doors) > 0: + explorable_door = local_state.next_avail_door() + if explorable_door.door.bigKey: + if bk_flag: + big_not_found = (not special_big_key_found(local_state) if local_state.big_key_special + else local_state.count_locations_exclude_specials(world, player) == 0) + if big_not_found: + continue # we can't open this door + if explorable_door.door in proposed_map: + connect_region = world.get_entrance(proposed_map[explorable_door.door].name, player).parent_region + else: + connect_region = world.get_entrance(explorable_door.door.name, player).connected_region + if connect_region is not None: + if valid_region_to_explore_in_regions(connect_region, all_regions, world, player) and not local_state.visited( + connect_region): + flag = explorable_door.flag or explorable_door.door.bigKey + local_state.visit_region(connect_region, bk_flag=flag) + local_state.add_all_doors_check_proposed(connect_region, proposed_map, valid_doors, flag, world, player, exception) + return local_state + + +def special_big_key_found(state): + for location in state.found_locations: + if location.forced_item and location.forced_item.bigkey: + return True + return False + + +def valid_region_to_explore_in_regions(region, all_regions, world, player): + if region is None: + return False + return ((region.type == RegionType.Dungeon and region in all_regions) + or region.name in world.inaccessible_regions[player] + or (region.name == 'Hyrule Castle Ledge' and world.mode[player] == 'standard')) + + +def valid_region_to_explore(region, name, world, player): + if region is None: + return False + return ((region.type == RegionType.Dungeon and region.dungeon and region.dungeon.name in name) + or region.name in world.inaccessible_regions[player] + or (region.name == 'Hyrule Castle Ledge' and world.mode[player] == 'standard')) + + +def get_doors(world, region, player): + res = [] + for ext in region.exits: + door = world.check_for_door(ext.name, player) + if door is not None: + res.append(door) + return res + + +def get_entrance_doors(world, region, player): + res = [] + for ext in region.entrances: + door = world.check_for_door(ext.name, player) + if door is not None: + res.append(door) + return res + + +class GenerationException(Exception): + pass + + diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index 415433c0..8325719b 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -77,6 +77,7 @@ def roll_settings(weights): door_shuffle = get_choice('door_shuffle') ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla' ret.intensity = get_choice('intensity') + ret.decoupledoors = get_choice('decoupledoors') == 'on' ret.experimental = get_choice('experimental') == 'on' ret.collection_rate = get_choice('collection_rate') == 'on' From 6e9d949439c5df5933d19052764d85cb774365c7 Mon Sep 17 00:00:00 2001 From: Catobat <69204835+Catobat@users.noreply.github.com> Date: Mon, 13 Jun 2022 20:38:24 +0200 Subject: [PATCH 022/146] Shuffle Back of Tavern --- BaseClasses.py | 7 ++- CLI.py | 5 +- ER_hint_reference.txt | 2 + EntranceShuffle.py | 4 +- Main.py | 3 +- README.md | 5 ++ Rom.py | 6 ++- data/base2current.bps | Bin 93021 -> 93118 bytes mystery_testsuite.yml | 3 ++ resources/app/cli/args.json | 4 ++ resources/app/cli/lang/en.json | 3 ++ resources/app/gui/lang/en.json | 1 + .../app/gui/randomize/entrando/widgets.json | 1 + source/classes/CustomSettings.py | 2 + source/classes/constants.py | 1 + source/overworld/EntranceShuffle2.py | 44 ++++++++++-------- source/tools/MysteryUtils.py | 1 + 17 files changed, 64 insertions(+), 28 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 2b56d39f..fd9e0c9c 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2460,6 +2460,7 @@ class Spoiler(object): 'goal': self.world.goal, 'shuffle': self.world.shuffle, 'shufflelinks': self.world.shufflelinks, + 'shuffletavern': self.world.shuffletavern, 'door_shuffle': self.world.doorShuffle, 'intensity': self.world.intensity, 'item_pool': self.world.difficulty, @@ -2541,7 +2542,8 @@ class Spoiler(object): outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player]) outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player]) outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player]) - outfile.write(f"Link's House Shuffled: {yn(self.metadata['shufflelinks'])}\n") + outfile.write(f"Link's House Shuffled: {yn(self.metadata['shufflelinks'][player])}\n") + outfile.write(f"Back of Tavern Shuffled: {yn(self.metadata['shuffletavern'][player])}\n") outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player]) outfile.write('Intensity: %s\n' % self.metadata['intensity'][player]) outfile.write(f"Drop Shuffle: {yn(self.metadata['dropshuffle'][player])}\n") @@ -2827,7 +2829,7 @@ class Settings(object): (0x80 if w.bigkeyshuffle[p] else 0) | (0x40 if w.keyshuffle[p] else 0) | (0x20 if w.mapshuffle[p] else 0) | (0x10 if w.compassshuffle[p] else 0) - | (enemy_mode[w.enemy_shuffle[p]]), + | (0x8 if w.shuffletavern[p] else 0) | (enemy_mode[w.enemy_shuffle[p]]), (e_health[w.enemy_health[p]] << 5) | (e_dmg[w.enemy_damage[p]] << 3) | (0x4 if w.potshuffle[p] else 0) | (0x2 if w.bombbag[p] else 0) | (1 if w.shufflelinks[p] else 0), @@ -2885,6 +2887,7 @@ class Settings(object): args.mapshuffle[p] = True if settings[7] & 0x20 else False args.compassshuffle[p] = True if settings[7] & 0x10 else False # args.shufflebosses[p] = r(boss_mode)[(settings[7] & 0xc) >> 2] + args.shuffletavern[p] = True if settings[7] & 0x8 else False args.shuffleenemies[p] = r(enemy_mode)[settings[7] & 0x3] args.enemy_health[p] = r(e_health)[(settings[8] & 0xE0) >> 5] diff --git a/CLI.py b/CLI.py index c659d3b5..62fee1b3 100644 --- a/CLI.py +++ b/CLI.py @@ -119,8 +119,8 @@ def parse_cli(argv, no_defaults=False): 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'usestartinventory', 'bombbag', 'overworld_map', 'restrict_boss_items', 'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max', - 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'pseudoboots', - 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', + 'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'shuffletavern', + 'pseudoboots', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle', @@ -170,6 +170,7 @@ def parse_settings(): "shuffleganon": True, "shuffle": "vanilla", "shufflelinks": False, + "shuffletavern": False, "overworld_map": "default", "pseudoboots": False, diff --git a/ER_hint_reference.txt b/ER_hint_reference.txt index 999fb436..018dfb3a 100644 --- a/ER_hint_reference.txt +++ b/ER_hint_reference.txt @@ -91,6 +91,7 @@ While the exact verbage of location names and item names can be found in the sou Overworld Entrance naming: +Links House: The hero's old residence Turtle Rock: Turtle Rock Main Misery Mire: Misery Mire Ice Palace: Ice Palace @@ -141,6 +142,7 @@ Lake Hylia Fairy: A cave NE of Lake Hylia Light Hype Fairy: The cave south of your house Desert Fairy: The cave near the desert Chicken House: The chicken lady's house +Tavern North: A backdoor Aginahs Cave: The open desert cave Sahasrahlas Hut: The house near armos Cave Shop (Lake Hylia): The cave NW Lake Hylia diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 0d3f502b..2899b28b 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -3364,7 +3364,7 @@ door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000)), 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000)), 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x08f9, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), # do not use, buggy + 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x091b, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000)), 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000)), 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000)), @@ -3653,7 +3653,7 @@ ow_prize_table = {'Links House': (0x8b1, 0xb2d), 'Inverted Big Bomb Shop': (0x8b 'Light Hype Fairy': (0x940, 0xc80), 'Desert Fairy': (0x420, 0xe00), 'Kings Grave': (0x920, 0x520), - 'Tavern North': None, # can't mark this one technically + 'Tavern North': (0x270, 0x900), 'Chicken House': (0x120, 0x880), 'Aginahs Cave': (0x2e0, 0xd00), 'Sahasrahlas Hut': (0xcf0, 0x6c0), diff --git a/Main.py b/Main.py index 1c2357bb..19515022 100644 --- a/Main.py +++ b/Main.py @@ -118,6 +118,7 @@ def main(args, seed=None, fish=None): world.treasure_hunt_count = {k: int(v) for k, v in args.triforce_goal.items()} world.treasure_hunt_total = {k: int(v) for k, v in args.triforce_pool.items()} world.shufflelinks = args.shufflelinks.copy() + world.shuffletavern = args.shuffletavern.copy() world.pseudoboots = args.pseudoboots.copy() world.overworld_map = args.overworld_map.copy() world.restrict_boss_items = args.restrict_boss_items.copy() @@ -192,7 +193,7 @@ def main(args, seed=None, fish=None): logger.info(world.fish.translate("cli","cli","shuffling.world")) for player in range(1, world.players + 1): - if world.experimental[player] or (world.customizer and world.customizer.get_entrances()): + if world.experimental[player] or world.shuffle[player] in ['lite', 'lean'] or world.shuffletavern[player] or (world.customizer and world.customizer.get_entrances()): link_entrances_new(world, player) else: if world.mode[player] != 'inverted': diff --git a/README.md b/README.md index f419292f..f2980840 100644 --- a/README.md +++ b/README.md @@ -333,6 +333,11 @@ Start with dash ability, but no way to use boots to accomplish checks Whether to shuffle links house in most ER modes. +``` +--shuffletavern +``` + +Whether to shuffle the back of the tavern in most ER modes. ``` --bombbag diff --git a/Rom.py b/Rom.py index 616b7978..6289874a 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '01166fb16b38b49ef79acc9993dc4f02' +RANDOMIZERBASEHASH = 'e5556450b16f74709c666e419f2a42ad' class JsonRom(object): @@ -730,6 +730,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): else: # patch door table rom.write_byte(0xDBB73 + exit.addresses, exit.target) + if exit.name == 'Tavern North': + rom.write_byte(0x157D0, exit.target) if world.mode[player] == 'inverted': patch_shuffled_dark_sanc(world, rom, player) @@ -2048,6 +2050,8 @@ def write_strings(rom, world, player, team): entrances_to_hint.update({'Inverted Links House': 'The hero\'s old residence'}) else: entrances_to_hint.update({'Links House': 'The hero\'s old residence'}) + if world.shuffletavern[player] and world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + entrances_to_hint.update({'Tavern North': 'A backdoor'}) if world.mode[player] == 'inverted': entrances_to_hint.update({'Inverted Dark Sanctuary': 'The dark sanctuary cave'}) entrances_to_hint.update({'Inverted Big Bomb Shop': 'The old hero\'s dark home'}) diff --git a/data/base2current.bps b/data/base2current.bps index bd6417a47ef665eabc70d7f6055e50cdcb4562a4..d44d2e2d89935611c1bbf1e5eee7fb9a50bb251f 100644 GIT binary patch delta 7654 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 K{mEBG82=AhtZ_&H delta 7235 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 Date: Mon, 13 Jun 2022 20:51:11 +0200 Subject: [PATCH 023/146] Fix Insanity --- source/overworld/EntranceShuffle2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 79687b38..66c5c131 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -542,8 +542,8 @@ def figure_out_must_exits_same_world(entrances, exits, avail): def must_exits_helper(avail, lw_entrances, dw_entrances): - must_exit_lw = Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit - must_exit_dw = Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit + must_exit_lw = (Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit).copy() + must_exit_dw = (Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit).copy() if not avail.inverted and not avail.skull_handled: must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) must_exit_lw = must_exit_filter(avail, must_exit_lw, lw_entrances) @@ -554,8 +554,8 @@ def must_exits_helper(avail, lw_entrances, dw_entrances): def figure_out_must_exits_cross_world(entrances, exits, avail): multi_exit_caves = figure_out_connectors(exits) - must_exit_lw = Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit - must_exit_dw = Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit + must_exit_lw = (Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit).copy() + must_exit_dw = (Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit).copy() if not avail.inverted and not avail.skull_handled: must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) must_exit = must_exit_filter(avail, must_exit_lw + must_exit_dw, entrances) From 5dce2daa0b02debf83cb7abf0c20157fbece7c4c Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 14 Jun 2022 12:29:57 -0600 Subject: [PATCH 024/146] Standard throne room changes --- DoorShuffle.py | 32 +++++++- DungeonGenerator.py | 167 +++++++++++++++++++++++++++++++----------- Main.py | 2 +- RELEASENOTES.md | 8 ++ Rom.py | 2 +- data/base2current.bps | Bin 93021 -> 93062 bytes 6 files changed, 164 insertions(+), 47 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 0d36a2b0..23df9b58 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -14,7 +14,7 @@ from Items import ItemFactory from RoomData import DoorKind, PairedDoor, reset_rooms from DungeonGenerator import ExplorationState, convert_regions, generate_dungeon, pre_validate, determine_required_paths, drop_entrances from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances -from DungeonGenerator import dungeon_portals, dungeon_drops, GenerationException +from DungeonGenerator import dungeon_portals, dungeon_drops, GenerationException, connect_doors from DungeonGenerator import valid_region_to_explore as valid_region_to_explore_lim from KeyDoorShuffle import analyze_dungeon, build_key_layout, validate_key_layout, determine_prize_lock from Utils import ncr, kth_combination @@ -685,6 +685,13 @@ def create_dungeon_entrances(world, player): choice = random.choice(filtered_choices) r_name = portal.door.entrance.parent_region.name split_map[key][choice].append(r_name) + elif key == 'Hyrule Castle' and world.mode[player] == 'standard': + for portal_name in portal_list: + portal = world.get_portal(portal_name, player) + choice = 'Sewers' if portal_name == 'Sanctuary' else 'Dungeon' + r_name = portal.door.entrance.parent_region.name + split_map[key][choice].append(r_name) + entrance_map[key].append(r_name) else: for portal_name in portal_list: portal = world.get_portal(portal_name, player) @@ -774,7 +781,8 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_ logging.getLogger('').info(world.fish.translate("cli", "cli", "generating.dungeon")) while len(sector_queue) > 0: builder = sector_queue.popleft() - split_dungeon = builder.name.startswith('Desert Palace') or builder.name.startswith('Skull Woods') + split_dungeon = (builder.name.startswith('Desert Palace') or builder.name.startswith('Skull Woods') + or (builder.name.startswith('Hyrule Castle') and world.mode[player] == 'standard')) name = builder.name if split_dungeon: name = ' '.join(builder.name.split(' ')[:-1]) @@ -782,6 +790,7 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_ del dungeon_builders[builder.name] continue origin_list = list(builder.entrance_list) + find_standard_origins(builder, recombinant_builders, origin_list) find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, name) split_dungeon = treat_split_as_whole_dungeon(split_dungeon, name, origin_list, world, player) if len(origin_list) <= 0 or not pre_validate(builder, origin_list, split_dungeon, world, player): @@ -798,7 +807,7 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_ builder.master_sector = ds builder.layout_starts = origin_list if len(builder.entrance_list) <= 0 else builder.entrance_list last_key = None - combine_layouts(recombinant_builders, dungeon_builders, entrances_map) + combine_layouts(recombinant_builders, dungeon_builders, entrances_map, world, player) world.dungeon_layouts[player] = {} for builder in dungeon_builders.values(): builder.entrance_list = builder.layout_starts = builder.path_entrances = find_accessible_entrances(world, player, builder) @@ -872,6 +881,14 @@ def add_shuffled_entrances(sectors, region_list, entrance_list): entrance_list.append(region.name) +def find_standard_origins(builder, recomb_builders, origin_list): + if builder.name == 'Hyrule Castle Sewers': + throne_door = recomb_builders['Hyrule Castle'].throne_door + sewer_entrance = throne_door.entrance.parent_region.name + if sewer_entrance not in origin_list: + origin_list.append(sewer_entrance) + + def find_enabled_origins(sectors, enabled, entrance_list, entrance_map, key): for sector in sectors: for region in sector.regions: @@ -1378,7 +1395,7 @@ def merge_sectors(all_sectors, world, player): # those with split region starts like Desert/Skull combine for key layouts -def combine_layouts(recombinant_builders, dungeon_builders, entrances_map): +def combine_layouts(recombinant_builders, dungeon_builders, entrances_map, world, player): for recombine in recombinant_builders.values(): queue = deque(dungeon_builders.values()) while len(queue) > 0: @@ -1390,6 +1407,10 @@ def combine_layouts(recombinant_builders, dungeon_builders, entrances_map): recombine.master_sector.name = recombine.name else: recombine.master_sector.regions.extend(builder.master_sector.regions) + if recombine.name == 'Hyrule Castle': + recombine.master_sector.regions.extend(recombine.throne_sector.regions) + throne_n = world.get_door('Hyrule Castle Throne Room N', player) + connect_doors(throne_n, recombine.throne_door) recombine.layout_starts = list(entrances_map[recombine.name]) dungeon_builders[recombine.name] = recombine @@ -1487,11 +1508,14 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True proposal = kth_combination(sample_list[itr], builder.candidates, builder.key_doors_num) # eliminate start region if portal marked as destination + std_flag = world.mode[player] == 'standard' and builder.name == 'Hyrule Castle' excluded = {} for region in start_regions: portal = next((x for x in world.dungeon_portals[player] if x.door.entrance.parent_region == region), None) if portal and portal.destination: excluded[region] = None + if std_flag and (not portal or portal.find_portal_entrance().parent_region.name != 'Hyrule Castle Courtyard'): + excluded[region] = None start_regions = [x for x in start_regions if x not in excluded.keys()] key_layout = build_key_layout(builder, start_regions, proposal, world, player) diff --git a/DungeonGenerator.py b/DungeonGenerator.py index f0038f45..68b82732 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -43,7 +43,10 @@ def pre_validate(builder, entrance_region_names, split_dungeon, world, player): for sector in builder.sectors: for door in sector.outstanding_doors: doors_to_connect[door.name] = door - all_regions.update(sector.regions) + if world.mode[player] == 'standard' and builder.name == 'Hyrule Castle Dungeon': + all_regions.update([x for x in sector.regions if x.name != 'Hyrule Castle Behind Tapestry']) + else: + all_regions.update(sector.regions) bk_special |= check_for_special(sector.regions) bk_needed = False for sector in builder.sectors: @@ -91,18 +94,27 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon p_region = portal.door.entrance.connected_region access_region = next(x.parent_region for x in p_region.entrances if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld]) + if ((access_region.name in world.inaccessible_regions[player] and + region.name not in world.enabled_entrances[player]) + or (world.mode[player] == 'standard' and access_region.name != 'Hyrule Castle Courtyard' + and 'Hyrule Castle' in builder.name)): + excluded[region] = None + else: # for non-portals, holes and sewers in std + access_region = next((x.parent_region for x in region.entrances + if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld] + or x.parent_region.name == 'Sewer Drop'), None) + if access_region is None: + if builder.sewers_access is None: + excluded[region] = None + else: + if access_region.name == 'Sewer Drop': + if world.mode[player] == 'standard' and (builder.sewers_access is None + or builder.sewers_access.entrance.parent_region != region): + excluded[region] = None + access_region = next(x.parent_region for x in access_region.entrances) if (access_region.name in world.inaccessible_regions[player] and region.name not in world.enabled_entrances[player]): excluded[region] = None - elif len(region.entrances) == 1: # for holes - access_region = next(x.parent_region for x in region.entrances - if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld] - or x.parent_region.name == 'Sewer Drop') - if access_region.name == 'Sewer Drop': - access_region = next(x.parent_region for x in access_region.entrances) - if (access_region.name in world.inaccessible_regions[player] and - region.name not in world.enabled_entrances[player]): - excluded[region] = None entrance_regions = [x for x in entrance_regions if x not in excluded.keys()] doors_to_connect = {} all_regions = set() @@ -143,7 +155,11 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon dungeon, hangers, hooks = gen_dungeon_info(name, builder.sectors, entrance_regions, all_regions, proposed_map, doors_to_connect, bk_needed, bk_special, world, player) dungeon_cache[depth] = dungeon, hangers, hooks - valid = check_valid(name, dungeon, hangers, hooks, proposed_map, doors_to_connect, all_regions, + if len(proposed_map) != len(doors_to_connect) and builder.name == 'Hyrule Castle Dungeon': + check_regions = all_regions.difference({world.get_region('Hyrule Castle Behind Tapestry', player)}) + else: + check_regions = all_regions + valid = check_valid(name, dungeon, hangers, hooks, proposed_map, doors_to_connect, check_regions, bk_needed, bk_special, paths, entrance_regions, world, player) else: dungeon, hangers, hooks = dungeon_cache[depth] @@ -565,9 +581,15 @@ def determine_paths_for_dungeon(world, player, all_regions, name): non_hole_portals.append(portal.door.entrance.parent_region.name) if portal.destination: paths.append(portal.door.entrance.parent_region.name) - if world.mode[player] == 'standard' and name == 'Hyrule Castle': - paths.append('Hyrule Dungeon Cellblock') - paths.append(('Hyrule Dungeon Cellblock', 'Sanctuary')) + if world.mode[player] == 'standard': + if name == 'Hyrule Castle': + paths.append('Hyrule Dungeon Cellblock') + paths.append(('Hyrule Dungeon Cellblock', 'Sanctuary')) + if name == 'Hyrule Castle Sewers': + paths.append('Sanctuary') + if name == 'Hyrule Castle Dungeon': + paths.append('Hyrule Dungeon Cellblock') + paths.append(('Hyrule Dungeon Cellblock', 'Hyrule Castle Throne Room')) if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town': paths.append('Thieves Attic Window') elif 'Thieves Attic Window' in all_r_names: @@ -1206,6 +1228,11 @@ class DungeonBuilder(object): self.split_dungeon_map = None self.exception_list = [] + self.throne_door = None + self.throne_sector = None + self.chosen_lobby = None + self.sewers_access = None + def polarity_complement(self): pol = Polarity() for sector in self.sectors: @@ -1258,7 +1285,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, for r_name in dungeon_boss_sectors[key]: assign_sector(find_sector(r_name, candidate_sectors), current_dungeon, candidate_sectors, global_pole) if key == 'Hyrule Castle' and world.mode[player] == 'standard': - for r_name in ['Hyrule Dungeon Cellblock', 'Sanctuary']: # need to deliver zelda + for r_name in ['Hyrule Dungeon Cellblock', 'Sanctuary', 'Hyrule Castle Throne Room']: # need to deliver zelda assign_sector(find_sector(r_name, candidate_sectors), current_dungeon, candidate_sectors, global_pole) if key == 'Thieves Town' and world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind': @@ -2077,16 +2104,18 @@ def assign_polarized_sectors(dungeon_map, polarized_sectors, global_pole, builde while len(problem_builders) > 0: for name, builder in problem_builders.items(): candidates = find_branching_candidates(builder, neutral_choices, builder_info) - valid, choice = False, None + valid, choice, package = False, None, None while not valid: if len(candidates) <= 0: raise GenerationException('Cross Dungeon Builder: Complex branch problems: %s' % name) - choice = random.choice(candidates) - candidates.remove(choice) + choice, package = random.choice(candidates) + candidates.remove((choice, package)) valid = global_pole.is_valid_choice(dungeon_map, builder, choice) and valid_polarized_assignment(builder, choice) neutral_choices.remove(choice) for sector in choice: assign_sector(sector, builder, polarized_sectors, global_pole) + if package: + builder.throne_door, builder.throne_sector, builder.chosen_lobby = package builder.unfulfilled.clear() problem_builders = identify_branching_issues(problem_builders, builder_info) @@ -2107,16 +2136,21 @@ def assign_polarized_sectors(dungeon_map, polarized_sectors, global_pole, builde chosen_sectors = defaultdict(list) for i, choice in enumerate(choices): chosen_sectors[choice].extend(neutral_choices[i]) - all_valid = True + all_valid, package_map = True, {} for name, sector_list in chosen_sectors.items(): - if not valid_assignment(dungeon_map[name], sector_list, builder_info): + flag, package = valid_assignment(dungeon_map[name], sector_list, builder_info) + if not flag: all_valid = False break + if package: + package_map[dungeon_map[name]] = package if all_valid: for i, choice in enumerate(choices): builder = dungeon_map[choice] for sector in neutral_choices[i]: assign_sector(sector, builder, polarized_sectors, global_pole) + if builder in package_map: + builder.throne_door, builder.throne_sector, builder.chosen_lobby = package_map[builder] tries += 1 @@ -2629,9 +2663,9 @@ def weed_candidates(builder, candidates, best_charge): def find_branching_candidates(builder, neutral_choices, builder_info): candidates = [] for choice in neutral_choices: - resolved, problem_list = check_for_valid_layout(builder, choice, builder_info) + resolved, problem_list, package = check_for_valid_layout(builder, choice, builder_info) if resolved: - candidates.append(choice) + candidates.append((choice, package)) return candidates @@ -2786,13 +2820,13 @@ def categorize_groupings(sectors): def valid_assignment(builder, sector_list, builder_info): if not valid_entrance(builder, sector_list, builder_info): - return False + return False, None if not valid_c_switch(builder, sector_list): - return False + return False, None if not valid_polarized_assignment(builder, sector_list): - return False - resolved, problems = check_for_valid_layout(builder, sector_list, builder_info) - return resolved + return False, None + resolved, problems, package = check_for_valid_layout(builder, sector_list, builder_info) + return resolved, package def valid_entrance(builder, sector_list, builder_info): @@ -2898,31 +2932,56 @@ def assign_the_rest(dungeon_map, neutral_sectors, global_pole, builder_info): chosen_sectors = defaultdict(list) for i, choice in enumerate(choices): chosen_sectors[choice].append(neutral_sector_list[i]) - all_valid = True + all_valid, package_map = True, {} for name, sector_list in chosen_sectors.items(): - if not valid_assignment(dungeon_map[name], sector_list, builder_info): + flag, package = valid_assignment(dungeon_map[name], sector_list, builder_info) + if not flag: all_valid = False break + if package: + package_map[dungeon_map[name]] = package if all_valid: for name, sector_list in chosen_sectors.items(): builder = dungeon_map[name] for sector in sector_list: assign_sector(sector, builder, neutral_sectors, global_pole) + if builder in package_map: + builder.throne_door, builder.throne_sector, builder.chosen_lobby = package_map[builder] tries += 1 def split_dungeon_builder(builder, split_list, builder_info): + ents, splits, c_tuple, world, player = builder_info if builder.split_dungeon_map and len(builder.exception_list) == 0: for name, proposal in builder.valid_proposal.items(): builder.split_dungeon_map[name].valid_proposal = proposal + if builder.name == 'Hyrule Castle': + builder.chosen_lobby.outstanding_doors.remove(builder.throne_door) + builder.throne_sector.outstanding_doors.remove(world.get_door('Hyrule Castle Throne Room N', player)) return builder.split_dungeon_map # we made this earlier in gen, just use it attempts, comb_w_replace, merge_attempt, merge_limit = 0, None, 0, len(split_list) - 1 while attempts < 5: # does not solve coin flips 3% of the time try: candidate_sectors = dict.fromkeys(builder.sectors) - global_pole = GlobalPolarity(candidate_sectors) + if builder.name == 'Hyrule Castle': + throne_sector = find_sector('Hyrule Castle Throne Room', candidate_sectors) + chosen_lobbies = {r_name for x in split_list.values() for r_name in x} + choices = {} + for sector in candidate_sectors: + if sector.adj_outflow() > 1 and sector != throne_sector: + for door in sector.outstanding_doors: + if door.direction == Direction.South and door.entrance.parent_region not in chosen_lobbies: + choices[door] = sector + chosen_door = random.choice(list(choices.keys())) + split_list['Sewers'].append(chosen_door.entrance.parent_region.name) + choices[chosen_door].outstanding_doors.remove(chosen_door) + builder.throne_door = chosen_door + builder.throne_sector = throne_sector + builder.chosen_lobby = choices[chosen_door] + throne_sector.outstanding_doors.remove(world.get_door('Hyrule Castle Throne Room N', player)) + global_pole = GlobalPolarity(candidate_sectors) dungeon_map, sub_builder, merge_keys = {}, None, [] if merge_attempt > 0: candidates = [] @@ -2932,7 +2991,6 @@ def split_dungeon_builder(builder, split_list, builder_info): continue elif len(split_entrances) <= 0: continue - ents, splits, c_tuple, world, player = builder_info r_name = split_entrances[0] p = next((x for x in world.dungeon_portals[player] if x.door.entrance.parent_region.name == r_name), None) if p and not p.deadEnd: @@ -2953,6 +3011,13 @@ def split_dungeon_builder(builder, split_list, builder_info): sub_builder.all_entrances = list(split_entrances) for r_name in split_entrances: assign_sector(find_sector(r_name, candidate_sectors), sub_builder, candidate_sectors, global_pole) + if builder.name == 'Hyrule Castle': + assign_sector(find_sector('Hyrule Castle Throne Room', candidate_sectors), + dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole) + assign_sector(find_sector('Hyrule Dungeon Cellblock', candidate_sectors), + dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole) + dungeon_map['Hyrule Castle Dungeon'].throne_door = world.get_door('Hyrule Castle Throne Room N', player) + dungeon_map['Hyrule Castle Sewers'].sewers_access = builder.throne_door comb_w_replace = len(dungeon_map) ** len(candidate_sectors) return balance_split(candidate_sectors, dungeon_map, global_pole, builder_info) except (GenerationException, NeutralizingException): @@ -2960,7 +3025,13 @@ def split_dungeon_builder(builder, split_list, builder_info): attempts += 5 # all the combinations were tried already, no use repeating else: attempts += 1 - if attempts >= 5 and merge_attempt < merge_limit: + if builder.throne_door: + previous = find_sector(builder.throne_door.entrance.parent_region.name, builder.sectors) + previous.outstanding_doors.append(builder.throne_door) + builder.throne_sector.outstanding_doors.append(world.get_door('Hyrule Castle Throne Room N', player)) + split_list['Sewers'].remove(builder.throne_door.entrance.parent_region.name) + builder.throne_door = None + if attempts >= 5 and merge_attempt < merge_limit and builder.name != 'Hyrule Castle': merge_attempt, attempts = merge_attempt + 1, 0 raise GenerationException('Unable to resolve in 5 attempts') @@ -2981,16 +3052,21 @@ def balance_split(candidate_sectors, dungeon_map, global_pole, builder_info): chosen_sectors = defaultdict(list) for i, choice in enumerate(choices): chosen_sectors[choice].append(main_sector_list[i]) - all_valid = True + all_valid, package_map = True, {} for name, builder in dungeon_map.items(): - if not valid_assignment(builder, chosen_sectors[name], builder_info): + flag, package = valid_assignment(builder, chosen_sectors[name], builder_info) + if not flag: all_valid = False break + if package: + package_map[builder] = package if all_valid: for name, sector_list in chosen_sectors.items(): builder = dungeon_map[name] for sector in sector_list: assign_sector(sector, builder, candidate_sectors, global_pole) + if builder in package_map: + builder.throne_door, builder.throne_sector, builder.chosen_lobby = package_map[builder] return dungeon_map tries += 1 raise GenerationException('Split Dungeon Builder: Impossible dungeon. Ref %s' % next(iter(dungeon_map.keys()))) @@ -3380,7 +3456,7 @@ class DungeonAccess: def identify_branching_issues(dungeon_map, builder_info): unconnected_builders = {} for name, builder in dungeon_map.items(): - resolved, unreached_doors = check_for_valid_layout(builder, [], builder_info) + resolved, unreached_doors, package = check_for_valid_layout(builder, [], builder_info) if not resolved: unconnected_builders[name] = builder for hook, door_list in unreached_doors.items(): @@ -3421,16 +3497,27 @@ def check_for_valid_layout(builder, sector_list, builder_info): proposal = generate_dungeon_find_proposal(split_build, entrance_regions, split, world, player) # record split proposals builder.valid_proposal[name] = proposal + package = None + if temp_builder.name == 'Hyrule Castle': + temp_builder.chosen_lobby.outstanding_doors.append(temp_builder.throne_door) + temp_builder.throne_sector.outstanding_doors.append(world.get_door('Hyrule Castle Throne Room N', player)) + package = temp_builder.throne_door, temp_builder.throne_sector, temp_builder.chosen_lobby + split_list['Sewers'].remove(temp_builder.throne_door.entrance.parent_region.name) builder.exception_list = list(sector_list) - return True, {} + return True, {}, package except (GenerationException, NeutralizingException): builder.split_dungeon_map = None builder.valid_proposal = None + if temp_builder.name == 'Hyrule Castle' and temp_builder.throne_door: + temp_builder.chosen_lobby.outstanding_doors.append(temp_builder.throne_door) + temp_builder.throne_sector.outstanding_doors.append(world.get_door('Hyrule Castle Throne Room N', player)) + old_entrance = temp_builder.throne_door.entrance.parent_region.name + split_dungeon_entrances[builder.name]['Sewers'].remove(old_entrance) unreached_doors = resolve_equations(builder, sector_list) - return False, unreached_doors + return False, unreached_doors, None else: unreached_doors = resolve_equations(builder, sector_list) - return len(unreached_doors) == 0, unreached_doors + return len(unreached_doors) == 0, unreached_doors, None def find_independent_entrances(entrance_regions, world, player): @@ -3831,9 +3918,7 @@ def find_free_equation(equations): def copy_door_equations(builder, sector_list): equations = {} for sector in builder.sectors + sector_list: - if sector.equations is None: - # todo: sort equations? - sector.equations = calc_sector_equations(sector) + sector.equations = calc_sector_equations(sector) curr_list = equations[sector] = [] for equation in sector.equations: curr_list.append(equation.copy()) diff --git a/Main.py b/Main.py index f3dcb0ee..32b7dd7f 100644 --- a/Main.py +++ b/Main.py @@ -31,7 +31,7 @@ from Utils import output_path, parse_player_names from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config from source.tools.BPS import create_bps_from_data -__version__ = '1.0.2.4-v' +__version__ = '1.0.2.4-x' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 31d1e10e..286704e6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -155,8 +155,16 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o ## Notes and Bug Fixes +#### StandardThrone + + * Changed standard dungeon generation to always have Throne Room in hyrule castle and always have sanctuary behind it + * S&Q/death in standard after moving the tapestry but before delivering Zelda will result in spawning at the tapestry + * Mirror scroll will return you to Zelda's cell instead of last entrance. This reverts to normal behavior once the tapestry open trigger is reach + #### Volatile +* 1.0.2.5 + * Some textual changes for hints * 1.0.2.4 * Updated tourney winners (included Doors Async League winners) * Fixed a couple issues with dungeon counters and the DungeonCompletion field for autotracking diff --git a/Rom.py b/Rom.py index 1c9d82a7..f062e4d3 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '01166fb16b38b49ef79acc9993dc4f02' +RANDOMIZERBASEHASH = '4941faf4496875a373a51119f2bedf4c' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index bd6417a47ef665eabc70d7f6055e50cdcb4562a4..4005551c18297514faad1e8e8ed9872d957d261b 100644 GIT binary patch delta 1773 zcmW;MeNaZ(aH``v8a5+tx5*aL2>CW3#?m~Zs55cWLQ8T z;k`)2Ktha%BtoEhBcvLThUu%TZDpd-7PGURjjeWDSpJY56et$(gLXUB-Dm$fzqucC z=bSV5-s!JHPW>xntP}|+OOxDO1=@}faDcBts0rMH3F5kq?3!d37WOhm@|}~8$PW`c z&18agsMf#;ubIiup|$-7nf&(ycFtY| zVrhnC4}V?}Z6zCFzcfJ{y3B54Y~%qrE=`Hx&n9h)?3v!u6_!j|f>CJ_8iuc=yJfG= z@)cilTFm4zh>^WOt(-C}U4WXof`~5#(XJI|c2nw14kl%i_|b0c|HEl94mAgNyS6Q`nXfZ1-^K_wJdI)T}Wo` zmtBIcsLiN?Qh;68VXTCbY>%AJS9QVoQGmrvd>^^+oDB#S!)v*@ zXd0;8AS#6{RX#eyb*O66Q6BfW?g@URxN6QL_TGM?3kZV|9;v;pyuCLy+;e6iD7TYK zkEj{qmqk1n;VtGjpc|lLCYtao?qY6S?X6)_gMvcEEYvoUF>!XA z*Iv}NYnR1r^XLtjN57l?(O8Jh!bnpVuDlQPO^0!QZ}y2TI6tX5!Q#;?AZ=F5`l?kQ z80#Le&XN_VXeOgx_mB4=I^0NO%OM^>w7~Q3$PPc)o8vcWk1*rQ!T>%d(RjjGR2DN6 zqIrYHv76k@8?BJlT8Zj`ZH>>nY$?2*M84)5Lj`zrg>BTz20Go` zhf$t7Lmzb>^R_Xmej+Hkj1eP?lp7=F9#KBkO&vM%0(Z3~K7-nfRp*I}RcPWxJ5~YP zvFeoYih0-YDtKdfmAspH3EnNd$-HU2sk}RRGk2^ylB&Wd2NcVK!jVPqvLn3`n6_Rt z2eEXDygFmme2%VhpT%gGYA2M?rPA0#Gv=~OKZQCQ;1fCvPs@cL>G*wHSBBs7_Jg`$ z_56@GqhQsrb*1k;!wlgpRIeIdxqSBI$Zx6`+fg@m0rPQT)r`TP>fC)`)zG@)eE(&* z$h10|;rGl&T=EoJ8B*E&jA?Y~nMRA=_0}^>+_R-Wl)d=#_lL{jZ%lvGW-0ygUjF{7 zX9&u@){Jc`BMKM_H2Uq5;-&nx|9SI^g!ehOUKJrvdBD=^{DilaleZglxF^=zTO!IU zy9SgV9JA<(+5p{!zkk{zu9BLVc9%v9?_7%)x5!M)X_rpMnXWwwiARy9K9N#Cuq+x+ zl?QO@LS9yfO-Wfkd!lnDW`V=c;D-je^*8fSVtA|xM6o7D4WHVC8V{m0j*Ycl?m$r+ z|2oiljB*^%a)w(KNYq+L57vsf`Oh+uj5=ttDhzRydg(9Rwux&KBcD$X;)vO$j rL&qHB;V1_W)n0iXj$R2B{i>RA>{)XqG7_mu#5u9ozy0}P|Jwfp4>1UU delta 1774 zcmW;Ndr(tX9tZH8n-G!!fkhtS6~h%#T-gDEE%HnOONywGQMaYRMMXhVcc@w(0?ECB zh{41VeufC)aYv09(GA6IQV}{x1NIAqwt|g4C6Z`#_KF(o30i?pBVEMVcjg=F+UxLkyW;j!;&UbBmOpETeW zXy8Q&Y!4{6wAF;)cLBxI`}TP#f`cbP3cnOZz-fLK_QC~U@Fj7*d9#$L{M6>bDS?jD zY{H)nU2=~Y@Yh3^s=E#NN3+yi=Q;=!r18U<1?7YZ-vV0%t9TFRsr958Uj=o7#6V_o zT=|r0?@C&r@c(`X*95B(0WLwN-%pPyxBH6KXu$J8;`bVr&@25nu#ucD3B1D&|8T*Y zUDtJ9ysmXbi<_q+Ii1G{EnZG%uHa+g!iUsyJp$JScLB32rYk2H;JwgykQlCoej*;2 zqd5IKe0J6n8GSZh*9AD_g#!6-+g_k7O$W zYha{iBZ`E@nq64Rw@_3YgM?63n~m6Tu{PbW>~k{Cm_^twkNLrqT0H#7BpK4ZE9eC2 z4;_#&Wg6lge>n*20Ixe3nrx0GBoje@W!W&9;}DrN%`TpO1XLX!Av2pDopNft!CA%2zJpF+!1s@@>hHc&lLpx(M|R?+PmaqjX}d z={F^n@b`vntgaBE8uNrHsXv%xm&c?UYs62wN>DcLLlXF^Q5+UQ8jHtOM(Mb!=Pb9U zi#sE6++I?3G>KMD^OjqR?iOr}Y{3MV$L`$6wA9#LCI{Y)dx>xOJq zuJ~w~n`B$oya}YtdO-ZMse&!qkI`X7FIA4ebVIi)Iyy1r{^VKF;jp|b;d$-o_O}xf zrOZ`&HzVl2HWluuicvVMR7a}Gr%D@3a_gCLO!}z`AAF7VtK*(Sbeh+?I?W4ljERiv z8Pgb38M7I)7&kE%Fm7QiX57iRgRzWJ!MLBXBF$^rUg7Eu^014^rw)&0_gQm?z6cCBR&@`{%EOE%z!6N$KPX{$oDkzlC7!+4t`dV@LhRDLoav+uz zt62+|`y4%RtjK%rf@4pSSIb)H?$gdltaXK6ZSeJu=0UWdG?&|01FSJRy^7RMBv~tq zz1orm>&4}`M3z|MH+%c4wO8lnP6jQNJ5q=w55KSEh`mc`|Jm>-j&dMv>En=$ukx2v z?EwxZo%@D5_Yr?kIzCuZ!7Y+6ihoYl_G`#mqo$wz+$j5g-cRv5(4$hoKgpi31_AML z0doyxGZLk3g@F~TkZdNy!K6v$H+X7-zlr){n~nanMj9w&&r(Flgv8NE3tMy{bacn< zguvvAQ@tWP#xknpYDl~bOE=E&Hu~wwmi{b1Fy0jNw)yMHll>+B^!1z1e8f9L_1#>N zrq{zAO%ggW<-pO*R?WtHV< z^(mWEu4e8SI>%C4>Kp0bf3_QO*A^4!3w-I|&(o1#?l!$CNE@w`%}3BXr*0x{SjQ%U zc~8Tg$;`v_w(~lh` Date: Thu, 16 Jun 2022 12:35:16 -0600 Subject: [PATCH 025/146] Mirror scroll behavior during escape altered. Pray I do not alter it further --- RELEASENOTES.md | 6 +++++- Rom.py | 2 +- data/base2current.bps | Bin 93062 -> 93061 bytes 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 286704e6..6ebb761e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -157,9 +157,13 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o #### StandardThrone +* Bug fixes + * Fix HC Ledge entrances after rescuing Zelda, also includes the throne spawn point now. +* Original Release * Changed standard dungeon generation to always have Throne Room in hyrule castle and always have sanctuary behind it * S&Q/death in standard after moving the tapestry but before delivering Zelda will result in spawning at the tapestry - * Mirror scroll will return you to Zelda's cell instead of last entrance. This reverts to normal behavior once the tapestry open trigger is reach + * Mirror scroll will return you to Zelda's cell instead of last entrance. This reverts to normal behavior once the tapestry open trigger is reached + #### Volatile diff --git a/Rom.py b/Rom.py index f062e4d3..cc28f3bd 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '4941faf4496875a373a51119f2bedf4c' +RANDOMIZERBASEHASH = 'add982e935888df04ddfa570bc07bede' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 4005551c18297514faad1e8e8ed9872d957d261b..060733f6e6579357fc34f52d728345c5cfe9ea01 100644 GIT binary patch delta 1735 zcmW;Mdr(tX8UXN|JTM88L=7RluNQ>kW2+)oc}PI1QP9Ck8LLs*MIG>>3k>oQNbZeB z3?#r#^ z+s$~A^+L6Q;t!hf+hF4Vj;f$t@Vl({Aw6lFdPFO!8ygKD8*hOl>}^!Vd>x8h^Pgk+IZ$Yy#R_uF72UKlV{FNVQp=s7gkS6(f38ag*qZ~LP%0}_sc0MXp~9XbIrNAwQ??tQ z`Dl5YaVPA|@krR?s(Ovrd^E?z7L1XviAQJ?EYHnF51=-843)rI)kf6LoKWpwj`EoQ z)Xw28JD?}LTc@=?G$!@lW90_Z**US7pbN0xIAxz>sJ|@C`@cZ~DQ6_=?0IK@U zy!?0Dz*>(BDmIhwR~V>Yjs619>r1)Kzre5Es zNdq30`3WWOE|ndlW`hlCMy>tA!!P@w7VySOd6RuUiH*qq!Etld-u=|lF}^(grgo4e zdN|kAiNay^;mv}o3EH_4Oox+-Qb&ePAu_^9a)JU6Ad=@f*tc-xj`}K>>yrir6`JUA zLGr(fe}njolo0er2^s0ADWQhg(s27l6`t8Nn%PqE7FpK<|2@0`ErWvQbo41SHNPkB z_?hr=Ib(TP2YlO{gH#aHvR2Z(;y0`M@~}$pjDBV80HUQFRlw&h35q48rRa{A)tZZ9AX}@7&)OBBc#hOOpw!MkCH`UE!&C0%G77SX zF2fU`OB)||NdC>;)5-&i{3}uUC(*rMMleF{-~J_c&Nqf_@P)Pr?S@2MjLtntxH;JP zQ({>4krwZJ&2{OLU%;M>kn=!B2&z~QvDUG+vbL}aR)&DTGUSY4oy{7_Drb#njbmNF zn#{U{b@9rOBYLmDM;7E2xhK6rM@qThZVBGidY?Nbl=b;t7|?Z~aacz#iP)JDGM^^* zyKNlOwF0!{4zYC0xLI@Ms&;3jm`Mb;(ng&w9^5c46q;1#enm$dEkMebz9J zIaTVAVeWO?k-iOkDSMfl)5{rVIF*!PWU2GbO(8@5l=I?DxJ1=E4i<*aRvWH9etcXu zUFJ=->LO<5uQKHpYn;`*6Ew_%+J?OYfnaa+2||p?<^2HlU9~@^e8=CjzwFngF|1!^sQ6Ebe@Si z>RQPI%V2_V1K&g)cNOuO>w`}P@ez@x?l7gkCm1%gRN~_jy;<39b|qoCJFRspVR%H3 z3Yh$l)F>%B)&z57O_UmL+4&V7L{vByRd=|3#X9!KpmQ9;k;h#9csCMM7m?>%m^q)U zM&S*cO;(v9j!-}QGxP4~APU=MDFCPmBxP6!LL#l)fP}jE*a(D!s|R=T4(AJc-x+92@mF+UuU{n;1{x! z-QAw13clr#G7(>sv4WZfCmaVE+tk)LROXn7Kx??oEjLmmXznZlUP(DJZsbIwyi(x@ Mn{KaL>vq@u4@G?T)Bpeg delta 1727 zcmW;Me^3)=8VB%w^8-SF5DS4|_^~b^%GDc0;ZQ(A(V7A}C|B@`C{{7dImNrSw(*#oaz&BC8K9KNO#QC>}0EB6nfj0CyN|MF;={6N1zhC=qHI_#pHx zeCOLPx$I_-(I(;+XeBD?=a1NVbqhlX9)VqA^u6a{DG^Z!Nq&VW8%%!bCXmnJL=Y)4Pw5=+DZCtZ&&fm@p9zkZgVY{+Id5yt@cUq$s?bU>02X}SGD ze-nn;muwleJ?EnmT1NE5*u+{wQzk&X?Xb3t(Uh7vfG;gIp|sxKI>xLC}{?~4oB5s6R%BxPozX{gMcLWPj6&OseqySh9H?dJYd zxki|>NY3ESdn-DZU@FL2z>B7Q$MLcsM!q4(aqE_SZ4ERzipyN5ru^_(w@cK4wv+fQ zq*d<~mc@60v6>K9?WLd&xaw`_Jy@(hfcq|3X5>_Y^N6+lL&ljvC0;y-!6zSdGC1Mr zXW?xqsmVZ_;7>KF{+lQ0SaUixaA_)JLvL*iihxgRLj~9@d{vu{ln{Kp0LkH<i#A5FWqh;?QGo^u^N1aQD52xM!4w$NMxzG! zr&b}r8o;Z417(1^ZVQ@%s=7Z&nJ1)6fK6rL3_PsMKzX33&zAWn|Hx=Ajj5Y#;XfG| zI8tANs$jA{D)_27@0QN2zNI^J+UHDkq>NT^=GKs&Q@O-~u^-;d6`RnEJMk7+e+D z8)KhCMY7j+JlPAiyeP#BSc=!?$1CAo!z}qJB4oX$~ zW=usxFMMs)FhixI%@9pTHzq7yI_o?Gnq2R>erIy7SD&!ddsaV#+wwGC{VP{Hn+M-4 zr7gt+*ad8i3ph&a#}jR7d%XJkCEJHD<04&e)#iH7R_HI!&7G336g#(2i5|bR`zswi zq~jOUq=>xW_ru2_+dt1<(RBnm`E->Gcb8Bfk)$^WMgwLnUo}N{0Y5>+%}`eF4kYyCkJjBYnbNCWZDJQIa}; zBYn!Q^XIPISQJMhg|XL1+0^Ip8BLVA1muO?=`9u|X}+_fv&F)v<4tHEmvvi%Vggl0 z@KG6Q4P3W~${dI+vqo364Y=|f`RhREFw(k*8~W@mB(Be+&R1~qyW5aIx!1_Z^%11z z*}L3tCvG60^3Gip|2KxZHlz1Bjq9pVEX*_7_j7{#4w1h=O)+wpXv+Wm2i#vCxP>SO zm@hZ-XL Date: Tue, 28 Jun 2022 13:05:38 -0600 Subject: [PATCH 026/146] Large refactor underway. Wrote new main method Implemented trap door shuffle to some degree Still needs the other types --- DoorShuffle.py | 585 ++++++++++++++++++++++++++++-- Doors.py | 26 +- DungeonGenerator.py | 4 +- RoomData.py | 8 +- source/dungeon/DungeonStitcher.py | 104 ++++-- 5 files changed, 648 insertions(+), 79 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 3d20be76..b8c8abbe 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -6,13 +6,14 @@ from enum import unique, Flag from typing import DefaultDict, Dict, List from BaseClasses import RegionType, Region, Door, DoorType, Direction, Sector, CrystalBarrier, DungeonInfo, dungeon_keys -from BaseClasses import PotFlags, LocationType +from BaseClasses import PotFlags, LocationType, Direction from Doors import reset_portals from Dungeons import dungeon_regions, region_starts, standard_starts, split_region_starts from Dungeons import dungeon_bigs, dungeon_hints from Items import ItemFactory from RoomData import DoorKind, PairedDoor, reset_rooms from source.dungeon.DungeonStitcher import GenerationException, generate_dungeon +from source.dungeon.DungeonStitcher import ExplorationState as ExplorationState2 # from DungeonGenerator import generate_dungeon from DungeonGenerator import ExplorationState, convert_regions, pre_validate, determine_required_paths, drop_entrances from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances @@ -759,6 +760,131 @@ def find_entrance_region(portal): return None +# each dungeon_pool members is a pair of lists: dungeon names and regions in those dungeons +def main_dungeon_pool(dungeon_pool, world, player): + add_inaccessible_doors(world, player) + entrances_map, potentials, connections = determine_entrance_list(world, player) + connections_tuple = (entrances_map, potentials, connections) + entrances, splits = create_dungeon_entrances(world, player) + + dungeon_builders = {} + door_type_pools = [] + for pool, region_list in dungeon_pool: + if len(pool) == 1: + dungeon_key = next(pool) + sector_pool = convert_to_sectors(region_list, world, player) + merge_sectors(sector_pool, world, player) + dungeon_builders[dungeon_key] = simple_dungeon_builder(dungeon_key, sector_pool) + dungeon_builders[dungeon_key].entrance_list = list(entrances_map[dungeon_key]) + else: + if 'Hyrule Castle' in pool: + hc = world.get_dungeon('Hyrule Castle', player) + hc.dungeon_items.append(ItemFactory('Compass (Escape)', player)) + if 'Agahnims Tower' in pool: + at = world.get_dungeon('Agahnims Tower', player) + at.dungeon_items.append(ItemFactory('Compass (Agahnims Tower)', player)) + at.dungeon_items.append(ItemFactory('Map (Agahnims Tower)', player)) + sector_pool = convert_to_sectors(region_list, world, player) + merge_sectors(sector_pool, world, player) + # todo: which dungeon to create + dungeon_builders.update(create_dungeon_builders(sector_pool, connections_tuple, + world, player, pool, entrances, splits)) + door_type_pools.append((pool, DoorTypePool(sector_pool, world, player))) + + update_forced_keys(dungeon_builders, entrances_map, world, player) + recombinant_builders = {} + builder_info = entrances, splits, connections_tuple, world, player + handle_split_dungeons(dungeon_builders, recombinant_builders, entrances_map, builder_info) + + main_dungeon_generation(dungeon_builders, recombinant_builders, connections_tuple, world, player) + + setup_custom_door_types(world, player) + paths = determine_required_paths(world, player) + shuffle_door_types(door_type_pools, paths, world, player) + + check_required_paths(paths, world, player) + + all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items)) + target_items = 34 + if world.retro[player]: + target_items += 1 if world.dropshuffle[player] else 0 # the hc big key + else: + target_items += 29 # small keys in chests + if world.dropshuffle[player]: + target_items += 14 # 13 dropped smalls + 1 big + if world.pottery[player] not in ['none', 'cave']: + target_items += 19 # 19 pot keys + d_items = target_items - all_dungeon_items_cnt + world.pool_adjustment[player] = d_items + if not world.decoupledoors[player]: + smooth_door_pairs(world, player) + + +def update_forced_keys(dungeon_builders, entrances_map, world, player): + for builder in dungeon_builders.values(): + builder.entrance_list = list(entrances_map[builder.name]) + dungeon_obj = world.get_dungeon(builder.name, player) + for sector in builder.sectors: + for region in sector.regions: + region.dungeon = dungeon_obj + for loc in region.locations: + if loc.forced_item: + key_name = (dungeon_keys[builder.name] if loc.name != 'Hyrule Castle - Big Key Drop' + else dungeon_bigs[builder.name]) + loc.forced_item = loc.item = ItemFactory(key_name, player) + + +def finish_up_work(world, player): + dungeon_builders = world.dungeon_layouts[player] + # Re-assign dungeon bosses + gt = world.get_dungeon('Ganons Tower', player) + for name, builder in dungeon_builders.items(): + reassign_boss('GT Ice Armos', 'bottom', builder, gt, world, player) + reassign_boss('GT Lanmolas 2', 'middle', builder, gt, world, player) + reassign_boss('GT Moldorm', 'top', builder, gt, world, player) + + sanctuary = world.get_region('Sanctuary', player) + d_name = sanctuary.dungeon.name + if d_name != 'Hyrule Castle': + possible_portals = [] + for portal_name in dungeon_portals[d_name]: + portal = world.get_portal(portal_name, player) + if portal.door.name == 'Sanctuary S': + possible_portals.clear() + possible_portals.append(portal) + break + if not portal.destination and not portal.deadEnd: + possible_portals.append(portal) + if len(possible_portals) == 1: + world.sanc_portal[player] = possible_portals[0] + else: + reachable_portals = [] + for portal in possible_portals: + start_area = portal.door.entrance.parent_region + state = ExplorationState(dungeon=d_name) + state.visit_region(start_area) + state.add_all_doors_check_unattached(start_area, world, player) + explore_state(state, world, player) + if state.visited_at_all(sanctuary): + reachable_portals.append(portal) + world.sanc_portal[player] = random.choice(reachable_portals) + if world.intensity[player] >= 3: + if player in world.sanc_portal: + portal = world.sanc_portal[player] + else: + portal = world.get_portal('Sanctuary', player) + target = portal.door.entrance.parent_region + connect_simple_door(world, 'Sanctuary Mirror Route', target, player) + + check_entrance_fixes(world, player) + + if world.standardize_palettes[player] == 'standardize' and world.doorShuffle[player] not in ['basic']: + palette_assignment(world, player) + + refine_hints(dungeon_builders) + refine_boss_exits(world, player) + + # def unpair_all_doors(world, player): # for paired_door in world.paired_doors[player]: # paired_door.pair = False @@ -1522,7 +1648,9 @@ def setup_custom_door_types(world, player): custom_doors = custom_doors[player] if 'doors' not in custom_doors: return - world.custom_door_types[player] = type_map = {'Key Door': defaultdict(list), 'Dash Door': [], 'Bomb Door': []} + # todo: dash/bomb door pool specific + customizeable_types = ['Key Door', 'Dash Door', 'Bomb Door', 'Trap Door', 'Big Key Door'] + world.custom_door_types[player] = type_map = {x: defaultdict(list) for x in customizeable_types} for door, dest in custom_doors['doors'].items(): if isinstance(dest, dict): if 'type' in dest: @@ -1531,17 +1659,206 @@ def setup_custom_door_types(world, player): dungeon = d.entrance.parent_region.dungeon if d.type == DoorType.SpiralStairs: type_map[door_kind][dungeon.name].append(d) - elif door_kind == 'Key Door': + else: # check if the if d.dest.type in [DoorType.Interior, DoorType.Normal]: type_map[door_kind][dungeon.name].append((d, d.dest)) else: type_map[door_kind][dungeon.name].append(d) - else: - if d.dest.type in [DoorType.Interior, DoorType.Normal]: - type_map[door_kind].append((d, d.dest)) - else: - type_map[door_kind].append(d) + + +class DoorTypePool: + def __init__(self, sectors, world, player): + self.smalls = 0 + self.bombable = 0 + self.dashable = 0 + self.bigs = 0 + self.traps = 0 + # self.tricky = 0 + # self.hidden = 0 + # todo: custom pools? + self.count_via_sectors(sectors, world, player) + + def count_via_sectors(self, sectors, world, player): + skips = set() + for sector in sectors: + for region in sector.regions: + for ext in region.exits: + if ext.door: + d = ext.door + if d.name not in skips and d.type in [DoorType.Normal, DoorType.Interior]: + if d.smallKey: + self.smalls += 1 + elif d.bigKey: + self.bigs += 1 + elif d.blocked and d.trapFlag and 'Boss' not in d.name and 'Agahnim' not in d.name: + self.traps += 1 + elif d.name == 'TR Compass Room NW': + self.tricky += 1 + elif d.name in ['Skull Vines NW', 'Tower Altar NW']: + self.hidden += 1 + else: + kind = world.get_room(d.roomIndex, player).kind(d) + if kind == DoorKind.Bombable: + self.bombable += 1 + elif kind == DoorKind.Dashable: + self.dashable += 1 + if d.type == DoorType.Interior: + skips.add(d.dest.name) ## lookup a different way for interior door shuffle + elif d.type == DoorType.Normal: + for dp in world.paired_doors[player]: + if d.name == dp.door_a or d.name == dp.door_b: + skips.add(dp.door_b if d.name == dp.door_a else dp.door_a) + break + + def chaos_shuffle(self): + weights = [1, 2, 4, 3, 2, 1] + self.smalls = random.choices(self.get_choices(self.smalls), weights=weights) + self.bombable = random.choices(self.get_choices(self.bombable), weights=weights) + self.dashable = random.choices(self.get_choices(self.dashable), weights=weights) + self.bigs = random.choices(self.get_choices(self.bigs), weights=weights) + self.traps = random.choices(self.get_choices(self.traps), weights=weights) + # self.tricky = random.choices(self.get_choices(self.tricky), weights=weights) + # self.hidden = random.choices(self.get_choices(self.hidden), weights=weights) + + @staticmethod + def get_choices(number): + return [max(number-i, 0) for i in range(-1, 5)] + + +class BuilderDoorCandidates: + def __init__(self): + self.small = set() + self.big = set() + self.trap = set() + self.bombable = set() + self.dashable = set() + + self.checked = set() + + +def shuffle_door_types(door_type_pools, paths, world, player): + start_regions_map = {} + for name, builder in world.dungeon_layouts[player]: + start_regions = convert_regions(builder.path_entrances, world, player) + start_regions_map[name] = start_regions + used_doors = shuffle_door_traps(door_type_pools, paths, start_regions_map, world, player) + # big keys + # small keys + + # bombable / dashable + + # tricky / hidden + + +def shuffle_door_traps(door_type_pools, paths, start_regions_map, world, player): + used_doors = set() + for pool, door_type_pool in door_type_pools: + ttl = 0 + suggestion_map, trap_map, flex_map = {}, {}, {} + remaining = door_type_pool.traps + if player in world.custom_door_types: + custom_trap_doors = world.custom_door_types[player]['Trap Door'] + else: + custom_trap_doors = defaultdict(list) + + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + find_trappable_candidates(builder, world, player) + if custom_trap_doors[dungeon]: + builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon]) + remaining -= len(custom_trap_doors[dungeon]) + ttl += len(builder.candidates.trap) + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + proportion = len(builder.candidates.trap) + calc = int(round(proportion * door_type_pool.traps/ttl)) + suggested = min(proportion, calc) + remaining -= suggested + suggestion_map[dungeon] = suggested + flex_map[dungeon] = (proportion - suggested) if suggested < proportion else 0 + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + valid_traps, trap_number = find_valid_trap_combination(builder, suggestion_map[dungeon], + start_regions_map[dungeon], paths, world, player) + trap_map[dungeon] = valid_traps + if trap_number < suggestion_map[dungeon]: + flex_map[dungeon] = 0 + remaining += suggestion_map[dungeon] - trap_number + suggestion_map[dungeon] = trap_number + builder_order = [x for x in pool if flex_map[x] > 0] + queue = deque(builder_order) + while len(queue) > 0 and remaining > 0: + dungeon = queue.popleft() + builder = world.dungeon_layouts[player][dungeon] + increased = suggestion_map[dungeon] + 1 + valid_traps, trap_number = find_valid_trap_combination(builder, increased, start_regions_map[dungeon], + paths, world, player) + if valid_traps: + trap_map[dungeon] = valid_traps + remaining -= 1 + suggestion_map[dungeon] = increased + flex_map[dungeon] -= 1 + if flex_map[dungeon] > 0: + queue.append(dungeon) + # time to re-assign + reassign_trap_doors(trap_map, world, player) + for name, traps in trap_map.items(): + used_doors.update(traps) + return used_doors + + +def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, player): + for pool, door_type_pool in door_type_pools: + ttl = 0 + suggestion_map, bk_map, flex_map = {}, {}, {} + remaining = door_type_pool.bigs + if player in world.custom_door_types: + custom_bk_doors = world.custom_door_types[player]['Big Key Door'] + else: + custom_bk_doors = defaultdict(list) + + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + find_big_key_candidates(builder, used_doors, world, player) + if custom_bk_doors[dungeon]: + builder.candidates.trap = filter_key_door_pool(builder.candidates.big, custom_bk_doors[dungeon]) + remaining -= len(custom_bk_doors[dungeon]) + ttl += len(builder.candidates.big) + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + proportion = len(builder.candidates.big) + calc = int(round(proportion * door_type_pool.big/ttl)) + suggested = min(proportion, calc) + remaining -= suggested + suggestion_map[dungeon] = suggested + flex_map[dungeon] = (proportion - suggested) if suggested < proportion else 0 + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + valid_doors, bk_number = find_valid_bk_combination(builder, suggestion_map[dungeon], + start_regions_map[dungeon], world, player) + bk_map[dungeon] = valid_doors + if bk_number < suggestion_map[dungeon]: + flex_map[dungeon] = 0 + remaining += suggestion_map[dungeon] - bk_number + suggestion_map[dungeon] = bk_number + builder_order = [x for x in pool if flex_map[x] > 0] + queue = deque(builder_order) + while len(queue) > 0 and remaining > 0: + dungeon = queue.popleft() + builder = world.dungeon_layouts[player][dungeon] + increased = suggestion_map[dungeon] + 1 + valid_doors, bk_number = find_valid_bk_combination(builder, increased, start_regions_map[dungeon], + paths, world, player) + if valid_doors: + bk_map[dungeon] = valid_doors + remaining -= 1 + suggestion_map[dungeon] = increased + flex_map[dungeon] -= 1 + if flex_map[dungeon] > 0: + queue.append(dungeon) + # time to re-assign + reassign_big_key_doors(bk_map, world, player) def shuffle_key_doors(builder, world, player): @@ -1582,6 +1899,223 @@ def find_current_key_doors(builder): return current_doors +def find_trappable_candidates(builder, world, player): + if world.door_type_mode[player] != 'original': # all, chaos + r_set = builder.master_sector.region_set() + filtered_doors = [ext.door for r in r_set for ext in r.exits + if ext.door and ext.door.type in [DoorType.Interior, DoorType.Normal]] + for d in filtered_doors: + # I only support the first 3 due to the trapFlag right now + if 0 <= d.doorListPos < 3 and not d.entranceFlag: + room = world.get_room(d.roomIndex, player) + kind = room.kind(d) + if d.type == DoorType.Interior: + if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, + DoorKind.BigKey] + or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name) + or (kind == DoorKind.TrapTriggerable and d.direction in [Direction.North, Direction.East]) + or (kind == DoorKind.Trap2 and d.direction in [Direction.South, Direction.West])): + builder.candidates.trap.add(d) + elif d.type == DoorType.Normal: + if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, + DoorKind.BigKey] + or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name)): + builder.candidates.trap.add(d) + else: + r_set = builder.master_sector.region_set() + for r in r_set: + for ext in r.exits: + if ext.door: + d = ext.door + if d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name: + builder.candidates.trap.add(d) + + +def find_valid_trap_combination(builder, suggested, start_regions, paths, world, player, drop=True): + trap_door_pool = builder.candidates.trap + trap_doors_needed = suggested + if player in world.custom_door_types: + custom_trap_doors = world.custom_door_types[player]['Trap Door'][builder.name] + else: + custom_trap_doors = [] + if custom_trap_doors: + trap_door_pool = filter_key_door_pool(trap_door_pool, custom_trap_doors) + trap_doors_needed -= len(custom_trap_doors) + if len(trap_door_pool) < trap_doors_needed: + if not drop: + return None, 0 + trap_doors_needed = len(trap_door_pool) + combinations = ncr(len(trap_door_pool), trap_doors_needed) + itr = 0 + sample_list = build_sample_list(combinations, 1000) + proposal = kth_combination(sample_list[itr], trap_door_pool, trap_doors_needed) + proposal.extend(custom_trap_doors) + + start_regions = filter_start_regions(builder, start_regions, world, player) + while not validate_trap_layout(proposal, builder, start_regions, paths, world, player): + itr += 1 + if itr >= len(sample_list): + if not drop: + return None, 0 + trap_doors_needed -= 1 + if trap_doors_needed < 0: + raise Exception(f'Bad dungeon {builder.name} - maybe custom trap doors are bad') + combinations = ncr(len(trap_door_pool), trap_doors_needed) + sample_list = build_sample_list(combinations, 1000) + itr = 0 + proposal = kth_combination(sample_list[itr], trap_door_pool, trap_doors_needed) + proposal.extend(custom_trap_doors) + return proposal, trap_doors_needed + + +# eliminate start region if portal marked as destination +def filter_start_regions(builder, start_regions, world, player): + std_flag = world.mode[player] == 'standard' and builder.name == 'Hyrule Castle' + excluded = {} + for region in start_regions: + portal = next((x for x in world.dungeon_portals[player] if x.door.entrance.parent_region == region), None) + if portal and portal.destination: + excluded[region] = None + if std_flag and (not portal or portal.find_portal_entrance().parent_region.name != 'Hyrule Castle Courtyard'): + excluded[region] = None + return [x for x in start_regions if x not in excluded.keys()] + + +def validate_trap_layout(proposal, builder, start_regions, paths, world, player): + return check_required_paths_with_traps(paths, proposal, builder.name, start_regions, world, player) + + +def check_required_paths_with_traps(paths, proposal, dungeon_name, start_regions, world, player): + if len(paths[dungeon_name]) > 0: + states_to_explore = {} + common_starts = tuple(start_regions) + for path in paths[dungeon_name]: + if type(path) is tuple: + states_to_explore[tuple([path[0]])] = (path[1], 'any') + else: + if common_starts not in states_to_explore: + states_to_explore[common_starts] = ([], 'all') + states_to_explore[common_starts][0].append(path) + cached_initial_state = None + for start_regs, info in states_to_explore.items(): + dest_regs, path_type = info + if type(dest_regs) is not list: + dest_regs = [dest_regs] + check_paths = convert_regions(dest_regs, world, player) + start_regions = convert_regions(start_regs, world, player) + initial = start_regs == common_starts + if not initial or cached_initial_state is None: + init = determine_init_crystal(initial, cached_initial_state, start_regions) + state = ExplorationState2(init, dungeon_name) + for region in start_regions: + state.visit_region(region) + state.add_all_doors_check_proposed_traps(region, proposal, world, player) + explore_state_proposed_traps(state, world, player) + if initial and cached_initial_state is None: + cached_initial_state = state + else: + state = cached_initial_state + if path_type == 'any': + valid, bad_region = check_if_any_regions_visited(state, check_paths) + else: + valid, bad_region = check_if_all_regions_visited(state, check_paths) + if not valid: + return False + return True + + +def reassign_trap_doors(trap_map, world, player): + logger = logging.getLogger('') + for name, traps in trap_map.items(): + builder = world.dungeon_layouts[player][name] + queue = deque(find_current_trap_doors(builder)) + while len(queue) > 0: + d = queue.pop() + if d.type is DoorType.Interior and d not in traps: + room = world.get_room(d.roomIndex, player) + kind = room.kind(d) + if kind == DoorKind.Trap: + new_type = (DoorKind.TrapTriggerable if d.direction in [Direction.South, Direction.East] else + DoorKind.Trap2) + room.change(d.doorListPos, new_type) + elif kind in [DoorKind.Trap2, DoorKind.TrapTriggerable]: + room.change(d.doorListPos, DoorKind.Normal) + d.blocked = False + elif d.type is DoorType.Normal and d not in traps: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + d.blocked = False + for d in traps: + change_door_to_trap(d, world, player) + world.spoiler.set_door_type(d.name, 'Trap Door', player) + logger.debug('Key Door: %s', d.name) + + +def find_current_trap_doors(builder): + current_doors = [] + for region in builder.master_sector.regions: + for ext in region.exits: + d = ext.door + if d and d.blocked and d.trapFlag != 0: + current_doors.append(d) + return current_doors + + +def change_door_to_trap(d, world, player): + room = world.get_room(d.roomIndex, player) + if d.type is DoorType.Interior: + kind = room.kind(d) + new_kind = None + if kind == DoorKind.TrapTriggerable and d.direction in [Direction.North, Direction.West]: + new_kind = DoorKind.Trap + elif kind == DoorKind.Trap2 and d.direction in [Direction.South, Direction.East]: + new_kind = DoorKind.Trap + elif d.direction in [Direction.North, Direction.West]: + new_kind = DoorKind.Trap2 + elif d.direction in [Direction.South, Direction.East]: + new_kind = DoorKind.TrapTriggerable + if new_kind: + d.blocked = True + verify_door_list_pos(d, room, world, player, pos=3) + d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos] + room.change(d.doorListPos, new_kind) + elif d.type is DoorType.Normal: + d.blocked = True + verify_door_list_pos(d, room, world, player, pos=3) + d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos] + room.change(d.doorListPos, DoorKind.Trap) + + +def find_big_key_candidates(builder, used, world, player): + if world.door_type_mode[player] != 'original': # all, chaos + r_set = builder.master_sector.region_set() + filtered_doors = [ext.door for r in r_set for ext in r.exits + if ext.door and ext.door.type in [DoorType.Interior, DoorType.Normal]] + for d in filtered_doors: + if 0 <= d.doorListPos < 4 and not d.entranceFlag: + room = world.get_room(d.roomIndex, player) + kind = room.kind(d) + if d.type in [DoorType.Interior, DoorType.Normal]: + if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, + DoorKind.BigKey] and d not in used) + or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name) + or (kind == DoorKind.TrapTriggerable and d.direction in [Direction.North, Direction.East]) + or (kind == DoorKind.Trap2 and d.direction in [Direction.South, Direction.West])): + builder.candidates.big.add(d) + elif d.type == DoorType.Normal: + if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, + DoorKind.BigKey] + or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name)): + builder.candidates.trap.add(d) + else: + r_set = builder.master_sector.region_set() + for r in r_set: + for ext in r.exits: + if ext.door: + d = ext.door + if d.bigKey and d.type in [DoorType.Normal, DoorType.Interior]: + builder.candidates.big.add(d) + + def find_small_key_door_candidates(builder, start_regions, world, player): # traverse dungeon and find candidates candidates = [] @@ -1638,16 +2172,7 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True sample_list = build_sample_list(combinations) proposal = kth_combination(sample_list[itr], key_door_pool, key_doors_needed) proposal.extend(custom_key_doors) - # eliminate start region if portal marked as destination - std_flag = world.mode[player] == 'standard' and builder.name == 'Hyrule Castle' - excluded = {} - for region in start_regions: - portal = next((x for x in world.dungeon_portals[player] if x.door.entrance.parent_region == region), None) - if portal and portal.destination: - excluded[region] = None - if std_flag and (not portal or portal.find_portal_entrance().parent_region.name != 'Hyrule Castle Courtyard'): - excluded[region] = None - start_regions = [x for x in start_regions if x not in excluded.keys()] + start_regions = filter_start_regions(builder, start_regions, world, player) key_layout = build_key_layout(builder, start_regions, proposal, world, player) determine_prize_lock(key_layout, world, player) @@ -1682,13 +2207,12 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True return True -def build_sample_list(combinations): - if combinations <= 1000000: +def build_sample_list(combinations, max_combinations=1000000): + if combinations <= max_combinations: sample_list = list(range(0, int(combinations))) - else: num_set = set() - while len(num_set) < 1000000: + while len(num_set) < max_combinations: num_set.add(random.randint(0, combinations)) sample_list = list(num_set) sample_list.sort() @@ -1885,9 +2409,9 @@ def change_door_to_small_key(d, world, player): room.change(d.doorListPos, DoorKind.SmallKey) -def verify_door_list_pos(d, room, world, player): - if d.doorListPos >= 4: - new_index = room.next_free() +def verify_door_list_pos(d, room, world, player, pos=4): + if d.doorListPos >= pos: + new_index = room.next_free(pos) if new_index is not None: room.swap(new_index, d.doorListPos) other = next(x for x in world.doors if x.player == player and x.roomIndex == d.roomIndex @@ -1895,7 +2419,7 @@ def verify_door_list_pos(d, room, world, player): other.doorListPos = d.doorListPos d.doorListPos = new_index else: - raise Exception(f'Invalid stateful door: {d.name}. Only 4 stateful doors per supertile') + raise Exception(f'Invalid stateful door: {d.name}. Only {pos} stateful doors per supertile') def smooth_door_pairs(world, player): @@ -2261,6 +2785,15 @@ def explore_state(state, world, player): state.add_all_doors_check_unattached(connect_region, world, player) +def explore_state_proposed_traps(state, proposed_traps, world, player): + while len(state.avail_doors) > 0: + door = state.next_avail_door().door + connect_region = world.get_entrance(door.name, player).connected_region + if not state.visited(connect_region) and valid_region_to_explore(connect_region, world, player): + state.visit_region(connect_region) + state.add_all_doors_check_proposed_traps(connect_region, proposed_traps, world, player) + + def explore_state_not_inaccessible(state, world, player): while len(state.avail_doors) > 0: door = state.next_avail_door().door diff --git a/Doors.py b/Doors.py index 26d474cc..99b4fab3 100644 --- a/Doors.py +++ b/Doors.py @@ -348,7 +348,7 @@ def create_doors(world, player): create_door(player, 'Tower Catwalk North Stairs', StrS).dir(No, 0x40, Left, High), create_door(player, 'Tower Antechamber South Stairs', StrS).dir(So, 0x30, Left, High), create_door(player, 'Tower Antechamber NW', Intr).dir(No, 0x30, Left, High).pos(1), - create_door(player, 'Tower Altar SW', Intr).dir(So, 0x30, Left, High).no_exit().pos(1), + create_door(player, 'Tower Altar SW', Intr).dir(So, 0x30, Left, High).no_exit().trap(0x2).pos(1), create_door(player, 'Tower Altar NW', Nrml).dir(No, 0x30, Left, High).pos(0), create_door(player, 'Tower Agahnim 1 SW', Nrml).dir(So, 0x20, Left, High).no_exit().trap(0x4).pos(0), @@ -667,7 +667,7 @@ def create_doors(world, player): create_door(player, 'Thieves Conveyor Maze SW', Intr).dir(So, 0xbc, Left, High).pos(6), create_door(player, 'Thieves Pot Alcove Top NW', Intr).dir(No, 0xbc, Left, High).pos(6), create_door(player, 'Thieves Conveyor Maze EN', Intr).dir(Ea, 0xbc, Top, High).pos(2), - create_door(player, 'Thieves Hallway WN', Intr).dir(We, 0xbc, Top, High).no_exit().pos(2), + create_door(player, 'Thieves Hallway WN', Intr).dir(We, 0xbc, Top, High).no_exit().trap(0x1).pos(2), create_door(player, 'Thieves Conveyor Maze Down Stairs', Sprl).dir(Dn, 0xbc, 0, HTH).ss(A, 0x11, 0x80, True, True), create_door(player, 'Thieves Boss SE', Nrml).dir(So, 0xac, Right, High).no_exit().trap(0x4).pos(0), create_door(player, 'Thieves Spike Track ES', Nrml).dir(Ea, 0xbb, Bot, High).pos(5), @@ -742,7 +742,7 @@ def create_doors(world, player): create_door(player, 'Ice Big Key Push Block', Lgcl), create_door(player, 'Ice Big Key Down Ladder', Lddr).dir(So, 0x1f, 3, High), create_door(player, 'Ice Stalfos Hint SE', Intr).dir(So, 0x3e, Right, High).pos(0), - create_door(player, 'Ice Conveyor NE', Intr).dir(No, 0x3e, Right, High).no_exit().pos(0), + create_door(player, 'Ice Conveyor NE', Intr).dir(No, 0x3e, Right, High).no_exit().trap(0x4).pos(0), create_door(player, 'Ice Conveyor to Crystal', Lgcl), create_door(player, 'Ice Conveyor Crystal Exit', Lgcl), create_door(player, 'Ice Conveyor SW', Nrml).dir(So, 0x3e, Left, High).small_key().pos(1).portal(Z, 0x20), @@ -760,7 +760,7 @@ def create_doors(world, player): create_door(player, 'Ice Firebar ES', Intr).dir(Ea, 0x5e, Bot, High).pos(3), create_door(player, 'Ice Firebar Down Ladder', Lddr).dir(So, 0x5e, 5, High), create_door(player, 'Ice Spike Cross NE', Intr).dir(No, 0x5e, Right, High).pos(1), - create_door(player, 'Ice Falling Square SE', Intr).dir(So, 0x5e, Right, High).no_exit().pos(1), + create_door(player, 'Ice Falling Square SE', Intr).dir(So, 0x5e, Right, High).no_exit().trap(0x1).pos(1), create_door(player, 'Ice Falling Square Hole', Hole), create_door(player, 'Ice Spike Room WS', Nrml).dir(We, 0x5f, Bot, High).small_key().pos(0), create_door(player, 'Ice Spike Room Down Stairs', Sprl).dir(Dn, 0x5f, 3, HTH).ss(Z, 0x11, 0x48, True, True), @@ -840,12 +840,12 @@ def create_doors(world, player): create_door(player, 'Mire Hub Top NW', Nrml).dir(No, 0xc2, Left, High).pos(2), create_door(player, 'Mire Lone Shooter WS', Nrml).dir(We, 0xc3, Bot, High).pos(6), create_door(player, 'Mire Lone Shooter ES', Intr).dir(Ea, 0xc3, Bot, High).pos(3), - create_door(player, 'Mire Falling Bridge WS', Intr).dir(We, 0xc3, Bot, High).no_exit().pos(3), + create_door(player, 'Mire Falling Bridge WS', Intr).dir(We, 0xc3, Bot, High).no_exit().trap(0x8).pos(3), create_door(player, 'Mire Falling Bridge W', Intr).dir(We, 0xc3, Mid, High).pos(2), - create_door(player, 'Mire Failure Bridge E', Intr).dir(Ea, 0xc3, Mid, High).no_exit().pos(2), + create_door(player, 'Mire Failure Bridge E', Intr).dir(Ea, 0xc3, Mid, High).no_exit().trap(0x1).pos(2), create_door(player, 'Mire Failure Bridge W', Nrml).dir(We, 0xc3, Mid, High).pos(5), create_door(player, 'Mire Falling Bridge WN', Intr).dir(We, 0xc3, Top, High).pos(1), - create_door(player, 'Mire Map Spike Side EN', Intr).dir(Ea, 0xc3, Top, High).no_exit().pos(1), + create_door(player, 'Mire Map Spike Side EN', Intr).dir(Ea, 0xc3, Top, High).no_exit().trap(0x2).pos(1), create_door(player, 'Mire Map Spot WN', Nrml).dir(We, 0xc3, Top, High).small_key().pos(0), create_door(player, 'Mire Crystal Dead End NW', Nrml).dir(No, 0xc3, Left, High).pos(4), create_door(player, 'Mire Map Spike Side Drop Down', Lgcl), @@ -903,7 +903,7 @@ def create_doors(world, player): create_door(player, 'Mire Tile Room NW', Intr).dir(No, 0xc1, Left, High).pos(3), create_door(player, 'Mire Compass Room SW', Intr).dir(So, 0xc1, Left, High).pos(3), create_door(player, 'Mire Compass Room EN', Intr).dir(Ea, 0xc1, Top, High).pos(2), - create_door(player, 'Mire Wizzrobe Bypass WN', Intr).dir(We, 0xc1, Top, High).no_exit().pos(2), + create_door(player, 'Mire Wizzrobe Bypass WN', Intr).dir(We, 0xc1, Top, High).no_exit().trap(0x1).pos(2), create_door(player, 'Mire Compass Blue Barrier', Lgcl), create_door(player, 'Mire Compass Chest Exit', Lgcl), create_door(player, 'Mire Neglected Room NE', Nrml).dir(No, 0xd1, Right, High).pos(2), @@ -912,7 +912,7 @@ def create_doors(world, player): create_door(player, 'Mire Neglected Room SE', Intr).dir(So, 0xd1, Right, High).pos(3), create_door(player, 'Mire Chest View NE', Intr).dir(No, 0xd1, Right, High).pos(3), create_door(player, 'Mire BK Chest Ledge WS', Intr).dir(We, 0xd1, Bot, High).pos(0), - create_door(player, 'Mire Warping Pool ES', Intr).dir(Ea, 0xd1, Bot, High).no_exit().pos(0), + create_door(player, 'Mire Warping Pool ES', Intr).dir(Ea, 0xd1, Bot, High).no_exit().trap(0x4).pos(0), create_door(player, 'Mire Warping Pool Warp', Warp), create_door(player, 'Mire Torches Top Down Stairs', Sprl).dir(Dn, 0x97, 0, HTH).ss(A, 0x11, 0xb0, True).kill(), create_door(player, 'Mire Torches Top SW', Intr).dir(So, 0x97, Left, High).pos(1), @@ -1011,7 +1011,7 @@ def create_doors(world, player): create_door(player, 'TR Big Chest Entrance SE', Nrml).dir(So, 0x24, Right, High).pos(4).kill().portal(X, 0x00), create_door(player, 'TR Big Chest Entrance Gap', Lgcl), create_door(player, 'TR Big Chest NE', Intr).dir(No, 0x24, Right, High).pos(3), - create_door(player, 'TR Dodgers SE', Intr).dir(So, 0x24, Right, High).no_exit().pos(3), + create_door(player, 'TR Dodgers SE', Intr).dir(So, 0x24, Right, High).no_exit().trap(0x8).pos(3), create_door(player, 'TR Dodgers NE', Nrml).dir(No, 0x24, Right, High).big_key().pos(0), create_door(player, 'TR Lazy Eyes SE', Nrml).dir(So, 0x23, Right, High).pos(0).portal(X, 0x00), create_door(player, 'TR Lazy Eyes ES', Nrml).dir(Ea, 0x23, Bot, High).pos(1), @@ -1073,7 +1073,7 @@ def create_doors(world, player): create_door(player, 'GT Hope Room EN', Nrml).dir(Ea, 0x8c, Top, High).trap(0x4).pos(0), create_door(player, 'GT Torch EN', Intr).dir(Ea, 0x8c, Top, High).small_key().pos(2), create_door(player, 'GT Hope Room WN', Intr).dir(We, 0x8c, Top, High).small_key().pos(2), - create_door(player, 'GT Torch SW', Intr).dir(So, 0x8c, Left, High).no_exit().pos(1), + create_door(player, 'GT Torch SW', Intr).dir(So, 0x8c, Left, High).no_exit().trap(0x2).pos(1), create_door(player, 'GT Big Chest NW', Intr).dir(No, 0x8c, Left, High).pos(1), create_door(player, 'GT Blocked Stairs Down Stairs', Sprl).dir(Dn, 0x8c, 3, HTH).ss(Z, 0x12, 0x40, True, True).kill(), create_door(player, 'GT Blocked Stairs Block Path', Lgcl), @@ -1179,7 +1179,7 @@ def create_doors(world, player): create_door(player, 'GT Ice Armos NE', Intr).dir(No, 0x1c, Right, High).pos(0), create_door(player, 'GT Big Key Room SE', Intr).dir(So, 0x1c, Right, High).pos(0), create_door(player, 'GT Ice Armos WS', Intr).dir(We, 0x1c, Bot, High).pos(1), - create_door(player, 'GT Four Torches ES', Intr).dir(Ea, 0x1c, Bot, High).no_exit().pos(1), + create_door(player, 'GT Four Torches ES', Intr).dir(Ea, 0x1c, Bot, High).no_exit().trap(0x2).pos(1), create_door(player, 'GT Four Torches NW', Intr).dir(No, 0x1c, Left, High).pos(2), create_door(player, 'GT Fairy Abyss SW', Intr).dir(So, 0x1c, Left, High).pos(2), create_door(player, 'GT Four Torches Up Stairs', Sprl).dir(Up, 0x1c, 0, HTH).ss(Z, 0x1b, 0x2c, True, True), @@ -1211,7 +1211,7 @@ def create_doors(world, player): create_door(player, 'GT Beam Dash WS', Intr).dir(We, 0x6c, Bot, High).pos(0), create_door(player, 'GT Lanmolas 2 ES', Intr).dir(Ea, 0x6c, Bot, High).pos(0), create_door(player, 'GT Lanmolas 2 NW', Intr).dir(No, 0x6c, Left, High).pos(1), - create_door(player, 'GT Quad Pot SW', Intr).dir(So, 0x6c, Left, High).no_exit().pos(1), + create_door(player, 'GT Quad Pot SW', Intr).dir(So, 0x6c, Left, High).no_exit().trap(0x2).pos(1), create_door(player, 'GT Quad Pot Up Stairs', Sprl).dir(Up, 0x6c, 0, HTH).ss(A, 0x1b, 0x6c, True, True), create_door(player, 'GT Wizzrobes 1 Down Stairs', Sprl).dir(Dn, 0xa5, 0, HTH).ss(A, 0x12, 0x80, True, True), create_door(player, 'GT Wizzrobes 1 SW', Intr).dir(So, 0xa5, Left, High).pos(2), diff --git a/DungeonGenerator.py b/DungeonGenerator.py index eb5ef97b..7e3b2ef7 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1262,7 +1262,7 @@ def simple_dungeon_builder(name, sector_list): return builder -def create_dungeon_builders(all_sectors, connections_tuple, world, player, +def create_dungeon_builders(all_sectors, connections_tuple, world, player, dungeon_pool, dungeon_entrances=None, split_dungeon_entrances=None): logger = logging.getLogger('') logger.info('Shuffling Dungeon Sectors') @@ -1278,7 +1278,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, global_pole = GlobalPolarity(candidate_sectors) dungeon_map = {} - for key in dungeon_regions.keys(): + for key in dungeon_pool: dungeon_map[key] = DungeonBuilder(key) for key in dungeon_boss_sectors.keys(): current_dungeon = dungeon_map[key] diff --git a/RoomData.py b/RoomData.py index e3f432d0..cfdd183f 100644 --- a/RoomData.py +++ b/RoomData.py @@ -316,9 +316,9 @@ class Room(object): byte_array.append(kind.value) return byte_array - def next_free(self): + def next_free(self, pos=4): for i, door in enumerate(self.doorList): - if i >= 4: + if i >= pos: return None pos, kind = door if kind not in [DoorKind.SmallKey, DoorKind.Dashable, DoorKind.Bombable, DoorKind.TrapTriggerable, @@ -395,8 +395,8 @@ class DoorKind(Enum): Bombable = 0x2E BlastWall = 0x30 Hidden = 0x32 - TrapTriggerable = 0x36 # right side trap or south side trap - Trap2 = 0x38 # left side trap or north side trap + TrapTriggerable = 0x36 # right side trap or south side trap (West, South) + Trap2 = 0x38 # left side trap or north side trap (East, North) NormalLow2 = 0x40 TrapTriggerableLow = 0x44 Warp = 0x46 diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py index e16b449d..05721c9b 100644 --- a/source/dungeon/DungeonStitcher.py +++ b/source/dungeon/DungeonStitcher.py @@ -68,16 +68,11 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon entrance_regions = [x for x in entrance_regions if x not in excluded.keys()] doors_to_connect, idx = {}, 0 all_regions = set() - bk_special = False for sector in builder.sectors: for door in sector.outstanding_doors: doors_to_connect[door.name] = door, idx idx += 1 all_regions.update(sector.regions) - bk_special |= check_for_special(sector.regions) - bk_needed = False - for sector in builder.sectors: - bk_needed |= determine_if_bk_needed(sector, split_dungeon, bk_special, world, player) finished = False # flag if standard and this is hyrule castle paths = determine_paths_for_dungeon(world, player, all_regions, name) @@ -96,9 +91,9 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon if hash_code not in hash_code_set: hash_code_set.add(hash_code) explored_state = explore_proposal(name, entrance_regions, all_regions, proposed_map, doors_to_connect, - bk_needed, bk_special, world, player) + world, player) if check_valid(name, explored_state, proposed_map, doors_to_connect, all_regions, - bk_needed, bk_special, paths, entrance_regions, world, player): + paths, entrance_regions, world, player): finished = True else: proposed_map, hash_code = modify_proposal(proposed_map, explored_state, doors_to_connect, @@ -217,29 +212,21 @@ def modify_proposal(proposed_map, explored_state, doors_to_connect, hash_code_se return proposed_map, hash_code -def explore_proposal(name, entrance_regions, all_regions, proposed_map, valid_doors, - bk_needed, bk_special, world, player): +def explore_proposal(name, entrance_regions, all_regions, proposed_map, valid_doors, world, player): start = ExplorationState(dungeon=name) - start.big_key_special = bk_special - - bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed - - def exception(d): - return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS' - original_state = extend_reachable_state_improved(entrance_regions, start, proposed_map, all_regions, - valid_doors, bk_flag, world, player, exception) + original_state = extend_reachable_state_lenient(entrance_regions, start, proposed_map, + all_regions, valid_doors, world, player) return original_state def check_valid(name, exploration_state, proposed_map, doors_to_connect, all_regions, - bk_needed, bk_special, paths, entrance_regions, world, player): + paths, entrance_regions, world, player): all_visited = set() all_visited.update(exploration_state.visited_blue) all_visited.update(exploration_state.visited_orange) if len(all_regions.difference(all_visited)) > 0: return False - if not valid_paths(name, paths, entrance_regions, doors_to_connect, all_regions, proposed_map, - bk_needed, bk_special, world, player): + if not valid_paths(name, paths, entrance_regions, doors_to_connect, all_regions, proposed_map, world, player): return False return True @@ -262,8 +249,7 @@ def check_for_special(regions): return False -def valid_paths(name, paths, entrance_regions, valid_doors, all_regions, proposed_map, - bk_needed, bk_special, world, player): +def valid_paths(name, paths, entrance_regions, valid_doors, all_regions, proposed_map, world, player): for path in paths: if type(path) is tuple: target = path[1] @@ -275,14 +261,12 @@ def valid_paths(name, paths, entrance_regions, valid_doors, all_regions, propose else: target = path start_regions = entrance_regions - if not valid_path(name, start_regions, target, valid_doors, proposed_map, all_regions, - bk_needed, bk_special, world, player): + if not valid_path(name, start_regions, target, valid_doors, proposed_map, all_regions, world, player): return False return True -def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_regions, - bk_needed, bk_special, world, player): +def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_regions, world, player): target_regions = set() if type(target) is not list: for region in all_regions: @@ -295,16 +279,11 @@ def valid_path(name, starting_regions, target, valid_doors, proposed_map, all_re target_regions.add(region) start = ExplorationState(dungeon=name) - start.big_key_special = bk_special - bk_flag = False if world.bigkeyshuffle[player] and not bk_special else bk_needed - - def exception(d): - return name == 'Skull Woods 2' and d.name == 'Skull Pinball WS' - original_state = extend_reachable_state_improved(starting_regions, start, proposed_map, all_regions, - valid_doors, bk_flag, world, player, exception) + original_state = extend_reachable_state_lenient(starting_regions, start, proposed_map, all_regions, + valid_doors, world, player) for exp_door in original_state.unattached_doors: - if not exp_door.door.blocked: + if not exp_door.door.blocked or exp_door.door.trapFlag != 0: return True # outstanding connection possible for target in target_regions: if original_state.visited_at_all(target): @@ -637,6 +616,37 @@ class ExplorationState(object): elif not self.in_door_list(door, self.avail_doors): self.append_door_to_list(door, self.avail_doors, flag) + def add_all_doors_check_proposed_2(self, region, proposed_map, valid_doors, flag, world, player): + for door in get_doors(world, region, player): + if door in proposed_map and door.name in valid_doors: + self.visited_doors.add(door) + if self.can_traverse_ignore_traps(door): + if door.controller is not None: + door = door.controller + if door.dest is None and door not in proposed_map.keys() and door.name in valid_doors: + if not self.in_door_list_ic(door, self.unattached_doors): + self.append_door_to_list(door, self.unattached_doors, flag) + else: + other = self.find_door_in_list(door, self.unattached_doors) + if self.crystal != other.crystal: + other.crystal = CrystalBarrier.Either + elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, + self.event_doors): + self.append_door_to_list(door, self.event_doors, flag) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors, flag) + + def add_all_doors_check_proposed_traps(self, region, proposed_traps, world, player): + for door in get_doors(world, region, player): + if self.can_traverse_ignore_traps(door) and door not in proposed_traps: + if door.controller is not None: + door = door.controller + if door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, + self.event_doors): + self.append_door_to_list(door, self.event_doors, False) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors, False) + def add_all_doors_check_key_region(self, region, key_region, world, player): for door in get_doors(world, region, player): if self.can_traverse(door): @@ -693,6 +703,13 @@ class ExplorationState(object): return self.crystal == CrystalBarrier.Either or door.crystal == self.crystal return True + def can_traverse_ignore_traps(self, door): + if door.blocked and door.trapFlag == 0: + return False + if door.crystal not in [CrystalBarrier.Null, CrystalBarrier.Either]: + return self.crystal == CrystalBarrier.Either or door.crystal == self.crystal + return True + def count_locations_exclude_specials(self, world, player): return count_locations_exclude_big_chest(self.found_locations, world, player) @@ -801,6 +818,25 @@ def extend_reachable_state_improved(search_regions, state, proposed_map, all_reg return local_state +def extend_reachable_state_lenient(search_regions, state, proposed_map, all_regions, valid_doors, world, player): + local_state = state.copy() + for region in search_regions: + local_state.visit_region(region) + local_state.add_all_doors_check_proposed_2(region, proposed_map, valid_doors, world, player) + while len(local_state.avail_doors) > 0: + explorable_door = local_state.next_avail_door() + if explorable_door.door in proposed_map: + connect_region = world.get_entrance(proposed_map[explorable_door.door].name, player).parent_region + else: + connect_region = world.get_entrance(explorable_door.door.name, player).connected_region + if connect_region is not None: + if (valid_region_to_explore_in_regions(connect_region, all_regions, world, player) + and not local_state.visited(connect_region)): + local_state.visit_region(connect_region) + local_state.add_all_doors_check_proposed_2(connect_region, proposed_map, valid_doors, world, player) + return local_state + + def special_big_key_found(state): for location in state.found_locations: if location.forced_item and location.forced_item.bigkey: From d9f0e2a7b6e9226f2c2517fc0d51210eed2c6bc0 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 6 Jul 2022 10:06:29 -0600 Subject: [PATCH 027/146] Options added for door_type_mode and new partitioned mode --- BaseClasses.py | 17 +- CLI.py | 3 +- DoorShuffle.py | 770 +++++++++++++----- DungeonGenerator.py | 26 +- KeyDoorShuffle.py | 50 +- Main.py | 1 + Rom.py | 31 +- RoomData.py | 4 +- data/base2current.bps | Bin 93061 -> 93211 bytes mystery_example.yml | 5 + resources/app/cli/args.json | 11 +- resources/app/cli/lang/en.json | 8 + resources/app/gui/lang/en.json | 7 + .../app/gui/randomize/dungeon/widgets.json | 14 + source/classes/CustomSettings.py | 2 + source/classes/constants.py | 1 + source/dungeon/DungeonStitcher.py | 29 +- source/tools/MysteryUtils.py | 1 + 18 files changed, 722 insertions(+), 258 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 8c7957d8..39286e37 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -28,6 +28,7 @@ class World(object): self.shuffle = shuffle.copy() self.doorShuffle = doorShuffle.copy() self.intensity = {} + self.door_type_mode = {} self.logic = logic.copy() self.mode = mode.copy() self.swords = swords.copy() @@ -143,6 +144,7 @@ class World(object): set_player_attr('colorizepots', False) set_player_attr('pot_pool', {}) set_player_attr('decoupledoors', False) + set_player_attr('door_type_mode', 'original') set_player_attr('shopsanity', False) set_player_attr('mixed_travel', 'prevent') @@ -1872,7 +1874,6 @@ class Sector(object): self.item_logic = set() self.chest_location_set = set() - def region_set(self): if self.r_name_set is None: self.r_name_set = dict.fromkeys(map(lambda r: r.name, self.regions)) @@ -2154,7 +2155,7 @@ class Location(object): def gen_name(self): name = self.name world = self.parent_region.world if self.parent_region and self.parent_region.world else None - if self.parent_region.dungeon and world and world.doorShuffle[self.player] == 'crossed': + if self.parent_region.dungeon and world and world.doorShuffle[self.player] not in ['basic', 'vanilla']: name += f' @ {self.parent_region.dungeon.name}' if world and world.players > 1: name += f' ({world.get_player_names(self.player)})' @@ -2377,6 +2378,8 @@ class Spoiler(object): 'overworld_map': self.world.overworld_map, 'door_shuffle': self.world.doorShuffle, 'intensity': self.world.intensity, + 'door_type_mode': self.world.door_type_mode, + 'decoupledoors': self.world.decoupledoors, 'dungeon_counters': self.world.dungeon_counters, 'item_pool': self.world.difficulty, 'item_functionality': self.world.difficulty_adjustments, @@ -2578,6 +2581,7 @@ class Spoiler(object): outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player]) if self.metadata['door_shuffle'][player] != 'vanilla': outfile.write(f"Intensity: {self.metadata['intensity'][player]}\n") + outfile.write(f"Door Type Mode: {self.metadata['door_type_mode'][player]}\n") outfile.write(f"Decouple Doors: {yn(self.metadata['decoupledoors'][player])}\n") outfile.write(f"Experimental: {yn(self.metadata['experimental'][player])}\n") outfile.write(f"Dungeon Counters: {self.metadata['dungeon_counters'][player]}\n") @@ -2815,7 +2819,7 @@ class Pot(object): # byte 0: DDDE EEEE (DR, ER) -dr_mode = {"basic": 1, "crossed": 2, "vanilla": 0} +dr_mode = {"basic": 1, "crossed": 2, "vanilla": 0, "partitioned": 3} er_mode = {"vanilla": 0, "simple": 1, "restricted": 2, "full": 3, "crossed": 4, "insanity": 5, 'lite': 8, 'lean': 9, "dungeonsfull": 7, "dungeonssimple": 6} @@ -2845,7 +2849,8 @@ counter_mode = {"default": 0, "off": 1, "on": 2, "pickup": 3} # byte 6: CCCC CPAA (crystals ganon, pyramid, access access_mode = {"items": 0, "locations": 1, "none": 2} -# byte 7: BSMC ??EE (big, small, maps, compass, bosses, enemies) +# byte 7: BSMC DDEE (big, small, maps, compass, door_type, enemies) +door_type_mode = {'original': 0, 'big': 1, 'all': 2, 'chaos': 3} enemy_mode = {"none": 0, "shuffled": 1, "chaos": 2, "random": 2, "legacy": 3} # byte 8: HHHD DPBS (enemy_health, enemy_dmg, potshuffle, bomb logic, shuffle links) @@ -2898,7 +2903,7 @@ class Settings(object): (0x80 if w.bigkeyshuffle[p] else 0) | (0x40 if w.keyshuffle[p] else 0) | (0x20 if w.mapshuffle[p] else 0) | (0x10 if w.compassshuffle[p] else 0) - | (enemy_mode[w.enemy_shuffle[p]]), + | (door_type_mode[w.door_type_mode[p]] << 2) | (enemy_mode[w.enemy_shuffle[p]]), (e_health[w.enemy_health[p]] << 5) | (e_dmg[w.enemy_damage[p]] << 3) | (0x4 if w.potshuffle[p] else 0) | (0x2 if w.bombbag[p] else 0) | (1 if w.shufflelinks[p] else 0), @@ -2955,7 +2960,7 @@ class Settings(object): args.keyshuffle[p] = True if settings[7] & 0x40 else False args.mapshuffle[p] = True if settings[7] & 0x20 else False args.compassshuffle[p] = True if settings[7] & 0x10 else False - # args.shufflebosses[p] = r(boss_mode)[(settings[7] & 0xc) >> 2] + args.door_type_mode[p] = r(door_type_mode)[(settings[7] & 0xc) >> 2] args.shuffleenemies[p] = r(enemy_mode)[settings[7] & 0x3] args.enemy_health[p] = r(e_health)[(settings[8] & 0xE0) >> 5] diff --git a/CLI.py b/CLI.py index 77b020b4..2e01e4bc 100644 --- a/CLI.py +++ b/CLI.py @@ -125,7 +125,7 @@ def parse_cli(argv, no_defaults=False): 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle', 'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx', - 'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors']: + 'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors', 'door_type_mode']: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) @@ -192,6 +192,7 @@ def parse_settings(): "keysanity": False, "door_shuffle": "basic", "intensity": 2, + 'door_type_mode': 'original', 'decoupledoors': False, "experimental": False, "dungeon_counters": "default", diff --git a/DoorShuffle.py b/DoorShuffle.py index b8c8abbe..42d32c24 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -4,6 +4,7 @@ import logging import time from enum import unique, Flag from typing import DefaultDict, Dict, List +from itertools import chain from BaseClasses import RegionType, Region, Door, DoorType, Direction, Sector, CrystalBarrier, DungeonInfo, dungeon_keys from BaseClasses import PotFlags, LocationType, Direction @@ -18,8 +19,9 @@ from source.dungeon.DungeonStitcher import ExplorationState as ExplorationState2 from DungeonGenerator import ExplorationState, convert_regions, pre_validate, determine_required_paths, drop_entrances from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances from DungeonGenerator import dungeon_portals, dungeon_drops, connect_doors -from DungeonGenerator import valid_region_to_explore as valid_region_to_explore_lim +from DungeonGenerator import valid_region_to_explore from KeyDoorShuffle import analyze_dungeon, build_key_layout, validate_key_layout, determine_prize_lock +from KeyDoorShuffle import validate_bk_layout, check_bk_special from Utils import ncr, kth_combination @@ -87,7 +89,7 @@ def link_doors_prep(world, player): find_inaccessible_regions(world, player) - if world.intensity[player] >= 3 and world.doorShuffle[player] in ['basic', 'crossed']: + if world.intensity[player] >= 3 and world.doorShuffle[player] != 'vanilla': choose_portals(world, player) else: if world.shuffle[player] == 'vanilla': @@ -128,14 +130,21 @@ def link_doors_prep(world, player): def link_doors_main(world, player): + pool = None if world.doorShuffle[player] == 'basic': - within_dungeon(world, player) + pool = [([name], regions) for name, regions in dungeon_regions.items()] + elif world.doorShuffle[player] == 'partitioned': + groups = [['Hyrule Castle', 'Eastern Palace', 'Desert Palace', 'Tower of Hera', 'Agahnims Tower'], + ['Palace of Darkness', 'Swamp Palace', 'Skull Woods', 'Thieves Town'], + ['Ice Palace', 'Misery Mire', 'Turtle Rock', 'Ganons Tower']] + pool = [(group, list(chain.from_iterable([dungeon_regions[d] for d in group]))) for group in groups] elif world.doorShuffle[player] == 'crossed': - cross_dungeon(world, player) + pool = [list(dungeon_regions.keys()), sum(r for r in dungeon_regions.values())] elif world.doorShuffle[player] != 'vanilla': logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player]) raise Exception('Invalid door shuffle setting: %s' % world.doorShuffle[player]) - + if pool: + main_dungeon_pool(pool, world, player) if world.doorShuffle[player] != 'vanilla': create_door_spoiler(world, player) @@ -395,8 +404,20 @@ def pair_existing_key_doors(world, player, door_a, door_b): def choose_portals(world, player): - if world.doorShuffle[player] in ['basic', 'crossed']: - cross_flag = world.doorShuffle[player] == 'crossed' + if world.doorShuffle[player] != ['vanilla']: + shuffle_flag = world.doorShuffle[player] != 'basic' + allowed = {} + if world.doorShuffle[player] == 'basic': + allowed = {name: {name} for name in dungeon_regions} + elif world.doorShuffle[player] == 'partitioned': + groups = [['Hyrule Castle', 'Eastern Palace', 'Desert Palace', 'Tower of Hera', 'Agahnims Tower'], + ['Palace of Darkness', 'Swamp Palace', 'Skull Woods', 'Thieves Town'], + ['Ice Palace', 'Misery Mire', 'Turtle Rock', 'Ganons Tower']] + allowed = {name: set(group) for group in groups for name in group} + elif world.doorShuffle[player] == 'crossed': + all_dungeons = set(dungeon_regions.keys()) + allowed = {name: all_dungeons for name in dungeon_regions} + # key drops allow the big key in the right place in Desert Tiles 2 bk_shuffle = world.bigkeyshuffle[player] or world.dropshuffle[player] std_flag = world.mode[player] == 'standard' @@ -443,7 +464,7 @@ def choose_portals(world, player): custom = customizer_portals(master_door_list, world, player) - if cross_flag: + if shuffle_flag: random.shuffle(shuffled_info) for dungeon, info in shuffled_info: outstanding_portals = list(dungeon_portals[dungeon]) @@ -457,15 +478,15 @@ def choose_portals(world, player): info.required_passage[target_region] = [x for x in possible_portals if x != sanc.name] info.required_passage = {x: y for x, y in info.required_passage.items() if len(y) > 0} for target_region, possible_portals in info.required_passage.items(): - candidates = find_portal_candidates(master_door_list, dungeon, custom, need_passage=True, - crossed=cross_flag, bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) + candidates = find_portal_candidates(master_door_list, dungeon, custom, allowed, need_passage=True, + bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) choice, portal = assign_portal(candidates, possible_portals, custom, world, player) portal.destination = True clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals) dead_end_choices = info.total - 1 - len(portal_assignment[dungeon]) for i in range(0, dead_end_choices): - candidates = find_portal_candidates(master_door_list, dungeon, custom, dead_end_allowed=True, - crossed=cross_flag, bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) + candidates = find_portal_candidates(master_door_list, dungeon, custom, allowed, dead_end_allowed=True, + bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) possible_portals = outstanding_portals if not info.sole_entrance else [x for x in outstanding_portals if x != info.sole_entrance] choice, portal = assign_portal(candidates, possible_portals, custom, world, player) if choice.deadEnd: @@ -476,7 +497,7 @@ def choose_portals(world, player): clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals) the_rest = info.total - len(portal_assignment[dungeon]) for i in range(0, the_rest): - candidates = find_portal_candidates(master_door_list, dungeon, custom, crossed=cross_flag, + candidates = find_portal_candidates(master_door_list, dungeon, custom, allowed, bk_shuffle=bk_shuffle, standard=hc_flag, rupee_bow=rupee_bow_flag) choice, portal = assign_portal(candidates, outstanding_portals, custom, world, player) clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals) @@ -620,7 +641,7 @@ def disconnect_portal(portal, world, player): chosen_door.entranceFlag = False -def find_portal_candidates(door_list, dungeon, custom, need_passage=False, dead_end_allowed=False, crossed=False, +def find_portal_candidates(door_list, dungeon, custom, allowed, need_passage=False, dead_end_allowed=False, bk_shuffle=False, standard=False, rupee_bow=False): custom_portals, assigned_doors = custom if assigned_doors: @@ -628,10 +649,8 @@ def find_portal_candidates(door_list, dungeon, custom, need_passage=False, dead_ else: ret = door_list ret = [x for x in ret if bk_shuffle or not x.bk_shuffle_req] - if crossed: - ret = [x for x in ret if not x.dungeonLink or x.dungeonLink == dungeon or x.dungeonLink.startswith('link')] - else: - ret = [x for x in ret if x.entrance.parent_region.dungeon.name == dungeon] + ret = [x for x in ret if not x.dungeonLink or x.dungeonLink == dungeon or x.dungeonLink.startswith('link')] + ret = [x for x in ret if x.entrance.parent_region.dungeon.name in allowed[dungeon]] if need_passage: ret = [x for x in ret if x.passage] if not dead_end_allowed: @@ -789,7 +808,7 @@ def main_dungeon_pool(dungeon_pool, world, player): # todo: which dungeon to create dungeon_builders.update(create_dungeon_builders(sector_pool, connections_tuple, world, player, pool, entrances, splits)) - door_type_pools.append((pool, DoorTypePool(sector_pool, world, player))) + door_type_pools.append((pool, DoorTypePool(pool, world, player))) update_forced_keys(dungeon_builders, entrances_map, world, player) recombinant_builders = {} @@ -816,8 +835,60 @@ def main_dungeon_pool(dungeon_pool, world, player): target_items += 19 # 19 pot keys d_items = target_items - all_dungeon_items_cnt world.pool_adjustment[player] = d_items + # todo: remove unused pairs if not world.decoupledoors[player]: smooth_door_pairs(world, player) + cross_dungeon_clean_up(world, player) + + +def cross_dungeon_clean_up(world, player): + # Re-assign dungeon bosses + gt = world.get_dungeon('Ganons Tower', player) + for name, builder in world.dungeon_layouts[player].items(): + reassign_boss('GT Ice Armos', 'bottom', builder, gt, world, player) + reassign_boss('GT Lanmolas 2', 'middle', builder, gt, world, player) + reassign_boss('GT Moldorm', 'top', builder, gt, world, player) + + sanctuary = world.get_region('Sanctuary', player) + d_name = sanctuary.dungeon.name + if d_name != 'Hyrule Castle': + possible_portals = [] + for portal_name in dungeon_portals[d_name]: + portal = world.get_portal(portal_name, player) + if portal.door.name == 'Sanctuary S': + possible_portals.clear() + possible_portals.append(portal) + break + if not portal.destination and not portal.deadEnd: + possible_portals.append(portal) + if len(possible_portals) == 1: + world.sanc_portal[player] = possible_portals[0] + else: + reachable_portals = [] + for portal in possible_portals: + start_area = portal.door.entrance.parent_region + state = ExplorationState(dungeon=d_name) + state.visit_region(start_area) + state.add_all_doors_check_unattached(start_area, world, player) + explore_state(state, world, player) + if state.visited_at_all(sanctuary): + reachable_portals.append(portal) + world.sanc_portal[player] = random.choice(reachable_portals) + if world.intensity[player] >= 3: + if player in world.sanc_portal: + portal = world.sanc_portal[player] + else: + portal = world.get_portal('Sanctuary', player) + target = portal.door.entrance.parent_region + connect_simple_door(world, 'Sanctuary Mirror Route', target, player) + + check_entrance_fixes(world, player) + + if world.standardize_palettes[player] == 'standardize' and world.doorShuffle[player] != 'basic': + palette_assignment(world, player) + + refine_hints(world.dungeon_layouts[player]) + refine_boss_exits(world, player) def update_forced_keys(dungeon_builders, entrances_map, world, player): @@ -1629,14 +1700,6 @@ def combine_layouts(recombinant_builders, dungeon_builders, entrances_map, world dungeon_builders[recombine.name] = recombine -# todo: this allows cross-dungeon exploring via HC Ledge or Inaccessible Regions -# todo: @deprecated -def valid_region_to_explore(region, world, player): - return region and (region.type == RegionType.Dungeon - or region.name in world.inaccessible_regions[player] - or (region.name == 'Hyrule Castle Ledge' and world.mode[player] == 'standard')) - - def setup_custom_door_types(world, player): if not hasattr(world, 'custom_door_types'): world.custom_door_types = defaultdict(dict) @@ -1668,58 +1731,30 @@ def setup_custom_door_types(world, player): class DoorTypePool: - def __init__(self, sectors, world, player): + def __init__(self, pool, world, player): self.smalls = 0 self.bombable = 0 self.dashable = 0 self.bigs = 0 self.traps = 0 - # self.tricky = 0 - # self.hidden = 0 + self.tricky = 0 + self.hidden = 0 # todo: custom pools? - self.count_via_sectors(sectors, world, player) + for dungeon in pool: + counts = door_type_counts[dungeon] + if world.door_type_mode[player] == 'chaos': + counts = self.chaos_shuffle(counts) + self.smalls += counts[0] + self.bigs += counts[1] + self.traps += counts[2] + self.bombable += counts[3] + self.dashable += counts[4] + self.hidden += counts[5] + self.tricky += counts[6] - def count_via_sectors(self, sectors, world, player): - skips = set() - for sector in sectors: - for region in sector.regions: - for ext in region.exits: - if ext.door: - d = ext.door - if d.name not in skips and d.type in [DoorType.Normal, DoorType.Interior]: - if d.smallKey: - self.smalls += 1 - elif d.bigKey: - self.bigs += 1 - elif d.blocked and d.trapFlag and 'Boss' not in d.name and 'Agahnim' not in d.name: - self.traps += 1 - elif d.name == 'TR Compass Room NW': - self.tricky += 1 - elif d.name in ['Skull Vines NW', 'Tower Altar NW']: - self.hidden += 1 - else: - kind = world.get_room(d.roomIndex, player).kind(d) - if kind == DoorKind.Bombable: - self.bombable += 1 - elif kind == DoorKind.Dashable: - self.dashable += 1 - if d.type == DoorType.Interior: - skips.add(d.dest.name) ## lookup a different way for interior door shuffle - elif d.type == DoorType.Normal: - for dp in world.paired_doors[player]: - if d.name == dp.door_a or d.name == dp.door_b: - skips.add(dp.door_b if d.name == dp.door_a else dp.door_a) - break - - def chaos_shuffle(self): + def chaos_shuffle(self, counts): weights = [1, 2, 4, 3, 2, 1] - self.smalls = random.choices(self.get_choices(self.smalls), weights=weights) - self.bombable = random.choices(self.get_choices(self.bombable), weights=weights) - self.dashable = random.choices(self.get_choices(self.dashable), weights=weights) - self.bigs = random.choices(self.get_choices(self.bigs), weights=weights) - self.traps = random.choices(self.get_choices(self.traps), weights=weights) - # self.tricky = random.choices(self.get_choices(self.tricky), weights=weights) - # self.hidden = random.choices(self.get_choices(self.hidden), weights=weights) + return [random.choices(self.get_choices(counts[i]), weights=weights) for i, c in enumerate(counts)] @staticmethod def get_choices(number): @@ -1728,24 +1763,24 @@ class DoorTypePool: class BuilderDoorCandidates: def __init__(self): - self.small = set() - self.big = set() - self.trap = set() - self.bombable = set() - self.dashable = set() - - self.checked = set() + self.small = [] + self.big = [] + self.trap = [] + self.bombable = [] + self.dashable = [] def shuffle_door_types(door_type_pools, paths, world, player): start_regions_map = {} - for name, builder in world.dungeon_layouts[player]: + for name, builder in world.dungeon_layouts[player].items(): start_regions = convert_regions(builder.path_entrances, world, player) start_regions_map[name] = start_regions + builder.candidates = BuilderDoorCandidates() used_doors = shuffle_door_traps(door_type_pools, paths, start_regions_map, world, player) # big keys + used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, player) # small keys - + used_doors = shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, world, player) # bombable / dashable # tricky / hidden @@ -1780,13 +1815,15 @@ def shuffle_door_traps(door_type_pools, paths, start_regions_map, world, player) for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] valid_traps, trap_number = find_valid_trap_combination(builder, suggestion_map[dungeon], - start_regions_map[dungeon], paths, world, player) + start_regions_map[dungeon], paths, world, player, + drop=True) trap_map[dungeon] = valid_traps if trap_number < suggestion_map[dungeon]: flex_map[dungeon] = 0 remaining += suggestion_map[dungeon] - trap_number - suggestion_map[dungeon] = trap_number + suggestion_map[dungeon] = trap_number builder_order = [x for x in pool if flex_map[x] > 0] + random.shuffle(builder_order) queue = deque(builder_order) while len(queue) > 0 and remaining > 0: dungeon = queue.popleft() @@ -1820,15 +1857,15 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] - find_big_key_candidates(builder, used_doors, world, player) + find_big_key_candidates(builder, start_regions_map[dungeon], used_doors, world, player) if custom_bk_doors[dungeon]: - builder.candidates.trap = filter_key_door_pool(builder.candidates.big, custom_bk_doors[dungeon]) + builder.candidates.big = filter_key_door_pool(builder.candidates.big, custom_bk_doors[dungeon]) remaining -= len(custom_bk_doors[dungeon]) ttl += len(builder.candidates.big) for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.big) - calc = int(round(proportion * door_type_pool.big/ttl)) + calc = int(round(proportion * door_type_pool.bigs/ttl)) suggested = min(proportion, calc) remaining -= suggested suggestion_map[dungeon] = suggested @@ -1836,20 +1873,21 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] valid_doors, bk_number = find_valid_bk_combination(builder, suggestion_map[dungeon], - start_regions_map[dungeon], world, player) + start_regions_map[dungeon], world, player, True) bk_map[dungeon] = valid_doors if bk_number < suggestion_map[dungeon]: flex_map[dungeon] = 0 remaining += suggestion_map[dungeon] - bk_number - suggestion_map[dungeon] = bk_number + suggestion_map[dungeon] = bk_number builder_order = [x for x in pool if flex_map[x] > 0] + random.shuffle(builder_order) queue = deque(builder_order) while len(queue) > 0 and remaining > 0: dungeon = queue.popleft() builder = world.dungeon_layouts[player][dungeon] increased = suggestion_map[dungeon] + 1 valid_doors, bk_number = find_valid_bk_combination(builder, increased, start_regions_map[dungeon], - paths, world, player) + world, player) if valid_doors: bk_map[dungeon] = valid_doors remaining -= 1 @@ -1859,6 +1897,93 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, queue.append(dungeon) # time to re-assign reassign_big_key_doors(bk_map, world, player) + for name, big_list in bk_map.items(): + used_doors.update(flatten_pair_list(big_list)) + return used_doors + + +def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, world, player): + for pool, door_type_pool in door_type_pools: + ttl = 0 + suggestion_map, small_map, flex_map = {}, {}, {} + remaining = door_type_pool.smalls + total_keys = remaining + if player in world.custom_door_types: + custom_key_doors = world.custom_door_types[player]['Key Door'] + else: + custom_key_doors = defaultdict(list) + + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + find_small_key_door_candidates(builder, start_regions_map[dungeon], used_doors, world, player) + if custom_key_doors[dungeon]: + builder.candidates.small = filter_key_door_pool(builder.candidates.small, custom_key_doors[dungeon]) + remaining -= len(custom_key_doors[dungeon]) + builder.key_doors_num = max(0, len(builder.candidates.small) - builder.key_drop_cnt) + total_keys -= builder.key_drop_cnt + ttl += builder.key_doors_num + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + calculated = int(round(builder.key_doors_num*total_keys/ttl)) + max_keys = max(0, builder.location_cnt - calc_used_dungeon_items(builder, world, player)) + cand_len = max(0, len(builder.candidates.small) - builder.key_drop_cnt) + limit = min(max_keys, cand_len) + suggested = min(calculated, limit) + combo_size = ncr(len(builder.candidates.small), suggested + builder.key_drop_cnt) + while combo_size > 500000 and suggested > 0: + suggested -= 1 + combo_size = ncr(len(builder.candidates.small), suggested + builder.key_drop_cnt) + suggestion_map[dungeon] = builder.key_doors_num = suggested + builder.key_drop_cnt + builder.combo_size = combo_size + flex_map[dungeon] = (limit - suggested) if suggested < limit else 0 + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + valid_doors, small_number = find_valid_combination(builder, suggestion_map[dungeon], + start_regions_map[dungeon], world, player) + small_map[dungeon] = valid_doors + actual_chest_keys = small_number - builder.key_drop_cnt + if actual_chest_keys < suggestion_map[dungeon]: + flex_map[dungeon] = 0 + remaining += suggestion_map[dungeon] - actual_chest_keys + suggestion_map[dungeon] = small_number + builder_order = [world.dungeon_layouts[player][x] for x in pool if flex_map[x] > 0] + builder_order.sort(key=lambda b: b.combo_size) + queue = deque(builder_order) + while len(queue) > 0 and remaining > 0: + builder = queue.popleft() + dungeon = builder.name + increased = suggestion_map[dungeon] + 1 + builder.key_doors_num = increased + valid_doors, small_number = find_valid_combination(builder, increased, start_regions_map[dungeon], + world, player) + if valid_doors: + small_map[dungeon] = valid_doors + remaining -= 1 + suggestion_map[dungeon] = increased + flex_map[dungeon] -= 1 + if flex_map[dungeon] > 0: + builder.combo_size = ncr(len(builder.candidates.small), builder.key_doors_num) + queue.append(builder) + queue = deque(sorted(queue, key=lambda b: b.combo_size)) + else: + builder.key_doors_num -= 1 + # time to re-assign + reassign_key_doors(small_map, world, player) + for dungeon_name in pool: + if not world.retro[player]: + builder = world.dungeon_layouts[player][dungeon_name] + log_key_logic(builder.name, world.key_logic[player][builder.name]) + if world.doorShuffle[player] != 'basic': + actual_chest_keys = max(builder.key_doors_num - builder.key_drop_cnt, 0) + dungeon = world.get_dungeon(dungeon_name, player) + if actual_chest_keys == 0: + dungeon.small_keys = [] + else: + dungeon.small_keys = [ItemFactory(dungeon_keys[dungeon_name], player)] * actual_chest_keys + + for name, small_list in small_map.items(): + used_doors.update(flatten_pair_list(small_list)) + return used_doors def shuffle_key_doors(builder, world, player): @@ -1900,9 +2025,9 @@ def find_current_key_doors(builder): def find_trappable_candidates(builder, world, player): - if world.door_type_mode[player] != 'original': # all, chaos + if world.door_type_mode[player] not in ['original', 'big']: # all, chaos r_set = builder.master_sector.region_set() - filtered_doors = [ext.door for r in r_set for ext in r.exits + filtered_doors = [ext.door for r in r_set for ext in world.get_region(r, player).exits if ext.door and ext.door.type in [DoorType.Interior, DoorType.Normal]] for d in filtered_doors: # I only support the first 3 due to the trapFlag right now @@ -1913,14 +2038,14 @@ def find_trappable_candidates(builder, world, player): if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, DoorKind.BigKey] or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name) - or (kind == DoorKind.TrapTriggerable and d.direction in [Direction.North, Direction.East]) - or (kind == DoorKind.Trap2 and d.direction in [Direction.South, Direction.West])): - builder.candidates.trap.add(d) + or (kind == DoorKind.TrapTriggerable and d.direction in [Direction.South, Direction.East]) + or (kind == DoorKind.Trap2 and d.direction in [Direction.North, Direction.West])): + builder.candidates.trap.append(d) elif d.type == DoorType.Normal: if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, DoorKind.BigKey] or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name)): - builder.candidates.trap.add(d) + builder.candidates.trap.append(d) else: r_set = builder.master_sector.region_set() for r in r_set: @@ -1928,7 +2053,7 @@ def find_trappable_candidates(builder, world, player): if ext.door: d = ext.door if d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name: - builder.candidates.trap.add(d) + builder.candidates.trap.append(d) def find_valid_trap_combination(builder, suggested, start_regions, paths, world, player, drop=True): @@ -1965,6 +2090,7 @@ def find_valid_trap_combination(builder, suggested, start_regions, paths, world, itr = 0 proposal = kth_combination(sample_list[itr], trap_door_pool, trap_doors_needed) proposal.extend(custom_trap_doors) + builder.trap_door_proposal = proposal return proposal, trap_doors_needed @@ -1982,21 +2108,40 @@ def filter_start_regions(builder, start_regions, world, player): def validate_trap_layout(proposal, builder, start_regions, paths, world, player): - return check_required_paths_with_traps(paths, proposal, builder.name, start_regions, world, player) + flag, state = check_required_paths_with_traps(paths, proposal, builder.name, start_regions, world, player) + if not flag: + return False + bk_special_loc = find_bk_special_location(builder, world, player) + if bk_special_loc: + if not state.found_forced_bk(): + return False + if world.accessibility[player] != 'beatable': + all_locations = [l for r in builder.master_sector.region_set() for l in world.get_region(r, player).locations] + if any(l not in state.found_locations for l in all_locations): + return False + return True +def find_bk_special_location(builder, world, player): + for r_name in builder.master_sector.region_set(): + region = world.get_region(r_name, player) + for loc in region.locations: + if loc.forced_big_key(): + return loc + return None + def check_required_paths_with_traps(paths, proposal, dungeon_name, start_regions, world, player): + cached_initial_state = None if len(paths[dungeon_name]) > 0: - states_to_explore = {} common_starts = tuple(start_regions) + states_to_explore = {common_starts: ([], 'all')} for path in paths[dungeon_name]: if type(path) is tuple: states_to_explore[tuple([path[0]])] = (path[1], 'any') else: - if common_starts not in states_to_explore: - states_to_explore[common_starts] = ([], 'all') + # if common_starts not in states_to_explore: + # states_to_explore[common_starts] = ([], 'all') states_to_explore[common_starts][0].append(path) - cached_initial_state = None for start_regs, info in states_to_explore.items(): dest_regs, path_type = info if type(dest_regs) is not list: @@ -2005,12 +2150,14 @@ def check_required_paths_with_traps(paths, proposal, dungeon_name, start_regions start_regions = convert_regions(start_regs, world, player) initial = start_regs == common_starts if not initial or cached_initial_state is None: + if cached_initial_state and any(not cached_initial_state.visited_at_all(r) for r in start_regions): + return False, None # can't start processing the initial state because start regs aren't reachable init = determine_init_crystal(initial, cached_initial_state, start_regions) state = ExplorationState2(init, dungeon_name) for region in start_regions: state.visit_region(region) state.add_all_doors_check_proposed_traps(region, proposal, world, player) - explore_state_proposed_traps(state, world, player) + explore_state_proposed_traps(state, proposal, world, player) if initial and cached_initial_state is None: cached_initial_state = state else: @@ -2020,8 +2167,8 @@ def check_required_paths_with_traps(paths, proposal, dungeon_name, start_regions else: valid, bad_region = check_if_all_regions_visited(state, check_paths) if not valid: - return False - return True + return False, None + return True, cached_initial_state def reassign_trap_doors(trap_map, world, player): @@ -2041,13 +2188,14 @@ def reassign_trap_doors(trap_map, world, player): elif kind in [DoorKind.Trap2, DoorKind.TrapTriggerable]: room.change(d.doorListPos, DoorKind.Normal) d.blocked = False + connect_one_way(world, d.name, d.dest.name, player) elif d.type is DoorType.Normal and d not in traps: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.blocked = False for d in traps: change_door_to_trap(d, world, player) world.spoiler.set_door_type(d.name, 'Trap Door', player) - logger.debug('Key Door: %s', d.name) + logger.debug('Trap Door: %s', d.name) def find_current_trap_doors(builder): @@ -2078,34 +2226,37 @@ def change_door_to_trap(d, world, player): verify_door_list_pos(d, room, world, player, pos=3) d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos] room.change(d.doorListPos, new_kind) + if d.entrance.connected_region is not None: + d.entrance.connected_region.entrances.remove(d.entrance) + d.entrance.connected_region = None elif d.type is DoorType.Normal: d.blocked = True verify_door_list_pos(d, room, world, player, pos=3) d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos] room.change(d.doorListPos, DoorKind.Trap) + if d.entrance.connected_region is not None: + d.entrance.connected_region.entrances.remove(d.entrance) + d.entrance.connected_region = None -def find_big_key_candidates(builder, used, world, player): - if world.door_type_mode[player] != 'original': # all, chaos - r_set = builder.master_sector.region_set() - filtered_doors = [ext.door for r in r_set for ext in r.exits - if ext.door and ext.door.type in [DoorType.Interior, DoorType.Normal]] - for d in filtered_doors: - if 0 <= d.doorListPos < 4 and not d.entranceFlag: - room = world.get_room(d.roomIndex, player) - kind = room.kind(d) - if d.type in [DoorType.Interior, DoorType.Normal]: - if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, - DoorKind.BigKey] and d not in used) - or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name) - or (kind == DoorKind.TrapTriggerable and d.direction in [Direction.North, Direction.East]) - or (kind == DoorKind.Trap2 and d.direction in [Direction.South, Direction.West])): - builder.candidates.big.add(d) - elif d.type == DoorType.Normal: - if (kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, - DoorKind.BigKey] - or (d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name)): - builder.candidates.trap.add(d) +def find_big_key_candidates(builder, start_regions, used, world, player): + if world.door_type_mode[player] != 'original': # big, all, chaos + # traverse dungeon and find candidates + candidates = [] + checked_doors = set() + for region in start_regions: + possible, checked = find_big_key_door_candidates(region, checked_doors, used, world, player) + candidates.extend([x for x in possible if x not in candidates]) + checked_doors.update(checked) + flat_candidates = [] + for candidate in candidates: + # not valid if: Normal Coupled and Pair in is Checked and Pair is not in Candidates + if (world.decoupledoors[player] or candidate.type != DoorType.Normal + or candidate.dest not in checked_doors or candidate.dest in candidates): + flat_candidates.append(candidate) + + paired_candidates = build_pair_list(flat_candidates) + builder.candidates.big = paired_candidates else: r_set = builder.master_sector.region_set() for r in r_set: @@ -2113,15 +2264,177 @@ def find_big_key_candidates(builder, used, world, player): if ext.door: d = ext.door if d.bigKey and d.type in [DoorType.Normal, DoorType.Interior]: - builder.candidates.big.add(d) + builder.candidates.big.append(d) -def find_small_key_door_candidates(builder, start_regions, world, player): +def find_big_key_door_candidates(region, checked, used, world, player): + decoupled = world.decoupledoors[player] + dungeon_name = region.dungeon.name + candidates = [] + checked_doors = list(checked) + queue = deque([(region, None, None)]) + while len(queue) > 0: + current, last_door, last_region = queue.pop() + for ext in current.exits: + d = ext.door + controlled = d + if d and d.controller: + d = d.controller + if (d and not d.blocked and d.dest is not last_door and d.dest is not last_region + and d not in checked_doors and d not in used): + valid = False + if (0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal] + and not d.entranceFlag and d.direction in [Direction.North, Direction.South]): + room = world.get_room(d.roomIndex, player) + position, kind = room.doorList[d.doorListPos] + if d.type == DoorType.Interior: + valid = kind in okay_interiors + if valid and d.dest not in candidates: # interior doors are not separable yet + candidates.append(d.dest) + elif d.type == DoorType.Normal: + if decoupled: + valid = kind in okay_normals + else: + d2 = d.dest + if d2 not in candidates and d2 not in used: + if d2.type == DoorType.Normal: + room_b = world.get_room(d2.roomIndex, player) + pos_b, kind_b = room_b.doorList[d2.doorListPos] + valid = kind in okay_normals and kind_b in okay_normals and valid_key_door_pair(d, d2) + else: + valid = kind in okay_normals + if valid and 0 <= d2.doorListPos < 4: + candidates.append(d2) + else: + valid = True + if valid and d not in candidates: + candidates.append(d) + connected = ext.connected_region + if valid_region_to_explore(connected, dungeon_name, world, player): + queue.append((ext.connected_region, controlled, current)) + if d is not None: + checked_doors.append(d) + return candidates, checked_doors + + +def find_valid_bk_combination(builder, suggested, start_regions, world, player, drop=True): + bk_door_pool = builder.candidates.big + bk_doors_needed = suggested + if player in world.custom_door_types: + custom_bk_doors = world.custom_door_types[player]['Big Key Door'][builder.name] + else: + custom_bk_doors = [] + if custom_bk_doors: + bk_door_pool = filter_key_door_pool(bk_door_pool, custom_bk_doors) + bk_doors_needed -= len(custom_bk_doors) + if len(bk_door_pool) < bk_doors_needed: + if not drop: + return None, 0 + bk_doors_needed = len(bk_door_pool) + combinations = ncr(len(bk_door_pool), bk_doors_needed) + itr = 0 + sample_list = build_sample_list(combinations, 10000) + proposal = kth_combination(sample_list[itr], bk_door_pool, bk_doors_needed) + proposal.extend(custom_bk_doors) + + start_regions = filter_start_regions(builder, start_regions, world, player) + while not validate_bk_layout(proposal, builder, start_regions, world, player): + itr += 1 + if itr >= len(sample_list): + if not drop: + return None, 0 + bk_doors_needed -= 1 + if bk_doors_needed < 0: + raise Exception(f'Bad dungeon {builder.name} - maybe custom bk doors are bad') + combinations = ncr(len(bk_door_pool), bk_doors_needed) + sample_list = build_sample_list(combinations, 10000) + itr = 0 + proposal = kth_combination(sample_list[itr], bk_door_pool, bk_doors_needed) + proposal.extend(custom_bk_doors) + builder.bk_door_proposal = proposal + return proposal, bk_doors_needed + + +def find_current_bk_doors(builder): + current_doors = [] + for region in builder.master_sector.regions: + for ext in region.exits: + d = ext.door + if d and d.type != DoorType.Logical and d.bigKey: + current_doors.append(d) + return current_doors + + +def reassign_big_key_doors(bk_map, world, player): + for name, big_doors in bk_map.items(): + flat_proposal = flatten_pair_list(big_doors) + builder = world.dungeon_layouts[player][name] + queue = deque(find_current_bk_doors(builder)) + while len(queue) > 0: + d = queue.pop() + if d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal: + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + d.bigKey = False + elif d.type is DoorType.Normal and d not in flat_proposal: + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + d.bigKey = False + for obj in big_doors: + if type(obj) is tuple: + d1 = obj[0] + d2 = obj[1] + if d1.type is DoorType.Interior: + change_door_to_big_key(d1, world, player) + d2.bigKey = True # ensure flag is set + else: + names = [d1.name, d2.name] + found = False + for dp in world.paired_doors[player]: + if dp.door_a in names and dp.door_b in names: + dp.pair = True + found = True + elif dp.door_a in names: + dp.pair = False + elif dp.door_b in names: + dp.pair = False + if not found: + world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) + change_door_to_big_key(d1, world, player) + change_door_to_big_key(d2, world, player) + world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Big Key Door', player) + else: + d = obj + if d.type is DoorType.Interior: + change_door_to_big_key(d, world, player) + d.dest.bigKey = True # ensure flag is set + elif d.type is DoorType.SpiralStairs: + pass # we don't have spiral stairs candidates yet that aren't already key doors + elif d.type is DoorType.Normal: + change_door_to_big_key(d, world, player) + if not world.decoupledoors[player] and d.dest: + if d.dest.type in [DoorType.Normal]: + dest_room = world.get_room(d.dest.roomIndex, player) + if stateful_door(d.dest, dest_room.kind(d.dest)): + change_door_to_big_key(d.dest, world, player) + add_pair(d, d.dest, world, player) + world.spoiler.set_door_type(d.name, 'Big Key Door', player) + + +def change_door_to_big_key(d, world, player): + d.bigKey = True + room = world.get_room(d.roomIndex, player) + if room.doorList[d.doorListPos][1] != DoorKind.BigKey: + verify_door_list_pos(d, room, world, player) + room.change(d.doorListPos, DoorKind.BigKey) + + +def find_small_key_door_candidates(builder, start_regions, used, world, player): # traverse dungeon and find candidates candidates = [] checked_doors = set() for region in start_regions: - possible, checked = find_key_door_candidates(region, checked_doors, world, player) + possible, checked = find_key_door_candidates(region, checked_doors, used, world, player) candidates.extend([x for x in possible if x not in candidates]) checked_doors.update(checked) flat_candidates = [] @@ -2132,25 +2445,26 @@ def find_small_key_door_candidates(builder, start_regions, world, player): flat_candidates.append(candidate) paired_candidates = build_pair_list(flat_candidates) - builder.candidates = paired_candidates + builder.candidates.small = paired_candidates def calc_used_dungeon_items(builder, world, player): base = 2 + basic_flag = world.doorShuffle[player] == 'basic' if not world.bigkeyshuffle[player]: if builder.bk_required and not builder.bk_provided: base += 1 - if not world.compassshuffle[player]: + if not world.compassshuffle[player] and (builder.name not in ['Hyrule Castle', 'Agahnims Tower'] or not basic_flag): base += 1 - if not world.mapshuffle[player]: + if not world.mapshuffle[player] and (builder.name != 'Agahnims Tower' or not basic_flag): base += 1 return base -def find_valid_combination(builder, start_regions, world, player, drop_keys=True): +def find_valid_combination(builder, target, start_regions, world, player, drop_keys=True): logger = logging.getLogger('') - key_door_pool = list(builder.candidates) # can these be a set? - key_doors_needed = builder.key_doors_num + key_door_pool = list(builder.candidates.small) + key_doors_needed = target if player in world.custom_door_types: custom_key_doors = world.custom_door_types[player]['Key Door'][builder.name] else: @@ -2163,8 +2477,9 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True if len(key_door_pool) < key_doors_needed: if not drop_keys: logger.info('No valid layouts for %s with %s doors', builder.name, builder.key_doors_num) - return False + return None, 0 builder.key_doors_num -= key_doors_needed - len(key_door_pool) # reduce number of key doors + key_doors_needed = len(key_door_pool) logger.info('%s: %s', world.fish.translate("cli", "cli", "lowering.keys.candidates"), builder.name) combinations = ncr(len(key_door_pool), key_doors_needed) itr = 0 @@ -2181,12 +2496,12 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True if itr >= len(sample_list): if not drop_keys: logger.info('No valid layouts for %s with %s doors', builder.name, builder.key_doors_num) - return False + return None, 0 logger.info('%s: %s', world.fish.translate("cli","cli","lowering.keys.layouts"), builder.name) builder.key_doors_num -= 1 key_doors_needed -= 1 - if builder.key_doors_num < 0: - raise Exception('Bad dungeon %s - less than 0 key doors not valid' % builder.name) + if key_doors_needed < 0: + raise Exception(f'Bad dungeon {builder.name} - less than 0 key doors or invalid custom key door') combinations = ncr(len(key_door_pool), max(0, key_doors_needed)) sample_list = build_sample_list(combinations) itr = 0 @@ -2200,14 +2515,15 @@ def find_valid_combination(builder, start_regions, world, player, drop_keys=True # make changes if player not in world.key_logic.keys(): world.key_logic[player] = {} + builder.total_keys = builder.key_doors_num analyze_dungeon(key_layout, world, player) builder.key_door_proposal = proposal world.key_logic[player][builder.name] = key_layout.key_logic world.key_layout[player][builder.name] = key_layout - return True + return builder.key_door_proposal, key_doors_needed -def build_sample_list(combinations, max_combinations=1000000): +def build_sample_list(combinations, max_combinations=100000): if combinations <= max_combinations: sample_list = list(range(0, int(combinations))) else: @@ -2273,10 +2589,13 @@ def flatten_pair_list(paired_list): return flat_list -okay_normals = [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, DoorKind.DungeonChanger] +okay_normals = [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, + DoorKind.DungeonChanger, DoorKind.BigKey] + +okay_interiors = [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, DoorKind.BigKey] -def find_key_door_candidates(region, checked, world, player): +def find_key_door_candidates(region, checked, used, world, player): decoupled = world.decoupledoors[player] dungeon_name = region.dungeon.name candidates = [] @@ -2289,14 +2608,15 @@ def find_key_door_candidates(region, checked, world, player): controlled = d if d and d.controller: d = d.controller - if d and not d.blocked and d.dest is not last_door and d.dest is not last_region and d not in checked_doors: + if (d and not d.blocked and d.dest is not last_door and d.dest is not last_region + and d not in checked_doors and d not in used): valid = False if (0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal, DoorType.SpiralStairs] and not d.entranceFlag): room = world.get_room(d.roomIndex, player) position, kind = room.doorList[d.doorListPos] if d.type == DoorType.Interior: - valid = kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable] + valid = kind in okay_interiors if valid and d.dest not in candidates: # interior doors are not separable yet candidates.append(d.dest) elif d.type == DoorType.SpiralStairs: @@ -2306,7 +2626,7 @@ def find_key_door_candidates(region, checked, world, player): valid = kind in okay_normals else: d2 = d.dest - if d2 not in candidates: + if d2 not in candidates and d2 not in used: if d2.type == DoorType.Normal: room_b = world.get_room(d2.roomIndex, player) pos_b, kind_b = room_b.doorList[d2.doorListPos] @@ -2320,7 +2640,7 @@ def find_key_door_candidates(region, checked, world, player): if valid and d not in candidates: candidates.append(d) connected = ext.connected_region - if valid_region_to_explore_lim(connected, dungeon_name, world, player): + if valid_region_to_explore(connected, dungeon_name, world, player): queue.append((ext.connected_region, controlled, current)) if d is not None: checked_doors.append(d) @@ -2333,72 +2653,80 @@ def valid_key_door_pair(door1, door2): return len(door1.entrance.parent_region.exits) <= 1 or len(door2.entrance.parent_region.exits) <= 1 -def reassign_key_doors(builder, world, player): +def reassign_key_doors(small_map, world, player): logger = logging.getLogger('') - logger.debug('Key doors for %s', builder.name) - proposal = builder.key_door_proposal - flat_proposal = flatten_pair_list(proposal) - queue = deque(find_current_key_doors(builder)) - while len(queue) > 0: - d = queue.pop() - if d.type is DoorType.SpiralStairs and d not in proposal: - room = world.get_room(d.roomIndex, player) - if room.doorList[d.doorListPos][1] == DoorKind.StairKeyLow: - room.delete(d.doorListPos) - else: - if len(room.doorList) > 1: - room.mirror(d.doorListPos) # I think this works for crossed now - else: + for name, small_doors in small_map.items(): + logger.debug(f'Key doors for {name}') + builder = world.dungeon_layouts[player][name] + proposal = builder.key_door_proposal + flat_proposal = flatten_pair_list(proposal) + queue = deque(find_current_key_doors(builder)) + while len(queue) > 0: + d = queue.pop() + if d.type is DoorType.SpiralStairs and d not in proposal: + room = world.get_room(d.roomIndex, player) + if room.doorList[d.doorListPos][1] == DoorKind.StairKeyLow: room.delete(d.doorListPos) - d.smallKey = False - elif d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal: - if not d.entranceFlag: - world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) - d.smallKey = False - d.dest.smallKey = False - queue.remove(d.dest) - elif d.type is DoorType.Normal and d not in flat_proposal: - if not d.entranceFlag: - world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) - d.smallKey = False - for dp in world.paired_doors[player]: - if dp.door_a == d.name or dp.door_b == d.name: - dp.pair = False - for obj in proposal: - if type(obj) is tuple: - d1 = obj[0] - d2 = obj[1] - if d1.type is DoorType.Interior: - change_door_to_small_key(d1, world, player) - d2.smallKey = True # ensure flag is set - else: - names = [d1.name, d2.name] - found = False + else: + if len(room.doorList) > 1: + room.mirror(d.doorListPos) # I think this works for crossed now + else: + room.delete(d.doorListPos) + d.smallKey = False + elif d.type is DoorType.Interior and d not in flat_proposal and d.dest not in flat_proposal: + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + d.smallKey = False + d.dest.smallKey = False + queue.remove(d.dest) + elif d.type is DoorType.Normal and d not in flat_proposal: + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + d.smallKey = False for dp in world.paired_doors[player]: - if dp.door_a in names and dp.door_b in names: - dp.pair = True - found = True - elif dp.door_a in names: + if dp.door_a == d.name or dp.door_b == d.name: dp.pair = False - elif dp.door_b in names: - dp.pair = False - if not found: - world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) - change_door_to_small_key(d1, world, player) - change_door_to_small_key(d2, world, player) - world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Key Door', player) - logger.debug('Key Door: %s', d1.name+' <-> '+d2.name) - else: - d = obj - if d.type is DoorType.Interior: - change_door_to_small_key(d, world, player) - d.dest.smallKey = True # ensure flag is set - elif d.type is DoorType.SpiralStairs: - pass # we don't have spiral stairs candidates yet that aren't already key doors - elif d.type is DoorType.Normal: - change_door_to_small_key(d, world, player) - world.spoiler.set_door_type(d.name, 'Key Door', player) - logger.debug('Key Door: %s', d.name) + for obj in proposal: + if type(obj) is tuple: + d1 = obj[0] + d2 = obj[1] + if d1.type is DoorType.Interior: + change_door_to_small_key(d1, world, player) + d2.smallKey = True # ensure flag is set + else: + names = [d1.name, d2.name] + found = False + for dp in world.paired_doors[player]: + if dp.door_a in names and dp.door_b in names: + dp.pair = True + found = True + elif dp.door_a in names: + dp.pair = False + elif dp.door_b in names: + dp.pair = False + if not found: + world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) + change_door_to_small_key(d1, world, player) + change_door_to_small_key(d2, world, player) + world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Key Door', player) + logger.debug('Key Door: %s', d1.name+' <-> '+d2.name) + else: + d = obj + if d.type is DoorType.Interior: + change_door_to_small_key(d, world, player) + d.dest.smallKey = True # ensure flag is set + elif d.type is DoorType.SpiralStairs: + pass # we don't have spiral stairs candidates yet that aren't already key doors + elif d.type is DoorType.Normal: + change_door_to_small_key(d, world, player) + if not world.decoupledoors[player] and d.dest: + if d.dest.type in [DoorType.Normal]: + dest_room = world.get_room(d.dest.roomIndex, player) + if stateful_door(d.dest, dest_room.kind(d.dest)): + change_door_to_small_key(d.dest, world, player) + add_pair(d, d.dest, world, player) + world.spoiler.set_door_type(d.name, 'Key Door', player) + logger.debug('Key Door: %s', d.name) def change_door_to_small_key(d, world, player): @@ -2499,7 +2827,7 @@ def remove_pair(door, world, player): def stateful_door(door, kind): if 0 <= door.doorListPos < 4: - return kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable] #, DoorKind.BigKey] + return kind in [DoorKind.Normal, DoorKind.SmallKey, DoorKind.Bombable, DoorKind.Dashable, DoorKind.BigKey] return False @@ -2780,7 +3108,8 @@ def explore_state(state, world, player): while len(state.avail_doors) > 0: door = state.next_avail_door().door connect_region = world.get_entrance(door.name, player).connected_region - if state.can_traverse(door) and not state.visited(connect_region) and valid_region_to_explore(connect_region, world, player): + if (state.can_traverse(door) and not state.visited(connect_region) + and valid_region_to_explore(connect_region, state.dungeon, world, player)): state.visit_region(connect_region) state.add_all_doors_check_unattached(connect_region, world, player) @@ -2789,7 +3118,8 @@ def explore_state_proposed_traps(state, proposed_traps, world, player): while len(state.avail_doors) > 0: door = state.next_avail_door().door connect_region = world.get_entrance(door.name, player).connected_region - if not state.visited(connect_region) and valid_region_to_explore(connect_region, world, player): + if (not state.visited(connect_region) + and valid_region_to_explore(connect_region, state.dungeon, world, player)): state.visit_region(connect_region) state.add_all_doors_check_proposed_traps(connect_region, proposed_traps, world, player) @@ -2851,6 +3181,7 @@ class DROptions(Flag): # Open_Desert_Wall = 0x80 # No longer pre-opening desert wall - unused Hide_Total = 0x100 DarkWorld_Spawns = 0x200 + BigKeyDoor_Shuffle = 0x400 # DATA GOES DOWN HERE @@ -3913,4 +4244,21 @@ bomb_dash_counts = { 'Ganons Tower': (2, 1) } +# small, big, trap, bomb, dash, hidden, tricky +door_type_counts = { + 'Hyrule Castle': (4, 0, 1, 0, 2, 0, 0), + 'Eastern Palace': (2, 2, 0, 0, 0, 0, 0), + 'Desert Palace': (4, 1, 0, 0, 0, 0, 0), + 'Agahnims Tower': (4, 0, 1, 0, 0, 1, 0), + 'Swamp Palace': (6, 0, 0, 2, 0, 0, 0), + 'Palace of Darkness': (6, 1, 1, 3, 2, 0, 0), + 'Misery Mire': (6, 3, 5, 2, 0, 0, 0), + 'Skull Woods': (5, 0, 2, 2, 0, 1, 0), + 'Ice Palace': (6, 1, 3, 0, 0, 0, 0), + 'Tower of Hera': (1, 1, 0, 0, 0, 0, 0), + 'Thieves Town': (3, 1, 2, 1, 1, 0, 0), + 'Turtle Rock': (6, 2, 2, 0, 2, 0, 1), # 2 bombs kind of for entrances, but I put 0 here + 'Ganons Tower': (8, 2, 5, 2, 1, 0, 0) +} + diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 7e3b2ef7..f06c3535 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -808,6 +808,7 @@ class ExplorationState(object): self.prize_door_set = {} self.prize_doors = [] self.prize_doors_opened = False + self.prize_received = False def copy(self): ret = ExplorationState(dungeon=self.dungeon) @@ -839,6 +840,7 @@ class ExplorationState(object): ret.prize_door_set = dict(self.prize_door_set) ret.prize_doors = list(self.prize_doors) ret.prize_doors_opened = self.prize_doors_opened + ret.prize_received = self.prize_received return ret def next_avail_door(self): @@ -984,6 +986,20 @@ class ExplorationState(object): elif not self.in_door_list(door, self.avail_doors): self.append_door_to_list(door, self.avail_doors) + def add_all_doors_check_big_keys(self, region, big_key_door_proposal, world, player): + for door in get_doors(world, region, player): + if self.can_traverse(door): + if door.controller: + door = door.controller + if (door in big_key_door_proposal or door.name in special_big_key_doors) and not self.big_key_opened: + if not self.in_door_list(door, self.big_doors): + self.append_door_to_list(door, self.big_doors) + elif door.req_event is not None and door.req_event not in self.events: + if not self.in_door_list(door, self.event_doors): + self.append_door_to_list(door, self.event_doors) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors) + def visited(self, region): if self.crystal == CrystalBarrier.Either: return region in self.visited_blue and region in self.visited_orange @@ -1213,6 +1229,8 @@ class DungeonBuilder(object): self.combo_size = None self.flex = 0 self.key_door_proposal = None + self.bk_door_proposal = None + self.trap_door_proposal = None self.allowance = None if 'Stonewall' in name: @@ -1279,9 +1297,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge dungeon_map = {} for key in dungeon_pool: - dungeon_map[key] = DungeonBuilder(key) - for key in dungeon_boss_sectors.keys(): - current_dungeon = dungeon_map[key] + current_dungeon = dungeon_map[key] = DungeonBuilder(key) for r_name in dungeon_boss_sectors[key]: assign_sector(find_sector(r_name, candidate_sectors), current_dungeon, candidate_sectors, global_pole) if key == 'Hyrule Castle' and world.mode[player] == 'standard': @@ -1293,7 +1309,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge candidate_sectors, global_pole) entrances_map, potentials, connections = connections_tuple accessible_sectors, reverse_d_map = set(), {} - for key in dungeon_entrances.keys(): + for key in dungeon_pool: current_dungeon = dungeon_map[key] current_dungeon.all_entrances = dungeon_entrances[key] for r_name in current_dungeon.all_entrances: @@ -1419,6 +1435,8 @@ def identify_destination_sectors(accessible_sectors, reverse_d_map, dungeon_map, if ent_name in found_connections: continue sector = find_sector(ent_name, reverse_d_map.keys()) + if sector is None: + continue if sector in accessible_sectors: found_connections.add(ent_name) accessible_overworld.add(region) # todo: drops don't give ow access diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index bb4f6835..8a70abcf 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -248,7 +248,7 @@ def find_all_locations(sector): def calc_max_chests(builder, key_layout, world, player): - if world.doorShuffle[player] != 'crossed': + if world.doorShuffle[player] in ['basic', 'vanilla']: return len(world.get_dungeon(key_layout.sector.name, player).small_keys) return max(0, builder.key_doors_num - key_layout.max_drops) @@ -1169,6 +1169,16 @@ def expand_key_state(state, flat_proposal, world, player): state.add_all_doors_check_keys(connect_region, flat_proposal, world, player) +def expand_big_key_state(state, flat_proposal, world, player): + while len(state.avail_doors) > 0: + exp_door = state.next_avail_door() + door = exp_door.door + connect_region = world.get_entrance(door.name, player).connected_region + if state.validate(door, connect_region, world, player): + state.visit_region(connect_region, key_checks=True) + state.add_all_doors_check_big_keys(connect_region, flat_proposal, world, player) + + def flatten_pair_list(paired_list): flat_list = [] for d in paired_list: @@ -1398,6 +1408,42 @@ def prize_relevance(key_layout, dungeon_entrance): return None +def prize_relevance_sig2(start_regions, d_name, dungeon_entrance): + if len(start_regions) > 1 and dungeon_entrance and dungeon_table[d_name].prize: + if dungeon_entrance.name in ['Ganons Tower', 'Inverted Ganons Tower']: + return 'GT' + elif dungeon_entrance.name == 'Pyramid Fairy': + return 'BigBomb' + return None + + +def validate_bk_layout(proposal, builder, start_regions, world, player): + bk_special = check_bk_special(builder.master_sector.regions, world, player) + if world.bigkeyshuffle[player] and (world.dropshuffle[player] or not bk_special): + return True + flat_proposal = flatten_pair_list(proposal) + state = ExplorationState(dungeon=builder.name) + state.big_key_special = bk_special + for region in start_regions: + dungeon_entrance, portal_door = find_outside_connection(region) + prize_relevant_flag = prize_relevance_sig2(start_regions, builder.name, dungeon_entrance) + if prize_relevant_flag: + state.append_door_to_list(portal_door, state.prize_doors) + state.prize_door_set[portal_door] = dungeon_entrance + # key_layout.prize_relevant = prize_relevant_flag + else: + state.visit_region(region, key_checks=True) + state.add_all_doors_check_big_keys(region, flat_proposal, world, player) + expand_big_key_state(state, flat_proposal, world, player) + if bk_special: + for loc in state.found_locations: + if loc.forced_big_key(): + return True + else: + return len(state.bk_found) > 0 + return False + + # Soft lock stuff def validate_key_layout(key_layout, world, player): # retro is all good - except for hyrule castle in standard mode @@ -1601,7 +1647,7 @@ def create_key_counters(key_layout, world, player): state.key_locations = len(builder.key_door_proposal) - builder.key_drop_cnt else: builder = world.dungeon_layouts[player][key_layout.sector.name] - state.key_locations = builder.total_keys - builder.key_drop_cnt + state.key_locations = max(0, builder.total_keys - builder.key_drop_cnt) state.big_key_special = False for region in key_layout.sector.regions: for location in region.locations: diff --git a/Main.py b/Main.py index 80c79887..4e6b9c4b 100644 --- a/Main.py +++ b/Main.py @@ -106,6 +106,7 @@ def main(args, seed=None, fish=None): world.enemy_damage = args.enemy_damage.copy() world.beemizer = args.beemizer.copy() world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)} + world.door_type_mode = args.door_type_mode.copy() world.experimental = args.experimental.copy() world.dungeon_counters = args.dungeon_counters.copy() world.fish = fish diff --git a/Rom.py b/Rom.py index 4cb0354c..d6717617 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'add982e935888df04ddfa570bc07bede' +RANDOMIZERBASEHASH = 'afcd895b87559cd29b04aa3714cbc929' class JsonRom(object): @@ -738,11 +738,11 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # setup dr option flags based on experimental, etc. dr_flags = DROptions.Eternal_Mini_Bosses if world.doorShuffle[player] == 'vanilla' else DROptions.Town_Portal - if world.doorShuffle[player] == 'crossed': + if world.doorShuffle[player] not in ['vanilla', 'basic']: dr_flags |= DROptions.Map_Info if world.collection_rate[player] and world.goal[player] not in ['triforcehunt', 'trinity']: dr_flags |= DROptions.Debug - if world.doorShuffle[player] == 'crossed' and world.logic[player] != 'nologic'\ + if world.doorShuffle[player] not in ['vanilla', 'basic'] and world.logic[player] != 'nologic'\ and world.mixed_travel[player] == 'prevent': # PoD Falling Bridge or Hammjump # 1FA607: db $2D, $79, $69 ; 0x0069: Vertical Rail ↕ | { 0B, 1E } | Size: 05 @@ -763,6 +763,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): dr_flags |= DROptions.DarkWorld_Spawns if world.logic[player] != 'nologic': dr_flags |= DROptions.Fix_EG + if world.door_type_mode in ['big', 'chaos']: + dr_flags |= DROptions.BigKeyDoor_Shuffle my_locations = world.get_filled_locations(player) valid_locations = [l for l in my_locations if ((l.type == LocationType.Pot and not l.forced_item) @@ -772,7 +774,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): valid_loc_by_dungeon = valid_dungeon_locations(valid_locations) # fix hc big key problems (map and compass too) - if world.doorShuffle[player] == 'crossed' or world.dropshuffle[player] or world.pottery[player] not in ['none', 'cave']: + if (world.doorShuffle[player] not in ['vanilla', 'basic'] or world.dropshuffle[player] + or world.pottery[player] not in ['none', 'cave']): rom.write_byte(0x151f1, 2) rom.write_byte(0x15270, 2) sanctuary = world.get_region('Sanctuary', player) @@ -800,7 +803,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0x13fff4, [0xe4, 0x00]) # patch doors - if world.doorShuffle[player] == 'crossed': + if world.doorShuffle[player] not in ['vanilla', 'basic']: rom.write_byte(0x138002, 2) for name, layout in world.key_layout[player].items(): offset = compass_data[name][4]//2 @@ -1377,7 +1380,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): if len(portal_list) == 1: portal_idx = 0 else: - if world.doorShuffle[player] == 'crossed': + if world.doorShuffle[player] not in ['vanilla', 'basic']: # the random choice excludes sanctuary portal_idx = next((i for i, elem in enumerate(portal_list) if world.get_portal(elem, player).chosen), random.choice([1, 2, 3])) @@ -1392,7 +1395,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0x53E56+ow_map_index*2, int16_as_bytes(coords[1])) rom.write_byte(0x53EA6+ow_map_index, world_indicator) # in crossed doors - flip the compass exists flags - if world.doorShuffle[player] == 'crossed': + if world.doorShuffle[player] not in ['vanilla', 'basic']: for dungeon, portal_list in dungeon_portals.items(): ow_map_index = dungeon_table[dungeon].map_index exists_flag = any(x for x in world.get_dungeon(dungeon, player).dungeon_items if x.type == 'Compass') @@ -1495,7 +1498,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_bytes(0x180188, [0x20, 0, 0]) # Zelda respawn refills (magic, bombs, arrows) rom.write_bytes(0x18018B, [0x20, 0, 0]) # Mantle respawn refills (magic, bombs, arrows) magic_max, magic_small = 0x80, 0x20 - if world.doorShuffle[player] == 'crossed': + if world.doorShuffle[player] not in ['vanilla', 'basic']: # Uncle respawn refills (magic, bombs, arrows) rom.write_bytes(0x180185, [max(0x20, magic_max), max(3, bomb_max), max(10, bow_max)]) rom.write_bytes(0x180188, [0x20, 3, 10]) # Zelda respawn refills (magic, bombs, arrows) @@ -2081,13 +2084,13 @@ def write_strings(rom, world, player, team): # Next we write a few hints for specific inconvenient locations. We don't make many because in entrance this is highly unpredictable. locations_to_hint = InconvenientLocations.copy() - if world.doorShuffle[player] != 'crossed': + if world.doorShuffle[player] == 'vanilla': locations_to_hint.extend(InconvenientDungeonLocations) if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: locations_to_hint.extend(InconvenientVanillaLocations) random.shuffle(locations_to_hint) hint_count = 3 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 5 - hint_count -= 2 if world.doorShuffle[player] == 'crossed' else 0 + hint_count -= 2 if world.doorShuffle[player] not in ['vanilla', 'basic'] else 0 del locations_to_hint[hint_count:] for location in locations_to_hint: if location == 'Swamp Left': @@ -2150,7 +2153,7 @@ def write_strings(rom, world, player, team): items_to_hint.extend(BigKeys) random.shuffle(items_to_hint) hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 8 - hint_count += 2 if world.doorShuffle[player] == 'crossed' else 0 + hint_count += 2 if world.doorShuffle[player] not in ['vanilla', 'basic'] else 0 while hint_count > 0 and len(items_to_hint) > 0: this_item = items_to_hint.pop(0) this_location = world.find_items_not_key_only(this_item, player) @@ -2163,8 +2166,8 @@ def write_strings(rom, world, player, team): tt[hint_locations.pop(0)] = this_hint hint_count -= 1 - # Adding a hint for the Thieves' Town Attic location in Crossed door shuffle. - if world.doorShuffle[player] in ['crossed']: + # Adding a hint for the Thieves' Town Attic location in mixed door shuffles. + if world.doorShuffle[player] not in ['vanilla', 'basic']: attic_hint = world.get_location("Thieves' Town - Attic", player).parent_region.dungeon.name this_hint = 'A cracked floor can be found in ' + attic_hint + '.' if world.intensity[player] < 2 and hint_locations[0] == 'telepathic_tile_thieves_town_upstairs': @@ -2324,7 +2327,7 @@ def write_strings(rom, world, player, team): tt['tablet_bombos_book'] = bombos_text # attic hint - if world.doorShuffle[player] in ['crossed']: + if world.doorShuffle[player] not in ['vanilla', 'basic']: attic_hint = world.get_location("Thieves' Town - Attic", player).parent_region.dungeon.name tt['blind_not_that_way'] = f'{attic_hint} is too bright for my eyes' # see tagalog.asm tables at 957,967 or Follower_HandleTrigger in JPDASM diff --git a/RoomData.py b/RoomData.py index cfdd183f..03700e32 100644 --- a/RoomData.py +++ b/RoomData.py @@ -395,8 +395,8 @@ class DoorKind(Enum): Bombable = 0x2E BlastWall = 0x30 Hidden = 0x32 - TrapTriggerable = 0x36 # right side trap or south side trap (West, South) - Trap2 = 0x38 # left side trap or north side trap (East, North) + TrapTriggerable = 0x36 # right side trap or bottom side trap (West, North) + Trap2 = 0x38 # left side trap or top side trap (East, South) NormalLow2 = 0x40 TrapTriggerableLow = 0x44 Warp = 0x46 diff --git a/data/base2current.bps b/data/base2current.bps index 060733f6e6579357fc34f52d728345c5cfe9ea01..d657ad40ba6c5ce7ceabd188463dc93b16f6db49 100644 GIT binary patch delta 3819 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 {secondary_door.name}') + logger.debug(f' Linking {primary_door.name} <-> {secondary_door.name}') else: - logger.debug(f'Linking {primary_door.name} -> {secondary_door.name}') + logger.debug(f' Linking {primary_door.name} -> {secondary_door.name}') def decouple_check(primary_list, secondary_list, primary_door, secondary_door, world, player): @@ -203,11 +203,11 @@ def modify_proposal(proposed_map, explored_state, doors_to_connect, hash_code_se itr += 1 if not world.decoupledoors[player]: - logger.debug(f'Re-linking {attempt.name} <-> {new_door.name}') - logger.debug(f'Re-linking {old_attempt.name} <-> {old_target.name}') + logger.debug(f' Re-linking {attempt.name} <-> {new_door.name}') + logger.debug(f' Re-linking {old_attempt.name} <-> {old_target.name}') else: - logger.debug(f'Re-Linking {attempt.name} -> {new_door.name}') - logger.debug(f'Re-Linking {old_attempt.name} -> {old_target.name}') + logger.debug(f' Re-Linking {attempt.name} -> {new_door.name}') + logger.debug(f' Re-Linking {old_attempt.name} -> {old_target.name}') hash_code_set.add(hash_code) return proposed_map, hash_code @@ -349,12 +349,7 @@ def connect_doors(a, b): return # Connect supported types if a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]: - if a.blocked: - connect_one_way(b.entrance, a.entrance) - elif b.blocked: - connect_one_way(a.entrance, b.entrance) - else: - connect_two_way(a.entrance, b.entrance) + connect_two_way(a.entrance, b.entrance) dep_doors, target = [], None if len(a.dependents) > 0: dep_doors, target = a.dependents, b @@ -527,7 +522,7 @@ class ExplorationState(object): self.key_locations += 1 if location.name not in dungeon_events and '- Prize' not in location.name and location.name not in ['Agahnim 1', 'Agahnim 2']: self.ttl_locations += 1 - if location not in self.found_locations: # todo: special logic for TT Boss? + if location not in self.found_locations: self.found_locations.append(location) if not bk_flag: self.bk_found.add(location) @@ -616,7 +611,7 @@ class ExplorationState(object): elif not self.in_door_list(door, self.avail_doors): self.append_door_to_list(door, self.avail_doors, flag) - def add_all_doors_check_proposed_2(self, region, proposed_map, valid_doors, flag, world, player): + def add_all_doors_check_proposed_2(self, region, proposed_map, valid_doors, world, player): for door in get_doors(world, region, player): if door in proposed_map and door.name in valid_doors: self.visited_doors.add(door) @@ -625,16 +620,16 @@ class ExplorationState(object): door = door.controller if door.dest is None and door not in proposed_map.keys() and door.name in valid_doors: if not self.in_door_list_ic(door, self.unattached_doors): - self.append_door_to_list(door, self.unattached_doors, flag) + self.append_door_to_list(door, self.unattached_doors) else: other = self.find_door_in_list(door, self.unattached_doors) if self.crystal != other.crystal: other.crystal = CrystalBarrier.Either elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, self.event_doors): - self.append_door_to_list(door, self.event_doors, flag) + self.append_door_to_list(door, self.event_doors) elif not self.in_door_list(door, self.avail_doors): - self.append_door_to_list(door, self.avail_doors, flag) + self.append_door_to_list(door, self.avail_doors) def add_all_doors_check_proposed_traps(self, region, proposed_traps, world, player): for door in get_doors(world, region, player): diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index 8325719b..3816ef7c 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -77,6 +77,7 @@ def roll_settings(weights): door_shuffle = get_choice('door_shuffle') ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla' ret.intensity = get_choice('intensity') + ret.door_type_mode = get_choice('door_type_mode') ret.decoupledoors = get_choice('decoupledoors') == 'on' ret.experimental = get_choice('experimental') == 'on' ret.collection_rate = get_choice('collection_rate') == 'on' From 09fbdc46cadb018f2731a67d8345aa1ad2f55953 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 5 Aug 2022 14:01:19 -0600 Subject: [PATCH 028/146] Finish bomb/dash doors Lots of minor fixes Fixed a few existing bugs --- DoorShuffle.py | 417 +++++++++++++++++++++++------- DungeonGenerator.py | 12 +- Main.py | 1 + Rom.py | 5 +- RoomData.py | 6 +- data/base2current.bps | Bin 93211 -> 93229 bytes source/dungeon/DungeonStitcher.py | 3 +- 7 files changed, 338 insertions(+), 106 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 42d32c24..69baf30f 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -18,7 +18,7 @@ from source.dungeon.DungeonStitcher import ExplorationState as ExplorationState2 # from DungeonGenerator import generate_dungeon from DungeonGenerator import ExplorationState, convert_regions, pre_validate, determine_required_paths, drop_entrances from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, simple_dungeon_builder, default_dungeon_entrances -from DungeonGenerator import dungeon_portals, dungeon_drops, connect_doors +from DungeonGenerator import dungeon_portals, dungeon_drops, connect_doors, count_reserved_locations from DungeonGenerator import valid_region_to_explore from KeyDoorShuffle import analyze_dungeon, build_key_layout, validate_key_layout, determine_prize_lock from KeyDoorShuffle import validate_bk_layout, check_bk_special @@ -139,7 +139,7 @@ def link_doors_main(world, player): ['Ice Palace', 'Misery Mire', 'Turtle Rock', 'Ganons Tower']] pool = [(group, list(chain.from_iterable([dungeon_regions[d] for d in group]))) for group in groups] elif world.doorShuffle[player] == 'crossed': - pool = [list(dungeon_regions.keys()), sum(r for r in dungeon_regions.values())] + pool = [(list(dungeon_regions.keys()), sum((r for r in dungeon_regions.values()), []))] elif world.doorShuffle[player] != 'vanilla': logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player]) raise Exception('Invalid door shuffle setting: %s' % world.doorShuffle[player]) @@ -172,6 +172,9 @@ def mark_regions(world, player): def create_door_spoiler(world, player): logger = logging.getLogger('') + shuffled_door_types = [DoorType.Normal, DoorType.SpiralStairs] + if world.intensity[player] > 1: + shuffled_door_types += [DoorType.Open, DoorType.StraightStairs, DoorType.Ladder] queue = deque(world.dungeon_layouts[player].values()) while len(queue) > 0: @@ -185,20 +188,23 @@ def create_door_spoiler(world, player): for ext in next.exits: door_a = ext.door connect = ext.connected_region - if door_a and door_a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, - DoorType.StraightStairs, DoorType.Ladder] and door_a not in done: + if door_a and door_a.type in shuffled_door_types and door_a not in done: done.add(door_a) + door_b = door_a.dest if door_b and not isinstance(door_b, Region): - done.add(door_b) - if not door_a.blocked and not door_b.blocked: - world.spoiler.set_door(door_a.name, door_b.name, 'both', player, builder.name) - elif door_a.blocked: - world.spoiler.set_door(door_b.name, door_a.name, 'entrance', player, builder.name) - elif door_b.blocked: + if world.decoupledoors[player]: world.spoiler.set_door(door_a.name, door_b.name, 'entrance', player, builder.name) else: - logger.warning('This is a bug during door spoiler') + done.add(door_b) + if not door_a.blocked and not door_b.blocked: + world.spoiler.set_door(door_a.name, door_b.name, 'both', player, builder.name) + elif door_a.blocked: + world.spoiler.set_door(door_b.name, door_a.name, 'entrance', player, builder.name) + elif door_b.blocked: + world.spoiler.set_door(door_a.name, door_b.name, 'entrance', player, builder.name) + else: + logger.warning('This is a bug during door spoiler') elif not isinstance(door_b, Region): logger.warning('Door not connected: %s', door_a.name) if connect and connect.type == RegionType.Dungeon and connect not in visited: @@ -305,12 +311,7 @@ def connect_door_only(world, exit_name, region, player): def connect_interior_doors(a, b, world, player): door_a = world.get_door(a, player) door_b = world.get_door(b, player) - if door_a.blocked: - connect_one_way(world, b, a, player) - elif door_b.blocked: - connect_one_way(world, a, b, player) - else: - connect_two_way(world, a, b, player) + connect_two_way(world, a, b, player) def connect_two_way(world, entrancename, exitname, player): @@ -790,7 +791,7 @@ def main_dungeon_pool(dungeon_pool, world, player): door_type_pools = [] for pool, region_list in dungeon_pool: if len(pool) == 1: - dungeon_key = next(pool) + dungeon_key = next(iter(pool)) sector_pool = convert_to_sectors(region_list, world, player) merge_sectors(sector_pool, world, player) dungeon_builders[dungeon_key] = simple_dungeon_builder(dungeon_key, sector_pool) @@ -823,6 +824,17 @@ def main_dungeon_pool(dungeon_pool, world, player): check_required_paths(paths, world, player) + for pool, door_type_pool in door_type_pools: + for name in pool: + builder = world.dungeon_layouts[player][name] + region_set = builder.master_sector.region_set() + builder.bk_required = len(builder.bk_door_proposal) > 0 or any(x in region_set for x in special_bk_regions) + dungeon = world.get_dungeon(name, player) + if not builder.bk_required or builder.bk_provided: + dungeon.big_key = None + elif builder.bk_required and not builder.bk_provided: + dungeon.big_key = ItemFactory(dungeon_bigs[name], player) + all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items)) target_items = 34 if world.retro[player]: @@ -835,12 +847,12 @@ def main_dungeon_pool(dungeon_pool, world, player): target_items += 19 # 19 pot keys d_items = target_items - all_dungeon_items_cnt world.pool_adjustment[player] = d_items - # todo: remove unused pairs - if not world.decoupledoors[player]: - smooth_door_pairs(world, player) cross_dungeon_clean_up(world, player) +special_bk_regions = ['Hyrule Dungeon Cellblock', "Thieves Blind's Cell"] + + def cross_dungeon_clean_up(world, player): # Re-assign dungeon bosses gt = world.get_dungeon('Ganons Tower', player) @@ -956,47 +968,6 @@ def finish_up_work(world, player): refine_boss_exits(world, player) -# def unpair_all_doors(world, player): -# for paired_door in world.paired_doors[player]: -# paired_door.pair = False - -def within_dungeon(world, player): - add_inaccessible_doors(world, player) - entrances_map, potentials, connections = determine_entrance_list(world, player) - connections_tuple = (entrances_map, potentials, connections) - - dungeon_builders = {} - for key in dungeon_regions.keys(): - sector_list = convert_to_sectors(dungeon_regions[key], world, player) - dungeon_builders[key] = simple_dungeon_builder(key, sector_list) - dungeon_builders[key].entrance_list = list(entrances_map[key]) - recombinant_builders = {} - entrances, splits = create_dungeon_entrances(world, player) - builder_info = entrances, splits, connections_tuple, world, player - handle_split_dungeons(dungeon_builders, recombinant_builders, entrances_map, builder_info) - main_dungeon_generation(dungeon_builders, recombinant_builders, connections_tuple, world, player) - - paths = determine_required_paths(world, player) - check_required_paths(paths, world, player) - - setup_custom_door_types(world, player) - # shuffle_key_doors for dungeons - logging.getLogger('').info(world.fish.translate("cli", "cli", "shuffling.keydoors")) - start = time.process_time() - for builder in world.dungeon_layouts[player].values(): - shuffle_key_doors(builder, world, player) - logging.getLogger('').info('%s: %s', world.fish.translate("cli", "cli", "keydoor.shuffle.time"), time.process_time()-start) - if not world.decoupledoors[player]: - smooth_door_pairs(world, player) - - if world.intensity[player] >= 3: - portal = world.get_portal('Sanctuary', player) - target = portal.door.entrance.parent_region - connect_simple_door(world, 'Sanctuary Mirror Route', target, player) - - refine_boss_exits(world, player) - - def handle_split_dungeons(dungeon_builders, recombinant_builders, entrances_map, builder_info): dungeon_entrances, split_dungeon_entrances, c_tuple, world, player = builder_info if dungeon_entrances is None: @@ -1601,7 +1572,12 @@ def refine_boss_exits(world, player): if len(reachable_portals) == 0: reachable_portals = possible_portals unreachable = world.inaccessible_regions[player] - filtered = [x for x in reachable_portals if x.door.entrance.connected_region.name not in unreachable] + filtered = [] + for reachable in reachable_portals: + for entrance in reachable.door.entrance.connected_region.entrances: + parent = entrance.parent_region + if parent.type != RegionType.Dungeon and parent.name not in unreachable: + filtered.append(reachable) if 0 < len(filtered) < len(reachable_portals): reachable_portals = filtered chosen_one = random.choice(reachable_portals) if len(reachable_portals) > 1 else reachable_portals[0] @@ -1766,8 +1742,7 @@ class BuilderDoorCandidates: self.small = [] self.big = [] self.trap = [] - self.bombable = [] - self.dashable = [] + self.bomb_dash = [] def shuffle_door_types(door_type_pools, paths, world, player): @@ -1776,17 +1751,19 @@ def shuffle_door_types(door_type_pools, paths, world, player): start_regions = convert_regions(builder.path_entrances, world, player) start_regions_map[name] = start_regions builder.candidates = BuilderDoorCandidates() - used_doors = shuffle_door_traps(door_type_pools, paths, start_regions_map, world, player) + + world.paired_doors[player].clear() + used_doors = shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player) # big keys used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, player) # small keys used_doors = shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, world, player) # bombable / dashable - - # tricky / hidden + used_doors = shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, world, player) + # handle paired list -def shuffle_door_traps(door_type_pools, paths, start_regions_map, world, player): +def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player): used_doors = set() for pool, door_type_pool in door_type_pools: ttl = 0 @@ -1804,6 +1781,8 @@ def shuffle_door_traps(door_type_pools, paths, start_regions_map, world, player) builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon]) remaining -= len(custom_trap_doors[dungeon]) ttl += len(builder.candidates.trap) + if ttl == 0: + return used_doors for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.trap) @@ -1862,6 +1841,8 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, builder.candidates.big = filter_key_door_pool(builder.candidates.big, custom_bk_doors[dungeon]) remaining -= len(custom_bk_doors[dungeon]) ttl += len(builder.candidates.big) + if ttl == 0: + return used_doors for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.big) @@ -1934,6 +1915,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl suggested -= 1 combo_size = ncr(len(builder.candidates.small), suggested + builder.key_drop_cnt) suggestion_map[dungeon] = builder.key_doors_num = suggested + builder.key_drop_cnt + remaining -= suggested + builder.key_drop_cnt builder.combo_size = combo_size flex_map[dungeon] = (limit - suggested) if suggested < limit else 0 for dungeon in pool: @@ -1986,6 +1968,79 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl return used_doors +def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, world, player): + for pool, door_type_pool in door_type_pools: + ttl = 0 + suggestion_map, bd_map = {}, {} + remaining_bomb = door_type_pool.bombable + remaining_dash = door_type_pool.dashable + + if player in world.custom_door_types: + custom_bomb_doors = world.custom_door_types[player]['Bomb Door'] + custom_dash_doors = world.custom_door_types[player]['Dash Door'] + else: + custom_bomb_doors = defaultdict(list) + custom_dash_doors = defaultdict(list) + + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + find_bd_candidates(builder, start_regions_map[dungeon], used_doors, world, player) + if custom_bomb_doors[dungeon]: + builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, custom_bomb_doors[dungeon]) + remaining_bomb -= len(custom_bomb_doors[dungeon]) + if custom_dash_doors[dungeon]: + builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, custom_dash_doors[dungeon]) + remaining_dash -= len(custom_dash_doors[dungeon]) + ttl += len(builder.candidates.bomb_dash) + if ttl == 0: + return used_doors + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + proportion = len(builder.candidates.bomb_dash) + calc = int(round(proportion * door_type_pool.bombable/ttl)) + suggested_bomb = min(proportion, calc) + remaining_bomb -= suggested_bomb + calc = int(round(proportion * door_type_pool.dashable/ttl)) + suggested_dash = min(proportion, calc) + remaining_dash -= suggested_dash + suggestion_map[dungeon] = suggested_bomb, suggested_dash + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + bomb_doors, dash_doors, bd_number = find_valid_bd_combination(builder, suggestion_map[dungeon], world, player) + bd_map[dungeon] = (bomb_doors, dash_doors) + if bd_number < suggestion_map[dungeon][0] + suggestion_map[dungeon][1]: + remaining_bomb += suggestion_map[dungeon][0] - len(bomb_doors) + remaining_dash += suggestion_map[dungeon][1] - len(dash_doors) + suggestion_map[dungeon] = len(bomb_doors), len(dash_doors) + builder_order = [x for x in pool] + random.shuffle(builder_order) + queue = deque(builder_order) + while len(queue) > 0 and (remaining_bomb > 0 or remaining_dash > 0): + dungeon = queue.popleft() + builder = world.dungeon_layouts[player][dungeon] + type_pool = [] + if remaining_bomb > 0: + type_pool.append('bomb') + if remaining_dash > 0: + type_pool.append('dash') + type_choice = random.choice(type_pool) + pair = suggestion_map[dungeon] + pair = pair[0] + (1 if type_choice == 'bomb' else 0), pair[1] + (1 if type_choice == 'dash' else 0) + bomb_doors, dash_doors, bd_number = find_valid_bd_combination(builder, pair, world, player) + if bomb_doors and dash_doors: + bd_map[dungeon] = (bomb_doors, dash_doors) + remaining_bomb -= (1 if type_choice == 'bomb' else 0) + remaining_dash -= (1 if type_choice == 'dash' else 0) + suggestion_map[dungeon] = pair + queue.append(dungeon) + # time to re-assign + reassign_bd_doors(bd_map, world, player) + for name, pair in bd_map.items(): + used_doors.update(flatten_pair_list(pair[0])) + used_doors.update(flatten_pair_list(pair[1])) + return used_doors + + def shuffle_key_doors(builder, world, player): start_regions = convert_regions(builder.path_entrances, world, player) # count number of key doors - this could be a table? @@ -2049,7 +2104,7 @@ def find_trappable_candidates(builder, world, player): else: r_set = builder.master_sector.region_set() for r in r_set: - for ext in r.exits: + for ext in world.get_region(r, player).exits: if ext.door: d = ext.door if d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name: @@ -2188,7 +2243,7 @@ def reassign_trap_doors(trap_map, world, player): elif kind in [DoorKind.Trap2, DoorKind.TrapTriggerable]: room.change(d.doorListPos, DoorKind.Normal) d.blocked = False - connect_one_way(world, d.name, d.dest.name, player) + # connect_one_way(world, d.name, d.dest.name, player) elif d.type is DoorType.Normal and d not in traps: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) d.blocked = False @@ -2213,18 +2268,19 @@ def change_door_to_trap(d, world, player): if d.type is DoorType.Interior: kind = room.kind(d) new_kind = None - if kind == DoorKind.TrapTriggerable and d.direction in [Direction.North, Direction.West]: + if kind == DoorKind.TrapTriggerable and d.direction in [Direction.South, Direction.East]: new_kind = DoorKind.Trap - elif kind == DoorKind.Trap2 and d.direction in [Direction.South, Direction.East]: + elif kind == DoorKind.Trap2 and d.direction in [Direction.North, Direction.West]: new_kind = DoorKind.Trap - elif d.direction in [Direction.North, Direction.West]: - new_kind = DoorKind.Trap2 elif d.direction in [Direction.South, Direction.East]: + new_kind = DoorKind.Trap2 + elif d.direction in [Direction.North, Direction.West]: new_kind = DoorKind.TrapTriggerable if new_kind: d.blocked = True - verify_door_list_pos(d, room, world, player, pos=3) - d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1}[d.doorListPos] + pos = 3 if d.type == DoorType.Normal else 4 + verify_door_list_pos(d, room, world, player, pos) + d.trapFlag = {0: 0x4, 1: 0x2, 2: 0x1, 3: 0x8}[d.doorListPos] room.change(d.doorListPos, new_kind) if d.entrance.connected_region is not None: d.entrance.connected_region.entrances.remove(d.entrance) @@ -2281,10 +2337,10 @@ def find_big_key_door_candidates(region, checked, used, world, player): if d and d.controller: d = d.controller if (d and not d.blocked and d.dest is not last_door and d.dest is not last_region - and d not in checked_doors and d not in used): + and d not in checked_doors): valid = False if (0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal] - and not d.entranceFlag and d.direction in [Direction.North, Direction.South]): + and not d.entranceFlag and d.direction in [Direction.North, Direction.South] and d not in used): room = world.get_room(d.roomIndex, player) position, kind = room.doorList[d.doorListPos] if d.type == DoorType.Interior: @@ -2366,6 +2422,7 @@ def find_current_bk_doors(builder): def reassign_big_key_doors(bk_map, world, player): + logger = logging.getLogger('') for name, big_doors in bk_map.items(): flat_proposal = flatten_pair_list(big_doors) builder = world.dungeon_layouts[player][name] @@ -2388,21 +2445,11 @@ def reassign_big_key_doors(bk_map, world, player): change_door_to_big_key(d1, world, player) d2.bigKey = True # ensure flag is set else: - names = [d1.name, d2.name] - found = False - for dp in world.paired_doors[player]: - if dp.door_a in names and dp.door_b in names: - dp.pair = True - found = True - elif dp.door_a in names: - dp.pair = False - elif dp.door_b in names: - dp.pair = False - if not found: - world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) + world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) change_door_to_big_key(d1, world, player) change_door_to_big_key(d2, world, player) world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Big Key Door', player) + logger.debug(f'Big Key Door: {d1.name} <-> {d2.name}') else: d = obj if d.type is DoorType.Interior: @@ -2419,6 +2466,7 @@ def reassign_big_key_doors(bk_map, world, player): change_door_to_big_key(d.dest, world, player) add_pair(d, d.dest, world, player) world.spoiler.set_door_type(d.name, 'Big Key Door', player) + logger.debug(f'Big Key Door: {d.name}') def change_door_to_big_key(d, world, player): @@ -2449,7 +2497,7 @@ def find_small_key_door_candidates(builder, start_regions, used, world, player): def calc_used_dungeon_items(builder, world, player): - base = 2 + base = max(count_reserved_locations(world, player, builder.location_set), 2) basic_flag = world.doorShuffle[player] == 'basic' if not world.bigkeyshuffle[player]: if builder.bk_required and not builder.bk_provided: @@ -2523,7 +2571,186 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k return builder.key_door_proposal, key_doors_needed -def build_sample_list(combinations, max_combinations=100000): +def find_bd_candidates(builder, start_regions, used, world, player): + # traverse dungeon and find candidates + candidates = [] + checked_doors = set() + for region in start_regions: + possible, checked = find_bd_door_candidates(region, checked_doors, used, world, player) + candidates.extend([x for x in possible if x not in candidates]) + checked_doors.update(checked) + flat_candidates = [] + for candidate in candidates: + # not valid if: Normal Coupled and Pair in is Checked and Pair is not in Candidates + if (world.decoupledoors[player] or candidate.type != DoorType.Normal + or candidate.dest not in checked_doors or candidate.dest in candidates): + flat_candidates.append(candidate) + builder.candidates.bomb_dash = build_pair_list(flat_candidates) + + +def find_bd_door_candidates(region, checked, used, world, player): + decoupled = world.decoupledoors[player] + dungeon_name = region.dungeon.name + candidates = [] + checked_doors = list(checked) + queue = deque([(region, None, None)]) + while len(queue) > 0: + current, last_door, last_region = queue.pop() + for ext in current.exits: + d = ext.door + controlled = d + if d and d.controller: + d = d.controller + if (d and not d.blocked and d.dest is not last_door and d.dest is not last_region + and d not in checked_doors): + valid = False + if (0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal] and not d.entranceFlag + and d not in used): + room = world.get_room(d.roomIndex, player) + position, kind = room.doorList[d.doorListPos] + if d.type == DoorType.Interior: + valid = kind in okay_interiors + if valid and d.dest not in candidates: # interior doors are not separable yet + candidates.append(d.dest) + elif d.type == DoorType.Normal: + if decoupled: + valid = kind in okay_normals + else: + d2 = d.dest + if d2 not in candidates and d2 not in used: + if d2.type == DoorType.Normal: + room_b = world.get_room(d2.roomIndex, player) + pos_b, kind_b = room_b.doorList[d2.doorListPos] + valid = kind in okay_normals and kind_b in okay_normals and valid_key_door_pair(d, d2) + else: + valid = kind in okay_normals + if valid and 0 <= d2.doorListPos < 4: + candidates.append(d2) + else: + valid = True + if valid and d not in candidates: + candidates.append(d) + connected = ext.connected_region + if valid_region_to_explore(connected, dungeon_name, world, player): + queue.append((ext.connected_region, controlled, current)) + if d is not None: + checked_doors.append(d) + return candidates, checked_doors + + +def find_valid_bd_combination(builder, suggested, world, player): + # bombable/dashable doors could be excluded in escape in standard until we can guarantee bomb access + # if world.mode[player] == 'standard' and builder.name == 'Hyrule Castle': + # return None, None, 0 + bd_door_pool = builder.candidates.bomb_dash + bomb_doors_needed, dash_doors_needed = suggested + ttl_needed = bomb_doors_needed + dash_doors_needed + if player in world.custom_door_types: + custom_bomb_doors = world.custom_door_types[player]['Bomb Door'][builder.name] + custom_dash_doors = world.custom_door_types[player]['Dash Door'][builder.name] + else: + custom_bomb_doors = [] + custom_dash_doors = [] + if custom_bomb_doors: + bd_door_pool = filter_key_door_pool(bd_door_pool, custom_bomb_doors) + bomb_doors_needed -= len(custom_bomb_doors) + if custom_dash_doors: + bd_door_pool = filter_key_door_pool(bd_door_pool, custom_dash_doors) + dash_doors_needed -= len(custom_dash_doors) + while len(bd_door_pool) < bomb_doors_needed + dash_doors_needed: + bomb_doors_needed = round(len(bd_door_pool) * bomb_doors_needed/ttl_needed) + dash_doors_needed = round(len(bd_door_pool) * dash_doors_needed/ttl_needed) + bomb_proposal = random.sample(bd_door_pool, k=bomb_doors_needed) + bomb_proposal.extend(custom_bomb_doors) + dash_pool = [x for x in bd_door_pool if x not in bomb_proposal] + dash_proposal = random.sample(dash_pool, k=dash_doors_needed) + dash_proposal.extend(custom_dash_doors) + return bomb_proposal, dash_proposal, ttl_needed + + +def reassign_bd_doors(bd_map, world, player): + for name, pair in bd_map.items(): + flat_bomb_proposal = flatten_pair_list(pair[0]) + flat_dash_proposal = flatten_pair_list(pair[1]) + + def not_in_proposal(door): + return (door not in flat_bomb_proposal and door.dest not in flat_bomb_proposal and + door not in flat_dash_proposal and door.dest not in flat_bomb_proposal) + + builder = world.dungeon_layouts[player][name] + queue = deque(find_current_bd_doors(builder, world)) + while len(queue) > 0: + d = queue.pop() + if d.type is DoorType.Interior and not_in_proposal(d): + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + elif d.type is DoorType.Normal and not_in_proposal(d): + if not d.entranceFlag: + world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) + do_bombable_dashable(flat_bomb_proposal, DoorKind.Bombable, world, player) + do_bombable_dashable(flat_dash_proposal, DoorKind.Dashable, world, player) + + +def do_bombable_dashable(proposal, kind, world, player): + for obj in proposal: + if type(obj) is tuple: + d1 = obj[0] + d2 = obj[1] + if d1.type is DoorType.Interior: + change_door_to_kind(d1, kind, world, player) + else: + names = [d1.name, d2.name] + found = False + for dp in world.paired_doors[player]: + if dp.door_a in names and dp.door_b in names: + dp.pair = True + found = True + elif dp.door_a in names: + dp.pair = False + elif dp.door_b in names: + dp.pair = False + if not found: + world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) + change_door_to_kind(d1, kind, world, player) + change_door_to_kind(d2, kind, world, player) + spoiler_type = 'Bomb Door' if kind == DoorKind.Bombable else 'Dash Door' + world.spoiler.set_door_type(d1.name+' <-> '+d2.name, spoiler_type, player) + else: + d = obj + if d.type is DoorType.Interior: + change_door_to_kind(d, kind, world, player) + elif d.type is DoorType.Normal: + change_door_to_kind(d, kind, world, player) + if not world.decoupledoors[player] and d.dest: + if d.dest.type in okay_normals and not std_forbidden(d.dest, world, player): + dest_room = world.get_room(d.dest.roomIndex, player) + if stateful_door(d.dest, dest_room.kind(d.dest)): + change_door_to_kind(d.dest, kind, world, player) + add_pair(d, d.dest, world, player) + spoiler_type = 'Bomb Door' if kind == DoorKind.Bombable else 'Dash Door' + world.spoiler.set_door_type(d.name, spoiler_type, player) + + +def find_current_bd_doors(builder, world): + current_doors = [] + for region in builder.master_sector.regions: + for ext in region.exits: + d = ext.door + if d and d.type in [DoorType.Interior, DoorType.Normal]: + kind = d.kind(world) + if kind in [DoorKind.Dashable, DoorKind.Bombable]: + current_doors.append(d) + return current_doors + + +def change_door_to_kind(d, kind, world, player): + room = world.get_room(d.roomIndex, player) + if room.doorList[d.doorListPos][1] != kind: + verify_door_list_pos(d, room, world, player) + room.change(d.doorListPos, kind) + + +def build_sample_list(combinations, max_combinations=10000): if combinations <= max_combinations: sample_list = list(range(0, int(combinations))) else: @@ -2609,10 +2836,10 @@ def find_key_door_candidates(region, checked, used, world, player): if d and d.controller: d = d.controller if (d and not d.blocked and d.dest is not last_door and d.dest is not last_region - and d not in checked_doors and d not in used): + and d not in checked_doors): valid = False if (0 <= d.doorListPos < 4 and d.type in [DoorType.Interior, DoorType.Normal, DoorType.SpiralStairs] - and not d.entranceFlag): + and not d.entranceFlag and d not in used): room = world.get_room(d.roomIndex, player) position, kind = room.doorList[d.doorListPos] if d.type == DoorType.Interior: diff --git a/DungeonGenerator.py b/DungeonGenerator.py index f06c3535..055a7252 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -15,6 +15,8 @@ from Regions import dungeon_events, flooded_keys_reverse from Dungeons import dungeon_regions, split_region_starts from RoomData import DoorKind +from source.dungeon.DungeonStitcher import generate_dungeon_find_proposal + class GraphPiece: @@ -62,7 +64,7 @@ def generate_dungeon(builder, entrance_region_names, split_dungeon, world, playe if builder.valid_proposal: # we made this earlier in gen, just use it proposed_map = builder.valid_proposal else: - proposed_map = generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon, world, player) + proposed_map = generate_dungeon_find_proposal_old(builder, entrance_region_names, split_dungeon, world, player) builder.valid_proposal = proposed_map queue = collections.deque(proposed_map.items()) while len(queue) > 0: @@ -80,7 +82,7 @@ def generate_dungeon(builder, entrance_region_names, split_dungeon, world, playe return master_sector -def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon, world, player): +def generate_dungeon_find_proposal_old(builder, entrance_region_names, split_dungeon, world, player): logger = logging.getLogger('') name = builder.name entrance_regions = convert_regions(entrance_region_names, world, player) @@ -868,9 +870,9 @@ class ExplorationState(object): self.key_locations += 1 if location.name not in dungeon_events and '- Prize' not in location.name and location.name not in ['Agahnim 1', 'Agahnim 2']: self.ttl_locations += 1 - if location not in self.found_locations: # todo: special logic for TT Boss? + if location not in self.found_locations: self.found_locations.append(location) - if not bk_Flag: + if not bk_Flag and (not location.forced_item or 'Big Key' in location.item.name): self.bk_found.add(location) if location.name in dungeon_events and location.name not in self.events: if self.flooded_key_check(location): @@ -1199,6 +1201,7 @@ class DungeonBuilder(object): self.name = name self.sectors = [] self.location_cnt = 0 + self.location_set = set() self.key_drop_cnt = 0 self.dungeon_items = None # during fill how many dungeon items are left self.free_items = None # during fill how many dungeon items are left @@ -1569,6 +1572,7 @@ def assign_sector_helper(sector, builder): builder.sectors.append(sector) builder.location_cnt += sector.chest_locations builder.key_drop_cnt += sector.key_only_locations + builder.location_set.update(sector.chest_location_set) if sector.c_switch: builder.c_switch_present = True if sector.blue_barrier: diff --git a/Main.py b/Main.py index 4e6b9c4b..5efc990b 100644 --- a/Main.py +++ b/Main.py @@ -107,6 +107,7 @@ def main(args, seed=None, fish=None): world.beemizer = args.beemizer.copy() world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)} world.door_type_mode = args.door_type_mode.copy() + world.decoupledoors = args.decoupledoors.copy() world.experimental = args.experimental.copy() world.dungeon_counters = args.dungeon_counters.copy() world.fish = fish diff --git a/Rom.py b/Rom.py index d6717617..18f0c70b 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'afcd895b87559cd29b04aa3714cbc929' +RANDOMIZERBASEHASH = 'b4daf51397414464562a772f72f0b551' class JsonRom(object): @@ -843,7 +843,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): if world.doorShuffle[player] != 'vanilla': for name, pair in boss_indicator.items(): dungeon_id, boss_door = pair - opposite_door = world.get_door(boss_door, player).dest + boss_region = world.get_door(boss_door, player).entrance.parent_region + opposite_door = next(iter(x for x in boss_region.entrances if x.name != 'Skull Final Drop WS')).door if opposite_door and isinstance(opposite_door, Door) and opposite_door.roomIndex > -1: dungeon_name = opposite_door.entrance.parent_region.dungeon.name dungeon_id = boss_indicator[dungeon_name][0] diff --git a/RoomData.py b/RoomData.py index 03700e32..85c3b1fd 100644 --- a/RoomData.py +++ b/RoomData.py @@ -320,7 +320,7 @@ class Room(object): for i, door in enumerate(self.doorList): if i >= pos: return None - pos, kind = door + position, kind = door if kind not in [DoorKind.SmallKey, DoorKind.Dashable, DoorKind.Bombable, DoorKind.TrapTriggerable, DoorKind.Trap, DoorKind.Trap2, DoorKind.TrapTriggerableLow, DoorKind.TrapLowE3, DoorKind.BigKey, DoorKind.StairKey, DoorKind.StairKey2, DoorKind.StairKeyLow, @@ -395,8 +395,8 @@ class DoorKind(Enum): Bombable = 0x2E BlastWall = 0x30 Hidden = 0x32 - TrapTriggerable = 0x36 # right side trap or bottom side trap (West, North) - Trap2 = 0x38 # left side trap or top side trap (East, South) + TrapTriggerable = 0x36 # right side trap or bottom side trap (door directions: West, North) + Trap2 = 0x38 # left side trap or top side trap (door directions: East, South) NormalLow2 = 0x40 TrapTriggerableLow = 0x44 Warp = 0x46 diff --git a/data/base2current.bps b/data/base2current.bps index d657ad40ba6c5ce7ceabd188463dc93b16f6db49..f20e51505f4403e3ec1f477e0fcba47d5b000d0f 100644 GIT binary patch delta 9728 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 delta 9675 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 diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py index b179cb1c..aa74dee0 100644 --- a/source/dungeon/DungeonStitcher.py +++ b/source/dungeon/DungeonStitcher.py @@ -370,8 +370,7 @@ def connect_doors_one_way(a, b): return # Connect supported types if a.type in [DoorType.Normal, DoorType.SpiralStairs, DoorType.Open, DoorType.StraightStairs, DoorType.Ladder]: - if not a.blocked: - connect_one_way(a.entrance, b.entrance) + connect_one_way(a.entrance, b.entrance) dep_doors, target = [], None if len(a.dependents) > 0: dep_doors, target = a.dependents, b From 5dd9403afd988e1b0d395296f435cd96f3d12f61 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 11 Aug 2022 15:38:15 -0600 Subject: [PATCH 029/146] Correct rom for tavern work --- Rom.py | 2 +- data/base2current.bps | Bin 93041 -> 93253 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index d63ac585..2b76e5e4 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'e33204b6023f07025eba16874308f57d' +RANDOMIZERBASEHASH = 'a8b35a6396c104e9419ff1e46342e4db' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index fc22d9c3956780075f6752188bd52fca2ae6c189..a5f9cc86e0647cb500a73cc56d94863bd395834d 100644 GIT binary patch delta 16205 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 Date: Thu, 11 Aug 2022 16:07:11 -0600 Subject: [PATCH 030/146] Rom update --- data/base2current.bps | Bin 93229 -> 93357 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/base2current.bps b/data/base2current.bps index f20e51505f4403e3ec1f477e0fcba47d5b000d0f..7811e083f0ec3e68051cbd97a49c301b23b61b7b 100644 GIT binary patch delta 8035 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 delta 8030 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 From c3dcd569924d38e97282e63fe6cafb54fcde8908 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 11 Aug 2022 16:37:15 -0600 Subject: [PATCH 031/146] Some fixes sent by Catobat --- DoorShuffle.py | 4 ++-- Rom.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 165dabf6..9d4a8475 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1730,7 +1730,7 @@ class DoorTypePool: def chaos_shuffle(self, counts): weights = [1, 2, 4, 3, 2, 1] - return [random.choices(self.get_choices(counts[i]), weights=weights) for i, c in enumerate(counts)] + return [random.choices(self.get_choices(counts[i]), weights=weights)[0] for i, c in enumerate(counts)] @staticmethod def get_choices(number): @@ -2316,7 +2316,7 @@ def find_big_key_candidates(builder, start_regions, used, world, player): else: r_set = builder.master_sector.region_set() for r in r_set: - for ext in r.exits: + for ext in world.get_region(r, player).exits: if ext.door: d = ext.door if d.bigKey and d.type in [DoorType.Normal, DoorType.Interior]: diff --git a/Rom.py b/Rom.py index 453e486a..3bc64b82 100644 --- a/Rom.py +++ b/Rom.py @@ -753,7 +753,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): dr_flags |= DROptions.DarkWorld_Spawns if world.logic[player] != 'nologic': dr_flags |= DROptions.Fix_EG - if world.door_type_mode in ['big', 'chaos']: + if world.door_type_mode[player] in ['big', 'all', 'chaos']: dr_flags |= DROptions.BigKeyDoor_Shuffle my_locations = world.get_filled_locations(player) From a5354f1f30b21bb644f2361041639268c2d4c66c Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 12 Aug 2022 13:50:04 -0600 Subject: [PATCH 032/146] Spoiler bug --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 118ff9de..2dc61574 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2574,7 +2574,7 @@ class Spoiler(object): outfile.write(f"Pseudoboots: {yn(self.metadata['pseudoboots'][player])}\n") outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player]) if self.metadata['shuffle'][player] != 'vanilla': - outfile.write(f"Link's House Shuffled: {yn(self.metadata['shufflelinks'])}\n") + outfile.write(f"Link's House Shuffled: {yn(self.metadata['shufflelinks'][player])}\n") outfile.write(f"Back of Tavern Shuffled: {yn(self.metadata['shuffletavern'][player])}\n") outfile.write(f"GT/Ganon Shuffled: {yn(self.metadata['shuffleganon'])}\n") outfile.write(f"Overworld Map: {self.metadata['overworld_map'][player]}\n") From 3e7dfaf8567952ba2ecca140b1b7377ab6df5002 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 23 Aug 2022 15:06:36 -0600 Subject: [PATCH 033/146] Fix Key Rat region --- DoorShuffle.py | 9 +++++---- Doors.py | 8 +++++--- Dungeons.py | 8 ++++---- KeyDoorShuffle.py | 2 +- PotShuffle.py | 12 ++++++------ Regions.py | 5 ++++- Rules.py | 3 ++- 7 files changed, 27 insertions(+), 20 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 9d4a8475..586a2c64 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -3888,6 +3888,7 @@ interior_doors = [ ('Hyrule Dungeon Armory Interior Key Door S', 'Hyrule Dungeon Armory Interior Key Door N'), ('Hyrule Dungeon Armory ES', 'Hyrule Dungeon Armory Boomerang WS'), ('Hyrule Dungeon Map Room Key Door S', 'Hyrule Dungeon North Abyss Key Door N'), + ('Sewers Dark Aquabats N', 'Sewers Key Rat S'), ('Sewers Rat Path WS', 'Sewers Secret Room ES'), ('Sewers Rat Path WN', 'Sewers Secret Room EN'), ('Sewers Yet More Rats S', 'Sewers Pull Switch N'), @@ -4058,7 +4059,7 @@ interior_doors = [ ] key_doors = [ - ('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'), + ('Sewers Key Rat NE', 'Sewers Secret Room Key Door S'), ('Sewers Dark Cross Key Door N', 'Sewers Water S'), ('Eastern Dark Square Key Door WN', 'Eastern Cannonball Ledge Key Door EN'), ('Eastern Darkness Up Stairs', 'Eastern Attic Start Down Stairs'), @@ -4078,7 +4079,7 @@ key_doors = [ default_small_key_doors = { 'Hyrule Castle': [ - ('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'), + ('Sewers Key Rat NE', 'Sewers Secret Room Key Door S'), ('Sewers Dark Cross Key Door N', 'Sewers Water S'), ('Hyrule Dungeon Map Room Key Door S', 'Hyrule Dungeon North Abyss Key Door N'), ('Hyrule Dungeon Armory Interior Key Door N', 'Hyrule Dungeon Armory Interior Key Door S') @@ -4178,8 +4179,8 @@ default_door_connections = [ ('Hyrule Castle Throne Room N', 'Sewers Behind Tapestry S'), ('Hyrule Dungeon Guardroom N', 'Hyrule Dungeon Armory S'), ('Sewers Dark Cross Key Door N', 'Sewers Water S'), - ('Sewers Water W', 'Sewers Key Rat E'), - ('Sewers Key Rat Key Door N', 'Sewers Secret Room Key Door S'), + ('Sewers Water W', 'Sewers Dark Aquabats ES'), + ('Sewers Key Rat NE', 'Sewers Secret Room Key Door S'), ('Eastern Lobby Bridge N', 'Eastern Cannonball S'), ('Eastern Cannonball N', 'Eastern Courtyard Ledge S'), ('Eastern Cannonball Ledge WN', 'Eastern Big Key EN'), diff --git a/Doors.py b/Doors.py index 99b4fab3..38daaa6a 100644 --- a/Doors.py +++ b/Doors.py @@ -104,8 +104,10 @@ def create_doors(world, player): create_door(player, 'Sewers Dark Cross Key Door N', Nrml).dir(No, 0x32, Mid, High).small_key().pos(0), create_door(player, 'Sewers Water S', Nrml).dir(So, 0x22, Mid, High).small_key().pos(0).portal(Z, 0x22), create_door(player, 'Sewers Water W', Nrml).dir(We, 0x22, Bot, High).pos(1), - create_door(player, 'Sewers Key Rat E', Nrml).dir(Ea, 0x21, Bot, High).pos(1), - create_door(player, 'Sewers Key Rat Key Door N', Nrml).dir(No, 0x21, Right, High).small_key().pos(0), + create_door(player, 'Sewers Dark Aquabats ES', Nrml).dir(Ea, 0x21, Bot, High).pos(2), + create_door(player, 'Sewers Dark Aquabats N', Intr).dir(No, 0x21, Mid, High).pos(1), + create_door(player, 'Sewers Key Rat S', Intr).dir(So, 0x21, Mid, High).pos(1), + create_door(player, 'Sewers Key Rat NE', Nrml).dir(No, 0x21, Right, High).small_key().pos(0), create_door(player, 'Sewers Secret Room Key Door S', Nrml).dir(So, 0x11, Right, High).small_key().pos(2).portal(X, 0x02), create_door(player, 'Sewers Rat Path WS', Intr).dir(We, 0x11, Bot, High).pos(1), create_door(player, 'Sewers Rat Path WN', Intr).dir(We, 0x11, Top, High).pos(0), @@ -1567,7 +1569,7 @@ def reset_portals(world, player): def create_paired_doors(world, player): world.paired_doors[player] = [ - PairedDoor('Sewers Secret Room Key Door S', 'Sewers Key Rat Key Door N', True), + PairedDoor('Sewers Secret Room Key Door S', 'Sewers Key Rat NE', True), PairedDoor('TR Pokey 2 ES', 'TR Lava Island WS', True), # TR Pokey Key PairedDoor('TR Dodgers NE', 'TR Lava Escape SE', True), # TR Big key door by pipes PairedDoor('PoD Falling Bridge WN', 'PoD Dark Maze EN', True), # Pod Dark maze door diff --git a/Dungeons.py b/Dungeons.py index 188cf59f..58ebcc75 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -52,10 +52,10 @@ hyrule_castle_regions = [ 'Hyrule Dungeon South Abyss', 'Hyrule Dungeon South Abyss Catwalk', 'Hyrule Dungeon Guardroom', 'Hyrule Dungeon Armory Main', 'Hyrule Dungeon Armory Boomerang', 'Hyrule Dungeon Armory North Branch', 'Hyrule Dungeon Staircase', 'Hyrule Dungeon Cellblock', 'Hyrule Dungeon Cell', 'Sewers Behind Tapestry', - 'Sewers Rope Room', 'Sewers Dark Cross', 'Sewers Water', 'Sewers Key Rat', 'Sewers Rat Path', - 'Sewers Secret Room Blocked Path', 'Sewers Secret Room', 'Sewers Yet More Rats', 'Sewers Pull Switch', 'Sanctuary', - 'Sanctuary Portal', 'Hyrule Castle West Portal', 'Hyrule Castle South Portal', 'Hyrule Castle East Portal' - + 'Sewers Rope Room', 'Sewers Dark Cross', 'Sewers Water', 'Sewers Dark Aquabats', 'Sewers Key Rat', + 'Sewers Rat Path', 'Sewers Secret Room Blocked Path', 'Sewers Secret Room', 'Sewers Yet More Rats', + 'Sewers Pull Switch', 'Sanctuary', 'Sanctuary Portal', 'Hyrule Castle West Portal', 'Hyrule Castle South Portal', + 'Hyrule Castle East Portal' ] eastern_regions = [ diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index 8a70abcf..4d501764 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -1908,7 +1908,7 @@ def val_hyrule(key_logic, world, player): val_rule(key_logic.door_rules['Hyrule Dungeon Map Room Key Door S'], 1) val_rule(key_logic.door_rules['Hyrule Dungeon Armory Interior Key Door N'], 2) val_rule(key_logic.door_rules['Sewers Dark Cross Key Door N'], 3) - val_rule(key_logic.door_rules['Sewers Key Rat Key Door N'], 4) + val_rule(key_logic.door_rules['Sewers Key Rat NE'], 4) else: val_rule(key_logic.door_rules['Sewers Secret Room Key Door S'], 2) val_rule(key_logic.door_rules['Sewers Dark Cross Key Door N'], 2) diff --git a/PotShuffle.py b/PotShuffle.py index 7806f495..eafc7399 100644 --- a/PotShuffle.py +++ b/PotShuffle.py @@ -93,12 +93,12 @@ vanilla_pots = { Pot(28, 23, PotItem.Nothing, 'Ice Pengator Switch', obj=RoomObject(0x1FC388, [0x3B, 0xBB, 0xFA])), Pot(86, 26, PotItem.Nothing, 'Ice Big Key', obj=RoomObject(0x1FC397, [0xAF, 0xD3, 0xFA])), Pot(86, 27, PotItem.Nothing, 'Ice Big Key', obj=RoomObject(0x1FC39A, [0xAF, 0xDB, 0xFA]))], - 0x21: [Pot(160, 20, PotItem.Nothing, 'Sewers Key Rat', obj=RoomObject(0x0A8C71, [0x43, 0xA7, 0xFA])), - Pot(168, 24, PotItem.SmallMagic, 'Sewers Key Rat', obj=RoomObject(0x0A8C7A, [0x53, 0xC7, 0xFA])), - Pot(48, 28, PotItem.Heart, 'Sewers Key Rat', obj=RoomObject(0x0A8C80, [0x63, 0xE3, 0xFA])), - Pot(82, 28, PotItem.SmallMagic, 'Sewers Key Rat', obj=RoomObject(0x0A8C7D, [0xA7, 0xE3, 0xFA])), - Pot(100, 28, PotItem.Nothing, 'Sewers Key Rat', obj=RoomObject(0x0A8C74, [0xCB, 0xE3, 0xFA])), - Pot(104, 28, PotItem.Nothing, 'Sewers Key Rat', obj=RoomObject(0x0A8C77, [0xD3, 0xE3, 0xFA]))], + 0x21: [Pot(160, 20, PotItem.Nothing, 'Sewers Dark Aquabats', obj=RoomObject(0x0A8C71, [0x43, 0xA7, 0xFA])), + Pot(168, 24, PotItem.SmallMagic, 'Sewers Dark Aquabats', obj=RoomObject(0x0A8C7A, [0x53, 0xC7, 0xFA])), + Pot(48, 28, PotItem.Heart, 'Sewers Dark Aquabats', obj=RoomObject(0x0A8C80, [0x63, 0xE3, 0xFA])), + Pot(82, 28, PotItem.SmallMagic, 'Sewers Dark Aquabats', obj=RoomObject(0x0A8C7D, [0xA7, 0xE3, 0xFA])), + Pot(100, 28, PotItem.Nothing, 'Sewers Dark Aquabats', obj=RoomObject(0x0A8C74, [0xCB, 0xE3, 0xFA])), + Pot(104, 28, PotItem.Nothing, 'Sewers Dark Aquabats', obj=RoomObject(0x0A8C77, [0xD3, 0xE3, 0xFA]))], 0x23: [Pot(86, 26, PotItem.OneRupee, 'TR Lazy Eyes', obj=RoomObject(0x1FED09, [0xAF, 0xD3, 0xFA])), Pot(90, 26, PotItem.Heart, 'TR Lazy Eyes', obj=RoomObject(0x1FED0C, [0xB7, 0xD3, 0xFA])), Pot(94, 26, PotItem.OneRupee, 'TR Lazy Eyes', obj=RoomObject(0x1FED0F, [0xBF, 0xD3, 0xFA])), diff --git a/Regions.py b/Regions.py index c0ef0364..c3fe40c5 100644 --- a/Regions.py +++ b/Regions.py @@ -284,7 +284,10 @@ def create_dungeon_regions(world, player): create_dungeon_region(player, 'Sewers Rope Room', 'Hyrule Castle', None, ['Sewers Rope Room Up Stairs', 'Sewers Rope Room North Stairs']), create_dungeon_region(player, 'Sewers Dark Cross', 'Hyrule Castle', ['Sewers - Dark Cross'], ['Sewers Dark Cross Key Door N', 'Sewers Dark Cross South Stairs']), create_dungeon_region(player, 'Sewers Water', 'Hyrule Castle', None, ['Sewers Water S', 'Sewers Water W']), - create_dungeon_region(player, 'Sewers Key Rat', 'Hyrule Castle', ['Hyrule Castle - Key Rat Key Drop'], ['Sewers Key Rat E', 'Sewers Key Rat Key Door N']), + create_dungeon_region(player, 'Sewers Dark Aquabats', 'Hyrule Castle', None, + ['Sewers Dark Aquabats ES', 'Sewers Dark Aquabats N']), + create_dungeon_region(player, 'Sewers Key Rat', 'Hyrule Castle', ['Hyrule Castle - Key Rat Key Drop'], + ['Sewers Key Rat S', 'Sewers Key Rat NE']), create_dungeon_region(player, 'Sewers Secret Room Blocked Path', 'Hyrule Castle', None, ['Sewers Secret Room Up Stairs']), create_dungeon_region(player, 'Sewers Rat Path', 'Hyrule Castle', None, ['Sewers Secret Room Key Door S', 'Sewers Secret Room Push Block', 'Sewers Rat Path WS', 'Sewers Rat Path WN']), create_dungeon_region(player, 'Sewers Secret Room', 'Hyrule Castle', ['Sewers - Secret Room - Left', 'Sewers - Secret Room - Middle', 'Sewers - Secret Room - Right'], diff --git a/Rules.py b/Rules.py index 18ec1fff..b86a7345 100644 --- a/Rules.py +++ b/Rules.py @@ -1149,7 +1149,8 @@ def add_conditional_lamps(world, player): 'Sewers Behind Tapestry': {'sewer': True, 'entrances': ['Sewers Behind Tapestry S', 'Sewers Behind Tapestry Down Stairs'], 'locations': []}, 'Sewers Rope Room': {'sewer': True, 'entrances': ['Sewers Rope Room Up Stairs', 'Sewers Rope Room North Stairs'], 'locations': []}, 'Sewers Water': {'sewer': True, 'entrances': ['Sewers Water S', 'Sewers Water W'], 'locations': []}, - 'Sewers Key Rat': {'sewer': True, 'entrances': ['Sewers Key Rat E', 'Sewers Key Rat Key Door N'], 'locations': ['Hyrule Castle - Key Rat Key Drop']}, + 'Sewers Dark Aquabats': {'sewer': True, 'entrances': ['Sewers Dark Aquabats N', 'Sewers Dark Aquabats ES'], 'locations': []}, + 'Sewers Key Rat': {'sewer': True, 'entrances': ['Sewers Key Rat S', 'Sewers Key Rat NE'], 'locations': ['Hyrule Castle - Key Rat Key Drop']}, 'Old Man Cave': {'sewer': False, 'entrances': ['Old Man Cave Exit (East)']}, 'Old Man House Back': {'sewer': False, 'entrances': ['Old Man House Back to Front', 'Old Man House Exit (Top)']}, 'Death Mountain Return Cave (left)': {'sewer': False, 'entrances': ['Death Mountain Return Cave E', 'Death Mountain Return Cave Exit (West)']}, From 5b8b0cb7f8c0835c339fd645d268f49a48531619 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 23 Aug 2022 15:27:22 -0600 Subject: [PATCH 034/146] Mire Falling Bridge logic refinement for possible trap door movement --- DoorShuffle.py | 4 ++++ Doors.py | 8 ++++++++ Dungeons.py | 18 ++++++++++-------- Regions.py | 7 ++++++- Rules.py | 9 +++++---- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 586a2c64..31744208 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -3593,6 +3593,8 @@ logical_connections = [ ('Mire Hub Top Blue Barrier', 'Mire Hub Switch'), ('Mire Hub Switch Blue Barrier N', 'Mire Hub Top'), ('Mire Hub Switch Blue Barrier S', 'Mire Hub'), + ('Mire Falling Bridge Hook Path', 'Mire Falling Bridge - Chest'), + ('Mire Falling Bridge Hook Only Path', 'Mire Falling Bridge - Chest'), ('Mire Map Spike Side Drop Down', 'Mire Lone Shooter'), ('Mire Map Spike Side Blue Barrier', 'Mire Crystal Dead End'), ('Mire Map Spot Blue Barrier', 'Mire Crystal Dead End'), @@ -3725,6 +3727,8 @@ vanilla_logical_connections = [ ('Ice Cross Right Push Block Bottom', 'Ice Compass Room'), ('Ice Cross Bottom Push Block Right', 'Ice Pengator Switch'), ('Ice Cross Top Push Block Right', 'Ice Pengator Switch'), + ('Mire Falling Bridge Primary Path', 'Mire Lone Shooter'), + ('Mire Falling Bridge Failure Path', 'Mire Failure Bridge'), ] spiral_staircases = [ diff --git a/Doors.py b/Doors.py index 38daaa6a..5a205f1c 100644 --- a/Doors.py +++ b/Doors.py @@ -847,6 +847,10 @@ def create_doors(world, player): create_door(player, 'Mire Failure Bridge E', Intr).dir(Ea, 0xc3, Mid, High).no_exit().trap(0x1).pos(2), create_door(player, 'Mire Failure Bridge W', Nrml).dir(We, 0xc3, Mid, High).pos(5), create_door(player, 'Mire Falling Bridge WN', Intr).dir(We, 0xc3, Top, High).pos(1), + create_door(player, 'Mire Falling Bridge Hook Path', Lgcl), + create_door(player, 'Mire Falling Bridge Hook Only Path', Lgcl), + create_door(player, 'Mire Falling Bridge Primary Path', Lgcl), # dynamic + create_door(player, 'Mire Falling Bridge Failure Path', Lgcl), # dynamic create_door(player, 'Mire Map Spike Side EN', Intr).dir(Ea, 0xc3, Top, High).no_exit().trap(0x2).pos(1), create_door(player, 'Mire Map Spot WN', Nrml).dir(We, 0xc3, Top, High).small_key().pos(0), create_door(player, 'Mire Crystal Dead End NW', Nrml).dir(No, 0xc3, Left, High).pos(4), @@ -1477,6 +1481,10 @@ def create_doors(world, player): controller_door(south_controller, world.get_door('Ice Cross Top Push Block Bottom', player)) controller_door(east_controller, world.get_door('Ice Cross Bottom Push Block Right', player)) controller_door(east_controller, world.get_door('Ice Cross Top Push Block Right', player)) + failure_controller = world.get_door('Mire Falling Bridge W', player) + primary_controller = world.get_door('Mire Falling Bridge WS', player) + controller_door(failure_controller, world.get_door('Mire Falling Bridge Failure Path', player)) + controller_door(primary_controller, world.get_door('Mire Falling Bridge Primary Path', player)) assign_entrances(world, player) diff --git a/Dungeons.py b/Dungeons.py index 58ebcc75..59a6a963 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -155,14 +155,16 @@ ice_regions = [ mire_regions = [ 'Mire Lobby', 'Mire Post-Gap', 'Mire 2', 'Mire Hub', 'Mire Hub Right', 'Mire Hub Top', 'Mire Hub Switch', - 'Mire Lone Shooter', 'Mire Failure Bridge', 'Mire Falling Bridge', 'Mire Map Spike Side', 'Mire Map Spot', - 'Mire Crystal Dead End', 'Mire Hidden Shooters', 'Mire Hidden Shooters Blocked', 'Mire Cross', 'Mire Minibridge', - 'Mire BK Door Room', 'Mire Spikes', 'Mire Ledgehop', 'Mire Bent Bridge', 'Mire Over Bridge', 'Mire Right Bridge', - 'Mire Left Bridge', 'Mire Fishbone', 'Mire South Fish', 'Mire Spike Barrier', 'Mire Square Rail', 'Mire Lone Warp', - 'Mire Wizzrobe Bypass', 'Mire Conveyor Crystal', 'Mire Conveyor - Crystal', 'Mire Tile Room', 'Mire Compass Room', 'Mire Compass Chest', - 'Mire Neglected Room', 'Mire Chest View', 'Mire Conveyor Barrier', 'Mire BK Chest Ledge', 'Mire Warping Pool', - 'Mire Torches Top', 'Mire Torches Bottom', 'Mire Attic Hint', 'Mire Dark Shooters', 'Mire Key Rupees', - 'Mire Block X', 'Mire Tall Dark and Roomy', 'Mire Tall Dark and Roomy - Ranged Crystal', 'Mire Crystal Right', 'Mire Crystal Mid', 'Mire Crystal Left', + 'Mire Lone Shooter', 'Mire Failure Bridge', 'Mire Falling Bridge - Primary', 'Mire Falling Bridge - Failure', + 'Mire Falling Bridge - Chest', 'Mire Map Spike Side', 'Mire Map Spot', 'Mire Crystal Dead End', + 'Mire Hidden Shooters', 'Mire Hidden Shooters Blocked', 'Mire Cross', 'Mire Minibridge', 'Mire BK Door Room', + 'Mire Spikes', 'Mire Ledgehop', 'Mire Bent Bridge', 'Mire Over Bridge', 'Mire Right Bridge', 'Mire Left Bridge', + 'Mire Fishbone', 'Mire South Fish', 'Mire Spike Barrier', 'Mire Square Rail', 'Mire Lone Warp', + 'Mire Wizzrobe Bypass', 'Mire Conveyor Crystal', 'Mire Conveyor - Crystal', 'Mire Tile Room', 'Mire Compass Room', + 'Mire Compass Chest', 'Mire Neglected Room', 'Mire Chest View', 'Mire Conveyor Barrier', 'Mire BK Chest Ledge', + 'Mire Warping Pool', 'Mire Torches Top', 'Mire Torches Bottom', 'Mire Attic Hint', 'Mire Dark Shooters', + 'Mire Key Rupees', 'Mire Block X', 'Mire Tall Dark and Roomy', 'Mire Tall Dark and Roomy - Ranged Crystal', + 'Mire Crystal Right', 'Mire Crystal Mid', 'Mire Crystal Left', 'Mire Crystal Top', 'Mire Shooter Rupees', 'Mire Falling Foes', 'Mire Firesnake Skip', 'Mire Antechamber', 'Mire Boss', 'Mire Portal' ] diff --git a/Regions.py b/Regions.py index c3fe40c5..88c0242b 100644 --- a/Regions.py +++ b/Regions.py @@ -636,7 +636,12 @@ def create_dungeon_regions(world, player): create_dungeon_region(player, 'Mire Hub Switch', 'Misery Mire', ['Misery Mire - Main Lobby'], ['Mire Hub Switch Blue Barrier N', 'Mire Hub Switch Blue Barrier S']), create_dungeon_region(player, 'Mire Lone Shooter', 'Misery Mire', None, ['Mire Lone Shooter WS', 'Mire Lone Shooter ES']), create_dungeon_region(player, 'Mire Failure Bridge', 'Misery Mire', None, ['Mire Failure Bridge W', 'Mire Failure Bridge E']), - create_dungeon_region(player, 'Mire Falling Bridge', 'Misery Mire', ['Misery Mire - Big Chest'], ['Mire Falling Bridge WS', 'Mire Falling Bridge W', 'Mire Falling Bridge WN']), + create_dungeon_region(player, 'Mire Falling Bridge - Failure', 'Misery Mire', None, + ['Mire Falling Bridge W', 'Mire Falling Bridge Hook Only Path', 'Mire Falling Bridge Primary Path']), + create_dungeon_region(player, 'Mire Falling Bridge - Primary', 'Misery Mire', None, + ['Mire Falling Bridge WS', 'Mire Falling Bridge Hook Path', 'Mire Falling Bridge Failure Path']), + create_dungeon_region(player, 'Mire Falling Bridge - Chest', 'Misery Mire', ['Misery Mire - Big Chest'], + ['Mire Falling Bridge WN']), create_dungeon_region(player, 'Mire Map Spike Side', 'Misery Mire', None, ['Mire Map Spike Side EN', 'Mire Map Spike Side Drop Down', 'Mire Map Spike Side Blue Barrier']), create_dungeon_region(player, 'Mire Map Spot', 'Misery Mire', ['Misery Mire - Map Chest'], ['Mire Map Spot WN', 'Mire Map Spot Blue Barrier']), create_dungeon_region(player, 'Mire Crystal Dead End', 'Misery Mire', None, ['Mire Crystal Dead End Left Barrier', 'Mire Crystal Dead End Right Barrier', 'Mire Crystal Dead End NW']), diff --git a/Rules.py b/Rules.py index b86a7345..a0d78863 100644 --- a/Rules.py +++ b/Rules.py @@ -314,7 +314,8 @@ def global_rules(world, player): set_rule(world.get_entrance('Mire Lobby Gap', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player)) set_rule(world.get_entrance('Mire Post-Gap Gap', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player)) - set_rule(world.get_entrance('Mire Falling Bridge WN', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player)) # this is due to the fact the the door opposite is blocked + set_rule(world.get_entrance('Mire Falling Bridge Hook Path', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player)) + set_rule(world.get_entrance('Mire Falling Bridge Hook Only Path', player), lambda state: state.has('Hookshot', player)) set_rule(world.get_entrance('Mire 2 NE', player), lambda state: state.has_sword(player) or (state.has('Fire Rod', player) and (state.can_use_bombs(player) or state.can_extend_magic(player, 9))) or # 9 fr shots or 8 with some bombs (state.has('Ice Rod', player) and state.can_use_bombs(player)) or # freeze popo and throw, bomb to finish @@ -2021,9 +2022,9 @@ bunny_impassible_doors = { 'Ice Backwards Room Hole', 'Ice Switch Room SE', 'Ice Antechamber NE', 'Ice Antechamber Hole', 'Mire Lobby Gap', 'Mire Post-Gap Gap', 'Mire 2 NE', 'Mire Hub Upper Blue Barrier', 'Mire Hub Lower Blue Barrier', 'Mire Hub Right Blue Barrier', 'Mire Hub Top Blue Barrier', 'Mire Hub Switch Blue Barrier N', - 'Mire Hub Switch Blue Barrier S', 'Mire Falling Bridge WN', 'Mire Map Spike Side Blue Barrier', - 'Mire Map Spot Blue Barrier', 'Mire Crystal Dead End Left Barrier', 'Mire Crystal Dead End Right Barrier', - 'Mire Cross ES', 'Mire Left Bridge Hook Path', 'Mire Fishbone Blue Barrier', + 'Mire Hub Switch Blue Barrier S', 'Mire Falling Bridge Hook Path', 'Mire Falling Bridge Hook Only Path', + 'Mire Map Spike Side Blue Barrier', 'Mire Map Spot Blue Barrier', 'Mire Crystal Dead End Left Barrier', + 'Mire Crystal Dead End Right Barrier', 'Mire Cross ES', 'Mire Left Bridge Hook Path', 'Mire Fishbone Blue Barrier', 'Mire South Fish Blue Barrier', 'Mire Tile Room NW', 'Mire Compass Blue Barrier', 'Mire Attic Hint Hole', 'Mire Dark Shooters SW', 'Mire Crystal Mid Blue Barrier', 'Mire Crystal Left Blue Barrier', 'TR Main Lobby Gap', 'TR Lobby Ledge Gap', 'TR Hub SW', 'TR Hub SE', 'TR Hub ES', 'TR Hub EN', 'TR Hub NW', 'TR Hub NE', 'TR Hub Path', From 32305a2202c28ca80d9bb3b0d28fc0bbf7c2d4e7 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 24 Aug 2022 12:53:04 -0600 Subject: [PATCH 035/146] Copy world needs to copy location type --- Main.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Main.py b/Main.py index 1f9d7066..7c93eaf8 100644 --- a/Main.py +++ b/Main.py @@ -584,11 +584,7 @@ def copy_dynamic_regions_and_locations(world, ret): for location in world.dynamic_locations: new_reg = ret.get_region(location.parent_region.name, location.parent_region.player) new_loc = Location(location.player, location.name, location.address, location.crystal, location.hint_text, new_reg) - # todo: this is potentially dangerous. later refactor so we - # can apply dynamic region rules on top of copied world like other rules - new_loc.access_rule = location.access_rule - new_loc.always_allow = location.always_allow - new_loc.item_rule = location.item_rule + new_loc.type = location.type new_reg.locations.append(new_loc) ret.clear_location_cache() From 262b36cac66d3d47f4f098ace26d1663ad0b60fc Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 24 Aug 2022 13:10:32 -0600 Subject: [PATCH 036/146] Custom yaml properly record interior doors that are key doors --- source/classes/CustomSettings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 03a203f9..dd99853e 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -306,7 +306,7 @@ class CustomSettings(object): for door in world.doors: if door.player == p and not door.entranceFlag and door.type in door_types and door not in skip: if door.type == DoorType.Interior: - if door.name in door_types: + if door.name in door_kinds: door_value = {'type': door_kinds[door.name]} door_map[door.name] = door_value # intra-tile note skip.add(door.dest) From 6b369b68b7885471b73b4eea04f9488d250b70ff Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 24 Aug 2022 13:29:14 -0600 Subject: [PATCH 037/146] Update lite/lean with pottery options. Houses and caves with pots are shuffled in the ER pool if the pottery setting turns that on. --- source/overworld/EntranceShuffle2.py | 63 +++++++++++++++++++--------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index cb176aba..da454795 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -770,6 +770,9 @@ def do_vanilla_connect(pool_def, avail): if pool_def['condition'] == 'shopsanity': if avail.world.shopsanity[avail.player]: return + elif pool_def['condition'] == 'pottery': # this condition involves whether caves with pots are shuffled or not + if avail.world.pottery[avail.player] not in ['none', 'keys', 'dungeon']: + return defaults = inverted_default_connections if avail.inverted else default_connections for entrance in pool_def['entrances']: if entrance in avail.entrances: @@ -1188,16 +1191,13 @@ modes = { 'fixed_non_items': { 'special': 'vanilla', 'condition': '', - 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Dark Desert Hint', 'Archery Game', + 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Archery Game', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Bonk Fairy (Dark)', - 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop', - 'Palace of Darkness Hint', 'East Dark World Hint', 'Hookshot Fairy', '50 Rupee Cave', - 'Kakariko Gamble Game', '20 Rupee Cave', 'Good Bee Cave', 'Long Fairy Cave', - 'Light World Bomb Hut', 'Tavern (Front)', 'Bush Covered House', 'Snitch Lady (West)', - 'Snitch Lady (East)', 'Fortune Teller (Light)', 'Lost Woods Gamble', 'Desert Fairy', - 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', - 'Lumberjack House', 'Inverted Dark Sanctuary'], + 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', + 'Dark Lake Hylia Shop', 'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', + 'Long Fairy Cave', 'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble', + 'Desert Fairy', 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', + 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'], }, 'fixed_shops': { 'special': 'vanilla', @@ -1206,7 +1206,16 @@ modes = { 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)'], }, - 'item_caves': { # shuffles shops if they weren't fixed in the last one + 'fixed_pottery': { + 'special': 'vanilla', + 'condition': 'pottery', + 'entrances': ['Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', + 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', + 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Desert Hint'] + + }, + 'item_caves': { # shuffles shops/pottery if they weren't fixed in the last steps 'entrances': ['Mimic Cave', 'Spike Cave', 'Mire Shed', 'Dark World Hammer Peg Cave', 'Chest Game', 'C-Shaped House', 'Brewery', 'Hype Cave', 'Big Bomb Shop', 'Pyramid Fairy', 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', @@ -1215,6 +1224,10 @@ modes = { 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', + 'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', + 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', + 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Desert Hint', 'Links House', 'Inverted Links House', 'Tavern North'] }, 'old_man_cave': { # have to do old man cave first so lw dungeon don't use up everything @@ -1254,16 +1267,13 @@ modes = { 'fixed_non_items': { 'special': 'vanilla', 'condition': '', - 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Dark Desert Hint', 'Archery Game', + 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Archery Game', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Bonk Fairy (Dark)', - 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop', - 'Palace of Darkness Hint', 'East Dark World Hint', 'Hookshot Fairy', '50 Rupee Cave', - 'Kakariko Gamble Game', '20 Rupee Cave', 'Good Bee Cave', 'Long Fairy Cave', - 'Light World Bomb Hut', 'Tavern (Front)', 'Bush Covered House', 'Snitch Lady (West)', - 'Snitch Lady (East)', 'Fortune Teller (Light)', 'Lost Woods Gamble', 'Desert Fairy', - 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', - 'Lumberjack House', 'Inverted Dark Sanctuary'], + 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', + 'Dark Lake Hylia Shop', 'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', + 'Long Fairy Cave', 'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble', + 'Desert Fairy', 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', + 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'], }, 'fixed_shops': { 'special': 'vanilla', @@ -1272,7 +1282,16 @@ modes = { 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)'], }, - 'item_caves': { # shuffles shops if they weren't fixed in the last one + 'fixed_pottery': { + 'special': 'vanilla', + 'condition': 'pottery', + 'entrances': ['Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', + 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', + 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Desert Hint'] + + }, + 'item_caves': { # shuffles shops/pottery if they weren't fixed in the last steps 'entrances': ['Mimic Cave', 'Spike Cave', 'Mire Shed', 'Dark World Hammer Peg Cave', 'Chest Game', 'C-Shaped House', 'Brewery', 'Hype Cave', 'Big Bomb Shop', 'Pyramid Fairy', 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', @@ -1281,6 +1300,10 @@ modes = { 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', + 'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', + 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', + 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', + 'Dark Desert Hint', 'Links House', 'Inverted Links House', 'Tavern North'] } } From 16d7ce5e76c5c55f1e1a029bc41bafc1d85f1125 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 25 Aug 2022 08:59:44 -0600 Subject: [PATCH 038/146] Minor issue with new Mire Falling Bridge and a miss in dungeon gen for dungeon pools. --- DoorShuffle.py | 2 +- Doors.py | 4 +--- DungeonGenerator.py | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 31744208..b6e264af 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -3595,6 +3595,7 @@ logical_connections = [ ('Mire Hub Switch Blue Barrier S', 'Mire Hub'), ('Mire Falling Bridge Hook Path', 'Mire Falling Bridge - Chest'), ('Mire Falling Bridge Hook Only Path', 'Mire Falling Bridge - Chest'), + ('Mire Falling Bridge Failure Path', 'Mire Falling Bridge - Failure'), ('Mire Map Spike Side Drop Down', 'Mire Lone Shooter'), ('Mire Map Spike Side Blue Barrier', 'Mire Crystal Dead End'), ('Mire Map Spot Blue Barrier', 'Mire Crystal Dead End'), @@ -3728,7 +3729,6 @@ vanilla_logical_connections = [ ('Ice Cross Bottom Push Block Right', 'Ice Pengator Switch'), ('Ice Cross Top Push Block Right', 'Ice Pengator Switch'), ('Mire Falling Bridge Primary Path', 'Mire Lone Shooter'), - ('Mire Falling Bridge Failure Path', 'Mire Failure Bridge'), ] spiral_staircases = [ diff --git a/Doors.py b/Doors.py index 5a205f1c..c80ea51a 100644 --- a/Doors.py +++ b/Doors.py @@ -850,7 +850,7 @@ def create_doors(world, player): create_door(player, 'Mire Falling Bridge Hook Path', Lgcl), create_door(player, 'Mire Falling Bridge Hook Only Path', Lgcl), create_door(player, 'Mire Falling Bridge Primary Path', Lgcl), # dynamic - create_door(player, 'Mire Falling Bridge Failure Path', Lgcl), # dynamic + create_door(player, 'Mire Falling Bridge Failure Path', Lgcl), create_door(player, 'Mire Map Spike Side EN', Intr).dir(Ea, 0xc3, Top, High).no_exit().trap(0x2).pos(1), create_door(player, 'Mire Map Spot WN', Nrml).dir(We, 0xc3, Top, High).small_key().pos(0), create_door(player, 'Mire Crystal Dead End NW', Nrml).dir(No, 0xc3, Left, High).pos(4), @@ -1481,9 +1481,7 @@ def create_doors(world, player): controller_door(south_controller, world.get_door('Ice Cross Top Push Block Bottom', player)) controller_door(east_controller, world.get_door('Ice Cross Bottom Push Block Right', player)) controller_door(east_controller, world.get_door('Ice Cross Top Push Block Right', player)) - failure_controller = world.get_door('Mire Falling Bridge W', player) primary_controller = world.get_door('Mire Falling Bridge WS', player) - controller_door(failure_controller, world.get_door('Mire Falling Bridge Failure Path', player)) controller_door(primary_controller, world.get_door('Mire Falling Bridge Primary Path', player)) assign_entrances(world, player) diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 055a7252..4404d53f 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1346,8 +1346,8 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge sanc = find_sector('Sanctuary', candidate_sectors) if sanc: # only run if sanc if a candidate lw_builders = [] - for name, portal_list in dungeon_portals.items(): - for portal_name in portal_list: + for name in dungeon_pool: + for portal_name in dungeon_portals[name]: if world.get_portal(portal_name, player).light_world: lw_builders.append(dungeon_map[name]) break From af4f8e5b4b141cac36e175754f315de9340ff5fa Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 1 Sep 2022 13:59:26 -0600 Subject: [PATCH 039/146] Flute mode And some odd fixes --- BaseClasses.py | 17 ++++++++-- CLI.py | 2 ++ DoorShuffle.py | 11 ++++--- InitialSram.py | 1 + ItemList.py | 9 ++++-- Items.py | 1 + Main.py | 6 +++- Rom.py | 5 +-- Rules.py | 30 +++++++++--------- data/base2current.bps | Bin 93382 -> 93432 bytes mystery_example.yml | 3 ++ resources/app/cli/args.json | 6 ++++ resources/app/cli/lang/en.json | 5 +++ resources/app/gui/lang/en.json | 12 ++----- resources/app/gui/randomize/item/widgets.json | 13 ++------ source/classes/CustomSettings.py | 2 ++ source/classes/constants.py | 3 +- source/item/FillUtil.py | 3 +- source/tools/MysteryUtils.py | 1 + 19 files changed, 79 insertions(+), 51 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 25cee608..8ff91295 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -895,7 +895,7 @@ class CollectionState(object): 'Golden Sword', 'Progressive Sword', 'Progressive Glove', 'Silver Arrows', 'Green Pendant', 'Blue Pendant', 'Red Pendant', 'Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7', 'Blue Boomerang', 'Red Boomerang', 'Blue Shield', 'Red Shield', - 'Mirror Shield', 'Progressive Shield', 'Bug Catching Net', 'Cane of Byrna', + 'Mirror Shield', 'Progressive Shield', 'Bug Catching Net', 'Cane of Byrna', 'Ocarina (Activated)', 'Boss Heart Container', 'Sanctuary Heart Container', 'Piece of Heart', 'Magic Upgrade (1/2)', 'Magic Upgrade (1/4)'] or item_name.startswith(('Bottle', 'Small Key', 'Big Key')) @@ -1129,8 +1129,11 @@ class CollectionState(object): return self.has('Fire Rod', player) or self.has('Lamp', player) def can_flute(self, player): + if any(map(lambda i: i.name in ['Ocarina', 'Ocarina (Activated)'], self.world.precollected_items)): + return True lw = self.world.get_region('Light World', player) - return self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player) + return self.has('Ocarina (Activated)', player) or (self.has('Ocarina', player) and lw.can_reach(self) + and self.is_not_bunny(lw, player)) def can_melt_things(self, player): return self.has('Fire Rod', player) or (self.has('Bombos', player) and self.has_sword(player)) @@ -2371,6 +2374,7 @@ class Spoiler(object): 'retro': self.world.retro, 'bombbag': self.world.bombbag, 'weapons': self.world.swords, + 'flute_mode': self.world.flute_mode, 'goal': self.world.goal, 'shuffle': self.world.shuffle, 'shuffleganon': self.world.shuffle_ganon, @@ -2569,6 +2573,7 @@ class Spoiler(object): outfile.write(f"Restricted Boss Items: {self.metadata['restricted_boss_items'][player]}\n") outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player]) outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player]) + outfile.write(f"Flute Mode: {self.metadata['flute_mode'][player]}\n") outfile.write(f"Shopsanity: {yn(self.metadata['shopsanity'][player])}\n") outfile.write(f"Bombbag: {yn(self.metadata['bombbag'][player])}\n") outfile.write(f"Pseudoboots: {yn(self.metadata['pseudoboots'][player])}\n") @@ -2873,6 +2878,8 @@ boss_mode = {"none": 0, "simple": 1, "full": 2, "chaos": 3, 'random': 3, 'unique # byte 10: settings_version +# byte 11: F???, ???? (flute_mode) +flute_mode = {'normal': 0, 'active': 1} # additions # psuedoboots does not effect code @@ -2917,7 +2924,9 @@ class Settings(object): (rb_mode[w.restrict_boss_items[p]] << 6) | (algo_mode[w.algorithm] << 3) | (boss_mode[w.boss_shuffle[p]]), - settings_version]) + settings_version, + + flute_mode[w.flute_mode[p]] << 7]) return base64.b64encode(code, "+-".encode()).decode() @staticmethod @@ -2979,6 +2988,8 @@ class Settings(object): args.restrict_boss_items[p] = r(rb_mode)[(settings[9] & 0xC0) >> 6] args.algorithm = r(algo_mode)[(settings[9] & 0x38) >> 3] args.shufflebosses[p] = r(boss_mode)[(settings[9] & 0x07)] + if len(settings) > 11: + args.flute_mode[p] = r(flute_mode)[(settings[11] & 0x80) >> 7] class KeyRuleType(FastEnum): diff --git a/CLI.py b/CLI.py index 987652fd..44c7b76c 100644 --- a/CLI.py +++ b/CLI.py @@ -115,6 +115,7 @@ def parse_cli(argv, no_defaults=False): playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True) for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', + 'flute_mode', 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'usestartinventory', 'bombbag', 'overworld_map', 'restrict_boss_items', @@ -156,6 +157,7 @@ def parse_settings(): "crystals_gt": "7", "crystals_ganon": "7", "swords": "random", + 'flute_mode': 'normal', "difficulty": "normal", "item_functionality": "normal", "timer": "none", diff --git a/DoorShuffle.py b/DoorShuffle.py index 3ced8a44..89463230 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -834,7 +834,7 @@ def main_dungeon_pool(dungeon_pool, world, player): for name in pool: builder = world.dungeon_layouts[player][name] region_set = builder.master_sector.region_set() - builder.bk_required = len(builder.bk_door_proposal) > 0 or any(x in region_set for x in special_bk_regions) + builder.bk_required = builder.bk_door_proposal or any(x in region_set for x in special_bk_regions) dungeon = world.get_dungeon(name, player) if not builder.bk_required or builder.bk_provided: dungeon.big_key = None @@ -1793,7 +1793,7 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player) remaining -= len(custom_trap_doors[dungeon]) ttl += len(builder.candidates.trap) if ttl == 0: - return used_doors + continue for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.trap) @@ -1853,7 +1853,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, remaining -= len(custom_bk_doors[dungeon]) ttl += len(builder.candidates.big) if ttl == 0: - return used_doors + continue for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.big) @@ -2004,7 +2004,7 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, worl remaining_dash -= len(custom_dash_doors[dungeon]) ttl += len(builder.candidates.bomb_dash) if ttl == 0: - return used_doors + continue for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.bomb_dash) @@ -2508,8 +2508,9 @@ def find_small_key_door_candidates(builder, start_regions, used, world, player): def calc_used_dungeon_items(builder, world, player): - base = max(count_reserved_locations(world, player, builder.location_set), 2) basic_flag = world.doorShuffle[player] == 'basic' + base = 0 if basic_flag else 2 # at least 2 items per dungeon, except in basic + base = max(count_reserved_locations(world, player, builder.location_set), base) if not world.bigkeyshuffle[player]: if builder.bk_required and not builder.bk_provided: base += 1 diff --git a/InitialSram.py b/InitialSram.py index 772e1d46..63c822cd 100644 --- a/InitialSram.py +++ b/InitialSram.py @@ -144,6 +144,7 @@ class InitialSram: 'Big Key (Ganons Tower)': (0x366, 0x04), 'Compass (Ganons Tower)': (0x364, 0x04), 'Map (Ganons Tower)': (0x368, 0x04)} set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02),'Pegasus Boots': (0x355, 1, 0x379, 0x04), 'Shovel': (0x34C, 1, 0x38C, 0x04), 'Ocarina': (0x34C, 3, 0x38C, 0x01), + 'Ocarina (Activated)': (0x34C, 3, 0x38C, 0x01), 'Mushroom': (0x344, 1, 0x38C, 0x20 | 0x08), 'Magic Powder': (0x344, 2, 0x38C, 0x10), 'Blue Boomerang': (0x341, 1, 0x38C, 0x80), 'Red Boomerang': (0x341, 2, 0x38C, 0x40)} keys = {'Small Key (Eastern Palace)': [0x37E], 'Small Key (Desert Palace)': [0x37F], diff --git a/ItemList.py b/ItemList.py index f2500e07..1dffb859 100644 --- a/ItemList.py +++ b/ItemList.py @@ -267,7 +267,7 @@ def generate_itempool(world, player): (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray) world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) else: - (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player]) + (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.flute_mode[player] == 'active') if player in world.pool_adjustment.keys() and not skip_pool_adjustments: amt = world.pool_adjustment[player] @@ -789,7 +789,8 @@ def add_pot_contents(world, player): world.itempool.append(ItemFactory(item, player)) -def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic): +def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, + door_shuffle, logic, flute_activated): pool = [] placed_items = {} precollected_items = [] @@ -802,6 +803,10 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, pool.extend(alwaysitems) + if flute_activated: + pool.remove('Ocarina') + pool.append('Ocarina (Activated)') + def place_item(loc, item): assert loc not in placed_items placed_items[loc] = item diff --git a/Items.py b/Items.py index ef88991f..da9d7385 100644 --- a/Items.py +++ b/Items.py @@ -30,6 +30,7 @@ item_table = {'Bow': (True, False, None, 0x0B, 200, 'You have\nchosen the\narche 'Hookshot': (True, False, None, 0x0A, 250, 'BOING!!!\nBOING!!!\nBOING!!!', 'and the tickle beam', 'tickle-monster kid', 'tickle beam for sale', 'witch and tickle boy', 'beam boy tickles again', 'the Hookshot'), 'Magic Mirror': (True, False, None, 0x1A, 250, 'Isn\'t your\nreflection so\npretty?', 'the face reflector', 'the narcissistic kid', 'your face for sale', 'trades looking-glass', 'narcissistic boy is happy again', 'the mirror'), 'Ocarina': (True, False, None, 0x14, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the flute'), + 'Ocarina (Activated)': (True, False, None, 0x4A, 250, 'Save the duck\nand fly to\nfreedom!', 'and the duck call', 'the duck-call kid', 'duck call for sale', 'duck-calls for trade', 'ocarina boy plays again', 'the flute'), 'Pegasus Boots': (True, False, None, 0x4B, 250, 'Gotta go fast!', 'and the sprint shoes', 'the running-man kid', 'sprint shoe for sale', 'shrooms for speed', 'gotta-go-fast boy runs again', 'the boots'), 'Power Glove': (True, False, None, 0x1B, 100, 'Now you can\nlift weak\nstuff!', 'and the grey mittens', 'body-building kid', 'lift glove for sale', 'fungus for gloves', 'body-building boy lifts again', 'the Glove'), 'Cape': (True, False, None, 0x19, 50, 'Wear this to\nbecome\ninvisible!', 'the camouflage cape', 'red riding-hood kid', 'red hood for sale', 'hood from a hood', 'dapper boy hides again', 'the cape'), diff --git a/Main.py b/Main.py index e63a5ec7..1c6cc442 100644 --- a/Main.py +++ b/Main.py @@ -95,6 +95,7 @@ def main(args, seed=None, fish=None): world.keyshuffle = args.keyshuffle.copy() world.bigkeyshuffle = args.bigkeyshuffle.copy() world.bombbag = args.bombbag.copy() + world.flute_mode = args.flute_mode.copy() world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)} world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)} world.crystals_ganon_orig = args.crystals_ganon.copy() @@ -158,7 +159,9 @@ def main(args, seed=None, fish=None): if args.usestartinventory[player]: for tok in filter(None, args.startinventory[player].split(',')): - item = ItemFactory(tok.strip(), player) + name = tok.strip() + name = name if name != 'Ocarina' or world.flute_mode[player] != 'active' else 'Ocarina (Activated)' + item = ItemFactory(name, player) if item: world.push_precollected(item) @@ -451,6 +454,7 @@ def copy_world(world): ret.keyshuffle = world.keyshuffle.copy() ret.bigkeyshuffle = world.bigkeyshuffle.copy() ret.bombbag = world.bombbag.copy() + ret.flute_mode = world.flute_mode.copy() ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy() ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy() ret.crystals_ganon_orig = world.crystals_ganon_orig.copy() diff --git a/Rom.py b/Rom.py index ef640da5..458e24df 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '7b877dcee4ece38713768b74acb333a6' +RANDOMIZERBASEHASH = '0be31dc5cb338e7e85d1ce65e839c99e' class JsonRom(object): @@ -2161,8 +2161,8 @@ def write_strings(rom, world, player, team): while hint_count > 0 and len(items_to_hint) > 0: this_item = items_to_hint.pop(0) this_location = world.find_items_not_key_only(this_item, player) - random.shuffle(this_location) if this_location: + random.shuffle(this_location) item_name = this_location[0].item.hint_text item_name = item_name[0].upper() + item_name[1:] this_hint = f'{item_name} can be found {hint_text(this_location[0])}.' @@ -2847,6 +2847,7 @@ RelevantItems = ['Bow', 'Hookshot', 'Magic Mirror', 'Ocarina', + 'Ocarina (Activated)', 'Pegasus Boots', 'Power Glove', 'Cape', diff --git a/Rules.py b/Rules.py index d12e7341..9d3dad12 100644 --- a/Rules.py +++ b/Rules.py @@ -786,9 +786,9 @@ def default_rules(world, player): set_rule(world.get_entrance('50 Rupee Cave', player), lambda state: state.can_lift_rocks(player)) set_rule(world.get_entrance('Death Mountain Entrance Rock', player), lambda state: state.can_lift_rocks(player)) set_rule(world.get_entrance('Bumper Cave Entrance Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.has('Ocarina', player)) + set_rule(world.get_entrance('Flute Spot 1', player), lambda state: state.can_flute(player)) set_rule(world.get_entrance('Lake Hylia Central Island Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) - set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.has('Ocarina', player) and state.can_lift_heavy_rocks(player)) + set_rule(world.get_entrance('Dark Desert Teleporter', player), lambda state: state.can_flute(player) and state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: ((state.has('Hammer', player) and state.can_lift_rocks(player)) or state.can_lift_heavy_rocks(player)) and state.has_Pearl(player)) # bunny cannot lift bushes @@ -1514,7 +1514,7 @@ def set_big_bomb_rules(world, player): #2. Mirror and Flute and basic routes (can make difference if accessed via insanity or w/ mirror from connector, and then via hyrule castle gate, because no gloves are needed in that case) #3. Go to south DW and then cross peg bridge: Need Mitts and hammer and moon pearl # -> (Mitts and CPB) or (((G or Flute) and M) and BR)) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or (((state.can_lift_rocks(player) or state.has('Ocarina', player)) and state.has_Mirror(player)) and basic_routes(state))) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and cross_peg_bridge(state)) or (((state.can_lift_rocks(player) or state.can_flute(player)) and state.has_Mirror(player)) and basic_routes(state))) elif bombshop_entrance.name in Southern_DW_entrances: #1. Mirror and enter via gate: Need mirror and Aga1 #2. cross peg bridge: Need hammer and moon pearl @@ -1523,52 +1523,52 @@ def set_big_bomb_rules(world, player): elif bombshop_entrance.name in Isolated_DW_entrances: # 1. mirror then flute then basic routes # -> M and Flute and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.has('Ocarina', player) and basic_routes(state)) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) and state.can_flute(player) and basic_routes(state)) elif bombshop_entrance.name in Isolated_LW_entrances: # 1. flute then basic routes # Prexisting mirror spot is not permitted, because mirror might have been needed to reach these isolated locations. # -> Flute and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and basic_routes(state)) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and basic_routes(state)) elif bombshop_entrance.name in West_LW_DM_entrances: # 1. flute then basic routes or mirror # Prexisting mirror spot is permitted, because flute can be used to reach west DM directly. # -> Flute and (M or BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and (state.has_Mirror(player) or basic_routes(state))) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and (state.has_Mirror(player) or basic_routes(state))) elif bombshop_entrance.name in East_LW_DM_entrances: # 1. flute then basic routes or mirror and hookshot # Prexisting mirror spot is permitted, because flute can be used to reach west DM directly and then east DM via Hookshot # -> Flute and ((M and Hookshot) or BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and ((state.has_Mirror(player) and state.has('Hookshot', player)) or basic_routes(state))) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and ((state.has_Mirror(player) and state.has('Hookshot', player)) or basic_routes(state))) elif bombshop_entrance.name == 'Fairy Ascension Cave (Bottom)': # Same as East_LW_DM_entrances except navigation without BR requires Mitts # -> Flute and ((M and Hookshot and Mitts) or BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has('Ocarina', player) and ((state.has_Mirror(player) and state.has('Hookshot', player) and state.can_lift_heavy_rocks(player)) or basic_routes(state))) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_flute(player) and ((state.has_Mirror(player) and state.has('Hookshot', player) and state.can_lift_heavy_rocks(player)) or basic_routes(state))) elif bombshop_entrance.name in Castle_ledge_entrances: # 1. mirror on pyramid to castle ledge, grab bomb, return through mirror spot: Needs mirror # 2. flute then basic routes # -> M or (Flute and BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) or (state.has('Ocarina', player) and basic_routes(state))) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.has_Mirror(player) or (state.can_flute(player) and basic_routes(state))) elif bombshop_entrance.name in Desert_mirrorable_ledge_entrances: # Cases when you have mire access: Mirror to reach locations, return via mirror spot, move to center of desert, mirror anagin and: # 1. Have mire access, Mirror to reach locations, return via mirror spot, move to center of desert, mirror again and then basic routes # 2. flute then basic routes # -> (Mire access and M) or Flute) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has_Mirror(player)) or state.has('Ocarina', player)) and basic_routes(state)) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: ((state.can_reach('Dark Desert', 'Region', player) and state.has_Mirror(player)) or state.can_flute(player)) and basic_routes(state)) elif bombshop_entrance.name == 'Old Man Cave (West)': # 1. Lift rock then basic_routes # 2. flute then basic_routes # -> (Flute or G) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Ocarina', player) or state.can_lift_rocks(player)) and basic_routes(state)) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or state.can_lift_rocks(player)) and basic_routes(state)) elif bombshop_entrance.name == 'Graveyard Cave': # 1. flute then basic routes # 2. (has west dark world access) use existing mirror spot (required Pearl), mirror again off ledge # -> (Flute or (M and P and West Dark World access) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Ocarina', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state)) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state)) elif bombshop_entrance.name in Mirror_from_SDW_entrances: # 1. flute then basic routes # 2. (has South dark world access) use existing mirror spot, mirror again off ledge # -> (Flute or (M and South Dark World access) and BR - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Ocarina', player) or (state.can_reach('South Dark World', 'Region', player) and state.has_Mirror(player))) and basic_routes(state)) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_flute(player) or (state.can_reach('South Dark World', 'Region', player) and state.has_Mirror(player))) and basic_routes(state)) elif bombshop_entrance.name == 'Dark World Potion Shop': # 1. walk down by lifting rock: needs gloves and pearl` # 2. walk down by hammering peg: needs hammer and pearl @@ -1580,11 +1580,11 @@ def set_big_bomb_rules(world, player): # (because otherwise mirror was used to reach the grave, so would cancel a pre-existing mirror spot) # to account for insanity, must consider a way to escape without a cave for basic_routes # -> (M and Mitts) or ((Mitts or Flute or (M and P and West Dark World access)) and BR) - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.has('Ocarina', player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has_Mirror(player)) or ((state.can_lift_heavy_rocks(player) or state.can_flute(player) or (state.can_reach('West Dark World', 'Region', player) and state.has_Pearl(player) and state.has_Mirror(player))) and basic_routes(state))) elif bombshop_entrance.name == 'Waterfall of Wishing': # same as the Normal_LW_entrances case except in insanity it's possible you could be here without Flippers which # means you need an escape route of either Flippers or Flute - add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.has('Ocarina', player)) and (basic_routes(state) or state.has_Mirror(player))) + add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)) and (basic_routes(state) or state.has_Mirror(player))) def set_inverted_big_bomb_rules(world, player): diff --git a/data/base2current.bps b/data/base2current.bps index 2137836da0324c77a1c4a6f9b2adf4d3e253c105..9740c94d9fb0f54c63443282dd8a82eff36b7240 100644 GIT binary patch delta 2139 zcmW-iYgAKL7RPgLo`m;1C}6l~LBtWO1Bg;1j}|2$RjP~zWYrfEbs?fW4fh5k1`=Yj z4Jky(EstVES8&~Bu_Fvtd}X>iO;sunXQt{X8m$CsGmf*ynd^M{|IYrh&)NUI_c}Kx zxNj!714W4AvBOQl=cpd#z$5f6x(_|rcW4aC*itkE!|dmn@ELuU!$Ih4xWHZGw|AU! zI!jK%;h5%yDkEME|KeWspPiy!s#iayMC9NG)pa%ZDO}-Y27djNN>Fy-i9M7HD|W`K zw0I!|@-vVP3i!?FG5mwS1Y7g~`~}+h*-2_Ysl~Zd)PNTMPg75p$%qfBdz?jN}?}d%pjbH24KE0Tp*sNp0#GCkg!&`!b3GhIr9iT zeg$fU(SmFj6;B#*J$xlx>ciZKPrRf~wRJLweeh8D0eS@j&!muXy=)a@N}1A#mp)<4 zId9f!@d3#791ZP|oxR)R#5azc(wAF$RF0;6!s3%+0kKy+x=QDGtze@+(WLJk_Oi#b z=G3aT?#Q^t%W9lGHyX}qtsqqRUo5=>wH9w^>5-5m@l20jwo%2`2M^L@pbLf8{gvW0 z=<%G%9%lyQ9uwv{HUD)qAB=ae&+d?<6l zNJtFoqNhWQANY(sp^8OKYL}e~YE<_@Q|i8r-!oNt5o*B%HK2YqPL(xj@zx&d9+ZdA z)iK5X?foQ_F^?QJC6i@@;h;!ea7KN@PE`@QDxKhrnsH0gr@myTSQ@6a4F_dDHt4oBK+2IQEG7pEk3{qTJ~1QwR`n1Xj}-9|Bu`*|47@l}=ec;w&N+or#j@3t z3D?99-X)fJ=B2!sC60e3ACZhI@cwt01ugmwsuJC1l;j3hlH2UTP{7cip&!FAh9ZVh z48;r=GmK@poM8gPRSc6Eu45=ka+{X!@t*APbFrl}FKsSU$}af1z730i1+_%H&!I%O z_6wr4*T5nySt)Rd*d~nL^hhf^|CVo7Kp43OTP1<5WaP&OXU}!o&On~j-PL1DmAX|2 zXWKhfkHqHu^=?(bB|}61_C2JrxR=$(8leM9N!7Ikb9$~@b#>PK)q6QhUNvDkaD|M- z{_q;6NL;kRO;%czWTj4NiE-=p|2DI?@ZHvz+lnAqc_w6m2k}h?Gk95##PZ%iEh|bU z&L$7TE#*p&^j|gwJ>LAol0KT#Ao2A%^pqlku8D1Rw9j$1lHO$aZn5uYpEq}itQbqD z$g77>??L>~X+fcfhCFU5_JG?%k%GfQ4SCXXR7k%X;$u;rf=!_6;=sj=4*tsoM*DJ9P2aK)vUy0VvE*gb$G@jIo`Q9R-p|f)cy=G7 zm))6UW1B?a`BUuXh!v!+u9hI<-d5F)8J1K(hTJ#}Dep=tHt+i&L^ZA zBSI%XWw&-`RcJc6w#GSy+$uH)R%k9{P70c{`+J)fOI%5&?fLYHpNhjgcZL%BP=~i| zsU?7(oe9BsI~TQ>ieqW-xehO0avlK^1wHWYf-kBt75Si#Fki)Brw_{Fb61vMx09IC$n delta 2082 zcmWmEeN+=y769U zgb=PF3lTE~B1Y8UnL~A}tP1rb+qEZKYgOFs?$Q-COEut1TRdxb`p^BH_s@Or-TU7C z`2qjN1O9L^;<@VmkHCjWg_go3x`u2pfPIAqp`5Eg?J&xHiv8^|bBf19=qQ}!Cy5j8 z(=J!(Q8*OQ7DgHIO!$R=e&P5-dRnt!ik6TU-l4wK+BB4OghDPAuf)&_L4`HED7d<{fA0T!3y$O0)hySm2Aj4$DFKY%|E^)gK zSF{cM*ML8INW0`M23!Jv7Pbq%chdw9FNa;8@*wnp786Fi^Bzrb_YmFq?FY1*=gK>x z!*{?Jo@@NO>P0;{-K1Df=O{+gA#OUFG~&C#Dq88o?uidg(;eOAGc>*t{wWGaS3%$v?_1Jr#FHMebva|! z>u@#Xd5!xT3Qye`aNVMut$Bo{paoWWN25+=r*|wDbufD0Z@8;QX3WVo-Tl(2mWvdA z_vR8_S0zE=w1pOGba-?7fSe?WCkFhYoi6$ELKM^C=SG3s{!a6n4S3eXfGdry7rV@1 zFSQL!{spKQ-2PXkkDt&yiv|yWY+4fhsm8@tP;Dq&`;>M?lK(0kgRcW3P$e@LU<~&$ zJfce^ts1w3Ueuzgh3@3CYzy05Z$dM1pB~m+y-%07>hP`s`dg?7o^4PY@!{WkU(Oy< zZ`weX6P*Vonu6n+>khhx(AVgN$2Dwq`3`S4k|^!hnHUY>6m+dm`3Lw_MR28iG>}{s z>dX17(c0=Do!+LPW_^sMi^7YKmi1ZzO)!C;}j*HW{sghT82Y9GtaLC;(p7euizDffIFE zeDIqK#)uwlURL7f)|ME6;zM1 zk7HMnF=H~P#|TGuZCYvN$X@@bydocO!iQdC7WC#z2#%XGzZo|NVXP}zqgmIpu47GR zO=3-FO=HbsRj|Itn#WqiTFAPWbx+)!DR=LJiC(drtGG68cbkfLgCEh2z5Wr-5z#*W zadWyq5c{p29Kv!S0iF==i?-%Y>I%=y3(Pnu$Rw;N6t*BEXMp%)*RJ2V?Oy?I7N1v!WHn0 zlwyr9z(d%5GStTd>OF}+rm+t$V^XHH`sp~K zg|bXC5a!kEJnNqw_WL2|>+F+Ee6!rwXUh~#EE<#98yKG>nmmT;{A#)Hn%!-^5*xJIF>d`y@i(vn9kNg{Z4St`u-(vn9l?|LzzqXG=KY-HFp@o`|v!9z(cMu}2?{Y8^GCkZ|t zkHK=qjAh)6!afSpLP?O8%z#TqUa1W!OHH-qZB|E)iv0knkE1kIH!{W7i;+io7SW&P z0b@5P(bgT>_9e-L<^3Iyd(*Z!JzHxKQ^CrN=YemKlzrDwg^Hl;+sp|3Zk1t*d}z8Q z#a92GIdMyZ7KUvmjdly0UTiAvOeffRf77uBg)qN3E^s}H6k1EPg8BS5&GU+u69%z^ z=k)3iWj^?3f{Psvgyiocw{KcY>Sgr=88u&1f46f*?GF&OLQ5+95-UvRz_@nO2FVn; zr9bj5QiBnJ6S>^3{;(=-FW=rW+oZI~%%47bMd>9#a^ir z!Vu_OU|(rD$SiXQU>>RA?WUyVOzLc}w?`p6!h%)InK`B^l;{~S=$`J4i Y%1Belg^&PrCtrAG_|o|;hYrL40YqAt`2YX_ diff --git a/mystery_example.yml b/mystery_example.yml index 34ce9963..78b47a95 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -45,6 +45,9 @@ bombbag: on: 1 off: 4 + flute_mode: + normal: 3 + active: 1 entrance_shuffle: none: 15 dungeonssimple: 3 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 6e8d0310..d25f542b 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -42,6 +42,12 @@ "vanilla" ] }, + "flute_mode": { + "choices": [ + "normal", + "active" + ] + }, "goal": { "choices": [ "ganon", diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index 1bfd124a..eab0e34d 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -121,6 +121,11 @@ "Hard: Reduced functionality.", "Expert: Greatly reduced functionality." ], + "flute_mode": [ + "Determine if you need to wake up the bird or not on flute pickup (default: %(default)s)", + "Normal: Normal functionality.", + "Active: Flute is activated on pickup." + ], "timer": [ "Select game timer setting. Affects available itempool. (default: %(default)s)", "None: No timer.", diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index ef9ffd13..5a6e0a9f 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -285,10 +285,9 @@ "randomizer.item.shopsanity": "Shopsanity", - "randomizer.item.itemfunction": "Item Functionality", - "randomizer.item.itemfunction.normal": "Normal", - "randomizer.item.itemfunction.hard": "Hard", - "randomizer.item.itemfunction.expert": "Expert", + "randomizer.item.flute_mode": "Flute Mode", + "randomizer.item.flute_mode.normal": "Normal", + "randomizer.item.flute_mode.active": "Pre-Activated", "randomizer.item.timer": "Timer Setting", "randomizer.item.timer.none": "No Timer", @@ -298,11 +297,6 @@ "randomizer.item.timer.ohko": "OHKO", "randomizer.item.timer.timed-countdown": "Timed Countdown", - "randomizer.item.progressives": "Progressive Items", - "randomizer.item.progressives.on": "On", - "randomizer.item.progressives.off": "Off", - "randomizer.item.progressives.random": "Random", - "randomizer.item.accessibility": "Accessibility", "randomizer.item.accessibility.items": "100% Inventory", "randomizer.item.accessibility.locations": "100% Locations", diff --git a/resources/app/gui/randomize/item/widgets.json b/resources/app/gui/randomize/item/widgets.json index 76537817..b55d6117 100644 --- a/resources/app/gui/randomize/item/widgets.json +++ b/resources/app/gui/randomize/item/widgets.json @@ -78,12 +78,11 @@ "expert" ] }, - "itemfunction": { + "flute_mode": { "type": "selectbox", "options": [ "normal", - "hard", - "expert" + "active" ] }, "timer": { @@ -97,14 +96,6 @@ "timed-countdown" ] }, - "progressives": { - "type": "selectbox", - "options": [ - "on", - "off", - "random" - ] - }, "accessibility": { "type": "selectbox", "options": [ diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 64ef8b3d..82cf0ac9 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -68,6 +68,7 @@ class CustomSettings(object): args.logic[p] = get_setting(settings['logic'], args.logic[p]) args.mode[p] = get_setting(settings['mode'], args.mode[p]) args.swords[p] = get_setting(settings['swords'], args.swords[p]) + args.flute_mode[p] = get_setting(settings['flute_mode'], args.flute_mode[p]) args.item_functionality[p] = get_setting(settings['item_functionality'], args.item_functionality[p]) args.goal[p] = get_setting(settings['goal'], args.goal[p]) args.difficulty[p] = get_setting(settings['difficulty'], args.difficulty[p]) @@ -189,6 +190,7 @@ class CustomSettings(object): settings_dict[p]['logic'] = world.logic[p] settings_dict[p]['mode'] = world.mode[p] settings_dict[p]['swords'] = world.swords[p] + settings_dict[p]['flute_mode'] = world.flute_mode[p] settings_dict[p]['difficulty'] = world.difficulty[p] settings_dict[p]['goal'] = world.goal[p] settings_dict[p]['accessibility'] = world.accessibility[p] diff --git a/source/classes/constants.py b/source/classes/constants.py index 2dccc1fe..3fb8da88 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -67,9 +67,8 @@ SETTINGSTOPROCESS = { "crystals_ganon": "crystals_ganon", "weapons": "swords", "itempool": "difficulty", - "itemfunction": "item_functionality", + "flute_mode": "flute_mode", "timer": "timer", - "progressives": "progressive", "accessibility": "accessibility", "sortingalgo": "algorithm", "beemizer": "beemizer", diff --git a/source/item/FillUtil.py b/source/item/FillUtil.py index 9614eeef..6f60b72e 100644 --- a/source/item/FillUtil.py +++ b/source/item/FillUtil.py @@ -454,6 +454,7 @@ vanilla_mapping = { 'Hookshot': ['Swamp Palace - Big Chest'], 'Magic Mirror': ['Old Man'], 'Ocarina': ['Flute Spot'], + 'Ocarina (Activated)': ['Flute Spot'], 'Pegasus Boots': ['Sahasrahla'], 'Power Glove': ['Desert Palace - Big Chest'], 'Cape': ["King's Tomb"], @@ -779,7 +780,7 @@ major_items = {'Bombos', 'Book of Mudora', 'Cane of Somaria', 'Ether', 'Fire Rod 'Bug Catching Net', 'Cane of Byrna', 'Blue Boomerang', 'Red Boomerang', 'Progressive Glove', 'Power Glove', 'Titans Mitts', 'Bottle', 'Bottle (Red Potion)', 'Bottle (Green Potion)', 'Magic Mirror', 'Bottle (Blue Potion)', 'Bottle (Fairy)', 'Bottle (Bee)', 'Bottle (Good Bee)', 'Magic Upgrade (1/2)', - 'Sanctuary Heart Container', 'Boss Heart Container', 'Progressive Shield', + 'Sanctuary Heart Container', 'Boss Heart Container', 'Progressive Shield', 'Ocarina (Activated)', 'Mirror Shield', 'Progressive Armor', 'Blue Mail', 'Red Mail', 'Progressive Sword', 'Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword', 'Bow', 'Silver Arrows', 'Triforce Piece', 'Moon Pearl', 'Progressive Bow', 'Progressive Bow (Alt)'} diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index 5ca41b6d..ae628b7c 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -144,6 +144,7 @@ def roll_settings(weights): }[swords] ret.difficulty = get_choice('item_pool') + ret.flute_mode = get_choice_default('flute_mode', default='normal') ret.item_functionality = get_choice('item_functionality') From 87834986d4f5767b9e0b2bc6c11a196bce74bc78 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 2 Sep 2022 13:09:39 -0600 Subject: [PATCH 040/146] Retro break up of various options --- BaseClasses.py | 71 ++++--- CLI.py | 25 ++- DoorShuffle.py | 14 +- DungeonGenerator.py | 2 +- Dungeons.py | 2 +- Fill.py | 22 ++- InitialSram.py | 4 +- ItemList.py | 179 ++++++++++-------- KeyDoorShuffle.py | 25 +-- Main.py | 9 +- PotShuffle.py | 7 +- Regions.py | 2 +- Rom.py | 36 ++-- Rules.py | 2 +- mystery_example.yml | 18 +- mystery_testsuite.yml | 1 - resources/app/cli/args.json | 22 ++- resources/app/cli/lang/en.json | 15 +- resources/app/gui/lang/en.json | 16 +- .../app/gui/randomize/dungeon/keysanity.json | 1 - .../app/gui/randomize/dungeon/widgets.json | 8 + .../app/gui/randomize/entrando/widgets.json | 8 + resources/app/gui/randomize/item/widgets.json | 9 + source/classes/CustomSettings.py | 5 +- source/classes/constants.py | 2 + source/gui/bottom.py | 8 + source/item/FillUtil.py | 21 +- source/tools/MysteryUtils.py | 10 +- 28 files changed, 351 insertions(+), 193 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 8ff91295..a601a3c5 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -22,7 +22,7 @@ from source.dungeon.RoomObject import RoomObject class World(object): def __init__(self, players, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments, - timer, progressive, goal, algorithm, accessibility, shuffle_ganon, retro, custom, customitemarray, hints): + timer, progressive, goal, algorithm, accessibility, shuffle_ganon, custom, customitemarray, hints): self.players = players self.teams = 1 self.shuffle = shuffle.copy() @@ -64,7 +64,6 @@ class World(object): self.fix_trock_exit = {} self.shuffle_ganon = shuffle_ganon self.fix_gtower_exit = self.shuffle_ganon - self.retro = retro.copy() self.custom = custom self.customitemarray = customitemarray self.can_take_damage = True @@ -91,10 +90,6 @@ class World(object): self.pot_contents = {} for player in range(1, players + 1): - # If World State is Retro, set to Open and set Retro flag - if self.mode[player] == "retro": - self.mode[player] = "open" - self.retro[player] = True def set_player_attr(attr, val): self.__dict__.setdefault(attr, {})[player] = val set_player_attr('_region_cache', {}) @@ -118,10 +113,12 @@ class World(object): set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'nologic'] or shuffle[player] in ['crossed', 'insanity']) set_player_attr('mapshuffle', False) set_player_attr('compassshuffle', False) - set_player_attr('keyshuffle', False) + set_player_attr('keyshuffle', 'standard') set_player_attr('bigkeyshuffle', False) set_player_attr('restrict_boss_items', 'none') set_player_attr('bombbag', False) + set_player_attr('flute_mode', False) + set_player_attr('bow_mode', False) set_player_attr('difficulty_requirements', None) set_player_attr('boss_shuffle', 'none') set_player_attr('enemy_shuffle', 'none') @@ -134,6 +131,7 @@ class World(object): set_player_attr('crystals_ganon_orig', {}) set_player_attr('crystals_gt_orig', {}) set_player_attr('open_pyramid', False) + set_player_attr('take_any', 'none') set_player_attr('treasure_hunt_icon', 'Triforce Piece') set_player_attr('treasure_hunt_count', 0) set_player_attr('treasure_hunt_total', 0) @@ -154,6 +152,11 @@ class World(object): set_player_attr('exp_cache', defaultdict(dict)) set_player_attr('enabled_entrances', {}) + def finish_init(self): + for player in range(1, self.players + 1): + if self.mode[player] == 'retro': + self.mode[player] == 'open' + def get_name_string_for_object(self, obj): return obj.name if self.players == 1 else f'{obj.name} ({self.get_player_names(obj.player)})' @@ -375,7 +378,8 @@ class World(object): def push_precollected(self, item): item.world = self - if (item.smallkey and self.keyshuffle[item.player]) or (item.bigkey and self.bigkeyshuffle[item.player]): + if ((item.smallkey and self.keyshuffle[item.player] != 'none') + or (item.bigkey and self.bigkeyshuffle[item.player])): item.advancement = True self.precollected_items.append(item) self.state.collect(item, True) @@ -587,7 +591,7 @@ class CollectionState(object): if key_logic.sm_doors[door]: self.reached_doors[player].add(key_logic.sm_doors[door].name) if not connection.can_reach(self): - checklist_key = 'Universal' if self.world.retro[player] else dungeon_name + checklist_key = 'Universal' if self.world.keyshuffle[player] == 'universal' else dungeon_name checklist = self.dungeons_to_check[player][checklist_key] checklist[connection.name] = (connection, crystal_state) elif door.name not in self.opened_doors[player]: @@ -759,7 +763,7 @@ class CollectionState(object): return None def set_dungeon_limits(self, player, dungeon_name): - if self.world.retro[player] and self.world.mode[player] == 'standard': + if self.world.keyshuffle[player] == 'universal' and self.world.mode[player] == 'standard': self.dungeon_limits = ['Hyrule Castle', 'Agahnims Tower'] else: self.dungeon_limits = [dungeon_name] @@ -935,7 +939,7 @@ class CollectionState(object): checked_locations = 0 while new_locations: reachable_events = [location for location in locations if location.event and - (not key_only or (not self.world.keyshuffle[location.item.player] and location.item.smallkey) or (not self.world.bigkeyshuffle[location.item.player] and location.item.bigkey)) + (not key_only or (self.world.keyshuffle[location.item.player] == 'none' and location.item.smallkey) or (not self.world.bigkeyshuffle[location.item.player] and location.item.bigkey)) and location.can_reach(self)] reachable_events = self._do_not_flood_the_keys(reachable_events) for event in reachable_events: @@ -995,7 +999,7 @@ class CollectionState(object): return self.prog_items[item, player] >= count def has_sm_key(self, item, player, count=1): - if self.world.retro[player]: + if self.world.keyshuffle[player] == 'universal': if self.world.mode[player] == 'standard' and self.world.doorShuffle[player] == 'vanilla' and item == 'Small Key (Escape)': return True # Cannot access the shop until escape is finished. This is safe because the key is manually placed in make_custom_item_pool return self.can_buy_unlimited('Small Key (Universal)', player) @@ -1091,7 +1095,7 @@ class CollectionState(object): or self.has('Cane of Somaria', player)) def can_shoot_arrows(self, player): - if self.world.retro[player]: + if self.world.bow_mode[player] in ['retro', 'retro_silvers']: #todo: Non-progressive silvers grant wooden arrows, but progressive bows do not. Always require shop arrows to be safe return self.has('Bow', player) and (self.can_buy_unlimited('Single Arrow', player) or self.has('Single Arrow', player)) return self.has('Bow', player) @@ -1373,7 +1377,7 @@ class Region(object): return False def can_fill(self, item): - inside_dungeon_item = ((item.smallkey and not self.world.keyshuffle[item.player]) + inside_dungeon_item = ((item.smallkey and self.world.keyshuffle[item.player] == 'none') or (item.bigkey and not self.world.bigkeyshuffle[item.player]) or (item.map and not self.world.mapshuffle[item.player]) or (item.compass and not self.world.compassshuffle[item.player])) @@ -2239,7 +2243,7 @@ class Item(object): return item_dungeon def is_inside_dungeon_item(self, world): - return ((self.smallkey and not world.keyshuffle[self.player]) + return ((self.smallkey and world.keyshuffle[self.player] == 'none') or (self.bigkey and not world.bigkeyshuffle[self.player]) or (self.compass and not world.compassshuffle[self.player]) or (self.map and not world.mapshuffle[self.player])) @@ -2371,15 +2375,16 @@ class Spoiler(object): self.metadata = {'version': ERVersion, 'logic': self.world.logic, 'mode': self.world.mode, - 'retro': self.world.retro, 'bombbag': self.world.bombbag, 'weapons': self.world.swords, 'flute_mode': self.world.flute_mode, + 'bow_mode': self.world.bow_mode, 'goal': self.world.goal, 'shuffle': self.world.shuffle, 'shuffleganon': self.world.shuffle_ganon, 'shufflelinks': self.world.shufflelinks, 'shuffletavern': self.world.shuffletavern, + 'take_any': self.world.take_any, 'overworld_map': self.world.overworld_map, 'door_shuffle': self.world.doorShuffle, 'intensity': self.world.intensity, @@ -2561,7 +2566,6 @@ class Spoiler(object): outfile.write(f'Settings Code: {self.metadata["code"][player]}\n') outfile.write('Logic: %s\n' % self.metadata['logic'][player]) outfile.write('Mode: %s\n' % self.metadata['mode'][player]) - outfile.write('Retro: %s\n' % ('Yes' if self.metadata['retro'][player] else 'No')) outfile.write('Swords: %s\n' % self.metadata['weapons'][player]) outfile.write('Goal: %s\n' % self.metadata['goal'][player]) if self.metadata['goal'][player] in ['triforcehunt', 'trinity']: @@ -2574,6 +2578,7 @@ class Spoiler(object): outfile.write('Difficulty: %s\n' % self.metadata['item_pool'][player]) outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player]) outfile.write(f"Flute Mode: {self.metadata['flute_mode'][player]}\n") + outfile.write(f"Bow Mode: {self.metadata['bow_mode'][player]}\n") outfile.write(f"Shopsanity: {yn(self.metadata['shopsanity'][player])}\n") outfile.write(f"Bombbag: {yn(self.metadata['bombbag'][player])}\n") outfile.write(f"Pseudoboots: {yn(self.metadata['pseudoboots'][player])}\n") @@ -2583,6 +2588,8 @@ class Spoiler(object): outfile.write(f"Back of Tavern Shuffled: {yn(self.metadata['shuffletavern'][player])}\n") outfile.write(f"GT/Ganon Shuffled: {yn(self.metadata['shuffleganon'])}\n") outfile.write(f"Overworld Map: {self.metadata['overworld_map'][player]}\n") + outfile.write(f"Take Any Caves: {self.metadata['take_any'][player]}\n") + outfile.write(f"Overworld Map: {self.metadata['overworld_map'][player]}\n") if self.metadata['goal'][player] != 'trinity': outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No')) outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player]) @@ -2597,7 +2604,7 @@ class Spoiler(object): outfile.write(f"Pot Shuffle (Legacy): {yn(self.metadata['potshuffle'][player])}\n") outfile.write('Map shuffle: %s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No')) outfile.write('Compass shuffle: %s\n' % ('Yes' if self.metadata['compassshuffle'][player] else 'No')) - outfile.write('Small Key shuffle: %s\n' % ('Yes' if self.metadata['keyshuffle'][player] else 'No')) + outfile.write(f"Small Key shuffle: {self.metadata['keyshuffle'][player]}\n") outfile.write('Big Key shuffle: %s\n' % ('Yes' if self.metadata['bigkeyshuffle'][player] else 'No')) outfile.write('Boss shuffle: %s\n' % self.metadata['boss_shuffle'][player]) outfile.write('Enemy shuffle: %s\n' % self.metadata['enemy_shuffle'][player]) @@ -2835,7 +2842,7 @@ dr_mode = {"basic": 1, "crossed": 2, "vanilla": 0, "partitioned": 3} er_mode = {"vanilla": 0, "simple": 1, "restricted": 2, "full": 3, "crossed": 4, "insanity": 5, 'lite': 8, 'lean': 9, "dungeonsfull": 7, "dungeonssimple": 6} -# byte 1: LLLW WSSR (logic, mode, sword, retro) +# byte 1: LLLW WSS? (logic, mode, sword) logic_mode = {"noglitches": 0, "minorglitches": 1, "nologic": 2, "owglitches": 3, "majorglitches": 4} world_mode = {"open": 0, "standard": 1, "inverted": 2} sword_mode = {"random": 0, "assured": 1, "swordless": 2, "vanilla": 3} @@ -2861,7 +2868,7 @@ counter_mode = {"default": 0, "off": 1, "on": 2, "pickup": 3} # byte 6: CCCC CPAA (crystals ganon, pyramid, access access_mode = {"items": 0, "locations": 1, "none": 2} -# byte 7: BSMC DDEE (big, small, maps, compass, door_type, enemies) +# byte 7: B?MC DDEE (big, ?, maps, compass, door_type, enemies) door_type_mode = {'original': 0, 'big': 1, 'all': 2, 'chaos': 3} enemy_mode = {"none": 0, "shuffled": 1, "chaos": 2, "random": 2, "legacy": 3} @@ -2878,15 +2885,18 @@ boss_mode = {"none": 0, "simple": 1, "full": 2, "chaos": 3, 'random': 3, 'unique # byte 10: settings_version -# byte 11: F???, ???? (flute_mode) +# byte 11: FBBB, TTSS (flute_mode, bow_mode, take_any, small_key_mode) flute_mode = {'normal': 0, 'active': 1} +keyshuffle_mode = {'none': 0, 'wild': 1, 'universal': 2} # reserved 8 modes? +take_any_mode = {'none': 0, 'random': 1, 'fixed': 2} +bow_mode = {'progressive': 0, 'silvers': 1, 'retro': 2, 'retro_silver': 3} # additions # psuedoboots does not effect code # sfx_shuffle and other adjust items does not effect settings code # Bump this when making changes that are not backwards compatible (nearly all of them) -settings_version = 0 +settings_version = 1 class Settings(object): @@ -2897,7 +2907,7 @@ class Settings(object): (dr_mode[w.doorShuffle[p]] << 5) | er_mode[w.shuffle[p]], (logic_mode[w.logic[p]] << 5) | (world_mode[w.mode[p]] << 3) - | (sword_mode[w.swords[p]] << 1) | (1 if w.retro[p] else 0), + | (sword_mode[w.swords[p]] << 1), (goal_mode[w.goal[p]] << 5) | (diff_mode[w.difficulty[p]] << 3) | (func_mode[w.difficulty_adjustments[p]] << 1) | (1 if w.hints[p] else 0), @@ -2915,7 +2925,7 @@ class Settings(object): ((8 if w.crystals_ganon_orig[p] == "random" else int(w.crystals_ganon_orig[p])) << 3) | (0x4 if w.open_pyramid[p] else 0) | access_mode[w.accessibility[p]], - (0x80 if w.bigkeyshuffle[p] else 0) | (0x40 if w.keyshuffle[p] else 0) + (0x80 if w.bigkeyshuffle[p] else 0) | (0x20 if w.mapshuffle[p] else 0) | (0x10 if w.compassshuffle[p] else 0) | (door_type_mode[w.door_type_mode[p]] << 2) | (enemy_mode[w.enemy_shuffle[p]]), @@ -2926,14 +2936,16 @@ class Settings(object): settings_version, - flute_mode[w.flute_mode[p]] << 7]) + (flute_mode[w.flute_mode[p]] << 7 | bow_mode[w.bow_mode[p]] << 4 + | take_any_mode[w.take_any[p]] << 2 | keyshuffle_mode[w.keyshuffle[p]]) + ]) return base64.b64encode(code, "+-".encode()).decode() @staticmethod def adjust_args_from_code(code, player, args): settings, p = base64.b64decode(code.encode(), "+-".encode()), player - if len(settings) < 11: + if len(settings) < 12: raise Exception('Provided code is incompatible with this version') if settings[10] != settings_version: raise Exception('Provided code is incompatible with this version') @@ -2950,7 +2962,7 @@ class Settings(object): args.item_functionality[p] = r(func_mode)[(settings[2] & 0x6) >> 1] args.goal[p] = r(goal_mode)[(settings[2] & 0xE0) >> 5] args.accessibility[p] = r(access_mode)[settings[6] & 0x3] - args.retro[p] = True if settings[1] & 0x01 else False + # args.retro[p] = True if settings[1] & 0x01 else False args.hints[p] = True if settings[2] & 0x01 else False args.shopsanity[p] = True if settings[3] & 0x80 else False args.decoupledoors[p] = True if settings[3] & 0x40 else False @@ -2973,7 +2985,7 @@ class Settings(object): args.openpyramid[p] = True if settings[6] & 0x4 else False args.bigkeyshuffle[p] = True if settings[7] & 0x80 else False - args.keyshuffle[p] = True if settings[7] & 0x40 else False + # args.keyshuffle[p] = True if settings[7] & 0x40 else False args.mapshuffle[p] = True if settings[7] & 0x20 else False args.compassshuffle[p] = True if settings[7] & 0x10 else False args.door_type_mode[p] = r(door_type_mode)[(settings[7] & 0xc) >> 2] @@ -2990,6 +3002,9 @@ class Settings(object): args.shufflebosses[p] = r(boss_mode)[(settings[9] & 0x07)] if len(settings) > 11: args.flute_mode[p] = r(flute_mode)[(settings[11] & 0x80) >> 7] + args.bow_mode[p] = r(bow_mode)[(settings[11] & 0x70) >> 4] + args.take_any[p] = r(take_any_mode)[(settings[11] & 0xC) >> 2] + args.keyshuffle[p] = r(keyshuffle_mode)[settings[11] & 0x3] class KeyRuleType(FastEnum): diff --git a/CLI.py b/CLI.py index 44c7b76c..942bd7f2 100644 --- a/CLI.py +++ b/CLI.py @@ -103,19 +103,28 @@ def parse_cli(argv, no_defaults=False): ret = parser.parse_args(argv) if ret.keysanity: - ret.mapshuffle, ret.compassshuffle, ret.keyshuffle, ret.bigkeyshuffle = [True] * 4 + ret.mapshuffle, ret.compassshuffle, ret.bigkeyshuffle = [True] * 3 + ret.keyshuffle = 'wild' if ret.keydropshuffle: ret.dropshuffle = True ret.pottery = 'keys' if ret.pottery == 'none' else ret.pottery + if ret.retro or ret.mode == 'retro': + if ret.bow_mode == 'progressive': + ret.bow_mode = 'retro' + elif ret.bow_mode == 'silvers': + ret.bow_mode = 'retro_silvers' + ret.take_any = 'random' if ret.take_any == 'none' else ret.take_any + ret.keyshuffle = 'universal' + if player_num: defaults = copy.deepcopy(ret) for player in range(1, player_num + 1): playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True) for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', - 'flute_mode', + 'flute_mode', 'bow_mode', 'take_any', 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'usestartinventory', 'bombbag', 'overworld_map', 'restrict_boss_items', @@ -158,6 +167,7 @@ def parse_settings(): "crystals_ganon": "7", "swords": "random", 'flute_mode': 'normal', + 'bow_mode': 'progressive', "difficulty": "normal", "item_functionality": "normal", "timer": "none", @@ -175,6 +185,7 @@ def parse_settings(): "shufflelinks": False, "shuffletavern": False, "overworld_map": "default", + 'take_any': 'none', "pseudoboots": False, "shuffleenemies": "none", @@ -189,11 +200,11 @@ def parse_settings(): 'pottery': 'none', 'colorizepots': False, 'shufflepots': False, - "mapshuffle": False, - "compassshuffle": False, - "keyshuffle": False, - "bigkeyshuffle": False, - "keysanity": False, + 'mapshuffle': False, + 'compassshuffle': False, + 'keyshuffle': 'none', + 'bigkeyshuffle': False, + 'keysanity': False, "door_shuffle": "basic", "intensity": 2, 'door_type_mode': 'original', diff --git a/DoorShuffle.py b/DoorShuffle.py index 89463230..0d56882e 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -470,7 +470,7 @@ def choose_portals(world, player): for dungeon, info in shuffled_info: outstanding_portals = list(dungeon_portals[dungeon]) hc_flag = std_flag and dungeon == 'Hyrule Castle' - rupee_bow_flag = hc_flag and world.retro[player] # rupee bow + rupee_bow_flag = hc_flag and world.bow_mode[player].startswith('retro') # rupee bow if hc_flag: sanc = world.get_portal('Sanctuary', player) sanc.destination = True @@ -843,7 +843,7 @@ def main_dungeon_pool(dungeon_pool, world, player): all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items)) target_items = 34 - if world.retro[player]: + if world.keyshuffle[player] == 'universal': target_items += 1 if world.dropshuffle[player] else 0 # the hc big key else: target_items += 29 # small keys in chests @@ -1248,7 +1248,7 @@ def cross_dungeon(world, player): assign_cross_keys(dungeon_builders, world, player) all_dungeon_items_cnt = len(list(y for x in world.dungeons if x.player == player for y in x.all_items)) target_items = 34 - if world.retro[player]: + if world.keyshuffle[player] == 'universal': target_items += 1 if world.dropshuffle[player] else 0 # the hc big key else: target_items += 29 # small keys in chests @@ -1336,7 +1336,7 @@ def filter_key_door_pool(pool, selected_custom): def assign_cross_keys(dungeon_builders, world, player): logging.getLogger('').info(world.fish.translate("cli", "cli", "shuffling.keydoors")) start = time.process_time() - if world.retro[player]: + if world.keyshuffle[player] == 'universal': remaining = 29 if world.dropshuffle[player]: remaining += 13 @@ -1424,7 +1424,7 @@ def assign_cross_keys(dungeon_builders, world, player): # Last Step: Adjust Small Key Dungeon Pool for name, builder in dungeon_builders.items(): reassign_key_doors(builder, world, player) - if not world.retro[player]: + if world.keyshuffle[player] != 'universal': log_key_logic(builder.name, world.key_logic[player][builder.name]) actual_chest_keys = max(builder.key_doors_num - builder.key_drop_cnt, 0) dungeon = world.get_dungeon(name, player) @@ -1963,7 +1963,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl # time to re-assign reassign_key_doors(small_map, world, player) for dungeon_name in pool: - if not world.retro[player]: + if world.keyshuffle[player] != 'universal': builder = world.dungeon_layouts[player][dungeon_name] log_key_logic(builder.name, world.key_logic[player][builder.name]) if world.doorShuffle[player] != 'basic': @@ -2470,7 +2470,7 @@ def reassign_big_key_doors(bk_map, world, player): pass # we don't have spiral stairs candidates yet that aren't already key doors elif d.type is DoorType.Normal: change_door_to_big_key(d, world, player) - if not world.decoupledoors[player] and d.dest: + if not world.decoupledoors[player] and d.dest and world.door_type_mode[player] != 'original': if d.dest.type in [DoorType.Normal]: dest_room = world.get_room(d.dest.roomIndex, player) if stateful_door(d.dest, dest_room.kind(d.dest)): diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 4404d53f..445ed9b3 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1355,7 +1355,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge sanc_builder = random.choice(lw_builders) assign_sector(sanc, sanc_builder, candidate_sectors, global_pole) - bow_sectors, retro_std_flag = {}, world.retro[player] and world.mode[player] == 'standard' + bow_sectors, retro_std_flag = {}, world.bow_mode[player].startswith('retro') and world.mode[player] == 'standard' free_location_sectors = {} crystal_switches = {} crystal_barriers = {} diff --git a/Dungeons.py b/Dungeons.py index 59a6a963..9d862b05 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -5,7 +5,7 @@ from Items import ItemFactory def create_dungeons(world, player): def make_dungeon(name, id, default_boss, dungeon_regions, big_key, small_keys, dungeon_items): - dungeon = Dungeon(name, dungeon_regions, big_key, [] if world.retro[player] else small_keys, + dungeon = Dungeon(name, dungeon_regions, big_key, [] if world.keyshuffle[player] == 'universal' else small_keys, dungeon_items, player, id) dungeon.boss = BossFactory(default_boss, player) for region in dungeon.regions: diff --git a/Fill.py b/Fill.py index a8eecc3a..db18996f 100644 --- a/Fill.py +++ b/Fill.py @@ -39,7 +39,8 @@ def fill_dungeons_restrictive(world, shuffled_locations): # with shuffled dungeon items they are distributed as part of the normal item pool for item in world.get_items(): - if (item.smallkey and world.keyshuffle[item.player]) or (item.bigkey and world.bigkeyshuffle[item.player]): + if ((item.smallkey and world.keyshuffle[item.player] != 'none') + or (item.bigkey and world.bigkeyshuffle[item.player])): item.advancement = True elif (item.map and world.mapshuffle[item.player]) or (item.compass and world.compassshuffle[item.player]): item.priority = True @@ -50,7 +51,7 @@ def fill_dungeons_restrictive(world, shuffled_locations): (bigs if i.bigkey else smalls if i.smallkey else others).append(i) unplaced_smalls = list(smalls) for i in world.itempool: - if i.smallkey and world.keyshuffle[i.player]: + if i.smallkey and world.keyshuffle[i.player] != 'none': unplaced_smalls.append(i) def fill(base_state, items, key_pool): @@ -160,7 +161,7 @@ def valid_key_placement(item, location, key_pool, world): if not valid_reserved_placement(item, location, world): return False if ((not item.smallkey and not item.bigkey) or item.player != location.player - or world.retro[item.player] or world.logic[item.player] == 'nologic'): + or world.keyshuffle[item.player] == 'universal' or world.logic[item.player] == 'nologic'): return True dungeon = location.parent_region.dungeon if dungeon: @@ -215,7 +216,7 @@ def track_dungeon_items(item, location, world): def is_dungeon_item(item, world): - return ((item.smallkey and not world.keyshuffle[item.player]) + return ((item.smallkey and world.keyshuffle[item.player] == 'none') or (item.bigkey and not world.bigkeyshuffle[item.player]) or (item.compass and not world.compassshuffle[item.player]) or (item.map and not world.mapshuffle[item.player])) @@ -419,7 +420,8 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None # Make sure the escape small key is placed first in standard with key shuffle to prevent running out of spots # todo: crossed - progitempool.sort(key=lambda item: 1 if item.name == 'Small Key (Escape)' and world.keyshuffle[item.player] and world.mode[item.player] == 'standard' else 0) + progitempool.sort(key=lambda item: 1 if item.name == 'Small Key (Escape)' + and world.keyshuffle[item.player] != 'none' and world.mode[item.player] == 'standard' else 0) key_pool = [x for x in progitempool if x.smallkey] # sort maps and compasses to the back -- this may not be viable in equitable & ambrosia @@ -498,7 +500,7 @@ def ensure_good_pots(world, write_skips=False): else: loc.item = ItemFactory(invalid_location_replacement[loc.item.name], loc.player) # do the arrow retro check - if world.retro[loc.item.player] and loc.item.name in {'Arrows (5)', 'Arrows (10)'}: + if world.bow_mode[loc.item.player].startswith('retro') and loc.item.name in {'Arrows (5)', 'Arrows (10)'}: loc.item = ItemFactory('Rupees (5)', loc.item.player) # don't write out all pots to spoiler if write_skips: @@ -663,7 +665,7 @@ def balance_multiworld_progression(world): candidate_items = collections.defaultdict(set) while True: for location in balancing_sphere: - if location.event and (world.keyshuffle[location.item.player] or not location.item.smallkey) and (world.bigkeyshuffle[location.item.player] or not location.item.bigkey): + if location.event and (world.keyshuffle[location.item.player] != 'none' or not location.item.smallkey) and (world.bigkeyshuffle[location.item.player] or not location.item.bigkey): balancing_state.collect(location.item, True, location) player = location.item.player if player in balancing_players and not location.locked and location.player != player: @@ -738,7 +740,7 @@ def balance_multiworld_progression(world): sphere_locations.add(location) for location in sphere_locations: - if location.event and (world.keyshuffle[location.item.player] or not location.item.smallkey) and (world.bigkeyshuffle[location.item.player] or not location.item.bigkey): + if location.event and (world.keyshuffle[location.item.player] != 'none' or not location.item.smallkey) and (world.bigkeyshuffle[location.item.player] or not location.item.bigkey): state.collect(location.item, True, location) checked_locations |= sphere_locations @@ -812,7 +814,9 @@ def balance_money_progression(world): return True if item.name in ['Progressive Armor', 'Blue Mail', 'Red Mail']: return True - if world.retro[player] and (item.name in ['Single Arrow', 'Small Key (Universal)']): + if world.keyshuffle[player] == 'universal' and item.name == 'Small Key (Universal)': + return True + if world.bow_mode[player].startswith('retro') and item.name == 'Single Arrow': return True if location.name in pay_for_locations: return True diff --git a/InitialSram.py b/InitialSram.py index 63c822cd..8d0ade11 100644 --- a/InitialSram.py +++ b/InitialSram.py @@ -73,7 +73,7 @@ class InitialSram: if startingstate.has('Bow', player): equip[0x340] = 3 if startingstate.has('Silver Arrows', player) else 1 equip[0x38E] |= 0x20 # progressive flag to get the correct hint in all cases - if not world.retro[player]: + if not world.bow_mode[player].startswith('retro'): equip[0x38E] |= 0x80 if startingstate.has('Silver Arrows', player): equip[0x38E] |= 0x40 @@ -188,7 +188,7 @@ class InitialSram: elif item.name in bombs: starting_bombs += bombs[item.name] elif item.name in arrows: - if world.retro[player]: + if world.bow_mode[player].startswith('retro'): equip[0x38E] |= 0x80 starting_arrows = 1 else: diff --git a/ItemList.py b/ItemList.py index 1dffb859..c1981365 100644 --- a/ItemList.py +++ b/ItemList.py @@ -264,10 +264,10 @@ def generate_itempool(world, player): (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = make_customizer_pool(world, player) skip_pool_adjustments = True elif world.custom: - (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray) + (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world, player, world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.bombbag[player], world.customitemarray) world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) else: - (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.flute_mode[player] == 'active') + (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world, player, world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.flute_mode[player] == 'active') if player in world.pool_adjustment.keys() and not skip_pool_adjustments: amt = world.pool_adjustment[player] @@ -295,7 +295,8 @@ def generate_itempool(world, player): if not found_sword and world.swords[player] != 'swordless': found_sword = True possible_weapons.append(item) - if item in ['Progressive Bow', 'Bow'] and not found_bow and not world.retro[player]: + if (item in ['Progressive Bow', 'Bow'] and not found_bow + and not world.bow_mode[player].startswith('retro')): found_bow = True possible_weapons.append(item) if item in ['Hammer', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna']: @@ -349,7 +350,7 @@ def generate_itempool(world, player): world.treasure_hunt_icon[player] = 'Triforce Piece' world.itempool.extend([item for item in get_dungeon_item_pool(world) if item.player == player - and ((item.smallkey and world.keyshuffle[player]) + and ((item.smallkey and world.keyshuffle[player] != 'none') or (item.bigkey and world.bigkeyshuffle[player]) or (item.map and world.mapshuffle[player]) or (item.compass and world.compassshuffle[player]))]) @@ -409,8 +410,9 @@ def generate_itempool(world, player): set_up_shops(world, player) - if world.retro[player]: + if world.take_any[player] != 'none': set_up_take_anys(world, player, skip_pool_adjustments) + if world.keyshuffle[player] == 'universal': if world.dropshuffle[player] and not skip_pool_adjustments: world.itempool += [ItemFactory('Small Key (Universal)', player)] * 13 if world.pottery[player] not in ['none', 'cave'] and not skip_pool_adjustments: @@ -432,6 +434,10 @@ take_any_locations = [ 'Palace of Darkness Hint', 'East Dark World Hint', 'Archery Game', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Dark Desert Hint'] +fixed_take_anys = [ + 'Desert Healer Fairy', 'Swamp Healer Fairy', 'Dark Death Mountain Healer Fairy', + 'Dark Lake Hylia Ledge Healer Fairy', 'Bonk Fairy (Dark)'] + def set_up_take_anys(world, player, skip_adjustments=False): if world.mode[player] == 'inverted': @@ -440,9 +446,12 @@ def set_up_take_anys(world, player, skip_adjustments=False): if 'Archery Game' in take_any_locations: take_any_locations.remove('Archery Game') - take_any_candidates = [x for x in take_any_locations if len(world.get_region(x, player).locations) == 0] - - regions = random.sample(take_any_candidates, 5) + if world.take_any[player] == 'random': + take_any_candidates = [x for x in take_any_locations if len(world.get_region(x, player).locations) == 0] + regions = random.sample(take_any_candidates, 5) + elif world.take_any[player] == 'fixed': + regions = list(fixed_take_anys) + random.shuffle(regions) old_man_take_any = Region("Old Man Sword Cave", RegionType.Cave, 'the sword cave', player) world.regions.append(old_man_take_any) @@ -539,38 +548,47 @@ def fill_prizes(world, attempts=15): def set_up_shops(world, player): - if world.retro[player]: + retro_bow = world.bow_mode[player].startswith('retro') + universal_keys = world.keyshuffle[player] == 'universal' + if retro_bow or universal_keys: if world.shopsanity[player]: - removals = [next(item for item in world.itempool if item.name == 'Arrows (10)' and item.player == player)] - red_pots = [item for item in world.itempool if item.name == 'Red Potion' and item.player == player][:5] - shields_n_hearts = [item for item in world.itempool if item.name in ['Blue Shield', 'Small Heart'] and item.player == player] - removals.extend([item for item in world.itempool if item.name == 'Arrow Upgrade (+5)' and item.player == player]) - removals.extend(red_pots) - removals.extend(random.sample(shields_n_hearts, 5)) + removals = [] + if retro_bow: + removals = [next(item for item in world.itempool if item.name == 'Arrows (10)' and item.player == player)] + removals.extend([item for item in world.itempool if item.name == 'Arrow Upgrade (+5)' and item.player == player]) + shields_n_hearts = [item for item in world.itempool if item.name in ['Blue Shield', 'Small Heart'] and item.player == player] + removals.extend(random.sample(shields_n_hearts, 5)) + if universal_keys: + red_pots = [item for item in world.itempool if item.name == 'Red Potion' and item.player == player][:5] + removals.extend(red_pots) for remove in removals: world.itempool.remove(remove) - for i in range(6): # replace the Arrows (10) and randomly selected hearts/blue shield - arrow_item = ItemFactory('Single Arrow', player) - arrow_item.advancement = True - world.itempool.append(arrow_item) - for i in range(5): # replace the red potions - world.itempool.append(ItemFactory('Small Key (Universal)', player)) - world.itempool.append(ItemFactory('Rupees (50)', player)) # replaces the arrow upgrade + if retro_bow: + for i in range(6): # replace the Arrows (10) and randomly selected hearts/blue shield + arrow_item = ItemFactory('Single Arrow', player) + arrow_item.advancement = True + world.itempool.append(arrow_item) + world.itempool.append(ItemFactory('Rupees (50)', player)) # replaces the arrow upgrade + if universal_keys: + for i in range(5): # replace the red potions + world.itempool.append(ItemFactory('Small Key (Universal)', player)) # TODO: move hard+ mode changes for shields here, utilizing the new shops else: - rss = world.get_region('Red Shield Shop', player).shop - if not rss.locked: - rss.custom = True - rss.add_inventory(2, 'Single Arrow', 80) + if retro_bow: + rss = world.get_region('Red Shield Shop', player).shop + if not rss.locked: + rss.custom = True + rss.add_inventory(2, 'Single Arrow', 80) + rss.locked = True + cap_shop = world.get_region('Capacity Upgrade', player).shop + cap_shop.inventory[1] = None # remove arrow capacity upgrades in retro for shop in random.sample([s for s in world.shops[player] if not s.locked and s.region.player == player], 5): shop.custom = True shop.locked = True - shop.add_inventory(0, 'Single Arrow', 80) - shop.add_inventory(1, 'Small Key (Universal)', 100) - shop.add_inventory(2, 'Bombs (10)', 50) - rss.locked = True - cap_shop = world.get_region('Capacity Upgrade', player).shop - cap_shop.inventory[1] = None # remove arrow capacity upgrades in retro + if retro_bow: + shop.add_inventory(0, 'Single Arrow', 80) + if universal_keys: + shop.add_inventory(1, 'Small Key (Universal)', 100) if world.bombbag[player]: if world.shopsanity[player]: removals = [item for item in world.itempool if item.name == 'Bomb Upgrade (+5)' and item.player == player] @@ -583,10 +601,11 @@ def set_up_shops(world, player): def customize_shops(world, player): - found_bomb_upgrade, found_arrow_upgrade = False, world.retro[player] + retro_bow = world.bow_mode[player].startswith('retro') + found_bomb_upgrade, found_arrow_upgrade = False, retro_bow possible_replacements = [] shops_to_customize = shop_to_location_table.copy() - if world.retro[player]: + if world.take_any[player] != 'none': shops_to_customize.update(retro_shops) for shop_name, loc_list in shops_to_customize.items(): shop = world.get_region(shop_name, player).shop @@ -609,7 +628,7 @@ def customize_shops(world, player): price = 0 else: price = 120 if shop_name == 'Potion Shop' and item.name == 'Red Potion' else item.price - if world.retro[player] and item.name == 'Single Arrow': + if retro_bow and item.name == 'Single Arrow': price = 80 # randomize price shop.add_inventory(idx, item.name, randomize_price(price), max_repeat, player=item.player) @@ -636,7 +655,7 @@ def customize_shops(world, player): if not found_arrow_upgrade and len(possible_replacements) > 0: choices = [] for shop, idx, loc, item in possible_replacements: - if item.name == 'Arrows (10)' or (item.name == 'Single Arrow' and not world.retro[player]): + if item.name == 'Arrows (10)' or (item.name == 'Single Arrow' and not retro_bow): choices.append((shop, idx, loc, item)) if len(choices) > 0: shop, idx, loc, item = random.choice(choices) @@ -780,16 +799,17 @@ rupee_chart = {'Rupee (1)': 1, 'Rupees (5)': 5, 'Rupees (20)': 20, 'Rupees (50)' def add_pot_contents(world, player): + retro_bow = world.bow_mode[player].startswith('retro') for super_tile, pot_list in vanilla_pots.items(): for pot in pot_list: if pot.item not in [PotItem.Hole, PotItem.Key, PotItem.Switch]: if valid_pot_location(pot, world.pot_pool[player], world, player): - item = ('Rupees (5)' if world.retro[player] and pot_items[pot.item] == 'Arrows (5)' + item = ('Rupees (5)' if retro_bow and pot_items[pot.item] == 'Arrows (5)' else pot_items[pot.item]) world.itempool.append(ItemFactory(item, player)) -def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, +def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, bombbag, door_shuffle, logic, flute_activated): pool = [] placed_items = {} @@ -862,7 +882,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, else: pool.extend(diff.basicarmor) - if want_progressives(): + if 'silvers' not in world.bow_mode[player]: pool.extend(['Progressive Bow'] * 2) elif swords != 'swordless': pool.extend(diff.basicbow) @@ -910,13 +930,14 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, if goal in ['pedestal', 'trinity'] and swords != 'vanilla': place_item('Master Sword Pedestal', 'Triforce') - if retro: - pool = [item.replace('Single Arrow','Rupees (5)') for item in pool] - pool = [item.replace('Arrows (10)','Rupees (5)') for item in pool] - pool = [item.replace('Arrow Upgrade (+5)','Rupees (5)') for item in pool] - pool = [item.replace('Arrow Upgrade (+10)','Rupees (5)') for item in pool] + if world.bow_mode[player].startswith('retro'): + pool = [item.replace('Single Arrow', 'Rupees (5)') for item in pool] + pool = [item.replace('Arrows (10)', 'Rupees (5)') for item in pool] + pool = [item.replace('Arrow Upgrade (+5)', 'Rupees (5)') for item in pool] + pool = [item.replace('Arrow Upgrade (+10)', 'Rupees (5)') for item in pool] + if world.keyshuffle[player] == 'universal': pool.extend(diff.retro) - if door_shuffle != 'vanilla': # door shuffle needs more keys for retro + if door_shuffle != 'vanilla': # door shuffle needs more keys for universal keys replace = 'Rupees (20)' if difficulty == 'normal' else 'Rupees (5)' indices = [i for i, x in enumerate(pool) if x == replace] for i in range(0, min(10, len(indices))): @@ -932,7 +953,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) -def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bombbag, customitemarray): +def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer, goal, mode, swords, bombbag, customitemarray): if isinstance(customitemarray,dict) and 1 in customitemarray: customitemarray = customitemarray[1] pool = [] @@ -1014,7 +1035,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s itemtotal = itemtotal + 1 if mode == 'standard': - if retro: + if world.keyshuffle[player] == 'universal': key_location = random.choice(['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross']) place_item(key_location, 'Small Key (Universal)') pool.extend(['Small Key (Universal)'] * max((customitemarray["generickeys"] - 1), 0)) @@ -1028,7 +1049,7 @@ def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, s pool.extend(['Magic Mirror'] * customitemarray["mirror"]) pool.extend(['Moon Pearl'] * customitemarray["pearl"]) - if retro: + if world.keyshuffle[player] == 'universal': itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in Retro Mode if itemtotal < total_items_to_place: nothings = total_items_to_place - itemtotal @@ -1066,7 +1087,7 @@ def make_customizer_pool(world, player): pool.append(random.choice(diff.bottles)) elif item_name.startswith('Small Key') and item_name != 'Small Key (Universal)': d_item = ItemFactory(item_name, player) - if not world.keyshuffle[player]: + if world.keyshuffle[player] == 'none': d_name = d_item.dungeon dungeon = world.get_dungeon(d_name, player) target_amount = max(amount, len(dungeon.small_keys)) @@ -1121,7 +1142,7 @@ def make_customizer_pool(world, player): guaranteed_items = alwaysitems + ['Magic Mirror', 'Moon Pearl'] if world.shopsanity[player]: guaranteed_items.extend(['Blue Potion', 'Green Potion', 'Red Potion']) - if world.retro[player]: + if world.keyshuffle[player] == 'universal': guaranteed_items.append('Small Key (Universal)') for item in guaranteed_items: if item not in pool: @@ -1199,34 +1220,34 @@ def set_default_triforce(goal, custom_goal, custom_total): # A quick test to ensure all combinations generate the correct amount of items. -def test(): - for difficulty in ['normal', 'hard', 'expert']: - for goal in ['ganon', 'triforcehunt', 'pedestal', 'trinity']: - for timer in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown']: - for mode in ['open', 'standard', 'inverted', 'retro']: - for swords in ['random', 'assured', 'swordless', 'vanilla']: - for progressive in ['on', 'off']: - for shuffle in ['full']: - for logic in ['noglitches', 'minorglitches', 'owglitches', 'nologic']: - for retro in [True, False]: - for bombbag in [True, False]: - for door_shuffle in ['basic', 'crossed', 'vanilla']: - out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic) - count = len(out[0]) + len(out[1]) - - correct_count = total_items_to_place - if goal in ['pedestal', 'trinity'] and swords != 'vanilla': - # pedestal goals generate one extra item - correct_count += 1 - if retro: - correct_count += 28 - try: - assert count == correct_count, "expected {0} items but found {1} items for {2}".format(correct_count, count, (progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bombbag)) - except AssertionError as e: - print(e) - -if __name__ == '__main__': - test() +# def test(): +# for difficulty in ['normal', 'hard', 'expert']: +# for goal in ['ganon', 'triforcehunt', 'pedestal', 'trinity']: +# for timer in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown']: +# for mode in ['open', 'standard', 'inverted', 'retro']: +# for swords in ['random', 'assured', 'swordless', 'vanilla']: +# for progressive in ['on', 'off']: +# for shuffle in ['full']: +# for logic in ['noglitches', 'minorglitches', 'owglitches', 'nologic']: +# for retro in [True, False]: +# for bombbag in [True, False]: +# for door_shuffle in ['basic', 'crossed', 'vanilla']: +# out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic) +# count = len(out[0]) + len(out[1]) +# +# correct_count = total_items_to_place +# if goal in ['pedestal', 'trinity'] and swords != 'vanilla': +# # pedestal goals generate one extra item +# correct_count += 1 +# if retro: +# correct_count += 28 +# try: +# assert count == correct_count, "expected {0} items but found {1} items for {2}".format(correct_count, count, (progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bombbag)) +# except AssertionError as e: +# print(e) +# +# if __name__ == '__main__': +# test() def fill_specific_items(world): @@ -1270,7 +1291,7 @@ def fill_specific_items(world): def is_dungeon_item(item, world, player): - return ((item.startswith('Small Key') and not world.keyshuffle[player]) + return ((item.startswith('Small Key') and world.keyshuffle[player] == 'none') or (item.startswith('Big Key') and not world.bigkeyshuffle[player]) or (item.startswith('Compass') and not world.compassshuffle[player]) or (item.startswith('Map') and not world.mapshuffle[player])) diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index 4d501764..9cca37e3 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -158,7 +158,7 @@ class PlacementRule(object): left -= rule_needed return False - def is_satisfiable(self, outside_keys, unplaced_keys, big_key_loc, prize_location, cr_count): + def is_satisfiable(self, outside_keys, wild_keys, unplaced_keys, big_key_loc, prize_location, cr_count): if self.prize_relevance and prize_location: if self.prize_relevance == 'BigBomb': if prize_location.item.name not in ['Crystal 5', 'Crystal 6']: @@ -272,7 +272,7 @@ def analyze_dungeon(key_layout, world, player): key_logic.bk_chests.update(find_big_chest_locations(key_layout.all_chest_locations)) key_logic.bk_chests.update(find_big_key_locked_locations(key_layout.all_chest_locations)) key_logic.prize_location = dungeon_table[key_layout.sector.name].prize - if world.retro[player] and world.mode[player] != 'standard': + if world.keyshuffle[player] == 'universal' and world.mode[player] != 'standard': return original_key_counter = find_counter({}, False, key_layout, False) @@ -923,7 +923,7 @@ def self_lock_possible(counter): def available_chest_small_keys(key_counter, world, player): - if not world.keyshuffle[player] and not world.retro[player]: + if world.keyshuffle[player] == 'none': cnt = 0 for loc in key_counter.free_locations: if key_counter.big_key_opened or '- Big Chest' not in loc.name: @@ -934,7 +934,7 @@ def available_chest_small_keys(key_counter, world, player): def available_chest_small_keys_logic(key_counter, world, player, sm_restricted): - if not world.keyshuffle[player] and not world.retro[player]: + if world.keyshuffle[player] == 'none': cnt = 0 for loc in key_counter.free_locations: if loc not in sm_restricted and (key_counter.big_key_opened or '- Big Chest' not in loc.name): @@ -1446,8 +1446,9 @@ def validate_bk_layout(proposal, builder, start_regions, world, player): # Soft lock stuff def validate_key_layout(key_layout, world, player): - # retro is all good - except for hyrule castle in standard mode - if (world.retro[player] and (world.mode[player] != 'standard' or key_layout.sector.name != 'Hyrule Castle')) or world.logic[player] == 'nologic': + # universal key is all good - except for hyrule castle in standard mode + if world.logic[player] == 'nologic' or (world.keyshuffle[player] == 'universal' and + (world.mode[player] != 'standard' or key_layout.sector.name != 'Hyrule Castle')): return True flat_proposal = key_layout.flat_prop state = ExplorationState(dungeon=key_layout.sector.name) @@ -1575,8 +1576,8 @@ def enough_small_locations(state, avail_small_loc): def determine_prize_lock(key_layout, world, player): - if ((world.retro[player] and (world.mode[player] != 'standard' or key_layout.sector.name != 'Hyrule Castle')) - or world.logic[player] == 'nologic'): + if world.logic[player] == 'nologic' or (world.keyshuffle[player] == 'universal' and + (world.mode[player] != 'standard' or key_layout.sector.name != 'Hyrule Castle')): return # done, doesn't matter what flat_proposal = key_layout.flat_prop state = ExplorationState(dungeon=key_layout.sector.name) @@ -1608,7 +1609,7 @@ def determine_prize_lock(key_layout, world, player): def cnt_avail_small_locations(free_locations, key_only, state, world, player): - if not world.keyshuffle[player] and not world.retro[player]: + if world.keyshuffle[player] == 'none': bk_adj = 1 if state.big_key_opened and not state.big_key_special else 0 avail_chest_keys = min(free_locations - bk_adj, state.key_locations - key_only) return max(0, avail_chest_keys + key_only - state.used_smalls) @@ -1616,7 +1617,7 @@ def cnt_avail_small_locations(free_locations, key_only, state, world, player): def cnt_avail_small_locations_by_ctr(free_locations, counter, layout, world, player): - if not world.keyshuffle[player] and not world.retro[player]: + if world.keyshuffle[player] == 'none': bk_adj = 1 if counter.big_key_opened and not layout.big_key_special else 0 avail_chest_keys = min(free_locations - bk_adj, layout.max_chests) return max(0, avail_chest_keys + len(counter.key_only_locations) - counter.used_keys) @@ -2059,14 +2060,14 @@ def val_rule(rule, skn, allow=False, loc=None, askn=None, setCheck=None): # Soft lock stuff def validate_key_placement(key_layout, world, player): - if world.retro[player] or world.accessibility[player] == 'none': + if world.keyshuffle[player] == 'universal' or world.accessibility[player] == 'none': return True # Can't keylock in retro. Expected if beatable only. max_counter = find_max_counter(key_layout) keys_outside = 0 big_key_outside = False smallkey_name = dungeon_keys[key_layout.sector.name] bigkey_name = dungeon_bigs[key_layout.sector.name] - if world.keyshuffle[player]: + if world.keyshuffle[player] != 'none': keys_outside = key_layout.max_chests - sum(1 for i in max_counter.free_locations if i.item is not None and i.item.name == smallkey_name and i.item.player == player) if world.bigkeyshuffle[player]: max_counter = find_max_counter(key_layout) diff --git a/Main.py b/Main.py index 1c6cc442..b1f94d6b 100644 --- a/Main.py +++ b/Main.py @@ -75,7 +75,7 @@ def main(args, seed=None, fish=None): customized.adjust_args(args) world = World(args.multi, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, - args.accessibility, args.shuffleganon, args.retro, args.custom, args.customitemarray, args.hints) + args.accessibility, args.shuffleganon, args.custom, args.customitemarray, args.hints) world.customizer = customized if customized else None logger = logging.getLogger('') if seed is None: @@ -96,6 +96,7 @@ def main(args, seed=None, fish=None): world.bigkeyshuffle = args.bigkeyshuffle.copy() world.bombbag = args.bombbag.copy() world.flute_mode = args.flute_mode.copy() + world.bow_mode = args.bow_mode.copy() world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)} world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)} world.crystals_ganon_orig = args.crystals_ganon.copy() @@ -124,11 +125,13 @@ def main(args, seed=None, fish=None): world.shuffletavern = args.shuffletavern.copy() world.pseudoboots = args.pseudoboots.copy() world.overworld_map = args.overworld_map.copy() + world.take_any = args.take_any.copy() world.restrict_boss_items = args.restrict_boss_items.copy() world.collection_rate = args.collection_rate.copy() world.colorizepots = args.colorizepots.copy() world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)} + world.finish_init() logger.info( world.fish.translate("cli","cli","app.title") + "\n", @@ -247,7 +250,7 @@ def main(args, seed=None, fish=None): for player in range(1, world.players + 1): if world.shopsanity[player]: sell_potions(world, player) - if world.retro[player]: + if world.keyshuffle[player] == 'universal': sell_keys(world, player) else: lock_shop_locations(world, player) @@ -425,7 +428,7 @@ def copy_world(world): # ToDo: Not good yet ret = World(world.players, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, - world.accessibility, world.shuffle_ganon, world.retro, world.custom, world.customitemarray, world.hints) + world.accessibility, world.shuffle_ganon, world.custom, world.customitemarray, world.hints) ret.teams = world.teams ret.player_names = copy.deepcopy(world.player_names) ret.remote_items = world.remote_items.copy() diff --git a/PotShuffle.py b/PotShuffle.py index 2848dfe8..fd59f6cc 100644 --- a/PotShuffle.py +++ b/PotShuffle.py @@ -879,7 +879,8 @@ def shuffle_pots(world, player): elif old_pot.item == PotItem.Switch: available_pots = (pot for pot in new_pots if (pot.room == old_pot.room or pot.room in movable_switch_rooms[old_pot.room]) and not (pot.flags & PotFlags.NoSwitch)) elif old_pot.item == PotItem.Key: - if world.doorShuffle[player] == 'vanilla' and not world.retro[player] and world.pottery[player] == 'none' and world.logic[player] != 'nologic': + if (world.doorShuffle[player] == 'vanilla' and world.keyshuffle[player] != 'universal' + and world.pottery[player] == 'none' and world.logic[player] != 'nologic'): available_pots = (pot for pot in new_pots if pot.room not in invalid_key_rooms) else: available_pots = new_pots @@ -890,7 +891,7 @@ def shuffle_pots(world, player): new_pot = random.choice(available_pots) new_pot.item = old_pot.item - if world.retro[player] and new_pot.item == PotItem.FiveArrows: + if world.bow_mode[player].startswith('retro') and new_pot.item == PotItem.FiveArrows: new_pot.item = PotItem.FiveRupees if new_pot.item == PotItem.Key: @@ -938,7 +939,7 @@ def shuffle_pot_switches(world, player): new_pot = random.choice(available_pots) new_pot.item, old_pot.item = old_pot.item, new_pot.item - if world.retro[player] and new_pot.item == PotItem.FiveArrows: + if world.bow_mode[player].startswith('retro') and new_pot.item == PotItem.FiveArrows: new_pot.item = PotItem.FiveRupees if new_pot.item == PotItem.Switch and (new_pot.flags & PotFlags.SwitchLogicChange): diff --git a/Regions.py b/Regions.py index d0ff68ab..3e288727 100644 --- a/Regions.py +++ b/Regions.py @@ -1029,7 +1029,7 @@ def adjust_locations(world, player): loc.event = False item_dungeon = key_item.dungeon dungeon = world.get_dungeon(item_dungeon, player) - if key_item.smallkey and not world.retro[player]: + if key_item.smallkey and world.keyshuffle[player] != 'universal': dungeon.small_keys.append(key_item) elif key_item.bigkey: dungeon.big_key = key_item diff --git a/Rom.py b/Rom.py index 458e24df..544f2c5b 100644 --- a/Rom.py +++ b/Rom.py @@ -797,7 +797,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x138002, 2) for name, layout in world.key_layout[player].items(): offset = compass_data[name][4]//2 - if world.retro[player]: + if world.keyshuffle[player] == 'universal': rom.write_byte(0x13f030+offset, layout.max_chests + layout.max_drops) else: rom.write_byte(0x13f020+offset, layout.max_chests + layout.max_drops) # not currently used @@ -898,7 +898,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x142A50, 1) # StandingItemsOn multiClientFlags = ((0x1 if world.dropshuffle[player] else 0) | (0x2 if world.shopsanity[player] else 0) - | (0x4 if world.retro[player] else 0) + | (0x4 if world.take_any[player] != 'none' else 0) | (0x8 if world.pottery[player] != 'none' else 0) | (0x10 if is_mystery else 0)) rom.write_byte(0x142A51, multiClientFlags) @@ -1112,7 +1112,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): prizes = [prize_replacements.get(prize, prize) for prize in prizes] dig_prizes = [prize_replacements.get(prize, prize) for prize in dig_prizes] - if world.retro[player]: + if world.bow_mode[player].startswith('retro'): prize_replacements = {0xE1: 0xDA, #5 Arrows -> Blue Rupee 0xE2: 0xDB} #10 Arrows -> Red Rupee prizes = [prize_replacements.get(prize, prize) for prize in prizes] @@ -1155,7 +1155,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): 0x12, 0x01, 0x35, 0xFF, # lamp -> 5 rupees 0x51, 0x00 if world.bombbag[player] else 0x06, 0x31 if world.bombbag[player] else 0x52, 0xFF, # 6 +5 bomb upgrades -> +10 bomb upgrade. If bombbag -> turns into Bombs (10) 0x53, 0x06, 0x54, 0xFF, # 6 +5 arrow upgrades -> +10 arrow upgrade - 0x58, 0x01, 0x36 if world.retro[player] else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode) + 0x58, 0x01, 0x36 if world.bow_mode[player].startswith('retro') else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode) 0x3E, difficulty.boss_heart_container_limit, 0x47, 0xff, # boss heart -> green 20 0x17, difficulty.heart_piece_limit, 0x47, 0xff, # piece of heart -> green 20 0xFF, 0xFF, 0xFF, 0xFF, # end of table sentinel @@ -1204,7 +1204,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): ERtimeincrease = 10 else: ERtimeincrease = 20 - if world.keyshuffle[player] or world.bigkeyshuffle[player] or world.mapshuffle[player]: + if world.keyshuffle[player] != 'none' or world.bigkeyshuffle[player] or world.mapshuffle[player]: ERtimeincrease = ERtimeincrease + 15 if world.clock_mode == 'none': rom.write_bytes(0x180190, [0x00, 0x00, 0x00]) # turn off clock mode @@ -1337,7 +1337,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # m - enabled for inside maps # c - enabled for inside compasses # s - enabled for inside small keys - rom.write_byte(0x18016A, 0x10 | ((0x01 if world.keyshuffle[player] else 0x00) + rom.write_byte(0x18016A, 0x10 | ((0x01 if world.keyshuffle[player] == 'wild' else 0x00) | (0x02 if world.compassshuffle[player] else 0x00) | (0x04 if world.mapshuffle[player] else 0x00) | (0x08 if world.bigkeyshuffle[player] else 0x00))) # free roaming item text boxes @@ -1403,7 +1403,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): # a - Small Key # enable_menu_map_check = world.overworld_map[player] != 'default' and world.shuffle[player] != 'none' - rom.write_byte(0x180045, ((0x01 if world.keyshuffle[player] else 0x00) + rom.write_byte(0x180045, ((0x01 if world.keyshuffle[player] == 'wild' else 0x00) | (0x02 if world.bigkeyshuffle[player] else 0x00) | (0x04 if world.mapshuffle[player] or enable_menu_map_check else 0x00) | (0x08 if world.compassshuffle[player] else 0x00))) # free roaming items in menu @@ -1434,17 +1434,17 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): write_int16(rom, 0x18017A, get_reveal_bytes('Green Pendant') if world.mapshuffle[player] else 0x0000) # Sahasrahla reveal write_int16(rom, 0x18017C, get_reveal_bytes('Crystal 5')|get_reveal_bytes('Crystal 6') if world.mapshuffle[player] else 0x0000) # Bomb Shop Reveal - rom.write_byte(0x180172, 0x01 if world.retro[player] else 0x00) # universal keys - rom.write_byte(0x180175, 0x01 if world.retro[player] else 0x00) # rupee bow - rom.write_byte(0x180176, 0x0A if world.retro[player] else 0x00) # wood arrow cost - rom.write_byte(0x180178, 0x32 if world.retro[player] else 0x00) # silver arrow cost - rom.write_byte(0x301FC, 0xDA if world.retro[player] else 0xE1) # rupees replace arrows under pots + rom.write_byte(0x180172, 0x01 if world.keyshuffle[player] == 'universal' else 0x00) # universal keys + rom.write_byte(0x180175, 0x01 if world.bow_mode[player].startswith('retro') else 0x00) # rupee bow + rom.write_byte(0x180176, 0x0A if world.bow_mode[player].startswith('retro') else 0x00) # wood arrow cost + rom.write_byte(0x180178, 0x32 if world.bow_mode[player].startswith('retro') else 0x00) # silver arrow cost + rom.write_byte(0x301FC, 0xDA if world.bow_mode[player].startswith('retro') else 0xE1) # rupees replace arrows under pots if enemized: - rom.write_byte(0x1B152e, 0xDA if world.retro[player] else 0xE1) - rom.write_byte(0x30052, 0xDB if world.retro[player] else 0xE2) # replace arrows in fish prize from bottle merchant - rom.write_bytes(0xECB4E, [0xA9, 0x00, 0xEA, 0xEA] if world.retro[player] else [0xAF, 0x77, 0xF3, 0x7E]) # Thief steals rupees instead of arrows - rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if world.retro[player] else [0xAF, 0x77, 0xF3, 0x7E]) # Pikit steals rupees instead of arrows - rom.write_bytes(0xEDA5, [0x35, 0x41] if world.retro[player] else [0x43, 0x44]) # Chest game gives rupees instead of arrows + rom.write_byte(0x1B152e, 0xDA if world.bow_mode[player].startswith('retro') else 0xE1) + rom.write_byte(0x30052, 0xDB if world.bow_mode[player].startswith('retro') else 0xE2) # replace arrows in fish prize from bottle merchant + rom.write_bytes(0xECB4E, [0xA9, 0x00, 0xEA, 0xEA] if world.bow_mode[player].startswith('retro') else [0xAF, 0x77, 0xF3, 0x7E]) # Thief steals rupees instead of arrows + rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if world.bow_mode[player].startswith('retro') else [0xAF, 0x77, 0xF3, 0x7E]) # Pikit steals rupees instead of arrows + rom.write_bytes(0xEDA5, [0x35, 0x41] if world.bow_mode[player].startswith('retro') else [0x43, 0x44]) # Chest game gives rupees instead of arrows digging_game_rng = random.randint(1, 30) # set rng for digging game rom.write_byte(0x180020, digging_game_rng) rom.write_byte(0xEFD95, digging_game_rng) @@ -2151,7 +2151,7 @@ def write_strings(rom, world, player, team): # It is done the way it is to re-use the silver code and also to give one hint per each type of item regardless # of how many exist. This supports many settings well. items_to_hint = RelevantItems.copy() - if world.keyshuffle[player]: + if world.keyshuffle[player] == 'wild': items_to_hint.extend(SmallKeys) if world.bigkeyshuffle[player]: items_to_hint.extend(BigKeys) diff --git a/Rules.py b/Rules.py index 9d3dad12..5bd27023 100644 --- a/Rules.py +++ b/Rules.py @@ -2072,7 +2072,7 @@ def add_key_logic_rules(world, player): add_rule(big_chest, create_rule(d_logic.bk_name, player)) if len(d_logic.bk_doors) == 0 and len(d_logic.bk_chests) <= 1: set_always_allow(big_chest, allow_big_key_in_big_chest(d_logic.bk_name, player)) - if world.retro[player]: + if world.keyshuffle[player] == 'universal': for d_name, layout in world.key_layout[player].items(): for door in layout.flat_prop: if world.mode[player] != 'standard' or not retro_in_hc(door.entrance): diff --git a/mystery_example.yml b/mystery_example.yml index 78b47a95..26fb559f 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -48,6 +48,11 @@ flute_mode: normal: 3 active: 1 + bow_mode: + progressive: 5 + silvers: 5 + retro: 1 + retro_silvers: 1 entrance_shuffle: none: 15 dungeonssimple: 3 @@ -66,9 +71,10 @@ open: 1 inverted: 1 retro: 0 - retro: - on: 1 - off: 4 + take_any: + random: 1 + fixed: 3 + none: 16 goals: ganon: 2 fast_ganon: 2 @@ -86,6 +92,12 @@ mc: 3 mcs: 2 full: 5 + mcu: 1 # map, compass, universal smalls +# for use when you aren't using the dungeon_items above +# smallkey_shuffle: +# standard: 5 +# wild: 1 +# universal: 1 dungeon_counters: on: 5 off: 0 diff --git a/mystery_testsuite.yml b/mystery_testsuite.yml index 364806e6..aca535c3 100644 --- a/mystery_testsuite.yml +++ b/mystery_testsuite.yml @@ -50,7 +50,6 @@ world_state: standard: 1 open: 1 inverted: 1 - retro: 0 retro: on: 1 off: 1 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index d25f542b..0074143d 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -48,6 +48,14 @@ "active" ] }, + "bow_mode": { + "choices": [ + "progressive", + "silvers", + "retro", + "retro_silvers" + ] + }, "goal": { "choices": [ "ganon", @@ -266,8 +274,11 @@ "type": "bool" }, "keyshuffle": { - "action": "store_true", - "type": "bool" + "choices": [ + "none", + "wild", + "universal" + ] }, "bigkeyshuffle": { "action": "store_true", @@ -286,6 +297,13 @@ "action": "store_true", "type": "bool" }, + "take_any": { + "choices": [ + "none", + "random", + "fixed" + ] + }, "startinventory": {}, "usestartinventory": { "type": "bool" diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index eab0e34d..a6dcc3ee 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -122,10 +122,17 @@ "Expert: Greatly reduced functionality." ], "flute_mode": [ - "Determine if you need to wake up the bird or not on flute pickup (default: %(default)s)", + "Determines if you need to wake up the bird or not on flute pickup (default: %(default)s)", "Normal: Normal functionality.", "Active: Flute is activated on pickup." ], + "bow_mode": [ + "Determines how the bow acts in the pool (default: %(default)s)", + "Progressive: Two progressive bows placed. First picked up is the bow. Second is silvers.", + "Silvers Separate: Bow and silvers are completely separate items.", + "Retro: Z1 Bow where arrows cost money and the Single Arrow must be bought or found to shoot", + "Retro + Silvers: Bow and silvers are completely separate items." + ], "timer": [ "Select game timer setting. Affects available itempool. (default: %(default)s)", "None: No timer.", @@ -300,6 +307,12 @@ "Keys are universal, shooting arrows costs rupees,", "and a few other little things make this more like Zelda-1. (default: %(default)s)" ], + "take_any": [ + "Take Any caves from Zelda 1 (default: %(default)s)", + "None: No take any caves", + "Random: Take any caves can replace a random set of un-interesting caves. See documentation for full list", + "Fixed: Take any caves will replace certain location. See documentation for full list" + ], "pseudoboots": [ " Players starts with pseudo boots that allow dashing but no item checks (default: %(default)s"], "bombbag": ["Start with 0 bomb capacity. Two capacity upgrades (+10) are added to the pool (default: %(default)s)" ], "startinventory": [ "Specifies a list of items that will be in your starting inventory (separated by commas). (default: %(default)s)" ], diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 5a6e0a9f..9c7f9dfa 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -53,6 +53,9 @@ "randomizer.dungeon.mapshuffle": "Maps", "randomizer.dungeon.compassshuffle": "Compasses", "randomizer.dungeon.smallkeyshuffle": "Small Keys", + "randomizer.dungeon.smallkeyshuffle.standard": "In Dungeon", + "randomizer.dungeon.smallkeyshuffle.wild": "Randomized", + "randomizer.dungeon.smallkeyshuffle.universal": "Universal", "randomizer.dungeon.bigkeyshuffle": "Big Keys", "randomizer.dungeon.keydropshuffle": "Key Drop Shuffle (Legacy)", "randomizer.dungeon.decoupledoors": "Decouple Doors", @@ -155,7 +158,10 @@ "randomizer.entrance.entranceshuffle.dungeonsfull": "Dungeons + Full", "randomizer.entrance.entranceshuffle.dungeonssimple": "Dungeons + Simple", - + "randomizer.entrance.take_any": "Take Any Caves", + "randomizer.entrance.take_any.none": "None", + "randomizer.entrance.take_any.random": "Random", + "randomizer.entrance.take_any.fixed": "Fixed", "randomizer.gameoptions.nobgm": "Disable Music & MSU-1", "randomizer.gameoptions.quickswap": "L/R Quickswapping", @@ -219,7 +225,7 @@ "randomizer.generation.rom.dialog.allfiles": "All Files", "randomizer.item.hints": "Include Helpful Hints", - "randomizer.item.retro": "Retro mode (universal keys)", + "randomizer.item.retro": "Retro mode", "randomizer.item.pseudoboots": "Start with Pseudo Boots", "randomizer.item.bombbag": "Bombbag", @@ -289,6 +295,12 @@ "randomizer.item.flute_mode.normal": "Normal", "randomizer.item.flute_mode.active": "Pre-Activated", + "randomizer.item.bow_mode": "Bow Mode", + "randomizer.item.bow_mode.progressive": "Progressive", + "randomizer.item.bow_mode.silvers": "Silvers Separate", + "randomizer.item.bow_mode.retro": "Retro (Progressive)", + "randomizer.item.bow_mode.retro_silvers": "Retro + Silvers", + "randomizer.item.timer": "Timer Setting", "randomizer.item.timer.none": "No Timer", "randomizer.item.timer.display": "Stopwatch", diff --git a/resources/app/gui/randomize/dungeon/keysanity.json b/resources/app/gui/randomize/dungeon/keysanity.json index 49a17237..ffd9bc92 100644 --- a/resources/app/gui/randomize/dungeon/keysanity.json +++ b/resources/app/gui/randomize/dungeon/keysanity.json @@ -2,7 +2,6 @@ "keysanity": { "mapshuffle": { "type": "checkbox" }, "compassshuffle": { "type": "checkbox" }, - "smallkeyshuffle": { "type": "checkbox" }, "bigkeyshuffle": { "type": "checkbox" } } } diff --git a/resources/app/gui/randomize/dungeon/widgets.json b/resources/app/gui/randomize/dungeon/widgets.json index df7d3474..02a7f262 100644 --- a/resources/app/gui/randomize/dungeon/widgets.json +++ b/resources/app/gui/randomize/dungeon/widgets.json @@ -1,5 +1,13 @@ { "widgets": { + "keyshuffle": { + "type": "selectbox", + "options": [ + "standard", + "wild", + "universal" + ] + }, "dungeondoorshuffle": { "type": "selectbox", "default": "basic", diff --git a/resources/app/gui/randomize/entrando/widgets.json b/resources/app/gui/randomize/entrando/widgets.json index b4c6698c..a136de91 100644 --- a/resources/app/gui/randomize/entrando/widgets.json +++ b/resources/app/gui/randomize/entrando/widgets.json @@ -29,6 +29,14 @@ "config": { "width": 45 } + }, + "take_any": { + "type": "selectbox", + "options": [ + "none", + "random", + "fixed" + ] } } } diff --git a/resources/app/gui/randomize/item/widgets.json b/resources/app/gui/randomize/item/widgets.json index b55d6117..88f85858 100644 --- a/resources/app/gui/randomize/item/widgets.json +++ b/resources/app/gui/randomize/item/widgets.json @@ -85,6 +85,15 @@ "active" ] }, + "bow_mode": { + "type": "selectbox", + "options": [ + "progressive", + "silvers", + "retro", + "retro_silvers" + ] + }, "timer": { "type": "selectbox", "options": [ diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 82cf0ac9..08150a77 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -69,11 +69,13 @@ class CustomSettings(object): args.mode[p] = get_setting(settings['mode'], args.mode[p]) args.swords[p] = get_setting(settings['swords'], args.swords[p]) args.flute_mode[p] = get_setting(settings['flute_mode'], args.flute_mode[p]) + args.bow_mode[p] = get_setting(settings['bow_mode'], args.bow_mode[p]) args.item_functionality[p] = get_setting(settings['item_functionality'], args.item_functionality[p]) args.goal[p] = get_setting(settings['goal'], args.goal[p]) args.difficulty[p] = get_setting(settings['difficulty'], args.difficulty[p]) args.accessibility[p] = get_setting(settings['accessibility'], args.accessibility[p]) args.retro[p] = get_setting(settings['retro'], args.retro[p]) + args.take_any[p] = get_setting(settings['take_any'], args.take_any[p]) args.hints[p] = get_setting(settings['hints'], args.hints[p]) args.shopsanity[p] = get_setting(settings['shopsanity'], args.shopsanity[p]) args.dropshuffle[p] = get_setting(settings['dropshuffle'], args.dropshuffle[p]) @@ -191,11 +193,12 @@ class CustomSettings(object): settings_dict[p]['mode'] = world.mode[p] settings_dict[p]['swords'] = world.swords[p] settings_dict[p]['flute_mode'] = world.flute_mode[p] + settings_dict[p]['bow_mode'] = world.bow_mode[p] settings_dict[p]['difficulty'] = world.difficulty[p] settings_dict[p]['goal'] = world.goal[p] settings_dict[p]['accessibility'] = world.accessibility[p] settings_dict[p]['item_functionality'] = world.difficulty_adjustments[p] - settings_dict[p]['retro'] = world.retro[p] + settings_dict[p]['take_any'] = world.take_any[p] settings_dict[p]['hints'] = world.hints[p] settings_dict[p]['shopsanity'] = world.shopsanity[p] settings_dict[p]['dropshuffle'] = world.dropshuffle[p] diff --git a/source/classes/constants.py b/source/classes/constants.py index 3fb8da88..1f801e33 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -68,6 +68,7 @@ SETTINGSTOPROCESS = { "weapons": "swords", "itempool": "difficulty", "flute_mode": "flute_mode", + "bow_mode": "bow_mode", "timer": "timer", "accessibility": "accessibility", "sortingalgo": "algorithm", @@ -81,6 +82,7 @@ SETTINGSTOPROCESS = { "shuffletavern": "shuffletavern", "entranceshuffle": "shuffle", "overworld_map": "overworld_map", + "take_any": "take_any", }, "enemizer": { "enemyshuffle": "shuffleenemies", diff --git a/source/gui/bottom.py b/source/gui/bottom.py index b887e1ac..27a22217 100644 --- a/source/gui/bottom.py +++ b/source/gui/bottom.py @@ -285,4 +285,12 @@ def create_guiargs(parent): guiargs.dropshuffle = 1 guiargs.pottery = 'keys' if guiargs.pottery == 'none' else guiargs.pottery + if guiargs.retro or guiargs.mode == 'retro': + if guiargs.bow_mode == 'progressive': + guiargs.bow_mode = 'retro' + elif guiargs.bow_mode == 'silvers': + guiargs.bow_mode = 'retro_silvers' + guiargs.take_any = 'random' if guiargs.take_any == 'none' else guiargs.take_any + guiargs.keyshuffle = 'universal' + return guiargs diff --git a/source/item/FillUtil.py b/source/item/FillUtil.py index 6f60b72e..8cb74805 100644 --- a/source/item/FillUtil.py +++ b/source/item/FillUtil.py @@ -82,10 +82,11 @@ def create_item_pool_config(world): if world.shopsanity[player]: for item, locs in shop_vanilla_mapping.items(): config.static_placement[player][item].extend(locs) - if world.retro[player]: + if world.take_any[player] != 'none': for item, locs in retro_vanilla_mapping.items(): config.static_placement[player][item].extend(locs) # universal keys + if world.keyshuffle[player] == 'universal': universal_key_locations = [] for item, locs in vanilla_mapping.items(): if 'Small Key' in item: @@ -98,12 +99,13 @@ def create_item_pool_config(world): for item, locs in potkeys_vanilla_mapping.items(): universal_key_locations.extend(locs) if world.shopsanity[player]: - single_arrow_placement = list(shop_vanilla_mapping['Red Potion']) - single_arrow_placement.append('Red Shield Shop - Right') - config.static_placement[player]['Single Arrow'] = single_arrow_placement universal_key_locations.extend(shop_vanilla_mapping['Small Heart']) universal_key_locations.extend(shop_vanilla_mapping['Blue Shield']) config.static_placement[player]['Small Key (Universal)'] = universal_key_locations + if world.bow_mode[player].startswith('retro') and world.shopsanity[player]: + single_arrow_placement = list(shop_vanilla_mapping['Red Potion']) + single_arrow_placement.append('Red Shield Shop - Right') + config.static_placement[player]['Single Arrow'] = single_arrow_placement config.location_groups[player] = [ LocationGroup('Major').locs(mode_grouping['Overworld Major'] + mode_grouping['Big Chests'] + mode_grouping['Heart Containers']), LocationGroup('bkhp').locs(mode_grouping['Heart Pieces']), @@ -124,7 +126,7 @@ def create_item_pool_config(world): groups.locations.extend(mode_grouping['Big Keys']) if world.dropshuffle[player] != 'none': groups.locations.extend(mode_grouping['Big Key Drops']) - if world.keyshuffle[player]: + if world.keyshuffle[player] != 'none': groups.locations.extend(mode_grouping['Small Keys']) if world.dropshuffle[player] != 'none': groups.locations.extend(mode_grouping['Key Drops']) @@ -137,7 +139,7 @@ def create_item_pool_config(world): if world.shopsanity[player]: groups.locations.append('Capacity Upgrade - Left') groups.locations.append('Capacity Upgrade - Right') - if world.retro[player]: + if world.take_any[player] != 'none': if world.shopsanity[player]: groups.locations.extend(retro_vanilla_mapping['Heart Container']) groups.locations.append('Old Man Sword Cave Item 1') @@ -249,7 +251,7 @@ def previously_reserved(location, world, player): if world.restrict_boss_items[player] == 'dungeon' and (not world.compassshuffle[player] or not world.mapshuffle[player] or not world.bigkeyshuffle[player] - or not (world.keyshuffle[player] or world.retro[player])): + or world.keyshuffle[player] == 'standard'): return True return False @@ -335,7 +337,7 @@ def determine_major_items(world, player): pass # now what? if world.bigkeyshuffle[player]: major_item_set.update({x for x, y in item_table.items() if y[2] == 'BigKey'}) - if world.keyshuffle[player]: + if world.keyshuffle[player] != 'none': major_item_set.update({x for x, y in item_table.items() if y[2] == 'SmallKey'}) if world.compassshuffle[player]: major_item_set.update({x for x, y in item_table.items() if y[2] == 'Compass'}) @@ -344,8 +346,9 @@ def determine_major_items(world, player): if world.shopsanity[player]: major_item_set.add('Bomb Upgrade (+5)') major_item_set.add('Arrow Upgrade (+5)') - if world.retro[player]: + if world.bow_mode[player].startswith('retro'): major_item_set.add('Single Arrow') + if world.keyshuffle[player] == 'universal': major_item_set.add('Small Key (Universal)') if world.goal == 'triforcehunt': major_item_set.add('Triforce Piece') diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index ae628b7c..38ee8c1a 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -64,7 +64,13 @@ def roll_settings(weights): dungeon_items = 'mcsb' if dungeon_items == 'full' else dungeon_items ret.mapshuffle = get_choice('map_shuffle') == 'on' if 'map_shuffle' in weights else 'm' in dungeon_items ret.compassshuffle = get_choice('compass_shuffle') == 'on' if 'compass_shuffle' in weights else 'c' in dungeon_items - ret.keyshuffle = get_choice('smallkey_shuffle') == 'on' if 'smallkey_shuffle' in weights else 's' in dungeon_items + if 'smallkey_shuffle' in weights: + ret.keyshuffle = get_choice('smallkey_shuffle') + else: + if 's' in dungeon_items: + ret.keyshuffle = 'wild' + if 'u' in dungeon_items: + ret.keyshuffle = 'universal' ret.bigkeyshuffle = get_choice('bigkey_shuffle') == 'on' if 'bigkey_shuffle' in weights else 'b' in dungeon_items ret.accessibility = get_choice('accessibility') @@ -130,6 +136,7 @@ def roll_settings(weights): ret.mode = 'open' ret.retro = True ret.retro = get_choice('retro') == 'on' # this overrides world_state if used + ret.take_any = get_choice_default('take_any', default='none') ret.bombbag = get_choice('bombbag') == 'on' @@ -145,6 +152,7 @@ def roll_settings(weights): ret.difficulty = get_choice('item_pool') ret.flute_mode = get_choice_default('flute_mode', default='normal') + ret.bow_mode = get_choice_default('bow_mode', default='progressive') ret.item_functionality = get_choice('item_functionality') From 4e418f4218bf9d30ea7771d765c8a16faeec4d16 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 2 Sep 2022 13:10:03 -0600 Subject: [PATCH 041/146] Important key fix for logic placment --- Fill.py | 3 ++- KeyDoorShuffle.py | 23 +++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Fill.py b/Fill.py index db18996f..f695bd9a 100644 --- a/Fill.py +++ b/Fill.py @@ -173,7 +173,8 @@ def valid_key_placement(item, location, key_pool, world): if key_logic.prize_location: prize_loc = world.get_location(key_logic.prize_location, location.player) cr_count = world.crystals_needed_for_gt[location.player] - return key_logic.check_placement(unplaced_keys, location if item.bigkey else None, prize_loc, cr_count) + wild_keys = world.keyshuffle[item.player] != 'none' + return key_logic.check_placement(unplaced_keys, wild_keys, location if item.bigkey else None, prize_loc, cr_count) else: return not item.is_inside_dungeon_item(world) diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index 9cca37e3..6d495aed 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -62,9 +62,9 @@ class KeyLogic(object): self.sm_doors = {} self.prize_location = None - def check_placement(self, unplaced_keys, big_key_loc=None, prize_loc=None, cr_count=7): + def check_placement(self, unplaced_keys, wild_keys, big_key_loc=None, prize_loc=None, cr_count=7): for rule in self.placement_rules: - if not rule.is_satisfiable(self.outside_keys, unplaced_keys, big_key_loc, prize_loc, cr_count): + if not rule.is_satisfiable(self.outside_keys, wild_keys, unplaced_keys, big_key_loc, prize_loc, cr_count): return False if big_key_loc: for rule_a, rule_b in itertools.combinations(self.placement_rules, 2): @@ -186,17 +186,20 @@ class PlacementRule(object): if not bk_blocked and check_locations is None: return True available_keys = outside_keys - empty_chests = 0 # todo: sometimes we need an extra empty chest to accomodate the big key too # dungeon bias seed 563518200 for example threshold = self.needed_keys_wo_bk if bk_blocked else self.needed_keys_w_bk - for loc in check_locations: - if not loc.item: - empty_chests += 1 - elif loc.item and loc.item.name == self.small_key: - available_keys += 1 - place_able_keys = min(empty_chests, unplaced_keys) - available_keys += place_able_keys + if not wild_keys: + empty_chests = 0 + for loc in check_locations: + if not loc.item: + empty_chests += 1 + elif loc.item and loc.item.name == self.small_key: + available_keys += 1 + place_able_keys = min(empty_chests, unplaced_keys) + available_keys += place_able_keys + else: + available_keys += unplaced_keys return available_keys >= threshold From 5850edfbe6f7d99a3e62461c36dd9baaded90834 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 7 Sep 2022 16:49:47 -0600 Subject: [PATCH 042/146] Couple minor issues - let a door not be dead in higher intensity, slightly better reporting --- Doors.py | 7 ++++++- ItemList.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Doors.py b/Doors.py index c80ea51a..32ffd9ae 100644 --- a/Doors.py +++ b/Doors.py @@ -437,7 +437,7 @@ def create_doors(world, player): create_door(player, 'PoD Dark Basement W Up Stairs', Sprl).dir(Up, 0x6a, 0, HTH).ss(S, 0x1b, 0x3c, True), create_door(player, 'PoD Dark Basement E Up Stairs', Sprl).dir(Up, 0x6a, 1, HTH).ss(S, 0x1b, 0x9c, True), create_door(player, 'PoD Dark Alley NE', Nrml).dir(No, 0x6a, Right, High).big_key().pos(0), - create_door(player, 'PoD Mimics 2 SW', Nrml).dir(So, 0x1b, Left, High).pos(1).kill().portal(Z, 0x00), + create_door(player, 'PoD Mimics 2 SW', Nrml).dir(So, 0x1b, Left, High).pos(1).portal(Z, 0x00), create_door(player, 'PoD Mimics 2 NW', Intr).dir(No, 0x1b, Left, High).pos(0), create_door(player, 'PoD Bow Statue SW', Intr).dir(So, 0x1b, Left, High).pos(0), create_door(player, 'PoD Bow Statue Left to Right Barrier - Orange', Lgcl), @@ -1473,6 +1473,11 @@ def create_doors(world, player): world.get_door('GT Spike Crystal Right to Left Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('GT Spike Crystal Left to Right Bypass', player).barrier(CrystalBarrier.Blue) + # kill certain doors + if world.intensity[player] == 1: # due to ladder & warp being fixed + world.get_door('PoD Mimics 2 SW', player).kill() + + # nifty dynamic logical doors: south_controller = world.get_door('Ice Cross Bottom SE', player) east_controller = world.get_door('Ice Cross Right ES', player) diff --git a/ItemList.py b/ItemList.py index c1981365..2e7f0040 100644 --- a/ItemList.py +++ b/ItemList.py @@ -544,7 +544,7 @@ def fill_prizes(world, attempts=15): continue break else: - raise FillError('Unable to place dungeon prizes') + raise FillError(f'Unable to place dungeon prizes {", ".join(list(map(lambda d: d.hint_text, prize_locs)))}') def set_up_shops(world, player): From e2b9735600b34fa6d6ccf7c7e1616c4dcfee07fb Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 7 Sep 2022 16:50:44 -0600 Subject: [PATCH 043/146] Rain prevention fix for keydoors (plus test case) Couple fixes for standard throne --- DungeonGenerator.py | 19 +++++++++++-------- Rom.py | 2 +- data/base2current.bps | Bin 93432 -> 93438 bytes source/dungeon/DungeonStitcher.py | 12 ++++++++++-- test/customizer/rainprevent_keydoor.yaml | 13 +++++++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 test/customizer/rainprevent_keydoor.yaml diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 445ed9b3..f982cb6f 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -16,6 +16,7 @@ from Dungeons import dungeon_regions, split_region_starts from RoomData import DoorKind from source.dungeon.DungeonStitcher import generate_dungeon_find_proposal +from source.dungeon.DungeonStitcher import GenerationException as OtherGenException class GraphPiece: @@ -1505,6 +1506,8 @@ def calc_allowance_and_dead_ends(builder, connections_tuple, world, player): builder.branches -= 1 if entrance not in drop_entrances_allowance: needed_connections.append(entrance) + if builder.sewers_access: + starting_allowance += 1 builder.allowance = starting_allowance for entrance in needed_connections: sector = find_sector(entrance, builder.sectors) @@ -3051,7 +3054,7 @@ def split_dungeon_builder(builder, split_list, builder_info): comb_w_replace = len(dungeon_map) ** len(candidate_sectors) return balance_split(candidate_sectors, dungeon_map, global_pole, builder_info) except (GenerationException, NeutralizingException): - if comb_w_replace and comb_w_replace <= 10000: + if comb_w_replace and comb_w_replace <= 10000 and not builder.throne_door: attempts += 5 # all the combinations were tried already, no use repeating else: attempts += 1 @@ -3535,7 +3538,7 @@ def check_for_valid_layout(builder, sector_list, builder_info): split_list['Sewers'].remove(temp_builder.throne_door.entrance.parent_region.name) builder.exception_list = list(sector_list) return True, {}, package - except (GenerationException, NeutralizingException): + except (GenerationException, NeutralizingException, OtherGenException): builder.split_dungeon_map = None builder.valid_proposal = None if temp_builder.name == 'Hyrule Castle' and temp_builder.throne_door: @@ -3948,20 +3951,20 @@ def find_free_equation(equations): def copy_door_equations(builder, sector_list): equations = {} for sector in builder.sectors + sector_list: - sector.equations = calc_sector_equations(sector) + sector.equations = calc_sector_equations(sector, builder.sewers_access) curr_list = equations[sector] = [] for equation in sector.equations: curr_list.append(equation.copy()) return equations -def calc_sector_equations(sector): +def calc_sector_equations(sector, sewers_flag=False): equations = [] - is_entrance = sector.is_entrance_sector() and not sector.destination_entrance + is_entrance = (sector.is_entrance_sector() and not sector.destination_entrance) or sewers_flag if is_entrance: flagged_equations = [] for door in sector.outstanding_doors: - equation, flag = calc_door_equation(door, sector, True) + equation, flag = calc_door_equation(door, sector, True, sewers_flag) if flag: flagged_equations.append(equation) equations.append(equation) @@ -3977,9 +3980,9 @@ def calc_sector_equations(sector): return equations -def calc_door_equation(door, sector, look_for_entrance): +def calc_door_equation(door, sector, look_for_entrance, sewers_flag=None): if look_for_entrance and not door.blocked: - flag = sector.is_entrance_sector() + flag = sector.is_entrance_sector() or sewers_flag if flag: eq = DoorEquation(door) eq.benefit[hook_from_door(door)].append(door) diff --git a/Rom.py b/Rom.py index 544f2c5b..18677375 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '0be31dc5cb338e7e85d1ce65e839c99e' +RANDOMIZERBASEHASH = '61c296effe6180274721d570d2471e1c' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 9740c94d9fb0f54c63443282dd8a82eff36b7240..03d6471ed59fbc3a0aa2fcb13383c31d53c06f20 100644 GIT binary patch delta 950 zcmW-dZ%i9?7{~AFwX~y!7HC;JVEiZ5+|)Re`KM}NXu(BYvZ=s+ zS3E*-3wJ%r16&qL<(xoB7n-Gk1=(?X5jcC@~6{$f1vW^xOcESU!V4=iNhe570d6EU6 z(NZV!?um73)}+qlL?&Ek-)gfSXuSAaII5#8sgzdIs&nL|HN1HprnV`19!O<3%~JHE9X$~e7RU~Mw04sb^;Ij0p-$KIrk2Yl1?^oZzixh+f1gD-<0n zn&S-espjynlk@75_JS`IhIC83PBChOmL?TLSPxV_R3cr`k*gBVC>C_#mKAmtzIcN( z^#`X7ik{SoYxBcPyjhA}w)nkP`5+#(L1~7ibUWocvDF4{n8ix^d`F`8 zn}+@}8u|fObHJ6gDNz^p4rdQgEBOWg$bsXwih;m=o76ZcS!*10KQ&`hE;Ll@UJgw| z>U6y3&#sj+yT&z#9(mz+?Ec19oSbjWWNu?>XtfI~=wri}Jy@jcqzIgKfo7#jGl60K>a#tooBslPHFN6# delta 973 zcmW+xe@q)?7{0gHqb)03+qFO)KR&3?R-6GhCqjm}O`H`Ii9d)gagECyShi%ifHMkT z%MLA*wbvVbz`0Num(UW@>1n#nU>S<6e_2g18OfFmGlTyuXSNZXk$Us5_j#Z9$@9F= z)(vL!26O3M&>9YJM1}WYCrry>D5k+B&uM?uKuGS=kdtILWvw-e!2mYn$lnWDg+T+nN-pv!FI?v>^8Qc#`-nOjNxe~8fc^QQ znIR94_6rlk63s==b%yCGX_b^0eZF{=SkX$PX>n37h&`mH?ikyx%$e5M}i_% zAQ&e(C3oVP=r9SfV6fL+SrNk$jXoUkqIg(B=$o*+i9%ap@)Zjud(2n;jM#QGawk5o zEUCq3Bno{ha2iRcE-H#kOhgMqph1%YM@dGKN3@6i3XlnJf-1P1yles%YJV26b%6<0;oxrqj_7aC zdDLip)4M=XiYr9?4iXr;Cty4Id`y2Hv*;GtG{Y;V%JaT8ldyM0U>j|?7Bl2^3p5vY zw*}`Qb12bxuQ$C;ho71)=KZ^gfn2hH-B9lhiqIJpJISvW^^Y?0zyin2=SD+Q#B~B+ zn_ljnuTjuBa(p{PEX_nP1tcAnp<9|s%x8UAW(ijKpk%QhR{7K7Qz1O}R&%arE}63I{#HlL4WS z9JGNO_LD9fG@1{Tj0X!`-cXva82D*=RV{tZ22Lm?f7)PYUSE#LE!G?pc7Na}r<0BX zXfe>$r~64)8C21p-u|Rm2KfL@B#vMo%ThtUz1|m%ChWVyVpsAX1R8)hlUwDm>CtbV L-S-)h+rIn{?#hFv diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py index aa74dee0..b5e7515e 100644 --- a/source/dungeon/DungeonStitcher.py +++ b/source/dungeon/DungeonStitcher.py @@ -56,6 +56,8 @@ def generate_dungeon_find_proposal(builder, entrance_region_names, split_dungeon if (access_region.name in world.inaccessible_regions[player] and region.name not in world.enabled_entrances[player]): excluded[region] = None + elif split_dungeon and builder.sewers_access and builder.sewers_access.entrance.parent_region == region: + continue elif len(region.entrances) == 1: # for holes access_region = next(x.parent_region for x in region.entrances if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld] @@ -182,11 +184,17 @@ def modify_proposal(proposed_map, explored_state, doors_to_connect, hash_code_se return proposed_map, hash_code attempt, opp_hook = None, None - opp_hook_len = 0 + opp_hook_len, possible_swaps = 0, list(visited_choices) while opp_hook_len == 0: - attempt = random.choice(visited_choices) + if len(possible_swaps) == 0: + break + attempt = random.choice(possible_swaps) + possible_swaps.remove(attempt) opp_hook = type_map[hook_from_door(attempt)] opp_hook_len = len(unvisted_bucket[opp_hook]) + if opp_hook_len == 0: + itr += 1 + continue unvisted_bucket[opp_hook].sort(key=lambda d: d.name) new_door = random.choice(unvisted_bucket[opp_hook]) old_target = proposed_map[attempt] diff --git a/test/customizer/rainprevent_keydoor.yaml b/test/customizer/rainprevent_keydoor.yaml new file mode 100644 index 00000000..31930dce --- /dev/null +++ b/test/customizer/rainprevent_keydoor.yaml @@ -0,0 +1,13 @@ +meta: + players: 1 +settings: + 1: + door_shuffle: crossed + mode: standard + shuffle: crossed +doors: + 1: + doors: + Hyrule Castle East Lobby N: + dest: Sewers Secret Room Key Door S + type: Key Door From db43ce8d15fd88503a8fc9f1a674644b7578b16b Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 8 Sep 2022 16:24:48 -0600 Subject: [PATCH 044/146] Fix keyshuffle --- BaseClasses.py | 2 +- resources/app/gui/lang/en.json | 2 +- resources/app/gui/randomize/dungeon/widgets.json | 2 +- source/item/FillUtil.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index a601a3c5..60d04d82 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -113,7 +113,7 @@ class World(object): set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'nologic'] or shuffle[player] in ['crossed', 'insanity']) set_player_attr('mapshuffle', False) set_player_attr('compassshuffle', False) - set_player_attr('keyshuffle', 'standard') + set_player_attr('keyshuffle', 'none') set_player_attr('bigkeyshuffle', False) set_player_attr('restrict_boss_items', 'none') set_player_attr('bombbag', False) diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 9c7f9dfa..9a55893a 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -53,7 +53,7 @@ "randomizer.dungeon.mapshuffle": "Maps", "randomizer.dungeon.compassshuffle": "Compasses", "randomizer.dungeon.smallkeyshuffle": "Small Keys", - "randomizer.dungeon.smallkeyshuffle.standard": "In Dungeon", + "randomizer.dungeon.smallkeyshuffle.none": "In Dungeon", "randomizer.dungeon.smallkeyshuffle.wild": "Randomized", "randomizer.dungeon.smallkeyshuffle.universal": "Universal", "randomizer.dungeon.bigkeyshuffle": "Big Keys", diff --git a/resources/app/gui/randomize/dungeon/widgets.json b/resources/app/gui/randomize/dungeon/widgets.json index 02a7f262..19606b23 100644 --- a/resources/app/gui/randomize/dungeon/widgets.json +++ b/resources/app/gui/randomize/dungeon/widgets.json @@ -3,7 +3,7 @@ "keyshuffle": { "type": "selectbox", "options": [ - "standard", + "none", "wild", "universal" ] diff --git a/source/item/FillUtil.py b/source/item/FillUtil.py index 8cb74805..040497a2 100644 --- a/source/item/FillUtil.py +++ b/source/item/FillUtil.py @@ -251,7 +251,7 @@ def previously_reserved(location, world, player): if world.restrict_boss_items[player] == 'dungeon' and (not world.compassshuffle[player] or not world.mapshuffle[player] or not world.bigkeyshuffle[player] - or world.keyshuffle[player] == 'standard'): + or world.keyshuffle[player] == 'none'): return True return False From 30833152f63de6e25f68915352c1c2269862921a Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 13 Sep 2022 15:54:06 -0600 Subject: [PATCH 045/146] Minor decoupled adjustment --- DoorShuffle.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 0d56882e..368aa931 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -353,9 +353,6 @@ def connect_one_way(world, entrancename, exitname, player): y = world.check_for_door(exitname, player) if x is not None: x.dest = y - if y is not None: - y.dest = x - def unmark_ugly_smalls(world, player): for d in ['Eastern Hint Tile Blocked Path SE', 'Eastern Darkness S', 'Thieves Hallway SE', 'Mire Left Bridge S', From 4f5a41d0406e8a4d7ba3e17d35485a76c71335e7 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 16 Sep 2022 10:41:18 -0600 Subject: [PATCH 046/146] Change customizer item pool to warn of missing items --- ItemList.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/ItemList.py b/ItemList.py index f2500e07..c1deb8db 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1114,37 +1114,35 @@ def make_customizer_pool(world, player): place_item('Master Sword Pedestal', 'Triforce') guaranteed_items = alwaysitems + ['Magic Mirror', 'Moon Pearl'] + missing_items = [] if world.shopsanity[player]: guaranteed_items.extend(['Blue Potion', 'Green Potion', 'Red Potion']) if world.retro[player]: guaranteed_items.append('Small Key (Universal)') for item in guaranteed_items: if item not in pool: - pool.append(item) + missing_items.append(item) glove_count = sum(1 for i in pool if i == 'Progressive Glove') glove_count = 2 if next((i for i in pool if i == 'Titans Glove'), None) is not None else glove_count for i in range(glove_count, 2): - pool.append('Progressive Glove') + missing_items.append('Progressive Glove') if world.bombbag[player]: if 'Bomb Upgrade (+10)' not in pool: - pool.append('Bomb Upgrade (+10)') + missing_items.append('Bomb Upgrade (+10)') if world.swords[player] != 'swordless': beam_swords = {'Master Sword', 'Tempered Sword', 'Golden Sword'} sword_count = sum(1 for i in pool if i in 'Progressive Sword') sword_count = 2 if next((i for i in pool if i in beam_swords), None) is not None else sword_count for i in range(sword_count, 2): - pool.append('Progressive Sword') + missing_items.append('Progressive Sword') bow_found = next((i for i in pool if i in {'Bow', 'Progressive Bow'}), None) if not bow_found: - pool.append('Progressive Bow') - - heart_found = next((i for i in pool if i in {'Boss Heart Container', 'Sanctuary Heart Container'}), None) - if heart_found is None: - pool.append('Boss Heart Container') + missing_items.append('Progressive Bow') + logging.getLogger('').warning(f'The following items are not in the custom item pool {", ".join(missing_items)}') g, t = set_default_triforce(world.goal[player], world.treasure_hunt_count[player], world.treasure_hunt_total[player]) From 513782683742db05b492f320d665f8c7ec40a839 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 16 Sep 2022 13:00:15 -0600 Subject: [PATCH 047/146] Fix github build? --- resources/ci/common/install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/ci/common/install.py b/resources/ci/common/install.py index 6830905e..3d0b5965 100644 --- a/resources/ci/common/install.py +++ b/resources/ci/common/install.py @@ -6,7 +6,7 @@ import subprocess # do stuff at the shell level env = common.prepare_env() -pip_requirements = os.path.join("..","resources","app","meta","manifests","pip_requirements.txt") +pip_requirements = os.path.join(".","resources","app","meta","manifests","pip_requirements.txt") if not os.path.isfile(pip_requirements): pip_requirements = os.path.join("..","..","..","resources","app","meta","manifests","pip_requirements.txt") From a9806ec40f52fce69edb631b9cd82471e0311809 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 16 Sep 2022 13:31:26 -0600 Subject: [PATCH 048/146] Minor doc update --- RELEASENOTES.md | 72 +------------------------------------------------ 1 file changed, 1 insertion(+), 71 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index fab0c559..ba7ac9e0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -179,10 +179,6 @@ Currently bugged, not recommended for use. Same as above but both small keys and bigs keys of the dungeon are not allowed on a boss. (Note: this does not affect universal keys as they are not dungeon-specific) -## Notes and Bug Fixes - -#### Unstable - # Bug Fixes and Notes * 1.1.0 @@ -244,70 +240,4 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o * Add Light Hype Fairy to bombbag mode as needing bombs * 1.0.1 * Fixed a bug with key doors not detecting one side of an interior door - * Sprite selector fix for systems with SSL issues -* 0.5.1.7 - * Baserom update - * Fix for Inverted Mode: Dark Lake Hylia shop defaults to selling a blue potion - * Fix for Ijwu's enemizer: Boss door in Thieves' Town no longer closes after the maiden hint if Blind is shuffled to Theives' Town in boss shuffle + crossed mode - * No logic now sets the AllowAccidentalMajorGlitches flag in the rom appropriately - * Houlihan room now exits wherever Link's House is shuffled to - * Rom fixes from Catobat and Codemann8. Thanks! -* 0.5.1.6 - * Rules fixes for TT (Boss and Cell) can now have TT Big Key if not otherwise required (boss shuffle + crossed dungeon) - * BUg fix for money balancing - * Add some bomb assumptions for bosses in bombbag mode -* 0.5.1.5 - * Fix for hard pool capacity upgrades missing - * Bonk Fairy (Light) is no longer in logic for ER Standard and is forbidden to be a connector, so rain state isn't exitable - * Bug fix for retro + enemizer and arrows appearing under pots - * Added bombbag and shufflelinks to settings code - * Catobat fixes: - * Fairy refills in spoiler - * Subweights support in mystery - * More defaults for mystery weights - * Less camera jank for straight stair transitions - * Bug with Straight stairs with vanilla doors where Link's walking animation stopped early is fixed -* 0.5.1.4 - * Revert quadrant glitch fix for baserom - * Fix for inverted -* 0.5.1.3 - * Certain lobbies forbidden in standard when rupee bow is enabled - * PoD EG disarmed when mirroring (except in nologic) - * Fixed issue with key logic - * Updated baserom -* 0.5.1.2 - * Allowed Blind's Cell to be shuffled anywhere if Blind is not the boss of Thieves Town - * Remove unique annotation from a FastEnum that was causing problems - * Updated prevent mixed_travel setting to prevent more mixed travel - * Prevent key door loops on the same supertile where you could have spent 2 keys on one logical door - * Promoted dynamic soft-lock prevention on "stonewalls" from experimental to be the primary prevention (Stonewalls are now never pre-opened) - * Fix to money balancing algorithm with small item_pool, thanks Catobat - * Many fixes and refinements to key logic and generation -* 0.5.1.1 - * Shop hints in ER are now more generic instead of using "near X" because they aren't near that anymore - * Added memory location for mutliworld scripts to read what item was just obtain (longer than one frame) - * Fix for bias in boss shuffle "full" - * Fix for certain lone big chests in keysanity (allowed you to get contents without big key) - * Fix for pinball checking - * Fix for multi-entrance dungeons - * 2 fixes for big key placement logic - * ensure big key is placed early if the validator assumes it) - * Open big key doors appropriately when generating rules and big key is forced somewhere - * Updated cutoff entrances for intensity 3 -* 0.5.1.0 - * Large logic refactor introducing a new method of key logic - * Some performance optimization - * Some outstanding bug fixes (boss shuffle "full" picks three unique bosses to be duplicated, e.g.) -* 0.5.0.3 - * Fixed a bug in retro+vanilla and big key placement - * Fixed a problem with shops not registering in the Multiclient until you visit one - * Fixed a bug in the Mystery code with sfx -* 0.5.0.2 - * --shuffle_sfx option added -* 0.5.0.1 - * --bombbag option added -* 0.5.0.0 - * Handles headered roms for enemizer (Thanks compiling) - * Warning added for earlier version of python (Thanks compiling) - * Minor logic issue for defeating Aga in standard (Thanks compiling) - * Fix for boss music in non-DR modes (Thanks codemann8) \ No newline at end of file + * Sprite selector fix for systems with SSL issues \ No newline at end of file From 4f2fed48d7be409b9105104ad9886d35704c677b Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 26 Oct 2022 16:46:32 -0600 Subject: [PATCH 049/146] Big key door fix Some generation fixes (need to look at pre-validate some more) Bumped up escape assist values in non-basic shuffles --- DoorShuffle.py | 20 +++++++++++++------- DungeonGenerator.py | 27 +++++++++++++++++---------- Fill.py | 2 +- Rom.py | 8 +++++--- data/base2current.bps | Bin 93438 -> 93445 bytes source/dungeon/DungeonStitcher.py | 22 ++++++++++++---------- 6 files changed, 48 insertions(+), 31 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 368aa931..1dea2f99 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1018,7 +1018,8 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_ find_standard_origins(builder, recombinant_builders, origin_list) find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, name) split_dungeon = treat_split_as_whole_dungeon(split_dungeon, name, origin_list, world, player) - if len(origin_list) <= 0 or not pre_validate(builder, origin_list, split_dungeon, world, player): + # todo: figure out pre-validate, ensure all needed origins are enabled? + if len(origin_list) <= 0: # or not pre_validate(builder, origin_list, split_dungeon, world, player): if last_key == builder.name or loops > 1000: origin_name = world.get_region(origin_list[0], player).entrances[0].parent_region.name if len(origin_list) > 0 else 'no origin' raise GenerationException(f'Infinite loop detected for "{builder.name}" located at {origin_name}') @@ -1068,14 +1069,14 @@ def determine_entrance_list(world, player): connections = {} for key, portal_list in dungeon_portals.items(): entrance_map[key] = [] - r_names = {} + r_names = [] if key in dungeon_drops.keys(): for drop in dungeon_drops[key]: - r_names[drop] = None + r_names.append((drop, None)) for portal_name in portal_list: portal = world.get_portal(portal_name, player) - r_names[portal.door.entrance.parent_region.name] = portal - for region_name, portal in r_names.items(): + r_names.append((portal.door.entrance.parent_region.name, portal)) + for region_name, portal in r_names: if portal: region = world.get_region(portal.name + ' Portal', player) else: @@ -2160,11 +2161,16 @@ def find_valid_trap_combination(builder, suggested, start_regions, paths, world, # eliminate start region if portal marked as destination def filter_start_regions(builder, start_regions, world, player): std_flag = world.mode[player] == 'standard' and builder.name == 'Hyrule Castle' - excluded = {} + excluded = {} # todo: drop lobbies, might be better to white list instead (two entrances per region) for region in start_regions: portal = next((x for x in world.dungeon_portals[player] if x.door.entrance.parent_region == region), None) if portal and portal.destination: - excluded[region] = None + # make sure that a drop is not accessible for this "destination" + drop_region = next((x.parent_region for x in region.entrances + if x.parent_region.type in [RegionType.LightWorld, RegionType.DarkWorld] + or x.parent_region.name == 'Sewer Drop'), None) + if not drop_region: + excluded[region] = None if std_flag and (not portal or portal.find_portal_entrance().parent_region.name != 'Hyrule Castle Courtyard'): excluded[region] = None return [x for x in start_regions if x not in excluded.keys()] diff --git a/DungeonGenerator.py b/DungeonGenerator.py index f982cb6f..d33db874 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1356,7 +1356,8 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge sanc_builder = random.choice(lw_builders) assign_sector(sanc, sanc_builder, candidate_sectors, global_pole) - bow_sectors, retro_std_flag = {}, world.bow_mode[player].startswith('retro') and world.mode[player] == 'standard' + retro_std_flag = world.bow_mode[player].startswith('retro') and world.mode[player] == 'standard' + non_hc_sectors = {} free_location_sectors = {} crystal_switches = {} crystal_barriers = {} @@ -1364,7 +1365,9 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge neutral_sectors = {} for sector in candidate_sectors: if retro_std_flag and 'Bow' in sector.item_logic: # these need to be distributed outside of HC - bow_sectors[sector] = None + non_hc_sectors[sector] = None + elif world.mode[player] == 'standard' and 'Open Floodgate' in sector.item_logic: + non_hc_sectors[sector] = None elif sector.chest_locations > 0: free_location_sectors[sector] = None elif sector.c_switch: @@ -1375,8 +1378,8 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge neutral_sectors[sector] = None else: polarized_sectors[sector] = None - if bow_sectors: - assign_bow_sectors(dungeon_map, bow_sectors, global_pole) + if non_hc_sectors: + assign_non_hc_sectors(dungeon_map, non_hc_sectors, global_pole) leftover = assign_location_sectors_minimal(dungeon_map, free_location_sectors, global_pole, world, player) free_location_sectors = scatter_extra_location_sectors(dungeon_map, leftover, global_pole) for sector in free_location_sectors: @@ -1420,7 +1423,8 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge def standard_stair_check(dungeon_map, dungeon, candidate_sectors, global_pole): # this is because there must be at least one non-dead stairway in hc to get out # this check may not be necessary - filtered_sectors = [x for x in candidate_sectors if any(y for y in x.outstanding_doors if not y.dead and y.type == DoorType.SpiralStairs)] + filtered_sectors = [x for x in candidate_sectors if 'Open Floodgate' not in x.item_logic and + any(y for y in x.outstanding_doors if not y.dead and y.type == DoorType.SpiralStairs)] valid = False while not valid: chosen_sector = random.choice(filtered_sectors) @@ -1550,7 +1554,7 @@ def define_sector_features(sectors): sector.bk_required = True for ext in region.exits: door = ext.door - if door is not None: + if door is not None and not door.blocked: if door.crystal == CrystalBarrier.Either: sector.c_switch = True elif door.crystal == CrystalBarrier.Orange: @@ -1562,6 +1566,8 @@ def define_sector_features(sectors): if region.name in ['PoD Mimics 2', 'PoD Bow Statue Right', 'PoD Mimics 1', 'GT Mimics 1', 'GT Mimics 2', 'Eastern Single Eyegore', 'Eastern Duo Eyegores']: sector.item_logic.add('Bow') + if region.name in ['Swamp Lobby', 'Swamp Entrance']: + sector.item_logic.add('Open Floodgate') def assign_sector(sector, dungeon, candidate_sectors, global_pole): @@ -1613,8 +1619,8 @@ def find_sector(r_name, sectors): return None -def assign_bow_sectors(dungeon_map, bow_sectors, global_pole): - sector_list = list(bow_sectors) +def assign_non_hc_sectors(dungeon_map, non_hc_sectors, global_pole): + sector_list = list(non_hc_sectors) random.shuffle(sector_list) population = [] for name in dungeon_map: @@ -1623,7 +1629,7 @@ def assign_bow_sectors(dungeon_map, bow_sectors, global_pole): choices = random.choices(population, k=len(sector_list)) for i, choice in enumerate(choices): builder = dungeon_map[choice] - assign_sector(sector_list[i], builder, bow_sectors, global_pole) + assign_sector(sector_list[i], builder, non_hc_sectors, global_pole) def scatter_extra_location_sectors(dungeon_map, free_location_sectors, global_pole): @@ -3511,7 +3517,8 @@ def check_for_valid_layout(builder, sector_list, builder_info): for portal in world.dungeon_portals[player]: if not portal.destination and portal.name in dungeon_portals[builder.name]: possible_regions.add(portal.door.entrance.parent_region.name) - if builder.name in dungeon_drops.keys(): + if builder.name in dungeon_drops.keys() and (builder.name != 'Hyrule Castle' + or world.mode[player] != 'standard'): possible_regions.update(dungeon_drops[builder.name]) independents = find_independent_entrances(possible_regions, world, player) for name, split_build in builder.split_dungeon_map.items(): diff --git a/Fill.py b/Fill.py index f695bd9a..8487c750 100644 --- a/Fill.py +++ b/Fill.py @@ -289,7 +289,7 @@ def last_ditch_placement(item_to_place, locations, world, state, base_state, ite possible_swaps = [x for x in state.locations_checked if x.item.type == 'Crystal'] else: possible_swaps = [x for x in state.locations_checked - if x.item.type not in ['Event', 'Crystal'] and not x.forced_item] + if x.item.type not in ['Event', 'Crystal'] and not x.forced_item and not x.locked] swap_locations = sorted(possible_swaps, key=location_preference) return try_possible_swaps(swap_locations, item_to_place, locations, world, base_state, itempool, key_pool, single_player_placement) diff --git a/Rom.py b/Rom.py index 18677375..fff0456a 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '61c296effe6180274721d570d2471e1c' +RANDOMIZERBASEHASH = '5639de3bfd500ba238d3f27ea78c19e1' class JsonRom(object): @@ -1492,8 +1492,10 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): if world.doorShuffle[player] not in ['vanilla', 'basic']: # Uncle respawn refills (magic, bombs, arrows) rom.write_bytes(0x180185, [max(0x20, magic_max), max(3, bomb_max), max(10, bow_max)]) - rom.write_bytes(0x180188, [0x20, 3, 10]) # Zelda respawn refills (magic, bombs, arrows) - rom.write_bytes(0x18018B, [0x20, 3, 10]) # Mantle respawn refills (magic, bombs, arrows) + # Zelda respawn refills (magic, bombs, arrows) + rom.write_bytes(0x180188, [max(0x20, magic_max), max(3, bomb_max), max(10, bow_max)]) + # Mantle respawn refills (magic, bombs, arrows) + rom.write_bytes(0x18018B, [max(0x20, magic_max), max(3, bomb_max), max(10, bow_max)]) elif world.doorShuffle[player] == 'basic': # just in case a bomb is needed to get to a chest rom.write_bytes(0x180185, [max(0x00, magic_max), max(3, bomb_max), max(0, bow_max)]) rom.write_bytes(0x180188, [magic_small, 3, bow_small]) # Zelda respawn refills (magic, bombs, arrows) diff --git a/data/base2current.bps b/data/base2current.bps index 03d6471ed59fbc3a0aa2fcb13383c31d53c06f20..3fd78189a58e8bcb70b83f770932c6ebbe1745dc 100644 GIT binary patch delta 867 zcmW-cUu;u#6vyxBy|?YQ(tB_JtwpTAwQg<2kZn$!pk!z@q?9a!MB?8xBsyit!_*gI z#;?WOP{`8WUdq{aL#S*wp(V=}`cOccb(%SdFAK>MTwIhHqYs4iVFWaUdiA`V@A>4L z?>Fb^&%C_G&wm7*^Mm`-l_L;ip{Fv--C<#|Lap^SXjb;Rmfi+`#q$1F+k=x}a|+BB z!2MB%*1*F%UEtywyU@;nozspUU}!~4+xJ3OrM%p`8|t`jf{^v5LU|p?Beb#Lhx@pl zg$_Q7sU)oqu@JY|qKX_SZPGTwM60D%*ujAh@7kgFWQk!$>dl6QJjfSKlqI{=+s%e| zYDmccZD5{c6$AdH5Kpc@;Z6LH%y|Qy$S-{2_t0c}HZ^`oA#wF|L1*RSH|8HYZ`8O5 zU1`xd8OSTA=oX#3_;tEK3OTY>zPRsd<@M_q{xf(DgNkVZ9NyUV)tQ{mk}uK;QpxFr z)N+vlhFEZ30RPV5jU=xf{y6_fxz<>UG?~jfL(-~j(k;eesIt!IIiT8W9qI)WDXTK0 z+weK$MCjc1-gilBHZ{xZ9EmD_)h3tZHuciDEfEp4-T0OWL9-*+PGyS6MF_x6R7B{4 zN7ZX02+(s^rLH=k?V_1qRhqZnn~fRObUjgLm_|5@$snf2pQzM_rzfRzR3LxiV+r<) zJI;-4i0a^ZRoLUEJ=Bhe9B|kiP?CN449+{i*Ah=;H0QC5HimZ`Mr{v1bilBL6WL1` zK28^Bmd9${4TAW&6Y`EhRK=8TVOH4qAeN-?+%c3~K*(|-391Z-&)Bi4!NMyZH>67cHmS}&|Vg%l!lp+3x?zv>&a+b)PdJgitpw6P&a4?vFS=nM@PeMP&TVGXr4?zTyVNd!_~17a zN)}E2zWYtJ?`RT-t3eN>Tj3y<3A`b8Fd603T_eTfobRQa#`RU75HM!A`m_Tc$E@q4 LJ5ygCZ29G1-!Dm} delta 854 zcmW-bZ%i9?7{~AF^=Ly2cm3b)5Bt$>v=uYhUvQd9mxTz{45Ma7GrgHOjkx(jm#Go_ zUD-A5B5Cgq_7pA)h3(wRf=v6OVFtlJ2uplHO!i^~lWoz&#l-YQO+=@7@p@Lq(e`MjSGPN%{;9)u8UFwFdW!uYVTX!sh)59|j z;NTcwJmBX%-rV2WMn0gOIghcS@`&%X=S(dAw(VsC`bMoB^bU0t-#>0NYq- z<`S5a1}ZPGkhD1yiX1N0sKYc3RA%a7w-p+2y%F~I^)GH#ZR9t#XrV0W&~9y3gX7Qg z>V}Cq@`+-?6@_^6onlb@AF-;5&Z!Gxlb=f7Txz&aAw61V)L`Y}`MPg+;7J|=PpWyc zMV>hFMY&_{k~L0OgN9YsoRf03e&RrJlm^KYDN%cH{pj57$-Kdmche%dkv9mrnU8ld z#EKOjnhtKiDRKJo*VSL9=c`NcP3D@xkReUB7&h}T)wIE>R-pR9X6=%NT-9X8aAF7@ z0_@uM{FjnFmzv=WD@iE7&W|n04sB}KDaLvI044>9)Hx#oDi7dU0m3kc1p!*1R#^~$ zhdsA7>Rse=Ei}8XQPqBLrq`^dKZ%PBQ;p?NiePGZL!%+gj5Ur>p8SlPE_hmK9qGR> zXgwD-{;-ekp$>e>4aZ~K6lp*DPG_Y&o|5pRtkiiqHF;=xkamPanJK+n%<2tqXZ82- zj@$gC6(73c4cAB^H-)h?^y@3jgY)fGGJ@}UKy@ck6H Date: Thu, 27 Oct 2022 13:56:37 -0600 Subject: [PATCH 050/146] Bumper cave fix Pottery coloring updated --- EntranceShuffle.py | 12 ++++++++---- InvertedRegions.py | 3 ++- Main.py | 2 +- PotShuffle.py | 18 +++++++++--------- RELEASENOTES.md | 3 +++ Regions.py | 3 ++- Rules.py | 8 ++++---- 7 files changed, 29 insertions(+), 20 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index f67c089b..8ff4fcc8 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -3141,6 +3141,8 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Bumper Cave Entrance Mirror Spot', 'Death Mountain Entrance'), ('Bumper Cave Ledge Drop', 'West Dark World'), ('Bumper Cave Ledge Mirror Spot', 'Death Mountain Return Ledge'), + ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), + ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Skull Woods Forest', 'Skull Woods Forest'), ('Desert Ledge Mirror Spot', 'Desert Ledge'), ('Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge (Northeast)'), @@ -3269,6 +3271,8 @@ inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), ('Bumper Cave Entrance Drop', 'West Dark World'), ('Bumper Cave Ledge Drop', 'West Dark World'), + ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), + ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Skull Woods Forest', 'Skull Woods Forest'), ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), ('Paradox Cave Push Block', 'Paradox Cave Front'), @@ -3492,8 +3496,8 @@ default_connections = [('Links House', 'Links House'), ('C-Shaped House', 'C-Shaped House'), ('Chest Game', 'Chest Game'), ('Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave'), - ('Bumper Cave (Bottom)', 'Bumper Cave'), - ('Bumper Cave (Top)', 'Bumper Cave'), + ('Bumper Cave (Bottom)', 'Bumper Cave (bottom)'), + ('Bumper Cave (Top)', 'Bumper Cave (top)'), ('Red Shield Shop', 'Red Shield Shop'), ('Dark Sanctuary Hint', 'Dark Sanctuary Hint'), ('Fortune Teller (Dark)', 'Fortune Teller (Dark)'), @@ -3655,7 +3659,7 @@ inverted_default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing' ('Inverted Big Bomb Shop', 'Inverted Big Bomb Shop'), ('Inverted Dark Sanctuary', 'Inverted Dark Sanctuary'), ('Inverted Dark Sanctuary Exit', 'West Dark World'), - ('Old Man Cave (West)', 'Bumper Cave'), + ('Old Man Cave (West)', 'Bumper Cave (bottom)'), ('Old Man Cave (East)', 'Death Mountain Return Cave (left)'), ('Old Man Cave Exit (West)', 'West Dark World'), ('Old Man Cave Exit (East)', 'Dark Death Mountain'), @@ -3664,7 +3668,7 @@ inverted_default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing' ('Bumper Cave (Top)', 'Dark Death Mountain Healer Fairy'), ('Bumper Cave Exit (Top)', 'Death Mountain Return Ledge'), ('Bumper Cave Exit (Bottom)', 'Light World'), - ('Death Mountain Return Cave (West)', 'Bumper Cave'), + ('Death Mountain Return Cave (West)', 'Bumper Cave (top)'), ('Death Mountain Return Cave (East)', 'Death Mountain Return Cave (right)'), ('Death Mountain Return Cave Exit (West)', 'Death Mountain'), ('Death Mountain Return Cave Exit (East)', 'Death Mountain'), diff --git a/InvertedRegions.py b/InvertedRegions.py index 175b2b76..a02bfbea 100644 --- a/InvertedRegions.py +++ b/InvertedRegions.py @@ -184,7 +184,8 @@ def create_inverted_regions(world, player): create_cave_region(player, 'Chest Game', 'a game of 16 chests', ['Chest Game']), create_cave_region(player, 'Red Shield Shop', 'the rare shop', ['Red Shield Shop - Left', 'Red Shield Shop - Middle', 'Red Shield Shop - Right']), create_cave_region(player, 'Inverted Dark Sanctuary', 'a storyteller', None, ['Inverted Dark Sanctuary Exit']), - create_cave_region(player, 'Bumper Cave', 'a connector', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)']), + create_cave_region(player, 'Bumper Cave (bottom)', 'a connector', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Bottom to Top']), + create_cave_region(player, 'Bumper Cave (top)', 'a connector', None, ['Bumper Cave Exit (Top)', 'Bumper Cave Top To Bottom']), create_dw_region(player, 'Skull Woods Forest', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']), create_dw_region(player, 'Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section']), diff --git a/Main.py b/Main.py index d1f4542d..d0174f27 100644 --- a/Main.py +++ b/Main.py @@ -31,7 +31,7 @@ from Utils import output_path, parse_player_names from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config from source.tools.BPS import create_bps_from_data -__version__ = '1.1.0-dev' +__version__ = '1.1.1-dev' from source.classes.BabelFish import BabelFish diff --git a/PotShuffle.py b/PotShuffle.py index a2a10c0f..88963ffe 100644 --- a/PotShuffle.py +++ b/PotShuffle.py @@ -745,11 +745,11 @@ vanilla_pots = { 0xE7: [Pot(68, 5, PotItem.OneRupee, 'Death Mountain Return Cave (right)', obj=RoomObject(0x0AB389, [0x8B, 0x2B, 0xFA])), Pot(72, 5, PotItem.OneRupee, 'Death Mountain Return Cave (right)', obj=RoomObject(0x0AB38C, [0x93, 0x2B, 0xFA]))], 0xE8: [Pot(96, 4, PotItem.Heart, 'Superbunny Cave (Bottom)', obj=RoomObject(0x0AA98E, [0xC3, 0x23, 0xFA]))], - 0xEB: [Pot(206, 8, PotItem.FiveRupees, 'Bumper Cave', obj=RoomObject(0x0AADE7, [0x9F, 0x47, 0xFA])), - Pot(210, 8, PotItem.FiveRupees, 'Bumper Cave', obj=RoomObject(0x0AADEA, [0xA7, 0x47, 0xFA])), - Pot(88, 14, PotItem.SmallMagic, 'Bumper Cave', obj=RoomObject(0x0AADED, [0xB3, 0x73, 0xFA])), - Pot(92, 14, PotItem.Heart, 'Bumper Cave', obj=RoomObject(0x0AADF0, [0xBB, 0x73, 0xFA])), - Pot(96, 14, PotItem.SmallMagic, 'Bumper Cave', obj=RoomObject(0x0AADF3, [0xC3, 0x73, 0xFA]))], + 0xEB: [Pot(206, 8, PotItem.FiveRupees, 'Bumper Cave (bottom)', obj=RoomObject(0x0AADE7, [0x9F, 0x47, 0xFA])), + Pot(210, 8, PotItem.FiveRupees, 'Bumper Cave (bottom)', obj=RoomObject(0x0AADEA, [0xA7, 0x47, 0xFA])), + Pot(88, 14, PotItem.SmallMagic, 'Bumper Cave (bottom)', obj=RoomObject(0x0AADED, [0xB3, 0x73, 0xFA])), + Pot(92, 14, PotItem.Heart, 'Bumper Cave (bottom)', obj=RoomObject(0x0AADF0, [0xBB, 0x73, 0xFA])), + Pot(96, 14, PotItem.SmallMagic, 'Bumper Cave (bottom)', obj=RoomObject(0x0AADF3, [0xC3, 0x73, 0xFA]))], 0xF1: [Pot(64, 5, PotItem.Heart, 'Old Man Cave', obj=RoomObject(0x0AA6B2, [0x83, 0x2B, 0xFA]))], 0xF3: [Pot(0x28, 0x14, PotItem.Nothing, 'Elder House', obj=RoomObject(0x0AA76F, [0x53, 0xA3, 0xFA])), Pot(0x2C, 0x14, PotItem.Nothing, 'Elder House', obj=RoomObject(0x0AA772, [0x5B, 0xA3, 0xFA])), @@ -851,10 +851,10 @@ vanilla_pots = { Pot(100, 22, PotItem.Heart, 'Dark Lake Hylia Ledge Spike Cave', obj=RoomObject(0x0AB62A, [0xCB, 0xB3, 0xFA])), Pot(88, 28, PotItem.Heart, 'Dark Lake Hylia Ledge Spike Cave', obj=RoomObject(0x0AB633, [0xB3, 0xE3, 0xFA])), Pot(100, 28, PotItem.Heart, 'Dark Lake Hylia Ledge Spike Cave', obj=RoomObject(0x0AB636, [0xCB, 0xE3, 0xFA]))], - 0x127: [Pot(24, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2A801A, [0x33, 0xCB, 0xFA])), - Pot(28, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2A801D, [0x3B, 0xCB, 0xFA])), - Pot(32, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2A8020, [0x43, 0xCB, 0xFA])), - Pot(36, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2A8023, [0x4B, 0xCB, 0xFA]))], + 0x127: [Pot(24, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2B801A, [0x33, 0xCB, 0xFA])), + Pot(28, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2B801D, [0x3B, 0xCB, 0xFA])), + Pot(32, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2B8020, [0x43, 0xCB, 0xFA])), + Pot(36, 25, PotItem.Nothing, 'Dark World Hammer Peg Cave', obj=RoomObject(0x2B8023, [0x4B, 0xCB, 0xFA]))], } diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ba7ac9e0..eff11535 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -181,6 +181,9 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o # Bug Fixes and Notes +* 1.1.1 + * Fixed a logic bug with Bumper Cave where the pots were accessible without Cape or Hookshot from the top entrance + * Fixed a pot coloring issue with hammer peg cave * 1.1.0 * Large features * New pottery modes - see notes above diff --git a/Regions.py b/Regions.py index 31a5ab92..506a8116 100644 --- a/Regions.py +++ b/Regions.py @@ -181,7 +181,8 @@ def create_regions(world, player): create_cave_region(player, 'Chest Game', 'a game of 16 chests', ['Chest Game']), create_cave_region(player, 'Red Shield Shop', 'the rare shop', ['Red Shield Shop - Left', 'Red Shield Shop - Middle', 'Red Shield Shop - Right']), create_cave_region(player, 'Dark Sanctuary Hint', 'a storyteller'), - create_cave_region(player, 'Bumper Cave', 'a connector', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Exit (Top)']), + create_cave_region(player, 'Bumper Cave (bottom)', 'a connector', None, ['Bumper Cave Exit (Bottom)', 'Bumper Cave Bottom to Top']), + create_cave_region(player, 'Bumper Cave (top)', 'a connector', None, ['Bumper Cave Exit (Top)', 'Bumper Cave Top To Bottom']), create_dw_region(player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], ['Bumper Cave Ledge Drop', 'Bumper Cave (Top)', 'Bumper Cave Ledge Mirror Spot'], 'a ledge with an item'), create_dw_region(player, 'Skull Woods Forest', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']), diff --git a/Rules.py b/Rules.py index a553fbfe..68f9e616 100644 --- a/Rules.py +++ b/Rules.py @@ -855,8 +855,8 @@ def default_rules(world, player): set_rule(world.get_entrance('Peg Area Rocks', player), lambda state: state.has_Pearl(player) and state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('Village of Outcasts Pegs', player), lambda state: state.has_Pearl(player) and state.has('Hammer', player)) set_rule(world.get_entrance('Grassy Lawn Pegs', player), lambda state: state.has_Pearl(player) and state.has('Hammer', player)) - set_rule(world.get_entrance('Bumper Cave Exit (Top)', player), lambda state: state.has('Cape', player)) - set_rule(world.get_entrance('Bumper Cave Exit (Bottom)', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player)) + set_rule(world.get_entrance('Bumper Cave Bottom to Top', player), lambda state: state.has('Cape', player)) + set_rule(world.get_entrance('Bumper Cave Top To Bottom', player), lambda state: state.has('Cape', player) or state.has('Hookshot', player)) set_rule(world.get_entrance('Skull Woods Final Section', player), lambda state: state.has('Fire Rod', player) and state.has_Pearl(player)) # bunny cannot use fire rod set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_Pearl(player) and state.has_sword(player) and state.has_misery_mire_medallion(player)) # sword required to cast magic (!) @@ -1782,8 +1782,8 @@ def set_bunny_rules(world, player, inverted): # regions for the exits of multi-entrace caves/drops that bunny cannot pass # Note spiral cave may be technically passible, but it would be too absurd to require since OHKO mode is a thing. - bunny_impassable_caves = ['Bumper Cave', 'Two Brothers House', 'Hookshot Cave (Middle)', - 'Pyramid', 'Spiral Cave (Top)', 'Fairy Ascension Cave (Drop)'] + bunny_impassable_caves = ['Bumper Cave (top)', 'Bumper Cave (bottom)', 'Two Brothers House', + 'Hookshot Cave (Middle)', 'Pyramid', 'Spiral Cave (Top)', 'Fairy Ascension Cave (Drop)'] bunny_accessible_locations = ['Link\'s Uncle', 'Sahasrahla', 'Sick Kid', 'Lost Woods Hideout', 'Lumberjack Tree', 'Checkerboard Cave', 'Potion Shop', 'Spectacle Rock Cave', 'Pyramid', 'Hype Cave - Generous Guy', 'Peg Cave', 'Bumper Cave Ledge', 'Dark Blacksmith Ruins', From 1167f2b1ba3feabf2c0c99fac617c00b6ac30dbe Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 27 Oct 2022 15:23:58 -0600 Subject: [PATCH 051/146] Bumper cave fix for new entrance shuffle --- source/overworld/EntranceShuffle2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index da454795..708e26ac 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -2290,8 +2290,8 @@ default_connections = {'Links House': 'Links House', 'C-Shaped House': 'C-Shaped House', 'Chest Game': 'Chest Game', 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', - 'Bumper Cave (Bottom)': 'Bumper Cave', - 'Bumper Cave (Top)': 'Bumper Cave', + 'Bumper Cave (Bottom)': 'Bumper Cave (bottom)', + 'Bumper Cave (Top)': 'Bumper Cave (top)', 'Red Shield Shop': 'Red Shield Shop', 'Dark Sanctuary Hint': 'Dark Sanctuary Hint', 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', @@ -2452,7 +2452,7 @@ inverted_default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', 'Inverted Big Bomb Shop': 'Inverted Big Bomb Shop', 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary', 'Inverted Dark Sanctuary Exit': 'West Dark World', - 'Old Man Cave (West)': 'Bumper Cave', + 'Old Man Cave (West)': 'Bumper Cave (bottom)', 'Old Man Cave (East)': 'Death Mountain Return Cave (left)', 'Old Man Cave Exit (West)': 'West Dark World', 'Old Man Cave Exit (East)': 'Dark Death Mountain', @@ -2461,7 +2461,7 @@ inverted_default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', 'Bumper Cave (Top)': 'Dark Death Mountain Healer Fairy', 'Bumper Cave Exit (Top)': 'Death Mountain Return Ledge', 'Bumper Cave Exit (Bottom)': 'Light World', - 'Death Mountain Return Cave (West)': 'Bumper Cave', + 'Death Mountain Return Cave (West)': 'Bumper Cave (top)', 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', 'Death Mountain Return Cave Exit (West)': 'Death Mountain', 'Death Mountain Return Cave Exit (East)': 'Death Mountain', From bd619ff2ef6847956be40e302cca2682614954a2 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 27 Oct 2022 15:48:04 -0600 Subject: [PATCH 052/146] Bumper cave fixes for ES2 --- source/overworld/EntranceShuffle2.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 708e26ac..ad073162 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -2292,6 +2292,8 @@ default_connections = {'Links House': 'Links House', 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', 'Bumper Cave (Bottom)': 'Bumper Cave (bottom)', 'Bumper Cave (Top)': 'Bumper Cave (top)', + 'Bumper Cave Top To Bottom': 'Bumper Cave (bottom)', + 'Bumper Cave Bottom to Top': 'Bumper Cave (top)', 'Red Shield Shop': 'Red Shield Shop', 'Dark Sanctuary Hint': 'Dark Sanctuary Hint', 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', @@ -2453,6 +2455,8 @@ inverted_default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary', 'Inverted Dark Sanctuary Exit': 'West Dark World', 'Old Man Cave (West)': 'Bumper Cave (bottom)', + 'Bumper Cave Top To Bottom': 'Bumper Cave (bottom)', + 'Bumper Cave Bottom to Top': 'Bumper Cave (top)', 'Old Man Cave (East)': 'Death Mountain Return Cave (left)', 'Old Man Cave Exit (West)': 'West Dark World', 'Old Man Cave Exit (East)': 'Dark Death Mountain', From 82965ac734a7a5f7cebbe442eef60f99f1573043 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 28 Oct 2022 08:56:06 -0600 Subject: [PATCH 053/146] Big Key fix for dungeons with only big chests Door pairing issues Minor gui error --- DoorShuffle.py | 40 ++++++------------- .../app/gui/randomize/dungeon/widgets.json | 2 +- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 1dea2f99..5737a5b8 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -831,7 +831,8 @@ def main_dungeon_pool(dungeon_pool, world, player): for name in pool: builder = world.dungeon_layouts[player][name] region_set = builder.master_sector.region_set() - builder.bk_required = builder.bk_door_proposal or any(x in region_set for x in special_bk_regions) + builder.bk_required = (builder.bk_door_proposal or any(x in region_set for x in special_bk_regions) + or len(world.key_logic[player][name].bk_chests) > 0) dungeon = world.get_dungeon(name, player) if not builder.bk_required or builder.bk_provided: dungeon.big_key = None @@ -2362,21 +2363,16 @@ def find_big_key_door_candidates(region, checked, used, world, player): if valid and d.dest not in candidates: # interior doors are not separable yet candidates.append(d.dest) elif d.type == DoorType.Normal: - if decoupled: - valid = kind in okay_normals - else: + valid = kind in okay_normals + if valid and not decoupled: d2 = d.dest if d2 not in candidates and d2 not in used: if d2.type == DoorType.Normal: room_b = world.get_room(d2.roomIndex, player) pos_b, kind_b = room_b.doorList[d2.doorListPos] - valid = kind in okay_normals and kind_b in okay_normals and valid_key_door_pair(d, d2) - else: - valid = kind in okay_normals + valid &= kind_b in okay_normals and valid_key_door_pair(d, d2) if valid and 0 <= d2.doorListPos < 4: candidates.append(d2) - else: - valid = True if valid and d not in candidates: candidates.append(d) connected = ext.connected_region @@ -2628,21 +2624,16 @@ def find_bd_door_candidates(region, checked, used, world, player): if valid and d.dest not in candidates: # interior doors are not separable yet candidates.append(d.dest) elif d.type == DoorType.Normal: - if decoupled: - valid = kind in okay_normals - else: + valid = kind in okay_normals + if valid and not decoupled: d2 = d.dest if d2 not in candidates and d2 not in used: if d2.type == DoorType.Normal: room_b = world.get_room(d2.roomIndex, player) pos_b, kind_b = room_b.doorList[d2.doorListPos] - valid = kind in okay_normals and kind_b in okay_normals and valid_key_door_pair(d, d2) - else: - valid = kind in okay_normals + valid &= kind_b in okay_normals and valid_key_door_pair(d, d2) if valid and 0 <= d2.doorListPos < 4: candidates.append(d2) - else: - valid = True if valid and d not in candidates: candidates.append(d) connected = ext.connected_region @@ -2702,8 +2693,8 @@ def reassign_bd_doors(bd_map, world, player): elif d.type is DoorType.Normal and not_in_proposal(d): if not d.entranceFlag: world.get_room(d.roomIndex, player).change(d.doorListPos, DoorKind.Normal) - do_bombable_dashable(flat_bomb_proposal, DoorKind.Bombable, world, player) - do_bombable_dashable(flat_dash_proposal, DoorKind.Dashable, world, player) + do_bombable_dashable(pair[0], DoorKind.Bombable, world, player) + do_bombable_dashable(pair[1], DoorKind.Dashable, world, player) def do_bombable_dashable(proposal, kind, world, player): @@ -2864,21 +2855,16 @@ def find_key_door_candidates(region, checked, used, world, player): elif d.type == DoorType.SpiralStairs: valid = kind in [DoorKind.StairKey, DoorKind.StairKey2, DoorKind.StairKeyLow] elif d.type == DoorType.Normal: - if decoupled: - valid = kind in okay_normals - else: + valid = kind in okay_normals + if valid and not decoupled: d2 = d.dest if d2 not in candidates and d2 not in used: if d2.type == DoorType.Normal: room_b = world.get_room(d2.roomIndex, player) pos_b, kind_b = room_b.doorList[d2.doorListPos] - valid = kind in okay_normals and kind_b in okay_normals and valid_key_door_pair(d, d2) - else: - valid = kind in okay_normals + valid &= kind_b in okay_normals and valid_key_door_pair(d, d2) if valid and 0 <= d2.doorListPos < 4: candidates.append(d2) - else: - valid = True if valid and d not in candidates: candidates.append(d) connected = ext.connected_region diff --git a/resources/app/gui/randomize/dungeon/widgets.json b/resources/app/gui/randomize/dungeon/widgets.json index 19606b23..bdedbfba 100644 --- a/resources/app/gui/randomize/dungeon/widgets.json +++ b/resources/app/gui/randomize/dungeon/widgets.json @@ -1,6 +1,6 @@ { "widgets": { - "keyshuffle": { + "smallkeyshuffle": { "type": "selectbox", "options": [ "none", From 9fafa8981e5aadf6ed474ddff9940dba327f3b62 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 28 Oct 2022 12:47:43 -0600 Subject: [PATCH 054/146] Big Key Door fix for when big key double sided is off Fix for basic issues - key total doesn't change Potential key lock logic fix --- DoorShuffle.py | 24 +++++++++++++++++------- Rules.py | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 5737a5b8..5458c020 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1903,9 +1903,11 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl custom_key_doors = world.custom_door_types[player]['Key Door'] else: custom_key_doors = defaultdict(list) - + total_adjustable = len(pool) > 1 for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] + if not total_adjustable: + builder.total_keys = total_keys find_small_key_door_candidates(builder, start_regions_map[dungeon], used_doors, world, player) if custom_key_doors[dungeon]: builder.candidates.small = filter_key_door_pool(builder.candidates.small, custom_key_doors[dungeon]) @@ -1930,11 +1932,15 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl flex_map[dungeon] = (limit - suggested) if suggested < limit else 0 for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] + if total_adjustable: + builder.total_keys = suggestion_map[dungeon] valid_doors, small_number = find_valid_combination(builder, suggestion_map[dungeon], start_regions_map[dungeon], world, player) small_map[dungeon] = valid_doors actual_chest_keys = small_number - builder.key_drop_cnt if actual_chest_keys < suggestion_map[dungeon]: + if total_adjustable: + builder.total_keys = actual_chest_keys flex_map[dungeon] = 0 remaining += suggestion_map[dungeon] - actual_chest_keys suggestion_map[dungeon] = small_number @@ -1953,6 +1959,8 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl remaining -= 1 suggestion_map[dungeon] = increased flex_map[dungeon] -= 1 + if total_adjustable: + builder.total_keys = actual_chest_keys if flex_map[dungeon] > 0: builder.combo_size = ncr(len(builder.candidates.small), builder.key_doors_num) queue.append(builder) @@ -2464,7 +2472,8 @@ def reassign_big_key_doors(bk_map, world, player): d = obj if d.type is DoorType.Interior: change_door_to_big_key(d, world, player) - d.dest.bigKey = True # ensure flag is set + if world.door_type_mode[player] != 'original': + d.dest.bigKey = True # ensure flag is set when bk doors are double sided elif d.type is DoorType.SpiralStairs: pass # we don't have spiral stairs candidates yet that aren't already key doors elif d.type is DoorType.Normal: @@ -2574,7 +2583,6 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k # make changes if player not in world.key_logic.keys(): world.key_logic[player] = {} - builder.total_keys = builder.key_doors_num analyze_dungeon(key_layout, world, player) builder.key_door_proposal = proposal world.key_logic[player][builder.name] = key_layout.key_logic @@ -2620,8 +2628,9 @@ def find_bd_door_candidates(region, checked, used, world, player): room = world.get_room(d.roomIndex, player) position, kind = room.doorList[d.doorListPos] if d.type == DoorType.Interior: - valid = kind in okay_interiors - if valid and d.dest not in candidates: # interior doors are not separable yet + # interior doors are not separable yet + valid = kind in okay_interiors and d.dest not in used + if valid and d.dest not in candidates: candidates.append(d.dest) elif d.type == DoorType.Normal: valid = kind in okay_normals @@ -2849,8 +2858,9 @@ def find_key_door_candidates(region, checked, used, world, player): room = world.get_room(d.roomIndex, player) position, kind = room.doorList[d.doorListPos] if d.type == DoorType.Interior: - valid = kind in okay_interiors - if valid and d.dest not in candidates: # interior doors are not separable yet + valid = kind in okay_interiors and d.dest not in used + # interior doors are not separable yet + if valid and d.dest not in candidates: candidates.append(d.dest) elif d.type == DoorType.SpiralStairs: valid = kind in [DoorKind.StairKey, DoorKind.StairKey2, DoorKind.StairKeyLow] diff --git a/Rules.py b/Rules.py index 3867d681..fa07bd5a 100644 --- a/Rules.py +++ b/Rules.py @@ -2093,7 +2093,7 @@ def eval_small_key_door_main(state, door_name, dungeon, player): elif ruleType == KeyRuleType.AllowSmall: if (door_rule.small_location.item and door_rule.small_location.item.name == key_logic.small_key_name and door_rule.small_location.item.player == player): - return True # always okay if allow small is on + door_openable |= state.has_sm_key(key_logic.small_key_name, player, number) elif isinstance(ruleType, tuple): lock, lock_item = ruleType # this doesn't track logical locks yet, i.e. hammer locks the item and hammer is there, but the item isn't From cb4cf65c9c9a0be03a1a754a3b3e585d89470fd0 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 1 Nov 2022 15:05:28 -0600 Subject: [PATCH 055/146] More robust sweep_for_events (supports events that later become unreachable) Minor fix for AllowSmall key logic --- BaseClasses.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 60d04d82..06c1855d 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -786,7 +786,21 @@ class CollectionState(object): else: door_candidates.append(door.name) return door_candidates - return None + door_candidates, skip = [], set() + if state.world.accessibility[player] != 'locations' and remaining_keys == 0: + key_logic = state.world.key_logic[player][dungeon_name] + for door, paired in key_logic.sm_doors.items(): + if door.name in key_logic.door_rules: + rule = key_logic.door_rules[door.name] + key = KeyRuleType.AllowSmall + if (key in rule.new_rules and key_total >= rule.new_rules[key] and door.name not in skip + and door.name in state.reached_doors[player] and door.name not in state.opened_doors[player]): + if paired: + door_candidates.append((door.name, paired.name)) + skip.add(paired.name) + else: + door_candidates.append(door.name) + return door_candidates if door_candidates else None @staticmethod def print_rrp(rrp): @@ -925,29 +939,30 @@ class CollectionState(object): checked_locations = set([l for l in locations if l in self.locations_checked]) reachable_events = [location for location in locations if location.event and location.can_reach(self)] reachable_events = self._do_not_flood_the_keys(reachable_events) + found_new = False for event in reachable_events: if event not in checked_locations: self.events.append((event.name, event.player)) self.collect(event.item, True, event) - return len(reachable_events) > len(checked_locations) + found_new = True + return found_new def sweep_for_events(self, key_only=False, locations=None): # this may need improvement if locations is None: locations = self.world.get_filled_locations() new_locations = True - checked_locations = 0 while new_locations: reachable_events = [location for location in locations if location.event and (not key_only or (self.world.keyshuffle[location.item.player] == 'none' and location.item.smallkey) or (not self.world.bigkeyshuffle[location.item.player] and location.item.bigkey)) and location.can_reach(self)] reachable_events = self._do_not_flood_the_keys(reachable_events) + new_locations = False for event in reachable_events: if (event.name, event.player) not in self.events: self.events.append((event.name, event.player)) self.collect(event.item, True, event) - new_locations = len(reachable_events) > checked_locations - checked_locations = len(reachable_events) + new_locations = True def can_reach_blue(self, region, player): From fa75d2b4e978c6653262de5dd81129d9cd07907d Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 10 Nov 2022 14:14:54 -0700 Subject: [PATCH 056/146] Possible fix for standing items weirdness Generation fix for Bumper Cave Chaos door type fix Minor fix for universal keys Relaase notes update --- BaseClasses.py | 2 +- DoorShuffle.py | 10 +- RELEASENOTES.md | 239 ++++++++------------------- Rom.py | 2 +- data/base2current.bps | Bin 93445 -> 93456 bytes source/overworld/EntranceShuffle2.py | 8 +- 6 files changed, 79 insertions(+), 182 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 06c1855d..d89147c9 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -787,7 +787,7 @@ class CollectionState(object): door_candidates.append(door.name) return door_candidates door_candidates, skip = [], set() - if state.world.accessibility[player] != 'locations' and remaining_keys == 0: + if state.world.accessibility[player] != 'locations' and remaining_keys == 0 and dungeon_name != 'Universal': key_logic = state.world.key_logic[player][dungeon_name] for door, paired in key_logic.sm_doors.items(): if door.name in key_logic.door_rules: diff --git a/DoorShuffle.py b/DoorShuffle.py index 5458c020..ad22b1c0 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1744,7 +1744,7 @@ class DoorTypePool: @staticmethod def get_choices(number): - return [max(number-i, 0) for i in range(-1, 5)] + return [max(number+i, 0) for i in range(-1, 5)] class BuilderDoorCandidates: @@ -2208,6 +2208,7 @@ def find_bk_special_location(builder, world, player): return loc return None + def check_required_paths_with_traps(paths, proposal, dungeon_name, start_regions, world, player): cached_initial_state = None if len(paths[dungeon_name]) > 0: @@ -2673,8 +2674,11 @@ def find_valid_bd_combination(builder, suggested, world, player): bd_door_pool = filter_key_door_pool(bd_door_pool, custom_dash_doors) dash_doors_needed -= len(custom_dash_doors) while len(bd_door_pool) < bomb_doors_needed + dash_doors_needed: - bomb_doors_needed = round(len(bd_door_pool) * bomb_doors_needed/ttl_needed) - dash_doors_needed = round(len(bd_door_pool) * dash_doors_needed/ttl_needed) + test = random.choice([True, False]) + if test: + bomb_doors_needed -= 1 + else: + dash_doors_needed -= 1 bomb_proposal = random.sample(bd_door_pool, k=bomb_doors_needed) bomb_proposal.extend(custom_bomb_doors) dash_pool = [x for x in bd_door_pool if x not in bomb_proposal] diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ce89548a..8fc802a6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,215 +1,108 @@ -## New Features +# New Features -## Pottery Lottery and Key Drop Shuffle Changes +One major change with this update is that big key doors and certain trap doors are no longer guaranteed to be vanilla in Dungeon Door Shuffle modes even if you choose not to shuffle those types. A newer algorithm for putting dungeons together has been written and it will remove big key doors and trap doors when necessary to ensure progress can be made. -### Pottery +Please note that retro features are now independently customizable as referenced below. Selecting Retro mode or World State: Retro will change Bow Mode to Retro (Progressive). Take Anys to Random, and Small Keys to Universal. -New pottery option that control which pots (and large blocks) are in the locations pool: +## Flute Mode -* None: No pots are in the pool, like normal randomizer -* Key Pots: The pots that have keys are in the pool. This is about half of the old keydropshuffle option -* Cave Pots: The pots that are not found in dungeons are in the pool. (Includes the large block in Spike Cave). Does -not include key pots. -* CaveKeys: Both non-dungeon pots and pots that used to have keys are in the pool. -* Reduced: Same as CaveKeys but also roughly a quarter of dungeon pots are added to the location pool picked at random. This is a dynamic mode so pots in the pool will be colored. Pots out of the pool will have vanilla contents. -* Clustered: Like reduced but pots are grouped by logical sets and roughly 50% of pots are chosen from those group. This is a dynamic mode like the above. -* Nonempty: All pots that had some sort of objects under them are chosen to be in the location pool. This excludes most large blocks and some pots out of dungeons. -* Dungeon Pots: The pots that are in dungeons are in the pool. (Includes serveral large blocks) -* Lottery: All pots and large blocks are in the pool +Normal mode for flute means you need to activate it at the village statue after finding it like usual. +Activated flute mode mean you can use it immediately upon finding it. the flute SFX plays to let you know this is the case. -By default, switches remain in their vanilla location (unless you turn on the legacy option below) +## Bow Mode -CLI `--pottery
    (&XkW@Bl?gM0pEv)Ism=-ZKtg*IL#4 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 UF#+0cl~6 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

    >i{#XS+f33w7XyErhUX^pq-345R?lQ~j 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

    Uy4${(lPFx6v9#e&c``KR6-Zh!4$s%jJEDT# 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


    s4aAQq-0nyr%f^ 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

    ?3{Fv=?Fb*jJ1LX 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 @Hrbqq(=lF)<1xRS1yNLn#X#*z;bed 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 z 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 Eebe+9L5 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%0AKZndJ?W>F2NqbZM@bM8qq!tsAa0&G(DJN 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 Fr`9+JyWGUb0b9Yn%sdm=u-TfLe!(j# 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
    4F~)xT{_M8yOpsJZRdjceho*G4nT;U(#}4 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%0D@euj?mAdnIu7G5z1Aiol>^9$C} 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 Date: Mon, 26 Dec 2022 05:09:27 -0600 Subject: [PATCH 079/146] Changing mirror exits to be dynamically created --- Main.py | 9 +- OWEdges.py | 190 +--------- OverworldShuffle.py | 529 ++++++++++++++------------- Regions.py | 326 ++++++++--------- Rules.py | 285 +-------------- source/overworld/EntranceShuffle2.py | 46 --- 6 files changed, 456 insertions(+), 929 deletions(-) diff --git a/Main.py b/Main.py index 017a9262..03c78887 100644 --- a/Main.py +++ b/Main.py @@ -16,7 +16,7 @@ from OverworldGlitchRules import create_owg_connections from PotShuffle import shuffle_pots, shuffle_pot_switches from Regions import create_regions, create_shops, mark_light_dark_world_regions, create_dungeon_regions, adjust_locations from OWEdges import create_owedges -from OverworldShuffle import link_overworld, update_world_regions, create_flute_exits +from OverworldShuffle import link_overworld, update_world_regions, create_flute_exits, create_mirror_exits from EntranceShuffle import link_entrances from Rom import patch_rom, patch_race_rom, patch_enemizer, apply_rom_settings, LocalRom, JsonRom, get_hash_string from Doors import create_doors @@ -232,6 +232,8 @@ def main(args, seed=None, fish=None): update_world_regions(world, player) mark_light_dark_world_regions(world, player) create_flute_exits(world, player) + create_mirror_exits(world, player) + world.initialize_regions() logger.info(world.fish.translate("cli","cli","shuffling.world")) @@ -522,11 +524,14 @@ def copy_world(world): if world.logic[player] in ('owglitches', 'nologic'): create_owg_connections(ret, player) create_flute_exits(ret, player) + create_mirror_exits(ret, player) create_dungeon_regions(ret, player) create_owedges(ret, player) create_shops(ret, player) + #create_doors(ret, player) create_rooms(ret, player) create_dungeons(ret, player) + world.initialize_regions() # there are region references here they must be migrated to preserve integrity # ret.exp_cache = world.exp_cache.copy() @@ -698,6 +703,8 @@ def copy_world_premature(world, player): if world.logic[player] in ('owglitches', 'nologic'): create_owg_connections(ret, player) create_flute_exits(ret, player) + create_mirror_exits(ret, player) + world.initialize_regions() create_dungeon_regions(ret, player) create_owedges(ret, player) create_shops(ret, player) diff --git a/OWEdges.py b/OWEdges.py index 7fe4b016..01b2ad69 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1733,195 +1733,7 @@ OWExitTypes = { 'Qirn Jump Whirlpool', 'Bomber Corner Whirlpool' ], - 'Mirror': ['Skull Woods Back Mirror Spot', - 'Skull Woods Forgotten (West) Mirror Spot', - 'Skull Woods Forgotten (East) Mirror Spot', - 'Skull Woods Portal Entry Mirror Spot', - 'Skull Woods Forgotten (Middle) Mirror Spot', - 'Skull Woods Front Mirror Spot', - 'Dark Lumberjack Mirror Spot', - 'West Dark Death Mountain (Top) Mirror Spot', - 'Bubble Boy Mirror Spot', - 'West Dark Death Mountain (Bottom) Mirror Spot', - 'East Dark Death Mountain (Top West) Mirror Spot', - 'East Dark Death Mountain (Top East) Mirror Spot', - 'TR Ledge (West) Mirror Spot', - 'TR Ledge (East) Mirror Spot', - 'TR Isolated Mirror Spot', - 'East Dark Death Mountain (Bottom Plateau) Mirror Spot', - 'East Dark Death Mountain (Bottom Left) Mirror Spot', - 'East Dark Death Mountain (Bottom) Mirror Spot', - 'Dark Floating Island Mirror Spot', - 'Turtle Rock Mirror Spot', - 'Turtle Rock Ledge Mirror Spot', - 'Bumper Cave Area Mirror Spot', - 'Bumper Cave Entry Mirror Spot', - 'Bumper Cave Ledge Mirror Spot', - 'Catfish Mirror Spot', - 'Skull Woods Pass West Mirror Spot', - 'Skull Woods Pass East Top Mirror Spot', - 'Skull Woods Pass Portal Mirror Spot', - 'Skull Woods Pass East Bottom Mirror Spot', - 'Outcast Fortune Mirror Spot', - 'Outcast Pond Mirror Spot', - 'Dark Chapel Mirror Spot', - 'Dark Chapel Ledge Mirror Spot', - 'Dark Graveyard Mirror Spot', - 'Dark Graveyard Ledge Mirror Spot', - 'Dark Graveyard Grave Mirror Spot', - 'Qirn Jump Mirror Spot', - 'Qirn Jump East Mirror Spot', - 'Dark Witch Mirror Spot', - 'Dark Witch Northeast Mirror Spot', - 'Catfish Approach Mirror Spot', - 'Catfish Approach Ledge Mirror Spot', - 'Village of Outcasts Mirror Spot', - 'Village of Outcasts Southwest Mirror Spot', - 'Hammer House Mirror Spot', - 'Shield Shop Mirror Spot', - 'Pyramid Mirror Spot', - 'Pyramid Pass Mirror Spot', - 'Pyramid Courtyard Mirror Spot', - 'Pyramid Uncle Mirror Spot', - 'Pyramid From Ledge Mirror Spot', - 'Pyramid Entry Mirror Spot', - 'Broken Bridge West Mirror Spot', - 'Broken Bridge East Mirror Spot', - 'Broken Bridge Northeast Mirror Spot', - 'Palace of Darkness Mirror Spot', - 'Hammer Pegs Mirror Spot', - 'Hammer Pegs Entry Mirror Spot', - 'Dark Dunes Mirror Spot', - 'Dig Game Mirror Spot', - 'Dig Game Ledge Mirror Spot', - 'Frog Mirror Spot', - 'Frog Prison Mirror Spot', - 'Archery Game Mirror Spot', - 'Stumpy Mirror Spot', - 'Stumpy Pass Mirror Spot', - 'Dark Bonk Rocks Mirror Spot', - 'Big Bomb Shop Mirror Spot', - 'Hammer Bridge North Mirror Spot', - 'Hammer Bridge South Mirror Spot', - 'Dark Hobo Mirror Spot', - 'Dark Tree Line Mirror Spot', - 'Darkness Nook Mirror Spot', - 'Misery Mire Mirror Spot', - 'Misery Mire Ledge Mirror Spot', - 'Misery Mire Blocked Mirror Spot', - 'Misery Mire Main Mirror Spot', - 'Stumpy Approach Mirror Spot', - 'Stumpy Bush Entry Mirror Spot', - 'Dark C Whirlpool Mirror Spot', - 'Dark C Whirlpool Outer Mirror Spot', - 'Hype Cave Mirror Spot', - 'Ice Lake Mirror Spot', - 'Ice Lake Southwest Mirror Spot', - 'Ice Lake Southeast Mirror Spot', - 'Ice Lake Northeast Mirror Spot', - 'Ice Palace Mirror Spot', - 'Ice Lake Moat Mirror Spot', - 'Shopping Mall Mirror Spot', - 'Swamp Nook Mirror Spot', - 'Swamp Nook Southeast Mirror Spot', - 'Swamp Nook Pegs Mirror Spot', - 'Swamp Mirror Spot', - 'Dark South Pass Mirror Spot', - 'Bomber Corner Mirror Spot', - 'Lost Woods East Mirror Spot', - 'Lost Woods Entry Mirror Spot', - 'Lost Woods Pedestal Mirror Spot', - 'Lost Woods Southwest Mirror Spot', - 'Lost Woods East (Forgotten) Mirror Spot', - 'Lost Woods West (Forgotten) Mirror Spot', - 'Lumberjack Mirror Spot', - 'West Death Mountain (Top) Mirror Spot', - 'Spectacle Rock Mirror Spot', - 'East Death Mountain (Top West) Mirror Spot', - 'East Death Mountain (Top East) Mirror Spot', - 'Fairy Ascension Mirror Spot', - 'Death Mountain Bridge Mirror Spot', - 'Spiral Cave Mirror Spot', - 'Mimic Cave Mirror Spot', - 'Isolated Ledge Mirror Spot', - 'Floating Island Mirror Spot', - 'TR Pegs Area Mirror Spot', - 'Mountain Entry Mirror Spot', - 'Mountain Entry Entrance Mirror Spot', - 'Mountain Entry Ledge Mirror Spot', - 'Zora Waterfall Mirror Spot', - 'Lost Woods Pass West Mirror Spot', - 'Lost Woods Pass East Top Mirror Spot', - 'Lost Woods Pass Portal Mirror Spot', - 'Lost Woods Pass East Bottom Mirror Spot', - 'Kakariko Fortune Mirror Spot', - 'Kakariko Pond Mirror Spot', - 'Sanctuary Mirror Spot', - 'Bonk Rock Ledge Mirror Spot', - 'Graveyard Ledge Mirror Spot', - 'Kings Grave Mirror Spot', - 'River Bend Mirror Spot', - 'River Bend East Mirror Spot', - 'Potion Shop Mirror Spot', - 'Potion Shop Northeast Mirror Spot', - 'Zora Approach Mirror Spot', - 'Zora Approach Ledge Mirror Spot', - 'Kakariko Mirror Spot', - 'Kakariko Grass Mirror Spot', - 'Forgotton Forest Mirror Spot', - 'Forgotton Forest Fence Mirror Spot', - 'HC Ledge Mirror Spot', - 'HC Courtyard Mirror Spot', - 'HC Area Mirror Spot', - 'HC East Entry Mirror Spot', - 'HC Courtyard Left Mirror Spot', - 'HC Area South Mirror Spot', - 'Wooden Bridge Mirror Spot', - 'Wooden Bridge Northeast Mirror Spot', - 'Wooden Bridge West Mirror Spot', - 'Eastern Palace Mirror Spot', - 'Blacksmith Entry Mirror Spot', - 'Blacksmith Mirror Spot', - 'Bat Cave Ledge Mirror Spot', - 'Sand Dunes Mirror Spot', - 'Maze Race Mirror Spot', - 'Maze Race Ledge Mirror Spot', - 'Kakariko Suburb Mirror Spot', - 'Kakariko Suburb South Mirror Spot', - 'Flute Boy Mirror Spot', - 'Flute Boy Pass Mirror Spot', - 'Central Bonk Rocks Mirror Spot', - 'Links House Mirror Spot', - 'Stone Bridge Mirror Spot', - 'Stone Bridge South Mirror Spot', - 'Hobo Mirror Spot', - 'Tree Line Mirror Spot', - 'Eastern Nook Mirror Spot', - 'Desert Mirror Spot', - 'Desert Ledge Mirror Spot', - 'Checkerboard Mirror Spot', - 'DP Stairs Mirror Spot', - 'DP Entrance (North) Mirror Spot', - 'Bombos Tablet Ledge Mirror Spot', - 'Cave 45 Mirror Spot', - 'Flute Boy Entry Mirror Spot', - 'C Whirlpool Mirror Spot', - 'C Whirlpool Outer Mirror Spot', - 'Statues Mirror Spot', - 'Lake Hylia Mirror Spot', - 'Lake Hylia Northeast Mirror Spot', - 'South Shore Mirror Spot', - 'South Shore East Mirror Spot', - 'Lake Hylia Island Mirror Spot', - 'Lake Hylia Water Mirror Spot', - 'Lake Hylia Water D Mirror Spot', - 'Lake Hylia Central Island Mirror Spot', - 'Ice Cave Mirror Spot', - 'Desert Pass Ledge Mirror Spot', - 'Desert Pass Mirror Spot', - 'Dam Mirror Spot', - 'South Pass Mirror Spot', - 'Octoballoon Mirror Spot' + 'Mirror': ['Bombos Tablet Ledge Mirror Spot' ] } diff --git a/OverworldShuffle.py b/OverworldShuffle.py index fe981f78..edee4b88 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -836,7 +836,33 @@ def create_flute_exits(world, player): exit.access_rule = lambda state: state.can_flute(player) exit.connect(world.get_region('Flute Sky', player)) region.exits.append(exit) - world.initialize_regions() + +def create_mirror_exits(world, player): + mirror_exits = set() + for region in (r for r in world.regions if r.player == player and r.name not in ['Zoras Domain', 'Master Sword Meadow', 'Hobo Bridge']): + if region.type == (RegionType.DarkWorld if world.mode[player] != 'inverted' else RegionType.LightWorld): + if region.name in mirror_connections: + for region_dest_name in mirror_connections[region.name]: + to_region = world.get_region(region_dest_name, player) + if len(mirror_connections[region.name]) == 1: + exitname = 'Mirror From ' + region.name + else: + exitname = 'Mirror To ' + region_dest_name + + assert(exitname not in mirror_exits, f'Mirror Exit with name already exists: {exitname}') + + exit = Entrance(region.player, exitname, region) + exit.spot_type = 'Mirror' + if region.terrain == Terrain.Water or to_region.terrain == Terrain.Water: + exit.access_rule = lambda state: state.has('Flippers', player) and state.has_Pearl(player) and state.has_Mirror(player) + else: + exit.access_rule = lambda state: state.has_Mirror(player) + exit.connect(to_region) + region.exits.append(exit) + + mirror_exits.add(exitname) + elif region.terrain == Terrain.Land: + logging.getLogger('').debug(f'Region has no mirror exit: {region.name}') def categorize_world_regions(world, player): for type in OWExitTypes: @@ -1359,47 +1385,14 @@ default_flute_connections = [ ] ow_connections = { - 0x00: ([ - ('Lost Woods East Mirror Spot', 'Lost Woods East Area'), - ('Lost Woods Entry Mirror Spot', 'Lost Woods West Area'), - ('Lost Woods Pedestal Mirror Spot', 'Lost Woods West Area'), - ('Lost Woods Southwest Mirror Spot', 'Lost Woods West Area'), - ('Lost Woods East (Forgotten) Mirror Spot', 'Lost Woods East Area'), - ('Lost Woods West (Forgotten) Mirror Spot', 'Lost Woods West Area') - ], [ - ('Skull Woods Back Mirror Spot', 'Skull Woods Forest (West)'), - ('Skull Woods Forgotten (West) Mirror Spot', 'Skull Woods Forgotten Path (Southwest)'), - ('Skull Woods Forgotten (East) Mirror Spot', 'Skull Woods Forgotten Path (Northeast)'), - ('Skull Woods Portal Entry Mirror Spot', 'Skull Woods Portal Entry'), - ('Skull Woods Forgotten (Middle) Mirror Spot', 'Skull Woods Forgotten Path (Northeast)'), - ('Skull Woods Front Mirror Spot', 'Skull Woods Forest') - ]), - 0x02: ([ - ('Lumberjack Mirror Spot', 'Lumberjack Area') - ], [ - ('Dark Lumberjack Mirror Spot', 'Dark Lumberjack Area') - ]), 0x03: ([ - ('Spectacle Rock Mirror Spot', 'Spectacle Rock Ledge'), - ('West Death Mountain (Top) Mirror Spot', 'West Death Mountain (Top)'), ('West Death Mountain Teleporter', 'West Dark Death Mountain (Bottom)') ], [ ('Spectacle Rock Leave', 'West Death Mountain (Top)'), ('Spectacle Rock Approach', 'Spectacle Rock Ledge'), - ('West Dark Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain (Top)'), - ('Bubble Boy Mirror Spot', 'West Dark Death Mountain (Bottom)'), - ('West Dark Death Mountain (Bottom) Mirror Spot', 'West Dark Death Mountain (Bottom)'), ('Dark Death Mountain Teleporter (West)', 'West Death Mountain (Bottom)') ]), 0x05: ([ - ('East Death Mountain (Top West) Mirror Spot', 'East Death Mountain (Top West)'), - ('East Death Mountain (Top East) Mirror Spot', 'East Death Mountain (Top East)'), - ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), - ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), - ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), - ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), - ('Death Mountain Bridge Mirror Spot', 'East Death Mountain (Bottom Left)'), - ('Floating Island Mirror Spot', 'Death Mountain Floating Island'), ('East Death Mountain Teleporter', 'East Dark Death Mountain (Bottom)') ], [ ('Floating Island Bridge (West)', 'East Death Mountain (Top East)'), @@ -1411,252 +1404,91 @@ ow_connections = { ('Spiral Ledge Approach', 'Spiral Cave Ledge'), ('Mimic Ledge Approach', 'Mimic Cave Ledge'), ('Spiral Mimic Ledge Drop', 'Fairy Ascension Ledge'), - ('East Dark Death Mountain (Top West) Mirror Spot', 'East Dark Death Mountain (Top)'), - ('East Dark Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain (Top)'), - ('TR Ledge (West) Mirror Spot', 'Dark Death Mountain Ledge'), - ('TR Ledge (East) Mirror Spot', 'Dark Death Mountain Ledge'), - ('TR Isolated Mirror Spot', 'Dark Death Mountain Isolated Ledge'), - ('East Dark Death Mountain (Bottom Plateau) Mirror Spot', 'East Dark Death Mountain (Bottom)'), - ('East Dark Death Mountain (Bottom Left) Mirror Spot', 'East Dark Death Mountain (Bottom Left)'), - ('East Dark Death Mountain (Bottom) Mirror Spot', 'East Dark Death Mountain (Bottom)'), - ('Dark Floating Island Mirror Spot', 'Dark Death Mountain Floating Island'), ('Dark Death Mountain Teleporter (East)', 'East Death Mountain (Bottom)') ]), 0x07: ([ - ('TR Pegs Area Mirror Spot', 'Death Mountain TR Pegs'), ('TR Pegs Teleporter', 'Turtle Rock Ledge') ], [ ('Turtle Rock Tail Ledge Drop', 'Turtle Rock Ledge'), - ('Turtle Rock Mirror Spot', 'Turtle Rock Area'), - ('Turtle Rock Ledge Mirror Spot', 'Turtle Rock Ledge'), ('Turtle Rock Teleporter', 'Death Mountain TR Pegs Ledge') ]), - 0x0a: ([ - ('Mountain Entry Mirror Spot', 'Mountain Entry Area'), - ('Mountain Entry Entrance Mirror Spot', 'Mountain Entry Entrance'), - ('Mountain Entry Ledge Mirror Spot', 'Mountain Entry Ledge') - ], [ - ('Bumper Cave Area Mirror Spot', 'Bumper Cave Area'), - ('Bumper Cave Entry Mirror Spot', 'Bumper Cave Entrance'), - ('Bumper Cave Ledge Mirror Spot', 'Bumper Cave Ledge') - ]), - 0x0f: ([ - ('Zora Waterfall Mirror Spot', 'Zora Waterfall Area') - ], [ - ('Catfish Mirror Spot', 'Catfish Area') - ]), 0x10: ([ - ('Lost Woods Pass West Mirror Spot', 'Lost Woods Pass West Area'), - ('Lost Woods Pass East Top Mirror Spot', 'Lost Woods Pass East Top Area'), - ('Lost Woods Pass Portal Mirror Spot', 'Lost Woods Pass Portal Area'), - ('Lost Woods Pass East Bottom Mirror Spot', 'Lost Woods Pass East Bottom Area'), ('Kakariko Teleporter', 'Skull Woods Pass Portal Area') ], [ - ('Skull Woods Pass West Mirror Spot', 'Skull Woods Pass West Area'), - ('Skull Woods Pass East Top Mirror Spot', 'Skull Woods Pass East Top Area'), - ('Skull Woods Pass Portal Mirror Spot', 'Skull Woods Pass Portal Area'), - ('Skull Woods Pass East Bottom Mirror Spot', 'Skull Woods Pass East Bottom Area'), ('West Dark World Teleporter', 'Lost Woods Pass Portal Area') ]), - 0x11: ([ - ('Kakariko Fortune Mirror Spot', 'Kakariko Fortune Area') - ], [ - ('Outcast Fortune Mirror Spot', 'Dark Fortune Area') - ]), - 0x12: ([ - ('Kakariko Pond Mirror Spot', 'Kakariko Pond Area') - ], [ - ('Outcast Pond Mirror Spot', 'Outcast Pond Area') - ]), - 0x13: ([ - ('Sanctuary Mirror Spot', 'Sanctuary Area'), - ('Bonk Rock Ledge Mirror Spot', 'Bonk Rock Ledge') - ], [ - ('Dark Chapel Mirror Spot', 'Dark Chapel Area'), - ('Dark Chapel Ledge Mirror Spot', 'Dark Chapel Area') - ]), 0x14: ([ - ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), - ('Kings Grave Mirror Spot', 'Kings Grave Area') + ], [ ('Graveyard Ladder (Top)', 'Graveyard Area'), - ('Graveyard Ladder (Bottom)', 'Graveyard Ledge'), - ('Dark Graveyard Mirror Spot', 'Dark Graveyard Area'), - ('Dark Graveyard Ledge Mirror Spot', 'Dark Graveyard Area'), - ('Dark Graveyard Grave Mirror Spot', 'Dark Graveyard Area') - ]), - 0x15: ([ - ('River Bend Mirror Spot', 'River Bend Area'), - ('River Bend East Mirror Spot', 'River Bend East Bank') - ], [ - ('Qirn Jump Mirror Spot', 'Qirn Jump Area'), - ('Qirn Jump East Mirror Spot', 'Qirn Jump East Bank') - ]), - 0x16: ([ - ('Potion Shop Mirror Spot', 'Potion Shop Area'), - ('Potion Shop Northeast Mirror Spot', 'Potion Shop Northeast') - ], [ - ('Dark Witch Mirror Spot', 'Dark Witch Area'), - ('Dark Witch Northeast Mirror Spot', 'Dark Witch Northeast') - ]), - 0x17: ([ - ('Zora Approach Mirror Spot', 'Zora Approach Area'), - ('Zora Approach Ledge Mirror Spot', 'Zora Approach Ledge') - ], [ - ('Catfish Approach Mirror Spot', 'Catfish Approach Area'), - ('Catfish Approach Ledge Mirror Spot', 'Catfish Approach Ledge') - ]), - 0x18: ([ - ('Kakariko Mirror Spot', 'Kakariko Area'), - ('Kakariko Grass Mirror Spot', 'Kakariko Area') - ], [ - ('Village of Outcasts Mirror Spot', 'Village of Outcasts Area'), - ('Village of Outcasts Southwest Mirror Spot', 'Village of Outcasts Area'), - ('Hammer House Mirror Spot', 'Dark Grassy Lawn') - ]), - 0x1a: ([ - ('Forgotton Forest Mirror Spot', 'Forgotten Forest Area'), - ('Forgotton Forest Fence Mirror Spot', 'Forgotten Forest Area') - ], [ - ('Shield Shop Mirror Spot', 'Shield Shop Area') + ('Graveyard Ladder (Bottom)', 'Graveyard Ledge') ]), 0x1b: ([ - ('HC Ledge Mirror Spot', 'Hyrule Castle Ledge'), - ('HC Courtyard Mirror Spot', 'Hyrule Castle Courtyard'), - ('HC Area Mirror Spot', 'Hyrule Castle Area'), - ('HC Courtyard Left Mirror Spot', 'Hyrule Castle Courtyard'), - ('HC Area South Mirror Spot', 'Hyrule Castle Area'), - ('HC East Entry Mirror Spot', 'Hyrule Castle East Entry'), ('Top of Pyramid', 'Pyramid Area'), ('Top of Pyramid (Inner)', 'Pyramid Area') ], [ - ('Pyramid Mirror Spot', 'Pyramid Area'), - ('Pyramid Pass Mirror Spot', 'Pyramid Pass'), - ('Pyramid Courtyard Mirror Spot', 'Pyramid Area'), - ('Pyramid Uncle Mirror Spot', 'Pyramid Area'), - ('Pyramid From Ledge Mirror Spot', 'Pyramid Area'), - ('Pyramid Entry Mirror Spot', 'Pyramid Area'), ('Post Aga Inverted Teleporter', 'Hyrule Castle Area') ]), - 0x1d: ([ - ('Wooden Bridge Mirror Spot', 'Wooden Bridge Area'), - ('Wooden Bridge Northeast Mirror Spot', 'Wooden Bridge Area'), - ('Wooden Bridge West Mirror Spot', 'Wooden Bridge Area') - ], [ - ('Broken Bridge West Mirror Spot', 'Broken Bridge West'), - ('Broken Bridge East Mirror Spot', 'Broken Bridge Area'), - ('Broken Bridge Northeast Mirror Spot', 'Broken Bridge Northeast') - ]), 0x1e: ([ - ('Eastern Palace Mirror Spot', 'Eastern Palace Area'), ('Eastern Palace Ledge Drop', 'Eastern Palace Area'), # OWG ('Palace of Darkness Ledge Drop', 'Palace of Darkness Area') # OWG ], [ - ('Palace of Darkness Mirror Spot', 'Palace of Darkness Area'), ('Eastern Palace Ledge Drop', 'Palace of Darkness Area'), # OWG ('Palace of Darkness Ledge Drop', 'Eastern Palace Area') # OWG ]), - 0x22: ([ - ('Blacksmith Mirror Spot', 'Blacksmith Area'), - ('Blacksmith Entry Mirror Spot', 'Blacksmith Area'), - ('Bat Cave Ledge Mirror Spot', 'Bat Cave Ledge') - ], [ - ('Hammer Pegs Mirror Spot', 'Hammer Pegs Area'), - ('Hammer Pegs Entry Mirror Spot', 'Hammer Pegs Entry') - ]), 0x25: ([ - ('Sand Dunes Mirror Spot', 'Sand Dunes Area'), ('Sand Dunes Ledge Drop', 'Sand Dunes Area'), # OWG ('Dark Dunes Ledge Drop', 'Dark Dunes Area') # OWG ], [ - ('Dark Dunes Mirror Spot', 'Dark Dunes Area'), ('Sand Dunes Ledge Drop', 'Dark Dunes Area'), # OWG ('Dark Dunes Ledge Drop', 'Sand Dunes Area') # OWG ]), - 0x28: ([ - ('Maze Race Mirror Spot', 'Maze Race Ledge'), - ('Maze Race Ledge Mirror Spot', 'Maze Race Ledge') - ], [ - ('Dig Game Mirror Spot', 'Dig Game Area'), - ('Dig Game Ledge Mirror Spot', 'Dig Game Ledge') - ]), 0x29: ([ - ('Kakariko Suburb Mirror Spot', 'Kakariko Suburb Area'), - ('Kakariko Suburb South Mirror Spot', 'Kakariko Suburb Area'), ('Suburb Cliff Ledge Drop', 'Kakariko Suburb Area'), # OWG ('Archery Game Cliff Ledge Drop', 'Archery Game Area') # OWG ], [ - ('Frog Mirror Spot', 'Frog Area'), - ('Frog Prison Mirror Spot', 'Frog Prison'), - ('Archery Game Mirror Spot', 'Archery Game Area'), ('Suburb Cliff Ledge Drop', 'Archery Game Area'), # OWG ('Archery Game Cliff Ledge Drop', 'Kakariko Suburb Area') # OWG ]), - 0x2a: ([ - ('Flute Boy Mirror Spot', 'Flute Boy Area'), - ('Flute Boy Pass Mirror Spot', 'Flute Boy Pass') - ], [ - ('Stumpy Mirror Spot', 'Stumpy Area'), - ('Stumpy Pass Mirror Spot', 'Stumpy Pass') - ]), 0x2b: ([ - ('Central Bonk Rocks Mirror Spot', 'Central Bonk Rocks Area'), ('Central Bonk Rocks Cliff Ledge Drop', 'Central Bonk Rocks Area'), # OWG ('Dark Bonk Rocks Cliff Ledge Drop', 'Dark Bonk Rocks Area') # OWG ], [ - ('Dark Bonk Rocks Mirror Spot', 'Dark Bonk Rocks Area'), ('Central Bonk Rocks Cliff Ledge Drop', 'Dark Bonk Rocks Area'), # OWG ('Dark Bonk Rocks Cliff Ledge Drop', 'Central Bonk Rocks Area') # OWG ]), 0x2c: ([ - ('Links House Mirror Spot', 'Links House Area'), ('Links House Cliff Ledge Drop', 'Links House Area'), # OWG ('Bomb Shop Cliff Ledge Drop', 'Big Bomb Shop Area') # OWG ], [ - ('Big Bomb Shop Mirror Spot', 'Big Bomb Shop Area'), ('Links House Cliff Ledge Drop', 'Big Bomb Shop Area'), # OWG ('Bomb Shop Cliff Ledge Drop', 'Links House Area') # OWG ]), 0x2d: ([ - ('Stone Bridge Mirror Spot', 'Stone Bridge North Area'), - ('Stone Bridge South Mirror Spot', 'Stone Bridge South Area'), - ('Hobo Mirror Spot', 'Stone Bridge Water'), ('Stone Bridge East Ledge Drop', 'Stone Bridge North Area'), # OWG ('Hammer Bridge North Ledge Drop', 'Hammer Bridge North Area'), # OWG ('Stone Bridge Cliff Ledge Drop', 'Stone Bridge South Area'), # OWG ('Hammer Bridge South Cliff Ledge Drop', 'Hammer Bridge South Area') # OWG ], [ - ('Hammer Bridge North Mirror Spot', 'Hammer Bridge North Area'), - ('Hammer Bridge South Mirror Spot', 'Hammer Bridge South Area'), - ('Dark Hobo Mirror Spot', 'Hammer Bridge Water'), ('Stone Bridge East Ledge Drop', 'Hammer Bridge North Area'), # OWG ('Hammer Bridge North Ledge Drop', 'Stone Bridge North Area'), # OWG ('Stone Bridge Cliff Ledge Drop', 'Hammer Bridge South Area'), # OWG ('Hammer Bridge South Cliff Ledge Drop', 'Stone Bridge South Area') # OWG ]), 0x2e: ([ - ('Tree Line Mirror Spot', 'Tree Line Area'), ('Tree Line Ledge Drop', 'Tree Line Area'), # OWG ('Dark Tree Line Ledge Drop', 'Dark Tree Line Area') # OWG ], [ - ('Dark Tree Line Mirror Spot', 'Dark Tree Line Area'), ('Tree Line Ledge Drop', 'Dark Tree Line Area'), # OWG ('Dark Tree Line Ledge Drop', 'Tree Line Area') # OWG ]), 0x2f: ([ - ('Eastern Nook Mirror Spot', 'Eastern Nook Area'), ('East Hyrule Teleporter', 'Palace of Darkness Nook Area') ], [ - ('Darkness Nook Mirror Spot', 'Palace of Darkness Nook Area'), ('East Dark World Teleporter', 'Eastern Nook Area') ]), 0x30: ([ - ('Desert Mirror Spot', 'Desert Area'), - ('Desert Ledge Mirror Spot', 'Desert Ledge'), - ('Checkerboard Mirror Spot', 'Desert Checkerboard Ledge'), - ('DP Stairs Mirror Spot', 'Desert Palace Stairs'), - ('DP Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), - ('Bombos Tablet Ledge Mirror Spot', 'Bombos Tablet Ledge'), + ('Bombos Tablet Ledge Mirror Spot', 'Bombos Tablet Ledge'), # OWG ('Desert Teleporter', 'Misery Mire Teleporter Ledge'), ('Desert Boss Cliff Ledge Drop', 'Desert Palace Entrance (North) Spot'), # OWG ('Mire Cliff Ledge Drop', 'Misery Mire Area'), # OWG @@ -1664,10 +1496,6 @@ ow_connections = { ], [ ('Checkerboard Ledge Approach', 'Desert Checkerboard Ledge'), ('Checkerboard Ledge Leave', 'Desert Area'), - ('Misery Mire Mirror Spot', 'Misery Mire Area'), - ('Misery Mire Ledge Mirror Spot', 'Misery Mire Area'), - ('Misery Mire Blocked Mirror Spot', 'Misery Mire Area'), - ('Misery Mire Main Mirror Spot', 'Misery Mire Area'), ('Misery Mire Teleporter', 'Desert Palace Teleporter Ledge'), ('Desert Boss Cliff Ledge Drop', 'Misery Mire Area'), # OWG ('Mire Cliff Ledge Drop', 'Desert Palace Entrance (North) Spot'), # OWG @@ -1675,21 +1503,15 @@ ow_connections = { ]), 0x32: ([ ('Cave 45 Ledge Drop', 'Flute Boy Approach Area'), - ('Flute Boy Entry Mirror Spot', 'Flute Boy Bush Entry'), - ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), ('Cave 45 Cliff Ledge Drop', 'Cave 45 Ledge'), # OWG ('Stumpy Approach Cliff Ledge Drop', 'Stumpy Approach Area') # OWG ], [ ('Cave 45 Inverted Leave', 'Flute Boy Approach Area'), ('Cave 45 Inverted Approach', 'Cave 45 Ledge'), - ('Stumpy Approach Mirror Spot', 'Stumpy Approach Area'), - ('Stumpy Bush Entry Mirror Spot', 'Stumpy Approach Bush Entry'), ('Cave 45 Cliff Ledge Drop', 'Stumpy Approach Area'), # OWG ('Stumpy Approach Cliff Ledge Drop', 'Cave 45 Ledge') # OWG ]), 0x33: ([ - ('C Whirlpool Mirror Spot', 'C Whirlpool Area'), - ('C Whirlpool Outer Mirror Spot', 'C Whirlpool Outer Area'), ('South Hyrule Teleporter', 'Dark C Whirlpool Portal Area'), ('C Whirlpool Cliff Ledge Drop', 'C Whirlpool Area'), # OWG ('Dark C Whirlpool Cliff Ledge Drop', 'Dark C Whirlpool Area'), # OWG @@ -1700,8 +1522,6 @@ ow_connections = { ('Desert C Whirlpool Cliff Ledge Drop', 'C Whirlpool Outer Area'), # OWG ('Mire C Whirlpool Cliff Ledge Drop', 'Dark C Whirlpool Outer Area') # OWG ], [ - ('Dark C Whirlpool Mirror Spot', 'Dark C Whirlpool Area'), - ('Dark C Whirlpool Outer Mirror Spot', 'Dark C Whirlpool Outer Area'), ('South Dark World Teleporter', 'C Whirlpool Portal Area'), ('C Whirlpool Cliff Ledge Drop', 'Dark C Whirlpool Area'), # OWG ('Dark C Whirlpool Cliff Ledge Drop', 'C Whirlpool Area'), # OWG @@ -1713,23 +1533,13 @@ ow_connections = { ('Mire C Whirlpool Cliff Ledge Drop', 'C Whirlpool Outer Area') # OWG ]), 0x34: ([ - ('Statues Mirror Spot', 'Statues Area'), ('Statues Cliff Ledge Drop', 'Statues Area'), # OWG ('Hype Cliff Ledge Drop', 'Hype Cave Area') # OWG ], [ - ('Hype Cave Mirror Spot', 'Hype Cave Area'), ('Statues Cliff Ledge Drop', 'Hype Cave Area'), # OWG ('Hype Cliff Ledge Drop', 'Statues Area') # OWG ]), 0x35: ([ - ('Lake Hylia Mirror Spot', 'Lake Hylia Area'), - ('Lake Hylia Northeast Mirror Spot', 'Lake Hylia Northeast Bank'), - ('South Shore Mirror Spot', 'Lake Hylia South Shore'), - ('South Shore East Mirror Spot', 'Lake Hylia South Shore'), - ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), - ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), - ('Lake Hylia Water Mirror Spot', 'Lake Hylia Water'), - ('Lake Hylia Water D Mirror Spot', 'Lake Hylia Water D'), ('Lake Hylia Teleporter', 'Ice Palace Area'), #('Ice Palace Ledge Drop', 'Ice Lake Moat'), ('Lake Hylia Area Cliff Ledge Drop', 'Lake Hylia Area'), # OWG @@ -1738,58 +1548,281 @@ ow_connections = { ('Ice Palace Island FAWT Ledge Drop', 'Ice Lake Moat') # OWG ], [ ('Lake Hylia Island Pier', 'Lake Hylia Island'), - ('Ice Lake Mirror Spot', 'Ice Lake Area'), - ('Ice Lake Southwest Mirror Spot', 'Ice Lake Ledge (West)'), - ('Ice Lake Southeast Mirror Spot', 'Ice Lake Ledge (East)'), - ('Ice Lake Northeast Mirror Spot', 'Ice Lake Northeast Bank'), - ('Ice Palace Mirror Spot', 'Ice Palace Area'), - ('Ice Lake Moat Mirror Spot', 'Ice Lake Moat'), ('Ice Palace Teleporter', 'Lake Hylia Water D'), ('Lake Hylia Area Cliff Ledge Drop', 'Ice Lake Area'), # OWG ('Ice Lake Area Cliff Ledge Drop', 'Lake Hylia Area'), # OWG ('Lake Hylia Island FAWT Ledge Drop', 'Ice Lake Moat'), # OWG ('Ice Palace Island FAWT Ledge Drop', 'Lake Hylia Island') # OWG ]), - 0x37: ([ - ('Ice Cave Mirror Spot', 'Ice Cave Area') - ], [ - ('Shopping Mall Mirror Spot', 'Shopping Mall Area') - ]), 0x3a: ([ - ('Desert Pass Ledge Mirror Spot', 'Desert Pass Ledge'), - ('Desert Pass Mirror Spot', 'Desert Pass Area'), ('Desert Pass Cliff Ledge Drop', 'Desert Pass Area'), # OWG ('Swamp Nook Cliff Ledge Drop', 'Swamp Nook Area') # OWG ], [ ('Desert Pass Ladder (North)', 'Desert Pass Area'), ('Desert Pass Ladder (South)', 'Desert Pass Ledge'), - ('Swamp Nook Mirror Spot', 'Swamp Nook Area'), - ('Swamp Nook Southeast Mirror Spot', 'Swamp Nook Area'), - ('Swamp Nook Pegs Mirror Spot', 'Swamp Nook Area'), ('Desert Pass Cliff Ledge Drop', 'Swamp Nook Area'), # OWG ('Swamp Nook Cliff Ledge Drop', 'Desert Pass Area') # OWG ]), 0x3b: ([ - ('Dam Mirror Spot', 'Dam Area'), ('Dam Cliff Ledge Drop', 'Dam Area'), # OWG ('Swamp Cliff Ledge Drop', 'Swamp Area') # OWG ], [ - ('Swamp Mirror Spot', 'Swamp Area'), ('Dam Cliff Ledge Drop', 'Swamp Area'), # OWG ('Swamp Cliff Ledge Drop', 'Dam Area') # OWG - ]), - 0x3c: ([ - ('South Pass Mirror Spot', 'South Pass Area') - ], [ - ('Dark South Pass Mirror Spot', 'Dark South Pass Area') - ]), - 0x3f: ([ - ('Octoballoon Mirror Spot', 'Octoballoon Area') - ], [ - ('Bomber Corner Mirror Spot', 'Bomber Corner Area') ]) } +mirror_connections = { + 'Skull Woods Forest': ['Lost Woods East Area'], + 'Skull Woods Portal Entry': ['Lost Woods West Area'], + 'Skull Woods Forest (West)': ['Lost Woods West Area'], + 'Skull Woods Forgotten Path (Southwest)': ['Lost Woods West Area'], + 'Skull Woods Forgotten Path (Northeast)': ['Lost Woods East Area', 'Lost Woods West Area'], + + 'Dark Lumberjack Area': ['Lumberjack Area'], + + 'West Dark Death Mountain (Top)': ['West Death Mountain (Top)'], + 'West Dark Death Mountain (Bottom)': ['Spectacle Rock Ledge'], + + 'Dark Death Mountain Floating Island': ['Death Mountain Floating Island'], + 'East Dark Death Mountain (Top)': ['East Death Mountain (Top West)', 'East Death Mountain (Top East)'], + 'Dark Death Mountain Ledge': ['Spiral Cave Ledge', 'Mimic Cave Ledge'], + 'Dark Death Mountain Isolated Ledge': ['Fairy Ascension Ledge'], + 'East Dark Death Mountain (Bottom)': ['Fairy Ascension Plateau'], + 'East Dark Death Mountain (Bottom Left)': ['East Death Mountain (Bottom Left)'], + + 'Turtle Rock Area': ['Death Mountain TR Pegs'], + + 'Bumper Cave Area': ['Mountain Entry Area'], + 'Bumper Cave Entrance': ['Mountain Entry Entrance'], + 'Bumper Cave Ledge': ['Mountain Entry Ledge'], + + 'Catfish Area': ['Zora Waterfall Area'], + + 'Skull Woods Pass West Area': ['Lost Woods Pass West Area'], + 'Skull Woods Pass East Top Area': ['Lost Woods Pass East Top Area'], + 'Skull Woods Pass Portal Area': ['Lost Woods Pass Portal Area'], + 'Skull Woods Pass East Bottom Area': ['Lost Woods Pass East Bottom Area'], + + 'Dark Fortune Area': ['Kakariko Fortune Area'], + + 'Outcast Pond Area': ['Kakariko Pond Area'], + + 'Dark Chapel Area': ['Sanctuary Area', 'Bonk Rock Ledge'], + + 'Dark Graveyard Area': ['Graveyard Area'], + 'Dark Graveyard North': ['Graveyard Ledge', 'Kings Grave Area'], + + 'Qirn Jump Area': ['River Bend Area'], + 'Qirn Jump East Bank': ['River Bend East Bank'], + + 'Dark Witch Area': ['Potion Shop Area'], + 'Dark Witch Northeast': ['Potion Shop Northeast'], + + 'Catfish Approach Area': ['Zora Approach Area'], + 'Catfish Approach Ledge': ['Zora Approach Ledge'], + + 'Village of Outcasts Area': ['Kakariko Area'], + 'Dark Grassy Lawn': ['Kakariko Area'], + + 'Shield Shop Area': ['Forgotten Forest Area'], + 'Shield Shop Fence': ['Forgotten Forest Area'], + + 'Pyramid Area': ['Hyrule Castle Ledge', 'Hyrule Castle Courtyard', 'Hyrule Castle Area', 'Hyrule Castle East Entry'], + 'Pyramid Exit Ledge': ['Hyrule Castle Courtyard'], + 'Pyramid Pass': ['Hyrule Castle Area'], + + 'Broken Bridge Area': ['Wooden Bridge Area'], + 'Broken Bridge Northeast': ['Wooden Bridge Area'], + 'Broken Bridge West': ['Wooden Bridge Area'], + + 'Palace of Darkness Area': ['Eastern Palace Area'], + + 'Hammer Pegs Area': ['Blacksmith Area', 'Bat Cave Ledge'], + 'Hammer Pegs Entry': ['Blacksmith Area'], + + 'Dark Dunes Area': ['Sand Dunes Area'], + + 'Dig Game Area': ['Maze Race Ledge'], + 'Dig Game Ledge': ['Maze Race Ledge'], + + 'Frog Area': ['Kakariko Suburb Area'], + 'Archery Game Area': ['Kakariko Suburb Area'], + + 'Stumpy Area': ['Flute Boy Area'], + 'Stumpy Pass': ['Flute Boy Pass'], + + 'Dark Bonk Rocks Area': ['Central Bonk Rocks Area'], + + 'Big Bomb Shop Area': ['Links House Area'], + + 'Hammer Bridge North Area': ['Stone Bridge North Area'], + 'Hammer Bridge South Area': ['Stone Bridge South Area'], + 'Hammer Bridge Water': ['Stone Bridge Water'], + + 'Dark Tree Line Area': ['Tree Line Area'], + + 'Palace of Darkness Nook Area': ['Eastern Nook Area'], + + 'Misery Mire Area': ['Desert Area', 'Desert Ledge', 'Desert Checkerboard Ledge', 'Desert Palace Stairs', 'Desert Palace Entrance (North) Spot'], + + 'Stumpy Approach Area': ['Cave 45 Ledge'], + 'Stumpy Approach Bush Entry': ['Flute Boy Bush Entry'], + + 'Dark C Whirlpool Area': ['C Whirlpool Area'], + 'Dark C Whirlpool Outer Area': ['C Whirlpool Outer Area'], + + 'Hype Cave Area': ['Statues Area'], + + 'Ice Lake Area': ['Lake Hylia Area'], + 'Ice Lake Northeast Bank': ['Lake Hylia Northeast Bank'], + 'Ice Lake Ledge (West)': ['Lake Hylia South Shore'], + 'Ice Lake Ledge (East)': ['Lake Hylia South Shore'], + 'Ice Lake Water': ['Lake Hylia Island'], + 'Ice Palace Area': ['Lake Hylia Central Island'], + 'Ice Lake Moat': ['Lake Hylia Water', 'Lake Hylia Water D'], #needs flippers + + 'Shopping Mall Area': ['Ice Cave Area'], + + 'Swamp Nook Area': ['Desert Pass Area', 'Desert Pass Ledge'], + + 'Swamp Area': ['Dam Area'], + + 'Dark South Pass Area': ['South Pass Area'], + + 'Bomber Corner Area': ['Octoballoon Area'], + + + 'Lost Woods West Area': ['Skull Woods Forest (West)', 'Skull Woods Forgotten Path (Southwest)', 'Skull Woods Portal Entry'], + #'Lost Woods West Area': ['Skull Woods Forgotten Path (Northeast)'], # technically yes, but we dont need it + 'Lost Woods East Area': ['Skull Woods Forgotten Path (Northeast)', 'Skull Woods Forest'], + + 'Lumberjack Area': ['Dark Lumberjack Area'], + + 'West Death Mountain (Top)': ['West Dark Death Mountain (Top)'], + 'Spectacle Rock Ledge': ['West Dark Death Mountain (Bottom)'], + 'West Death Mountain (Bottom)': ['West Dark Death Mountain (Bottom)'], + + 'East Death Mountain (Top West)': ['East Dark Death Mountain (Top)'], + 'East Death Mountain (Top East)': ['East Dark Death Mountain (Top)'], + 'Spiral Cave Ledge': ['Dark Death Mountain Ledge'], + 'Mimic Cave Ledge': ['Dark Death Mountain Ledge'], + 'Fairy Ascension Ledge': ['Dark Death Mountain Isolated Ledge'], + 'Fairy Ascension Plateau': ['East Dark Death Mountain (Bottom)'], + 'East Death Mountain (Bottom Left)': ['East Dark Death Mountain (Bottom Left)'], + 'East Death Mountain (Bottom)': ['East Dark Death Mountain (Bottom)'], + 'Death Mountain Floating Island': ['Dark Death Mountain Floating Island'], + + 'Death Mountain TR Pegs': ['Turtle Rock Area'], + 'Death Mountain TR Pegs Ledge': ['Turtle Rock Ledge'], + + 'Mountain Entry Area': ['Bumper Cave Area'], + 'Mountain Entry Entrance': ['Bumper Cave Entrance'], + 'Mountain Entry Ledge': ['Bumper Cave Ledge'], + + 'Zora Waterfall Area': ['Catfish Area'], + + 'Lost Woods Pass West Area': ['Skull Woods Pass West Area'], + 'Lost Woods Pass East Top Area': ['Skull Woods Pass East Top Area'], + 'Lost Woods Pass Portal Area': ['Skull Woods Pass Portal Area'], + 'Lost Woods Pass East Bottom Area': ['Skull Woods Pass East Bottom Area'], + + 'Kakariko Fortune Area': ['Dark Fortune Area'], + + 'Kakariko Pond Area': ['Outcast Pond Area'], + + 'Sanctuary Area': ['Dark Chapel Area'], + 'Bonk Rock Ledge': ['Dark Chapel Area'], + + 'Graveyard Area': ['Dark Graveyard Area'], + 'Graveyard Ledge': ['Dark Graveyard Area'], + 'Kings Grave Area': ['Dark Graveyard Area'], + + 'River Bend Area': ['Qirn Jump Area'], + 'River Bend East Bank': ['Qirn Jump East Bank'], + + 'Potion Shop Area': ['Dark Witch Area'], + 'Potion Shop Northeast': ['Dark Witch Northeast'], + + 'Zora Approach Area': ['Catfish Approach Area'], + 'Zora Approach Ledge': ['Catfish Approach Ledge'], + + 'Kakariko Area': ['Village of Outcasts Area'], + 'Kakariko Southwest': ['Village of Outcasts Area'], + 'Kakariko Grass Yard': ['Dark Grassy Lawn'], + + 'Forgotten Forest Area': ['Shield Shop Area'], + + 'Hyrule Castle Area': ['Pyramid Area', 'Pyramid Pass'], + 'Hyrule Castle Southwest': ['Pyramid Pass'], + 'Hyrule Castle Courtyard': ['Pyramid Area'], + 'Hyrule Castle Courtyard Northeast': ['Pyramid Area'], + 'Hyrule Castle Ledge': ['Pyramid Area'], + 'Hyrule Castle East Entry': ['Pyramid Area'], + + 'Wooden Bridge Area': ['Broken Bridge Area', 'Broken Bridge West'], + 'Wooden Bridge Northeast': ['Broken Bridge Northeast'], + + 'Eastern Palace Area': ['Palace of Darkness Area'], + + 'Blacksmith Area': ['Hammer Pegs Area', 'Hammer Pegs Entry'], + + 'Sand Dunes Area': ['Dark Dunes Area'], + + 'Maze Race Area': ['Dig Game Area'], + 'Maze Race Ledge': ['Dig Game Ledge'], + + 'Kakariko Suburb Area': ['Frog Area', 'Frog Prison', 'Archery Game Area'], + + 'Flute Boy Area': ['Stumpy Area'], + 'Flute Boy Pass': ['Stumpy Pass'], + + 'Central Bonk Rocks Area': ['Dark Bonk Rocks Area'], + + 'Links House Area': ['Big Bomb Shop Area'], + + 'Stone Bridge North Area': ['Hammer Bridge North Area'], + 'Stone Bridge South Area': ['Hammer Bridge South Area'], + 'Stone Bridge Water': ['Hammer Bridge Water'], + + 'Tree Line Area': ['Dark Tree Line Area'], + + 'Eastern Nook Area': ['Palace of Darkness Nook Area'], + + 'Desert Area': ['Misery Mire Area'], + 'Desert Ledge': ['Misery Mire Area'], + 'Desert Palace Entrance (North) Spot': ['Misery Mire Area'], + 'Desert Checkerboard Ledge': ['Misery Mire Area'], + 'Desert Palace Stairs': ['Misery Mire Area'], + + 'Flute Boy Approach Area': ['Stumpy Approach Area'], + 'Cave 45 Ledge': ['Stumpy Approach Area'], + 'Flute Boy Bush Entry': ['Stumpy Approach Bush Entry'], + + 'C Whirlpool Area': ['Dark C Whirlpool Area'], + 'C Whirlpool Outer Area': ['Dark C Whirlpool Outer Area'], + + 'Statues Area': ['Hype Cave Area'], + + 'Lake Hylia Area': ['Ice Lake Area'], + 'Lake Hylia South Shore': ['Ice Lake Ledge (West)', 'Ice Lake Ledge (East)'], + 'Lake Hylia Northeast Bank': ['Ice Lake Northeast Bank'], + 'Lake Hylia Central Island': ['Ice Palace Area'], + 'Lake Hylia Water D': ['Ice Lake Moat'], + + 'Ice Cave Area': ['Shopping Mall Area'], + + 'Desert Pass Area': ['Swamp Nook Area'], + 'Desert Pass Southeast': ['Swamp Nook Area'], + 'Desert Pass Ledge': ['Swamp Nook Area'], + + 'Dam Area': ['Swamp Area'], + + 'South Pass Area': ['Dark South Pass Area'], + + 'Octoballoon Area': ['Bomber Corner Area'] +} + parallelsimilar_connections = [('Maze Race ES', 'Kakariko Suburb WS'), ('Dig Game EC', 'Frog WC') ] diff --git a/Regions.py b/Regions.py index 010d6c3b..d8dfd7eb 100644 --- a/Regions.py +++ b/Regions.py @@ -10,223 +10,223 @@ def create_regions(world, player): create_menu_region(player, 'Flute Sky', None, ['Flute Spot 1', 'Flute Spot 2', 'Flute Spot 3', 'Flute Spot 4', 'Flute Spot 5', 'Flute Spot 6', 'Flute Spot 7', 'Flute Spot 8']), create_lw_region(player, 'Master Sword Meadow', ['Master Sword Pedestal'], ['Master Sword Meadow SC']), - create_lw_region(player, 'Lost Woods West Area', None, ['Lost Woods Bush (West)', 'Skull Woods Back Mirror Spot', 'Skull Woods Forgotten (West) Mirror Spot', 'Skull Woods Forgotten (East) Mirror Spot', 'Skull Woods Portal Entry Mirror Spot', 'Lost Woods NW', 'Lost Woods SW', 'Lost Woods SC']), - create_lw_region(player, 'Lost Woods East Area', ['Mushroom'], ['Lost Woods Bush (East)', 'Lost Woods Gamble', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump', 'Skull Woods Forgotten (Middle) Mirror Spot', 'Skull Woods Front Mirror Spot', 'Lost Woods SE', 'Lost Woods EN']), - create_lw_region(player, 'Lumberjack Area', None, ['Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Lumberjack House', 'Dark Lumberjack Mirror Spot', 'Lumberjack WN', 'Lumberjack SW']), - create_lw_region(player, 'West Death Mountain (Top)', ['Ether Tablet'], ['Spectacle Rock Approach', 'West Death Mountain Drop', 'Tower of Hera', 'West Dark Death Mountain (Top) Mirror Spot', 'West Death Mountain EN']), - create_lw_region(player, 'Spectacle Rock Ledge', ['Spectacle Rock'], ['Spectacle Rock Leave', 'Spectacle Rock Drop', 'Bubble Boy Mirror Spot']), - create_lw_region(player, 'West Death Mountain (Bottom)', ['Old Man Drop Off'], ['Old Man Drop Off', 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'West Dark Death Mountain (Bottom) Mirror Spot', 'West Death Mountain Teleporter', 'West Death Mountain ES']), + create_lw_region(player, 'Lost Woods West Area', None, ['Lost Woods Bush (West)', 'Lost Woods NW', 'Lost Woods SW', 'Lost Woods SC']), + create_lw_region(player, 'Lost Woods East Area', ['Mushroom'], ['Lost Woods Bush (East)', 'Lost Woods Gamble', 'Lost Woods Hideout Drop', 'Lost Woods Hideout Stump', 'Lost Woods SE', 'Lost Woods EN']), + create_lw_region(player, 'Lumberjack Area', None, ['Lumberjack Tree Tree', 'Lumberjack Tree Cave', 'Lumberjack House', 'Lumberjack WN', 'Lumberjack SW']), + create_lw_region(player, 'West Death Mountain (Top)', ['Ether Tablet'], ['Spectacle Rock Approach', 'West Death Mountain Drop', 'Tower of Hera', 'West Death Mountain EN']), + create_lw_region(player, 'Spectacle Rock Ledge', ['Spectacle Rock'], ['Spectacle Rock Leave', 'Spectacle Rock Drop']), + create_lw_region(player, 'West Death Mountain (Bottom)', ['Old Man Drop Off'], ['Old Man Drop Off', 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'West Death Mountain Teleporter', 'West Death Mountain ES']), create_dw_region(player, 'Old Man Drop Off', ['Old Man'], None), - create_lw_region(player, 'East Death Mountain (Top West)', None, ['DM Hammer Bridge (West)', 'East Dark Death Mountain (Top West) Mirror Spot', 'East Death Mountain WN']), - create_lw_region(player, 'East Death Mountain (Top East)', None, ['DM Hammer Bridge (East)', 'Floating Island Bridge (East)', 'East Death Mountain Spiral Ledge Drop', 'East Death Mountain Fairy Ledge Drop', 'East Death Mountain Mimic Ledge Drop', 'Paradox Cave (Top)', 'East Dark Death Mountain (Top East) Mirror Spot', 'East Death Mountain EN']), - create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Mimic Bridge (West)', 'Spiral Cave', 'TR Ledge (West) Mirror Spot']), - create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Ledge Drop', 'Spiral Mimic Bridge (East)', 'Mimic Cave', 'TR Ledge (East) Mirror Spot']), + create_lw_region(player, 'East Death Mountain (Top West)', None, ['DM Hammer Bridge (West)', 'East Death Mountain WN']), + create_lw_region(player, 'East Death Mountain (Top East)', None, ['DM Hammer Bridge (East)', 'Floating Island Bridge (East)', 'East Death Mountain Spiral Ledge Drop', 'East Death Mountain Fairy Ledge Drop', 'East Death Mountain Mimic Ledge Drop', 'Paradox Cave (Top)', 'East Death Mountain EN']), + create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Mimic Bridge (West)', 'Spiral Cave']), + create_lw_region(player, 'Mimic Cave Ledge', None, ['Mimic Ledge Drop', 'Spiral Mimic Bridge (East)', 'Mimic Cave']), create_lw_region(player, 'Spiral Mimic Ledge Extend', None, ['Spiral Ledge Approach', 'Mimic Ledge Approach', 'Spiral Mimic Ledge Drop']), - create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)', 'TR Isolated Mirror Spot']), - create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Rocks (North)', 'Fairy Ascension Plateau Ledge Drop', 'Fairy Ascension Cave (Bottom)', 'East Dark Death Mountain (Bottom Plateau) Mirror Spot']), - create_lw_region(player, 'East Death Mountain (Bottom Left)', None, ['DM Broken Bridge (West)', 'East Dark Death Mountain (Bottom Left) Mirror Spot', 'East Death Mountain WS']), - create_lw_region(player, 'East Death Mountain (Bottom)', None, ['DM Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Hookshot Fairy', 'Spiral Cave (Bottom)', 'Fairy Ascension Rocks (South)', 'East Dark Death Mountain (Bottom) Mirror Spot', 'East Death Mountain Teleporter']), - create_lw_region(player, 'Death Mountain Floating Island', ['Floating Island'], ['Floating Island Bridge (West)', 'Dark Floating Island Mirror Spot']), - create_lw_region(player, 'Death Mountain TR Pegs', None, ['TR Pegs Ledge Entry', 'Turtle Rock Mirror Spot', 'Death Mountain TR Pegs WN']), - create_lw_region(player, 'Death Mountain TR Pegs Ledge', None, ['TR Pegs Ledge Leave', 'TR Pegs Ledge Drop', 'Turtle Rock Ledge Mirror Spot', 'TR Pegs Teleporter']), - create_lw_region(player, 'Mountain Entry Area', None, ['Mountain Entry Entrance Rock (West)', 'Bumper Cave Area Mirror Spot', 'Mountain Entry NW', 'Mountain Entry SE']), - create_lw_region(player, 'Mountain Entry Entrance', None, ['Mountain Entry Entrance Rock (East)', 'Mountain Entry Entrance Ledge Drop', 'Old Man Cave (West)', 'Bumper Cave Entry Mirror Spot']), - create_lw_region(player, 'Mountain Entry Ledge', None, ['Mountain Entry Ledge Drop', 'Death Mountain Return Cave (West)', 'Bumper Cave Ledge Mirror Spot'], 'a ledge in the foothills'), - create_lw_region(player, 'Zora Waterfall Area', None, ['Zora Waterfall Water Entry', 'Catfish Mirror Spot', 'Zora Waterfall SE', 'Zora Waterfall NE']), + create_lw_region(player, 'Fairy Ascension Ledge', None, ['Fairy Ascension Ledge Drop', 'Fairy Ascension Cave (Top)']), + create_lw_region(player, 'Fairy Ascension Plateau', None, ['Fairy Ascension Rocks (North)', 'Fairy Ascension Plateau Ledge Drop', 'Fairy Ascension Cave (Bottom)']), + create_lw_region(player, 'East Death Mountain (Bottom Left)', None, ['DM Broken Bridge (West)', 'East Death Mountain WS']), + create_lw_region(player, 'East Death Mountain (Bottom)', None, ['DM Broken Bridge (East)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Hookshot Fairy', 'Spiral Cave (Bottom)', 'Fairy Ascension Rocks (South)', 'East Death Mountain Teleporter']), + create_lw_region(player, 'Death Mountain Floating Island', ['Floating Island'], ['Floating Island Bridge (West)']), + create_lw_region(player, 'Death Mountain TR Pegs', None, ['TR Pegs Ledge Entry', 'Death Mountain TR Pegs WN']), + create_lw_region(player, 'Death Mountain TR Pegs Ledge', None, ['TR Pegs Ledge Leave', 'TR Pegs Ledge Drop', 'TR Pegs Teleporter']), + create_lw_region(player, 'Mountain Entry Area', None, ['Mountain Entry Entrance Rock (West)', 'Mountain Entry NW', 'Mountain Entry SE']), + create_lw_region(player, 'Mountain Entry Entrance', None, ['Mountain Entry Entrance Rock (East)', 'Mountain Entry Entrance Ledge Drop', 'Old Man Cave (West)']), + create_lw_region(player, 'Mountain Entry Ledge', None, ['Mountain Entry Ledge Drop', 'Death Mountain Return Cave (West)'], 'a ledge in the foothills'), + create_lw_region(player, 'Zora Waterfall Area', None, ['Zora Waterfall Water Entry', 'Zora Waterfall SE', 'Zora Waterfall NE']), create_lw_region(player, 'Zora Waterfall Water', None, ['Zora Waterfall Water Approach', 'Zora Waterfall Landing', 'Zora Whirlpool'], 'Light World', Terrain.Water), create_lw_region(player, 'Zora Waterfall Entryway', None, ['Zora Waterfall Water Drop', 'Waterfall of Wishing']), create_lw_region(player, 'Zoras Domain', ['King Zora', 'Zora\'s Ledge'], ['Zoras Domain SW']), - create_lw_region(player, 'Lost Woods Pass West Area', None, ['Skull Woods Pass West Mirror Spot', 'Lost Woods Pass NW', 'Lost Woods Pass SW']), - create_lw_region(player, 'Lost Woods Pass East Top Area', None, ['Skull Woods Pass East Top Mirror Spot', 'Lost Woods Pass Hammer (North)', 'Lost Woods Pass NE']), - create_lw_region(player, 'Lost Woods Pass Portal Area', None, ['Skull Woods Pass Portal Mirror Spot', 'Kakariko Teleporter', 'Lost Woods Pass Hammer (South)', 'Lost Woods Pass Rock (North)']), - create_lw_region(player, 'Lost Woods Pass East Bottom Area', None, ['Skull Woods Pass East Bottom Mirror Spot', 'Lost Woods Pass Rock (South)', 'Lost Woods Pass SE']), - create_lw_region(player, 'Kakariko Fortune Area', None, ['Fortune Teller (Light)', 'Outcast Fortune Mirror Spot', 'Kakariko Fortune NE', 'Kakariko Fortune EN', 'Kakariko Fortune ES', 'Kakariko Fortune SC']), - create_lw_region(player, 'Kakariko Pond Area', None, ['Outcast Pond Mirror Spot', 'Kakariko Pond NE', 'Kakariko Pond WN', 'Kakariko Pond WS', 'Kakariko Pond SW', 'Kakariko Pond SE', 'Kakariko Pond EN', 'Kakariko Pond ES', 'Kakariko Pond Whirlpool']), - create_lw_region(player, 'Sanctuary Area', None, ['Sanctuary', 'Dark Chapel Mirror Spot', 'Sanctuary WS', 'Sanctuary EC']), - create_lw_region(player, 'Bonk Rock Ledge', None, ['Bonk Rock Cave', 'Bonk Rock Ledge Drop', 'Dark Chapel Ledge Mirror Spot', 'Sanctuary WN']), - create_lw_region(player, 'Graveyard Area', None, ['Sanctuary Grave', 'Kings Grave Outer Rocks', 'Graveyard Ladder (Bottom)', 'Dark Graveyard Mirror Spot', 'Graveyard WC', 'Graveyard EC']), - create_lw_region(player, 'Graveyard Ledge', None, ['Graveyard Ledge Drop', 'Graveyard Ladder (Top)', 'Graveyard Cave', 'Dark Graveyard Ledge Mirror Spot']), - create_lw_region(player, 'Kings Grave Area', None, ['Kings Grave Inner Rocks', 'Kings Grave', 'Dark Graveyard Grave Mirror Spot']), - create_lw_region(player, 'River Bend Area', None, ['North Fairy Cave Drop', 'River Bend Water Drop', 'North Fairy Cave', 'Qirn Jump Mirror Spot', 'River Bend WC', 'River Bend SW']), - create_lw_region(player, 'River Bend East Bank', None, ['River Bend East Water Drop', 'Qirn Jump East Mirror Spot', 'River Bend SE', 'River Bend EC', 'River Bend ES']), + create_lw_region(player, 'Lost Woods Pass West Area', None, ['Lost Woods Pass NW', 'Lost Woods Pass SW']), + create_lw_region(player, 'Lost Woods Pass East Top Area', None, ['Lost Woods Pass Hammer (North)', 'Lost Woods Pass NE']), + create_lw_region(player, 'Lost Woods Pass Portal Area', None, ['Kakariko Teleporter', 'Lost Woods Pass Hammer (South)', 'Lost Woods Pass Rock (North)']), + create_lw_region(player, 'Lost Woods Pass East Bottom Area', None, ['Lost Woods Pass Rock (South)', 'Lost Woods Pass SE']), + create_lw_region(player, 'Kakariko Fortune Area', None, ['Fortune Teller (Light)', 'Kakariko Fortune NE', 'Kakariko Fortune EN', 'Kakariko Fortune ES', 'Kakariko Fortune SC']), + create_lw_region(player, 'Kakariko Pond Area', None, ['Kakariko Pond NE', 'Kakariko Pond WN', 'Kakariko Pond WS', 'Kakariko Pond SW', 'Kakariko Pond SE', 'Kakariko Pond EN', 'Kakariko Pond ES', 'Kakariko Pond Whirlpool']), + create_lw_region(player, 'Sanctuary Area', None, ['Sanctuary', 'Sanctuary WS', 'Sanctuary EC']), + create_lw_region(player, 'Bonk Rock Ledge', None, ['Bonk Rock Cave', 'Bonk Rock Ledge Drop', 'Sanctuary WN']), + create_lw_region(player, 'Graveyard Area', None, ['Sanctuary Grave', 'Kings Grave Outer Rocks', 'Graveyard Ladder (Bottom)', 'Graveyard WC', 'Graveyard EC']), + create_lw_region(player, 'Graveyard Ledge', None, ['Graveyard Ledge Drop', 'Graveyard Ladder (Top)', 'Graveyard Cave']), + create_lw_region(player, 'Kings Grave Area', None, ['Kings Grave Inner Rocks', 'Kings Grave']), + create_lw_region(player, 'River Bend Area', None, ['North Fairy Cave Drop', 'River Bend Water Drop', 'North Fairy Cave', 'River Bend WC', 'River Bend SW']), + create_lw_region(player, 'River Bend East Bank', None, ['River Bend East Water Drop', 'River Bend SE', 'River Bend EC', 'River Bend ES']), create_lw_region(player, 'River Bend Water', None, ['River Bend West Pier', 'River Bend East Pier', 'River Bend EN', 'River Bend SC', 'River Bend Whirlpool'], 'Light World', Terrain.Water), - create_lw_region(player, 'Potion Shop Area', None, ['Potion Shop Water Drop', 'Potion Shop Rock (South)', 'Potion Shop', 'Dark Witch Mirror Spot', 'Potion Shop WC', 'Potion Shop WS']), - create_lw_region(player, 'Potion Shop Northeast', None, ['Potion Shop Northeast Water Drop', 'Potion Shop Rock (North)', 'Dark Witch Northeast Mirror Spot', 'Potion Shop EC']), + create_lw_region(player, 'Potion Shop Area', None, ['Potion Shop Water Drop', 'Potion Shop Rock (South)', 'Potion Shop', 'Potion Shop WC', 'Potion Shop WS']), + create_lw_region(player, 'Potion Shop Northeast', None, ['Potion Shop Northeast Water Drop', 'Potion Shop Rock (North)', 'Potion Shop EC']), create_lw_region(player, 'Potion Shop Water', None, ['Potion Shop WN', 'Potion Shop EN'], 'Light World', Terrain.Water), - create_lw_region(player, 'Zora Approach Area', None, ['Zora Approach Rocks (West)', 'Zora Approach Bottom Ledge Drop', 'Zora Approach Water Drop', 'Catfish Approach Mirror Spot', 'Zora Approach WC']), - create_lw_region(player, 'Zora Approach Ledge', None, ['Zora Approach Rocks (East)', 'Zora Approach Ledge Drop', 'Catfish Approach Ledge Mirror Spot', 'Zora Approach NE']), + create_lw_region(player, 'Zora Approach Area', None, ['Zora Approach Rocks (West)', 'Zora Approach Bottom Ledge Drop', 'Zora Approach Water Drop', 'Zora Approach WC']), + create_lw_region(player, 'Zora Approach Ledge', None, ['Zora Approach Rocks (East)', 'Zora Approach Ledge Drop', 'Zora Approach NE']), create_lw_region(player, 'Zora Approach Water', None, ['Zora Approach WN'], 'Light World', Terrain.Water), create_lw_region(player, 'Kakariko Area', ['Bottle Merchant'], ['Kakariko Southwest Bush (North)', 'Kakariko Yard Bush (South)', 'Kakariko Well Drop', 'Kakariko Well Cave', 'Blinds Hideout', 'Elder House (West)', 'Elder House (East)', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Chicken House', 'Sick Kids House', - 'Kakariko Shop', 'Tavern (Front)', 'Tavern North', 'Village of Outcasts Mirror Spot', 'Kakariko NW', 'Kakariko NC', 'Kakariko NE', 'Kakariko ES', 'Kakariko SE']), - create_lw_region(player, 'Kakariko Southwest', None, ['Kakariko Southwest Bush (South)', 'Light World Bomb Hut', 'Village of Outcasts Southwest Mirror Spot']), - create_lw_region(player, 'Kakariko Grass Yard', None, ['Kakariko Yard Bush (North)', 'Bush Covered House', 'Hammer House Mirror Spot']), - create_lw_region(player, 'Forgotten Forest Area', None, ['Shield Shop Mirror Spot', 'Forgotten Forest NW', 'Forgotten Forest NE', 'Forgotten Forest ES']), - create_lw_region(player, 'Hyrule Castle Area', None, ['Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Main Gate (South)', 'Hyrule Castle Inner East Rock', 'Hyrule Castle Southwest Bush (North)', 'Top of Pyramid', 'Pyramid Mirror Spot', 'Pyramid Pass Mirror Spot', 'Hyrule Castle WN', 'Hyrule Castle SE']), + 'Kakariko Shop', 'Tavern (Front)', 'Tavern North', 'Kakariko NW', 'Kakariko NC', 'Kakariko NE', 'Kakariko ES', 'Kakariko SE']), + create_lw_region(player, 'Kakariko Southwest', None, ['Kakariko Southwest Bush (South)', 'Light World Bomb Hut']), + create_lw_region(player, 'Kakariko Grass Yard', None, ['Kakariko Yard Bush (North)', 'Bush Covered House']), + create_lw_region(player, 'Forgotten Forest Area', None, ['Forgotten Forest NW', 'Forgotten Forest NE', 'Forgotten Forest ES']), + create_lw_region(player, 'Hyrule Castle Area', None, ['Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Main Gate (South)', 'Hyrule Castle Inner East Rock', 'Hyrule Castle Southwest Bush (North)', 'Top of Pyramid', 'Hyrule Castle WN', 'Hyrule Castle SE']), create_lw_region(player, 'Hyrule Castle Southwest', None, ['Hyrule Castle Southwest Bush (South)', 'Hyrule Castle SW']), - create_lw_region(player, 'Hyrule Castle Courtyard', None, ['Hyrule Castle Courtyard Bush (South)', 'Hyrule Castle Main Gate (North)', 'Hyrule Castle Entrance (South)', 'Pyramid Courtyard Mirror Spot', 'Top of Pyramid (Inner)']), - create_lw_region(player, 'Hyrule Castle Courtyard Northeast', None, ['Hyrule Castle Courtyard Bush (North)', 'Hyrule Castle Secret Entrance Stairs', 'Pyramid Uncle Mirror Spot']), - create_lw_region(player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Ledge Drop', 'Hyrule Castle Ledge Courtyard Drop', 'Inverted Pyramid Entrance', 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Hyrule Castle Entrance (East)', 'Inverted Pyramid Hole', 'Pyramid From Ledge Mirror Spot'], 'the castle rampart'), - create_lw_region(player, 'Hyrule Castle East Entry', None, ['Hyrule Castle Outer East Rock', 'Pyramid Entry Mirror Spot', 'Hyrule Castle ES']), + create_lw_region(player, 'Hyrule Castle Courtyard', None, ['Hyrule Castle Courtyard Bush (South)', 'Hyrule Castle Main Gate (North)', 'Hyrule Castle Entrance (South)', 'Top of Pyramid (Inner)']), + create_lw_region(player, 'Hyrule Castle Courtyard Northeast', None, ['Hyrule Castle Courtyard Bush (North)', 'Hyrule Castle Secret Entrance Stairs']), + create_lw_region(player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Ledge Drop', 'Hyrule Castle Ledge Courtyard Drop', 'Inverted Pyramid Entrance', 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Hyrule Castle Entrance (East)', 'Inverted Pyramid Hole'], 'the castle rampart'), + create_lw_region(player, 'Hyrule Castle East Entry', None, ['Hyrule Castle Outer East Rock', 'Hyrule Castle ES']), create_dw_region(player, 'Hyrule Castle Water', None, ['Blacksmith Water Exit'], 'Dark World', Terrain.Water), - create_lw_region(player, 'Wooden Bridge Area', None, ['Wooden Bridge Bush (South)', 'Wooden Bridge Water Drop', 'Broken Bridge West Mirror Spot', 'Broken Bridge East Mirror Spot', 'Wooden Bridge NW', 'Wooden Bridge SW']), - create_lw_region(player, 'Wooden Bridge Northeast', None, ['Wooden Bridge Bush (North)', 'Wooden Bridge Northeast Water Drop', 'Broken Bridge Northeast Mirror Spot', 'Wooden Bridge NE']), + create_lw_region(player, 'Wooden Bridge Area', None, ['Wooden Bridge Bush (South)', 'Wooden Bridge Water Drop', 'Wooden Bridge NW', 'Wooden Bridge SW']), + create_lw_region(player, 'Wooden Bridge Northeast', None, ['Wooden Bridge Bush (North)', 'Wooden Bridge Northeast Water Drop', 'Wooden Bridge NE']), create_lw_region(player, 'Wooden Bridge Water', None, ['Wooden Bridge NC'], 'Light World', Terrain.Water), - create_lw_region(player, 'Eastern Palace Area', None, ['Sahasrahlas Hut', 'Eastern Palace', 'Palace of Darkness Mirror Spot', 'Eastern Palace SW', 'Eastern Palace SE']), + create_lw_region(player, 'Eastern Palace Area', None, ['Sahasrahlas Hut', 'Eastern Palace', 'Eastern Palace SW', 'Eastern Palace SE']), create_lw_region(player, 'Eastern Cliff', None, ['Sand Dunes Ledge Drop', 'Stone Bridge East Ledge Drop', 'Tree Line Ledge Drop', 'Eastern Palace Ledge Drop']), - create_lw_region(player, 'Blacksmith Area', None, ['Blacksmiths Hut', 'Bat Cave Cave', 'Bat Cave Ledge Peg', 'Hammer Pegs Mirror Spot', 'Hammer Pegs Entry Mirror Spot', 'Blacksmith WS']), + create_lw_region(player, 'Blacksmith Area', None, ['Blacksmiths Hut', 'Bat Cave Cave', 'Bat Cave Ledge Peg', 'Blacksmith WS']), create_lw_region(player, 'Bat Cave Ledge', None, ['Bat Cave Ledge Peg (East)', 'Bat Cave Drop']), - create_lw_region(player, 'Sand Dunes Area', None, ['Dark Dunes Mirror Spot', 'Sand Dunes NW', 'Sand Dunes WN', 'Sand Dunes SC']), - create_lw_region(player, 'Maze Race Area', None, ['Dig Game Mirror Spot', 'Maze Race ES']), - create_lw_region(player, 'Maze Race Ledge', None, ['Two Brothers House (West)', 'Maze Race Game', 'Dig Game Ledge Mirror Spot'], 'a race against time'), + create_lw_region(player, 'Sand Dunes Area', None, ['Sand Dunes NW', 'Sand Dunes WN', 'Sand Dunes SC']), + create_lw_region(player, 'Maze Race Area', None, ['Maze Race ES']), + create_lw_region(player, 'Maze Race Ledge', None, ['Two Brothers House (West)', 'Maze Race Game'], 'a race against time'), create_lw_region(player, 'Maze Race Prize', ['Maze Race'], ['Maze Race Ledge Drop']), #this is a separate region to make OWG item get possible without allowing the Entrance access - create_lw_region(player, 'Kakariko Suburb Area', None, ['Library', 'Two Brothers House (East)', 'Kakariko Gamble Game', 'Frog Mirror Spot', 'Frog Prison Mirror Spot', 'Archery Game Mirror Spot', 'Kakariko Suburb NE', 'Kakariko Suburb WS', 'Kakariko Suburb ES']), - create_lw_region(player, 'Flute Boy Area', ['Flute Spot'], ['Stumpy Mirror Spot', 'Flute Boy SC']), - create_lw_region(player, 'Flute Boy Pass', None, ['Stumpy Pass Mirror Spot', 'Flute Boy WS', 'Flute Boy SW']), - create_lw_region(player, 'Central Bonk Rocks Area', None, ['Bonk Fairy (Light)', 'Dark Bonk Rocks Mirror Spot', 'Central Bonk Rocks NW', 'Central Bonk Rocks SW', 'Central Bonk Rocks EN', 'Central Bonk Rocks EC', 'Central Bonk Rocks ES']), - create_lw_region(player, 'Links House Area', None, ['Links House', 'Big Bomb Shop Mirror Spot', 'Links House NE', 'Links House WN', 'Links House WC', 'Links House WS', 'Links House SC', 'Links House ES']), - create_lw_region(player, 'Stone Bridge North Area', None, ['Stone Bridge Southbound', 'Hammer Bridge North Mirror Spot', 'Stone Bridge NC', 'Stone Bridge EN']), - create_lw_region(player, 'Stone Bridge South Area', None, ['Stone Bridge Northbound', 'Hammer Bridge South Mirror Spot', 'Stone Bridge WS', 'Stone Bridge SC']), - create_lw_region(player, 'Stone Bridge Water', None, ['Dark Hobo Mirror Spot', 'Stone Bridge WC', 'Stone Bridge EC'], 'Light World', Terrain.Water), + create_lw_region(player, 'Kakariko Suburb Area', None, ['Library', 'Two Brothers House (East)', 'Kakariko Gamble Game', 'Kakariko Suburb NE', 'Kakariko Suburb WS', 'Kakariko Suburb ES']), + create_lw_region(player, 'Flute Boy Area', ['Flute Spot'], ['Flute Boy SC']), + create_lw_region(player, 'Flute Boy Pass', None, ['Flute Boy WS', 'Flute Boy SW']), + create_lw_region(player, 'Central Bonk Rocks Area', None, ['Bonk Fairy (Light)', 'Central Bonk Rocks NW', 'Central Bonk Rocks SW', 'Central Bonk Rocks EN', 'Central Bonk Rocks EC', 'Central Bonk Rocks ES']), + create_lw_region(player, 'Links House Area', None, ['Links House', 'Links House NE', 'Links House WN', 'Links House WC', 'Links House WS', 'Links House SC', 'Links House ES']), + create_lw_region(player, 'Stone Bridge North Area', None, ['Stone Bridge Southbound', 'Stone Bridge NC', 'Stone Bridge EN']), + create_lw_region(player, 'Stone Bridge South Area', None, ['Stone Bridge Northbound', 'Stone Bridge WS', 'Stone Bridge SC']), + create_lw_region(player, 'Stone Bridge Water', None, ['Stone Bridge WC', 'Stone Bridge EC'], 'Light World', Terrain.Water), create_lw_region(player, 'Hobo Bridge', ['Hobo'], ['Hobo EC'], 'Light World', Terrain.Water), create_lw_region(player, 'Central Cliffs', None, ['Central Bonk Rocks Cliff Ledge Drop', 'Links House Cliff Ledge Drop', 'Stone Bridge Cliff Ledge Drop', 'Lake Hylia Area Cliff Ledge Drop', 'Lake Hylia Island FAWT Ledge Drop', 'Stone Bridge EC Cliff Water Drop', 'Tree Line WC Cliff Water Drop', 'C Whirlpool Outer Cliff Ledge Drop', 'C Whirlpool Cliff Ledge Drop', 'C Whirlpool Portal Cliff Ledge Drop', 'Statues Cliff Ledge Drop']), - create_lw_region(player, 'Tree Line Area', None, ['Lake Hylia Fairy', 'Dark Tree Line Mirror Spot', 'Tree Line WN', 'Tree Line NW', 'Tree Line SE']), + create_lw_region(player, 'Tree Line Area', None, ['Lake Hylia Fairy', 'Tree Line WN', 'Tree Line NW', 'Tree Line SE']), create_lw_region(player, 'Tree Line Water', None, ['Tree Line WC', 'Tree Line SC'], 'Light World', Terrain.Water), - create_lw_region(player, 'Eastern Nook Area', None, ['Long Fairy Cave', 'Darkness Nook Mirror Spot', 'East Hyrule Teleporter', 'Eastern Nook NE']), - create_lw_region(player, 'Desert Area', None, ['Desert Palace Statue Move', 'Checkerboard Ledge Approach', 'Aginahs Cave', 'Misery Mire Mirror Spot', 'Desert ES']), - create_lw_region(player, 'Desert Ledge', ['Desert Ledge'], ['Desert Ledge Outer Rocks', 'Desert Ledge Drop', 'Desert Palace Entrance (West)', 'Misery Mire Ledge Mirror Spot'], 'the desert ledge'), - create_lw_region(player, 'Desert Palace Entrance (North) Spot', None, ['Desert Ledge Inner Rocks', 'Desert Palace Entrance (North)', 'Misery Mire Blocked Mirror Spot'], 'the desert ledge'), + create_lw_region(player, 'Eastern Nook Area', None, ['Long Fairy Cave', 'East Hyrule Teleporter', 'Eastern Nook NE']), + create_lw_region(player, 'Desert Area', None, ['Desert Palace Statue Move', 'Checkerboard Ledge Approach', 'Aginahs Cave', 'Desert ES']), + create_lw_region(player, 'Desert Ledge', ['Desert Ledge'], ['Desert Ledge Outer Rocks', 'Desert Ledge Drop', 'Desert Palace Entrance (West)'], 'the desert ledge'), + create_lw_region(player, 'Desert Palace Entrance (North) Spot', None, ['Desert Ledge Inner Rocks', 'Desert Palace Entrance (North)'], 'the desert ledge'), create_lw_region(player, 'Desert Checkerboard Ledge', None, ['Checkerboard Ledge Leave', 'Checkerboard Ledge Drop', 'Checkerboard Cave']), - create_lw_region(player, 'Desert Palace Stairs', None, ['Desert Palace Entrance (South)', 'Misery Mire Main Mirror Spot'], 'a sandy vista'), + create_lw_region(player, 'Desert Palace Stairs', None, ['Desert Palace Entrance (South)'], 'a sandy vista'), create_lw_region(player, 'Desert Palace Mouth', None, ['Desert Mouth Drop', 'Desert Palace Entrance (East)']), create_lw_region(player, 'Desert Palace Teleporter Ledge', None, ['Desert Teleporter Drop', 'Desert Teleporter']), create_lw_region(player, 'Desert Northeast Cliffs', None, ['Desert Boss Cliff Ledge Drop', 'Checkerboard Cliff Ledge Drop', 'Suburb Cliff Ledge Drop', 'Cave 45 Cliff Ledge Drop', 'Desert C Whirlpool Cliff Ledge Drop', 'Desert Pass Cliff Ledge Drop', 'Dam Cliff Ledge Drop']), create_lw_region(player, 'Bombos Tablet Ledge', ['Bombos Tablet'], ['Bombos Tablet Drop', 'Desert EC']), - create_lw_region(player, 'Flute Boy Approach Area', None, ['Flute Boy Bush (South)', 'Cave 45 Inverted Approach', 'Stumpy Approach Mirror Spot', 'Flute Boy Approach NW', 'Flute Boy Approach EC']), - create_lw_region(player, 'Flute Boy Bush Entry', None, ['Flute Boy Bush (North)', 'Stumpy Bush Entry Mirror Spot', 'Flute Boy Approach NC']), + create_lw_region(player, 'Flute Boy Approach Area', None, ['Flute Boy Bush (South)', 'Cave 45 Inverted Approach', 'Flute Boy Approach NW', 'Flute Boy Approach EC']), + create_lw_region(player, 'Flute Boy Bush Entry', None, ['Flute Boy Bush (North)', 'Flute Boy Approach NC']), create_lw_region(player, 'Cave 45 Ledge', None, ['Cave 45 Inverted Leave', 'Cave 45 Ledge Drop', 'Cave 45']), - create_lw_region(player, 'C Whirlpool Area', None, ['C Whirlpool Rock (Bottom)', 'C Whirlpool Pegs (Right)', 'C Whirlpool Water Entry', 'Dark C Whirlpool Mirror Spot', 'C Whirlpool EN', 'C Whirlpool ES', 'C Whirlpool SC']), + create_lw_region(player, 'C Whirlpool Area', None, ['C Whirlpool Rock (Bottom)', 'C Whirlpool Pegs (Right)', 'C Whirlpool Water Entry', 'C Whirlpool EN', 'C Whirlpool ES', 'C Whirlpool SC']), create_lw_region(player, 'C Whirlpool Portal Area', None, ['C Whirlpool Pegs (Left)', 'South Hyrule Teleporter']), create_lw_region(player, 'C Whirlpool Water', None, ['C Whirlpool Landing', 'C Whirlpool', 'C Whirlpool EC'], 'Light World', Terrain.Water), - create_lw_region(player, 'C Whirlpool Outer Area', None, ['C Whirlpool Rock (Top)', 'Dark C Whirlpool Outer Mirror Spot', 'C Whirlpool WC', 'C Whirlpool NW']), - create_lw_region(player, 'Statues Area', None, ['Statues Water Entry', 'Light Hype Fairy', 'Hype Cave Mirror Spot', 'Statues NC', 'Statues WN', 'Statues WS', 'Statues SC']), + create_lw_region(player, 'C Whirlpool Outer Area', None, ['C Whirlpool Rock (Top)', 'C Whirlpool WC', 'C Whirlpool NW']), + create_lw_region(player, 'Statues Area', None, ['Statues Water Entry', 'Light Hype Fairy', 'Statues NC', 'Statues WN', 'Statues WS', 'Statues SC']), create_lw_region(player, 'Statues Water', None, ['Statues Landing', 'Statues WC'], 'Light World', Terrain.Water), - create_lw_region(player, 'Lake Hylia Area', None, ['Lake Hylia Water Drop', 'Lake Hylia Fortune Teller', 'Cave Shop (Lake Hylia)', 'Ice Lake Mirror Spot', 'Lake Hylia NW']), - create_lw_region(player, 'Lake Hylia South Shore', None, ['Lake Hylia South Water Drop', 'Mini Moldorm Cave', 'Ice Lake Southwest Mirror Spot', 'Ice Lake Southeast Mirror Spot', 'Lake Hylia WS', 'Lake Hylia ES']), - create_lw_region(player, 'Lake Hylia Northeast Bank', None, ['Lake Hylia Northeast Water Drop', 'Ice Lake Northeast Mirror Spot', 'Lake Hylia NE']), - create_lw_region(player, 'Lake Hylia Central Island', None, ['Lake Hylia Central Water Drop', 'Capacity Upgrade', 'Ice Palace Mirror Spot', 'Lake Hylia Teleporter']), + create_lw_region(player, 'Lake Hylia Area', None, ['Lake Hylia Water Drop', 'Lake Hylia Fortune Teller', 'Cave Shop (Lake Hylia)', 'Lake Hylia NW']), + create_lw_region(player, 'Lake Hylia South Shore', None, ['Lake Hylia South Water Drop', 'Mini Moldorm Cave', 'Lake Hylia WS', 'Lake Hylia ES']), + create_lw_region(player, 'Lake Hylia Northeast Bank', None, ['Lake Hylia Northeast Water Drop', 'Lake Hylia NE']), + create_lw_region(player, 'Lake Hylia Central Island', None, ['Lake Hylia Central Water Drop', 'Capacity Upgrade', 'Lake Hylia Teleporter']), create_lw_region(player, 'Lake Hylia Island', ['Lake Hylia Island'], ['Lake Hylia Island Water Drop']), create_lw_region(player, 'Lake Hylia Water', None, ['Lake Hylia Central Island Pier', 'Lake Hylia Island Pier', 'Lake Hylia West Pier', 'Lake Hylia East Pier', 'Lake Hylia Water D Approach', 'Lake Hylia NC', 'Lake Hylia EC', 'Lake Hylia Whirlpool'], 'Light World', Terrain.Water), - create_lw_region(player, 'Lake Hylia Water D', None, ['Lake Hylia Water D Leave', 'Ice Lake Moat Mirror Spot'], 'Light World', Terrain.Water), - create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Shopping Mall Mirror Spot', 'Ice Cave SE', 'Ice Cave SW']), - create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Pass Ladder (South)', 'Middle Aged Man', 'Desert Fairy', '50 Rupee Cave', 'Swamp Nook Mirror Spot', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']), + create_lw_region(player, 'Lake Hylia Water D', None, ['Lake Hylia Water D Leave'], 'Light World', Terrain.Water), + create_lw_region(player, 'Ice Cave Area', None, ['Ice Rod Cave', 'Good Bee Cave', '20 Rupee Cave', 'Ice Cave SE', 'Ice Cave SW']), + create_lw_region(player, 'Desert Pass Area', ['Middle Aged Man'], ['Desert Pass Ladder (South)', 'Middle Aged Man', 'Desert Fairy', '50 Rupee Cave', 'Desert Pass WS', 'Desert Pass EC', 'Desert Pass Rocks (North)']), create_lw_region(player, 'Middle Aged Man', ['Purple Chest'], None), - create_lw_region(player, 'Desert Pass Southeast', None, ['Desert Pass Rocks (South)', 'Swamp Nook Southeast Mirror Spot', 'Desert Pass ES']), - create_lw_region(player, 'Desert Pass Ledge', None, ['Desert Pass Ladder (North)', 'Desert Pass Ledge Drop', 'Swamp Nook Pegs Mirror Spot', 'Desert Pass WC']), - create_lw_region(player, 'Dam Area', ['Sunken Treasure'], ['Dam', 'Swamp Mirror Spot', 'Dam WC', 'Dam WS', 'Dam NC', 'Dam EC']), - create_lw_region(player, 'South Pass Area', None, ['Dark South Pass Mirror Spot', 'South Pass WC', 'South Pass NC', 'South Pass ES']), - create_lw_region(player, 'Octoballoon Area', None, ['Octoballoon Water Drop', 'Bomber Corner Mirror Spot', 'Octoballoon WS', 'Octoballoon NE']), + create_lw_region(player, 'Desert Pass Southeast', None, ['Desert Pass Rocks (South)', 'Desert Pass ES']), + create_lw_region(player, 'Desert Pass Ledge', None, ['Desert Pass Ladder (North)', 'Desert Pass Ledge Drop', 'Desert Pass WC']), + create_lw_region(player, 'Dam Area', ['Sunken Treasure'], ['Dam', 'Dam WC', 'Dam WS', 'Dam NC', 'Dam EC']), + create_lw_region(player, 'South Pass Area', None, ['South Pass WC', 'South Pass NC', 'South Pass ES']), + create_lw_region(player, 'Octoballoon Area', None, ['Octoballoon Water Drop', 'Octoballoon WS', 'Octoballoon NE']), create_lw_region(player, 'Octoballoon Water', None, ['Octoballoon Pier', 'Octoballoon WC', 'Octoballoon Whirlpool'], 'Light World', Terrain.Water), create_lw_region(player, 'Octoballoon Water Ledge', None, ['Octoballoon Waterfall Water Drop', 'Octoballoon NW'], 'Light World', Terrain.Water), create_dw_region(player, 'Skull Woods Forest', None, ['Skull Woods Bush Rock (East)', 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', - 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Lost Woods East Mirror Spot', 'Skull Woods SE']), - create_dw_region(player, 'Skull Woods Portal Entry', None, ['Skull Woods Bush Rock (West)', 'Lost Woods Entry Mirror Spot', 'Skull Woods SC']), - create_dw_region(player, 'Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', 'Lost Woods Pedestal Mirror Spot'], 'a deep, dark forest'), - create_dw_region(player, 'Skull Woods Forgotten Path (Southwest)', None, ['Skull Woods Forgotten Bush (West)', 'Lost Woods Southwest Mirror Spot', 'Skull Woods SW']), - create_dw_region(player, 'Skull Woods Forgotten Path (Northeast)', None, ['Skull Woods Forgotten Bush (East)', 'Lost Woods East (Forgotten) Mirror Spot', 'Lost Woods West (Forgotten) Mirror Spot', 'Skull Woods EN']), - create_dw_region(player, 'Dark Lumberjack Area', None, ['Dark World Lumberjack Shop', 'Lumberjack Mirror Spot', 'Dark Lumberjack WN', 'Dark Lumberjack SW']), - create_dw_region(player, 'West Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (West)', 'GT Entry Approach', 'West Death Mountain (Top) Mirror Spot', 'West Dark Death Mountain EN']), + 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods SE']), + create_dw_region(player, 'Skull Woods Portal Entry', None, ['Skull Woods Bush Rock (West)', 'Skull Woods SC']), + create_dw_region(player, 'Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section'], 'a deep, dark forest'), + create_dw_region(player, 'Skull Woods Forgotten Path (Southwest)', None, ['Skull Woods Forgotten Bush (West)', 'Skull Woods SW']), + create_dw_region(player, 'Skull Woods Forgotten Path (Northeast)', None, ['Skull Woods Forgotten Bush (East)', 'Skull Woods EN']), + create_dw_region(player, 'Dark Lumberjack Area', None, ['Dark World Lumberjack Shop', 'Dark Lumberjack WN', 'Dark Lumberjack SW']), + create_dw_region(player, 'West Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (West)', 'GT Entry Approach', 'West Dark Death Mountain EN']), create_dw_region(player, 'GT Approach', None, ['GT Entry Leave', 'Ganons Tower']), - create_dw_region(player, 'West Dark Death Mountain (Bottom)', None, ['Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'Spectacle Rock Mirror Spot', 'West Dark Death Mountain ES']), - create_dw_region(player, 'East Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Superbunny Cave (Top)', 'Hookshot Cave', 'East Death Mountain (Top West) Mirror Spot', 'East Death Mountain (Top East) Mirror Spot', 'East Dark Death Mountain WN', 'East Dark Death Mountain EN']), - create_dw_region(player, 'East Dark Death Mountain (Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East)', 'Fairy Ascension Mirror Spot']), - create_dw_region(player, 'East Dark Death Mountain (Bottom Left)', None, ['Death Mountain Bridge Mirror Spot', 'East Dark Death Mountain WS']), - create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)', 'Spiral Cave Mirror Spot', 'Mimic Cave Mirror Spot'], 'a dark ledge'), - create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Turtle Rock Isolated Ledge Entrance', 'Isolated Ledge Mirror Spot'], 'a dark vista'), - create_dw_region(player, 'Dark Death Mountain Floating Island', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance', 'Floating Island Mirror Spot'], 'a dark floating island'), - create_dw_region(player, 'Turtle Rock Area', None, ['Turtle Rock Tail Ledge Drop', 'Turtle Rock', 'TR Pegs Area Mirror Spot', 'Turtle Rock WN']), + create_dw_region(player, 'West Dark Death Mountain (Bottom)', None, ['Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'West Dark Death Mountain ES']), + create_dw_region(player, 'East Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Superbunny Cave (Top)', 'Hookshot Cave', 'East Dark Death Mountain WN', 'East Dark Death Mountain EN']), + create_dw_region(player, 'East Dark Death Mountain (Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East)']), + create_dw_region(player, 'East Dark Death Mountain (Bottom Left)', None, ['East Dark Death Mountain WS']), + create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)'], 'a dark ledge'), + create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Turtle Rock Isolated Ledge Entrance'], 'a dark vista'), + create_dw_region(player, 'Dark Death Mountain Floating Island', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance'], 'a dark floating island'), + create_dw_region(player, 'Turtle Rock Area', None, ['Turtle Rock Tail Ledge Drop', 'Turtle Rock', 'Turtle Rock WN']), create_dw_region(player, 'Turtle Rock Ledge', ['Turtle Medallion Pad'], ['Turtle Rock Ledge Drop', 'Turtle Rock Teleporter']), - create_dw_region(player, 'Bumper Cave Area', None, ['Bumper Cave Entrance Rock', 'Mountain Entry Mirror Spot', 'Bumper Cave NW', 'Bumper Cave SE']), - create_dw_region(player, 'Bumper Cave Entrance', None, ['Bumper Cave Ledge Drop', 'Bumper Cave (Bottom)', 'Mountain Entry Entrance Mirror Spot']), - create_dw_region(player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], ['Bumper Cave Entrance Drop', 'Bumper Cave (Top)', 'Mountain Entry Ledge Mirror Spot'], 'a ledge with an item'), - create_dw_region(player, 'Catfish Area', ['Catfish'], ['Zora Waterfall Mirror Spot', 'Catfish SE']), - create_dw_region(player, 'Skull Woods Pass West Area', None, ['Skull Woods Pass Bush Row (West)', 'Lost Woods Pass West Mirror Spot', 'Skull Woods Pass NW', 'Skull Woods Pass SW']), - create_dw_region(player, 'Skull Woods Pass East Top Area', None, ['Lost Woods Pass East Top Mirror Spot', 'Skull Woods Pass Bush Row (East)', 'Skull Woods Pass Bush (North)', 'Skull Woods Pass NE']), - create_dw_region(player, 'Skull Woods Pass Portal Area', None, ['Lost Woods Pass Portal Mirror Spot', 'West Dark World Teleporter', 'Skull Woods Pass Bush (South)', 'Skull Woods Pass Rock (North)']), - create_dw_region(player, 'Skull Woods Pass East Bottom Area', None, ['Lost Woods Pass East Bottom Mirror Spot', 'Skull Woods Pass Rock (South)', 'Skull Woods Pass SE']), - create_dw_region(player, 'Dark Fortune Area', None, ['Fortune Teller (Dark)', 'Kakariko Fortune Mirror Spot', 'Dark Fortune NE', 'Dark Fortune EN', 'Dark Fortune ES', 'Dark Fortune SC']), - create_dw_region(player, 'Outcast Pond Area', None, ['Kakariko Pond Mirror Spot', 'Outcast Pond NE', 'Outcast Pond WN', 'Outcast Pond WS', 'Outcast Pond SW', 'Outcast Pond SE', 'Outcast Pond EN', 'Outcast Pond ES']), - create_dw_region(player, 'Dark Chapel Area', None, ['Dark Sanctuary Hint', 'Sanctuary Mirror Spot', 'Bonk Rock Ledge Mirror Spot', 'Dark Chapel WN', 'Dark Chapel WS', 'Dark Chapel EC']), + create_dw_region(player, 'Bumper Cave Area', None, ['Bumper Cave Entrance Rock', 'Bumper Cave NW', 'Bumper Cave SE']), + create_dw_region(player, 'Bumper Cave Entrance', None, ['Bumper Cave Ledge Drop', 'Bumper Cave (Bottom)']), + create_dw_region(player, 'Bumper Cave Ledge', ['Bumper Cave Ledge'], ['Bumper Cave Entrance Drop', 'Bumper Cave (Top)'], 'a ledge with an item'), + create_dw_region(player, 'Catfish Area', ['Catfish'], ['Catfish SE']), + create_dw_region(player, 'Skull Woods Pass West Area', None, ['Skull Woods Pass Bush Row (West)', 'Skull Woods Pass NW', 'Skull Woods Pass SW']), + create_dw_region(player, 'Skull Woods Pass East Top Area', None, ['Skull Woods Pass Bush Row (East)', 'Skull Woods Pass Bush (North)', 'Skull Woods Pass NE']), + create_dw_region(player, 'Skull Woods Pass Portal Area', None, ['West Dark World Teleporter', 'Skull Woods Pass Bush (South)', 'Skull Woods Pass Rock (North)']), + create_dw_region(player, 'Skull Woods Pass East Bottom Area', None, ['Skull Woods Pass Rock (South)', 'Skull Woods Pass SE']), + create_dw_region(player, 'Dark Fortune Area', None, ['Fortune Teller (Dark)', 'Dark Fortune NE', 'Dark Fortune EN', 'Dark Fortune ES', 'Dark Fortune SC']), + create_dw_region(player, 'Outcast Pond Area', None, ['Outcast Pond NE', 'Outcast Pond WN', 'Outcast Pond WS', 'Outcast Pond SW', 'Outcast Pond SE', 'Outcast Pond EN', 'Outcast Pond ES']), + create_dw_region(player, 'Dark Chapel Area', None, ['Dark Sanctuary Hint', 'Dark Chapel WN', 'Dark Chapel WS', 'Dark Chapel EC']), create_dw_region(player, 'Dark Graveyard Area', None, ['Dark Graveyard Bush (South)', 'Dark Graveyard WC', 'Dark Graveyard EC']), - create_dw_region(player, 'Dark Graveyard North', None, ['Graveyard Ledge Mirror Spot', 'Kings Grave Mirror Spot', 'Dark Graveyard Bush (North)']), - create_dw_region(player, 'Qirn Jump Area', None, ['Qirn Jump Water Drop', 'River Bend Mirror Spot', 'Qirn Jump WC', 'Qirn Jump SW']), - create_dw_region(player, 'Qirn Jump East Bank', None, ['Qirn Jump East Water Drop', 'River Bend East Mirror Spot', 'Qirn Jump SE', 'Qirn Jump EC', 'Qirn Jump ES']), + create_dw_region(player, 'Dark Graveyard North', None, ['Dark Graveyard Bush (North)']), + create_dw_region(player, 'Qirn Jump Area', None, ['Qirn Jump Water Drop', 'Qirn Jump WC', 'Qirn Jump SW']), + create_dw_region(player, 'Qirn Jump East Bank', None, ['Qirn Jump East Water Drop', 'Qirn Jump SE', 'Qirn Jump EC', 'Qirn Jump ES']), create_dw_region(player, 'Qirn Jump Water', None, ['Qirn Jump Pier', 'Qirn Jump Whirlpool', 'Qirn Jump EN', 'Qirn Jump SC'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Dark Witch Area', None, ['Dark Witch Water Drop', 'Dark Witch Rock (South)', 'Dark World Potion Shop', 'Potion Shop Mirror Spot', 'Dark Witch WC', 'Dark Witch WS']), - create_dw_region(player, 'Dark Witch Northeast', None, ['Dark Witch Northeast Water Drop', 'Dark Witch Rock (North)', 'Potion Shop Northeast Mirror Spot', 'Dark Witch EC']), + create_dw_region(player, 'Dark Witch Area', None, ['Dark Witch Water Drop', 'Dark Witch Rock (South)', 'Dark World Potion Shop', 'Dark Witch WC', 'Dark Witch WS']), + create_dw_region(player, 'Dark Witch Northeast', None, ['Dark Witch Northeast Water Drop', 'Dark Witch Rock (North)', 'Dark Witch EC']), create_dw_region(player, 'Dark Witch Water', None, ['Dark Witch WN', 'Dark Witch EN'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Catfish Approach Area', None, ['Catfish Approach Rocks (West)', 'Catfish Approach Bottom Ledge Drop', 'Catfish Approach Water Drop', 'Zora Approach Mirror Spot', 'Catfish Approach WC']), - create_dw_region(player, 'Catfish Approach Ledge', None, ['Catfish Approach Rocks (East)', 'Catfish Approach Ledge Drop', 'Zora Approach Ledge Mirror Spot', 'Catfish Approach NE']), + create_dw_region(player, 'Catfish Approach Area', None, ['Catfish Approach Rocks (West)', 'Catfish Approach Bottom Ledge Drop', 'Catfish Approach Water Drop', 'Catfish Approach WC']), + create_dw_region(player, 'Catfish Approach Ledge', None, ['Catfish Approach Rocks (East)', 'Catfish Approach Ledge Drop', 'Catfish Approach NE']), create_dw_region(player, 'Catfish Approach Water', None, ['Catfish Approach WN'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Village of Outcasts Area', None, ['Village of Outcasts Pegs', 'Chest Game', 'Thieves Town', 'C-Shaped House', 'Brewery', 'Kakariko Mirror Spot', 'Village of Outcasts NW', 'Village of Outcasts NC', 'Village of Outcasts NE', 'Village of Outcasts ES', 'Village of Outcasts SE']), - create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop', 'Kakariko Grass Mirror Spot']), - create_dw_region(player, 'Shield Shop Area', None, ['Shield Shop Fence (Outer) Ledge Drop', 'Forgotton Forest Mirror Spot', 'Shield Shop NW', 'Shield Shop NE']), - create_dw_region(player, 'Shield Shop Fence', None, ['Shield Shop Fence (Inner) Ledge Drop', 'Red Shield Shop', 'Forgotton Forest Fence Mirror Spot']), - create_dw_region(player, 'Pyramid Area', ['Pyramid Crack', 'Pyramid'], ['Pyramid Crack', 'Pyramid Hole', 'HC Ledge Mirror Spot', 'HC Courtyard Mirror Spot', 'HC Area Mirror Spot', 'HC East Entry Mirror Spot', 'Pyramid ES']), + create_dw_region(player, 'Village of Outcasts Area', None, ['Village of Outcasts Pegs', 'Chest Game', 'Thieves Town', 'C-Shaped House', 'Brewery', 'Village of Outcasts NW', 'Village of Outcasts NC', 'Village of Outcasts NE', 'Village of Outcasts ES', 'Village of Outcasts SE']), + create_dw_region(player, 'Dark Grassy Lawn', None, ['Grassy Lawn Pegs', 'Dark World Shop']), + create_dw_region(player, 'Shield Shop Area', None, ['Shield Shop Fence (Outer) Ledge Drop', 'Shield Shop NW', 'Shield Shop NE']), + create_dw_region(player, 'Shield Shop Fence', None, ['Shield Shop Fence (Inner) Ledge Drop', 'Red Shield Shop']), + create_dw_region(player, 'Pyramid Area', ['Pyramid Crack', 'Pyramid'], ['Pyramid Crack', 'Pyramid Hole', 'Pyramid ES']), create_dw_region(player, 'Pyramid Crack', None, ['Pyramid Fairy']), - create_dw_region(player, 'Pyramid Exit Ledge', None, ['Pyramid Exit Ledge Drop', 'HC Courtyard Left Mirror Spot', 'Pyramid Entrance']), - create_dw_region(player, 'Pyramid Pass', None, ['Post Aga Inverted Teleporter', 'HC Area South Mirror Spot', 'Pyramid SW', 'Pyramid SE']), + create_dw_region(player, 'Pyramid Exit Ledge', None, ['Pyramid Exit Ledge Drop', 'Pyramid Entrance']), + create_dw_region(player, 'Pyramid Pass', None, ['Post Aga Inverted Teleporter', 'Pyramid SW', 'Pyramid SE']), create_dw_region(player, 'Pyramid Water', None, ['Hammerpegs Water Exit', 'Big Bomb Shop Water Exit'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Broken Bridge Area', None, ['Broken Bridge Hammer Rock (South)', 'Broken Bridge Water Drop', 'Wooden Bridge Mirror Spot', 'Broken Bridge SW']), - create_dw_region(player, 'Broken Bridge Northeast', None, ['Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', 'Broken Bridge Northeast Water Drop', 'Wooden Bridge Northeast Mirror Spot', 'Broken Bridge NE']), - create_dw_region(player, 'Broken Bridge West', None, ['Broken Bridge West Water Drop', 'Wooden Bridge West Mirror Spot', 'Broken Bridge NW']), + create_dw_region(player, 'Broken Bridge Area', None, ['Broken Bridge Hammer Rock (South)', 'Broken Bridge Water Drop', 'Broken Bridge SW']), + create_dw_region(player, 'Broken Bridge Northeast', None, ['Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', 'Broken Bridge Northeast Water Drop', 'Broken Bridge NE']), + create_dw_region(player, 'Broken Bridge West', None, ['Broken Bridge West Water Drop', 'Broken Bridge NW']), create_dw_region(player, 'Broken Bridge Water', None, ['Broken Bridge NC'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Palace of Darkness Area', None, ['Palace of Darkness Hint', 'Palace of Darkness', 'Eastern Palace Mirror Spot', 'Palace of Darkness SW', 'Palace of Darkness SE']), + create_dw_region(player, 'Palace of Darkness Area', None, ['Palace of Darkness Hint', 'Palace of Darkness', 'Palace of Darkness SW', 'Palace of Darkness SE']), create_dw_region(player, 'Darkness Cliff', None, ['Dark Dunes Ledge Drop', 'Hammer Bridge North Ledge Drop', 'Dark Tree Line Ledge Drop', 'Palace of Darkness Ledge Drop']), - create_dw_region(player, 'Hammer Pegs Entry', None, ['Peg Area Rocks (West)', 'Blacksmith Entry Mirror Spot', 'Hammer Pegs WS']), - create_dw_region(player, 'Hammer Pegs Area', ['Dark Blacksmith Ruins'], ['Peg Area Rocks (East)', 'Dark World Hammer Peg Cave', 'Blacksmith Mirror Spot', 'Bat Cave Ledge Mirror Spot']), - create_dw_region(player, 'Dark Dunes Area', None, ['Sand Dunes Mirror Spot', 'Dark Dunes NW', 'Dark Dunes WN', 'Dark Dunes SC']), - create_dw_region(player, 'Dig Game Area', ['Digging Game'], ['Dig Game To Ledge Drop', 'Maze Race Mirror Spot', 'Dig Game ES']), - create_dw_region(player, 'Dig Game Ledge', None, ['Dig Game Ledge Drop', 'Maze Race Ledge Mirror Spot', 'Dig Game EC']), - create_dw_region(player, 'Frog Area', None, ['Frog Ledge Drop', 'Frog Rock (Outer)', 'Archery Game Rock (North)', 'Kakariko Suburb Mirror Spot', 'Frog NE']), + create_dw_region(player, 'Hammer Pegs Entry', None, ['Peg Area Rocks (West)', 'Hammer Pegs WS']), + create_dw_region(player, 'Hammer Pegs Area', ['Dark Blacksmith Ruins'], ['Peg Area Rocks (East)', 'Dark World Hammer Peg Cave']), + create_dw_region(player, 'Dark Dunes Area', None, ['Dark Dunes NW', 'Dark Dunes WN', 'Dark Dunes SC']), + create_dw_region(player, 'Dig Game Area', ['Digging Game'], ['Dig Game To Ledge Drop', 'Dig Game ES']), + create_dw_region(player, 'Dig Game Ledge', None, ['Dig Game Ledge Drop', 'Dig Game EC']), + create_dw_region(player, 'Frog Area', None, ['Frog Ledge Drop', 'Frog Rock (Outer)', 'Archery Game Rock (North)', 'Frog NE']), create_dw_region(player, 'Frog Prison', ['Frog'], ['Frog Rock (Inner)']), - create_dw_region(player, 'Archery Game Area', None, ['Archery Game Rock (South)', 'Archery Game', 'Kakariko Suburb South Mirror Spot', 'Frog WC', 'Frog WS', 'Frog ES']), - create_dw_region(player, 'Stumpy Area', ['Stumpy'], ['Flute Boy Mirror Spot', 'Stumpy SC']), - create_dw_region(player, 'Stumpy Pass', None, ['Flute Boy Pass Mirror Spot', 'Stumpy WS', 'Stumpy SW']), - create_dw_region(player, 'Dark Bonk Rocks Area', None, ['Bonk Fairy (Dark)', 'Central Bonk Rocks Mirror Spot', 'Dark Bonk Rocks NW', 'Dark Bonk Rocks SW', 'Dark Bonk Rocks EN', 'Dark Bonk Rocks EC', 'Dark Bonk Rocks ES']), - create_dw_region(player, 'Big Bomb Shop Area', None, ['Big Bomb Shop', 'Links House Mirror Spot', 'Big Bomb Shop NE', 'Big Bomb Shop WN', 'Big Bomb Shop WC', 'Big Bomb Shop WS', 'Big Bomb Shop SC', 'Big Bomb Shop ES']), - create_dw_region(player, 'Hammer Bridge North Area', None, ['Hammer Bridge Pegs (North)', 'Hammer Bridge Water Drop', 'Stone Bridge Mirror Spot', 'Hammer Bridge NC', 'Hammer Bridge EN']), - create_dw_region(player, 'Hammer Bridge South Area', None, ['Hammer Bridge Pegs (South)', 'Stone Bridge South Mirror Spot', 'Hammer Bridge WS', 'Hammer Bridge SC']), - create_dw_region(player, 'Hammer Bridge Water', None, ['Hammer Bridge Pier', 'Hobo Mirror Spot', 'Hammer Bridge EC'], 'Dark World', Terrain.Water), + create_dw_region(player, 'Archery Game Area', None, ['Archery Game Rock (South)', 'Archery Game', 'Frog WC', 'Frog WS', 'Frog ES']), + create_dw_region(player, 'Stumpy Area', ['Stumpy'], ['Stumpy SC']), + create_dw_region(player, 'Stumpy Pass', None, ['Stumpy WS', 'Stumpy SW']), + create_dw_region(player, 'Dark Bonk Rocks Area', None, ['Bonk Fairy (Dark)', 'Dark Bonk Rocks NW', 'Dark Bonk Rocks SW', 'Dark Bonk Rocks EN', 'Dark Bonk Rocks EC', 'Dark Bonk Rocks ES']), + create_dw_region(player, 'Big Bomb Shop Area', None, ['Big Bomb Shop', 'Big Bomb Shop NE', 'Big Bomb Shop WN', 'Big Bomb Shop WC', 'Big Bomb Shop WS', 'Big Bomb Shop SC', 'Big Bomb Shop ES']), + create_dw_region(player, 'Hammer Bridge North Area', None, ['Hammer Bridge Pegs (North)', 'Hammer Bridge Water Drop', 'Hammer Bridge NC', 'Hammer Bridge EN']), + create_dw_region(player, 'Hammer Bridge South Area', None, ['Hammer Bridge Pegs (South)', 'Hammer Bridge WS', 'Hammer Bridge SC']), + create_dw_region(player, 'Hammer Bridge Water', None, ['Hammer Bridge Pier', 'Hammer Bridge EC'], 'Dark World', Terrain.Water), create_dw_region(player, 'Dark Central Cliffs', None, ['Dark Bonk Rocks Cliff Ledge Drop', 'Bomb Shop Cliff Ledge Drop', 'Hammer Bridge South Cliff Ledge Drop', 'Ice Lake Area Cliff Ledge Drop', 'Ice Palace Island FAWT Ledge Drop', 'Hammer Bridge EC Cliff Water Drop', 'Dark Tree Line WC Cliff Water Drop', 'Dark C Whirlpool Outer Cliff Ledge Drop', 'Dark C Whirlpool Cliff Ledge Drop', 'Dark C Whirlpool Portal Cliff Ledge Drop', 'Hype Cliff Ledge Drop']), - create_dw_region(player, 'Dark Tree Line Area', None, ['Dark Lake Hylia Fairy', 'Tree Line Mirror Spot', 'Dark Tree Line WN', 'Dark Tree Line NW', 'Dark Tree Line SE']), + create_dw_region(player, 'Dark Tree Line Area', None, ['Dark Lake Hylia Fairy', 'Dark Tree Line WN', 'Dark Tree Line NW', 'Dark Tree Line SE']), create_dw_region(player, 'Dark Tree Line Water', None, ['Dark Tree Line WC', 'Dark Tree Line SC'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Palace of Darkness Nook Area', None, ['East Dark World Hint', 'East Dark World Teleporter', 'Eastern Nook Mirror Spot', 'Palace of Darkness Nook NE']), - create_dw_region(player, 'Misery Mire Area', None, ['Mire Shed', 'Misery Mire', 'Dark Desert Fairy', 'Dark Desert Hint', 'Desert Mirror Spot', 'Desert Ledge Mirror Spot', 'Checkerboard Mirror Spot', 'DP Stairs Mirror Spot', 'DP Entrance (North) Mirror Spot']), + create_dw_region(player, 'Palace of Darkness Nook Area', None, ['East Dark World Hint', 'East Dark World Teleporter', 'Palace of Darkness Nook NE']), + create_dw_region(player, 'Misery Mire Area', None, ['Mire Shed', 'Misery Mire', 'Dark Desert Fairy', 'Dark Desert Hint']), create_dw_region(player, 'Misery Mire Teleporter Ledge', None, ['Misery Mire Teleporter Ledge Drop', 'Misery Mire Teleporter']), create_dw_region(player, 'Mire Northeast Cliffs', None, ['Mire Cliff Ledge Drop', 'Dark Checkerboard Cliff Ledge Drop', 'Archery Game Cliff Ledge Drop', 'Stumpy Approach Cliff Ledge Drop', 'Mire C Whirlpool Cliff Ledge Drop', 'Swamp Nook Cliff Ledge Drop', 'Swamp Cliff Ledge Drop', 'Bombos Tablet Ledge Mirror Spot']), - create_dw_region(player, 'Stumpy Approach Area', None, ['Stumpy Approach Bush (South)', 'Cave 45 Mirror Spot', 'Stumpy Approach NW', 'Stumpy Approach EC']), - create_dw_region(player, 'Stumpy Approach Bush Entry', None, ['Stumpy Approach Bush (North)', 'Flute Boy Entry Mirror Spot', 'Stumpy Approach NC']), - create_dw_region(player, 'Dark C Whirlpool Area', None, ['Dark C Whirlpool Rock (Bottom)', 'Dark C Whirlpool Pegs (Right)', 'C Whirlpool Mirror Spot', 'Dark C Whirlpool Water Entry', 'Dark C Whirlpool EN', 'Dark C Whirlpool ES', 'Dark C Whirlpool SC']), + create_dw_region(player, 'Stumpy Approach Area', None, ['Stumpy Approach Bush (South)', 'Stumpy Approach NW', 'Stumpy Approach EC']), + create_dw_region(player, 'Stumpy Approach Bush Entry', None, ['Stumpy Approach Bush (North)', 'Stumpy Approach NC']), + create_dw_region(player, 'Dark C Whirlpool Area', None, ['Dark C Whirlpool Rock (Bottom)', 'Dark C Whirlpool Pegs (Right)', 'Dark C Whirlpool Water Entry', 'Dark C Whirlpool EN', 'Dark C Whirlpool ES', 'Dark C Whirlpool SC']), create_dw_region(player, 'Dark C Whirlpool Portal Area', None, ['Dark C Whirlpool Pegs (Left)', 'South Dark World Teleporter']), create_dw_region(player, 'Dark C Whirlpool Water', None, ['Dark C Whirlpool Landing', 'Dark C Whirlpool EC'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Dark C Whirlpool Outer Area', None, ['Dark C Whirlpool Rock (Top)', 'C Whirlpool Outer Mirror Spot', 'Dark C Whirlpool WC', 'Dark C Whirlpool NW']), - create_dw_region(player, 'Hype Cave Area', None, ['Hype Cave Water Entry', 'Hype Cave', 'Statues Mirror Spot', 'Hype Cave NC', 'Hype Cave WN', 'Hype Cave WS', 'Hype Cave SC']), + create_dw_region(player, 'Dark C Whirlpool Outer Area', None, ['Dark C Whirlpool Rock (Top)', 'Dark C Whirlpool WC', 'Dark C Whirlpool NW']), + create_dw_region(player, 'Hype Cave Area', None, ['Hype Cave Water Entry', 'Hype Cave', 'Hype Cave NC', 'Hype Cave WN', 'Hype Cave WS', 'Hype Cave SC']), create_dw_region(player, 'Hype Cave Water', None, ['Hype Cave Landing', 'Hype Cave WC'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Ice Lake Area', None, ['Ice Lake Water Drop', 'Dark Lake Hylia Shop', 'Lake Hylia Mirror Spot', 'Ice Lake NW']), - create_dw_region(player, 'Ice Lake Northeast Bank', None, ['Ice Lake Northeast Water Drop', 'Lake Hylia Northeast Mirror Spot', 'Ice Lake NE']), - create_dw_region(player, 'Ice Lake Ledge (West)', None, ['Ice Lake Southwest Water Drop', 'South Shore Mirror Spot', 'Ice Lake WS']), - create_dw_region(player, 'Ice Lake Ledge (East)', None, ['Ice Lake Southeast Water Drop', 'South Shore East Mirror Spot', 'Ice Lake ES']), - create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Ice Lake Moat Bomb Jump', 'Lake Hylia Island Mirror Spot', 'Ice Lake NC', 'Ice Lake EC'], 'Dark World', Terrain.Water), - create_dw_region(player, 'Ice Lake Moat', None, ['Ice Palace Teleporter', 'Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop', 'Lake Hylia Water Mirror Spot', 'Lake Hylia Water D Mirror Spot']), - create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace', 'Lake Hylia Central Island Mirror Spot']), - create_dw_region(player, 'Shopping Mall Area', None, ['Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Ice Cave Mirror Spot', 'Shopping Mall SW', 'Shopping Mall SE']), - create_dw_region(player, 'Swamp Nook Area', None, ['Desert Pass Ledge Mirror Spot', 'Desert Pass Mirror Spot', 'Swamp Nook EC', 'Swamp Nook ES']), - create_dw_region(player, 'Swamp Area', None, ['Swamp Palace', 'Dam Mirror Spot', 'Swamp WC', 'Swamp WS', 'Swamp NC', 'Swamp EC']), - create_dw_region(player, 'Dark South Pass Area', None, ['South Pass Mirror Spot', 'Dark South Pass WC', 'Dark South Pass NC', 'Dark South Pass ES']), - create_dw_region(player, 'Bomber Corner Area', None, ['Bomber Corner Water Drop', 'Octoballoon Mirror Spot', 'Bomber Corner WS', 'Bomber Corner NE']), + create_dw_region(player, 'Ice Lake Area', None, ['Ice Lake Water Drop', 'Dark Lake Hylia Shop', 'Ice Lake NW']), + create_dw_region(player, 'Ice Lake Northeast Bank', None, ['Ice Lake Northeast Water Drop', 'Ice Lake NE']), + create_dw_region(player, 'Ice Lake Ledge (West)', None, ['Ice Lake Southwest Water Drop', 'Ice Lake WS']), + create_dw_region(player, 'Ice Lake Ledge (East)', None, ['Ice Lake Southeast Water Drop', 'Ice Lake ES']), + create_dw_region(player, 'Ice Lake Water', None, ['Ice Lake Northeast Pier', 'Ice Lake Moat Bomb Jump', 'Ice Lake NC', 'Ice Lake EC'], 'Dark World', Terrain.Water), + create_dw_region(player, 'Ice Lake Moat', None, ['Ice Palace Teleporter', 'Ice Lake Moat Water Entry', 'Ice Lake Northeast Pier Hop']), + create_dw_region(player, 'Ice Palace Area', None, ['Ice Palace']), + create_dw_region(player, 'Shopping Mall Area', None, ['Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Spike Cave', 'Shopping Mall SW', 'Shopping Mall SE']), + create_dw_region(player, 'Swamp Nook Area', None, ['Swamp Nook EC', 'Swamp Nook ES']), + create_dw_region(player, 'Swamp Area', None, ['Swamp Palace', 'Swamp WC', 'Swamp WS', 'Swamp NC', 'Swamp EC']), + create_dw_region(player, 'Dark South Pass Area', None, ['Dark South Pass WC', 'Dark South Pass NC', 'Dark South Pass ES']), + create_dw_region(player, 'Bomber Corner Area', None, ['Bomber Corner Water Drop', 'Bomber Corner WS', 'Bomber Corner NE']), create_dw_region(player, 'Bomber Corner Water', None, ['Bomber Corner Pier', 'Bomber Corner Whirlpool', 'Bomber Corner WC'], 'Dark World', Terrain.Water), create_dw_region(player, 'Bomber Corner Water Ledge', None, ['Bomber Corner Waterfall Water Drop', 'Bomber Corner NW'], 'Dark World', Terrain.Water), diff --git a/Rules.py b/Rules.py index 7eb1353d..4be18a1a 100644 --- a/Rules.py +++ b/Rules.py @@ -983,169 +983,33 @@ def ow_inverted_rules(world, player): set_rule(world.get_entrance('GT Entry Approach', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) set_rule(world.get_entrance('GT Entry Leave', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player) or state.world.shuffle[player] in ('restricted', 'full', 'lite', 'lean', 'crossed', 'insanity')) - if not world.is_tile_swapped(0x00, player): - set_rule(world.get_entrance('Lost Woods East Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pedestal Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods East (Forgotten) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods West (Forgotten) Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Skull Woods Back Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Forgotten (West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Forgotten (East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Portal Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Forgotten (Middle) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Front Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x02, player): - set_rule(world.get_entrance('Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dark Lumberjack Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x03, player): - set_rule(world.get_entrance('West Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Spectacle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('West Dark Death Mountain (Top) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bubble Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('West Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) + if world.is_tile_swapped(0x03, player): set_rule(world.get_entrance('Spectacle Rock Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) set_rule(world.get_entrance('Spectacle Rock Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) if not world.is_tile_swapped(0x05, player): - set_rule(world.get_entrance('East Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Death Mountain (Top East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Mimic Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Spiral Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Fairy Ascension Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player)) # need to lift flowers - set_rule(world.get_entrance('Isolated Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Death Mountain Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('East Death Mountain Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) else: - set_rule(world.get_entrance('East Dark Death Mountain (Top West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Top East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('TR Ledge (West) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('TR Ledge (East) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('TR Isolated Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Bottom Plateau) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Bottom Left) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('East Dark Death Mountain (Bottom) Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Floating Island Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Dark Death Mountain Teleporter (East)', player), lambda state: state.can_lift_heavy_rocks(player)) if not world.is_tile_swapped(0x07, player): - set_rule(world.get_entrance('TR Pegs Area Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('TR Pegs Teleporter', player), lambda state: state.has('Hammer', player)) else: - set_rule(world.get_entrance('Turtle Rock Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Turtle Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Turtle Rock Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('TR Pegs Ledge Drop', player), lambda state: False) set_rule(world.get_entrance('TR Pegs Ledge Leave', player), lambda state: state.has('Hammer', player) and state.can_lift_heavy_rocks(player) and state.has_Pearl(player)) set_rule(world.get_entrance('Turtle Rock Tail Ledge Drop', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) - if not world.is_tile_swapped(0x0a, player): - set_rule(world.get_entrance('Mountain Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Mountain Entry Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Mountain Entry Entrance Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Bumper Cave Area Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bumper Cave Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bumper Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x0f, player): - set_rule(world.get_entrance('Zora Waterfall Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Catfish Mirror Spot', player), lambda state: state.has_Mirror(player)) - if not world.is_tile_swapped(0x10, player): - set_rule(world.get_entrance('Lost Woods Pass West Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pass Portal Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lost Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Kakariko Teleporter', player), lambda state: state.can_lift_rocks(player)) else: - set_rule(world.get_entrance('Skull Woods Pass West Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Pass East Top Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Pass Portal Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Skull Woods Pass East Bottom Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('West Dark World Teleporter', player), lambda state: state.can_lift_rocks(player)) - if not world.is_tile_swapped(0x11, player): - set_rule(world.get_entrance('Kakariko Fortune Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Outcast Fortune Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x12, player): - set_rule(world.get_entrance('Kakariko Pond Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Outcast Pond Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x13, player): - set_rule(world.get_entrance('Sanctuary Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bonk Rock Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dark Chapel Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Chapel Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x14, player): - set_rule(world.get_entrance('Graveyard Ledge Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) - set_rule(world.get_entrance('Kings Grave Mirror Spot', player), lambda state: state.has_Pearl(player) and state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Graveyard Ladder (Top)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) - set_rule(world.get_entrance('Graveyard Ladder (Bottom)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches'] and state.has_Pearl(player)) - set_rule(world.get_entrance('Dark Graveyard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Graveyard Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Graveyard Grave Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x15, player): - set_rule(world.get_entrance('River Bend Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('River Bend East Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Qirn Jump Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Qirn Jump East Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x16, player): - set_rule(world.get_entrance('Potion Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Potion Shop Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dark Witch Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Witch Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x17, player): - set_rule(world.get_entrance('Zora Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Zora Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Catfish Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Catfish Approach Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x18, player): - set_rule(world.get_entrance('Kakariko Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Grass Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Village of Outcasts Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Village of Outcasts Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer House Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x1a, player): - set_rule(world.get_entrance('Forgotton Forest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Forgotton Forest Fence Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Shield Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) - if not world.is_tile_swapped(0x1b, player): set_rule(world.get_entrance('Inverted Pyramid Hole', player), lambda state: False) set_rule(world.get_entrance('Inverted Pyramid Entrance', player), lambda state: False) set_rule(world.get_entrance('Pyramid Hole', player), lambda state: world.is_pyramid_open(player) or state.has('Beat Agahnim 2', player)) - set_rule(world.get_entrance('HC Area Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC East Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Courtyard Left Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('HC Area South Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Hyrule Castle Main Gate (South)', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Hyrule Castle Main Gate (North)', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has_beaten_aga(player)) @@ -1155,182 +1019,39 @@ def ow_inverted_rules(world, player): set_rule(world.get_entrance('Pyramid Hole', player), lambda state: False) set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False) - set_rule(world.get_entrance('Pyramid Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Uncle Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid From Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Pyramid Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Post Aga Inverted Teleporter', player), lambda state: state.has_beaten_aga(player)) - if not world.is_tile_swapped(0x1d, player): - set_rule(world.get_entrance('Wooden Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Wooden Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Wooden Bridge West Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Broken Bridge West Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Broken Bridge East Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Broken Bridge Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x1e, player): - set_rule(world.get_entrance('Eastern Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Palace of Darkness Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x22, player): - set_rule(world.get_entrance('Blacksmith Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Blacksmith Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Bat Cave Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Hammer Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer Pegs Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x25, player): - set_rule(world.get_entrance('Sand Dunes Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dark Dunes Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x28, player): - set_rule(world.get_entrance('Maze Race Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Maze Race Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dig Game Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dig Game Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x29, player): - set_rule(world.get_entrance('Kakariko Suburb Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Kakariko Suburb South Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Frog Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Frog Prison Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Archery Game Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x2a, player): - set_rule(world.get_entrance('Flute Boy Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Flute Boy Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Stumpy Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stumpy Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x2b, player): - set_rule(world.get_entrance('Central Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dark Bonk Rocks Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x2c, player): - set_rule(world.get_entrance('Links House Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Big Bomb Shop Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x2d, player): - set_rule(world.get_entrance('Stone Bridge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stone Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) - else: - set_rule(world.get_entrance('Hammer Bridge North Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Hammer Bridge South Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark Hobo Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) - - if not world.is_tile_swapped(0x2e, player): - set_rule(world.get_entrance('Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dark Tree Line Mirror Spot', player), lambda state: state.has_Mirror(player)) - if not world.is_tile_swapped(0x2f, player): - set_rule(world.get_entrance('Eastern Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('East Hyrule Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) # bunny cannot use hammer else: - set_rule(world.get_entrance('Darkness Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) if not world.is_tile_swapped(0x30, player): - set_rule(world.get_entrance('Checkerboard Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('DP Stairs Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('DP Entrance (North) Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Bombos Tablet Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Desert Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) else: - set_rule(world.get_entrance('Misery Mire Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Misery Mire Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Misery Mire Blocked Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Misery Mire Main Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('Checkerboard Ledge Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) set_rule(world.get_entrance('Checkerboard Ledge Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) - if not world.is_tile_swapped(0x32, player): - set_rule(world.get_entrance('Cave 45 Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Flute Boy Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Stumpy Approach Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Stumpy Bush Entry Mirror Spot', player), lambda state: state.has_Mirror(player)) + if world.is_tile_swapped(0x32, player): set_rule(world.get_entrance('Cave 45 Inverted Approach', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) set_rule(world.get_entrance('Cave 45 Inverted Leave', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) if not world.is_tile_swapped(0x33, player): - set_rule(world.get_entrance('C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('C Whirlpool Outer Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('South Hyrule Teleporter', player), lambda state: state.can_lift_rocks(player)) else: - set_rule(world.get_entrance('Dark C Whirlpool Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Dark C Whirlpool Outer Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('South Dark World Teleporter', player), lambda state: state.can_lift_rocks(player)) - if not world.is_tile_swapped(0x34, player): - set_rule(world.get_entrance('Statues Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Hype Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - if not world.is_tile_swapped(0x35, player): - set_rule(world.get_entrance('Lake Hylia Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Island Mirror Spot', player), lambda state: state.has_Mirror(player) and state.has_Pearl(player) and state.has('Flippers', player)) - set_rule(world.get_entrance('Lake Hylia Central Island Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Water Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Lake Hylia Water D Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('South Shore Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('South Shore East Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Lake Hylia Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) else: - set_rule(world.get_entrance('Ice Lake Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Lake Southwest Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Lake Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Lake Northeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Ice Palace Mirror Spot', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Ice Palace Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) set_rule(world.get_entrance('Lake Hylia Island Pier', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) - if not world.is_tile_swapped(0x37, player): - set_rule(world.get_entrance('Ice Cave Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Shopping Mall Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x3a, player): - set_rule(world.get_entrance('Desert Pass Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Desert Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Swamp Nook Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Swamp Nook Southeast Mirror Spot', player), lambda state: state.has_Mirror(player)) - set_rule(world.get_entrance('Swamp Nook Pegs Mirror Spot', player), lambda state: state.has_Mirror(player)) + if world.is_tile_swapped(0x3a, player): set_rule(world.get_entrance('Desert Pass Ladder (South)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) set_rule(world.get_entrance('Desert Pass Ladder (North)', player), lambda state: world.logic[player] in ['noglitches', 'minorglitches']) - - if not world.is_tile_swapped(0x3b, player): - set_rule(world.get_entrance('Dam Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Swamp Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x3c, player): - set_rule(world.get_entrance('South Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Dark South Pass Mirror Spot', player), lambda state: state.has_Mirror(player)) - - if not world.is_tile_swapped(0x3f, player): - set_rule(world.get_entrance('Octoballoon Mirror Spot', player), lambda state: state.has_Mirror(player)) - else: - set_rule(world.get_entrance('Bomber Corner Mirror Spot', player), lambda state: state.has_Mirror(player)) def ow_bunny_rules(world, player): diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index b9bea9cd..8085b17b 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -1876,7 +1876,6 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Zora Waterfall Water Drop', 'Light World'), ('Kings Grave Outer Rocks', 'Kings Grave Area'), ('Kings Grave Inner Rocks', 'Light World'), - ('Kings Grave Mirror Spot', 'Kings Grave Area'), ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), ('Kakariko Well (top to back)', 'Kakariko Well (back)'), ('Master Sword Meadow', 'Master Sword Meadow'), @@ -1922,9 +1921,6 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Dark Lake Hylia Ledge', 'Dark Lake Hylia Ledge'), ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), ('East Dark World Pier', 'East Dark World'), - ('Lake Hylia Island Mirror Spot', 'Lake Hylia Island'), - ('Lake Hylia Central Island Mirror Spot', 'Lake Hylia Central Island'), - ('Hyrule Castle Ledge Mirror Spot', 'Hyrule Castle Ledge'), ('South Dark World Bridge', 'South Dark World'), ('East Dark World Bridge', 'East Dark World'), ('Maze Race Mirror Spot', 'Maze Race Ledge'), @@ -1934,7 +1930,6 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), ('Peg Area Rocks', 'West Dark World'), ('Grassy Lawn Pegs', 'West Dark World'), - ('Bat Cave Drop Ledge Mirror Spot', 'Bat Cave Drop Ledge'), ('East Dark World River Pier', 'East Dark World'), ('West Dark World Gap', 'West Dark World'), ('East Dark World Broken Bridge Pass', 'East Dark World'), @@ -1943,17 +1938,11 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), ('Bumper Cave Entrance Drop', 'West Dark World'), - ('Bumper Cave Entrance Mirror Spot', 'Death Mountain Entrance'), ('Bumper Cave Ledge Drop', 'West Dark World'), - ('Bumper Cave Ledge Mirror Spot', 'Death Mountain Return Ledge'), ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), ('Skull Woods Forest', 'Skull Woods Forest'), - ('Desert Ledge Mirror Spot', 'Desert Ledge'), - ('Desert Ledge (Northeast) Mirror Spot', 'Desert Ledge (Northeast)'), - ('Desert Palace Entrance (North) Mirror Spot', 'Desert Palace Entrance (North) Spot'), ('Dark Desert Teleporter', 'Dark Desert'), - ('Desert Palace Stairs Mirror Spot', 'Desert Palace Stairs'), ('East Hyrule Teleporter', 'East Dark World'), ('South Hyrule Teleporter', 'South Dark World'), ('Kakariko Teleporter', 'West Dark World'), @@ -1965,17 +1954,14 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Paradox Cave Drop', 'Paradox Cave Chest Area'), ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Mirror Spot', 'Fairy Ascension Plateau'), ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Spectacle Rock Mirror Spot', 'Spectacle Rock'), ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), - ('East Death Mountain (Top) Mirror Spot', 'East Death Mountain (Top)'), ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), @@ -1986,14 +1972,8 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), ('Floating Island Drop', 'Dark Death Mountain (Top)'), - ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Light World)'), ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), - ('Isolated Ledge Mirror Spot', 'Fairy Ascension Ledge'), - ('Spiral Cave Mirror Spot', 'Spiral Cave Ledge'), - ('Mimic Cave Mirror Spot', 'Mimic Cave Ledge'), - ('Cave 45 Mirror Spot', 'Cave 45 Ledge'), ('Bombos Tablet Mirror Spot', 'Bombos Tablet Ledge'), - ('Graveyard Ledge Mirror Spot', 'Graveyard Ledge'), ('Ganon Drop', 'Bottom of Pyramid'), ('Pyramid Drop', 'East Dark World'), ('Maze Race Ledge Drop', 'Light World'), @@ -2105,7 +2085,6 @@ inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), ('Potion Shop River Drop', 'River'), ('Graveyard Cave Inner Bushes', 'Light World'), ('Graveyard Cave Outer Bushes', 'Graveyard Cave Area'), - ('Graveyard Cave Mirror Spot', 'West Dark World'), ('Light World River Drop', 'River'), ('Light World Pier', 'Light World'), ('Potion Shop Pier', 'Potion Shop Area'), @@ -2131,30 +2110,7 @@ inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), ('Dark Death Mountain Teleporter (West)', 'Death Mountain'), ('Dark Death Mountain Teleporter (East)', 'East Death Mountain (Top)'), ('Dark Death Mountain Teleporter (East Bottom)', 'East Death Mountain (Bottom)'), - ('Mire Mirror Spot', 'Dark Desert'), ('Dark Desert Drop', 'Dark Desert'), - ('Desert Palace Stairs Mirror Spot', 'Dark Desert'), - ('Desert Palace North Mirror Spot', 'Dark Desert'), - ('Maze Race Mirror Spot', 'West Dark World'), - ('Lake Hylia Central Island Mirror Spot', 'Dark Lake Hylia Central Island'), - ('Hammer Peg Area Mirror Spot', 'Hammer Peg Area'), - ('Bumper Cave Ledge Mirror Spot', 'Bumper Cave Ledge'), - ('Bumper Cave Entrance Mirror Spot', 'Bumper Cave Entrance'), - ('Death Mountain Mirror Spot', 'Dark Death Mountain'), - ('East Death Mountain Mirror Spot (Top)', 'Dark Death Mountain'), - ('East Death Mountain Mirror Spot (Bottom)', 'Dark Death Mountain (East Bottom)'), - ('Death Mountain (Top) Mirror Spot', 'Dark Death Mountain'), - ('Dark Death Mountain Ledge Mirror Spot (East)', 'Dark Death Mountain Ledge'), - ('Dark Death Mountain Ledge Mirror Spot (West)', 'Dark Death Mountain Ledge'), - ('Floating Island Mirror Spot', 'Death Mountain Floating Island (Dark World)'), - ('Laser Bridge Mirror Spot', 'Dark Death Mountain Isolated Ledge'), - ('East Dark World Mirror Spot', 'East Dark World'), - ('West Dark World Mirror Spot', 'West Dark World'), - ('South Dark World Mirror Spot', 'South Dark World'), - ('Potion Shop Mirror Spot', 'Northeast Dark World'), - ('Catfish Mirror Spot', 'Catfish'), - ('Shopping Mall Mirror Spot', 'Dark Lake Hylia Ledge'), - ('Skull Woods Mirror Spot', 'Skull Woods Forest (West)'), ('DDM Flute', 'The Sky'), ('DDM Landing', 'Dark Death Mountain'), ('NEDW Flute', 'The Sky'), @@ -2174,10 +2130,8 @@ inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), ('Hammer Peg Area Flute', 'The Sky'), ('Bush Covered Lawn Inner Bushes', 'Light World'), ('Bush Covered Lawn Outer Bushes', 'Bush Covered Lawn'), - ('Bush Covered Lawn Mirror Spot', 'Dark Grassy Lawn'), ('Bomb Hut Inner Bushes', 'Light World'), ('Bomb Hut Outer Bushes', 'Bomb Hut Area'), - ('Bomb Hut Mirror Spot', 'West Dark World'), ('Maze Race Ledge Drop', 'Light World')] # non-shuffled entrance links From f6744f93b48e895e6b3873ed1c2f1ebd11e8c387 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 26 Dec 2022 05:21:59 -0600 Subject: [PATCH 080/146] Modeled 'Mirror To Fairy Ascension' correctly --- OWEdges.py | 1 + OverworldShuffle.py | 3 ++- Regions.py | 3 ++- Rules.py | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 01b2ad69..d3e1f8ac 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1655,6 +1655,7 @@ OWExitTypes = { 'Skull Woods Forgotten Bush (East)', 'GT Entry Approach', 'GT Entry Leave', + 'East Dark Death Mountain Bushes', 'Bumper Cave Entrance Rock', 'Skull Woods Pass Bush Row (West)', 'Skull Woods Pass Bush Row (East)', diff --git a/OverworldShuffle.py b/OverworldShuffle.py index edee4b88..e5c5cb93 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1293,6 +1293,7 @@ mandatory_connections = [# Intra-tile OW Connections ('GT Entry Leave', 'West Dark Death Mountain (Top)'), ('Floating Island Drop', 'East Dark Death Mountain (Top)'), ('Dark Death Mountain Drop (East)', 'East Dark Death Mountain (Bottom)'), + ('East Dark Death Mountain Bushes', 'East Dark Death Mountain (Bushes)'), ('Turtle Rock Ledge Drop', 'Turtle Rock Area'), ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), #glove ('Bumper Cave Ledge Drop', 'Bumper Cave Area'), @@ -1588,7 +1589,7 @@ mirror_connections = { 'East Dark Death Mountain (Top)': ['East Death Mountain (Top West)', 'East Death Mountain (Top East)'], 'Dark Death Mountain Ledge': ['Spiral Cave Ledge', 'Mimic Cave Ledge'], 'Dark Death Mountain Isolated Ledge': ['Fairy Ascension Ledge'], - 'East Dark Death Mountain (Bottom)': ['Fairy Ascension Plateau'], + 'East Dark Death Mountain (Bushes)': ['Fairy Ascension Plateau'], 'East Dark Death Mountain (Bottom Left)': ['East Death Mountain (Bottom Left)'], 'Turtle Rock Area': ['Death Mountain TR Pegs'], diff --git a/Regions.py b/Regions.py index d8dfd7eb..9bc2f5e4 100644 --- a/Regions.py +++ b/Regions.py @@ -140,7 +140,8 @@ def create_regions(world, player): create_dw_region(player, 'GT Approach', None, ['GT Entry Leave', 'Ganons Tower']), create_dw_region(player, 'West Dark Death Mountain (Bottom)', None, ['Spike Cave', 'Dark Death Mountain Fairy', 'Dark Death Mountain Teleporter (West)', 'West Dark Death Mountain ES']), create_dw_region(player, 'East Dark Death Mountain (Top)', None, ['Dark Death Mountain Drop (East)', 'Superbunny Cave (Top)', 'Hookshot Cave', 'East Dark Death Mountain WN', 'East Dark Death Mountain EN']), - create_dw_region(player, 'East Dark Death Mountain (Bottom)', None, ['Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East)']), + create_dw_region(player, 'East Dark Death Mountain (Bottom)', None, ['East Dark Death Mountain Bushes', 'Superbunny Cave (Bottom)', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Teleporter (East)']), + create_dw_region(player, 'East Dark Death Mountain (Bushes)', None, []), create_dw_region(player, 'East Dark Death Mountain (Bottom Left)', None, ['East Dark Death Mountain WS']), create_dw_region(player, 'Dark Death Mountain Ledge', None, ['Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)'], 'a dark ledge'), create_dw_region(player, 'Dark Death Mountain Isolated Ledge', None, ['Turtle Rock Isolated Ledge Entrance'], 'a dark vista'), diff --git a/Rules.py b/Rules.py index 4be18a1a..c3ac5308 100644 --- a/Rules.py +++ b/Rules.py @@ -1138,6 +1138,7 @@ def ow_bunny_rules(world, player): add_bunny_rule(world.get_entrance('Skull Woods Forgotten Bush (West)', player), player) add_bunny_rule(world.get_entrance('Skull Woods Forgotten Bush (East)', player), player) add_bunny_rule(world.get_entrance('Skull Woods Second Section Hole', player), player) + add_bunny_rule(world.get_entrance('East Dark Death Mountain Bushes', player), player) add_bunny_rule(world.get_entrance('Bumper Cave Entrance Rock', player), player) add_bunny_rule(world.get_entrance('Skull Woods Pass Bush Row (West)', player), player) add_bunny_rule(world.get_entrance('Skull Woods Pass Bush Row (East)', player), player) From a4a2993f99786c10147fe781121830c84b666c45 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 26 Dec 2022 05:22:36 -0600 Subject: [PATCH 081/146] Fixed flute exits to work correctly in Inverted --- OverworldShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index e5c5cb93..55b52a88 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -829,7 +829,7 @@ def adjust_edge_groups(world, trimmed_groups, edges_to_swap, player): def create_flute_exits(world, player): for region in (r for r in world.regions if r.player == player and r.terrain == Terrain.Land and r.name not in ['Zoras Domain', 'Master Sword Meadow', 'Hobo Bridge']): - if region.type == (RegionType.LightWorld if world.mode != 'inverted' else RegionType.DarkWorld): + if region.type == (RegionType.LightWorld if world.mode[player] != 'inverted' else RegionType.DarkWorld): exitname = 'Flute From ' + region.name exit = Entrance(region.player, exitname, region) exit.spot_type = 'Flute' From 32bbb431b40ddebed0e61752674da8d4f07e34f8 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 26 Dec 2022 05:23:36 -0600 Subject: [PATCH 082/146] Small formatting change for settings code --- BaseClasses.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index fdf6bf54..9a66a3d7 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -3451,9 +3451,11 @@ class Settings(object): settings_version, - (or_mode[w.owShuffle[p]] << 5) | (0x10 if w.owTerrain[p] else 0) | (0x08 if w.owWhirlpoolShuffle[p] else 0) | orcrossed_mode[w.owCrossed[p]], + (or_mode[w.owShuffle[p]] << 5) | (0x10 if w.owTerrain[p] else 0) + | (0x08 if w.owWhirlpoolShuffle[p] else 0) | orcrossed_mode[w.owCrossed[p]], - (0x80 if w.owKeepSimilar[p] else 0) | (0x40 if w.owMixed[p] else 0) | (0x20 if w.shuffle_bonk_drops[p] else 0) | (flutespot_mode[w.owFluteShuffle[p]] << 4), + (0x80 if w.owKeepSimilar[p] else 0) | (0x40 if w.owMixed[p] else 0) + | (0x20 if w.shuffle_bonk_drops[p] else 0) | (flutespot_mode[w.owFluteShuffle[p]] << 4), (flute_mode[w.flute_mode[p]] << 7 | bow_mode[w.bow_mode[p]] << 4 | take_any_mode[w.take_any[p]] << 2 | keyshuffle_mode[w.keyshuffle[p]]) From ca28a9654f3a6c00e831a2b82c960c07ab1d3568 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 26 Dec 2022 06:21:45 -0600 Subject: [PATCH 083/146] Renaming Bombos Tablet Ledge Mirror Spot to match new naming convention --- OWEdges.py | 2 +- OverworldShuffle.py | 2 +- Regions.py | 2 +- Rules.py | 2 +- source/overworld/EntranceShuffle2.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index d3e1f8ac..9db72771 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1734,7 +1734,7 @@ OWExitTypes = { 'Qirn Jump Whirlpool', 'Bomber Corner Whirlpool' ], - 'Mirror': ['Bombos Tablet Ledge Mirror Spot' + 'Mirror': ['Mirror To Bombos Tablet Ledge' ] } diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 55b52a88..4582d863 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1489,7 +1489,7 @@ ow_connections = { ('East Dark World Teleporter', 'Eastern Nook Area') ]), 0x30: ([ - ('Bombos Tablet Ledge Mirror Spot', 'Bombos Tablet Ledge'), # OWG + ('Mirror To Bombos Tablet Ledge', 'Bombos Tablet Ledge'), # OWG ('Desert Teleporter', 'Misery Mire Teleporter Ledge'), ('Desert Boss Cliff Ledge Drop', 'Desert Palace Entrance (North) Spot'), # OWG ('Mire Cliff Ledge Drop', 'Misery Mire Area'), # OWG diff --git a/Regions.py b/Regions.py index 9bc2f5e4..261b0113 100644 --- a/Regions.py +++ b/Regions.py @@ -207,7 +207,7 @@ def create_regions(world, player): create_dw_region(player, 'Palace of Darkness Nook Area', None, ['East Dark World Hint', 'East Dark World Teleporter', 'Palace of Darkness Nook NE']), create_dw_region(player, 'Misery Mire Area', None, ['Mire Shed', 'Misery Mire', 'Dark Desert Fairy', 'Dark Desert Hint']), create_dw_region(player, 'Misery Mire Teleporter Ledge', None, ['Misery Mire Teleporter Ledge Drop', 'Misery Mire Teleporter']), - create_dw_region(player, 'Mire Northeast Cliffs', None, ['Mire Cliff Ledge Drop', 'Dark Checkerboard Cliff Ledge Drop', 'Archery Game Cliff Ledge Drop', 'Stumpy Approach Cliff Ledge Drop', 'Mire C Whirlpool Cliff Ledge Drop', 'Swamp Nook Cliff Ledge Drop', 'Swamp Cliff Ledge Drop', 'Bombos Tablet Ledge Mirror Spot']), + create_dw_region(player, 'Mire Northeast Cliffs', None, ['Mire Cliff Ledge Drop', 'Dark Checkerboard Cliff Ledge Drop', 'Archery Game Cliff Ledge Drop', 'Stumpy Approach Cliff Ledge Drop', 'Mire C Whirlpool Cliff Ledge Drop', 'Swamp Nook Cliff Ledge Drop', 'Swamp Cliff Ledge Drop', 'Mirror To Bombos Tablet Ledge']), create_dw_region(player, 'Stumpy Approach Area', None, ['Stumpy Approach Bush (South)', 'Stumpy Approach NW', 'Stumpy Approach EC']), create_dw_region(player, 'Stumpy Approach Bush Entry', None, ['Stumpy Approach Bush (North)', 'Stumpy Approach NC']), create_dw_region(player, 'Dark C Whirlpool Area', None, ['Dark C Whirlpool Rock (Bottom)', 'Dark C Whirlpool Pegs (Right)', 'Dark C Whirlpool Water Entry', 'Dark C Whirlpool EN', 'Dark C Whirlpool ES', 'Dark C Whirlpool SC']), diff --git a/Rules.py b/Rules.py index c3ac5308..69b7fed2 100644 --- a/Rules.py +++ b/Rules.py @@ -1027,7 +1027,7 @@ def ow_inverted_rules(world, player): set_rule(world.get_entrance('East Dark World Teleporter', player), lambda state: state.has('Hammer', player) and state.can_lift_rocks(player) and state.has_Pearl(player)) if not world.is_tile_swapped(0x30, player): - set_rule(world.get_entrance('Bombos Tablet Ledge Mirror Spot', player), lambda state: state.has_Mirror(player)) + set_rule(world.get_entrance('Mirror To Bombos Tablet Ledge', player), lambda state: state.has_Mirror(player)) set_rule(world.get_entrance('Desert Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) else: set_rule(world.get_entrance('Misery Mire Teleporter', player), lambda state: state.can_lift_heavy_rocks(player)) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 8085b17b..1be0c5a4 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -1973,7 +1973,7 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), ('Floating Island Drop', 'Dark Death Mountain (Top)'), ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), - ('Bombos Tablet Mirror Spot', 'Bombos Tablet Ledge'), + ('Mirror To Bombos Tablet Ledge', 'Bombos Tablet Ledge'), ('Ganon Drop', 'Bottom of Pyramid'), ('Pyramid Drop', 'East Dark World'), ('Maze Race Ledge Drop', 'Light World'), From 3cb90d822194835667a30dd8b2866bd2094f534c Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 26 Dec 2022 13:09:23 -0600 Subject: [PATCH 084/146] Combining dynamic exits into one call --- Main.py | 14 ++++---------- OverworldShuffle.py | 5 +++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Main.py b/Main.py index 03c78887..73502cf4 100644 --- a/Main.py +++ b/Main.py @@ -16,7 +16,7 @@ from OverworldGlitchRules import create_owg_connections from PotShuffle import shuffle_pots, shuffle_pot_switches from Regions import create_regions, create_shops, mark_light_dark_world_regions, create_dungeon_regions, adjust_locations from OWEdges import create_owedges -from OverworldShuffle import link_overworld, update_world_regions, create_flute_exits, create_mirror_exits +from OverworldShuffle import link_overworld, update_world_regions, create_dynamic_exits from EntranceShuffle import link_entrances from Rom import patch_rom, patch_race_rom, patch_enemizer, apply_rom_settings, LocalRom, JsonRom, get_hash_string from Doors import create_doors @@ -231,9 +231,7 @@ def main(args, seed=None, fish=None): create_shops(world, player) update_world_regions(world, player) mark_light_dark_world_regions(world, player) - create_flute_exits(world, player) - create_mirror_exits(world, player) - world.initialize_regions() + create_dynamic_exits(world, player) logger.info(world.fish.translate("cli","cli","shuffling.world")) @@ -523,15 +521,13 @@ def copy_world(world): update_world_regions(ret, player) if world.logic[player] in ('owglitches', 'nologic'): create_owg_connections(ret, player) - create_flute_exits(ret, player) - create_mirror_exits(ret, player) + create_dynamic_exits(ret, player) create_dungeon_regions(ret, player) create_owedges(ret, player) create_shops(ret, player) #create_doors(ret, player) create_rooms(ret, player) create_dungeons(ret, player) - world.initialize_regions() # there are region references here they must be migrated to preserve integrity # ret.exp_cache = world.exp_cache.copy() @@ -702,9 +698,7 @@ def copy_world_premature(world, player): update_world_regions(ret, player) if world.logic[player] in ('owglitches', 'nologic'): create_owg_connections(ret, player) - create_flute_exits(ret, player) - create_mirror_exits(ret, player) - world.initialize_regions() + create_dynamic_exits(ret, player) create_dungeon_regions(ret, player) create_owedges(ret, player) create_shops(ret, player) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 4582d863..d61e82bf 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -864,6 +864,11 @@ def create_mirror_exits(world, player): elif region.terrain == Terrain.Land: logging.getLogger('').debug(f'Region has no mirror exit: {region.name}') +def create_dynamic_exits(world, player): + create_flute_exits(world, player) + create_mirror_exits(world, player) + world.initialize_regions() + def categorize_world_regions(world, player): for type in OWExitTypes: for exitname in OWExitTypes[type]: From 6351ea634b2066dd740333403a62763c9d72c71f Mon Sep 17 00:00:00 2001 From: codemann8 Date: Tue, 27 Dec 2022 06:33:25 -0600 Subject: [PATCH 085/146] Fixed follower logic to use new dynamic mirror connections --- BaseClasses.py | 75 +++++++++++++++++++++------------------------ OverworldShuffle.py | 36 +++++++++++++++++----- 2 files changed, 64 insertions(+), 47 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 9a66a3d7..3e83b69f 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1562,7 +1562,7 @@ class Entrance(object): def can_reach(self, state): # Destination Pickup OW Only No Ledges Can S&Q Allow Mirror - multi_step_locations = { 'Pyramid Area': ('Big Bomb', True, True, False, True), + multi_step_locations = { 'Pyramid Crack': ('Big Bomb', True, True, False, True), 'Missing Smith': ('Frog', True, False, True, True), 'Middle Aged Man': ('Dark Blacksmith Ruins', True, False, True, True), 'Old Man Drop Off': ('Lost Old Man', True, False, False, False), @@ -1581,7 +1581,13 @@ class Entrance(object): while len(self.temp_path): exit = self.temp_path.pop(0) path = (exit.name, (exit.parent_region.name, path)) - item_name = self.connected_region.locations[0].item.name if self.connected_region.locations[0].item else 'Deliver Item' + item_name = 'Deliver Item' + if len(self.connected_region.locations) > 0 and self.connected_region.locations[0].item: + item_name = self.connected_region.locations[0].item.name + for loc in self.parent_region.locations: + if loc.event and not loc.real and loc.item.name.find('Farmable') < 0: + item_name = loc.item.name + break path = (item_name, (self.parent_region.name, path)) state.path[self] = (self.name, path) return True @@ -1626,45 +1632,39 @@ class Entrance(object): exits_to_traverse = list() found = False - if not found and allow_mirror_reentry and state.has('Magic Mirror', self.player): + if not found and allow_mirror_reentry and state.has_Mirror(self.player): # check for path using mirror portal re-entry at location of the follower pickup # this is checked first as this often the shortest path follower_region = start_region if follower_region.type not in [RegionType.LightWorld, RegionType.DarkWorld]: follower_region = [i for i in start_region.entrances if i.parent_region.name != 'Menu'][0].parent_region if (follower_region.world.mode[self.player] != 'inverted') == (follower_region.type == RegionType.LightWorld): - from OWEdges import OWTileRegions - from OverworldShuffle import ow_connections - owid = OWTileRegions[follower_region.name] - (mirror_map_orig, other_world) = ow_connections[owid % 0x40] - mirror_map = list(mirror_map_orig).copy() - mirror_map.extend(other_world) - mirror_exit = None - while len(mirror_map): + from OverworldShuffle import get_mirror_edges + mirror_map = get_mirror_edges(follower_region.world, follower_region, self.player) + while len(mirror_map) and not found: if mirror_map[0][1] == follower_region.name: mirror_exit = mirror_map[0][0] - break + mirror_region = follower_region.world.get_entrance(mirror_exit, self.player).parent_region + if mirror_exit and mirror_region: + if mirror_region.can_reach(state): + traverse_paths(mirror_region, self.parent_region) + break # no need to continue if there is no path from the mirror re-entry to dest mirror_map.pop(0) - if mirror_exit: - mirror_region = follower_region.world.get_entrance(mirror_exit, self.player).parent_region - if mirror_region.can_reach(state): - traverse_paths(mirror_region, self.parent_region) - if found: - path = state.path.get(mirror_region, (mirror_region.name, None)) - path = (follower_region.name, (mirror_exit, path)) - item_name = step_location.item.name if step_location.item else 'Pick Up Item' - if start_region.name != follower_region.name: - path = (start_region.name, (start_region.entrances[0].name, path)) - path = (f'{step_location.parent_region.name} Exit', ('Leave Item Area', (item_name, path))) - else: - path = (item_name, path) - path = ('Use Mirror Portal', (follower_region.name, path)) - while len(self.temp_path): - exit = self.temp_path.pop(0) - path = (exit.name, (exit.parent_region.name, path)) - item_name = self.connected_region.locations[0].item.name if self.connected_region.locations[0].item else 'Deliver Item' - path = (self.parent_region.name, path) - state.path[self] = (self.name, path) + if found: + path = state.path.get(mirror_region, (mirror_region.name, None)) + path = (follower_region.name, (mirror_exit, path)) + item_name = step_location.item.name if step_location.item else 'Pick Up Item' + if start_region.name != follower_region.name: + path = (start_region.name, (start_region.entrances[0].name, path)) + path = (f'{step_location.parent_region.name} Exit', ('Leave Item Area', (item_name, path))) + else: + path = (item_name, path) + path = ('Use Mirror Portal', (follower_region.name, path)) + while len(self.temp_path): + exit = self.temp_path.pop(0) + path = (exit.name, (exit.parent_region.name, path)) + path = (self.parent_region.name, path) + state.path[self] = (self.name, path) if not found: # check normal paths @@ -1675,7 +1675,7 @@ class Entrance(object): exit = self.parent_region.world.get_entrance('Links House S&Q', self.player) traverse_paths(exit.connected_region, self.parent_region, [exit]) - if not found and allow_mirror_reentry and state.has('Magic Mirror', self.player): + if not found and allow_mirror_reentry and state.has_Mirror(self.player): # check for paths using mirror portal re-entry at location of final destination # this is checked last as this is the most complicated/exhaustive check follower_region = start_region @@ -1686,14 +1686,9 @@ class Entrance(object): if dest_region.type not in [RegionType.LightWorld, RegionType.DarkWorld]: dest_region = start_region.entrances[0].parent_region if (dest_region.world.mode[self.player] != 'inverted') != (dest_region.type == RegionType.LightWorld): - from OWEdges import OWTileRegions - from OverworldShuffle import ow_connections - owid = OWTileRegions[dest_region.name] - (mirror_map_orig, other_world) = ow_connections.copy()[owid % 0x40] - mirror_map = list(mirror_map_orig).copy() - mirror_map.extend(other_world) - mirror_map = [(x, d) for (x, d) in mirror_map if x in [e.name for e in dest_region.exits]] # loop thru potential places to leave a mirror portal + from OverworldShuffle import get_mirror_edges + mirror_map = get_mirror_edges(dest_region.world, dest_region, self.player) while len(mirror_map) and not found: mirror_exit = dest_region.world.get_entrance(mirror_map[0][0], self.player) if mirror_exit.connected_region.type != dest_region.type: diff --git a/OverworldShuffle.py b/OverworldShuffle.py index d61e82bf..4def7446 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -837,22 +837,44 @@ def create_flute_exits(world, player): exit.connect(world.get_region('Flute Sky', player)) region.exits.append(exit) +def get_mirror_exit_name(from_region, to_region): + if from_region in mirror_connections and to_region in mirror_connections[from_region]: + if len(mirror_connections[from_region]) == 1: + return f'Mirror From {from_region}' + else: + return f'Mirror To {to_region}' + return None + +def get_mirror_edges(world, region, player): + mirror_exits = list() + if (world.mode[player] != 'inverted') == (region.type == RegionType.DarkWorld): + # get mirror edges leaving the region + if region.name in mirror_connections: + for dest_region_name in mirror_connections[region.name]: + mirror_exits.append(tuple([get_mirror_exit_name(region.name, dest_region_name), dest_region_name])) + else: + # get mirror edges leading into the region + owid = OWTileRegions[region.name] + for other_world_region_name in OWTileRegions.inverse[(owid + 0x40) % 0x80]: + if other_world_region_name in mirror_connections: + for dest_region_name in mirror_connections[other_world_region_name]: + if dest_region_name == region.name: + mirror_exits.append(tuple([get_mirror_exit_name(other_world_region_name, region.name), region.name])) + return mirror_exits + def create_mirror_exits(world, player): mirror_exits = set() for region in (r for r in world.regions if r.player == player and r.name not in ['Zoras Domain', 'Master Sword Meadow', 'Hobo Bridge']): if region.type == (RegionType.DarkWorld if world.mode[player] != 'inverted' else RegionType.LightWorld): if region.name in mirror_connections: for region_dest_name in mirror_connections[region.name]: - to_region = world.get_region(region_dest_name, player) - if len(mirror_connections[region.name]) == 1: - exitname = 'Mirror From ' + region.name - else: - exitname = 'Mirror To ' + region_dest_name + exitname = get_mirror_exit_name(region.name, region_dest_name) - assert(exitname not in mirror_exits, f'Mirror Exit with name already exists: {exitname}') + assert exitname not in mirror_exits, f'Mirror Exit with name already exists: {exitname}' exit = Entrance(region.player, exitname, region) exit.spot_type = 'Mirror' + to_region = world.get_region(region_dest_name, player) if region.terrain == Terrain.Water or to_region.terrain == Terrain.Water: exit.access_rule = lambda state: state.has('Flippers', player) and state.has_Pearl(player) and state.has_Mirror(player) else: @@ -862,7 +884,7 @@ def create_mirror_exits(world, player): mirror_exits.add(exitname) elif region.terrain == Terrain.Land: - logging.getLogger('').debug(f'Region has no mirror exit: {region.name}') + pass def create_dynamic_exits(world, player): create_flute_exits(world, player) From cba3ced5017fc2e727fa6b913d1ded4f625d1966 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 29 Dec 2022 04:31:12 -0600 Subject: [PATCH 086/146] Added Mirror Offset Glitch exits for Uncle/HC Ledge in Inverted --- OverworldGlitchRules.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OverworldGlitchRules.py b/OverworldGlitchRules.py index 9a170f45..90d89e83 100644 --- a/OverworldGlitchRules.py +++ b/OverworldGlitchRules.py @@ -508,6 +508,6 @@ mirror_clips = [ ] mirror_offsets = [ - (['DM Offset Mirror', 'DDM Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Ledge', 'Pyramid Crack'], ['Pyramid Area', 'Hyrule Castle Courtyard']) - #(['DM To HC Ledge Offset Mirror', 'DDM To HC Ledge Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Ledge', None], ['Pyramid Area', None]) + (['DM Offset Mirror', 'DDM Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Courtyard Northeast', 'Pyramid Crack'], ['Pyramid Area', 'Hyrule Castle Courtyard']), + (['DM To HC Ledge Offset Mirror', 'DDM To HC Ledge Offset Mirror'], ['West Death Mountain (Bottom)', 'West Dark Death Mountain (Bottom)'], ['Hyrule Castle Ledge', None], ['Pyramid Area', None]) ] \ No newline at end of file From 5fd88fcc784ba4be68f9f594ad076392115c5bf4 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 29 Dec 2022 18:43:20 -0600 Subject: [PATCH 087/146] Minor OWG generation error issue --- OverworldGlitchRules.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OverworldGlitchRules.py b/OverworldGlitchRules.py index 90d89e83..1d36de35 100644 --- a/OverworldGlitchRules.py +++ b/OverworldGlitchRules.py @@ -312,7 +312,10 @@ def overworld_glitches_rules(world, player): #add_alternate_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has_Boots(player)) #revisit when we can guarantee water walk # Adding additional item requirements to OWG Clips - add_additional_rule(world.get_entrance('VoO To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player)) + if world.is_tile_swapped(0x18, player): + add_additional_rule(world.get_entrance('Kakariko To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player)) + else: + add_additional_rule(world.get_entrance('VoO To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player)) add_additional_rule(world.get_entrance('Tree Line Water Clip', player), lambda state: state.has('Flippers', player)) add_additional_rule(world.get_entrance('Dark Tree Line Water Clip', player), lambda state: state.has('Flippers', player)) From 7fc3929280b1223f7f38065615fb23274f1b4504 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 29 Dec 2022 18:44:07 -0600 Subject: [PATCH 088/146] Fixed follower logic to use new dynamic mirror connections --- BaseClasses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseClasses.py b/BaseClasses.py index 3e83b69f..532daced 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1585,7 +1585,7 @@ class Entrance(object): if len(self.connected_region.locations) > 0 and self.connected_region.locations[0].item: item_name = self.connected_region.locations[0].item.name for loc in self.parent_region.locations: - if loc.event and not loc.real and loc.item.name.find('Farmable') < 0: + if loc.event and not loc.real and loc.item and loc.item.name.find('Farmable') < 0: item_name = loc.item.name break path = (item_name, (self.parent_region.name, path)) From 106397b13c6211633bfa5324517ef61c4bcf2b9e Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 29 Dec 2022 19:39:13 -0700 Subject: [PATCH 089/146] Fixed door position typo --- Doors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doors.py b/Doors.py index 32ffd9ae..6627a345 100644 --- a/Doors.py +++ b/Doors.py @@ -775,7 +775,7 @@ def create_doors(world, player): create_door(player, 'Ice Freezors Hole', Hole), create_door(player, 'Ice Freezors Bomb Hole', Hole), # combine these two? -- they have to lead to the same spot create_door(player, 'Ice Freezors Ledge Hole', Hole), - create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(2), + create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint WS', Intr).dir(We, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint EN', Nrml).dir(Ea, 0x7e, Top, High).pos(2), create_door(player, 'Ice Tall Hint SE', Nrml).dir(So, 0x7e, Right, High).small_key().pos(0).portal(X, 0x02), From 285038c8713077918cedaf75d8b5520d0d5c306a Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 2 Jan 2023 07:48:02 -0600 Subject: [PATCH 090/146] Moving S&Q exits to OWR mandatory connections --- EntranceShuffle.py | 19 ++----------------- OverworldShuffle.py | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 3497e427..34e04037 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -39,7 +39,6 @@ def link_entrances(world, player): if not world.is_tile_swapped(0x1b, player): drop_connections.append(tuple(('Pyramid Hole', 'Pyramid'))) dropexit_connections.append(tuple(('Pyramid Entrance', 'Pyramid Exit'))) - connect_simple(world, 'Other World S&Q', 'Pyramid Area', player) else: entrance_pool.remove('Pyramid Hole') entrance_pool.append('Inverted Pyramid Hole') @@ -47,7 +46,6 @@ def link_entrances(world, player): entrance_pool.append('Inverted Pyramid Entrance') drop_connections.append(tuple(('Inverted Pyramid Hole', 'Pyramid'))) dropexit_connections.append(tuple(('Inverted Pyramid Entrance', 'Pyramid Exit'))) - connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player) unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits) Cave_Exits.extend(Cave_Exits_Directional) @@ -56,16 +54,6 @@ def link_entrances(world, player): for exitname, regionname in mandatory_connections: connect_simple(world, exitname, regionname, player) - if not world.is_bombshop_start(player): - connect_simple(world, 'Links House S&Q', 'Links House', player) - else: - connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player) - - if not invFlag: - connect_simple(world, 'Sanctuary S&Q', 'Sanctuary', player) - else: - connect_simple(world, 'Sanctuary S&Q', 'Dark Sanctuary Hint', player) - connect_simple(world, 'Tavern North', 'Tavern', player) suppress_spoiler = False @@ -2040,11 +2028,8 @@ Exit_Pool_Base = ['Links House Exit', 'Pyramid'] # these are connections that cannot be shuffled and always exist. -# They link together separate parts of the world we need to divide into regions -mandatory_connections = [('Old Man S&Q', 'Old Man House'), - - # UW Connections - ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), +# They link together underworld regions +mandatory_connections = [('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), ('Kakariko Well (top to back)', 'Kakariko Well (back)'), diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 4def7446..57721fc1 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -14,6 +14,21 @@ version_branch = '-u' __version__ = '%s%s' % (version_number, version_branch) def link_overworld(world, player): + if not world.is_bombshop_start(player): + connect_simple(world, 'Links House S&Q', 'Links House', player) + else: + connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player) + + if not world.mode[player] != 'inverted': + connect_simple(world, 'Sanctuary S&Q', 'Sanctuary', player) + else: + connect_simple(world, 'Sanctuary S&Q', 'Dark Sanctuary Hint', player) + + if not world.is_tile_swapped(0x1b, player): + connect_simple(world, 'Other World S&Q', 'Pyramid Area', player) + else: + connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player) + # setup mandatory connections for exitname, regionname in mandatory_connections: connect_simple(world, exitname, regionname, player) @@ -1202,7 +1217,9 @@ test_connections = [ ] # these are connections that cannot be shuffled and always exist. They link together separate parts of the world we need to divide into regions -mandatory_connections = [# Intra-tile OW Connections +mandatory_connections = [('Old Man S&Q', 'Old Man House'), + + # Intra-tile OW Connections ('Lost Woods Bush (West)', 'Lost Woods East Area'), #pearl ('Lost Woods Bush (East)', 'Lost Woods West Area'), #pearl ('West Death Mountain Drop', 'West Death Mountain (Bottom)'), From c2da20207bec1c5b1a6f50da40b8ae7519fa4f80 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 3 Jan 2023 16:10:32 -0700 Subject: [PATCH 091/146] Fix for experimental inverted + vanilla ER --- source/overworld/EntranceShuffle2.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index b9bea9cd..460125b0 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -66,6 +66,8 @@ def link_entrances_new(world, player): default_map['Old Man Cave (East)'] = 'Death Mountain Return Cave Exit (West)' one_way_map['Bumper Cave (Top)'] = 'Dark Death Mountain Healer Fairy' del default_map['Bumper Cave (Top)'] + del one_way_map['Big Bomb Shop'] + one_way_map['Inverted Big Bomb Shop'] = 'Inverted Big Bomb Shop' avail_pool.default_map = default_map avail_pool.one_way_map = one_way_map From 46903470b5f9daefa058b9ab217dfe7848f36dd1 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 3 Jan 2023 16:14:42 -0700 Subject: [PATCH 092/146] Fix typo for door "Sewers Key Rat E" --- Doors.py | 2 +- Main.py | 2 +- RELEASENOTES.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Doors.py b/Doors.py index a7c1d9f3..c137983f 100644 --- a/Doors.py +++ b/Doors.py @@ -104,7 +104,7 @@ def create_doors(world, player): create_door(player, 'Sewers Dark Cross Key Door N', Nrml).dir(No, 0x32, Mid, High).small_key().pos(0), create_door(player, 'Sewers Water S', Nrml).dir(So, 0x22, Mid, High).small_key().pos(0).portal(Z, 0x22), create_door(player, 'Sewers Water W', Nrml).dir(We, 0x22, Bot, High).pos(1), - create_door(player, 'Sewers Key Rat E', Nrml).dir(Ea, 0x21, Bot, High).pos(1), + create_door(player, 'Sewers Key Rat E', Nrml).dir(Ea, 0x21, Bot, High).pos(2), create_door(player, 'Sewers Key Rat Key Door N', Nrml).dir(No, 0x21, Right, High).small_key().pos(0), create_door(player, 'Sewers Secret Room Key Door S', Nrml).dir(So, 0x11, Right, High).small_key().pos(2).portal(X, 0x02), create_door(player, 'Sewers Rat Path WS', Intr).dir(We, 0x11, Bot, High).pos(1), diff --git a/Main.py b/Main.py index 506fe985..e1a86313 100644 --- a/Main.py +++ b/Main.py @@ -31,7 +31,7 @@ from Utils import output_path, parse_player_names from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config from source.tools.BPS import create_bps_from_data -__version__ = '1.1.2-dev' +__version__ = '1.1.3-dev' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 831368e8..924fdaa5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -181,6 +181,8 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o # Bug Fixes and Notes +* 1.1.3 + * Fixed a typo on a door near the key rat * 1.1.2 * Fixed a logic bug with GT Refill room not requiring boots to access the pots in there. * 1.1.1 From 8839926a9734de8204c0c93ae4bf24c6de56c1d1 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 6 Jan 2023 13:56:18 -0700 Subject: [PATCH 093/146] Race flag on GUI Async Doors League presets Take into account starting inventory with default item pool --- ItemList.py | 17 ++++++++++ Main.py | 14 ++------ RELEASENOTES.md | 11 +++++-- Rom.py | 4 +-- data/base2current.bps | Bin 93478 -> 93506 bytes .../async_doors_league/S3_BombBag.yaml | 23 ++++++++++++++ docs/presets/async_doors_league/S3_Main.yaml | 22 +++++++++++++ .../async_doors_league/S3_PotteryLottery.yaml | 22 +++++++++++++ .../async_doors_league/S3_Standard.yaml | 30 ++++++++++++++++++ resources/app/gui/lang/en.json | 1 + .../gui/randomize/generation/checkboxes.json | 3 +- source/classes/CustomSettings.py | 5 ++- source/classes/constants.py | 1 + 13 files changed, 134 insertions(+), 19 deletions(-) create mode 100644 docs/presets/async_doors_league/S3_BombBag.yaml create mode 100644 docs/presets/async_doors_league/S3_Main.yaml create mode 100644 docs/presets/async_doors_league/S3_PotteryLottery.yaml create mode 100644 docs/presets/async_doors_league/S3_Standard.yaml diff --git a/ItemList.py b/ItemList.py index 1b4b6087..7080b330 100644 --- a/ItemList.py +++ b/ItemList.py @@ -962,9 +962,26 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt pool.extend(['Small Key (Universal)']) else: pool.extend(['Small Key (Universal)']) + modify_pool_for_start_inventory(pool, world, player) return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) +def modify_pool_for_start_inventory(pool, world, player): + for item in world.precollected_items: + if item.player == player: + pool.remove(item.name) + if item.dungeon: + d = world.get_dungeon(item.dungeon, item.player) + match = next((i for i in d.all_items if i.name == item.name), None) + if match: + if match.map or match.compass: + d.dungeon_items.remove(match) + elif match.smallkey: + d.small_keys.remove(match) + elif match.bigkey: + d.big_key.remove(match) + + def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer, goal, mode, swords, bombbag, customitemarray): if isinstance(customitemarray,dict) and 1 in customitemarray: customitemarray = customitemarray[1] diff --git a/Main.py b/Main.py index cfb7e5e5..820cf079 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.2-u' +__version__ = '1.2.0.3-u' from source.classes.BabelFish import BabelFish @@ -150,7 +150,7 @@ def main(args, seed=None, fish=None): world.player_names[player].append(name) logger.info('') world.settings = CustomSettings() - world.settings.create_from_world(world) + world.settings.create_from_world(world, args.race) outfilebase = f'DR_{args.outputname if args.outputname else world.seed}' @@ -196,16 +196,6 @@ def main(args, seed=None, fish=None): item = ItemFactory(inv_item.strip(), p) if item: world.push_precollected(item) - if item.dungeon: - d = world.get_dungeon(item.dungeon, item.player) - match = next((i for i in d.all_items if i.name == item.name), None) - if match: - if match.map or match.compass: - d.dungeon_items.remove(match) - elif match.smallkey: - d.small_keys.remove(match) - elif match.bigkey: - d.big_key.remove(match) if args.print_custom_yaml: world.settings.record_info(world) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 794af2d6..21f4a884 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -109,6 +109,14 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes +* 1.2.0.3-u + * Starting inventory taken into account with default item pool. (Custom pools must do this themselves) + * Fast ROM update + * Fix for restricted boss item counting maps & compasses as vital + * Bug fix for vanilla ER + inverted + experimental +* 1.2.0.2-u + * Fixed a bug with certain trap doors missing + * Added a hint reference for district hints * 1.2.0.1-u * Added new ganonhunt and completionist goals * Fixed the issue when defeating Agahnim and standing in the doorway can cause door state to linger. @@ -116,9 +124,6 @@ These are now independent of retro mode and have three options: None, Random, an * Fix for vanilla Doors + Standard + ER * Added a limit per dungeon on small key doors to ensure reasonable generation * Fixed many small bugs -* 1.2.0.2-u - * Fixed a bug with certain trap doors missing - * Added a hint reference for district hints # Known Issues diff --git a/Rom.py b/Rom.py index 03ab0283..d210ae01 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'f204143853a58e55a5fbc4c5bc87045e' +RANDOMIZERBASEHASH = '1e1094919d6a9dd151f8bc15c40b35f7' class JsonRom(object): @@ -2226,7 +2226,7 @@ def write_strings(rom, world, player, team): for loc_name in district.locations: location_item = world.get_location(loc_name, player).item if location_item.advancement: - if 'Heart Container' in location_item.name: + if 'Heart Container' in location_item.name or location_item.compass or location_item.map: continue itm_type = 'useful' if useful_item_for_hint(location_item, world) else 'vital' hint_type = 'path' diff --git a/data/base2current.bps b/data/base2current.bps index 41a996a35b4b37b1f6e70916a66e816e618ce471..271b2c2e5bd56abf7e11615aee052723186d40f8 100644 GIT binary patch delta 1286 zcmWlXe@s(X6vulXEk8LnngSbc!M@G2_P&m7$V}iV0?9buLaL{sQhR z1?+>@AH0<}$}Ck|E^R={*jAUh7CM+VnMq@GOSa66GUCcRIjSCjT+ zU`y(44!(h~sNDvK5veCGScA8Dtk7k^vEPiByYM-S6-N7_IRUn}b2K}^np3A*5gmLxAgta!*s&oX7?`~SdS;KH9}S)iu;D~} zZ?HMQdOt=?nO)4-N*1E5)XU#y)aC-jg+V;StU>Hy)GdTMyB|189L9y{LzBLLR_05p z%AdTY_0B{+A~RjvMz5KkvS`Q1Ee)7usPFVShbNL2915^;S=H2(`HDM|L`YL1i()G7jM z>yE|E)Ra^aXRu^MMo?8XsUVQ=d)7z*CW9#iQ`hg&fSqtYR47UQ*o(a+mhy6$6kq{T z;B$ce-%+52(qOc7RuqxCo#9;(v1bEHcRijI#lgeiqjoIRN z9xk5j_6@Wazg*A28Uq%T$zT&HSCI_#Ny~7Uil~R2LD3U@^P)5^=PpXUj-{Ro1_^U% zphj%=R3KrC6uhN8aCXF;FK`a^VIY)&em|0eU%~F1N_e-!1zoQY-1G~Y^Xc5H?Fg9ea;1* z;<+=<$dffzbYFPOY8_DG#Fj8KBN9@redDDCI z@A~FdsJ`e{r|>Ba?kG9CGK;mAL-kdz@1vGEp*9aVBnVF5NB$Riz+0)fP;YULwU%3s Xw*=O%=LFvoa5Qzu#0RqXZ?F6xQ7rS9&6T(33HvR5` zJ_m{&8@I#TLuU^=T`_31qmq-S;aWTLgR-o9HuHDA9CpF;bx8agbOR)o(vZX&I+a8> zox22ihh%lj!PSp?c%kn^@5GdxfK4qm`Pb)JY>ieVPSF{}m!U|@ zLa{AYso=AGo5L(t3U0W!7R6#WT<`_qS9YkfqRTx?+n$S;wSo(7BGz)nc4EDxC^jHx z!jE>i7$d6I4bNiIPicMyt?PHeUMq_IV(Y0x$DA%0ZRw1eYF#jy6#sQWGXX`W%OSmv zDAxcqd_h?U2y)f0#c^~ROCX*~ctm2Arj$ijy)dVVOa&J;q2US5mbhwJ;`?!&)@Fek z=6um6yD-C}6oj-EiwkqXS4X5pJ3E9`o&t-o%VQCWJyq7OLnBOhO5PQ$I&Tp+5V1RN zGFs30L>dc5hZ)<$KsGo`xV{26NRLiln2bK)mR_5j(E1gHOGa;fP=7AkPdT_9HQd!P z=R8L`c56U9ZQ+g_YyUN(3HFUJvbJz+EPjY6$bq9nPDV6Y#Dlu|fDt{q18IyrBO2Ti zVtm2!XVsZ0&#Nc%-VHJ0T>W9P%o+VfCE0m<%IhR?ryO2Lpj*2+{u+Do3Q6)s-hh^% zq;OP6Fmv~_asqZVIE~=u^*bD3h6f(#^hE#d-@8aH`Q`RKxl(}J ztVo)z2HB+DPBpM7W}`42G4^!^sVC@W7bCOwF2>iBtxm>sYNaO{uuU0WASXy07_h=n zymg?h+joU(H&y`2#J>#GGvH^i-lm7QTXPK>+&sV2#e0V$TYJ{mB;ocV?}>Nrit`5_ z@96dF2auLHs2>262Tz!ErNIga4e25zlusnAOi$@!z3T+a$Q4x(N zm$!&3a$2RuET~LF3qd5IV@Y1aH6y>8hf;Izpb{ggp9S*_NSd|VBOMr2Wg^PpaX}UI;NCA6D&s!;AA3 Date: Fri, 6 Jan 2023 15:01:24 -0700 Subject: [PATCH 094/146] Fix for randomization replication issue --- source/overworld/EntranceShuffle2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 460125b0..0a9e206a 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -275,7 +275,7 @@ def do_main_shuffle(entrances, exits, avail, mode_def): # OM Cave entrance in lw/dw if cross_world off if 'Old Man Cave Exit (West)' in rem_exits: world_limiter = DW_Entrances if avail.inverted else LW_Entrances - om_cave_options = [x for x in rem_entrances if x in world_limiter and bonk_fairy_exception(x)] + om_cave_options = sorted([x for x in rem_entrances if x in world_limiter and bonk_fairy_exception(x)]) om_cave_choice = random.choice(om_cave_options) if not avail.coupled: connect_exit('Old Man Cave Exit (West)', om_cave_choice, avail) From 839baee9a4a07139458a7a2c97b097ba520b0bda Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 6 Jan 2023 15:11:38 -0700 Subject: [PATCH 095/146] Minor fix for preset --- docs/presets/async_doors_league/S3_Standard.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/presets/async_doors_league/S3_Standard.yaml b/docs/presets/async_doors_league/S3_Standard.yaml index 0b6e116c..050db332 100644 --- a/docs/presets/async_doors_league/S3_Standard.yaml +++ b/docs/presets/async_doors_league/S3_Standard.yaml @@ -22,9 +22,4 @@ settings: hints: true msu_resume: true collection_rate: true - quickswap: true -start_inventory: - 1: - - Progressive Armor - - Pegasus Boots - - Boss Heart Container \ No newline at end of file + quickswap: true \ No newline at end of file From 4d1b5f58c0537b15c6ea5a79942b765cf92dd571 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 6 Jan 2023 16:57:52 -0700 Subject: [PATCH 096/146] Minor naming convention fixed --- DoorShuffle.py | 2 +- Doors.py | 2 +- Regions.py | 2 +- Rules.py | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index adf2607b..95bfd4c7 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -4247,7 +4247,7 @@ default_door_connections = [ ('Eastern Map Valley SW', 'Eastern Dark Square NW'), ('Eastern Attic Start WS', 'Eastern False Switches ES'), ('Eastern Cannonball Hell WS', 'Eastern Single Eyegore ES'), - ('Desert Compass NW', 'Desert Cannonball S'), + ('Desert Compass NE', 'Desert Cannonball S'), ('Desert Beamos Hall NE', 'Desert Tiles 2 SE'), ('PoD Middle Cage N', 'PoD Pit Room S'), ('PoD Pit Room NW', 'PoD Arena Main SW'), diff --git a/Doors.py b/Doors.py index 6627a345..7c9e5ca6 100644 --- a/Doors.py +++ b/Doors.py @@ -207,7 +207,7 @@ def create_doors(world, player): create_door(player, 'Desert East Wing ES', Intr).dir(Ea, 0x85, Bot, High).pos(3), create_door(player, 'Desert East Wing Key Door EN', Intr).dir(Ea, 0x85, Top, High).small_key().pos(1), create_door(player, 'Desert Compass Key Door WN', Intr).dir(We, 0x85, Top, High).small_key().pos(1), - create_door(player, 'Desert Compass NW', Nrml).dir(No, 0x85, Right, High).trap(0x4).pos(0), + create_door(player, 'Desert Compass NE', Nrml).dir(No, 0x85, Right, High).trap(0x4).pos(0), create_door(player, 'Desert Cannonball S', Nrml).dir(So, 0x75, Right, High).pos(1).portal(X, 0x02), create_door(player, 'Desert Arrow Pot Corner S Edge', Open).dir(So, 0x75, None, High).edge(6, Z, 0x20), create_door(player, 'Desert Arrow Pot Corner W Edge', Open).dir(We, 0x75, None, High).edge(2, Z, 0x20), diff --git a/Regions.py b/Regions.py index 3c307e40..6be2bbf3 100644 --- a/Regions.py +++ b/Regions.py @@ -338,7 +338,7 @@ def create_dungeon_regions(world, player): create_dungeon_region(player, 'Desert Dead End', 'Desert Palace', None, ['Desert Dead End Edge']), create_dungeon_region(player, 'Desert East Lobby', 'Desert Palace', None, ['Desert East Lobby WS', 'Desert East Lobby S']), create_dungeon_region(player, 'Desert East Wing', 'Desert Palace', None, ['Desert East Wing ES', 'Desert East Wing Key Door EN', 'Desert East Wing W Edge', 'Desert East Wing N Edge']), - create_dungeon_region(player, 'Desert Compass Room', 'Desert Palace', ['Desert Palace - Compass Chest'], ['Desert Compass Key Door WN', 'Desert Compass NW']), + create_dungeon_region(player, 'Desert Compass Room', 'Desert Palace', ['Desert Palace - Compass Chest'], ['Desert Compass Key Door WN', 'Desert Compass NE']), create_dungeon_region(player, 'Desert Cannonball', 'Desert Palace', ['Desert Palace - Big Key Chest'], ['Desert Cannonball S']), create_dungeon_region(player, 'Desert Arrow Pot Corner', 'Desert Palace', None, ['Desert Arrow Pot Corner S Edge', 'Desert Arrow Pot Corner W Edge', 'Desert Arrow Pot Corner NW']), create_dungeon_region(player, 'Desert Trap Room', 'Desert Palace', None, ['Desert Trap Room SW']), diff --git a/Rules.py b/Rules.py index 0190aaa4..38ff5666 100644 --- a/Rules.py +++ b/Rules.py @@ -649,7 +649,7 @@ def bomb_rules(world, player): ('Hyrule Dungeon Armory S', True), # One green guard ('Hyrule Dungeon Armory ES', True), # One green guard ('Hyrule Dungeon Armory Boomerang WS', True), # One blue guard - ('Desert Compass NW', True), # Three popos + ('Desert Compass NE', True), # Three popos ('Desert Four Statues NW', True), # Four popos ('Desert Four Statues ES', True), # Four popos ('Hera Beetles WS', False), # Three blue beetles and only two pots, and bombs don't work. @@ -1219,7 +1219,7 @@ std_kill_rooms = { 'Hyrule Dungeon Armory Main': ['Hyrule Dungeon Armory S', 'Hyrule Dungeon Armory ES'], # One green guard 'Hyrule Dungeon Armory Boomerang': ['Hyrule Dungeon Armory Boomerang WS'], # One blue guard 'Eastern Stalfos Spawn': ['Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW'], # Can use pots - 'Desert Compass Room': ['Desert Compass NW'], # Three popos + 'Desert Compass Room': ['Desert Compass NE'], # Three popos 'Desert Four Statues': ['Desert Four Statues NW', 'Desert Four Statues ES'], # Four popos 'Hera Beetles': ['Hera Beetles WS'], # Three blue beetles and only two pots, and bombs don't work. 'Tower Gold Knights': ['Tower Gold Knights SW', 'Tower Gold Knights EN'], # Two ball and chain @@ -1994,7 +1994,7 @@ bunny_impassible_doors = { 'Eastern Map Balcony Hook Path', 'Eastern Stalfos Spawn ES', 'Eastern Stalfos Spawn NW', 'Eastern Darkness S', 'Eastern Darkness NE', 'Eastern Darkness Up Stairs', 'Eastern Attic Start WS', 'Eastern Single Eyegore NE', 'Eastern Duo Eyegores NE', 'Desert Main Lobby Left Path', - 'Desert Main Lobby Right Path', 'Desert Left Alcove Path', 'Desert Right Alcove Path', 'Desert Compass NW', + 'Desert Main Lobby Right Path', 'Desert Left Alcove Path', 'Desert Right Alcove Path', 'Desert Compass NE', 'Desert West Lobby NW', 'Desert Back Lobby NW', 'Desert Four Statues NW', 'Desert Four Statues ES', 'Desert Beamos Hall WS', 'Desert Beamos Hall NE', 'Desert Wall Slide NW', 'Hera Lobby to Front Barrier - Blue', 'Hera Front to Lobby Barrier - Blue', 'Hera Front to Down Stairs Barrier - Blue', From c98300e2ffec3a0b68edf1eaf3d4845038ea7518 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 6 Jan 2023 21:37:28 -0600 Subject: [PATCH 097/146] Merged in DR v1.2.0.3 --- Doors.py | 2 +- ItemList.py | 17 ++++++++++++ Main.py | 14 ++-------- RELEASENOTES.md | 11 +++++--- Rom.py | 4 +-- data/base2current.bps | Bin 105064 -> 105092 bytes .../async_doors_league/S3_BombBag.yaml | 23 ++++++++++++++++ docs/presets/async_doors_league/S3_Main.yaml | 22 +++++++++++++++ .../async_doors_league/S3_PotteryLottery.yaml | 22 +++++++++++++++ .../async_doors_league/S3_Standard.yaml | 25 ++++++++++++++++++ resources/app/gui/lang/en.json | 1 + .../gui/randomize/generation/checkboxes.json | 3 ++- source/classes/CustomSettings.py | 5 +++- source/classes/constants.py | 1 + source/overworld/EntranceShuffle2.py | 4 ++- 15 files changed, 133 insertions(+), 21 deletions(-) create mode 100644 docs/presets/async_doors_league/S3_BombBag.yaml create mode 100644 docs/presets/async_doors_league/S3_Main.yaml create mode 100644 docs/presets/async_doors_league/S3_PotteryLottery.yaml create mode 100644 docs/presets/async_doors_league/S3_Standard.yaml diff --git a/Doors.py b/Doors.py index 32ffd9ae..6627a345 100644 --- a/Doors.py +++ b/Doors.py @@ -775,7 +775,7 @@ def create_doors(world, player): create_door(player, 'Ice Freezors Hole', Hole), create_door(player, 'Ice Freezors Bomb Hole', Hole), # combine these two? -- they have to lead to the same spot create_door(player, 'Ice Freezors Ledge Hole', Hole), - create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(2), + create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint WS', Intr).dir(We, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint EN', Nrml).dir(Ea, 0x7e, Top, High).pos(2), create_door(player, 'Ice Tall Hint SE', Nrml).dir(So, 0x7e, Right, High).small_key().pos(0).portal(X, 0x02), diff --git a/ItemList.py b/ItemList.py index dd15a1ad..e7a21160 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1123,9 +1123,26 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt pool.extend(['Small Key (Universal)']) else: pool.extend(['Small Key (Universal)']) + modify_pool_for_start_inventory(pool, world, player) return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) +def modify_pool_for_start_inventory(pool, world, player): + for item in world.precollected_items: + if item.player == player: + pool.remove(item.name) + if item.dungeon: + d = world.get_dungeon(item.dungeon, item.player) + match = next((i for i in d.all_items if i.name == item.name), None) + if match: + if match.map or match.compass: + d.dungeon_items.remove(match) + elif match.smallkey: + d.small_keys.remove(match) + elif match.bigkey: + d.big_key.remove(match) + + def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer, goal, mode, swords, bombbag, customitemarray): pool = [] placed_items = {} diff --git a/Main.py b/Main.py index 73502cf4..f584b791 100644 --- a/Main.py +++ b/Main.py @@ -35,7 +35,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.2-u' +__version__ = '1.2.0.3-u' from source.classes.BabelFish import BabelFish @@ -160,7 +160,7 @@ def main(args, seed=None, fish=None): world.player_names[player].append(name) logger.info('') world.settings = CustomSettings() - world.settings.create_from_world(world) + world.settings.create_from_world(world, args.race) outfilebase = f'OR_{args.outputname if args.outputname else world.seed}' @@ -202,16 +202,6 @@ def main(args, seed=None, fish=None): item = ItemFactory(inv_item.strip(), p) if item: world.push_precollected(item) - if item.dungeon: - d = world.get_dungeon(item.dungeon, item.player) - match = next((i for i in d.all_items if i.name == item.name), None) - if match: - if match.map or match.compass: - d.dungeon_items.remove(match) - elif match.smallkey: - d.small_keys.remove(match) - elif match.bigkey: - d.big_key.remove(match) if args.print_custom_yaml: world.settings.record_info(world) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 794af2d6..21f4a884 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -109,6 +109,14 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes +* 1.2.0.3-u + * Starting inventory taken into account with default item pool. (Custom pools must do this themselves) + * Fast ROM update + * Fix for restricted boss item counting maps & compasses as vital + * Bug fix for vanilla ER + inverted + experimental +* 1.2.0.2-u + * Fixed a bug with certain trap doors missing + * Added a hint reference for district hints * 1.2.0.1-u * Added new ganonhunt and completionist goals * Fixed the issue when defeating Agahnim and standing in the doorway can cause door state to linger. @@ -116,9 +124,6 @@ These are now independent of retro mode and have three options: None, Random, an * Fix for vanilla Doors + Standard + ER * Added a limit per dungeon on small key doors to ensure reasonable generation * Fixed many small bugs -* 1.2.0.2-u - * Fixed a bug with certain trap doors missing - * Added a hint reference for district hints # Known Issues diff --git a/Rom.py b/Rom.py index fdb2f0c1..cf54c71d 100644 --- a/Rom.py +++ b/Rom.py @@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '1cdb34399467efa346b713db54d6cb02' +RANDOMIZERBASEHASH = '45aa34e724750862234f9a4b09caa3d6' class JsonRom(object): @@ -2343,7 +2343,7 @@ def write_strings(rom, world, player, team): for loc_name in district.locations: location_item = world.get_location(loc_name, player).item if location_item.advancement: - if 'Heart Container' in location_item.name: + if 'Heart Container' in location_item.name or location_item.compass or location_item.map: continue itm_type = 'useful' if useful_item_for_hint(location_item, world) else 'vital' hint_type = 'path' diff --git a/data/base2current.bps b/data/base2current.bps index ee0b630f2e14630a2a1a55b7c3685e9c93c6e881..7daea3d4a4286f9d848442a4260756e9c70556ca 100644 GIT binary patch delta 1359 zcmW-feN2-_9LIa5uu@uDRG>;->(Qye6cz=1iGqn6;1pjbllcl6&D82Pqtm$w+|w4c z4?KP0u{=@+R4E*7#FpVwv$$3oh%j~OHk}*lMy6xfEUr3T3{kpcf82fUoBQ53zuzx6 zaWT&DRh(A?b}V^(JrVHuJYUr3rF`~7vEA$YC|i!L4L&zv3%?>|V+S z_vmpreBBD45ng0qtN~x{T-^4Qy)34za03ZC81oLPaUiBwhAqOI49r59r?Qja=PBYQ9nHrjcf}X^V9Bwh$^xR zC|kkgC@pfcHz~O}8!;mwA~P!xtw9Z3u)g6zdqKN#a&*F^YZ()JW7aRa@`KtvH0t7+ zRa~-nk z6grYR8rT%1-GQoqYLv5{)=U=c3es$u>TiG=M>AyL74G}*ln==UZ7L-m;##i_@ z5ix5jB?Ow%u_S`GDufz>jYGFzAy{zZZVsUP1yl2-0CQOqunl0JUINlYM0TWtGejh7?xRIid3H278h97CiP>D;y&00a-^LwW>xM$NRMQ)z6r!zHu+R%h9xlkJz%x z8JrS=^vzi7NetF#CFKHxqHZo%k}E|EsN4@wN2wwSv4?vfszS1{An+yxRrES{fcFFs zYlEs`pG2#=#I8Nx#Lq_7kti<|Z%_VA$9{C^8OK7fHw9;akg%hmxM4`HU8aTGo17j2 z!dy~1m_Gw^igG(w-EW0G4xP3&L1E{L(!okGj_|8Ww8f(yK5?4T!BH~gST)Fz;gM)G zGIz)kdi=X8@NWcjZ>m8)_=2legSlkJt!gljdthyRU**N#peMfsOK{Bz%40bmnPHJVkp1FH1Dq-=MwTkM=XMa_mR(&4>ARS o@r|wo@w*e-c3K>snqtf0YX9O~hI`TiJ`@hNeK)*r=IQtT1G45|wg3PC delta 1331 zcmW-ee^Aq99LM+B297VAEKpc6;>*M2K{y3Z6TwsPLPSMU`~e}_D7aH+nU`sn%Jbbo z8!*QBHoiJe89z^!v;o?>PMMHg?$o=TW*KTxn$f!St6>?}Ne}(=ygu)H-p}XWpU+c$ zE_D2CsHYOP4y-Kr5+qWIcgpMGypFvg-35J|J>7m1J!`;?Qhl%_k=RjF117+?Yk#pJ zj}-?GUACaReWyQYv;~pIf=iB`K+7%I1N!uP=A^rwEU}^fW0=1P?ST2Wr08X=tL;V3 zJ5KceZB^L~Q>XH%1{?l^`IHTI$(jyr>&spTkWcS%e(6h-g;wV^Z$35}dZTaL+B0Uk&W z@c_m5p{u8ns8~S3Zw?!$=W?c8g)eoXoCX>Wr8nS#GtACuSG4lLG#XR~p^E7*Txa28 z9CD6}ZZ_Ho>&qAvQZ~18iydo>T(QH*ZE+l^ZreY|_@~5T-+_K3w~CtW*^{HSjEk2N zPGe0Y7C(q;tCrMOk~-nx(Q}ida)^00Mq64 zZwSbH7L)MKhZiLxjQf5wVd3sekVPM8VqvF7YAEwO2fnD@B8GN(TA0#juW+cS8Ve_4 zA(OVd5er6HEcQzSnr^30@)%!hV?>pujd68khDMPDldvZqisb$zQ6Y@P!y@&T4QEca zyDmshX(~ZTp7D=Y!NP6GGe;nO%g)_lq-l=RX6Wh*Z0N|ViX^8ByJ|{*pV}(=9(W9`C?%2zGIf-&1VJK=UWOok!5?fuJvI!U@L{%g zjmsx_f-f6}*~?y)f&GH;AJz$#%1C0C1i~EK)*1OlSuMgD1UsVfTnH#yv-9glG=?Px zRNB<(mJ=+bBtnuJ3)&KgaCm^<*Hsp`GrPSAx2>WRQRtM>7 z?4Ozv<3^l;$3L^azeFtPb&vsC;kXXs={Mo8n#yq)|krLgq|7sc$cjcdaHdz8q>SO@&m~{C$q$jW^{zI-=UKb|TL+F^iOCT@Mv<7sE}J$`LWU zwu#NGYtDIfR7lQ%)({E0bWh^FngJsGG8@brZE3bVtm{<9`Fw+6= OC`!6l7Vk;d Date: Sat, 7 Jan 2023 14:58:24 -0600 Subject: [PATCH 098/146] remove hard requirement of tkinter when using CLI --- source/meta/check_requirements.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/meta/check_requirements.py b/source/meta/check_requirements.py index 680dfe8f..6976f707 100644 --- a/source/meta/check_requirements.py +++ b/source/meta/check_requirements.py @@ -1,6 +1,4 @@ import importlib.util -import webbrowser -from tkinter import Tk, Label, Button, Frame def check_requirements(console=False): @@ -26,6 +24,9 @@ def check_requirements(console=False): logger.error('See the step about "Installing Platform-specific dependencies":') logger.error('https://github.com/aerinon/ALttPDoorRandomizer/blob/DoorDev/docs/BUILDING.md') else: + import webbrowser + from tkinter import Tk, Label, Button, Frame + master = Tk() master.title('Error') frame = Frame(master) From ce5f58ec3c4e7bb18750752edd5ca379c5ba3429 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 7 Jan 2023 16:58:43 -0600 Subject: [PATCH 099/146] Added Lite/Lean support for Fixed Take-Any caves --- EntranceShuffle.py | 40 +++++++++++++++++++--------- source/overworld/EntranceShuffle2.py | 39 +++++++++++++++++---------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 34e04037..b6eb3bf6 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -62,7 +62,8 @@ def link_entrances(world, player): # if we do not shuffle, set default connections if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - for entrancename, exitname in default_connections + default_pot_connections + drop_connections + default_item_connections + default_shop_connections: + for entrancename, exitname in (default_connections + default_pot_connections + + default_takeany_connections + drop_connections + default_item_connections + default_shop_connections): connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit')) for entrancename, exitname in default_connector_connections + dropexit_connections: connect_logical(world, entrancename, exitname, player, True) @@ -330,7 +331,10 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, list(entrance_pool), list(exit_pool), player) elif world.shuffle[player] == 'lite': - for entrancename, exitname in default_connections + ([] if world.shopsanity[player] else default_shop_connections) + ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections): + for entrancename, exitname in (default_connections + + ([] if world.shopsanity[player] else default_shop_connections) + + ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections) + + ([] if world.take_any[player] == 'fixed' else default_takeany_connections)): connect_logical(world, entrancename, exitname, player, False) if invFlag: world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance('Dark Sanctuary Hint', player).parent_region) @@ -420,7 +424,10 @@ def link_entrances(world, player): # place remaining doors connect_doors(world, list(entrance_pool), list(exit_pool), player) elif world.shuffle[player] == 'lean': - for entrancename, exitname in default_connections + ([] if world.shopsanity[player] else default_shop_connections) + ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections): + for entrancename, exitname in (default_connections + + ([] if world.shopsanity[player] else default_shop_connections) + + ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections) + + ([] if world.take_any[player] == 'fixed' else default_takeany_connections)): connect_logical(world, entrancename, exitname, player, False) if invFlag: world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance('Dark Sanctuary Hint', player).parent_region) @@ -1342,7 +1349,10 @@ def place_links_house(world, player, ignore_list=[]): else: links_house_doors = [i for i in get_starting_entrances(world, player, world.shuffle[player] != 'insanity') if i in entrance_pool] if world.shuffle[player] in ['lite', 'lean']: - links_house_doors = [e for e in links_house_doors if e in list(zip(*(default_item_connections + (default_shop_connections if world.shopsanity[player] else []) + (default_pot_connections if world.pottery[player] not in ['none', 'keys', 'dungeon'] else []))))[0]] + links_house_doors = [e for e in links_house_doors if e in list(zip(*(default_item_connections + + (default_shop_connections if world.shopsanity[player] else []) + + (default_pot_connections if world.pottery[player] not in ['none', 'keys', 'dungeon'] else []) + + (default_takeany_connections if world.take_any[player] == 'fixed' else []))))[0]] #TODO: Need to improve Links House placement to choose a better sector or eliminate entrances that are after ledge drops links_house_doors = [e for e in links_house_doors if e not in ignore_list] @@ -1390,7 +1400,10 @@ def place_blacksmith(world, links_house, player): sanc_region = world.get_entrance('Sanctuary Exit', player).connected_region.name blacksmith_doors = list(OrderedDict.fromkeys(blacksmith_doors + list(build_accessible_entrance_list(world, sanc_region, player, assumed_inventory, False, True, True)))) if world.shuffle[player] in ['lite', 'lean']: - blacksmith_doors = [e for e in blacksmith_doors if e in list(zip(*(default_item_connections + (default_shop_connections if world.shopsanity[player] else []) + (default_pot_connections if world.pottery[player] not in ['none', 'keys', 'dungeon'] else []))))[0]] + blacksmith_doors = [e for e in blacksmith_doors if e in list(zip(*(default_item_connections + + (default_shop_connections if world.shopsanity[player] else []) + + (default_pot_connections if world.pottery[player] not in ['none', 'keys', 'dungeon'] else []) + + (default_takeany_connections if world.take_any[player] == 'fixed' else []))))[0]] assert len(blacksmith_doors), 'No valid candidates to place Blacksmiths Hut' blacksmith_hut = random.choice(blacksmith_doors) @@ -1457,7 +1470,8 @@ def junk_fill_inaccessible(world, player): if not exit.connected_region and exit.name in entrance_pool: inaccessible_entrances.append(exit.name) - junk_locations = [e for e in list(zip(*(default_connections + ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections))))[1] if e in exit_pool] + junk_locations = [e for e in list(zip(*(default_connections + + ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections))))[1] if e in exit_pool] random.shuffle(junk_locations) for entrance in inaccessible_entrances: connect_entrance(world, entrance, junk_locations.pop(), player) @@ -2070,8 +2084,6 @@ mandatory_connections = [('Lost Woods Hideout (top to bottom)', 'Lost Woods Hide default_connections = [('Bonk Fairy (Light)', 'Bonk Fairy (Light)'), ('Lake Hylia Fairy', 'Lake Hylia Healer Fairy'), ('Lake Hylia Fortune Teller', 'Lake Hylia Fortune Teller'), - ('Light Hype Fairy', 'Swamp Healer Fairy'), - ('Desert Fairy', 'Desert Healer Fairy'), ('Lost Woods Gamble', 'Lost Woods Gamble'), ('Fortune Teller (Light)', 'Fortune Teller (Light)'), ('Bush Covered House', 'Bush Covered House'), @@ -2081,16 +2093,20 @@ default_connections = [('Bonk Fairy (Light)', 'Bonk Fairy (Light)'), ('East Dark World Hint', 'East Dark World Hint'), ('Dark Lake Hylia Fairy', 'Dark Lake Hylia Healer Fairy'), - ('Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Healer Fairy'), ('Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Hint'), - ('Bonk Fairy (Dark)', 'Bonk Fairy (Dark)'), ('Dark Sanctuary Hint', 'Dark Sanctuary Hint'), ('Fortune Teller (Dark)', 'Fortune Teller (Dark)'), ('Archery Game', 'Archery Game'), - ('Dark Desert Fairy', 'Dark Desert Healer Fairy'), - ('Dark Death Mountain Fairy', 'Dark Death Mountain Healer Fairy'), + ('Dark Desert Fairy', 'Dark Desert Healer Fairy') ] +default_takeany_connections = [('Light Hype Fairy', 'Swamp Healer Fairy'), + ('Desert Fairy', 'Desert Healer Fairy'), + ('Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Healer Fairy'), + ('Bonk Fairy (Dark)', 'Bonk Fairy (Dark)'), + ('Dark Death Mountain Fairy', 'Dark Death Mountain Healer Fairy') + ] + default_pot_connections = [('Lumberjack House', 'Lumberjack House'), ('Snitch Lady (East)', 'Snitch Lady (East)'), ('Snitch Lady (West)', 'Snitch Lady (West)'), diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 8fc505e1..abcd9da8 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -775,6 +775,9 @@ def do_vanilla_connect(pool_def, avail): elif pool_def['condition'] == 'pottery': # this condition involves whether caves with pots are shuffled or not if avail.world.pottery[avail.player] not in ['none', 'keys', 'dungeon']: return + elif pool_def['condition'] == 'takeany': + if avail.world.take_any[avail.player] == 'fixed': + return defaults = inverted_default_connections if avail.inverted else default_connections if avail.inverted: if 'Dark Death Mountain Fairy' in pool_def['entrances']: @@ -1200,13 +1203,11 @@ modes = { 'fixed_non_items': { 'special': 'vanilla', 'condition': '', - 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Archery Game', - 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Bonk Fairy (Dark)', - 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', - 'Dark Lake Hylia Shop', 'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', - 'Long Fairy Cave', 'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble', - 'Desert Fairy', 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', - 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'], + 'entrances': ['Dark Desert Fairy', 'Archery Game', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', + 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop', + 'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', 'Long Fairy Cave', + 'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble', + 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'], }, 'fixed_shops': { 'special': 'vanilla', @@ -1215,6 +1216,12 @@ modes = { 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)'], }, + 'fixed_takeanys': { + 'special': 'vanilla', + 'condition': 'takeany', + 'entrances': ['Desert Fairy', 'Light Hype Fairy', 'Dark Death Mountain Fairy', + 'Dark Lake Hylia Ledge Fairy', 'Bonk Fairy (Dark)'], + }, 'fixed_pottery': { 'special': 'vanilla', 'condition': 'pottery', @@ -1276,13 +1283,11 @@ modes = { 'fixed_non_items': { 'special': 'vanilla', 'condition': '', - 'entrances': ['Dark Death Mountain Fairy', 'Dark Desert Fairy', 'Archery Game', - 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Bonk Fairy (Dark)', - 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Fairy', - 'Dark Lake Hylia Shop', 'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', - 'Long Fairy Cave', 'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble', - 'Desert Fairy', 'Light Hype Fairy', 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', - 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'], + 'entrances': ['Dark Desert Fairy', 'Archery Game', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', + 'Dark Lake Hylia Ledge Hint', 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Shop', + 'East Dark World Hint', 'Kakariko Gamble Game', 'Good Bee Cave', 'Long Fairy Cave', + 'Bush Covered House', 'Fortune Teller (Light)', 'Lost Woods Gamble', + 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy', 'Bonk Fairy (Light)', 'Inverted Dark Sanctuary'], }, 'fixed_shops': { 'special': 'vanilla', @@ -1291,6 +1296,12 @@ modes = { 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)'], }, + 'fixed_takeanys': { + 'special': 'vanilla', + 'condition': 'takeany', + 'entrances': ['Desert Fairy', 'Light Hype Fairy', 'Dark Death Mountain Fairy', + 'Dark Lake Hylia Ledge Fairy', 'Bonk Fairy (Dark)'], + }, 'fixed_pottery': { 'special': 'vanilla', 'condition': 'pottery', From 52a94d55743a400df73ad216bba026ee53edf141 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 7 Jan 2023 21:07:14 -0600 Subject: [PATCH 100/146] Moving S&Q exits to OWR mandatory connections --- OverworldShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 57721fc1..7c8451bf 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -19,7 +19,7 @@ def link_overworld(world, player): else: connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player) - if not world.mode[player] != 'inverted': + if not world.mode[player] == 'inverted': connect_simple(world, 'Sanctuary S&Q', 'Sanctuary', player) else: connect_simple(world, 'Sanctuary S&Q', 'Dark Sanctuary Hint', player) From 87dd31633a4a4b3f34d9ac37c3d456b8577dcce3 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 8 Jan 2023 03:32:23 -0600 Subject: [PATCH 101/146] Corrected some one-way ledges in definition --- EntranceShuffle.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index b6eb3bf6..69904af1 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2265,23 +2265,22 @@ one_way_ledges = { 'Potion Shop Northeast'}, 'Zora Approach Water': {'Zora Approach Area'}, 'Hyrule Castle Area': {'Hyrule Castle Ledge'}, + 'Hyrule Castle Courtyard': {'Hyrule Castle Ledge'}, 'Wooden Bridge Water': {'Wooden Bridge Area', 'Wooden Bridge Northeast'}, 'Maze Race Area': {'Maze Race Ledge', 'Maze Race Prize'}, 'Flute Boy Approach Area': {'Cave 45 Ledge'}, 'Desert Area': {'Desert Ledge', - 'Desert Palace Entrance (North) Spot', 'Desert Checkerboard Ledge', 'Desert Palace Mouth', - 'Desert Palace Stairs', 'Bombos Tablet Ledge', 'Desert Palace Teleporter Ledge'}, 'Desert Pass Area': {'Desert Pass Ledge'}, 'Lake Hylia Water': {'Lake Hylia South Shore', 'Lake Hylia Island'}, 'West Dark Death Mountain (Bottom)': {'West Dark Death Mountain (Top)'}, - 'West Dark Death Mountain (Top)': {'Dark Death Mountain Floating Island'}, + 'East Dark Death Mountain (Top)': {'Dark Death Mountain Floating Island'}, 'East Dark Death Mountain (Bottom)': {'East Dark Death Mountain (Top)'}, 'Turtle Rock Area': {'Turtle Rock Ledge'}, 'Bumper Cave Area': {'Bumper Cave Ledge'}, From 72ba1f1f0dd2bb76c598086777b2b8edad00846a Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 8 Jan 2023 03:34:38 -0600 Subject: [PATCH 102/146] Minor OWG generation error issue --- OverworldGlitchRules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OverworldGlitchRules.py b/OverworldGlitchRules.py index 1d36de35..2372993f 100644 --- a/OverworldGlitchRules.py +++ b/OverworldGlitchRules.py @@ -312,7 +312,7 @@ def overworld_glitches_rules(world, player): #add_alternate_rule(world.get_location('Zora\'s Ledge', player), lambda state: state.has_Boots(player)) #revisit when we can guarantee water walk # Adding additional item requirements to OWG Clips - if world.is_tile_swapped(0x18, player): + if world.is_tile_swapped(0x18, player) != world.is_tile_swapped(0x28, player): add_additional_rule(world.get_entrance('Kakariko To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player)) else: add_additional_rule(world.get_entrance('VoO To Dig Game Hook Clip', player), lambda state: state.has('Hookshot', player)) From e335de8e92dbe03bfae3aedc293ca5fd7715f44c Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 8 Jan 2023 03:39:25 -0600 Subject: [PATCH 103/146] Fixing problems when connecting entrances from outside ER --- EntranceShuffle.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 69904af1..cc0faba9 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -10,7 +10,7 @@ from Utils import stack_size3a entrance_pool = list() exit_pool = list() entrance_exits = list() -ignore_pool = False +ignore_pool = True suppress_spoiler = True def link_entrances(world, player): @@ -699,9 +699,9 @@ def connect_logical(world, entrancename, exitname, player, isTwoWay = False): def connect_entrance(world, entrancename, exitname, player, mark_two_way=True): if not ignore_pool: logging.getLogger('').debug('Connecting %s -> %s', entrancename, exitname) - assert entrancename in entrance_pool, 'Entrance not in pool: ' + entrancename + assert entrancename in entrance_pool, f'Entrance not in pool: {entrancename}' if mark_two_way: - assert exitname in exit_pool, 'Exit not in pool: ' + exitname + assert exitname in exit_pool, f'Exit not in pool: {exitname}' entrance = world.get_entrance(entrancename, player) # check if we got an entrance or a region to connect to From 22dfeeeccad75b9a4a7d4f6f795413d90e69ad02 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 12 Jan 2023 15:32:49 -0700 Subject: [PATCH 104/146] Starting inventory updates Logic fix for skull woods star tile logic Standard logic improvement --- BaseClasses.py | 3 + DoorShuffle.py | 2 +- ItemList.py | 113 ++++++++++++++++-- Main.py | 2 +- RELEASENOTES.md | 6 +- Rom.py | 16 ++- Rules.py | 22 +++- .../async_doors_league/S3_BombBag.yaml | 39 +++--- docs/presets/async_doors_league/S3_Main.yaml | 37 +++--- .../async_doors_league/S3_PotteryLottery.yaml | 37 +++--- source/dungeon/DungeonStitcher.py | 2 + test/customizer/test_stuff.yaml | 28 +++++ 12 files changed, 225 insertions(+), 82 deletions(-) create mode 100644 test/customizer/test_stuff.yaml diff --git a/BaseClasses.py b/BaseClasses.py index f7fd2cc9..91404ebb 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2287,6 +2287,9 @@ class Item(object): def __unicode__(self): return self.world.get_name_string_for_object(self) if self.world else f'{self.name} (Player {self.player})' + def __eq__(self, other): + return self.name == other.name and self.player == other.player + # have 6 address that need to be filled class Crystal(Item): diff --git a/DoorShuffle.py b/DoorShuffle.py index 95bfd4c7..d4d94905 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -2107,7 +2107,7 @@ def find_trappable_candidates(builder, world, player): if ext.door and ext.door.type in [DoorType.Interior, DoorType.Normal]] for d in filtered_doors: # I only support the first 3 due to the trapFlag right now - if 0 <= d.doorListPos < 3 and not d.entranceFlag: + if 0 <= d.doorListPos < 3 and not d.entranceFlag and d.name != 'Skull Small Hall WS': room = world.get_room(d.roomIndex, player) kind = room.kind(d) if d.type == DoorType.Interior: diff --git a/ItemList.py b/ItemList.py index 7080b330..4bbd0f32 100644 --- a/ItemList.py +++ b/ItemList.py @@ -286,6 +286,7 @@ def generate_itempool(world, player): for _ in range(0, amt): pool.append('Rupees (20)') + start_inventory = list(world.precollected_items) for item in precollected_items: world.push_precollected(ItemFactory(item, player)) @@ -435,6 +436,22 @@ def generate_itempool(world, player): if world.pottery[player] not in ['none', 'keys'] and not skip_pool_adjustments: add_pot_contents(world, player) + # modfiy based on start inventory, if any + modify_pool_for_start_inventory(start_inventory, world, player) + + # increase pool if not enough items + ttl_locations = sum(1 for x in world.get_unfilled_locations(player) if '- Prize' not in x.name) + pool_size = count_player_dungeon_item_pool(world, player) + pool_size += sum(1 for x in world.itempool if x.player == player) + + if pool_size < ttl_locations: + retro_bow = world.bow_mode[player].startswith('retro') + amount_to_add = ttl_locations - pool_size + filler_additions = random.choices(list(filler_items.keys()), filler_items.values(), k=amount_to_add) + for item in filler_additions: + item_name = 'Rupees (5)' if retro_bow and item == 'Arrows (10)' else item + world.itempool.append(ItemFactory(item_name, player)) + take_any_locations = [ 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', 'Light World Bomb Hut', @@ -962,14 +979,60 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt pool.extend(['Small Key (Universal)']) else: pool.extend(['Small Key (Universal)']) - modify_pool_for_start_inventory(pool, world, player) return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) -def modify_pool_for_start_inventory(pool, world, player): - for item in world.precollected_items: +item_alternates = { + # Bows + 'Progressive Bow (Alt)': ('Progressive Bow', 1), + 'Bow': ('Progressive Bow', 1), + 'Silver Arrows': ('Progressive Bow', 2), + # Gloves + 'Power Glove': ('Progressive Glove', 1), + 'Titans Mitts': ('Progressive Glove', 2), + # Swords + 'Sword and Shield': ('Progressive Sword', 1), # could find a way to also remove a shield, but mostly not impactful + 'Fighter Sword': ('Progressive Sword', 1), + 'Master Sword': ('Progressive Sword', 2), + 'Tempered Sword': ('Progressive Sword', 3), + 'Golden Sword': ('Progressive Sword', 4), + # Shields + 'Blue Shield': ('Progressive Shield', 1), + 'Red Shield': ('Progressive Shield', 2), + 'Mirror Shield': ('Progressive Shield', 3), + # Armors + 'Blue Mail': ('Progressive Armor', 1), + 'Red Mail': ('Progressive Armor', 2), + + 'Magic Upgrade (1/4)': ('Magic Upgrade (1/2)', 2), + 'Ocarina': ('Ocarina (Activated)', 1), + 'Ocarina (Activated)': ('Ocarina', 1), + 'Boss Heart Container': ('Sanctuary Heart Container', 1), + 'Sanctuary Heart Container': ('Boss Heart Container', 1), + 'Power Star': ('Triforce Piece', 1) +} + + +def modify_pool_for_start_inventory(start_inventory, world, player): + # skips custom item pools - these shouldn't be adjusted + if (world.customizer and world.customizer.get_item_pool()) or world.custom: + return + for item in start_inventory: if item.player == player: - pool.remove(item.name) + if item in world.itempool: + world.itempool.remove(item) + elif item.name in item_alternates: + alt = item_alternates[item.name] + i = alt[1] + while i > 0: + alt_item = ItemFactory([alt[0]], player)[0] + if alt_item in world.itempool: + world.itempool.remove(alt_item) + i = i-1 + elif 'Bottle' in item.name: + bottle_item = next((x for x in world.itempool if 'Bottle' in item.name and x.player == player), None) + if bottle_item is not None: + world.itempool.remove(bottle_item) if item.dungeon: d = world.get_dungeon(item.dungeon, item.player) match = next((i for i in d.all_items if i.name == item.name), None) @@ -1085,6 +1148,22 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer # print("Placing " + str(nothings) + " Nothings") pool.extend(['Nothing'] * nothings) + start_inventory = [x for x in world.precollected_items if x.player == player] + if not start_inventory: + if world.logic[player] in ['owglitches', 'nologic']: + precollected_items.append('Pegasus Boots') + if 'Pegasus Boots' in pool: + pool.remove('Pegasus Boots') + pool.append('Rupees (20)') + if world.swords[player] == 'assured': + precollected_items.append('Progressive Sword') + if 'Progressive Sword' in pool: + pool.remove('Progressive Sword') + pool.append('Rupees (50)') + elif 'Fighter Sword' in pool: + pool.remove('Fighter Sword') + pool.append('Rupees (50)') + return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) @@ -1206,12 +1285,20 @@ def make_customizer_pool(world, player): if pieces < t: pool.extend(['Triforce Piece'] * (t - pieces)) - ttl_locations = sum(1 for x in world.get_unfilled_locations(player) if '- Prize' not in x.name) - pool_size = len(get_player_dungeon_item_pool(world, player)) + len(pool) - - if pool_size < ttl_locations: - amount_to_add = ttl_locations - pool_size - pool.extend(random.choices(list(filler_items.keys()), filler_items.values(), k=amount_to_add)) + if not world.customizer.get_start_inventory(): + if world.logic[player] in ['owglitches', 'nologic']: + precollected_items.append('Pegasus Boots') + if 'Pegasus Boots' in pool: + pool.remove('Pegasus Boots') + pool.append('Rupees (20)') + if world.swords[player] == 'assured': + precollected_items.append('Progressive Sword') + if 'Progressive Sword' in pool: + pool.remove('Progressive Sword') + pool.append('Rupees (50)') + elif 'Fighter Sword' in pool: + pool.remove('Fighter Sword') + pool.append('Rupees (50)') return pool, placed_items, precollected_items, clock_mode, 1 @@ -1227,9 +1314,9 @@ filler_items = { } -def get_player_dungeon_item_pool(world, player): - return [item for dungeon in world.dungeons for item in dungeon.all_items - if dungeon.player == player and item.location is None] +def count_player_dungeon_item_pool(world, player): + return sum(1 for dungeon in world.dungeons for item in dungeon.all_items + if dungeon.player == player and item.location is None and is_dungeon_item(item.name, world, player)) # location pool doesn't support larger values at this time diff --git a/Main.py b/Main.py index 820cf079..1dc01f14 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.3-u' +__version__ = '1.2.0.4-u' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 21f4a884..54b2edb0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -108,7 +108,11 @@ These are now independent of retro mode and have three options: None, Random, an * Bonk Fairy (Dark) # Bug Fixes and Notes - +* 1.2.0.4-u + * Starting inventory fixes if item not present in the item pool. + * Support for Assured sword setting and OWG Boots when using a custom item pool. (Customizer or GUI) + * Logic fix for the skull woods star tile that lets you into the X pot room. Now accounts for small key or big key door there blocking the way from the star tile. A trap door is not allowed there. + * Standard logic improvement that requires a path from Zelda to the start so that you cannot get softlocked by rescuing Zelda. Standard mirror scroll change may need to be reverted if impossible seed are still generated. * 1.2.0.3-u * Starting inventory taken into account with default item pool. (Custom pools must do this themselves) * Fast ROM update diff --git a/Rom.py b/Rom.py index d210ae01..b0121eea 100644 --- a/Rom.py +++ b/Rom.py @@ -2221,7 +2221,7 @@ def write_strings(rom, world, player, team): hint_candidates = [] for name, district in world.districts[player].items(): hint_type = 'foolish' - choice_set = set() + choices = [] item_count, item_type = 0, 'useful' for loc_name in district.locations: location_item = world.get_location(loc_name, player).item @@ -2231,34 +2231,32 @@ def write_strings(rom, world, player, team): itm_type = 'useful' if useful_item_for_hint(location_item, world) else 'vital' hint_type = 'path' if item_type == itm_type: - choice_set.add(location_item) + choices.append(location_item) item_count += 1 elif itm_type == 'vital': item_type = 'vital' item_count = 1 - choice_set.clear() - choice_set.add(location_item) + choices.clear() + choices.append(location_item) if hint_type == 'foolish': if district.dungeons and world.shuffle[player] != 'vanilla': - choice_set.update(district.dungeons) + choices.extend(district.dungeons) hint_type = 'dungeon_path' elif district.access_points and world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: - choice_set.update([x.hint_text for x in district.access_points]) + choices.extend([x.hint_text for x in district.access_points]) hint_type = 'connector' if hint_type == 'foolish': hint_candidates.append((hint_type, f'{name} is a foolish choice')) elif hint_type == 'dungeon_path': - choices = sorted(list(choice_set)) dungeon_choice = random.choice(choices) # prefer required dungeons... hint_candidates.append((hint_type, f'{name} is on the path to {dungeon_choice}')) elif hint_type == 'connector': - choices = sorted(list(choice_set)) access_point = random.choice(choices) # prefer required access... hint_candidates.append((hint_type, f'{name} can reach {access_point}')) elif hint_type == 'path': if item_count == 1: - the_item = text_for_item(next(iter(choice_set)), world, player, team) + the_item = text_for_item(next(iter(choices)), world, player, team) hint_candidates.append((hint_type, f'{name} conceals only {the_item}')) else: hint_candidates.append((hint_type, f'{name} conceals {item_count} {item_type} items')) diff --git a/Rules.py b/Rules.py index 38ff5666..4bf9cd83 100644 --- a/Rules.py +++ b/Rules.py @@ -124,6 +124,10 @@ def or_rule(rule1, rule2): return lambda state: rule1(state) or rule2(state) +def and_rule(rule1, rule2): + return lambda state: rule1(state) and rule2(state) + + def add_lamp_requirement(spot, player): add_rule(spot, lambda state: state.has('Lamp', player, state.world.lamps_needed_for_dark_rooms)) @@ -277,8 +281,22 @@ def global_rules(world, player): set_rule(world.get_entrance('Skull Big Chest Hookpath', player), lambda state: state.has('Hookshot', player)) set_rule(world.get_entrance('Skull Torch Room WN', player), lambda state: state.has('Fire Rod', player)) set_rule(world.get_entrance('Skull Vines NW', player), lambda state: state.has_sword(player)) - set_rule(world.get_entrance('Skull 2 West Lobby Pits', player), lambda state: state.has_Boots(player) or state.has('Hidden Pits', player)) - set_rule(world.get_entrance('Skull 2 West Lobby Ledge Pits', player), lambda state: state.has('Hidden Pits', player)) + + hidden_pits_door = world.get_door('Skull Small Hall WS', player) + + def hidden_pits_rule(state): + return state.has('Hidden Pits', player) + + if hidden_pits_door.bigKey: + key_logic = world.key_logic[player][hidden_pits_door.entrance.parent_region.dungeon.name] + hidden_pits_rule = and_rule(hidden_pits_rule, create_rule(key_logic.bk_name, player)) + elif hidden_pits_door.smallKey: + d_name = hidden_pits_door.entrance.parent_region.dungeon.name + hidden_pits_rule = and_rule(hidden_pits_rule, eval_small_key_door('Skull Small Hall WS', d_name, player)) + + set_rule(world.get_entrance('Skull 2 West Lobby Pits', player), lambda state: state.has_Boots(player) + or hidden_pits_rule(state)) + set_rule(world.get_entrance('Skull 2 West Lobby Ledge Pits', player), hidden_pits_rule) set_defeat_dungeon_boss_rule(world.get_location('Skull Woods - Boss', player)) set_defeat_dungeon_boss_rule(world.get_location('Skull Woods - Prize', player)) diff --git a/docs/presets/async_doors_league/S3_BombBag.yaml b/docs/presets/async_doors_league/S3_BombBag.yaml index e1f831f6..9edc1803 100644 --- a/docs/presets/async_doors_league/S3_BombBag.yaml +++ b/docs/presets/async_doors_league/S3_BombBag.yaml @@ -2,22 +2,23 @@ meta: players: 1 race: true settings: - shopsanity: true - pseudoboots: true - goal: crystals - crystals_gt: random - bombbag: true - shuffle: crossed - shufflelinks: true - keysanity: true - door_shuffle: crossed - intensity: 3 - door_type_mode: big - pottery: keys - dropshuffle: true - experimental: true - dungeon_counters: 'on' - hints: true - msu_resume: true - collection_rate: true - quickswap: true + 1: + shopsanity: true + pseudoboots: true + goal: crystals + crystals_gt: random + bombbag: true + shuffle: crossed + shufflelinks: true + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: keys + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true diff --git a/docs/presets/async_doors_league/S3_Main.yaml b/docs/presets/async_doors_league/S3_Main.yaml index e8d8f282..564d19d4 100644 --- a/docs/presets/async_doors_league/S3_Main.yaml +++ b/docs/presets/async_doors_league/S3_Main.yaml @@ -2,21 +2,22 @@ meta: players: 1 race: true settings: - shopsanity: true - pseudoboots: true - goal: crystals - crystals_gt: random - shuffle: crossed - shufflelinks: true - keysanity: true - door_shuffle: crossed - intensity: 3 - door_type_mode: big - pottery: keys - dropshuffle: true - experimental: true - dungeon_counters: 'on' - hints: true - msu_resume: true - collection_rate: true - quickswap: true + 1: + shopsanity: true + pseudoboots: true + goal: crystals + crystals_gt: random + shuffle: crossed + shufflelinks: true + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: keys + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true diff --git a/docs/presets/async_doors_league/S3_PotteryLottery.yaml b/docs/presets/async_doors_league/S3_PotteryLottery.yaml index d65e2387..baae256d 100644 --- a/docs/presets/async_doors_league/S3_PotteryLottery.yaml +++ b/docs/presets/async_doors_league/S3_PotteryLottery.yaml @@ -2,21 +2,22 @@ meta: players: 1 race: true settings: - shopsanity: true - pseudoboots: true - goal: crystals - crystals_gt: random - shuffle: crossed - shufflelinks: true - keysanity: true - door_shuffle: crossed - intensity: 3 - door_type_mode: big - pottery: lottery - dropshuffle: true - experimental: true - dungeon_counters: 'on' - hints: true - msu_resume: true - collection_rate: true - quickswap: true + 1: + shopsanity: true + pseudoboots: true + goal: crystals + crystals_gt: random + shuffle: crossed + shufflelinks: true + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: lottery + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py index 205941b5..d0b21d89 100644 --- a/source/dungeon/DungeonStitcher.py +++ b/source/dungeon/DungeonStitcher.py @@ -319,6 +319,8 @@ def determine_paths_for_dungeon(world, player, all_regions, name): if world.mode[player] == 'standard' and name == 'Hyrule Castle Dungeon': paths.append('Hyrule Dungeon Cellblock') paths.append(('Hyrule Dungeon Cellblock', 'Hyrule Castle Throne Room')) + entrance = next(x for x in world.dungeon_portals[player] if x.name == 'Hyrule Castle South') + paths.append(('Hyrule Dungeon Cellblock', entrance.door.entrance.parent_region.name)) if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town': paths.append('Thieves Attic Window') elif 'Thieves Attic Window' in all_r_names: diff --git a/test/customizer/test_stuff.yaml b/test/customizer/test_stuff.yaml new file mode 100644 index 00000000..552d5490 --- /dev/null +++ b/test/customizer/test_stuff.yaml @@ -0,0 +1,28 @@ +meta: + players: 1 + race: true +settings: + 1: + shopsanity: true + pseudoboots: true + goal: crystals + crystals_gt: random + keysanity: true + door_shuffle: crossed + intensity: 3 + door_type_mode: big + pottery: keys + dropshuffle: true + experimental: true + dungeon_counters: 'on' + hints: true + msu_resume: true + collection_rate: true + quickswap: true +start_inventory: + 1: + - Pegasus Boots + - Ocarina (Activated) + - Magic Mirror + - Boss Heart Container + - Blue Mail \ No newline at end of file From fb66ca5607f18778f46a1ea356c864b49898cf58 Mon Sep 17 00:00:00 2001 From: Cody Bailey Date: Sat, 14 Jan 2023 18:27:43 -0500 Subject: [PATCH 105/146] Add Race Yes/No to spoiler output --- BaseClasses.py | 1 + 1 file changed, 1 insertion(+) diff --git a/BaseClasses.py b/BaseClasses.py index 91404ebb..82eb0f37 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2646,6 +2646,7 @@ class Spoiler(object): outfile.write('Enemy health: %s\n' % self.metadata['enemy_health'][player]) outfile.write('Enemy damage: %s\n' % self.metadata['enemy_damage'][player]) outfile.write(f"Hints: {yn(self.metadata['hints'][player])}\n") + outfile.write('Race: %s\n' % ('Yes' if self.world.settings.world_rep['meta']['race'] else 'No')) if self.startinventory: outfile.write('Starting Inventory:'.ljust(line_width)) From a3edbaf8b981a463999e133833c8c9688d90e5b5 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 16 Jan 2023 07:13:44 -0600 Subject: [PATCH 106/146] New non-recursive ER Must-Exit fill algorithm --- EntranceShuffle.py | 194 ++++++++++++++++++++++++++++++++------------- 1 file changed, 140 insertions(+), 54 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index cc0faba9..ef1d36c6 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1478,65 +1478,151 @@ def junk_fill_inaccessible(world, player): def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, player, ignore_list=[]): - invFlag = world.mode[player] == 'inverted' + resolved_regions = list() + inaccessible_regions = list() + def find_inacessible_ow_regions(): + nonlocal inaccessible_regions + find_inaccessible_regions(world, player) + inaccessible_regions = list(world.inaccessible_regions[player]) + + # find OW regions that don't have a multi-entrance dungeon exit connected + glitch_regions = ['Central Cliffs', 'Eastern Cliff', 'Desert Northeast Cliffs', 'Hyrule Castle Water', + 'Dark Central Cliffs', 'Darkness Cliff', 'Mire Northeast Cliffs', 'Pyramid Water'] + multi_dungeon_exits = { + 'Hyrule Castle South Portal', 'Hyrule Castle West Portal', 'Hyrule Castle East Portal', 'Sanctuary Portal', + 'Desert South Portal', 'Desert West Portal', + 'Skull 2 East Portal', 'Skull 2 West Portal', + 'Turtle Rock Main Portal', 'Turtle Rock Lazy Eyes Portal', 'Turtle Rock Eye Bridge Portal' + } + for region_name in world.inaccessible_regions[player]: + if region_name in resolved_regions \ + or (region_name == 'Pyramid Exit Ledge' and (world.shuffle[player] != 'insanity' or world.is_tile_swapped(0x1b, player))) \ + or (region_name == 'Spiral Mimic Ledge Extend' and not world.is_tile_swapped(0x05, player)) \ + or (world.logic[player] in ['noglitches', 'minorglitches'] and region_name in glitch_regions): + # removing irrelevant and resolved regions + inaccessible_regions.remove(region_name) + continue + region = world.get_region(region_name, player) + if region.type not in [RegionType.LightWorld, RegionType.DarkWorld]: + inaccessible_regions.remove(region_name) + continue + if world.shuffle[player] != 'insanity': + for exit in region.exits: + # because dungeon regions haven't been connected yet, the inaccessibility check won't be able to know it's reachable yet + # TODO: Should also cascade to other regions and remove them as inaccessibles + if exit.connected_region and exit.connected_region.name in multi_dungeon_exits: + inaccessible_regions.remove(region_name) + break - if stack_size3a() > 500: - from DungeonGenerator import GenerationException - raise GenerationException(f'Infinite loop detected at \'connect_inaccessible_regions\'') + find_inacessible_ow_regions() - random.shuffle(lw_entrances) - random.shuffle(dw_entrances) - - find_inaccessible_regions(world, player) - - # remove regions that have a dungeon entrance - accessible_regions = list() - for region_name in world.inaccessible_regions[player]: + # keep track of neighboring regions for later consolidation + must_exit_links = OrderedDict() + for region_name in inaccessible_regions: region = world.get_region(region_name, player) - for exit in region.exits: - if exit.connected_region and exit.connected_region.type == RegionType.Dungeon: - accessible_regions.append(region_name) - break - for region_name in accessible_regions.copy(): - accessible_regions = list(OrderedDict.fromkeys(accessible_regions + list(build_accessible_region_list(world, region_name, player, True, True, False, False)))) - world.inaccessible_regions[player] = [r for r in world.inaccessible_regions[player] if r not in accessible_regions] - - # split inaccessible into 2 lists for each world - inaccessible_regions = list(world.inaccessible_regions[player]) + must_exit_links[region_name] = [x.connected_region.name for x in region.exits if x.connected_region and x.connected_region.name in inaccessible_regions] + + # group neighboring regions together, separated by one-ways + def consolidate_group(region): + processed_regions.append(region) + must_exit_links_copy.pop(region) + region_group.append(region) + for dest_region in must_exit_links[region]: + if region in must_exit_links[dest_region]: + if dest_region not in processed_regions: + consolidate_group(dest_region) + else: + one_ways.append(tuple((region, dest_region))) + + processed_regions = list() + must_exit_candidates = list() + one_ways = list() + must_exit_links_copy = must_exit_links.copy() + while len(must_exit_links_copy): + region_group = list() + region_name = next(iter(must_exit_links_copy)) + consolidate_group(region_name) + must_exit_candidates.append(region_group) + + # get available entrances in each group + for regions in must_exit_candidates: + entrances = list() + for region_name in regions: + region = world.get_region(region_name, player) + entrances = entrances + [x.name for x in region.exits if x.spot_type == 'Entrance' and not x.connected_region] + entrances = [e for e in entrances if e in entrance_pool and e not in ignore_list] + must_exit_candidates[must_exit_candidates.index(regions)] = tuple((regions, entrances)) + + # necessary for circular relations between region groups, it will pick the last group + # and fill one of those entrances, and we don't want it to bias the same group + random.shuffle(must_exit_candidates) + + # remove must exit candidates that would be made accessible thru other region groups + def find_group(region): + for group in must_exit_candidates: + regions, _ = group + if region in regions: + return group + raise Exception(f'Could not find region group for {region}') + + def cascade_ignore(group): + nonlocal ignored_regions + regions, _ = group + ignored_regions = ignored_regions + regions + for from_region, to_region in one_ways: + if from_region in regions and to_region not in ignored_regions: + cascade_ignore(find_group(to_region)) + + def process_group(group): + nonlocal processed_regions, ignored_regions + regions, entrances = group + must_exit_candidates_copy.remove(group) + processed_regions = processed_regions + regions + if regions[0] not in ignored_regions: + for from_region, to_region in one_ways: + if to_region in regions and from_region not in ignored_regions + processed_regions: + process_group(find_group(from_region)) # process the parent region group + if regions[0] not in ignored_regions: + # this is the top level region + if len(entrances): + # we will fulfill must exit here and cascade access to children + must_exit_regions.append(group) + cascade_ignore(group) + else: + ignored_regions = ignored_regions + regions + + processed_regions = list() + ignored_regions = list() must_exit_regions = list() - otherworld_must_exit_regions = list() - for region_name in inaccessible_regions.copy(): - region = world.get_region(region_name, player) - if region.type not in [RegionType.LightWorld, RegionType.DarkWorld] or not any((not exit.connected_region and exit.spot_type == 'Entrance') for exit in region.exits) \ - or (region_name == 'Pyramid Exit Ledge' and (world.shuffle[player] != 'insanity' or world.is_tile_swapped(0x1b, player))) \ - or region_name in ['Hyrule Castle Water', 'Pyramid Water']: - inaccessible_regions.remove(region_name) - elif region.type == (RegionType.LightWorld if not invFlag else RegionType.DarkWorld): - must_exit_regions.append(region_name) - elif region.type == (RegionType.DarkWorld if not invFlag else RegionType.LightWorld): - otherworld_must_exit_regions.append(region_name) - - def connect_one(region_name, pool): - inaccessible_entrances = list() - region = world.get_region(region_name, player) - for exit in region.exits: - if not exit.connected_region and exit.name in [e for e in entrance_pool if e not in ignore_list] and (world.shuffle[player] not in ['lite', 'lean'] or exit.name in pool): - inaccessible_entrances.append(exit.name) - if len(inaccessible_entrances): - random.shuffle(inaccessible_entrances) - connect_mandatory_exits(world, pool, caves, [inaccessible_entrances.pop()], player) - connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, player, ignore_list) - - # connect one connector at a time to ensure multiple connectors aren't assigned to the same inaccessible set of regions - pool = [e for e in (lw_entrances if world.shuffle[player] in ['lean', 'crossed', 'insanity'] else dw_entrances) if e in entrance_pool] - if len(otherworld_must_exit_regions) > 0 and len(pool): - random.shuffle(otherworld_must_exit_regions) - connect_one(otherworld_must_exit_regions[0], pool) - elif len(must_exit_regions) > 0: + must_exit_candidates_copy = must_exit_candidates.copy() + while len(must_exit_candidates_copy): + region_group = next(iter(must_exit_candidates_copy)) + process_group(region_group) + + # connect must exits + random.shuffle(must_exit_regions) + must_exits_lw = list() + must_exits_dw = list() + for regions, entrances in must_exit_regions: + region = world.get_region(regions[0], player) + if region.type == RegionType.LightWorld: + must_exits_lw.append(random.choice(entrances)) + else: + must_exits_dw.append(random.choice(entrances)) + if world.shuffle[player] in ['lean', 'crossed', 'insanity']: # cross world + pool = [e for e in lw_entrances + dw_entrances if e in entrance_pool] + connect_mandatory_exits(world, pool, caves, must_exits_lw + must_exits_dw, player) + else: pool = [e for e in lw_entrances if e in entrance_pool] - if len(pool): - random.shuffle(must_exit_regions) - connect_one(must_exit_regions[0], pool) + connect_mandatory_exits(world, pool, caves, must_exits_lw, player) + pool = [e for e in dw_entrances if e in entrance_pool] + connect_mandatory_exits(world, pool, caves, must_exits_dw, player) + + # check accessibility afterwards + find_inacessible_ow_regions() + if len(inaccessible_regions) > 0: + logging.getLogger('').debug(f'Could not resolve inaccessible regions: [{", ".join(inaccessible_regions)}]') + logging.getLogger('').debug(f'^ This is most often a false positive because Dungeon regions aren\'t connected yet') def unbias_some_entrances(Dungeon_Exits, Cave_Exits, Old_Man_House, Cave_Three_Exits): From 34d833b716f8af60f46c931640d1f2919164c31d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 16 Jan 2023 07:14:57 -0600 Subject: [PATCH 107/146] Added Lite/Lean support for Fixed Take-Any caves --- EntranceShuffle.py | 3 +- TestSuiteRandom.pyw | 144 +++++++++++++++++++ TestSuiteStat.py | 330 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 TestSuiteRandom.pyw create mode 100644 TestSuiteStat.py diff --git a/EntranceShuffle.py b/EntranceShuffle.py index ef1d36c6..e48db322 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1471,7 +1471,8 @@ def junk_fill_inaccessible(world, player): inaccessible_entrances.append(exit.name) junk_locations = [e for e in list(zip(*(default_connections + - ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections))))[1] if e in exit_pool] + ([] if world.pottery[player] not in ['none', 'keys', 'dungeon'] else default_pot_connections) + + ([] if world.take_any[player] == 'fixed' else default_takeany_connections))))[1] if e in exit_pool] random.shuffle(junk_locations) for entrance in inaccessible_entrances: connect_entrance(world, entrance, junk_locations.pop(), player) diff --git a/TestSuiteRandom.pyw b/TestSuiteRandom.pyw new file mode 100644 index 00000000..965ca1ee --- /dev/null +++ b/TestSuiteRandom.pyw @@ -0,0 +1,144 @@ +import subprocess +import sys +import multiprocessing +import concurrent.futures +import argparse +import sqlite3 +from collections import OrderedDict +from datetime import datetime + +cpu_threads = multiprocessing.cpu_count() +py_version = f"{sys.version_info.major}.{sys.version_info.minor}" + + +def main(args=None): + successes = [] + errors = [] + task_mapping = [] + tests = OrderedDict() + + max_attempts = 1 #args and args.count if args.count is not None else 1 + print(f"Testing Random OWR with {max_attempts} Tests") + + pool = concurrent.futures.ThreadPoolExecutor(max_workers=cpu_threads) + dead_or_alive = 0 + alive = 0 + + + basecommand = f'py Mystery.py --suppress_rom --suppress_meta --create_spoiler --outputpath L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime("%y%m%d")} --weights L:/_Work/Zelda/ROMs/Bug/Automate/_test.yml' + + def gen_seed(): + return subprocess.run(basecommand, capture_output=True, shell=True, text=True) + + for x in range(1, max_attempts + 1): + task = pool.submit(gen_seed) + task.success = False + task.name = "OWR Random Test" + task.mode = "" + task.cmd = basecommand + task_mapping.append(task) + + from tqdm import tqdm + with tqdm(concurrent.futures.as_completed(task_mapping), + total=len(task_mapping), unit="seed(s)", + desc=f"Success rate: 0.00%") as progressbar: + #with open("L:/_Work/Zelda/ROMs/Bug/Automate/_error_.txt", "a") as ff: + # ff.write("seed") + for task in progressbar: + dead_or_alive += 1 + try: + result = task.result() + if result.returncode: + errors.append([datetime.now(), result.stderr]) + #print(result.stderr) + #print(result.stdout) + else: + alive += 1 + successes.append([datetime.now(), result.stderr]) + task.success = True + except Exception as e: + with open("L:/_Work/Zelda/ROMs/Bug/Automate" + datetime.now().strftime("%y%m%d") + "/_error_.txt", "a") as ff: + exc_type, exc_obj, exc_tb = sys.exc_info() + ff.write(exc_type) + ff.write(exc_tb.tb_lineno) + raise e + + progressbar.set_description(f"Success rate: {(alive/dead_or_alive)*100:.2f}% - {task.name}{task.mode}") + + def get_results(testname: str): + result = "" + dead_or_alive = [task.success for task in task_mapping] + alive = [x for x in dead_or_alive if x] + success = f"Rate: {(len(alive) / len(dead_or_alive)) * 100:.2f}%" + #successes.append(success) + #print(success) + result += f"{(len(alive)/len(dead_or_alive))*100:.2f}%\t" + return result.strip() + + results = [] + results.append(get_results("")) + + #for result in results: + #print(result) + #successes.append(result) + + return successes, errors + + +if __name__ == "__main__": + successes = [] + + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('--count', default=1, type=lambda value: max(int(value), 1)) + parser.add_argument('--cpu_threads', default=cpu_threads, type=lambda value: max(int(value), 1)) + parser.add_argument('--help', default=False, action='store_true') + + args = parser.parse_args() + + if args.help: + parser.print_help() + exit(0) + + cpu_threads = args.cpu_threads + + args = argparse.Namespace() + successes, errors = main(args=args) + # if successes: + # successes += [""] * 2 + # successes += s + # print() + + + if errors: + with open(f"L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime('%y%m%d')}/_error_{datetime.now().strftime('%y%m%d')}.txt", 'a') as stream: + for error in errors: + stream.write("Run at: " + error[0].strftime("%Y-%m-%d %H:%M:%S") + "\n") + stream.write(error[1] + "\n\n") + stream.write("----------------------------------------------------\n") + + if successes: + with open(f"L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime('%y%m%d')}/_success_{datetime.now().strftime('%y%m%d')}.txt", 'a') as stream: + for success in successes: + stream.write("Run at: " + success[0].strftime("%Y-%m-%d %H:%M:%S") + "\n") + stream.write(success[1] + "\n\n") + stream.write("----------------------------------------------------\n") + + # with open(f"L:\\_Work\\Zelda\\ROMs\\Bug\\Automate\\{datetime.now().strftime('%y%m%d')}\\_success.txt", "w") as stream: + # stream.write(str.join("\n", successes)) + + + #conn = sqlite3.connect(f"L:/_Work/Zelda/ROMs/Bug/Automate/{datetime.now().strftime('%y%m%d')}/log.db") + # conn.execute('''CREATE TABLE SEEDGEN + # (SEED INT NOT NULL, + # MYSTERY CHAR(10), + # SETTINGSCODE CHAR(20) NOT NULL, + # VERSION CHAR(10) NOT NULL, + # TIMESTAMP INT NOT NULL, + # SUCCESS INT, + # LOG TEXT);''') + + #input("Press enter to continue") + + #conn.close() + + exit(0) diff --git a/TestSuiteStat.py b/TestSuiteStat.py new file mode 100644 index 00000000..92d066c6 --- /dev/null +++ b/TestSuiteStat.py @@ -0,0 +1,330 @@ +import subprocess +import sys +import multiprocessing +import concurrent.futures +import argparse +from collections import OrderedDict +import csv + +cpu_threads = multiprocessing.cpu_count() +py_version = f"{sys.version_info.major}.{sys.version_info.minor}" + + +ALL_SETTINGS = { + 'mode': ['open', 'standard', 'inverted'], + 'goal': ['ganon', 'pedestal', 'triforcehunt', 'trinity', 'crystals', 'dungeons'], + 'swords': ['random', 'swordless', 'assured'], + 'shuffle': ['vanilla','simple','restricted','full','dungeonssimple','dungeonsfull','lite','lean','crossed','insanity'], + 'shufflelinks': [True, False], + 'shuffleganon': [True, False], + 'door_shuffle': ['vanilla', 'basic', 'crossed'], + 'intensity': ['1','2','3'], + 'ow_shuffle': ['vanilla', 'parallel', 'full'], + 'ow_fluteshuffle': ['vanilla', 'balanced', 'random'], + 'ow_keepsimilar': [True, False], + 'ow_mixed': [True, False], + 'ow_crossed': [True, False], + 'accessibility': [True, False], + 'difficulty': [True, False], + 'shufflepots': [True, False], + 'keydropshuffle': [True, False], + 'keysanity': [True, False], + 'retro': [True, False], + 'bombbag': [True, False], + 'shopsanity': [True, False] +} + +SETTINGS = { + 'mode': ['standard', 'open', 'inverted'], + 'goal': ['ganon'], + 'swords': ['random'], + 'shuffle': ['vanilla', + 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted', 'full', 'lite', 'lean', 'crossed', 'insanity' + ], + 'shufflelinks': [True, False], + 'shuffleganon': [True, False], + 'door_shuffle': ['vanilla', 'crossed'], + 'intensity': ['2'], + 'ow_shuffle': ['vanilla', 'parallel', 'full'], + 'ow_fluteshuffle': ['balanced'], + 'ow_keepsimilar': [True, False], + 'ow_mixed': [True, False], + 'ow_crossed': ['none', 'polar', 'grouped', 'limited'], + 'accessibility': [True], + 'difficulty': [False], + 'shufflepots': [False], + 'keydropshuffle': [False], + 'keysanity': [False], + 'retro': [True, False], + 'bombbag': [False], + 'shopsanity': [True, False] +} + +optionsList = [] +for sett,options in SETTINGS.items(): + for option in options: + if isinstance(option, str): + optionsList.append(f'{option}') + else: + optionsList.append('{}-{}'.format(sett,str(option))) + +headerList = list(SETTINGS.keys()) + +def main(args=None): + successes = [] + errors = [] + task_mapping = [] + tests = OrderedDict() + + successes.append(f"Testing {args.ow} with {args.count} Tests" + (f" (intensity={args.tense})" if args.ow in ['basic', 'crossed'] else "")) + print(successes[0]) + + max_attempts = args.count + pool = concurrent.futures.ThreadPoolExecutor(max_workers=cpu_threads) + dead_or_alive = 0 + alive = 0 + + def test(testname: list, command: str): + tests[' '.join(testname)] = [command] + basecommand = f"py DungeonRandomizer.py --shuffle {args.ow} --suppress_rom --suppress_spoiler" + + def gen_seed(): + taskcommand = basecommand + ' ' + command + return subprocess.run(taskcommand, capture_output=True, shell=True, text=True) + + for _ in range(1, max_attempts + 1): + task = pool.submit(gen_seed) + task.success = False + task.name = ' '.join(testname) + task.settings = testname + task.cmd = basecommand + ' ' + command + task_mapping.append(task) + + for mode in SETTINGS['mode']: + for goal in SETTINGS['goal']: + for swords in SETTINGS['swords']: + #for shuffle in SETTINGS['shuffle']: + for ow_shuffle in SETTINGS['ow_shuffle']: + for shufflelinks in SETTINGS['shufflelinks']: + for shuffleganon in SETTINGS['shuffleganon']: + for door_shuffle in SETTINGS['door_shuffle']: + for intensity in SETTINGS['intensity']: + for ow_fluteshuffle in SETTINGS['ow_fluteshuffle']: + for ow_keepsimilar in SETTINGS['ow_keepsimilar']: + for ow_mixed in SETTINGS['ow_mixed']: + for ow_crossed in SETTINGS['ow_crossed']: + for difficulty in SETTINGS['difficulty']: + for shufflepots in SETTINGS['shufflepots']: + for accessibility in SETTINGS['accessibility']: + for keydropshuffle in SETTINGS['keydropshuffle']: + for keysanity in SETTINGS['keysanity']: + for retro in SETTINGS['retro']: + for bombbag in SETTINGS['bombbag']: + for shopsanity in SETTINGS['shopsanity']: + commands = '' + name = [] + commands = commands + f' --mode {mode}' + name.append(mode) + commands = commands + f' --goal {goal}' + name.append(goal) + commands = commands + f' --swords {swords}' + name.append(swords) + # if shuffle != 'vanilla': #since this is the output is grouped on this, we only want one of these in the loop + # continue + # commands = commands + f' --shuffle {shuffle}' + # name.append(f'ER{shuffle}') + commands = commands + f' --ow_shuffle {ow_shuffle}' + name.append(ow_shuffle) + if shufflelinks: + commands = commands + f' --shufflelinks' + name.append('shufflelinks-True') + else: + name.append('shufflelinks-False') + if shuffleganon: + commands = commands + f' --shuffleganon' + name.append('shuffleganon-True') + else: + name.append('shuffleganon-False') + commands = commands + f' --door_shuffle {door_shuffle}' + name.append(door_shuffle) + if intensity == '3' and door_shuffle == 'vanilla': + continue + commands = commands + f' --intensity {intensity}' + name.append(intensity) + commands = commands + f' --ow_fluteshuffle {ow_fluteshuffle}' + name.append(ow_fluteshuffle) + if difficulty: + commands = commands + f' --difficulty expert' + commands = commands + f' --item_functionality expert' + name.append('difficulty-True') + else: + name.append('difficulty-False') + if ow_keepsimilar: + commands = commands + f' --ow_keepsimilar' + name.append('ow_keepsimilar-True') + else: + if ow_crossed in ['none', 'polar', 'grouped']: + continue + name.append('ow_keepsimilar-False') + if ow_mixed: + commands = commands + f' --ow_mixed' + name.append('ow_mixed-True') + else: + if ow_crossed == 'polar': + continue + name.append('ow_mixed-False') + commands = commands + f' --ow_crossed {ow_crossed}' + name.append(ow_crossed) + if shufflepots: + commands = commands + f' --shufflepots' + name.append('shufflepots-True') + else: + name.append('shufflepots-False') + if not accessibility: + commands = commands + f' --accessibility none' + name.append('accessibility-False') + else: + name.append('accessibility-True') + if keydropshuffle: + commands = commands + f' --keydropshuffle' + name.append('keydropshuffle-True') + else: + name.append('keydropshuffle-False') + if keysanity: + commands = commands + f' --keysanity' + name.append('keysanity-True') + else: + name.append('keysanity-False') + if retro: + commands = commands + f' --retro' + name.append('retro-True') + else: + name.append('retro-False') + if bombbag: + commands = commands + f' --bombbag' + name.append('bombbag-True') + else: + name.append('bombbag-False') + if shopsanity: + commands = commands + f' --shopsanity' + name.append('shopsanity-True') + else: + name.append('shopsanity-False') + test(name, commands) + +# test("Vanilla ", "--futuro --shuffle vanilla") +# test("Basic ", "--futuro --retro --shuffle vanilla") +# test("Keysanity ", "--futuro --shuffle vanilla --keydropshuffle --keysanity") +# test("Simple ", "--futuro --shuffle simple") +# test("Crossed ", "--futuro --shuffle crossed") +# test("Insanity ", "--futuro --shuffle insanity") +# test("CrossKeys ", "--futuro --shuffle crossed --keydropshuffle --keysanity") + + from tqdm import tqdm + with tqdm(concurrent.futures.as_completed(task_mapping), + total=len(task_mapping), unit="seed(s)", + desc=f"Success rate: 0.00%") as progressbar: + for task in progressbar: + dead_or_alive += 1 + try: + result = task.result() + if result.returncode: + errors.append([task.name, task.cmd, result.stderr]) + else: + alive += 1 + task.success = True + except Exception as e: + raise e + + progressbar.set_description(f"Success rate: {(alive/dead_or_alive)*100:.2f}% - {task.name}") + + def get_results(option: str): + result = "" + dead_or_alive = [task.success for task in task_mapping if option in task.settings] + if len(dead_or_alive): + alive = [x for x in dead_or_alive if x] + success = f"{option} Rate: {(len(alive) / len(dead_or_alive)) * 100:.1f}%" + successes.append(success) + print(success) + result += f"{(len(alive)/len(dead_or_alive))*100:.2f}%\t" + else: + success = f"{option} Rate: NULL%" + print(success) + result += f"NULL%\t" + return result.strip() + + results = [] + for option in optionsList: + results.append(get_results(option)) + + for result in results: + successes.append(result) + + tabresultsfile = './output/' + args.ow + '.tsv' + with open(tabresultsfile, 'w+', newline='') as f: + writer = csv.writer(f, delimiter='\t') + header = headerList.copy() + header.append('Success') + writer.writerow(header) + for task in task_mapping: + settings = [] + for option in headerList: + if option in task.settings: + settings.append(1) + elif str(option + '-True') in task.settings: + settings.append(1) + else: + settings.append(0) + if task.success: + settings.append(1) + else: + settings.append(0) + writer.writerow(settings) + + return successes, errors + + +if __name__ == "__main__": + successes = [] + + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('--count', default=0, type=lambda value: max(int(value), 0)) + parser.add_argument('--cpu_threads', default=cpu_threads, type=lambda value: max(int(value), 1)) + parser.add_argument('--help', default=False, action='store_true') + + args = parser.parse_args() + + if args.help: + parser.print_help() + exit(0) + + cpu_threads = args.cpu_threads + +# for ow in [['full', args.count if args.count else 2, 1]]: + # for ow in [['vanilla', args.count if args.count else 2, 1], + # ['parallel', args.count if args.count else 5, 1], + # ['full', args.count if args.count else 10, 1]]: + count = args.count if args.count else 1 + for ow in SETTINGS['shuffle']: + for tense in range(1, 2): #ow[2] + 1): #unnecessary when DR is not the root setting + args = argparse.Namespace() + args.ow = ow #ow[0] + args.tense = tense + args.count = count #ow[1] + s, errors = main(args=args) + if successes: + successes += [""] * 2 + successes += s + print() + + if errors: + with open(f"./output/{ow[0]}{(f'-{tense}' if ow in ['parallel', 'full'] else '')}-errors.txt", 'w+') as stream: + for error in errors: + stream.write(error[0] + "\n") + stream.write(error[1] + "\n") + stream.write(error[2] + "\n\n") + + with open("./output/success.txt", "w+") as stream: + stream.write(str.join("\n", successes)) + + input("Press enter to continue") From 4547a0a43baddb3b399e33300d58e1941078f4f7 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 18 Jan 2023 08:02:32 -0700 Subject: [PATCH 108/146] Logic fix for sanc mirror route Minor updates to customizer Minor update to new ER (seed duplication issue) --- DoorShuffle.py | 25 ++++++++++++++++--------- Doors.py | 2 ++ ItemList.py | 3 ++- Main.py | 2 +- RELEASENOTES.md | 3 +++ source/overworld/EntranceShuffle2.py | 2 +- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index d4d94905..bb175461 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -551,7 +551,7 @@ def customizer_portals(master_door_list, world, player): if isinstance(dest, str): door = world.get_door(dest, player) assigned_doors.add(door) - else: + elif 'dest' in dest: door = world.get_door(dest['dest'], player) assigned_doors.add(door) return custom_portals, assigned_doors @@ -1708,8 +1708,8 @@ def setup_custom_door_types(world, player): if d.type == DoorType.SpiralStairs: type_map[door_kind][dungeon.name].append(d) else: - # check if the - if d.dest.type in [DoorType.Interior, DoorType.Normal]: + # check if the dest is paired + if d.dest.type in [DoorType.Interior, DoorType.Normal] and door_kind != 'Trap Door': type_map[door_kind][dungeon.name].append((d, d.dest)) else: type_map[door_kind][dungeon.name].append(d) @@ -1852,10 +1852,11 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, ttl += len(builder.candidates.big) if ttl == 0: continue + remaining = max(0, remaining) for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] proportion = len(builder.candidates.big) - calc = int(round(proportion * door_type_pool.bigs/ttl)) + calc = int(round(proportion * remaining/ttl)) suggested = min(proportion, calc) remaining -= suggested suggestion_map[dungeon] = suggested @@ -1909,12 +1910,15 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl if not total_adjustable: builder.total_keys = total_keys find_small_key_door_candidates(builder, start_regions_map[dungeon], used_doors, world, player) + custom_doors = 0 if custom_key_doors[dungeon]: builder.candidates.small = filter_key_door_pool(builder.candidates.small, custom_key_doors[dungeon]) - remaining -= len(custom_key_doors[dungeon]) - builder.key_doors_num = max(0, len(builder.candidates.small) - builder.key_drop_cnt) + custom_doors = len(custom_key_doors[dungeon]) + remaining -= custom_doors + builder.key_doors_num = max(0, len(builder.candidates.small) - builder.key_drop_cnt) + custom_doors total_keys -= builder.key_drop_cnt ttl += builder.key_doors_num + remaining = max(0, remaining) for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] calculated = int(round(builder.key_doors_num*total_keys/ttl)) @@ -1922,7 +1926,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl cand_len = max(0, len(builder.candidates.small) - builder.key_drop_cnt) limit = min(max_keys, cand_len, max_computation) suggested = min(calculated, limit) - key_door_num = min(suggested + builder.key_drop_cnt, max_computation) + key_door_num = min(suggested + builder.key_drop_cnt, max_computation) combo_size = ncr(len(builder.candidates.small), key_door_num) while combo_size > 500000 and suggested > 0: suggested -= 1 @@ -2142,6 +2146,7 @@ def find_valid_trap_combination(builder, suggested, start_regions, paths, world, if custom_trap_doors: trap_door_pool = filter_key_door_pool(trap_door_pool, custom_trap_doors) trap_doors_needed -= len(custom_trap_doors) + trap_doors_needed = max(0, trap_doors_needed) if len(trap_door_pool) < trap_doors_needed: if not drop: return None, 0 @@ -2420,6 +2425,7 @@ def find_valid_bk_combination(builder, suggested, start_regions, world, player, if custom_bk_doors: bk_door_pool = filter_key_door_pool(bk_door_pool, custom_bk_doors) bk_doors_needed -= len(custom_bk_doors) + bk_doors_needed = max(0, bk_doors_needed) if len(bk_door_pool) < bk_doors_needed: if not drop: return None, 0 @@ -2559,7 +2565,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k if custom_key_doors: # could validate that each custom item is in the candidates key_door_pool = filter_key_door_pool(key_door_pool, custom_key_doors) key_doors_needed -= len(custom_key_doors) - + key_doors_needed = max(0, key_doors_needed) # find valid combination of candidates if len(key_door_pool) < key_doors_needed: if not drop_keys: @@ -2574,6 +2580,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k sample_list = build_sample_list(combinations) proposal = kth_combination(sample_list[itr], key_door_pool, key_doors_needed) proposal.extend(custom_key_doors) + builder.key_doors_num = len(proposal) start_regions, event_starts = filter_start_regions(builder, start_regions, world, player) key_layout = build_key_layout(builder, start_regions, proposal, event_starts, world, player) @@ -2606,7 +2613,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k builder.key_door_proposal = proposal world.key_logic[player][builder.name] = key_layout.key_logic world.key_layout[player][builder.name] = key_layout - return builder.key_door_proposal, key_doors_needed + return builder.key_door_proposal, key_doors_needed + len(custom_key_doors) def find_bd_candidates(builder, start_regions, used, world, player): diff --git a/Doors.py b/Doors.py index 7c9e5ca6..110ca5c9 100644 --- a/Doors.py +++ b/Doors.py @@ -1473,6 +1473,8 @@ def create_doors(world, player): world.get_door('GT Spike Crystal Right to Left Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('GT Spike Crystal Left to Right Bypass', player).barrier(CrystalBarrier.Blue) + world.get_door('Sanctuary Mirror Route', player).barrier(CrystalBarrier.Orange) + # kill certain doors if world.intensity[player] == 1: # due to ladder & warp being fixed world.get_door('PoD Mimics 2 SW', player).kill() diff --git a/ItemList.py b/ItemList.py index 4bbd0f32..cac01f3f 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1383,7 +1383,8 @@ def fill_specific_items(world): world.push_item(loc, item_to_place, False) track_outside_keys(item_to_place, loc, world) track_dungeon_items(item_to_place, loc, world) - loc.event = event_flag or item_to_place.advancement + loc.event = (event_flag or item_to_place.advancement + or item_to_place.bigkey or item_to_place.smallkey) advanced_placements = world.customizer.get_advanced_placements() if advanced_placements: for player, placement_list in advanced_placements.items(): diff --git a/Main.py b/Main.py index 1dc01f14..40e6c702 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.4-u' +__version__ = '1.2.0.5-u' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 54b2edb0..095682e0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -108,6 +108,9 @@ These are now independent of retro mode and have three options: None, Random, an * Bonk Fairy (Dark) # Bug Fixes and Notes +* 1.2.0.5.u + * Logic fix for Sanctuary mirror (it wasn't resetting the crystal state) + * Minor bugfixes for customizer * 1.2.0.4-u * Starting inventory fixes if item not present in the item pool. * Support for Assured sword setting and OWG Boots when using a custom item pool. (Customizer or GUI) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 0a9e206a..d5df982a 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -311,7 +311,7 @@ def do_main_shuffle(entrances, exits, avail, mode_def): unused_entrances.update(lw_entrances) unused_entrances.update(dw_entrances) else: - entrance_list = [x for x in rem_entrances if bonk_fairy_exception(x)] + entrance_list = sorted([x for x in rem_entrances if bonk_fairy_exception(x)]) do_cross_world_connectors(entrance_list, multi_exit_caves, avail) unused_entrances.update(entrance_list) From 3ae853fa23b4a36e2321107f493276830652c954 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Thu, 19 Jan 2023 08:24:08 -0600 Subject: [PATCH 109/146] New non-recursive ER Must-Exit fill algorithm --- EntranceShuffle.py | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index e48db322..668faf0c 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1479,8 +1479,6 @@ def junk_fill_inaccessible(world, player): def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, player, ignore_list=[]): - resolved_regions = list() - inaccessible_regions = list() def find_inacessible_ow_regions(): nonlocal inaccessible_regions find_inaccessible_regions(world, player) @@ -1496,10 +1494,9 @@ def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, playe 'Turtle Rock Main Portal', 'Turtle Rock Lazy Eyes Portal', 'Turtle Rock Eye Bridge Portal' } for region_name in world.inaccessible_regions[player]: - if region_name in resolved_regions \ + if (world.logic[player] in ['noglitches', 'minorglitches'] and region_name in glitch_regions) \ or (region_name == 'Pyramid Exit Ledge' and (world.shuffle[player] != 'insanity' or world.is_tile_swapped(0x1b, player))) \ - or (region_name == 'Spiral Mimic Ledge Extend' and not world.is_tile_swapped(0x05, player)) \ - or (world.logic[player] in ['noglitches', 'minorglitches'] and region_name in glitch_regions): + or (region_name == 'Spiral Mimic Ledge Extend' and not world.is_tile_swapped(0x05, player)): # removing irrelevant and resolved regions inaccessible_regions.remove(region_name) continue @@ -1510,11 +1507,12 @@ def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, playe if world.shuffle[player] != 'insanity': for exit in region.exits: # because dungeon regions haven't been connected yet, the inaccessibility check won't be able to know it's reachable yet - # TODO: Should also cascade to other regions and remove them as inaccessibles if exit.connected_region and exit.connected_region.name in multi_dungeon_exits: - inaccessible_regions.remove(region_name) + resolved_regions.append(region_name) break + inaccessible_regions = list() + resolved_regions = list() find_inacessible_ow_regions() # keep track of neighboring regions for later consolidation @@ -1585,12 +1583,15 @@ def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, playe process_group(find_group(from_region)) # process the parent region group if regions[0] not in ignored_regions: # this is the top level region - if len(entrances): - # we will fulfill must exit here and cascade access to children - must_exit_regions.append(group) + if any(r in resolved_regions for r in regions): cascade_ignore(group) else: - ignored_regions = ignored_regions + regions + if len(entrances): + # we will fulfill must exit here and cascade access to children + must_exit_regions.append(group) + cascade_ignore(group) + else: + ignored_regions = ignored_regions + regions processed_regions = list() ignored_regions = list() @@ -1611,16 +1612,21 @@ def connect_inaccessible_regions(world, lw_entrances, dw_entrances, caves, playe else: must_exits_dw.append(random.choice(entrances)) if world.shuffle[player] in ['lean', 'crossed', 'insanity']: # cross world - pool = [e for e in lw_entrances + dw_entrances if e in entrance_pool] + pool = [e for e in lw_entrances + dw_entrances if e in entrance_pool and e not in must_exits_lw + must_exits_dw] connect_mandatory_exits(world, pool, caves, must_exits_lw + must_exits_dw, player) else: - pool = [e for e in lw_entrances if e in entrance_pool] - connect_mandatory_exits(world, pool, caves, must_exits_lw, player) - pool = [e for e in dw_entrances if e in entrance_pool] - connect_mandatory_exits(world, pool, caves, must_exits_dw, player) + pool = [e for e in lw_entrances if e in entrance_pool and e not in must_exits_lw] + if len(pool): + connect_mandatory_exits(world, pool, caves, must_exits_lw, player) + pool = [e for e in dw_entrances if e in entrance_pool and e not in must_exits_dw] + if len(pool): + connect_mandatory_exits(world, pool, caves, must_exits_dw, player) # check accessibility afterwards + resolved_regions = list() find_inacessible_ow_regions() + inaccessible_regions = [e for e in inaccessible_regions if e not in resolved_regions] + # TODO: Instead of line above, this should cascade from the resolved regions down to regions it can access if len(inaccessible_regions) > 0: logging.getLogger('').debug(f'Could not resolve inaccessible regions: [{", ".join(inaccessible_regions)}]') logging.getLogger('').debug(f'^ This is most often a false positive because Dungeon regions aren\'t connected yet') From 5cde789b434a4c0ab3ecb2b9b4f68fd9fda8b157 Mon Sep 17 00:00:00 2001 From: Cody Bailey Date: Thu, 19 Jan 2023 20:02:49 -0500 Subject: [PATCH 110/146] Potential fix for duped HC/AT Maps/Compasses --- DoorShuffle.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index bb175461..4fa84b78 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -797,15 +797,18 @@ def main_dungeon_pool(dungeon_pool, world, player): hc = world.get_dungeon('Hyrule Castle', player) hc_compass = ItemFactory('Compass (Escape)', player) hc_compass.advancement = world.restrict_boss_items[player] != 'none' - hc.dungeon_items.append(hc_compass) + if hc.dungeon_items.count(hc_compass) < 1: + hc.dungeon_items.append(hc_compass) if 'Agahnims Tower' in pool: at = world.get_dungeon('Agahnims Tower', player) at_compass = ItemFactory('Compass (Agahnims Tower)', player) at_compass.advancement = world.restrict_boss_items[player] != 'none' - at.dungeon_items.append(at_compass) + if at.dungeon_items.count(at_compass) < 1: + at.dungeon_items.append(at_compass) at_map = ItemFactory('Map (Agahnims Tower)', player) at_map.advancement = world.restrict_boss_items[player] != 'none' - at.dungeon_items.append(at_map) + if at.dungeon_items.count(at_map) < 1: + at.dungeon_items.append(at_map) sector_pool = convert_to_sectors(region_list, world, player) merge_sectors(sector_pool, world, player) # todo: which dungeon to create @@ -1237,10 +1240,13 @@ def cross_dungeon(world, player): if world.restrict_boss_items[player] != 'none': hc_compass.advancement = at_compass.advancement = at_map.advancement = True hc = world.get_dungeon('Hyrule Castle', player) - hc.dungeon_items.append(hc_compass) + if hc.dungeon_items.count(hc_compass) < 1: + hc.dungeon_items.append(hc_compass) at = world.get_dungeon('Agahnims Tower', player) - at.dungeon_items.append(at_compass) - at.dungeon_items.append(at_map) + if at.dungeon_items.count(at_compass) < 1: + at.dungeon_items.append(at_compass) + if at.dungeon_items.count(at_map) < 1: + at.dungeon_items.append(at_map) setup_custom_door_types(world, player) assign_cross_keys(dungeon_builders, world, player) From f67cf929f75386e4fca2db6f9695723caca5660f Mon Sep 17 00:00:00 2001 From: Kris Davie Date: Sun, 22 Jan 2023 11:13:40 +0100 Subject: [PATCH 111/146] Enable `settingsfile` for multiworld generation --- CLI.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CLI.py b/CLI.py index cfb3f2eb..0bbf1181 100644 --- a/CLI.py +++ b/CLI.py @@ -122,6 +122,11 @@ def parse_cli(argv, no_defaults=False): defaults = copy.deepcopy(ret) for player in range(1, player_num + 1): playerargs = parse_cli(shlex.split(getattr(ret, f"p{player}")), True) + + if playerargs.filename: + playersettings = apply_settings_file({}, playerargs.filename) + for k, v in playersettings.items(): + setattr(playerargs, k, v) for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'flute_mode', 'bow_mode', 'take_any', 'boots_hint', From 04a9bcc68b4ebba9764d35cf95828f09c548a1d9 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 27 Jan 2023 15:21:22 -0700 Subject: [PATCH 112/146] Fix for free light cone in escape. No longer missing when entering from DW. No longer disappears after using fire rod to light torch. --- Main.py | 2 +- RELEASENOTES.md | 3 +++ Rom.py | 2 +- data/base2current.bps | Bin 93506 -> 93487 bytes 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Main.py b/Main.py index 40e6c702..a412220e 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.5-u' +__version__ = '1.2.0.6-u' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 095682e0..3ee20968 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -108,6 +108,9 @@ These are now independent of retro mode and have three options: None, Random, an * Bonk Fairy (Dark) # Bug Fixes and Notes +* 1.2.0.6-u + * Fix for light cone in Escape when entering from Dark World post-zelda + * Fix for light cone in Escape when lighting a torch with fire rod * 1.2.0.5.u * Logic fix for Sanctuary mirror (it wasn't resetting the crystal state) * Minor bugfixes for customizer diff --git a/Rom.py b/Rom.py index b0121eea..54d801bd 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '1e1094919d6a9dd151f8bc15c40b35f7' +RANDOMIZERBASEHASH = '4eeafc915838a7c9c5eff7a1b53d4709' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 271b2c2e5bd56abf7e11615aee052723186d40f8..3afa29d0716c0797214cc3ce5204a82e3c8f5ff5 100644 GIT binary patch delta 9372 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 delta 9305 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 Date: Sat, 28 Jan 2023 11:51:42 -0700 Subject: [PATCH 113/146] Fix for starting with plain Ocarina (Inactived version) --- InitialSram.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InitialSram.py b/InitialSram.py index 8d0ade11..67c7dc83 100644 --- a/InitialSram.py +++ b/InitialSram.py @@ -142,8 +142,8 @@ class InitialSram: 'Big Key (Misery Mire)': (0x367, 0x01), 'Compass (Misery Mire)': (0x365, 0x01), 'Map (Misery Mire)': (0x369, 0x01), 'Big Key (Turtle Rock)': (0x366, 0x08), 'Compass (Turtle Rock)': (0x364, 0x08), 'Map (Turtle Rock)': (0x368, 0x08), 'Big Key (Ganons Tower)': (0x366, 0x04), 'Compass (Ganons Tower)': (0x364, 0x04), 'Map (Ganons Tower)': (0x368, 0x04)} - set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02),'Pegasus Boots': (0x355, 1, 0x379, 0x04), - 'Shovel': (0x34C, 1, 0x38C, 0x04), 'Ocarina': (0x34C, 3, 0x38C, 0x01), + set_or_table = {'Flippers': (0x356, 1, 0x379, 0x02), 'Pegasus Boots': (0x355, 1, 0x379, 0x04), + 'Shovel': (0x34C, 1, 0x38C, 0x04), 'Ocarina': (0x34C, 2, 0x38C, 0x02), 'Ocarina (Activated)': (0x34C, 3, 0x38C, 0x01), 'Mushroom': (0x344, 1, 0x38C, 0x20 | 0x08), 'Magic Powder': (0x344, 2, 0x38C, 0x10), 'Blue Boomerang': (0x341, 1, 0x38C, 0x80), 'Red Boomerang': (0x341, 2, 0x38C, 0x40)} From 4714e411b8619411a3254237b833675099b5c00c Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 30 Jan 2023 16:28:56 -0600 Subject: [PATCH 114/146] Fix issue with placing Dark Chapel in proper world --- EntranceShuffle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 668faf0c..88f707f9 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1368,7 +1368,7 @@ def place_links_house(world, player, ignore_list=[]): def place_dark_sanc(world, player, ignore_list=[]): if not world.shufflelinks[player]: - sanc_doors = [i for i in get_distant_entrances(world, 'Big Bomb Shop', player) if i in entrance_pool] + sanc_doors = [i for i in get_distant_entrances(world, 'Big Bomb Shop' if world.is_bombshop_start(player) else 'Links House', player) if i in entrance_pool] else: sanc_doors = [i for i in get_starting_entrances(world, player, world.shuffle[player] != 'insanity') if i in entrance_pool] if world.shuffle[player] in ['lite', 'lean']: From 7c75053cc1309a2fa6dafc5d754b6348bc212e4d Mon Sep 17 00:00:00 2001 From: aerinon Date: Mon, 30 Jan 2023 15:31:43 -0700 Subject: [PATCH 115/146] Fix for vanilla mire key logic --- BaseClasses.py | 9 +++++++++ Fill.py | 5 +++++ source/overworld/EntranceShuffle2.py | 15 +++++++++------ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 82eb0f37..ec04d679 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -743,6 +743,15 @@ class CollectionState(object): rrp[k] = missing_regions[k] possible_path = terminal_states[0].path[k] self.path[k] = paths[k] = possible_path + for conn in k.exits: + if self.is_small_door(conn): + door = conn.door if conn.door.smallKey else conn.door.controller + key_logic = self.world.key_logic[player][dungeon_name] + if door.name not in self.reached_doors[player]: + self.door_counter[player][0][dungeon_name] += 1 + self.reached_doors[player].add(door.name) + if key_logic.sm_doors[door]: + self.reached_doors[player].add(key_logic.sm_doors[door].name) missing_bc = {} for blocked, crystal in common_bc.items(): if (blocked not in bc and blocked.parent_region in rrp diff --git a/Fill.py b/Fill.py index 0cee1ab3..321e1a8e 100644 --- a/Fill.py +++ b/Fill.py @@ -380,6 +380,11 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None random.shuffle(fill_locations) random.shuffle(world.itempool) + if world.item_pool_config.preferred: + pref = list(world.item_pool_config.preferred.keys()) + pref_len = len(pref) + world.itempool.sort(key=lambda i: pref_len - pref.index((i.name, i.player)) + if (i.name, i.player) in world.item_pool_config.preferred else 0) progitempool = [item for item in world.itempool if item.advancement] prioitempool = [item for item in world.itempool if not item.advancement and item.priority] restitempool = [item for item in world.itempool if not item.advancement and not item.priority] diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index d5df982a..e6c5a13a 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -1022,12 +1022,15 @@ def connect_custom(avail_pool, world, player): if world.customizer and world.customizer.get_entrances(): custom_entrances = world.customizer.get_entrances() player_key = player - for ent_name, exit_name in custom_entrances[player_key]['two-way'].items(): - connect_two_way(ent_name, exit_name, avail_pool) - for ent_name, exit_name in custom_entrances[player_key]['entrances'].items(): - connect_entrance(ent_name, exit_name, avail_pool) - for ent_name, exit_name in custom_entrances[player_key]['exits'].items(): - connect_exit(exit_name, ent_name, avail_pool) + if 'two-way' in custom_entrances[player_key]: + for ent_name, exit_name in custom_entrances[player_key]['two-way'].items(): + connect_two_way(ent_name, exit_name, avail_pool) + if 'entrances' in custom_entrances[player_key]: + for ent_name, exit_name in custom_entrances[player_key]['entrances'].items(): + connect_entrance(ent_name, exit_name, avail_pool) + if 'exits' in custom_entrances[player_key]: + for ent_name, exit_name in custom_entrances[player_key]['exits'].items(): + connect_exit(exit_name, ent_name, avail_pool) def connect_simple(world, exit_name, region_name, player): From d68d821e068495c7afe8f6d887ab3117232f1bbe Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 3 Feb 2023 13:50:00 -0600 Subject: [PATCH 116/146] Fixed Bomb Shop to not exit at Spec Rock Ledges in Inverted --- EntranceShuffle.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 88f707f9..cb1a5bf2 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -210,6 +210,8 @@ def link_entrances(world, player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + if world.is_tile_swapped(0x03, player): + bomb_shop_doors = [x for x in bomb_shop_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] bomb_shop = random.choice(bomb_shop_doors) connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) @@ -256,6 +258,8 @@ def link_entrances(world, player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + if world.is_tile_swapped(0x03, player): + bomb_shop_doors = [x for x in bomb_shop_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] bomb_shop = random.choice(bomb_shop_doors) connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) @@ -314,6 +318,8 @@ def link_entrances(world, player): bomb_shop_doors = [e for e in entrance_pool if e not in list(zip(*drop_connections + dropexit_connections))[0]] if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in bomb_shop_doors if e not in ['Pyramid Fairy']] + if world.is_tile_swapped(0x03, player): + bomb_shop_doors = [x for x in bomb_shop_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] bomb_shop = random.choice(bomb_shop_doors) connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) @@ -418,6 +424,8 @@ def link_entrances(world, player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + if world.is_tile_swapped(0x03, player): + bomb_shop_doors = [x for x in bomb_shop_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] bomb_shop = random.choice(bomb_shop_doors) connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) @@ -476,6 +484,8 @@ def link_entrances(world, player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + if world.is_tile_swapped(0x03, player): + bomb_shop_doors = [x for x in bomb_shop_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] bomb_shop = random.choice(bomb_shop_doors) connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) @@ -526,6 +536,8 @@ def link_entrances(world, player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + if world.is_tile_swapped(0x03, player): + bomb_shop_doors = [x for x in bomb_shop_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] bomb_shop = random.choice(bomb_shop_doors) connect_entrance(world, bomb_shop, 'Big Bomb Shop', player) @@ -610,6 +622,8 @@ def link_entrances(world, player): bomb_shop_doors = list(entrance_pool) if world.logic[player] in ['noglitches', 'minorglitches'] or world.is_tile_swapped(0x1b, player): bomb_shop_doors = [e for e in entrance_pool if e not in ['Pyramid Fairy']] + if world.is_tile_swapped(0x03, player): + bomb_shop_doors = [x for x in bomb_shop_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] random.shuffle(bomb_shop_doors) bomb_shop = bomb_shop_doors.pop() pool.remove(bomb_shop) @@ -1348,6 +1362,8 @@ def place_links_house(world, player, ignore_list=[]): links_house_doors = [i for i in get_distant_entrances(world, dark_sanc, player) if i in entrance_pool] else: links_house_doors = [i for i in get_starting_entrances(world, player, world.shuffle[player] != 'insanity') if i in entrance_pool] + if world.is_bombshop_start(player) and world.is_tile_swapped(0x03, player): + links_house_doors = [x for x in links_house_doors if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] if world.shuffle[player] in ['lite', 'lean']: links_house_doors = [e for e in links_house_doors if e in list(zip(*(default_item_connections + (default_shop_connections if world.shopsanity[player] else []) + From fb13785abc87fc6cb9b1c209be6e37dfdfd5d927 Mon Sep 17 00:00:00 2001 From: aerinon Date: Mon, 6 Feb 2023 13:46:25 -0700 Subject: [PATCH 117/146] Minor standard generation fix Minor ER + Partitioned fix --- DoorShuffle.py | 4 ++-- Doors.py | 1 + Main.py | 2 +- RELEASENOTES.md | 6 ++++++ source/overworld/EntranceShuffle2.py | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 4fa84b78..e4d4a7be 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -476,14 +476,14 @@ def choose_portals(world, player): info.required_passage = {x: y for x, y in info.required_passage.items() if len(y) > 0} for target_region, possible_portals in info.required_passage.items(): candidates = find_portal_candidates(master_door_list, dungeon, custom, allowed, need_passage=True, - bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) + bk_shuffle=bk_shuffle, standard=std_flag, rupee_bow=rupee_bow_flag) choice, portal = assign_portal(candidates, possible_portals, custom, world, player) portal.destination = True clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals) dead_end_choices = info.total - 1 - len(portal_assignment[dungeon]) for i in range(0, dead_end_choices): candidates = find_portal_candidates(master_door_list, dungeon, custom, allowed, dead_end_allowed=True, - bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag) + bk_shuffle=bk_shuffle, standard=std_flag, rupee_bow=rupee_bow_flag) possible_portals = outstanding_portals if not info.sole_entrance else [x for x in outstanding_portals if x != info.sole_entrance] choice, portal = assign_portal(candidates, possible_portals, custom, world, player) if choice.deadEnd: diff --git a/Doors.py b/Doors.py index 110ca5c9..edc51ac0 100644 --- a/Doors.py +++ b/Doors.py @@ -1521,6 +1521,7 @@ def create_doors(world, player): world.get_door("GT Bob\'s Room SE", player).passage = False world.get_door('Desert Tiles 2 SE', player).bk_shuffle_req = True # key-drop note: allows this to be a portal world.get_door('Swamp Lobby S', player).standard_restricted = True + world.get_door('Sanctuary S', player).standard_restricted = True world.get_door('PoD Mimics 2 SW', player).rupee_bow_restricted = True # bow statue # enemizer logic could get rid of the following restriction world.get_door('PoD Pit Room S', player).rupee_bow_restricted = True # so mimics 1 shouldn't be required diff --git a/Main.py b/Main.py index a412220e..02b7d032 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.6-u' +__version__ = '1.2.0.7-u' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3ee20968..597cdc2f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -108,6 +108,12 @@ These are now independent of retro mode and have three options: None, Random, an * Bonk Fairy (Dark) # Bug Fixes and Notes +* 1.2.0.7-u + * Fix for some misery mire key logic + * Minor standard generation fix + * Fix for inactive flute start + * Settingsfile for multiworld generation support + * Fix for duped HC/AT Maps/Compasses * 1.2.0.6-u * Fix for light cone in Escape when entering from Dark World post-zelda * Fix for light cone in Escape when lighting a torch with fire rod diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index e6c5a13a..a364530c 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -632,7 +632,7 @@ def do_fixed_shuffle(avail, entrance_list): rules = Restrictions() rules.size = size if ('Hyrule Castle Entrance (South)' in entrances and - avail.world.doorShuffle[avail.player] in ['basic', 'crossed']): + avail.world.doorShuffle[avail.player] != 'vanilla'): rules.must_exit_to_lw = True if 'Inverted Ganons Tower' in entrances and not avail.world.shuffle_ganon: rules.fixed = True From 9bf73159045601238015de013235f6392db55e2b Mon Sep 17 00:00:00 2001 From: Thomas Prescott Date: Thu, 9 Feb 2023 13:08:36 -0600 Subject: [PATCH 118/146] Remove a bad triforce text It was brought up on the ALTTPR Discord that this Triforce text can feel really bad to see at the end of a long race. I think it's best we give it a permanent vacation. --- Text.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Text.py b/Text.py index 4da86b4c..27d27f1d 100644 --- a/Text.py +++ b/Text.py @@ -91,7 +91,6 @@ Triforce_texts = [ 'Who stole the fourth triangle?', 'Trifource?\nMore Like Tritrice, am I right?' '\n Well Done!', - 'You just wasted 2 hours of your life.', 'This was meant to be a trapezoid', # these ones are from web randomizer "\n G G", From 142b82a2619a65b9f8ee8ee136f72f8b0e75cc18 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 10 Feb 2023 13:47:58 -0700 Subject: [PATCH 119/146] BK door fix --- DoorShuffle.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DoorShuffle.py b/DoorShuffle.py index e4d4a7be..a4cf7397 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -2493,6 +2493,8 @@ def reassign_big_key_doors(bk_map, world, player): if d1.type is DoorType.Interior: change_door_to_big_key(d1, world, player) d2.bigKey = True # ensure flag is set + if d2.smallKey: + d2.smallKey = False else: world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) change_door_to_big_key(d1, world, player) @@ -2521,6 +2523,8 @@ def reassign_big_key_doors(bk_map, world, player): def change_door_to_big_key(d, world, player): d.bigKey = True + if d.smallKey: + d.smallKey = False room = world.get_room(d.roomIndex, player) if room.doorList[d.doorListPos][1] != DoorKind.BigKey: verify_door_list_pos(d, room, world, player) From a304fd31acb0819a1eb1194b1a9497983ebfb40a Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 14 Feb 2023 15:58:52 -0700 Subject: [PATCH 120/146] Standard keysanity distribution and generation fixes Includes new S&Q safety --- BaseClasses.py | 6 ++-- DungeonGenerator.py | 13 ++++++-- Fill.py | 36 +++++++++++++++++----- KeyDoorShuffle.py | 48 +++++++++++++++++++----------- Rom.py | 2 +- Rules.py | 2 +- data/base2current.bps | Bin 93487 -> 93523 bytes source/dungeon/DungeonStitcher.py | 12 +++++++- 8 files changed, 86 insertions(+), 33 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index ec04d679..c2da8e91 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1423,10 +1423,10 @@ class Region(object): or (item.bigkey and not self.world.bigkeyshuffle[item.player]) or (item.map and not self.world.mapshuffle[item.player]) or (item.compass and not self.world.compassshuffle[item.player])) - sewer_hack = self.world.mode[item.player] == 'standard' and item.name == 'Small Key (Escape)' - if sewer_hack or inside_dungeon_item: + # not all small keys to escape must be in escape + # sewer_hack = self.world.mode[item.player] == 'standard' and item.name == 'Small Key (Escape)' + if inside_dungeon_item: return self.dungeon and self.dungeon.is_dungeon_item(item) and item.player == self.player - return True def __str__(self): diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 2140520e..8231833b 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -772,6 +772,13 @@ def connect_simple_door(exit_door, region): special_big_key_doors = ['Hyrule Dungeon Cellblock Door', "Thieves Blind's Cell Door"] +std_special_big_key_doors = ['Hyrule Castle Throne Room Tapestry'] + special_big_key_doors + + +def get_special_big_key_doors(world, player): + if world.mode[player] == 'standard': + return std_special_big_key_doors + return special_big_key_doors class ExplorationState(object): @@ -1002,7 +1009,8 @@ class ExplorationState(object): if self.can_traverse(door): if door.controller: door = door.controller - if (door in big_key_door_proposal or door.name in special_big_key_doors) and not self.big_key_opened: + if (door in big_key_door_proposal + or door.name in get_special_big_key_doors(world, player)) and not self.big_key_opened: if not self.in_door_list(door, self.big_doors): self.append_door_to_list(door, self.big_doors) elif door.req_event is not None and door.req_event not in self.events: @@ -3554,7 +3562,8 @@ def check_for_valid_layout(builder, sector_list, builder_info): split_list['Sewers'].remove(temp_builder.throne_door.entrance.parent_region.name) builder.exception_list = list(sector_list) return True, {}, package - except (GenerationException, NeutralizingException, OtherGenException): + except (GenerationException, NeutralizingException, OtherGenException) as e: + logging.getLogger('').info(f'Bailing on this layout for', e) builder.split_dungeon_map = None builder.valid_proposal = None if temp_builder.name == 'Hyrule Castle' and temp_builder.throne_door: diff --git a/Fill.py b/Fill.py index 321e1a8e..239d8e8e 100644 --- a/Fill.py +++ b/Fill.py @@ -143,21 +143,24 @@ def verify_spot_to_fill(location, item_to_place, max_exp_state, single_player_pl key_pool, world): if item_to_place.smallkey or item_to_place.bigkey: # a better test to see if a key can go there location.item = item_to_place + location.event = True test_state = max_exp_state.copy() test_state.stale[item_to_place.player] = True else: test_state = max_exp_state if not single_player_placement or location.player == item_to_place.player: + test_state.sweep_for_events() if location.can_fill(test_state, item_to_place, perform_access_check): - if valid_key_placement(item_to_place, location, key_pool, world): + if valid_key_placement(item_to_place, location, key_pool, test_state, world): if item_to_place.crystal or valid_dungeon_placement(item_to_place, location, world): return location if item_to_place.smallkey or item_to_place.bigkey: location.item = None + location.event = False return None -def valid_key_placement(item, location, key_pool, world): +def valid_key_placement(item, location, key_pool, collection_state, world): if not valid_reserved_placement(item, location, world): return False if ((not item.smallkey and not item.bigkey) or item.player != location.player @@ -174,7 +177,15 @@ def valid_key_placement(item, location, key_pool, world): prize_loc = world.get_location(key_logic.prize_location, location.player) cr_count = world.crystals_needed_for_gt[location.player] wild_keys = world.keyshuffle[item.player] != 'none' - return key_logic.check_placement(unplaced_keys, wild_keys, location if item.bigkey else None, prize_loc, cr_count) + if wild_keys: + reached_keys = {x for x in collection_state.locations_checked + if x.item and x.item.name == key_logic.small_key_name and x.item.player == item.player} + else: + reached_keys = set() # will be calculated using key logic in a moment + self_locking_keys = sum(1 for d, rule in key_logic.door_rules.items() if rule.allow_small + and rule.small_location.item and rule.small_location.item.name == key_logic.small_key_name) + return key_logic.check_placement(unplaced_keys, wild_keys, reached_keys, self_locking_keys, + location if item.bigkey else None, prize_loc, cr_count) else: return not item.is_inside_dungeon_item(world) @@ -205,6 +216,7 @@ def track_outside_keys(item, location, world): if loc_dungeon and loc_dungeon.name == item_dungeon: return # this is an inside key world.key_logic[item.player][item_dungeon].outside_keys += 1 + world.key_logic[item.player][item_dungeon].outside_keys_locations.add(location) def track_dungeon_items(item, location, world): @@ -345,7 +357,9 @@ def find_spot_for_item(item_to_place, locations, world, base_state, pool, test_state = maximum_exploration_state if (not single_player_placement or location.player == item_to_place.player) \ and location.can_fill(test_state, item_to_place, perform_access_check) \ - and valid_key_placement(item_to_place, location, pool if (keys_in_itempool and keys_in_itempool[item_to_place.player]) else world.itempool, world): + and valid_key_placement(item_to_place, location, + pool if (keys_in_itempool and keys_in_itempool[item_to_place.player]) else world.itempool, + test_state, world): return location if item_to_place.smallkey or item_to_place.bigkey: location.item = old_item @@ -424,10 +438,16 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None random.shuffle(fill_locations) fill_locations.reverse() - # Make sure the escape small key is placed first in standard with key shuffle to prevent running out of spots - # todo: crossed - progitempool.sort(key=lambda item: 1 if item.name == 'Small Key (Escape)' - and world.keyshuffle[item.player] != 'none' and world.mode[item.player] == 'standard' else 0) + # Make sure the escape keys ire placed first in standard to prevent running out of spots + def std_item_sort(item): + if world.mode[item.player] == 'standard': + if item.name == 'Small Key (Escape)': + return 1 + if item.name == 'Big Key (Escape)': + return 2 + return 0 + + progitempool.sort(key=std_item_sort) key_pool = [x for x in progitempool if x.smallkey] # sort maps and compasses to the back -- this may not be viable in equitable & ambrosia diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index 7b5e011f..2a39f38c 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -5,7 +5,7 @@ from collections import defaultdict, deque from BaseClasses import DoorType, dungeon_keys, KeyRuleType, RegionType from Regions import dungeon_events from Dungeons import dungeon_keys, dungeon_bigs, dungeon_table -from DungeonGenerator import ExplorationState, special_big_key_doors, count_locations_exclude_big_chest, prize_or_event +from DungeonGenerator import ExplorationState, get_special_big_key_doors, count_locations_exclude_big_chest, prize_or_event from DungeonGenerator import reserved_location, blind_boss_unavail @@ -59,13 +59,16 @@ class KeyLogic(object): self.placement_rules = [] self.location_rules = {} self.outside_keys = 0 + self.outside_keys_locations = set() self.dungeon = dungeon_name self.sm_doors = {} self.prize_location = None - def check_placement(self, unplaced_keys, wild_keys, big_key_loc=None, prize_loc=None, cr_count=7): + def check_placement(self, unplaced_keys, wild_keys, reached_keys, self_locking_keys, + big_key_loc=None, prize_loc=None, cr_count=7): for rule in self.placement_rules: - if not rule.is_satisfiable(self.outside_keys, wild_keys, unplaced_keys, big_key_loc, prize_loc, cr_count): + if not rule.is_satisfiable(self.outside_keys_locations, wild_keys, reached_keys, self_locking_keys, + unplaced_keys, big_key_loc, prize_loc, cr_count): return False if big_key_loc: for rule_a, rule_b in itertools.combinations(self.placement_rules, 2): @@ -159,7 +162,8 @@ class PlacementRule(object): left -= rule_needed return False - def is_satisfiable(self, outside_keys, wild_keys, unplaced_keys, big_key_loc, prize_location, cr_count): + def is_satisfiable(self, outside_keys_locations, wild_keys, reached_keys, self_locking_keys, unplaced_keys, + big_key_loc, prize_location, cr_count): if self.prize_relevance and prize_location: if self.prize_relevance == 'BigBomb': if prize_location.item.name not in ['Crystal 5', 'Crystal 6']: @@ -186,10 +190,11 @@ class PlacementRule(object): check_locations = self.check_locations_wo_bk if bk_blocked else self.check_locations_w_bk if not bk_blocked and check_locations is None: return True - available_keys = outside_keys + available_keys = len(outside_keys_locations) # todo: sometimes we need an extra empty chest to accomodate the big key too # dungeon bias seed 563518200 for example threshold = self.needed_keys_wo_bk if bk_blocked else self.needed_keys_w_bk + threshold -= self_locking_keys if not wild_keys: empty_chests = 0 for loc in check_locations: @@ -200,7 +205,8 @@ class PlacementRule(object): place_able_keys = min(empty_chests, unplaced_keys) available_keys += place_able_keys else: - available_keys += unplaced_keys + available_keys += len(reached_keys.difference(outside_keys_locations)) # already placed small keys + available_keys += unplaced_keys # small keys not yet placed return available_keys >= threshold @@ -1002,7 +1008,7 @@ def find_worst_counter_wo_bk(small_key_num, accessible_set, door, odd_ctr, key_c def open_a_door(door, child_state, flat_proposal, world, player): - if door.bigKey or door.name in special_big_key_doors: + if door.bigKey or door.name in get_special_big_key_doors(world, player): child_state.big_key_opened = True child_state.avail_doors.extend(child_state.big_doors) child_state.opened_doors.extend(set([d.door for d in child_state.big_doors])) @@ -1485,7 +1491,8 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa else: ttl_locations = count_locations_exclude_big_chest(state.found_locations, world, player) ttl_small_key_only = count_small_key_only_locations(state) - available_small_locations = cnt_avail_small_locations(ttl_locations, ttl_small_key_only, state, world, player) + available_small_locations = cnt_avail_small_locations(ttl_locations, ttl_small_key_only, state, + key_layout, world, player) available_big_locations = cnt_avail_big_locations(ttl_locations, state, world, player) if invalid_self_locking_key(key_layout, state, prev_state, prev_avail, world, player): return False @@ -1615,18 +1622,24 @@ def determine_prize_lock(key_layout, world, player): key_layout.prize_can_lock = True -def cnt_avail_small_locations(free_locations, key_only, state, world, player): - if world.keyshuffle[player] == 'none': +def cnt_avail_small_locations(free_locations, key_only, state, key_layout, world, player): + std_flag = world.mode[player] == 'standard' and key_layout.sector.name == 'Hyrule Castle' + if world.keyshuffle[player] == 'none' or std_flag: bk_adj = 1 if state.big_key_opened and not state.big_key_special else 0 - avail_chest_keys = min(free_locations - bk_adj, state.key_locations - key_only) + # this is the secret passage, could expand to Uncle/Links House with appropriate logic + std_adj = 1 if std_flag and world.keyshuffle[player] != 'none' else 0 + avail_chest_keys = min(free_locations + std_adj - bk_adj, state.key_locations - key_only) return max(0, avail_chest_keys + key_only - state.used_smalls) return state.key_locations - state.used_smalls def cnt_avail_small_locations_by_ctr(free_locations, counter, layout, world, player): - if world.keyshuffle[player] == 'none': + std_flag = world.mode[player] == 'standard' and layout.sector.name == 'Hyrule Castle' + if world.keyshuffle[player] == 'none' or std_flag: bk_adj = 1 if counter.big_key_opened and not layout.big_key_special else 0 - avail_chest_keys = min(free_locations - bk_adj, layout.max_chests) + # this is the secret passage, could expand to Uncle/Links House with appropriate logic + std_adj = 1 if std_flag and world.keyshuffle[player] != 'none' else 0 + avail_chest_keys = min(free_locations + std_adj - bk_adj, layout.max_chests) return max(0, avail_chest_keys + len(counter.key_only_locations) - counter.used_keys) return layout.max_chests + len(counter.key_only_locations) - counter.used_keys @@ -1683,10 +1696,10 @@ def create_key_counters(key_layout, world, player): if door.dest in flat_proposal and door.type != DoorType.SpiralStairs: key_layout.found_doors.add(door.dest) child_state = parent_state.copy() - if door.bigKey or door.name in special_big_key_doors: + if door.bigKey or door.name in get_special_big_key_doors(world, player): key_layout.key_logic.bk_doors.add(door) # open the door, if possible - if can_open_door(door, child_state, world, player): + if can_open_door(door, child_state, key_layout, world, player): open_a_door(door, child_state, flat_proposal, world, player) expand_key_state(child_state, flat_proposal, world, player) code = state_id(child_state, key_layout.flat_prop) @@ -1707,14 +1720,15 @@ def find_outside_connection(region): return None, None -def can_open_door(door, state, world, player): +def can_open_door(door, state, key_layout, world, player): if state.big_key_opened: ttl_locations = count_free_locations(state, world, player) else: ttl_locations = count_locations_exclude_big_chest(state.found_locations, world, player) if door.smallKey: ttl_small_key_only = count_small_key_only_locations(state) - available_small_locations = cnt_avail_small_locations(ttl_locations, ttl_small_key_only, state, world, player) + available_small_locations = cnt_avail_small_locations(ttl_locations, ttl_small_key_only, state, + key_layout, world, player) return available_small_locations > 0 elif door.bigKey: available_big_locations = cnt_avail_big_locations(ttl_locations, state, world, player) diff --git a/Rom.py b/Rom.py index 54d801bd..3e353b3a 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '4eeafc915838a7c9c5eff7a1b53d4709' +RANDOMIZERBASEHASH = '6f64fcea052e37b39d6b4bb24ae2f548' class JsonRom(object): diff --git a/Rules.py b/Rules.py index 4bf9cd83..a550a9d4 100644 --- a/Rules.py +++ b/Rules.py @@ -1288,7 +1288,7 @@ def standard_rules(world, player): # zelda should be saved before agahnim is in play add_rule(world.get_location('Agahnim 1', player), lambda state: state.has('Zelda Delivered', player)) - # too restrictive for crossed? + # uncle can't have keys generally because unplaced items aren't used here def uncle_item_rule(item): copy_state = CollectionState(world) copy_state.collect(item) diff --git a/data/base2current.bps b/data/base2current.bps index 3afa29d0716c0797214cc3ce5204a82e3c8f5ff5..93e4cfd280c90a77261c2e40c3ac5c95ef7ece69 100644 GIT binary patch delta 1001 zcmW+zUrbwd6z=b~x2?3L1-iD#pZ$7a&?d5U%mJ%ovN;lk8A-N;7!uPEH*rPwpb0W2 z{BFxdIz!sqOZi>6!M3oQ(l)cojcJ%6OqLCJAhIkxSlz>>B%6sz6X5}z;>D-)o$q|- zJNa@lIr4Fi{PqK&dh&##xNcAfcqs(zO5*60B&qHbz%TV{3;<*#Mr%@mYuu#%hPEd# zPQ4RM@KUj%Sp)u*I?Nk{x;jXkF8nJ&>&v$YJug*ueb-BvC!|NKC*J_yU{VQcYf~&D zMF6*1SmsAc*ytC5v*m60D$|oEV`|v@W%`#&6wl#HN?<4Jv5)S{4k$sJMqke|RB{LD zclm4zAa3S6haraoHNj`s>d^YE|X z7$IMDaO($o+w?#eyLay(Pr@%)nOtO{D%9k$dH$z%4ym5-^7%>&qRHU=_&FB3xoAXG zGO-c$eQI%5Iq%(*pUsM z@p-rx>6*o@a7a|bPe(m49ugr;hny`6xQl-_g35;BMVb^kuY|W#OZf-R1I4_kfS+*; zA!_7CMk$dDs{j&gc5a4%JjWd=xa z4;egB0>UNDm^1lAjbc-Iu^A_e9GNqP__P@uh2KXKw&6#S#Qd@+pP0H}SzAl)R?Btn zR8u~#g&zF5862~G=rAMUT|aFUNaHk{S3}IF%S*6i25$}zP70?{Qa0A|nO5X->aoJl zB<OE2C(DCzBjiF`9unK@G`vB#=Yj_$jiI9_Xwy3Zai@W zoGq%Um=0JRp5Qu5@egn3a6kU-aN3P^7EovSL@h8YF5N`SH5yy9trjp^Ku{fc1A=qL p_lL*W9=A6Z%bYkF5-w*e?D9K_#{TSa3hcFMZI5&B{WI`_`47GVkP`p^ delta 906 zcmW-eZA@Er6vlgQU&mT*-)RTKe+wIJwq+yBgw5eVG{z3H=pw_pXhU%7N{nW67_z{> zotIFSuD!jMQ@BoA*iBcqg)P^tpdsL11QM4Jr-{~RvN@whKh*dVr$)T^={(PKemT#F zbEl}CE^4p50Giy-oi?Ehwn49)0FRpaH!aJW8w_;Gy?PVCS(!7KHSm-$V(eq=!?MfN zq=!%B4*P9J{dzf-{T2VTGC!eQ_x#l!=2t;3F7A8;Vpy(*IzyDFS_#NaY*Irt%;FI> zc(fLbgxd=dH3alV3(tA;ztQyy)L!_a3@SBjp2?d-*U7RMR*d77{aDFD)4+$x3`5mK zFD$Q?Tw_nO$p;IoB`rC^D`A=^-^Lq*uHgUCowex6skzcE|ElVOq#_3e zj*;|=QPh;AO=^IO9Yi?CkY0gPNk-g_ZD!cC@x%vVLp*X>D`|*@|6y+Q7PnrQh#7-^ zR(#frXU*W%ZS_`At{tx_8lw2688*YsYZhRkUJ|H%K^xypqn8AlG~B%$P^#(I!3CA7 zLEbg_zQA>9^K7nno(T~nA z_RsAok#3Z2khE2yV2((7)rz{U3iB4F}|cDC({=XTk%sn?Avm9MBGhd%Hi*EC~U-@ z2$%O1UXGl3kH7DX)mBVqYiKg2BY)uhC2VnkgSnT+P6uq<(22gjze2_NRm@G1?P*00 z2ZXH=q4glf9pD2u&N$#vOLx^+)aeVxmw9jc Date: Wed, 15 Feb 2023 08:41:08 -0700 Subject: [PATCH 121/146] Fix for Desert Tiles 1 --- RoomData.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RoomData.py b/RoomData.py index 85c3b1fd..d8d3a82a 100644 --- a/RoomData.py +++ b/RoomData.py @@ -103,7 +103,7 @@ def create_rooms(world, player): Room(player, 0x60, 0x51309).door(Position.NorthE2, DoorKind.NormalLow2).door(Position.East2, DoorKind.NormalLow2).door(Position.East2, DoorKind.ToggleFlag).door(Position.EastN, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.SouthE, DoorKind.IncognitoEntrance), Room(player, 0x61, 0x51454).door(Position.West2, DoorKind.NormalLow).door(Position.West2, DoorKind.ToggleFlag).door(Position.East2, DoorKind.NormalLow).door(Position.East2, DoorKind.ToggleFlag).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance).door(Position.WestN, DoorKind.Normal), Room(player, 0x62, 0x51577).door(Position.West2, DoorKind.NormalLow2).door(Position.West2, DoorKind.ToggleFlag).door(Position.NorthW2, DoorKind.NormalLow2).door(Position.North, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance), - Room(player, 0x63, 0xf88ed).door(Position.NorthE, DoorKind.StairKey).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.DungeonEntrance), # looked like a huge typo - I had to guess on StairKey + Room(player, 0x63, 0xf88ed).door(Position.NorthW, DoorKind.StairKey).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.DungeonEntrance), # looked like a huge typo - I had to guess on StairKey Room(player, 0x64, 0xfda53).door(Position.InteriorS, DoorKind.Trap2), Room(player, 0x65, 0xfdac5).door(Position.InteriorS, DoorKind.Normal), Room(player, 0x66, 0xfa01b).door(Position.InteriorE2, DoorKind.Waterfall).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.ToggleFlag).door(Position.InteriorW2, DoorKind.NormalLow2), From 67bd5e870c53945a9d26cc4c91b7fd02e773ee22 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 15 Feb 2023 14:13:10 -0700 Subject: [PATCH 122/146] Fix for decoupled door in standard --- DungeonGenerator.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 8231833b..7881df0a 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -3517,6 +3517,8 @@ def identify_branching_issues(dungeon_map, builder_info): unconnected_builders[name] = builder for hook, door_list in unreached_doors.items(): builder.unfulfilled[hook] += len(door_list) + elif package: + builder.throne_door, builder.throne_sector, builder.chosen_lobby = package return unconnected_builders From fe0e0805ad94b34f1fb979e3a8fc564d98a7c5f6 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 15 Feb 2023 08:41:08 -0700 Subject: [PATCH 123/146] Fix for Desert Tiles 1 --- RoomData.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RoomData.py b/RoomData.py index f3c82576..eae844ef 100644 --- a/RoomData.py +++ b/RoomData.py @@ -103,7 +103,7 @@ def create_rooms(world, player): Room(player, 0x60, 0x51309).door(Position.NorthE2, DoorKind.NormalLow2).door(Position.East2, DoorKind.NormalLow2).door(Position.East2, DoorKind.ToggleFlag).door(Position.EastN, DoorKind.Normal).door(Position.SouthE, DoorKind.Normal).door(Position.SouthE, DoorKind.IncognitoEntrance), Room(player, 0x61, 0x51454).door(Position.West2, DoorKind.NormalLow).door(Position.West2, DoorKind.ToggleFlag).door(Position.East2, DoorKind.NormalLow).door(Position.East2, DoorKind.ToggleFlag).door(Position.South2, DoorKind.NormalLow).door(Position.South2, DoorKind.IncognitoEntrance).door(Position.WestN, DoorKind.Normal), Room(player, 0x62, 0x51577).door(Position.West2, DoorKind.NormalLow2).door(Position.West2, DoorKind.ToggleFlag).door(Position.NorthW2, DoorKind.NormalLow2).door(Position.North, DoorKind.Normal).door(Position.SouthW, DoorKind.Normal).door(Position.SouthW, DoorKind.IncognitoEntrance), - Room(player, 0x63, 0xf88ed).door(Position.NorthE, DoorKind.StairKey).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.DungeonEntrance), # looked like a huge typo - I had to guess on StairKey + Room(player, 0x63, 0xf88ed).door(Position.NorthW, DoorKind.StairKey).door(Position.InteriorW, DoorKind.TrapTriggerable).door(Position.SouthW, DoorKind.DungeonEntrance), # looked like a huge typo - I had to guess on StairKey Room(player, 0x64, 0xfda53).door(Position.InteriorS, DoorKind.Trap2), Room(player, 0x65, 0xfdac5).door(Position.InteriorS, DoorKind.Normal), Room(player, 0x66, 0xfa01b).door(Position.InteriorE2, DoorKind.Waterfall).door(Position.SouthW2, DoorKind.NormalLow2).door(Position.SouthW2, DoorKind.ToggleFlag).door(Position.InteriorW2, DoorKind.NormalLow2), From afac655de2bfa82fb72e23f50e3f0b352bc91cbd Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 29 Dec 2022 19:39:13 -0700 Subject: [PATCH 124/146] Fixed door position typo --- Doors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doors.py b/Doors.py index c137983f..f89696c6 100644 --- a/Doors.py +++ b/Doors.py @@ -773,7 +773,7 @@ def create_doors(world, player): create_door(player, 'Ice Freezors Hole', Hole), create_door(player, 'Ice Freezors Bomb Hole', Hole), # combine these two? -- they have to lead to the same spot create_door(player, 'Ice Freezors Ledge Hole', Hole), - create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(2), + create_door(player, 'Ice Freezors Ledge ES', Intr).dir(Ea, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint WS', Intr).dir(We, 0x7e, Bot, High).pos(1), create_door(player, 'Ice Tall Hint EN', Nrml).dir(Ea, 0x7e, Top, High).pos(2), create_door(player, 'Ice Tall Hint SE', Nrml).dir(So, 0x7e, Right, High).small_key().pos(0).portal(X, 0x02), From 5f8be831ec96184dfd031f16cb8e5d7e8180707a Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 15 Feb 2023 14:25:00 -0700 Subject: [PATCH 125/146] Version bump and release notes --- Main.py | 2 +- RELEASENOTES.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Main.py b/Main.py index e1a86313..11138c65 100644 --- a/Main.py +++ b/Main.py @@ -31,7 +31,7 @@ from Utils import output_path, parse_player_names from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config from source.tools.BPS import create_bps_from_data -__version__ = '1.1.3-dev' +__version__ = '1.1.4-dev' from source.classes.BabelFish import BabelFish diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 924fdaa5..fd66faff 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -181,6 +181,10 @@ Same as above but both small keys and bigs keys of the dungeon are not allowed o # Bug Fixes and Notes +* 1.1.4 + * Removed a Triforce text + * Fix for Desert Tiles 1 key door + * Fix for Ice Freezors Ledge door position * 1.1.3 * Fixed a typo on a door near the key rat * 1.1.2 From f0101c98547f0bcec7840b007ce86c2a7ac11d83 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 16 Feb 2023 11:49:29 -0700 Subject: [PATCH 126/146] Trap door mode initial work --- BaseClasses.py | 28 +++- CLI.py | 5 +- DoorShuffle.py | 124 ++++++++++-------- Main.py | 2 + README.md | 21 +++ mystery_example.yml | 9 ++ resources/app/cli/args.json | 15 +++ resources/app/cli/lang/en.json | 13 ++ resources/app/gui/lang/en.json | 11 ++ .../app/gui/randomize/dungeon/widgets.json | 21 ++- source/classes/CustomSettings.py | 4 + source/classes/constants.py | 2 + source/tools/MysteryUtils.py | 2 + 13 files changed, 195 insertions(+), 62 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index c2da8e91..d9952095 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -29,6 +29,8 @@ class World(object): self.doorShuffle = doorShuffle.copy() self.intensity = {} self.door_type_mode = {} + self.trap_door_mode = {} + self.key_logic_algorithm = {} self.logic = logic.copy() self.mode = mode.copy() self.swords = swords.copy() @@ -144,6 +146,8 @@ class World(object): set_player_attr('pot_pool', {}) set_player_attr('decoupledoors', False) set_player_attr('door_type_mode', 'original') + set_player_attr('trap_door_mode', 'vanilla') + set_player_attr('key_logic_algorithm', 'default') set_player_attr('shopsanity', False) set_player_attr('mixed_travel', 'prevent') @@ -2434,6 +2438,8 @@ class Spoiler(object): 'door_shuffle': self.world.doorShuffle, 'intensity': self.world.intensity, 'door_type_mode': self.world.door_type_mode, + 'trap_door_mode': self.world.trap_door_mode, + 'key_logic': self.world.key_logic_algorithm, 'decoupledoors': self.world.decoupledoors, 'dungeon_counters': self.world.dungeon_counters, 'item_pool': self.world.difficulty, @@ -2640,6 +2646,8 @@ class Spoiler(object): if self.metadata['door_shuffle'][player] != 'vanilla': outfile.write(f"Intensity: {self.metadata['intensity'][player]}\n") outfile.write(f"Door Type Mode: {self.metadata['door_type_mode'][player]}\n") + outfile.write(f"Trap Door Mode: {self.metadata['trap_door_mode'][player]}\n") + outfile.write(f"Key Logic Algorithm: {self.metadata['key_logic'][player]}\n") outfile.write(f"Decouple Doors: {yn(self.metadata['decoupledoors'][player])}\n") outfile.write(f"Experimental: {yn(self.metadata['experimental'][player])}\n") outfile.write(f"Dungeon Counters: {self.metadata['dungeon_counters'][player]}\n") @@ -2931,15 +2939,19 @@ boss_mode = {"none": 0, "simple": 1, "full": 2, "chaos": 3, 'random': 3, 'unique # byte 10: settings_version -# byte 11: FBBB, TTSS (flute_mode, bow_mode, take_any, small_key_mode) +# byte 11: FBBB TTSS (flute_mode, bow_mode, take_any, small_key_mode) flute_mode = {'normal': 0, 'active': 1} keyshuffle_mode = {'none': 0, 'wild': 1, 'universal': 2} # reserved 8 modes? take_any_mode = {'none': 0, 'random': 1, 'fixed': 2} bow_mode = {'progressive': 0, 'silvers': 1, 'retro': 2, 'retro_silvers': 3} # additions -# psuedoboots does not effect code -# sfx_shuffle and other adjust items does not effect settings code +# byte 12: POOT TKKK (pseudoboots, overworld_map, trap_door_mode, key_logic_algo) +overworld_map_mode = {'default': 0, 'compass': 1, 'map': 2} +trap_door_mode = {'vanilla': 0, 'boss': 1, 'oneway': 2} +key_logic_algo = {'loose': 0, 'default': 1, 'partial': 2, 'strict': 4} + +# sfx_shuffle and other adjust items does not affect settings code # Bump this when making changes that are not backwards compatible (nearly all of them) settings_version = 1 @@ -2983,7 +2995,10 @@ class Settings(object): settings_version, (flute_mode[w.flute_mode[p]] << 7 | bow_mode[w.bow_mode[p]] << 4 - | take_any_mode[w.take_any[p]] << 2 | keyshuffle_mode[w.keyshuffle[p]]) + | take_any_mode[w.take_any[p]] << 2 | keyshuffle_mode[w.keyshuffle[p]]), + + ((0x80 if w.pseudoboots[p] else 0) | overworld_map_mode[w.overworld_map[p]] << 6 + | trap_door_mode[w.trap_door_mode[p]] << 4 | key_logic_algo[w.key_logic_algorithm[p]]), ]) return base64.b64encode(code, "+-".encode()).decode() @@ -3051,6 +3066,11 @@ class Settings(object): args.bow_mode[p] = r(bow_mode)[(settings[11] & 0x70) >> 4] args.take_any[p] = r(take_any_mode)[(settings[11] & 0xC) >> 2] args.keyshuffle[p] = r(keyshuffle_mode)[settings[11] & 0x3] + if len(settings) > 12: + args.pseudoboots[p] = True if settings[12] & 0x80 else False + args.overworld_map[p] = r(overworld_map_mode)[(settings[12] & 0x60) >> 6] + args.trap_door_mode[p] = r(trap_door_mode)[(settings[12] & 0x14) >> 4] + args.key_logic_algorithm[p] = r(key_logic_algo)[settings[12] & 0x07] class KeyRuleType(FastEnum): diff --git a/CLI.py b/CLI.py index 0bbf1181..0df0d03a 100644 --- a/CLI.py +++ b/CLI.py @@ -140,7 +140,8 @@ def parse_cli(argv, no_defaults=False): 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle', 'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx', - 'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors', 'door_type_mode']: + 'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors', 'door_type_mode', + 'trap_door_mode', 'key_logic_algorithm']: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) @@ -214,6 +215,8 @@ def parse_settings(): 'door_shuffle': 'vanilla', 'intensity': 2, 'door_type_mode': 'original', + 'trap_door_mode': 'vanilla', + 'key_logic_algorithm': 'default', 'decoupledoors': False, 'experimental': False, 'dungeon_counters': 'default', diff --git a/DoorShuffle.py b/DoorShuffle.py index a4cf7397..f53fe867 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1781,58 +1781,61 @@ def shuffle_door_types(door_type_pools, paths, world, player): def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player): used_doors = set() for pool, door_type_pool in door_type_pools: - ttl = 0 - suggestion_map, trap_map, flex_map = {}, {}, {} - remaining = door_type_pool.traps - if player in world.custom_door_types: - custom_trap_doors = world.custom_door_types[player]['Trap Door'] - else: - custom_trap_doors = defaultdict(list) + if world.trap_door_mode[player] != 'oneway': + ttl = 0 + suggestion_map, trap_map, flex_map = {}, {}, {} + remaining = door_type_pool.traps + if player in world.custom_door_types: + custom_trap_doors = world.custom_door_types[player]['Trap Door'] + else: + custom_trap_doors = defaultdict(list) - for dungeon in pool: - builder = world.dungeon_layouts[player][dungeon] - find_trappable_candidates(builder, world, player) - if custom_trap_doors[dungeon]: - builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon]) - remaining -= len(custom_trap_doors[dungeon]) - ttl += len(builder.candidates.trap) - if ttl == 0: - continue - for dungeon in pool: - builder = world.dungeon_layouts[player][dungeon] - proportion = len(builder.candidates.trap) - calc = int(round(proportion * door_type_pool.traps/ttl)) - suggested = min(proportion, calc) - remaining -= suggested - suggestion_map[dungeon] = suggested - flex_map[dungeon] = (proportion - suggested) if suggested < proportion else 0 - for dungeon in pool: - builder = world.dungeon_layouts[player][dungeon] - valid_traps, trap_number = find_valid_trap_combination(builder, suggestion_map[dungeon], - start_regions_map[dungeon], paths, world, player, - drop=True) - trap_map[dungeon] = valid_traps - if trap_number < suggestion_map[dungeon]: - flex_map[dungeon] = 0 - remaining += suggestion_map[dungeon] - trap_number - suggestion_map[dungeon] = trap_number - builder_order = [x for x in pool if flex_map[x] > 0] - random.shuffle(builder_order) - queue = deque(builder_order) - while len(queue) > 0 and remaining > 0: - dungeon = queue.popleft() - builder = world.dungeon_layouts[player][dungeon] - increased = suggestion_map[dungeon] + 1 - valid_traps, trap_number = find_valid_trap_combination(builder, increased, start_regions_map[dungeon], - paths, world, player) - if valid_traps: + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + find_trappable_candidates(builder, world, player) # todo: + if custom_trap_doors[dungeon]: + builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon]) + remaining -= len(custom_trap_doors[dungeon]) + ttl += len(builder.candidates.trap) + if ttl == 0: + continue + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + proportion = len(builder.candidates.trap) + calc = int(round(proportion * door_type_pool.traps/ttl)) + suggested = min(proportion, calc) + remaining -= suggested + suggestion_map[dungeon] = suggested + flex_map[dungeon] = (proportion - suggested) if suggested < proportion else 0 + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + valid_traps, trap_number = find_valid_trap_combination(builder, suggestion_map[dungeon], + start_regions_map[dungeon], paths, world, player, + drop=True) trap_map[dungeon] = valid_traps - remaining -= 1 - suggestion_map[dungeon] = increased - flex_map[dungeon] -= 1 - if flex_map[dungeon] > 0: - queue.append(dungeon) - # time to re-assign + if trap_number < suggestion_map[dungeon]: + flex_map[dungeon] = 0 + remaining += suggestion_map[dungeon] - trap_number + suggestion_map[dungeon] = trap_number + builder_order = [x for x in pool if flex_map[x] > 0] + random.shuffle(builder_order) + queue = deque(builder_order) + while len(queue) > 0 and remaining > 0: + dungeon = queue.popleft() + builder = world.dungeon_layouts[player][dungeon] + increased = suggestion_map[dungeon] + 1 + valid_traps, trap_number = find_valid_trap_combination(builder, increased, start_regions_map[dungeon], + paths, world, player) + if valid_traps: + trap_map[dungeon] = valid_traps + remaining -= 1 + suggestion_map[dungeon] = increased + flex_map[dungeon] -= 1 + if flex_map[dungeon] > 0: + queue.append(dungeon) + # time to re-assign + else: + trap_map = {dungeon: [] for dungeon in pool} reassign_trap_doors(trap_map, world, player) for name, traps in trap_map.items(): used_doors.update(traps) @@ -2138,7 +2141,7 @@ def find_trappable_candidates(builder, world, player): for ext in world.get_region(r, player).exits: if ext.door: d = ext.door - if d.blocked and d.trapFlag != 0 and 'Boss' not in d.name and 'Agahnim' not in d.name: + if d.blocked and d.trapFlag != 0 and exclude_boss_traps(d): builder.candidates.trap.append(d) @@ -2281,7 +2284,7 @@ def reassign_trap_doors(trap_map, world, player): logger = logging.getLogger('') for name, traps in trap_map.items(): builder = world.dungeon_layouts[player][name] - queue = deque(find_current_trap_doors(builder)) + queue = deque(find_current_trap_doors(builder, world, player)) while len(queue) > 0: d = queue.pop() if d.type is DoorType.Interior and d not in traps: @@ -2304,12 +2307,21 @@ def reassign_trap_doors(trap_map, world, player): logger.debug('Trap Door: %s', d.name) -def find_current_trap_doors(builder): +def exclude_boss_traps(d): + return ' Boss ' not in d.name and ' Agahnim ' not in d.name and d.name not in ['Skull Spike Corner SW', + 'Mire Warping Pool ES'] + +def exclude_logic_traps(d): + return d.name != 'Mire Warping Pool ES' + + +def find_current_trap_doors(builder, world, player): + checker = exclude_boss_traps if world.trap_door_mode[player] == 'vanilla' else exclude_logic_traps current_doors = [] for region in builder.master_sector.regions: for ext in region.exits: d = ext.door - if d and d.blocked and d.trapFlag != 0: # could exclude removing boss doors here + if d and d.blocked and d.trapFlag != 0 and checker(d): current_doors.append(d) return current_doors @@ -4550,8 +4562,8 @@ door_type_counts = { 'Agahnims Tower': (4, 0, 1, 0, 0, 1, 0), 'Swamp Palace': (6, 0, 0, 2, 0, 0, 0), 'Palace of Darkness': (6, 1, 1, 3, 2, 0, 0), - 'Misery Mire': (6, 3, 5, 2, 0, 0, 0), - 'Skull Woods': (5, 0, 2, 2, 0, 1, 0), + 'Misery Mire': (6, 3, 4, 2, 0, 0, 0), + 'Skull Woods': (5, 0, 1, 2, 0, 1, 0), 'Ice Palace': (6, 1, 3, 0, 0, 0, 0), 'Tower of Hera': (1, 1, 0, 0, 0, 0, 0), 'Thieves Town': (3, 1, 2, 1, 1, 0, 0), diff --git a/Main.py b/Main.py index 02b7d032..83e14f47 100644 --- a/Main.py +++ b/Main.py @@ -110,6 +110,8 @@ def main(args, seed=None, fish=None): world.beemizer = args.beemizer.copy() world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)} world.door_type_mode = args.door_type_mode.copy() + world.trap_door_mode = args.trap_door_mode.copy() + world.key_logic_algorithm = args.key_logic_algorithm.copy() world.decoupledoors = args.decoupledoors.copy() world.experimental = args.experimental.copy() world.dungeon_counters = args.dungeon_counters.copy() diff --git a/README.md b/README.md index bbb9b9bf..2cd2b881 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,27 @@ Four options here, and all of them only take effect if Dungeon Door Shuffle is n CLI: `--door_type_mode [original|big|all|chaos]` +### Trap Door Removal + +Three options here for making dungeon traversal nicer. Only applies if door shuffle is not vanilla. + +* Normal: This does not remove any trap doors. Note that boss trap doors are never shuffled in this mode. +* Remove Boss Traps: Boss traps are removed this includes the one near Mothula. +* Remove All Annoying Traps: This removes all trap doors that are annoying, including boss traps. Note, that the trap door near the mire cutscene chest is left alone because it enforces the use of fire to get to the chest. + +CLI: `--trap_door_mode [vanilla|boss|oneway]` + +### Key Logic Algorithm + +Determines how small key door logic works. + +* Loose: Skips placement rules checks. Currently, experimental to see what kinds of problems can arise. +* Default: Current key logic. Assumes worse case usage, placement checks, but assumes you can't get to a chest until you have sufficient keys. (May assume items are unreachable) +* Partial Protection: Assumes you always have full inventory and worse case usage. This should account for dark room and bunny revival glitches. +* Strict: For those would like to glitch and be protected from yourselves. Small keys door require all small keys to be available to be in logic. + +CLI: `--key_logic [loose|default|partial|strict]` + ### Decouple Doors This is similar to insanity mode in ER where door entrances and exits are not paired anymore. Tends to remove more logic from dungeons as many rooms will not be required to traverse to explore. Hope you like transitions. diff --git a/mystery_example.yml b/mystery_example.yml index 275359fc..dc1a21a7 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -22,6 +22,15 @@ big: 2 all: 1 chaos: 1 + trap_door_mode: + vanilla: 1 + boss: 0 + oneway: 0 + key_logic_algorithm: + loose: 0 + default: 1 + partial: 0 + strict: 0 decoupledoors: off dropshuffle: on: 1 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index a09b1722..0926a8c9 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -193,6 +193,21 @@ "chaos" ] }, + "trap_door_mode": { + "choices": [ + "vanilla", + "boss", + "oneway" + ] + }, + "key_logic_algorithm": { + "choices": [ + "loose", + "default", + "partial", + "strict" + ] + }, "decoupledoors": { "action": "store_true", "type": "bool" diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index 0d3d4cdd..8e574ee0 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -239,6 +239,19 @@ "all: Adds traps doors (and any future supported door types)", "chaos: Increases the number of door types in all dungeon pools" ], + "trap_door_mode" : [ + "Trap Door Removal (default: %(default)s)", + "vanilla: No trap door removal", + "boss: Remove boss traps", + "oneway: Remove annoying trap doors" + ], + "key_logic_algorithm": [ + "Key Logic Algorithm (default: %(default)s)", + "loose: Allow more randomization", + "default: Balance between safety and randomization", + "partial: Partial protection when using certain minor glitches", + "strict: Ensure small keys are available" + ], "decoupledoors" : [ "Door entrances and exits are decoupled" ], "experimental": [ "Enable experimental features. (default: %(default)s)" ], "dungeon_counters": [ "Enable dungeon chest counters. (default: %(default)s)" ], diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 418d623b..3135572e 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -91,6 +91,17 @@ "randomizer.dungeon.door_type_mode.all": "Adds Trap Doors", "randomizer.dungeon.door_type_mode.chaos": "Increases all door types", + "randomizer.dungeon.trap_door_mode": "Trap Door Removal", + "randomizer.dungeon.trap_door_mode.vanilla": "No Removal", + "randomizer.dungeon.trap_door_mode.boss": "Remove Boss Traps", + "randomizer.dungeon.trap_door_mode.oneway": "Remove Annoying Traps", + + "randomizer.dungeon.key_logic_algorithm": "Key Logic Algorithm", + "randomizer.dungeon.key_logic_algorithm.loose": "Loose", + "randomizer.dungeon.key_logic_algorithm.default": "Default", + "randomizer.dungeon.key_logic_algorithm.partial": "Partial Protection", + "randomizer.dungeon.key_logic_algorithm.strict": "Strict", + "randomizer.dungeon.experimental": "Enable Experimental Features", "randomizer.dungeon.dungeon_counters": "Dungeon Chest Counters", diff --git a/resources/app/gui/randomize/dungeon/widgets.json b/resources/app/gui/randomize/dungeon/widgets.json index bdedbfba..cecfeeff 100644 --- a/resources/app/gui/randomize/dungeon/widgets.json +++ b/resources/app/gui/randomize/dungeon/widgets.json @@ -33,7 +33,7 @@ }, "door_type_mode": { "type": "selectbox", - "default": "basic", + "default": "original", "options": [ "original", "big", @@ -44,6 +44,25 @@ "width": 45 } }, + "trap_door_mode": { + "type": "selectbox", + "default": "vanilla", + "options": [ + "vanilla", + "boss", + "oneway" + ] + }, + "key_logic_algorithm": { + "type": "selectbox", + "default": "default", + "options": [ + "loose", + "default", + "partial", + "strict" + ] + }, "decoupledoors": { "type": "checkbox" }, "keydropshuffle": { "type": "checkbox" }, "pottery": { diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index af6e47ff..fd15253f 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -109,6 +109,8 @@ class CustomSettings(object): args.standardize_palettes[p]) args.intensity[p] = get_setting(settings['intensity'], args.intensity[p]) args.door_type_mode[p] = get_setting(settings['door_type_mode'], args.door_type_mode[p]) + args.trap_door_mode[p] = get_setting(settings['trap_door_mode'], args.trap_door_mode[p]) + args.key_logic_algorithm[p] = get_setting(settings['key_logic_algorithm'], args.key_logic_algorithm[p]) args.decoupledoors[p] = get_setting(settings['decoupledoors'], args.decoupledoors[p]) args.dungeon_counters[p] = get_setting(settings['dungeon_counters'], args.dungeon_counters[p]) args.crystals_gt[p] = get_setting(settings['crystals_gt'], args.crystals_gt[p]) @@ -219,6 +221,8 @@ class CustomSettings(object): settings_dict[p]['door_shuffle'] = world.doorShuffle[p] settings_dict[p]['intensity'] = world.intensity[p] settings_dict[p]['door_type_mode'] = world.door_type_mode[p] + settings_dict[p]['trap_door_mode'] = world.trap_door_mode[p] + settings_dict[p]['key_logic_algorithm'] = world.key_logic_algorithm[p] settings_dict[p]['decoupledoors'] = world.decoupledoors[p] settings_dict[p]['logic'] = world.logic[p] settings_dict[p]['mode'] = world.mode[p] diff --git a/source/classes/constants.py b/source/classes/constants.py index e5ecd68c..d6624d8f 100644 --- a/source/classes/constants.py +++ b/source/classes/constants.py @@ -98,6 +98,8 @@ SETTINGSTOPROCESS = { "dungeondoorshuffle": "door_shuffle", "dungeonintensity": "intensity", "door_type_mode": "door_type_mode", + "trap_door_mode": "trap_door_mode", + "key_logic_algorithm": "key_logic_algorithm", "decoupledoors": "decoupledoors", "keydropshuffle": "keydropshuffle", "dropshuffle": "dropshuffle", diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index b5fef26d..322ed447 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -84,6 +84,8 @@ def roll_settings(weights): ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla' ret.intensity = get_choice('intensity') ret.door_type_mode = get_choice('door_type_mode') + ret.trap_door_mode = get_choice('trap_door_mode') + ret.key_logic_algorithm = get_choice('key_logic_algorithm') ret.decoupledoors = get_choice('decoupledoors') == 'on' ret.experimental = get_choice('experimental') == 'on' ret.collection_rate = get_choice('collection_rate') == 'on' From 77c4babca1f5e47079e8941428ff90eb10a25910 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 16 Feb 2023 15:40:13 -0700 Subject: [PATCH 127/146] Potential fix for vanilla door + ER key logic --- DoorShuffle.py | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index f53fe867..f1457b36 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -225,21 +225,37 @@ def vanilla_key_logic(world, player): add_inaccessible_doors(world, player) entrances_map, potentials, connections = determine_entrance_list(world, player) - for builder in builders: + enabled_entrances = world.enabled_entrances[player] = {} + builder_queue = deque(builders) + last_key, loops = None, 0 + while len(builder_queue) > 0: + builder = builder_queue.popleft() origin_list = entrances_map[builder.name] - start_regions = convert_regions(origin_list, world, player) - doors = convert_key_doors(default_small_key_doors[builder.name], world, player) - key_layout = build_key_layout(builder, start_regions, doors, {}, world, player) - valid = validate_key_layout(key_layout, world, player) - if not valid: - logging.getLogger('').info('Vanilla key layout not valid %s', builder.name) - builder.key_door_proposal = doors - if player not in world.key_logic.keys(): - world.key_logic[player] = {} - analyze_dungeon(key_layout, world, player) - world.key_logic[player][builder.name] = key_layout.key_logic - world.key_layout[player][builder.name] = key_layout - log_key_logic(builder.name, key_layout.key_logic) + find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, builder.name) + if len(origin_list) <= 0: + if last_key == builder.name or loops > 1000: + origin_name = (world.get_region(origin_list[0], player).entrances[0].parent_region.name + if len(origin_list) > 0 else 'no origin') + raise GenerationException(f'Infinite loop detected for "{builder.name}" located at {origin_name}') + builder_queue.append(builder) + last_key = builder.name + loops += 1 + else: + find_new_entrances(builder.master_sector, entrances_map, connections, potentials, + enabled_entrances, world, player) + start_regions = convert_regions(origin_list, world, player) + doors = convert_key_doors(default_small_key_doors[builder.name], world, player) + key_layout = build_key_layout(builder, start_regions, doors, {}, world, player) + valid = validate_key_layout(key_layout, world, player) + if not valid: + logging.getLogger('').info('Vanilla key layout not valid %s', builder.name) + builder.key_door_proposal = doors + if player not in world.key_logic.keys(): + world.key_logic[player] = {} + analyze_dungeon(key_layout, world, player) + world.key_logic[player][builder.name] = key_layout.key_logic + world.key_layout[player][builder.name] = key_layout + log_key_logic(builder.name, key_layout.key_logic) # if world.shuffle[player] == 'vanilla' and world.accessibility[player] == 'items' and not world.retro[player] and not world.keydropshuffle[player]: # validate_vanilla_key_logic(world, player) From 2b8b9156d96a7cc997ca96613d10f5e2a3a3ec78 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 17 Feb 2023 10:03:37 -0700 Subject: [PATCH 128/146] Minor randomization consistency --- source/overworld/EntranceShuffle2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index a364530c..a89e6085 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -304,7 +304,8 @@ def do_main_shuffle(entrances, exits, avail, mode_def): unused_entrances = set() if not cross_world: lw_entrances, dw_entrances = [], [] - for x in rem_entrances: + left = sorted(rem_entrances) + for x in left: if bonk_fairy_exception(x): lw_entrances.append(x) if x in LW_Entrances else dw_entrances.append(x) do_same_world_connectors(lw_entrances, dw_entrances, multi_exit_caves, avail) From d7c15ae22c7833c5746dc9dcbadbf1aee73e90ad Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 17 Feb 2023 10:07:43 -0700 Subject: [PATCH 129/146] Strict and Partial key logic implementations with new test suite utility --- BaseClasses.py | 28 ++- Fill.py | 64 ++++++- ItemList.py | 7 + README.md | 3 +- Rules.py | 21 ++- mystery_example.yml | 1 - resources/app/cli/args.json | 1 - resources/app/cli/lang/en.json | 1 - resources/app/gui/lang/en.json | 1 - .../app/gui/randomize/dungeon/widgets.json | 1 - source/item/FillUtil.py | 6 + test/NewTestSuite.py | 126 ++++++++++++++ test/suite/default_key_logic.yaml | 44 +++++ test/suite/partial_key_logic.yaml | 24 +++ test/suite/partial_key_logic_2.yaml | 26 +++ test/suite/partial_key_logic_3.yaml | 160 ++++++++++++++++++ test/suite/strict_key_logic.yaml | 22 +++ 17 files changed, 512 insertions(+), 24 deletions(-) create mode 100644 test/NewTestSuite.py create mode 100644 test/suite/default_key_logic.yaml create mode 100644 test/suite/partial_key_logic.yaml create mode 100644 test/suite/partial_key_logic_2.yaml create mode 100644 test/suite/partial_key_logic_3.yaml create mode 100644 test/suite/strict_key_logic.yaml diff --git a/BaseClasses.py b/BaseClasses.py index d9952095..ca44b0a3 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -510,6 +510,7 @@ class CollectionState(object): self.world = parent if not skip_init: self.prog_items = Counter() + self.forced_keys = Counter() self.reachable_regions = {player: dict() for player in range(1, parent.players + 1)} self.blocked_connections = {player: dict() for player in range(1, parent.players + 1)} self.events = [] @@ -542,12 +543,13 @@ class CollectionState(object): queue = deque(self.blocked_connections[player].items()) self.traverse_world(queue, rrp, bc, player) - unresolved_events = [x for y in self.reachable_regions[player] for x in y.locations - if x.event and x.item and (x.item.smallkey or x.item.bigkey or x.item.advancement) - and x not in self.locations_checked and x.can_reach(self)] - unresolved_events = self._do_not_flood_the_keys(unresolved_events) - if len(unresolved_events) == 0: - self.check_key_doors_in_dungeons(rrp, player) + if self.world.key_logic_algorithm[player] == 'default': + unresolved_events = [x for y in self.reachable_regions[player] for x in y.locations + if x.event and x.item and (x.item.smallkey or x.item.bigkey or x.item.advancement) + and x not in self.locations_checked and x.can_reach(self)] + unresolved_events = self._do_not_flood_the_keys(unresolved_events) + if len(unresolved_events) == 0: + self.check_key_doors_in_dungeons(rrp, player) def traverse_world(self, queue, rrp, bc, player): # run BFS on all connections, and keep track of those blocked by missing items @@ -639,6 +641,7 @@ class CollectionState(object): def check_key_doors_in_dungeons(self, rrp, player): for dungeon_name, checklist in self.dungeons_to_check[player].items(): + # todo: optimization idea - abort exploration if there are unresolved events now if self.apply_dungeon_exploration(rrp, player, dungeon_name, checklist): continue init_door_candidates = self.should_explore_child_state(self, dungeon_name, player) @@ -838,6 +841,7 @@ class CollectionState(object): def copy(self): ret = CollectionState(self.world, skip_init=True) ret.prog_items = self.prog_items.copy() + ret.forced_keys = self.forced_keys.copy() ret.reachable_regions = {player: copy.copy(self.reachable_regions[player]) for player in range(1, self.world.players + 1)} ret.blocked_connections = {player: copy.copy(self.blocked_connections[player]) for player in range(1, self.world.players + 1)} ret.events = copy.copy(self.events) @@ -1045,6 +1049,14 @@ class CollectionState(object): return (item, player) in self.prog_items return self.prog_items[item, player] >= count + def has_sm_key_strict(self, item, player, count=1): + if self.world.keyshuffle[player] == 'universal': + if self.world.mode[player] == 'standard' and self.world.doorShuffle[player] == 'vanilla' and item == 'Small Key (Escape)': + return True # Cannot access the shop until escape is finished. This is safe because the key is manually placed in make_custom_item_pool + return self.can_buy_unlimited('Small Key (Universal)', player) + obtained = self.prog_items[item, player] - self.forced_keys[item, player] + return obtained >= count + def can_buy_unlimited(self, item, player): for shop in self.world.shops[player]: if shop.region.player == player and shop.has_unlimited(item) and shop.region.can_reach(self): @@ -1241,6 +1253,8 @@ class CollectionState(object): def collect(self, item, event=False, location=None): if location: self.locations_checked.add(location) + if item and item.smallkey and location.forced_item is not None: + self.forced_keys[item.name, item.player] += 1 if not item: return changed = False @@ -2949,7 +2963,7 @@ bow_mode = {'progressive': 0, 'silvers': 1, 'retro': 2, 'retro_silvers': 3} # byte 12: POOT TKKK (pseudoboots, overworld_map, trap_door_mode, key_logic_algo) overworld_map_mode = {'default': 0, 'compass': 1, 'map': 2} trap_door_mode = {'vanilla': 0, 'boss': 1, 'oneway': 2} -key_logic_algo = {'loose': 0, 'default': 1, 'partial': 2, 'strict': 4} +key_logic_algo = {'default': 0, 'partial': 1, 'strict': 2} # sfx_shuffle and other adjust items does not affect settings code diff --git a/Fill.py b/Fill.py index 239d8e8e..4859ebc3 100644 --- a/Fill.py +++ b/Fill.py @@ -105,6 +105,8 @@ def fill_restrictive(world, base_state, locations, itempool, key_pool=None, sing spot_to_fill = None item_locations = filter_locations(item_to_place, locations, world, vanilla) + verify(item_to_place, item_locations, maximum_exploration_state, single_player_placement, + perform_access_check, key_pool, world) for location in item_locations: spot_to_fill = verify_spot_to_fill(location, item_to_place, maximum_exploration_state, single_player_placement, perform_access_check, key_pool, world) @@ -128,9 +130,6 @@ def fill_restrictive(world, base_state, locations, itempool, key_pool=None, sing raise FillError('No more spots to place %s' % item_to_place) world.push_item(spot_to_fill, item_to_place, False) - if item_to_place.smallkey: - with suppress(ValueError): - key_pool.remove(item_to_place) track_outside_keys(item_to_place, spot_to_fill, world) track_dungeon_items(item_to_place, spot_to_fill, world) locations.remove(spot_to_fill) @@ -144,6 +143,9 @@ def verify_spot_to_fill(location, item_to_place, max_exp_state, single_player_pl if item_to_place.smallkey or item_to_place.bigkey: # a better test to see if a key can go there location.item = item_to_place location.event = True + if item_to_place.smallkey: + with suppress(ValueError): + key_pool.remove(item_to_place) test_state = max_exp_state.copy() test_state.stale[item_to_place.player] = True else: @@ -157,6 +159,8 @@ def verify_spot_to_fill(location, item_to_place, max_exp_state, single_player_pl if item_to_place.smallkey or item_to_place.bigkey: location.item = None location.event = False + if item_to_place.smallkey: + key_pool.append(item_to_place) return None @@ -394,11 +398,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None random.shuffle(fill_locations) random.shuffle(world.itempool) - if world.item_pool_config.preferred: - pref = list(world.item_pool_config.preferred.keys()) - pref_len = len(pref) - world.itempool.sort(key=lambda i: pref_len - pref.index((i.name, i.player)) - if (i.name, i.player) in world.item_pool_config.preferred else 0) + config_sort(world) progitempool = [item for item in world.itempool if item.advancement] prioitempool = [item for item in world.itempool if not item.advancement and item.priority] restitempool = [item for item in world.itempool if not item.advancement and not item.priority] @@ -496,6 +496,20 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None ensure_good_pots(world) +def config_sort(world): + if world.item_pool_config.verify: + config_sort_helper(world, world.item_pool_config.verify) + elif world.item_pool_config.preferred: + config_sort_helper(world, world.item_pool_config.preferred) + + +def config_sort_helper(world, sort_dict): + pref = list(sort_dict.keys()) + pref_len = len(pref) + world.itempool.sort(key=lambda i: pref_len - pref.index((i.name, i.player)) + if (i.name, i.player) in sort_dict else 0) + + def calc_trash_locations(world, player): total_count, gt_count = 0, 0 for loc in world.get_locations(): @@ -667,6 +681,40 @@ def sell_keys(world, player): world.itempool.remove(universal_key) +def verify(item_to_place, item_locations, state, spp, pac, key_pool, world): + if world.item_pool_config.verify: + logger = logging.getLogger('') + item_name = 'Bottle' if item_to_place.name.startswith('Bottle') else item_to_place.name + item_player = item_to_place.player + config = world.item_pool_config + if (item_name, item_player) in config.verify: + tests = config.verify[(item_name, item_player)] + issues = [] + for location in item_locations: + if location.name in tests: + expected = tests[location.name] + spot = verify_spot_to_fill(location, item_to_place, state, spp, pac, key_pool, world) + if spot and (item_to_place.smallkey or item_to_place.bigkey): + location.item = None + location.event = False + if item_to_place.smallkey: + key_pool.append(item_to_place) + if (expected and spot) or (not expected and spot is None): + logger.debug(f'Placing {item_name} ({item_player}) at {location.name} was {expected}') + config.verify_count += 1 + if config.verify_count >= config.verify_target: + exit() + else: + issues.append((item_name, item_player, location.name, expected)) + if len(issues) > 0: + for name, player, loc, expected in issues: + if expected: + logger.error(f'Could not place {name} ({player}) at {loc}') + else: + logger.error(f'{name} ({player}) should not be allowed at {loc}') + raise Exception(f'Test failed placing {name}') + + def balance_multiworld_progression(world): state = CollectionState(world) checked_locations = set() diff --git a/ItemList.py b/ItemList.py index cac01f3f..b708b284 100644 --- a/ItemList.py +++ b/ItemList.py @@ -1431,6 +1431,13 @@ def fill_specific_items(world): item_player = player if len(item_parts) < 2 else int(item_parts[1]) item_name = item_parts[0] world.item_pool_config.preferred[(item_name, item_player)] = placement['locations'] + elif placement['type'] == 'Verification': + item = placement['item'] + item_parts = item.split('#') + item_player = player if len(item_parts) < 2 else int(item_parts[1]) + item_name = item_parts[0] + world.item_pool_config.verify[(item_name, item_player)] = placement['locations'] + world.item_pool_config.verify_target += len(placement['locations']) def get_item_and_event_flag(item, world, player, dungeon_pool, prize_set, prize_pool): diff --git a/README.md b/README.md index 2cd2b881..c7fd99bd 100644 --- a/README.md +++ b/README.md @@ -158,12 +158,11 @@ CLI: `--trap_door_mode [vanilla|boss|oneway]` Determines how small key door logic works. -* Loose: Skips placement rules checks. Currently, experimental to see what kinds of problems can arise. * Default: Current key logic. Assumes worse case usage, placement checks, but assumes you can't get to a chest until you have sufficient keys. (May assume items are unreachable) * Partial Protection: Assumes you always have full inventory and worse case usage. This should account for dark room and bunny revival glitches. * Strict: For those would like to glitch and be protected from yourselves. Small keys door require all small keys to be available to be in logic. -CLI: `--key_logic [loose|default|partial|strict]` +CLI: `--key_logic [default|partial|strict]` ### Decouple Doors diff --git a/Rules.py b/Rules.py index a550a9d4..ed6367dd 100644 --- a/Rules.py +++ b/Rules.py @@ -2076,13 +2076,16 @@ bunny_impassible_doors = { def add_key_logic_rules(world, player): key_logic = world.key_logic[player] + eval_func = eval_small_key_door + if world.key_logic_algorithm[player] == 'strict' and world.keyshuffle[player] == 'wild': + eval_func = eval_small_key_door_strict for d_name, d_logic in key_logic.items(): for door_name, rule in d_logic.door_rules.items(): door_entrance = world.get_entrance(door_name, player) - add_rule(door_entrance, eval_small_key_door(door_name, d_name, player)) + add_rule(door_entrance, eval_func(door_name, d_name, player)) if door_entrance.door.dependents: for dep in door_entrance.door.dependents: - add_rule(dep.entrance, eval_small_key_door(door_name, d_name, player)) + add_rule(dep.entrance, eval_func(door_name, d_name, player)) for location in d_logic.bk_restricted: if not location.forced_item: forbid_item(location, d_logic.bk_name, player) @@ -2129,10 +2132,24 @@ def eval_small_key_door_main(state, door_name, dungeon, player): return door_openable +def eval_small_key_door_strict_main(state, door_name, dungeon, player): + if state.is_door_open(door_name, player): + return True + key_layout = state.world.key_layout[player][dungeon] + number = key_layout.max_chests + if number <= 0: + return True + return state.has_sm_key_strict(key_layout.key_logic.small_key_name, player, number) + + def eval_small_key_door(door_name, dungeon, player): return lambda state: eval_small_key_door_main(state, door_name, dungeon, player) +def eval_small_key_door_strict(door_name, dungeon, player): + return lambda state: eval_small_key_door_strict_main(state, door_name, dungeon, player) + + def allow_big_key_in_big_chest(bk_name, player): return lambda state, item: item.name == bk_name and item.player == player diff --git a/mystery_example.yml b/mystery_example.yml index dc1a21a7..47d44e00 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -27,7 +27,6 @@ boss: 0 oneway: 0 key_logic_algorithm: - loose: 0 default: 1 partial: 0 strict: 0 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 0926a8c9..53eb2f45 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -202,7 +202,6 @@ }, "key_logic_algorithm": { "choices": [ - "loose", "default", "partial", "strict" diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index 8e574ee0..d27e69ab 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -247,7 +247,6 @@ ], "key_logic_algorithm": [ "Key Logic Algorithm (default: %(default)s)", - "loose: Allow more randomization", "default: Balance between safety and randomization", "partial: Partial protection when using certain minor glitches", "strict: Ensure small keys are available" diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 3135572e..54cd4965 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -97,7 +97,6 @@ "randomizer.dungeon.trap_door_mode.oneway": "Remove Annoying Traps", "randomizer.dungeon.key_logic_algorithm": "Key Logic Algorithm", - "randomizer.dungeon.key_logic_algorithm.loose": "Loose", "randomizer.dungeon.key_logic_algorithm.default": "Default", "randomizer.dungeon.key_logic_algorithm.partial": "Partial Protection", "randomizer.dungeon.key_logic_algorithm.strict": "Strict", diff --git a/resources/app/gui/randomize/dungeon/widgets.json b/resources/app/gui/randomize/dungeon/widgets.json index cecfeeff..d442ae21 100644 --- a/resources/app/gui/randomize/dungeon/widgets.json +++ b/resources/app/gui/randomize/dungeon/widgets.json @@ -57,7 +57,6 @@ "type": "selectbox", "default": "default", "options": [ - "loose", "default", "partial", "strict" diff --git a/source/item/FillUtil.py b/source/item/FillUtil.py index 07f36ac8..8c85bfdd 100644 --- a/source/item/FillUtil.py +++ b/source/item/FillUtil.py @@ -20,6 +20,9 @@ class ItemPoolConfig(object): self.reserved_locations = defaultdict(set) self.restricted = {} self.preferred = {} + self.verify = {} + self.verify_count = 0 + self.verify_target = 0 self.recorded_choices = [] @@ -435,6 +438,9 @@ def filter_locations(item_to_place, locations, world, vanilla_skip=False, potion if (item_name, item_to_place.player) in config.preferred: locs = config.preferred[(item_name, item_to_place.player)] return sorted(locations, key=lambda l: 0 if l.name in locs else 1) + if (item_name, item_to_place.player) in config.verify: + locs = config.verify[(item_name, item_to_place.player)].keys() + return sorted(locations, key=lambda l: 0 if l.name in locs else 1) return locations diff --git a/test/NewTestSuite.py b/test/NewTestSuite.py new file mode 100644 index 00000000..aca4e796 --- /dev/null +++ b/test/NewTestSuite.py @@ -0,0 +1,126 @@ +import fnmatch +import os +import subprocess +import sys +import multiprocessing +import concurrent.futures +import argparse +from collections import OrderedDict + +cpu_threads = multiprocessing.cpu_count() +py_version = f"{sys.version_info.major}.{sys.version_info.minor}" + + +def main(args=None): + successes = [] + errors = [] + task_mapping = [] + tests = OrderedDict() + + successes.append(f"Testing DR (NewTestSuite)") + print(successes[0]) + + # max_attempts = args.count + pool = concurrent.futures.ThreadPoolExecutor(max_workers=cpu_threads) + dead_or_alive = 0 + alive = 0 + + def test(test_name: str, command: str, test_file: str): + tests[test_name] = [command] + + base_command = f"python3.8 DungeonRandomizer.py --suppress_rom --suppress_spoiler" + + def gen_seed(): + task_command = base_command + " " + command + return subprocess.run(task_command, capture_output=True, shell=True, text=True) + + task = pool.submit(gen_seed) + task.success = False + task.name = test_name + task.test_file = test_file + task.cmd = base_command + " " + command + task_mapping.append(task) + + for test_suite, test_files in args.test_suite.items(): + for test_file in test_files: + test(test_suite, f'--customizer {os.path.join(test_suite, test_file)}', test_file) + + from tqdm import tqdm + with tqdm(concurrent.futures.as_completed(task_mapping), + total=len(task_mapping), unit="seed(s)", + desc=f"Success rate: 0.00%") as progressbar: + for task in progressbar: + dead_or_alive += 1 + try: + result = task.result() + if result.returncode: + errors.append([task.name + ' ' + task.test_file, task.cmd, result.stderr]) + else: + alive += 1 + task.success = True + except Exception as e: + raise e + + progressbar.set_description(f"Success rate: {(alive/dead_or_alive)*100:.2f}% - {task.name}") + + def get_results(testname: str): + result = "" + dead_or_alive = [task.success for task in task_mapping if task.name == testname] + alive = [x for x in dead_or_alive if x] + success = f"{testname} Rate: {(len(alive) / len(dead_or_alive)) * 100:.2f}%" + successes.append(success) + print(success) + result += f"{(len(alive)/len(dead_or_alive))*100:.2f}%\t" + return result.strip() + + results = [] + for t in tests.keys(): + results.append(get_results(t)) + + for result in results: + print(result) + successes.append(result) + + return successes, errors + + +if __name__ == "__main__": + successes = [] + + parser = argparse.ArgumentParser(add_help=False) + # parser.add_argument('--count', default=0, type=lambda value: max(int(value), 0)) + parser.add_argument('--cpu_threads', default=cpu_threads, type=lambda value: max(int(value), 1)) + parser.add_argument('--help', default=False, action='store_true') + + args = parser.parse_args() + + if args.help: + parser.print_help() + exit(0) + + cpu_threads = args.cpu_threads + + test_suites = {} + # not sure if it supports subdirectories properly yet + for root, dirnames, filenames in os.walk('test/suite'): + test_suites[root] = fnmatch.filter(filenames, '*.yaml') + + args = argparse.Namespace() + args.test_suite = test_suites + s, errors = main(args=args) + if successes: + successes += [""] * 2 + successes += s + print() + + if errors: + with open(f"new-test-suite-errors.txt", 'w') as stream: + for error in errors: + stream.write(error[0] + "\n") + stream.write(error[1] + "\n") + stream.write(error[2] + "\n\n") + + with open("new-test-suite-success.txt", "w") as stream: + stream.write(str.join("\n", successes)) + + input("Press enter to continue") diff --git a/test/suite/default_key_logic.yaml b/test/suite/default_key_logic.yaml new file mode 100644 index 00000000..e9f3e94b --- /dev/null +++ b/test/suite/default_key_logic.yaml @@ -0,0 +1,44 @@ +# Possible improvements: account for items that are possibly in logic +# Example: Mire Big Key in harmless means all 6 mire smalls required for fire-locked side, +# if you have access to harmless via: +# 2 pod smalls + bow, hammer or 3 pod small +meta: + players: 1 +settings: + 1: + key_logic_algorithm: default + keysanity: True + crystals_needed_for_gt: 0 # to skip trash fill +placements: + 1: + Hobo: Big Key (Misery Mire) + Waterfall Fairy - Left: Small Key (Misery Mire) + Waterfall Fairy - Right: Small Key (Misery Mire) + Palace of Darkness - Big Chest: Hammer +advanced_placements: + 1: + # Contrast with partial_2 + - type: Verification + item: Flippers + locations: + Misery Mire - Map Chest: True + Misery Mire - Main Lobby: True + Misery Mire - Bridge Chest: True + Misery Mire - Spike Chest: True + Misery Mire - Compass Chest: False + Misery Mire - Big Key Chest: False + Misery Mire - Boss: False + # Contrast with partial_3 + - type: Verification + item: Big Key (Ganons Tower) + locations: + Ganons Tower - Big Key Chest: True + Ganons Tower - Big Key Room - Left: True + Ganons Tower - Big Key Room - Right: True + Ganons Tower - Bob's Chest: True + # Normal logic doesn't allow this placement + # unless hammer is placed before it - no algorithm does this in non-keysanity, but possible in keysanity + - type: Verification + item: Small Key (Palace of Darkness) + locations: + Palace of Darkness - Dark Maze - Bottom: True \ No newline at end of file diff --git a/test/suite/partial_key_logic.yaml b/test/suite/partial_key_logic.yaml new file mode 100644 index 00000000..b5e951ed --- /dev/null +++ b/test/suite/partial_key_logic.yaml @@ -0,0 +1,24 @@ +# Even though Lamp is Flipper-locked, this logic considers that a key could be wasted in the dark in mire +# Only fire locked mire is off limits +meta: + players: 1 +settings: + 1: + key_logic_algorithm: partial + keysanity: true +placements: + 1: + Hobo: Lamp + Waterfall Fairy - Left: Small Key (Misery Mire) +advanced_placements: + 1: + - type: Verification + item: Flippers + locations: + Misery Mire - Map Chest: True + Misery Mire - Main Lobby: True + Misery Mire - Bridge Chest: True + Misery Mire - Spike Chest: True + Misery Mire - Compass Chest: False + Misery Mire - Big Key Chest: False + Misery Mire - Boss: False \ No newline at end of file diff --git a/test/suite/partial_key_logic_2.yaml b/test/suite/partial_key_logic_2.yaml new file mode 100644 index 00000000..a6f676e6 --- /dev/null +++ b/test/suite/partial_key_logic_2.yaml @@ -0,0 +1,26 @@ +# For contrast with default logic +# This logic is not yet smart enough to allow the crystal blocked chests with two keys (Spike Pot and one other) +meta: + players: 1 +settings: + 1: + key_logic_algorithm: partial + keysanity: True +placements: + 1: + Hobo: Lamp + Waterfall Fairy - Left: Small Key (Misery Mire) + Waterfall Fairy - Right: Small Key (Misery Mire) + Swamp Palace - Entrance: Big Key (Misery Mire) +advanced_placements: + 1: + - type: Verification + item: Flippers + locations: + Misery Mire - Map Chest: False + Misery Mire - Main Lobby: False + Misery Mire - Bridge Chest: True + Misery Mire - Spike Chest: True + Misery Mire - Compass Chest: False + Misery Mire - Big Key Chest: False + Misery Mire - Boss: False \ No newline at end of file diff --git a/test/suite/partial_key_logic_3.yaml b/test/suite/partial_key_logic_3.yaml new file mode 100644 index 00000000..774e4830 --- /dev/null +++ b/test/suite/partial_key_logic_3.yaml @@ -0,0 +1,160 @@ +# For contrast with default logic +# Examples of valid big key placement that doesn't work with pure worst case scenarios +# Basically chests that are obtainable two ways+ of spending keys +# (Possible fix: access to the extra door grants access to the mini helma key too) +meta: + players: 1 +settings: + 1: + key_logic_algorithm: partial + crystals_needed_for_gt: 0 # to skip trash fill +advanced_placements: + 1: + - type: Verification + item: Big Key (Desert Palace) + locations: + Desert Palace - Big Chest: False + Desert Palace - Big Key Chest: True + Desert Palace - Boss: False + Desert Palace - Compass Chest: True + Desert Palace - Map Chest: True + Desert Palace - Torch: True + - type: Verification + item: Big Key (Eastern Palace) + locations: + Eastern Palace - Big Chest: False + Eastern Palace - Big Key Chest: True + Eastern Palace - Boss: False + Eastern Palace - Cannonball Chest: True + Eastern Palace - Compass Chest: True + Eastern Palace - Map Chest: True + - type: Verification + item: Big Key (Ganons Tower) + locations: + # These four require not wasting keys upstairs because the big key is down here + Ganons Tower - Big Key Chest: False + Ganons Tower - Big Key Room - Left: False + Ganons Tower - Big Key Room - Right: False + Ganons Tower - Bob's Chest: False + # These are normal + Ganons Tower - Big Chest: False + Ganons Tower - Bob's Torch: True + Ganons Tower - Compass Room - Bottom Left: True + Ganons Tower - Compass Room - Bottom Right: True + Ganons Tower - Compass Room - Top Left: True + Ganons Tower - Compass Room - Top Right: True + Ganons Tower - DMs Room - Bottom Left: True + Ganons Tower - DMs Room - Bottom Right: True + Ganons Tower - DMs Room - Top Left: True + Ganons Tower - DMs Room - Top Right: True + Ganons Tower - Firesnake Room: True + Ganons Tower - Hope Room - Left: True + Ganons Tower - Hope Room - Right: True + Ganons Tower - Map Chest: True + Ganons Tower - Mini Helmasaur Room - Left: False + Ganons Tower - Mini Helmasaur Room - Right: False + Ganons Tower - Pre-Moldorm Chest: False + Ganons Tower - Randomizer Room - Bottom Left: True + Ganons Tower - Randomizer Room - Bottom Right: True + Ganons Tower - Randomizer Room - Top Left: True + Ganons Tower - Randomizer Room - Top Right: True + Ganons Tower - Tile Room: True + Ganons Tower - Validation Chest: False + - type: Verification + item: Big Key (Ice Palace) + locations: + Ice Palace - Big Chest: False + Ice Palace - Big Key Chest: True + Ice Palace - Boss: False + Ice Palace - Compass Chest: True + Ice Palace - Freezor Chest: True + Ice Palace - Iced T Room: True + Ice Palace - Map Chest: True + Ice Palace - Spike Room: True + - type: Verification + item: Big Key (Misery Mire) + locations: + Misery Mire - Big Chest: False + Misery Mire - Big Key Chest: True + Misery Mire - Boss: False + Misery Mire - Bridge Chest: True + Misery Mire - Compass Chest: True + Misery Mire - Main Lobby: True + Misery Mire - Map Chest: True + Misery Mire - Spike Chest: True + - type: Verification + item: Big Key (Palace of Darkness) + locations: + Palace of Darkness - Big Chest: False + Palace of Darkness - Big Key Chest: True + Palace of Darkness - Boss: False + Palace of Darkness - Compass Chest: True + Palace of Darkness - Dark Basement - Left: True + Palace of Darkness - Dark Basement - Right: True + Palace of Darkness - Dark Maze - Bottom: True + Palace of Darkness - Dark Maze - Top: True + Palace of Darkness - Harmless Hellway: True + Palace of Darkness - Map Chest: True + Palace of Darkness - Shooter Room: True + Palace of Darkness - Stalfos Basement: True + Palace of Darkness - The Arena - Bridge: True + Palace of Darkness - The Arena - Ledge: True + - type: Verification + item: Big Key (Skull Woods) + locations: + Skull Woods - Big Chest: True + Skull Woods - Big Key Chest: True + Skull Woods - Boss: True + Skull Woods - Bridge Room: True + Skull Woods - Compass Chest: True + Skull Woods - Map Chest: True + Skull Woods - Pinball Room: True + Skull Woods - Pot Prison: True + - type: Verification + item: Big Key (Swamp Palace) + locations: + Swamp Palace - Big Chest: True + Swamp Palace - Big Key Chest: True + Swamp Palace - Boss: True + Swamp Palace - Compass Chest: True + Swamp Palace - Entrance: False + Swamp Palace - Flooded Room - Left: True + Swamp Palace - Flooded Room - Right: True + Swamp Palace - Map Chest: True + Swamp Palace - Waterfall Room: True + Swamp Palace - West Chest: True + - type: Verification + item: Big Key (Thieves Town) + locations: + Thieves' Town - Ambush Chest: True + Thieves' Town - Attic: False + Thieves' Town - Big Chest: False + Thieves' Town - Big Key Chest: True + Thieves' Town - Blind's Cell: False + Thieves' Town - Boss: False + Thieves' Town - Compass Chest: True + Thieves' Town - Map Chest: True + - type: Verification + item: Big Key (Tower of Hera) + locations: + Tower of Hera - Basement Cage: True + Tower of Hera - Big Chest: False + Tower of Hera - Big Key Chest: True + Tower of Hera - Boss: False + Tower of Hera - Compass Chest: False + Tower of Hera - Map Chest: True + - type: Verification + item: Big Key (Turtle Rock) + locations: + Turtle Rock - Big Chest: False + Turtle Rock - Big Key Chest: True + Turtle Rock - Boss: False + Turtle Rock - Chain Chomps: True + Turtle Rock - Compass Chest: True + Turtle Rock - Crystaroller Room: False + Turtle Rock - Eye Bridge - Bottom Left: False + Turtle Rock - Eye Bridge - Bottom Right: False + Turtle Rock - Eye Bridge - Top Left: False + Turtle Rock - Eye Bridge - Top Right: False + Turtle Rock - Roller Room - Left: True + Turtle Rock - Roller Room - Right: True \ No newline at end of file diff --git a/test/suite/strict_key_logic.yaml b/test/suite/strict_key_logic.yaml new file mode 100644 index 00000000..89eb11c0 --- /dev/null +++ b/test/suite/strict_key_logic.yaml @@ -0,0 +1,22 @@ +meta: + players: 1 +settings: + 1: + key_logic_algorithm: strict + keysanity: true +placements: + 1: + Hobo: Big Key (Misery Mire) + Waterfall Fairy - Left: Small Key (Misery Mire) +advanced_placements: + 1: + - type: Verification + item: Flippers + locations: + Misery Mire - Map Chest: False + Misery Mire - Main Lobby: False + Misery Mire - Bridge Chest: True + Misery Mire - Spike Chest: True + Misery Mire - Compass Chest: False + Misery Mire - Big Key Chest: False + Misery Mire - Boss: False \ No newline at end of file From 9a71e56546ca0110370fa61c38ea998893faa616 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 17 Feb 2023 16:55:35 -0700 Subject: [PATCH 130/146] Trap door refinement with "optional" value versus "vanilla" Slight balance of chaos mode Warping Pool trap no longer shuffled --- BaseClasses.py | 7 +- CLI.py | 2 +- DoorShuffle.py | 65 ++++++++++--------- DungeonGenerator.py | 2 +- Main.py | 2 +- README.md | 17 +++-- RELEASENOTES.md | 10 ++- mystery_testsuite.yml | 20 +++++- resources/app/cli/args.json | 1 + resources/app/cli/lang/en.json | 5 +- resources/app/gui/lang/en.json | 5 +- .../app/gui/randomize/dungeon/widgets.json | 8 ++- source/dungeon/DungeonStitcher.py | 32 ++++++++- 13 files changed, 123 insertions(+), 53 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index ca44b0a3..dd39cfc9 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -146,7 +146,7 @@ class World(object): set_player_attr('pot_pool', {}) set_player_attr('decoupledoors', False) set_player_attr('door_type_mode', 'original') - set_player_attr('trap_door_mode', 'vanilla') + set_player_attr('trap_door_mode', 'optional') set_player_attr('key_logic_algorithm', 'default') set_player_attr('shopsanity', False) @@ -1905,6 +1905,9 @@ class Door(object): return world.get_room(self.roomIndex, self.player).kind(self) return None + def dungeon_name(self): + return self.entrance.parent_region.dungeon.name if self.entrance.parent_region.dungeon else 'Cave' + def __eq__(self, other): return isinstance(other, self.__class__) and self.name == other.name @@ -2962,7 +2965,7 @@ bow_mode = {'progressive': 0, 'silvers': 1, 'retro': 2, 'retro_silvers': 3} # additions # byte 12: POOT TKKK (pseudoboots, overworld_map, trap_door_mode, key_logic_algo) overworld_map_mode = {'default': 0, 'compass': 1, 'map': 2} -trap_door_mode = {'vanilla': 0, 'boss': 1, 'oneway': 2} +trap_door_mode = {'vanilla': 0, 'optional': 1, 'boss': 2, 'oneway': 3} key_logic_algo = {'default': 0, 'partial': 1, 'strict': 2} # sfx_shuffle and other adjust items does not affect settings code diff --git a/CLI.py b/CLI.py index 0df0d03a..536543f2 100644 --- a/CLI.py +++ b/CLI.py @@ -215,7 +215,7 @@ def parse_settings(): 'door_shuffle': 'vanilla', 'intensity': 2, 'door_type_mode': 'original', - 'trap_door_mode': 'vanilla', + 'trap_door_mode': 'optional', 'key_logic_algorithm': 'default', 'decoupledoors': False, 'experimental': False, diff --git a/DoorShuffle.py b/DoorShuffle.py index f1457b36..308a0731 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1760,12 +1760,12 @@ class DoorTypePool: self.tricky += counts[6] def chaos_shuffle(self, counts): - weights = [1, 2, 4, 3, 2, 1] + weights = [1, 2, 4, 3, 2] return [random.choices(self.get_choices(counts[i]), weights=weights)[0] for i, c in enumerate(counts)] @staticmethod def get_choices(number): - return [max(number+i, 0) for i in range(-1, 5)] + return [max(number+i, 0) for i in range(-1, 4)] class BuilderDoorCandidates: @@ -1801,14 +1801,17 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player) ttl = 0 suggestion_map, trap_map, flex_map = {}, {}, {} remaining = door_type_pool.traps - if player in world.custom_door_types: + if player in world.custom_door_types and 'Trap Door' in world.custom_door_types[player]: custom_trap_doors = world.custom_door_types[player]['Trap Door'] else: custom_trap_doors = defaultdict(list) for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] - find_trappable_candidates(builder, world, player) # todo: + if 'Mire Warping Pool' in builder.master_sector.region_set(): + custom_trap_doors[dungeon].append(world.get_door('Mire Warping Pool ES', player)) + world.custom_door_types[player]['Trap Door'] = custom_trap_doors + find_trappable_candidates(builder, world, player) if custom_trap_doors[dungeon]: builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon]) remaining -= len(custom_trap_doors[dungeon]) @@ -1852,6 +1855,10 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player) # time to re-assign else: trap_map = {dungeon: [] for dungeon in pool} + for dungeon in pool: + builder = world.dungeon_layouts[player][dungeon] + if 'Mire Warping Pool' in builder.master_sector.region_set(): + trap_map[dungeon].append(world.get_door('Mire Warping Pool ES', player)) reassign_trap_doors(trap_map, world, player) for name, traps in trap_map.items(): used_doors.update(traps) @@ -1863,7 +1870,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, ttl = 0 suggestion_map, bk_map, flex_map = {}, {}, {} remaining = door_type_pool.bigs - if player in world.custom_door_types: + if player in world.custom_door_types and 'Big Key Door' in world.custom_door_types[player]: custom_bk_doors = world.custom_door_types[player]['Big Key Door'] else: custom_bk_doors = defaultdict(list) @@ -1925,7 +1932,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl suggestion_map, small_map, flex_map = {}, {}, {} remaining = door_type_pool.smalls total_keys = remaining - if player in world.custom_door_types: + if player in world.custom_door_types and 'Key Door' in world.custom_door_types[player]: custom_key_doors = world.custom_door_types[player]['Key Door'] else: custom_key_doors = defaultdict(list) @@ -2025,7 +2032,7 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, worl remaining_bomb = door_type_pool.bombable remaining_dash = door_type_pool.dashable - if player in world.custom_door_types: + if player in world.custom_door_types and 'Bomb Door' in world.custom_door_types[player]: custom_bomb_doors = world.custom_door_types[player]['Bomb Door'] custom_dash_doors = world.custom_door_types[player]['Dash Door'] else: @@ -2164,7 +2171,7 @@ def find_trappable_candidates(builder, world, player): def find_valid_trap_combination(builder, suggested, start_regions, paths, world, player, drop=True): trap_door_pool = builder.candidates.trap trap_doors_needed = suggested - if player in world.custom_door_types: + if player in world.custom_door_types and 'Trap Door' in world.custom_door_types[player]: custom_trap_doors = world.custom_door_types[player]['Trap Door'][builder.name] else: custom_trap_doors = [] @@ -2319,20 +2326,16 @@ def reassign_trap_doors(trap_map, world, player): d.blocked = False for d in traps: change_door_to_trap(d, world, player) - world.spoiler.set_door_type(d.name, 'Trap Door', player) - logger.debug('Trap Door: %s', d.name) + world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Trap Door', player) + logger.debug(f'Trap Door: {d.name} ({d.dungeon_name()})') def exclude_boss_traps(d): - return ' Boss ' not in d.name and ' Agahnim ' not in d.name and d.name not in ['Skull Spike Corner SW', - 'Mire Warping Pool ES'] - -def exclude_logic_traps(d): - return d.name != 'Mire Warping Pool ES' + return ' Boss ' not in d.name and ' Agahnim ' not in d.name and d.name not in ['Skull Spike Corner SW'] def find_current_trap_doors(builder, world, player): - checker = exclude_boss_traps if world.trap_door_mode[player] == 'vanilla' else exclude_logic_traps + checker = exclude_boss_traps if world.trap_door_mode[player] in ['vanilla', 'optional'] else (lambda x: True) current_doors = [] for region in builder.master_sector.regions: for ext in region.exits: @@ -2452,7 +2455,7 @@ def find_big_key_door_candidates(region, checked, used, world, player): def find_valid_bk_combination(builder, suggested, start_regions, world, player, drop=True): bk_door_pool = builder.candidates.big bk_doors_needed = suggested - if player in world.custom_door_types: + if player in world.custom_door_types and 'Big Key Door' in world.custom_door_types[player]: custom_bk_doors = world.custom_door_types[player]['Big Key Door'][builder.name] else: custom_bk_doors = [] @@ -2527,8 +2530,8 @@ def reassign_big_key_doors(bk_map, world, player): world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) change_door_to_big_key(d1, world, player) change_door_to_big_key(d2, world, player) - world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Big Key Door', player) - logger.debug(f'Big Key Door: {d1.name} <-> {d2.name}') + world.spoiler.set_door_type(f'{d1.name} <-> {d2.name} ({d1.dungeon_name()})', 'Big Key Door', player) + logger.debug(f'Big Key Door: {d1.name} <-> {d2.name} ({d1.dungeon_name()})') else: d = obj if d.type is DoorType.Interior: @@ -2545,8 +2548,8 @@ def reassign_big_key_doors(bk_map, world, player): if stateful_door(d.dest, dest_room.kind(d.dest)): change_door_to_big_key(d.dest, world, player) add_pair(d, d.dest, world, player) - world.spoiler.set_door_type(d.name, 'Big Key Door', player) - logger.debug(f'Big Key Door: {d.name}') + world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Big Key Door', player) + logger.debug(f'Big Key Door: {d.name} ({d.dungeon_name()})') def change_door_to_big_key(d, world, player): @@ -2596,7 +2599,7 @@ def find_valid_combination(builder, target, start_regions, world, player, drop_k logger = logging.getLogger('') key_door_pool = list(builder.candidates.small) key_doors_needed = target - if player in world.custom_door_types: + if player in world.custom_door_types and 'Key Door' in world.custom_door_types[player]: custom_key_doors = world.custom_door_types[player]['Key Door'][builder.name] else: custom_key_doors = [] @@ -2724,7 +2727,7 @@ def find_valid_bd_combination(builder, suggested, world, player): bd_door_pool = builder.candidates.bomb_dash bomb_doors_needed, dash_doors_needed = suggested ttl_needed = bomb_doors_needed + dash_doors_needed - if player in world.custom_door_types: + if player in world.custom_door_types and 'Bomb Door' in world.custom_door_types[player]: custom_bomb_doors = world.custom_door_types[player]['Bomb Door'][builder.name] custom_dash_doors = world.custom_door_types[player]['Dash Door'][builder.name] else: @@ -2800,7 +2803,7 @@ def do_bombable_dashable(proposal, kind, world, player): change_door_to_kind(d1, kind, world, player) change_door_to_kind(d2, kind, world, player) spoiler_type = 'Bomb Door' if kind == DoorKind.Bombable else 'Dash Door' - world.spoiler.set_door_type(d1.name+' <-> '+d2.name, spoiler_type, player) + world.spoiler.set_door_type(f'{d1.name} <-> {d2.name} ({d1.dungeon_name()})', spoiler_type, player) else: d = obj if d.type is DoorType.Interior: @@ -2814,7 +2817,7 @@ def do_bombable_dashable(proposal, kind, world, player): change_door_to_kind(d.dest, kind, world, player) add_pair(d, d.dest, world, player) spoiler_type = 'Bomb Door' if kind == DoorKind.Bombable else 'Dash Door' - world.spoiler.set_door_type(d.name, spoiler_type, player) + world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', spoiler_type, player) def find_current_bd_doors(builder, world): @@ -3017,8 +3020,8 @@ def reassign_key_doors(small_map, world, player): world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) change_door_to_small_key(d1, world, player) change_door_to_small_key(d2, world, player) - world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Key Door', player) - logger.debug('Key Door: %s', d1.name+' <-> '+d2.name) + world.spoiler.set_door_type(f'{d1.name} <-> {d2.name} ({d1.dungeon_name()})', 'Key Door', player) + logger.debug(f'Key Door: {d1.name} <-> {d2.name} ({d1.dungeon_name()})') else: d = obj if d.type is DoorType.Interior: @@ -3034,8 +3037,8 @@ def reassign_key_doors(small_map, world, player): if stateful_door(d.dest, dest_room.kind(d.dest)): change_door_to_small_key(d.dest, world, player) add_pair(d, d.dest, world, player) - world.spoiler.set_door_type(d.name, 'Key Door', player) - logger.debug('Key Door: %s', d.name) + world.spoiler.set_door_type(f'{d.name} ({d.dungeon_name()})', 'Key Door', player) + logger.debug(f'Key Door: {d.name} ({d.dungeon_name()})') def change_door_to_small_key(d, world, player): @@ -3225,7 +3228,7 @@ def change_pair_type(door, new_type, world, player): room_b.change(door.dest.doorListPos, new_type) add_pair(door, door.dest, world, player) spoiler_type = 'Bomb Door' if new_type == DoorKind.Bombable else 'Dash Door' - world.spoiler.set_door_type(door.name + ' <-> ' + door.dest.name, spoiler_type, player) + world.spoiler.set_door_type(f'{door.name} <-> {door.dest.name} ({door.dungeon_name()})', spoiler_type, player) def remove_pair_type_if_present(door, world, player): @@ -4578,7 +4581,7 @@ door_type_counts = { 'Agahnims Tower': (4, 0, 1, 0, 0, 1, 0), 'Swamp Palace': (6, 0, 0, 2, 0, 0, 0), 'Palace of Darkness': (6, 1, 1, 3, 2, 0, 0), - 'Misery Mire': (6, 3, 4, 2, 0, 0, 0), + 'Misery Mire': (6, 3, 5, 2, 0, 0, 0), 'Skull Woods': (5, 0, 1, 2, 0, 1, 0), 'Ice Palace': (6, 1, 3, 0, 0, 0, 0), 'Tower of Hera': (1, 1, 0, 0, 0, 0, 0), diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 7881df0a..9be244f8 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -3565,7 +3565,7 @@ def check_for_valid_layout(builder, sector_list, builder_info): builder.exception_list = list(sector_list) return True, {}, package except (GenerationException, NeutralizingException, OtherGenException) as e: - logging.getLogger('').info(f'Bailing on this layout for', e) + logging.getLogger('').info(f'Bailing on this layout for {builder.name}', exc_info=1) builder.split_dungeon_map = None builder.valid_proposal = None if temp_builder.name == 'Hyrule Castle' and temp_builder.throne_door: diff --git a/Main.py b/Main.py index 83e14f47..a39fbe57 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.7-u' +__version__ = '1.2.0.8-u' from source.classes.BabelFish import BabelFish diff --git a/README.md b/README.md index c7fd99bd..6af52f44 100644 --- a/README.md +++ b/README.md @@ -139,20 +139,25 @@ Four options here, and all of them only take effect if Dungeon Door Shuffle is n * Small Key Doors, Bomb Doors, Dash Doors: This is what was normally shuffled previously * Adds Big Keys Doors: Big key doors are now shuffled in addition to those above, and Big Key doors are enabled to be on in both vertical directions thanks to a graphic that ended up on the cutting room floor. This does change -* Adds Trap Doors: All trap doors that are permanently shut in vanilla are shuffled. +* Adds Trap Doors: All trap doors that are permanently shut in vanilla are shuffled, excluding those by bosses. * Increases all Door Types: This is a chaos mode where each door type per dungeon is randomized between 1 less and 4 more. CLI: `--door_type_mode [original|big|all|chaos]` ### Trap Door Removal -Three options here for making dungeon traversal nicer. Only applies if door shuffle is not vanilla. +Options here for making dungeon traversal nicer. Only applies if door shuffle is not vanilla. -* Normal: This does not remove any trap doors. Note that boss trap doors are never shuffled in this mode. -* Remove Boss Traps: Boss traps are removed this includes the one near Mothula. -* Remove All Annoying Traps: This removes all trap doors that are annoying, including boss traps. Note, that the trap door near the mire cutscene chest is left alone because it enforces the use of fire to get to the chest. +* No Removal: This does not remove any trap doors. +* Removed If Blocking Path: Dungeon generation is relaxed to allow annoying trap doors to be removed if necessary. Note that boss trap doors are never shuffled in this mode. +* Remove Boss Traps: Boss traps are removed, this includes the one near Mothula. +* Remove All Annoying Traps: This removes all trap doors that are annoying, including boss traps. -CLI: `--trap_door_mode [vanilla|boss|oneway]` +If trap doors are shuffled the first two option behave the same. The last option overrides the shuffle because there is nothing left to shuffle. Boss traps are never shuffled. + +In all cases, that the trap door near the mire cutscene chest (Mire Warping Pool ES) is left alone because it enforces the use of fire to get to the chest. + +CLI: `--trap_door_mode [vanilla|optional|boss|oneway]` ### Key Logic Algorithm diff --git a/RELEASENOTES.md b/RELEASENOTES.md index efa12d9f..0328487c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -109,8 +109,14 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes * 1.2.0.8-u - * Removed a Triforce text - * Fix for Desert Tiles 1 key door + * New Features: trap_door_mode and key_logic_algorithm + * Change S&Q in door shuffle + standard during escape to spawn as Uncle + * Fix for vanilla doors + certain ER modes + * Fix for unintentional decoupled door in standard + * Fix a problem with BK doors being one-sided + * Change to how wilds keys are placed in standard, better randomization + * Removed a Triforce text + * Fix for Desert Tiles 1 key door * 1.2.0.7-u * Fix for some misery mire key logic * Minor standard generation fix diff --git a/mystery_testsuite.yml b/mystery_testsuite.yml index aca535c3..f919b7cc 100644 --- a/mystery_testsuite.yml +++ b/mystery_testsuite.yml @@ -7,12 +7,30 @@ algorithm: district: 1 door_shuffle: vanilla: 1 - basic: 2 + basic: 1 + partitioned: 1 crossed: 3 # crossed yield more errors so is preferred intensity: 1: 1 2: 1 3: 2 # intensity 3 usually yield more errors +door_type_mode: + original: 2 + big: 2 + all: 1 + chaos: 1 +trap_door_mode: + vanilla: 3 # more errors + optional: 1 + boss: 1 + oneway: 1 +key_logic_algorithm: + default: 1 + partial: 0 + strict: 0 +decoupledoors: + off: 9 # more strict + on: 1 dropshuffle: on: 1 off: 1 diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 53eb2f45..f85e51cd 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -196,6 +196,7 @@ "trap_door_mode": { "choices": [ "vanilla", + "optional", "boss", "oneway" ] diff --git a/resources/app/cli/lang/en.json b/resources/app/cli/lang/en.json index d27e69ab..4d5fb151 100644 --- a/resources/app/cli/lang/en.json +++ b/resources/app/cli/lang/en.json @@ -242,8 +242,9 @@ "trap_door_mode" : [ "Trap Door Removal (default: %(default)s)", "vanilla: No trap door removal", - "boss: Remove boss traps", - "oneway: Remove annoying trap doors" + "optional: Trap doors removed if blocking", + "boss: Also remove boss traps", + "oneway: Remove all annoying trap doors" ], "key_logic_algorithm": [ "Key Logic Algorithm (default: %(default)s)", diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 54cd4965..b8166baa 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -93,8 +93,9 @@ "randomizer.dungeon.trap_door_mode": "Trap Door Removal", "randomizer.dungeon.trap_door_mode.vanilla": "No Removal", - "randomizer.dungeon.trap_door_mode.boss": "Remove Boss Traps", - "randomizer.dungeon.trap_door_mode.oneway": "Remove Annoying Traps", + "randomizer.dungeon.trap_door_mode.optional": "Removed If Blocking Path", + "randomizer.dungeon.trap_door_mode.boss": "Also Remove Boss Traps", + "randomizer.dungeon.trap_door_mode.oneway": "Remove All Annoying Traps", "randomizer.dungeon.key_logic_algorithm": "Key Logic Algorithm", "randomizer.dungeon.key_logic_algorithm.default": "Default", diff --git a/resources/app/gui/randomize/dungeon/widgets.json b/resources/app/gui/randomize/dungeon/widgets.json index d442ae21..9749486e 100644 --- a/resources/app/gui/randomize/dungeon/widgets.json +++ b/resources/app/gui/randomize/dungeon/widgets.json @@ -46,12 +46,16 @@ }, "trap_door_mode": { "type": "selectbox", - "default": "vanilla", + "default": "optional", "options": [ "vanilla", + "optional", "boss", "oneway" - ] + ], + "config": { + "width": 30 + } }, "key_logic_algorithm": { "type": "selectbox", diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py index 8052b728..1eac3fb1 100644 --- a/source/dungeon/DungeonStitcher.py +++ b/source/dungeon/DungeonStitcher.py @@ -631,6 +631,7 @@ class ExplorationState(object): elif not self.in_door_list(door, self.avail_doors): self.append_door_to_list(door, self.avail_doors, flag) + # same as above but traps are ignored, and flag is not used def add_all_doors_check_proposed_2(self, region, proposed_map, valid_doors, world, player): for door in get_doors(world, region, player): if door in proposed_map and door.name in valid_doors: @@ -651,6 +652,27 @@ class ExplorationState(object): elif not self.in_door_list(door, self.avail_doors): self.append_door_to_list(door, self.avail_doors) + # same as above but traps are checked for + def add_all_doors_check_proposed_3(self, region, proposed_map, valid_doors, world, player): + for door in get_doors(world, region, player): + if door in proposed_map and door.name in valid_doors: + self.visited_doors.add(door) + if self.can_traverse(door): + if door.controller is not None: + door = door.controller + if door.dest is None and door not in proposed_map.keys() and door.name in valid_doors: + if not self.in_door_list_ic(door, self.unattached_doors): + self.append_door_to_list(door, self.unattached_doors) + else: + other = self.find_door_in_list(door, self.unattached_doors) + if self.crystal != other.crystal: + other.crystal = CrystalBarrier.Either + elif door.req_event is not None and door.req_event not in self.events and not self.in_door_list(door, + self.event_doors): + self.append_door_to_list(door, self.event_doors) + elif not self.in_door_list(door, self.avail_doors): + self.append_door_to_list(door, self.avail_doors) + def add_all_doors_check_proposed_traps(self, region, proposed_traps, world, player): for door in get_doors(world, region, player): if self.can_traverse_ignore_traps(door) and door not in proposed_traps: @@ -837,7 +859,10 @@ def extend_reachable_state_lenient(search_regions, state, proposed_map, all_regi local_state = state.copy() for region in search_regions: local_state.visit_region(region) - local_state.add_all_doors_check_proposed_2(region, proposed_map, valid_doors, world, player) + if world.trap_door_mode[player] == 'vanilla': + local_state.add_all_doors_check_proposed_3(region, proposed_map, valid_doors, world, player) + else: + local_state.add_all_doors_check_proposed_2(region, proposed_map, valid_doors, world, player) while len(local_state.avail_doors) > 0: explorable_door = local_state.next_avail_door() if explorable_door.door in proposed_map: @@ -848,7 +873,10 @@ def extend_reachable_state_lenient(search_regions, state, proposed_map, all_regi if (valid_region_to_explore_in_regions(connect_region, all_regions, world, player) and not local_state.visited(connect_region)): local_state.visit_region(connect_region) - local_state.add_all_doors_check_proposed_2(connect_region, proposed_map, valid_doors, world, player) + if world.trap_door_mode[player] == 'vanilla': + local_state.add_all_doors_check_proposed_3(connect_region, proposed_map, valid_doors, world, player) + else: + local_state.add_all_doors_check_proposed_2(connect_region, proposed_map, valid_doors, world, player) return local_state From 16dc743d2d582260e62a378dbe625e0f66a94ace Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 18 Feb 2023 20:31:04 -0600 Subject: [PATCH 131/146] Removed unused glitched exits --- OWEdges.py | 3 --- Regions.py | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 9db72771..1e40a0c4 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1608,7 +1608,6 @@ OWExitTypes = { 'Hyrule Castle Main Gate (North)', 'Hyrule Castle Courtyard Bush (North)', 'Hyrule Castle Outer East Rock', - 'Blacksmith Water Exit', 'Wooden Bridge Bush (South)', 'Wooden Bridge Bush (North)', 'Bat Cave Ledge Peg', @@ -1674,7 +1673,6 @@ OWExitTypes = { 'Village of Outcasts Pegs', 'Grassy Lawn Pegs', 'Pyramid Crack', - 'Hammerpegs Water Exit', 'Broken Bridge Hammer Rock (South)', 'Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', @@ -1684,7 +1682,6 @@ OWExitTypes = { 'Archery Game Rock (North)', 'Frog Rock (Inner)', 'Archery Game Rock (South)', - 'Big Bomb Shop Water Exit', 'Hammer Bridge Pegs (North)', 'Hammer Bridge Pegs (South)', 'Hammer Bridge Pier', diff --git a/Regions.py b/Regions.py index 5d3ff3d6..9ee4a9ce 100644 --- a/Regions.py +++ b/Regions.py @@ -68,7 +68,7 @@ def create_regions(world, player): create_lw_region(player, 'Hyrule Castle Courtyard Northeast', None, ['Hyrule Castle Courtyard Bush (North)', 'Hyrule Castle Secret Entrance Stairs']), create_lw_region(player, 'Hyrule Castle Ledge', None, ['Hyrule Castle Ledge Drop', 'Hyrule Castle Ledge Courtyard Drop', 'Inverted Pyramid Entrance', 'Hyrule Castle Entrance (West)', 'Agahnims Tower', 'Hyrule Castle Entrance (East)', 'Inverted Pyramid Hole'], 'the castle rampart'), create_lw_region(player, 'Hyrule Castle East Entry', None, ['Hyrule Castle Outer East Rock', 'Hyrule Castle ES']), - create_dw_region(player, 'Hyrule Castle Water', None, ['Blacksmith Water Exit'], 'Dark World', Terrain.Water), + create_lw_region(player, 'Hyrule Castle Water', None, [], 'Light World', Terrain.Water), create_lw_region(player, 'Wooden Bridge Area', None, ['Wooden Bridge Bush (South)', 'Wooden Bridge Water Drop', 'Wooden Bridge NW', 'Wooden Bridge SW']), create_lw_region(player, 'Wooden Bridge Northeast', None, ['Wooden Bridge Bush (North)', 'Wooden Bridge Northeast Water Drop', 'Wooden Bridge NE']), create_lw_region(player, 'Wooden Bridge Water', None, ['Wooden Bridge NC'], 'Light World', Terrain.Water), @@ -178,7 +178,7 @@ def create_regions(world, player): create_dw_region(player, 'Pyramid Crack', None, ['Pyramid Fairy']), create_dw_region(player, 'Pyramid Exit Ledge', None, ['Pyramid Exit Ledge Drop', 'Pyramid Entrance']), create_dw_region(player, 'Pyramid Pass', None, ['Post Aga Inverted Teleporter', 'Pyramid SW', 'Pyramid SE']), - create_dw_region(player, 'Pyramid Water', None, ['Hammerpegs Water Exit', 'Big Bomb Shop Water Exit'], 'Dark World', Terrain.Water), + create_dw_region(player, 'Pyramid Water', None, [], 'Dark World', Terrain.Water), create_dw_region(player, 'Broken Bridge Area', None, ['Broken Bridge Hammer Rock (South)', 'Broken Bridge Water Drop', 'Broken Bridge SW']), create_dw_region(player, 'Broken Bridge Northeast', None, ['Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', 'Broken Bridge Northeast Water Drop', 'Broken Bridge NE']), create_dw_region(player, 'Broken Bridge West', None, ['Broken Bridge West Water Drop', 'Broken Bridge NW']), From 4d62a2c7c49c9801da1b0ddea6d25f7f231a987a Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 18 Feb 2023 21:22:31 -0600 Subject: [PATCH 132/146] Suppressing console output for unconnected exits --- DoorShuffle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index de9a398a..701b3e4d 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -3346,7 +3346,8 @@ def create_doors_for_inaccessible_region(inaccessible_region, world, player): for ext in region.exits: create_door(world, player, ext.name, region.name) if ext.connected_region is None: - logging.getLogger('').warning('Exit not connected to any region: %s', ext.name) + # TODO: Since Open/Inverted regions are merged into one world model, some exits are left disconnected intentionally + logging.getLogger('').debug('Exit not connected to any region: %s', ext.name) elif ext.connected_region.name.endswith(' Portal'): for more_exts in ext.connected_region.exits: create_door(world, player, more_exts.name, ext.connected_region.name) From 7e6488656cdd71d3470fe244dbd4641fcd0d8968 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 18 Feb 2023 21:33:30 -0600 Subject: [PATCH 133/146] Minor assert addition --- EntranceShuffle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index cb1a5bf2..3d31172a 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -816,7 +816,7 @@ def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, must # if world.logic[player] in ['owglitches', 'nologic']: # import OverworldGlitchRules - # for entrance in OverworldGlitchRules.get_non_mandatory_exits(world.mode[player] == 'inverted'): + # for entrance in OverworldGlitchRules.get_non_mandatory_exits(world, player): # if entrance in must_be_exits: # must_be_exits.remove(entrance) # entrances.append(entrance) @@ -1437,6 +1437,7 @@ def place_old_man(world, pool, player, ignore_list=[]): old_man_entrances = [e for e in old_man_entrances if e != 'Old Man House (Bottom)' and e not in ignore_list] if world.shuffle[player] in ['lite', 'lean']: old_man_entrances = [e for e in old_man_entrances if e in pool] + assert len(old_man_entrances), 'No available entrances left to place Old Man Cave' random.shuffle(old_man_entrances) old_man_exit = None while not old_man_exit: From 4ea0eda0b930e05a02be93039f8dcc9edb8c55c3 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 22 Feb 2023 17:37:27 -0600 Subject: [PATCH 134/146] Initializing districts after OWR so ER can use them --- Main.py | 3 +++ source/item/District.py | 33 +++++++++++++++++++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Main.py b/Main.py index c05828fc..4a7407be 100644 --- a/Main.py +++ b/Main.py @@ -30,6 +30,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops, fill_specific_items, create_farm_locations from Utils import output_path, parse_player_names +from source.item.District import init_districts from source.item.FillUtil import create_item_pool_config, massage_item_pool, district_item_pool_config from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data @@ -224,6 +225,8 @@ def main(args, seed=None, fish=None): update_world_regions(world, player) mark_light_dark_world_regions(world, player) create_dynamic_exits(world, player) + + init_districts(world) logger.info(world.fish.translate("cli","cli","shuffling.world")) diff --git a/source/item/District.py b/source/item/District.py index d9e9e23e..3cd58a1f 100644 --- a/source/item/District.py +++ b/source/item/District.py @@ -43,7 +43,7 @@ def create_district_helper(world, player): world.districts[player] = districts -def resolve_districts(world): +def init_districts(world): def exclude_area(world, owid, area, player): # area can be a region or entrancecurrently, could potentially be a problem later if name collision std_regions = ['Pyramid Ledge', 'Pyramid Hole', 'Pyramid Entrance'] @@ -54,14 +54,7 @@ def resolve_districts(world): return False create_districts(world) - state = CollectionState(world) - state.sweep_for_events() for player in range(1, world.players + 1): - # these are not static for OWR - but still important - inaccessible = [r for r in inaccessible_regions_std if not world.is_tile_swapped(OWTileRegions[r], player)] - inaccessible = inaccessible + [r for r in inaccessible_regions_inv if world.is_tile_swapped(OWTileRegions[r], player)] - check_set = find_reachable_locations(state, player) - # adding regions to districts for owid, (alt_regions, alt_districts, default_districts) in OWTileDistricts.items(): idx = 0 if (world.mode[player] == 'inverted') == world.is_tile_swapped(owid, player) else 1 @@ -81,7 +74,26 @@ def resolve_districts(world): world.districts[player][alt_districts[(idx + 1) % 2]].regions.append(region) else: world.districts[player][default_districts[(idx + 1) % 2]].regions.append(region) - + + # adding entrances to districts + for name, district in world.districts[player].items(): + if not district.dungeon: + for region_name in district.regions: + region = world.get_region(region_name, player) + for exit in region.exits: + if exit.spot_type == 'Entrance' and not exclude_area(world, OWTileRegions[region.name], exit.name, player): + district.entrances.append(exit.name) + + +def resolve_districts(world): + state = CollectionState(world) + state.sweep_for_events() + for player in range(1, world.players + 1): + # these are not static for OWR - but still important + inaccessible = [r for r in inaccessible_regions_std if not world.is_tile_swapped(OWTileRegions[r], player)] + inaccessible = inaccessible + [r for r in inaccessible_regions_inv if world.is_tile_swapped(OWTileRegions[r], player)] + check_set = find_reachable_locations(state, player) + for name, district in world.districts[player].items(): if district.dungeon: layout = world.dungeon_layouts[player][district.dungeon] @@ -93,9 +105,6 @@ def resolve_districts(world): for location in region.locations: if not location.item and location.real: district.locations.add(location.name) - for exit in region.exits: - if exit.spot_type == 'Entrance' and not exclude_area(world, OWTileRegions[region.name], exit.name, player): - district.entrances.append(exit.name) for entrance in district.entrances: ent = world.get_entrance(entrance, player) queue = deque([ent.connected_region]) From 2c10c3b6ebc059c0a5500db1a8f5dc06af5b4466 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 22 Feb 2023 17:37:48 -0600 Subject: [PATCH 135/146] Minor incorrect region error --- Regions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Regions.py b/Regions.py index 9ee4a9ce..0bbca8b0 100644 --- a/Regions.py +++ b/Regions.py @@ -16,7 +16,7 @@ def create_regions(world, player): create_lw_region(player, 'West Death Mountain (Top)', ['Ether Tablet'], ['Spectacle Rock Approach', 'West Death Mountain Drop', 'Tower of Hera', 'West Death Mountain EN']), create_lw_region(player, 'Spectacle Rock Ledge', ['Spectacle Rock'], ['Spectacle Rock Leave', 'Spectacle Rock Drop']), create_lw_region(player, 'West Death Mountain (Bottom)', ['Old Man Drop Off'], ['Old Man Drop Off', 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'West Death Mountain Teleporter', 'West Death Mountain ES']), - create_dw_region(player, 'Old Man Drop Off', ['Old Man'], None), + create_lw_region(player, 'Old Man Drop Off', ['Old Man'], None), create_lw_region(player, 'East Death Mountain (Top West)', None, ['DM Hammer Bridge (West)', 'East Death Mountain WN']), create_lw_region(player, 'East Death Mountain (Top East)', None, ['DM Hammer Bridge (East)', 'Floating Island Bridge (East)', 'East Death Mountain Spiral Ledge Drop', 'East Death Mountain Fairy Ledge Drop', 'East Death Mountain Mimic Ledge Drop', 'Paradox Cave (Top)', 'East Death Mountain EN']), create_lw_region(player, 'Spiral Cave Ledge', None, ['Spiral Ledge Drop', 'Spiral Mimic Bridge (West)', 'Spiral Cave']), From 121c9424c1b42802638927fb0ef63dd34df92c76 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Wed, 22 Feb 2023 18:56:53 -0600 Subject: [PATCH 136/146] Moving OneWayLedge list to OWR code --- EntranceShuffle.py | 49 +++------------------------------------------ OverworldShuffle.py | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 3d31172a..e5b58111 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1716,6 +1716,7 @@ def unbias_dungeons(Dungeon_Exits): def build_accessible_entrance_list(world, start_region, player, assumed_inventory=[], cross_world=False, region_rules=True, exit_rules=True, include_one_ways=False): from Main import copy_world_premature from Items import ItemFactory + from OverworldShuffle import one_way_ledges for p in range(1, world.players + 1): world.key_logic[p] = {} @@ -1784,6 +1785,8 @@ def get_starting_entrances(world, player, force_starting_world=True): def get_distant_entrances(world, start_entrance, player): + from OverworldShuffle import one_way_ledges + # get walkable sector in which initial entrance was placed start_region = world.get_entrance(start_entrance, player).parent_region.name regions = next(s for s in world.owsectors[player] if any(start_region in w for w in s)) @@ -2361,52 +2364,6 @@ open_default_dungeon_connections = [('Ganons Tower', 'Ganons Tower Exit'), inverted_default_dungeon_connections = [('Ganons Tower', 'Agahnims Tower Exit'), ('Agahnims Tower', 'Ganons Tower Exit') ] - -one_way_ledges = { - 'West Death Mountain (Bottom)': {'West Death Mountain (Top)', - 'Spectacle Rock Ledge'}, - 'East Death Mountain (Bottom)': {'East Death Mountain (Top East)', - 'Spiral Cave Ledge'}, - 'Fairy Ascension Plateau': {'Fairy Ascension Ledge'}, - 'Mountain Entry Area': {'Mountain Entry Ledge'}, - 'Sanctuary Area': {'Bonk Rock Ledge'}, - 'Graveyard Area': {'Graveyard Ledge'}, - 'Potion Shop Water': {'Potion Shop Area', - 'Potion Shop Northeast'}, - 'Zora Approach Water': {'Zora Approach Area'}, - 'Hyrule Castle Area': {'Hyrule Castle Ledge'}, - 'Hyrule Castle Courtyard': {'Hyrule Castle Ledge'}, - 'Wooden Bridge Water': {'Wooden Bridge Area', - 'Wooden Bridge Northeast'}, - 'Maze Race Area': {'Maze Race Ledge', - 'Maze Race Prize'}, - 'Flute Boy Approach Area': {'Cave 45 Ledge'}, - 'Desert Area': {'Desert Ledge', - 'Desert Checkerboard Ledge', - 'Desert Palace Mouth', - 'Bombos Tablet Ledge', - 'Desert Palace Teleporter Ledge'}, - 'Desert Pass Area': {'Desert Pass Ledge'}, - 'Lake Hylia Water': {'Lake Hylia South Shore', - 'Lake Hylia Island'}, - 'West Dark Death Mountain (Bottom)': {'West Dark Death Mountain (Top)'}, - 'East Dark Death Mountain (Top)': {'Dark Death Mountain Floating Island'}, - 'East Dark Death Mountain (Bottom)': {'East Dark Death Mountain (Top)'}, - 'Turtle Rock Area': {'Turtle Rock Ledge'}, - 'Bumper Cave Area': {'Bumper Cave Ledge'}, - 'Qirn Jump Water': {'Qirn Jump Area'}, - 'Dark Witch Water': {'Dark Witch Area', - 'Dark Witch Northeast'}, - 'Catfish Approach Water': {'Catfish Approach Area'}, - 'Pyramid Area': {'Pyramid Exit Ledge'}, - 'Broken Bridge Water': {'Broken Bridge West', - 'Broken Bridge Area', - 'Broken Bridge Northeast'}, - 'Misery Mire Area': {'Misery Mire Teleporter Ledge'}, - 'Ice Lake Water': {'Ice Lake Area', - 'Ice Lake Ledge (West)', - 'Ice Lake Ledge (East)'} -} # format: # Key=Name # addr = (door_index, exitdata, ow_flag) # multiexit diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 7c8451bf..35b41271 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -2017,6 +2017,52 @@ default_connections = [('Lost Woods NW', 'Master Sword Meadow SC'), ('East Dark Death Mountain EN', 'Turtle Rock WN') ] +one_way_ledges = { + 'West Death Mountain (Bottom)': {'West Death Mountain (Top)', + 'Spectacle Rock Ledge'}, + 'East Death Mountain (Bottom)': {'East Death Mountain (Top East)', + 'Spiral Cave Ledge'}, + 'Fairy Ascension Plateau': {'Fairy Ascension Ledge'}, + 'Mountain Entry Area': {'Mountain Entry Ledge'}, + 'Sanctuary Area': {'Bonk Rock Ledge'}, + 'Graveyard Area': {'Graveyard Ledge'}, + 'Potion Shop Water': {'Potion Shop Area', + 'Potion Shop Northeast'}, + 'Zora Approach Water': {'Zora Approach Area'}, + 'Hyrule Castle Area': {'Hyrule Castle Ledge'}, + 'Hyrule Castle Courtyard': {'Hyrule Castle Ledge'}, + 'Wooden Bridge Water': {'Wooden Bridge Area', + 'Wooden Bridge Northeast'}, + 'Maze Race Area': {'Maze Race Ledge', + 'Maze Race Prize'}, + 'Flute Boy Approach Area': {'Cave 45 Ledge'}, + 'Desert Area': {'Desert Ledge', + 'Desert Checkerboard Ledge', + 'Desert Palace Mouth', + 'Bombos Tablet Ledge', + 'Desert Palace Teleporter Ledge'}, + 'Desert Pass Area': {'Desert Pass Ledge'}, + 'Lake Hylia Water': {'Lake Hylia South Shore', + 'Lake Hylia Island'}, + 'West Dark Death Mountain (Bottom)': {'West Dark Death Mountain (Top)'}, + 'East Dark Death Mountain (Top)': {'Dark Death Mountain Floating Island'}, + 'East Dark Death Mountain (Bottom)': {'East Dark Death Mountain (Top)'}, + 'Turtle Rock Area': {'Turtle Rock Ledge'}, + 'Bumper Cave Area': {'Bumper Cave Ledge'}, + 'Qirn Jump Water': {'Qirn Jump Area'}, + 'Dark Witch Water': {'Dark Witch Area', + 'Dark Witch Northeast'}, + 'Catfish Approach Water': {'Catfish Approach Area'}, + 'Pyramid Area': {'Pyramid Exit Ledge'}, + 'Broken Bridge Water': {'Broken Bridge West', + 'Broken Bridge Area', + 'Broken Bridge Northeast'}, + 'Misery Mire Area': {'Misery Mire Teleporter Ledge'}, + 'Ice Lake Water': {'Ice Lake Area', + 'Ice Lake Ledge (West)', + 'Ice Lake Ledge (East)'} +} + isolated_regions = [ 'Death Mountain Floating Island', 'Mimic Cave Ledge', From 409f7d50d5829e779a6bfcf9ebf6ec2e7895f20b Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 24 Feb 2023 14:25:04 -0700 Subject: [PATCH 137/146] Rom changes (see that commmit message or release notes) Customizer improvements: - Better logic around customized lobbies - Better logic around customized door types Fix to key doors that was causing extra key doors Generation improvement around crystal switches Fix bug in dungeon_only that wasn't using pot key locations (known issue still exists in pottery modes) Fixes an issue when keys are found in own dungeon for another player when using the bizhawk plugin --- DoorShuffle.py | 80 +++++++++++++++++++++----------- Doors.py | 2 +- DungeonGenerator.py | 9 +++- Main.py | 2 +- README.md | 23 ++++----- RELEASENOTES.md | 13 ++++++ Rom.py | 4 +- RoomData.py | 4 +- data/base2current.bps | Bin 93523 -> 93908 bytes source/item/FillUtil.py | 2 +- test/customizer/multi_test.yaml | 23 +++++++++ test/customizer/test_stuff.yaml | 54 ++++++++++++++------- 12 files changed, 152 insertions(+), 64 deletions(-) create mode 100644 test/customizer/multi_test.yaml diff --git a/DoorShuffle.py b/DoorShuffle.py index 308a0731..6bafd806 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -128,7 +128,7 @@ def link_doors_prep(world, player): vanilla_key_logic(world, player) -def link_doors_main(world, player): +def create_dungeon_pool(world, player): pool = None if world.doorShuffle[player] == 'basic': pool = [([name], regions) for name, regions in dungeon_regions.items()] @@ -142,6 +142,11 @@ def link_doors_main(world, player): elif world.doorShuffle[player] != 'vanilla': logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player]) raise Exception('Invalid door shuffle setting: %s' % world.doorShuffle[player]) + return pool + + +def link_doors_main(world, player): + pool = create_dungeon_pool(world, player) if pool: main_dungeon_pool(pool, world, player) if world.doorShuffle[player] != 'vanilla': @@ -557,7 +562,9 @@ def customizer_portals(master_door_list, world, player): custom_doors = world.customizer.get_doors()[player] if custom_doors and 'lobbies' in custom_doors: for portal, assigned_door in custom_doors['lobbies'].items(): - door = next(x for x in master_door_list if x.name == assigned_door) + door = next((x for x in master_door_list if x.name == assigned_door), None) + if door is None: + raise Exception(f'{assigned_door} not found. Check for typos') custom_portals[portal] = door assigned_doors.add(door) if custom_doors and 'doors' in custom_doors: @@ -570,6 +577,24 @@ def customizer_portals(master_door_list, world, player): elif 'dest' in dest: door = world.get_door(dest['dest'], player) assigned_doors.add(door) + # restricts connected doors to the customized portals + if assigned_doors: + pool = create_dungeon_pool(world, player) + if pool: + pool_map = {} + for pool, region_list in pool: + sector_pool = convert_to_sectors(region_list, world, player) + merge_sectors(sector_pool, world, player) + for p in pool: + pool_map[p] = sector_pool + for portal, assigned_door in custom_portals.items(): + portal_region = world.get_door(assigned_door, player).entrance.parent_region + portal_dungeon = world.get_region(f'{portal} Portal', player).dungeon.name + sector_pool = pool_map[portal_dungeon] + sector = next((s for s in sector_pool if portal_region in s.regions), None) + for door in sector.outstanding_doors: + if door.portalAble: + door.dungeonLink = portal_dungeon return custom_portals, assigned_doors @@ -1718,7 +1743,6 @@ def setup_custom_door_types(world, player): custom_doors = custom_doors[player] if 'doors' not in custom_doors: return - # todo: dash/bomb door pool specific customizeable_types = ['Key Door', 'Dash Door', 'Bomb Door', 'Trap Door', 'Big Key Door'] world.custom_door_types[player] = type_map = {x: defaultdict(list) for x in customizeable_types} for door, dest in custom_doors['doors'].items(): @@ -1731,7 +1755,7 @@ def setup_custom_door_types(world, player): type_map[door_kind][dungeon.name].append(d) else: # check if the dest is paired - if d.dest.type in [DoorType.Interior, DoorType.Normal] and door_kind != 'Trap Door': + if d.dest and d.dest.type in [DoorType.Interior, DoorType.Normal] and door_kind != 'Trap Door': type_map[door_kind][dungeon.name].append((d, d.dest)) else: type_map[door_kind][dungeon.name].append(d) @@ -1783,18 +1807,24 @@ def shuffle_door_types(door_type_pools, paths, world, player): start_regions_map[name] = start_regions builder.candidates = BuilderDoorCandidates() + all_custom = defaultdict(list) + if player in world.custom_door_types: + for custom_dict in world.custom_door_types[player].values(): + for dungeon, doors in custom_dict.items(): + all_custom[dungeon].extend(doors) + world.paired_doors[player].clear() - used_doors = shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player) + used_doors = shuffle_trap_doors(door_type_pools, paths, start_regions_map, all_custom, world, player) # big keys - used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, player) + used_doors = shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player) # small keys - used_doors = shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, world, player) + used_doors = shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player) # bombable / dashable - used_doors = shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, world, player) + used_doors = shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player) # handle paired list -def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player): +def shuffle_trap_doors(door_type_pools, paths, start_regions_map, all_custom, world, player): used_doors = set() for pool, door_type_pool in door_type_pools: if world.trap_door_mode[player] != 'oneway': @@ -1805,15 +1835,14 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player) custom_trap_doors = world.custom_door_types[player]['Trap Door'] else: custom_trap_doors = defaultdict(list) - for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] if 'Mire Warping Pool' in builder.master_sector.region_set(): custom_trap_doors[dungeon].append(world.get_door('Mire Warping Pool ES', player)) world.custom_door_types[player]['Trap Door'] = custom_trap_doors find_trappable_candidates(builder, world, player) - if custom_trap_doors[dungeon]: - builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, custom_trap_doors[dungeon]) + if all_custom[dungeon]: + builder.candidates.trap = filter_key_door_pool(builder.candidates.trap, all_custom[dungeon]) remaining -= len(custom_trap_doors[dungeon]) ttl += len(builder.candidates.trap) if ttl == 0: @@ -1865,7 +1894,7 @@ def shuffle_trap_doors(door_type_pools, paths, start_regions_map, world, player) return used_doors -def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, player): +def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player): for pool, door_type_pool in door_type_pools: ttl = 0 suggestion_map, bk_map, flex_map = {}, {}, {} @@ -1878,8 +1907,8 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] find_big_key_candidates(builder, start_regions_map[dungeon], used_doors, world, player) - if custom_bk_doors[dungeon]: - builder.candidates.big = filter_key_door_pool(builder.candidates.big, custom_bk_doors[dungeon]) + if all_custom[dungeon]: + builder.candidates.big = filter_key_door_pool(builder.candidates.big, all_custom[dungeon]) remaining -= len(custom_bk_doors[dungeon]) ttl += len(builder.candidates.big) if ttl == 0: @@ -1925,7 +1954,7 @@ def shuffle_big_key_doors(door_type_pools, used_doors, start_regions_map, world, return used_doors -def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, world, player): +def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player): max_computation = 11 # this is around 6 billion worse case factorial don't want to exceed this much for pool, door_type_pool in door_type_pools: ttl = 0 @@ -1943,8 +1972,8 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl builder.total_keys = total_keys find_small_key_door_candidates(builder, start_regions_map[dungeon], used_doors, world, player) custom_doors = 0 - if custom_key_doors[dungeon]: - builder.candidates.small = filter_key_door_pool(builder.candidates.small, custom_key_doors[dungeon]) + if all_custom[dungeon]: + builder.candidates.small = filter_key_door_pool(builder.candidates.small, all_custom[dungeon]) custom_doors = len(custom_key_doors[dungeon]) remaining -= custom_doors builder.key_doors_num = max(0, len(builder.candidates.small) - builder.key_drop_cnt) + custom_doors @@ -1960,13 +1989,10 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl suggested = min(calculated, limit) key_door_num = min(suggested + builder.key_drop_cnt, max_computation) combo_size = ncr(len(builder.candidates.small), key_door_num) - while combo_size > 500000 and suggested > 0: - suggested -= 1 - combo_size = ncr(len(builder.candidates.small), key_door_num) suggestion_map[dungeon] = builder.key_doors_num = key_door_num - remaining -= suggested + builder.key_drop_cnt + remaining -= key_door_num + builder.key_drop_cnt builder.combo_size = combo_size - flex_map[dungeon] = (limit - suggested) if suggested < limit else 0 + flex_map[dungeon] = (limit - key_door_num) if key_door_num < limit else 0 for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] if total_adjustable: @@ -2025,7 +2051,7 @@ def shuffle_small_key_doors(door_type_pools, used_doors, start_regions_map, worl return used_doors -def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, world, player): +def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, all_custom, world, player): for pool, door_type_pool in door_type_pools: ttl = 0 suggestion_map, bd_map = {}, {} @@ -2042,11 +2068,9 @@ def shuffle_bomb_dash_doors(door_type_pools, used_doors, start_regions_map, worl for dungeon in pool: builder = world.dungeon_layouts[player][dungeon] find_bd_candidates(builder, start_regions_map[dungeon], used_doors, world, player) - if custom_bomb_doors[dungeon]: - builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, custom_bomb_doors[dungeon]) + if all_custom[dungeon]: + builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, all_custom[dungeon]) remaining_bomb -= len(custom_bomb_doors[dungeon]) - if custom_dash_doors[dungeon]: - builder.candidates.bomb_dash = filter_key_door_pool(builder.candidates.bomb_dash, custom_dash_doors[dungeon]) remaining_dash -= len(custom_dash_doors[dungeon]) ttl += len(builder.candidates.bomb_dash) if ttl == 0: diff --git a/Doors.py b/Doors.py index edc51ac0..0bd13742 100644 --- a/Doors.py +++ b/Doors.py @@ -66,7 +66,7 @@ def create_doors(world, player): create_door(player, 'Hyrule Castle Back Hall Down Stairs', Sprl).dir(Dn, 0x01, 0, HTL).ss(A, 0x2a, 0x00), create_door(player, 'Hyrule Castle Throne Room Tapestry', Lgcl), create_door(player, 'Hyrule Castle Tapestry Backwards', Lgcl), - create_door(player, 'Hyrule Castle Throne Room N', Nrml).dir(No, 0x51, Mid, High).pos(1), + create_door(player, 'Hyrule Castle Throne Room N', Nrml).dir(No, 0x51, Mid, High).pos(0), create_door(player, 'Hyrule Castle Throne Room South Stairs', StrS).dir(So, 0x51, Mid, Low), # hyrule dungeon level diff --git a/DungeonGenerator.py b/DungeonGenerator.py index 9be244f8..e429719a 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1824,6 +1824,7 @@ def ensure_crystal_switches_reachable(dungeon_map, crystal_switches, polarized_s for name, builder in dungeon_map.items(): if builder.c_switch_present and builder.c_switch_required and not builder.c_locked: invalid_builders.append(builder) + random.shuffle(invalid_builders) while len(invalid_builders) > 0: valid_builders = [] for builder in invalid_builders: @@ -1849,6 +1850,7 @@ def ensure_crystal_switches_reachable(dungeon_map, crystal_switches, polarized_s if eq.c_switch: reachable_crystals[hook_from_door(eq.door)] = True valid_ent_sectors = [] + random.shuffle(entrance_sectors) for entrance_sector in entrance_sectors: other_sectors = [x for x in builder.sectors if x != entrance_sector] reachable, access = is_c_switch_reachable(entrance_sector, reachable_crystals, other_sectors) @@ -1866,7 +1868,12 @@ def ensure_crystal_switches_reachable(dungeon_map, crystal_switches, polarized_s while not valid: if len(candidates) <= 0: raise GenerationException(f'need to provide more sophisticated crystal connection for {entrance_sector}') - sector, which_list = random.choice(list(candidates.items())) + # prioritize candidates + if any(x == 'Crystals' for x in candidates.values()): + cand_list = [x for x in candidates.items() if x[1] == 'Crystals'] + else: + cand_list = list(candidates.items()) + sector, which_list = random.choice(cand_list) del candidates[sector] valid = global_pole.is_valid_choice(dungeon_map, builder, [sector]) if which_list == 'Polarized': diff --git a/Main.py b/Main.py index a39fbe57..7266628d 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -__version__ = '1.2.0.8-u' +__version__ = '1.2.0.9-u' from source.classes.BabelFish import BabelFish diff --git a/README.md b/README.md index 6af52f44..fbe9eed5 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,15 @@ See https://alttpr.com/ for more details on the normal randomizer. 1. [Dungeon Door Shuffle](#door-shuffle) 2. [Intensity Level](#intensity---intensity-number) 3. [Key Drop Shuffle (Legacy)](#key-drop-shuffle-legacy---keydropshuffle) - 4. [Door Type Shuffle](#door-type_shuffle) - 5. [Decouple Doors](#decouple-doors) - 6. [Pottery](#pottery) - 7. [Small Key Shuffle](#small-key-shuffle) - 8. [Shuffle Enemy Key Drops](#shuffle-enemy-key-drops) - 9. [Experimental Features](#experimental-features) - 10. [Crossed Dungeon Specific Settings](#crossed-dungeon-specific-settings) + 4. [Door Type Shuffle](#door-type-shuffle) + 5. [Trap Door Removal](#trap-door-removal) + 6. [Key Logic Algorithm](#key-logic-algorithm) + 7. [Decouple Doors](#decouple-doors) + 8. [Pottery](#pottery) + 9. [Small Key Shuffle](#small-key-shuffle) + 10. [Shuffle Enemy Key Drops](#shuffle-enemy-key-drops) + 11. [Experimental Features](#experimental-features) + 12. [Crossed Dungeon Specific Settings](#crossed-dungeon-specific-settings) 2. [Item Randomization Changes](#item-randomization) 1. [New "Items"](#new-items) 2. [Shopsanity](#shopsanity) @@ -40,7 +42,7 @@ See https://alttpr.com/ for more details on the normal randomizer. ### Feedback and Bug Reports -Please just DM me on discord for now. I (Aerinon) can be found at the [ALTTP Randomizer discord](https://discordapp.com/invite/alttprandomizer). +You can use the #bug-reports or #door-rando channel at the [ALTTP Randomizer discord](https://discordapp.com/invite/alttprandomizer) to provide feedback or bug reports. ### Installation @@ -73,15 +75,14 @@ Most of these apply only when the door shuffle is not vanilla. ### Starting Item -You start with a “Mirror Scroll”, a dumbed-down mirror that only works in dungeons, not the overworld and can’t erase blocks like the Mirror. +You start with a “Mirror Scroll” (it looks like a map), a dumbed-down mirror that only works in dungeons, not the overworld, and can’t erase blocks like the Mirror. ### Navigation -* The Pinball Room’s trap door can be removed in the case where it is required to go through to get to the back of Skull Woods. * Holes in Mire Torches Top and Mire Torches Bottom fall through to rooms below (you only need fire to get the chest) * You can Hookshot from the left Mire wooden Bridge to the right one. * In the PoD Arena, you can bonk with Boots between the two blue crystal barriers against the ladder to reach the Arena Bridge chest and door. (Bomb Jump also possible but not in logic - Boots are required) -* Flooded Rooms in Swamp can be traversed backward and may be required. +* Flooded Rooms in Swamp can be traversed backward and may be required. The flippers are needed to get out of the water. ### Other Logic diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 0328487c..d5a492b1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -108,6 +108,19 @@ These are now independent of retro mode and have three options: None, Random, an * Bonk Fairy (Dark) # Bug Fixes and Notes +* 1.2.0.9-u + * Disallowed standard exits (due to ER) are now graphically half blocked instead of missing + * Graphical issues with Sanctuary and Swamp Hub lobbies are fixed + * Fixes an issue surrounding door state and decoupled doors leading to blocked doors + * Customizer improvements: + * Better logic around customized lobbies + * Better logic around customized door types + * Fix to key doors that was causing extra key doors + * Generation improvement around crystal switches + * Fix bug in dungeon_only that wasn't using pot key locations (known issue still exists in pottery modes) + * Fixes for multiworld: + * Fixes an issue when keys are found in own dungeon for another player when using the bizhawk plugin. + * Fixes an issue with absorbables for another player also being received by the player picking it up. * 1.2.0.8-u * New Features: trap_door_mode and key_logic_algorithm * Change S&Q in door shuffle + standard during escape to spawn as Uncle diff --git a/Rom.py b/Rom.py index 3e353b3a..1dd05a8f 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '6f64fcea052e37b39d6b4bb24ae2f548' +RANDOMIZERBASEHASH = '67279b96a589f09e3ba8393a5bc5f071' class JsonRom(object): @@ -572,7 +572,7 @@ class Sprite(object): def handle_native_dungeon(location, itemid): # Keys in their native dungeon should use the original item code for keys - if location.parent_region.dungeon: + if location.parent_region.dungeon and location.player == location.item.player: if location.parent_region.dungeon.name == location.item.dungeon: if location.item.bigkey: return 0x32 diff --git a/RoomData.py b/RoomData.py index d8d3a82a..13339364 100644 --- a/RoomData.py +++ b/RoomData.py @@ -244,7 +244,9 @@ def create_rooms(world, player): # Room(player, 0xff, 0x52c9a).door(Position.InteriorW, DoorKind.Bombable).door(Position.InteriorE, DoorKind.Bombable).door(Position.SouthE, DoorKind.CaveEntrance), ] # fix some wonky things - world.get_room(0x51, player).change(1, DoorKind.Normal) # fix the dungeon changer + # should I put back the dungeon changer for certain logic - like no logic? maybe in basic + if world.doorShuffle[player] != 'vanilla': + world.get_room(0x51, player).delete(1) # remove the dungeon changer world.get_room(0x60, player).swap(2, 4) # puts the exit at pos 2 - enables pos 3 world.get_room(0x61, player).swap(1, 6) # puts the WN door at pos 1 - enables it world.get_room(0x61, player).swap(5, 6) # puts the Incognito Entrance at the end, so it can be deleted diff --git a/data/base2current.bps b/data/base2current.bps index 93e4cfd280c90a77261c2e40c3ac5c95ef7ece69..be3d11ea1f94a232964df475e95479bc094ec0cc 100644 GIT binary patch delta 3181 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 H2Alo^TSOZ1 delta 2862 zcmW+&dstM}7C-CE6BypF;UOFjh>Qx3n2LxD>@#qHVI1ah zgbj?u@R()>!T~1pS{X=c(*3G2qpwT(-NNwd+_Yn1b^YpckN1zg_u6Z%z4ki4-&yON zFRx3kO-js-FyCUhw)6URng)U-&d#14WX`siOWrCPVw%;>9rQ?((@bjo&!(bgdS{ap z0oR>4ZJ}FDPJh)EBYl0yb;xY-(@LZB*}675-{>3!jrxXu(dAwWS?FPI1iIlO_cBSx z)|_yrH4e}%6L$Kq-vk$5tLZJMH_}C%ja(HIe8TA%;-xK>IX^v(^v(57vCc?e;O>$! z%TLrg#mGqC{JeLxjhL1)1FqRy_qh3=oiHp>C7+fTY?3QCb@Uyxgi~= zUH(d>5BS7hjP#4RKjbEOi#rie9CF?0yy&21O-{d`{>{k!8n9VDHstdE%}8J4HU|C< zUhfk@e}S020wI2dm67CZ6wq3E+Lb6g!i(HTidV@eP2Q~F1`=G}v!U;b;f}W~>bwdl z@521e0GV9X>LN1F1hwz%VlkY7 zg+?*Esnn|cvRQlj1+hMV&Ae2GsQSU3iAV(GW51u zXK}QF#AQ-QPvvWmpg2driXi{pHzGq$im!F_=iHVPZ2u8Nmh@Yf81cJO*c!3&U(BtR z1M3WPk(l~`WeI8m$IBoW#CW?57O#s@{1A=CkAYd@4g)04xxJ6jP}}Rq2|jIH#wU&g zuN)T-D#uBmluIz^L&in8^u#%zcucL-jHz=p)C6l*;Z={~&t#yAURTh{95m_LsvgFx z2b_&MH!Q*mIi%0aTM&+zpiUhVYSJ;_)G;K znc>KGWInEvL!BhW*b~`=WdX2IF`(xvJGlLEZF(vWuMU9Rd3lh4?hD998XSG=S*bt@ zxjtuF$_KO3K;@o3w$BcxcT6&D4}cBi6P5T*03?R3FabJ4u`)YQD-6`n4LB}PU?mfO z9tio%vn?#`oLIkyk7 z;?_XrtKvTDDpo6imIe1PB3p3}-l>4a5Qhy4$lIHZPfUQn?u_6{QJg|p__x;^LFctB;vNe6oJ_AN#{N?5;??ur3fC3 zWFfNi4V)MZ$%=z>!cpg@#Bjt_4B)lFFehTo+ty7+%lIte3uuo%qT^mG$8Q9~(S)e| zjojQ_?L)$wBylvV3bY<6a^gpJwc}W<2!UhpIBpDqCDm_6KYo{4*B6r2%Is;`O|xBu zuh{c|ck(o@d_{(sgw8$X_Nzefk2wg{EHN(FSCqQtgx1rDiNoBz1>OIhy>)AZ=bhuT zv;3S(cHg}zYUEemd5Q1^wH!WbJ~Kv@=4i(#^mVCH+fB4@t1@?x?l7%8lx?={fMM(l zfjI(ncSB%V_2?`wqrSD;Nuks;xbazD*?#yr%YOv5ggRysl;YAw@cIYwgJvBx^ycb>l_SX>T*s^nPGArm%&)aQ^`#ei(e z6t07$S~-?*DDcrazqN@qI5P}V65nU!Cf$IUFiMz_<1!?vH0sq*b-P2CKL`2_{GgQI|_0l zR$(qo=a3OTQPC>w4$tu9;i@R0s58w@W%bo&r)xyRJKNU8T)E=DpC+t5OLO=xIi*8W8NYZMd&9&NF$KyD$d92Z0b1+n<0Xov?9u8M}F zxWhQ($OG-<2-WKBqqejPV&i&lp^lSaZ#1YN7hjKt{Oa^M?fRGujcHu?m$}?Ki4R^F z3R>ScGB|TQzEhYUyoR=__4-|Q!c)r-PF>p(4Qn?xiSf&u^m>xdZqF5a27D?HKkK|? z=fgZdbMqZ~xo5^y=k|q9sok;c^LM`^@qVd|9a9ILEZEE7*oYBRNiOPqYAd5xNQq$E zGjCkPzr;e8sA9SIY?=}ZWlxr~^2uF|fqf%)PP^E^CjKh*)qr{Nh*DFX7U)w+0y_n1 zN^K)VQOM{cew?`yq&5C5Hp62;7bVMG79 zEkpepYA;@y3N4At54L5ZDfI)PAjYWE&B3r@=}xdG}dQ8q8TQS6-Xk{O94@?Ee6hg`^Sy diff --git a/source/item/FillUtil.py b/source/item/FillUtil.py index 8c85bfdd..0252673f 100644 --- a/source/item/FillUtil.py +++ b/source/item/FillUtil.py @@ -163,7 +163,7 @@ def create_item_pool_config(world): dungeon_set = (mode_grouping['Big Chests'] + mode_grouping['Dungeon Trash'] + mode_grouping['Big Keys'] + mode_grouping['Heart Containers'] + mode_grouping['GT Trash'] + mode_grouping['Small Keys'] + mode_grouping['Compasses'] + mode_grouping['Maps'] + mode_grouping['Key Drops'] + - mode_grouping['Big Key Drops']) + mode_grouping['Pot Keys'] + mode_grouping['Big Key Drops']) for player in range(1, world.players + 1): config.item_pool[player] = determine_major_items(world, player) config.location_groups[0].locations = set(dungeon_set) diff --git a/test/customizer/multi_test.yaml b/test/customizer/multi_test.yaml new file mode 100644 index 00000000..360499ef --- /dev/null +++ b/test/customizer/multi_test.yaml @@ -0,0 +1,23 @@ +meta: + players: 2 +settings: + 1: + pottery: cavekeys + keysanity: True + 2: + keysanity: True +placements: + 1: + Sanctuary: Small Key (Escape)#2 + 'Links House Pot #3': Rupees (20)#2 +start_inventory: + 1: + - Pegasus Boots + - Ocarina (Activated) + - Magic Mirror + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Boss Heart Container + - Red Mail + - Golden Sword \ No newline at end of file diff --git a/test/customizer/test_stuff.yaml b/test/customizer/test_stuff.yaml index 552d5490..313d35d2 100644 --- a/test/customizer/test_stuff.yaml +++ b/test/customizer/test_stuff.yaml @@ -1,28 +1,46 @@ meta: players: 1 - race: true + algorithm: dungeon_only settings: 1: - shopsanity: true + goal: dungeons pseudoboots: true - goal: crystals - crystals_gt: random - keysanity: true door_shuffle: crossed + decoupledoors: true intensity: 3 - door_type_mode: big - pottery: keys - dropshuffle: true + door_type_mode: all experimental: true dungeon_counters: 'on' - hints: true - msu_resume: true - collection_rate: true - quickswap: true -start_inventory: + compassshuffle: true + mapshuffle: true + keydropshuffle: true +doors: 1: - - Pegasus Boots - - Ocarina (Activated) - - Magic Mirror - - Boss Heart Container - - Blue Mail \ No newline at end of file + lobbies: + Hyrule Castle South: Thieves Lobby S + doors: + Thieves Lobby NE Edge: + dest: Hyrule Castle Throne Room South Stairs + one-way: True + Hyrule Castle Throne Room South Stairs: + dest: Desert Beamos Hall NE + one-way: True + Desert Beamos Hall NE: + dest: Ice Spike Cross SE + type: Key Door + one-way: True + Ice Spike Cross SE: + dest: Thieves Lobby NE Edge + one-way: True + Hyrule Castle Throne Room N: + dest: Ice Firebar Down Ladder + type: Key Door + Swamp Lobby S: + dest: Thieves Lobby N Edge + type: Bomb Door + Thieves Lobby E: Thieves Compass Room W + Thieves Compass Room NW Edge: Ice Tall Hint SE + Thieves Compass Room N Edge: PoD Bow Statue Down Ladder + + + From c284b90f741f75c50ef926eba55ddd2e9ab73583 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 25 Feb 2023 20:16:27 -0600 Subject: [PATCH 138/146] Fixed issue where S&Q points getting set before Mixed OWR --- EntranceShuffle.py | 3 +-- OverworldShuffle.py | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index e5b58111..dc6e6fd4 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1402,8 +1402,7 @@ def place_blacksmith(world, links_house, player): invFlag = world.mode[player] == 'inverted' assumed_inventory = list() - region = world.get_region('Frog Prison', player) - if world.logic[player] in ['noglitches', 'minorglitches'] and region.type == (RegionType.DarkWorld if not invFlag else RegionType.LightWorld): + if world.logic[player] in ['noglitches', 'minorglitches'] and (world.is_tile_swapped(0x29, player) == invFlag): assumed_inventory.append('Titans Mitts') links_region = world.get_entrance(links_house, player).parent_region.name diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 35b41271..d916d711 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -14,21 +14,6 @@ version_branch = '-u' __version__ = '%s%s' % (version_number, version_branch) def link_overworld(world, player): - if not world.is_bombshop_start(player): - connect_simple(world, 'Links House S&Q', 'Links House', player) - else: - connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player) - - if not world.mode[player] == 'inverted': - connect_simple(world, 'Sanctuary S&Q', 'Sanctuary', player) - else: - connect_simple(world, 'Sanctuary S&Q', 'Dark Sanctuary Hint', player) - - if not world.is_tile_swapped(0x1b, player): - connect_simple(world, 'Other World S&Q', 'Pyramid Area', player) - else: - connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player) - # setup mandatory connections for exitname, regionname in mandatory_connections: connect_simple(world, exitname, regionname, player) @@ -183,6 +168,21 @@ def link_overworld(world, player): world.spoiler.set_map('swaps', text_output, world.owswaps[player][0], player) # apply tile logical connections + if not world.is_bombshop_start(player): + connect_simple(world, 'Links House S&Q', 'Links House', player) + else: + connect_simple(world, 'Links House S&Q', 'Big Bomb Shop', player) + + if not world.mode[player] == 'inverted': + connect_simple(world, 'Sanctuary S&Q', 'Sanctuary', player) + else: + connect_simple(world, 'Sanctuary S&Q', 'Dark Sanctuary Hint', player) + + if not world.is_tile_swapped(0x1b, player): + connect_simple(world, 'Other World S&Q', 'Pyramid Area', player) + else: + connect_simple(world, 'Other World S&Q', 'Hyrule Castle Ledge', player) + for owid in ow_connections.keys(): if not world.is_tile_swapped(owid, player): for (exitname, regionname) in ow_connections[owid][0]: From 9867424e605c815e61924cf199d50c0d4d576646 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 25 Feb 2023 21:38:22 -0600 Subject: [PATCH 139/146] Disable flute in rain state --- Rom.py | 2 +- data/base2current.bps | Bin 105489 -> 105524 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index 0b6fd1af..aaf94f2b 100644 --- a/Rom.py +++ b/Rom.py @@ -38,7 +38,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = 'e9a22882bb59523c19845274d76b3761' +RANDOMIZERBASEHASH = '695fe1ac7794b8fc2383454eb15cbdd5' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index 71f15e40f792d6488ee3a5105494c77f0cbf21d0..6621ea5b715fc6a18d75218daa0498103cad2e5c 100644 GIT binary patch delta 2513 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 F;{PS=Q;7fo delta 2507 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 D-2q&_ From a8d30c3686c86a2492af377267391c0eb253de7b Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 25 Feb 2023 21:39:13 -0600 Subject: [PATCH 140/146] Remove some glitch fixes from glitched modes --- Rom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rom.py b/Rom.py index aaf94f2b..e53fdb06 100644 --- a/Rom.py +++ b/Rom.py @@ -1586,7 +1586,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): rom.write_byte(0x1800A3, 0x01) # enable correct world setting behaviour after agahnim kills rom.write_byte(0x1800A4, 0x01 if world.logic[player] != 'nologic' else 0x00) # enable POD EG fix rom.write_byte(0x180042, 0x01 if world.save_and_quit_from_boss else 0x00) # Allow Save and Quit after boss kill - rom.write_byte(0x180358, 0x01 if world.logic[player] == 'nologic' else 0x00) + rom.write_byte(0x180358, 0x01 if world.logic[player] in ['owglitches', 'nologic'] else 0x00) # remove shield from uncle rom.write_bytes(0x6D253, [0x00, 0x00, 0xf6, 0xff, 0x00, 0x0E]) From 12cd83a92cb73d2be8c2474e3155d73cfaa91a20 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 25 Feb 2023 23:08:10 -0600 Subject: [PATCH 141/146] Reducing verbosity in DR generation --- DungeonGenerator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DungeonGenerator.py b/DungeonGenerator.py index e429719a..f97f8ecf 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -3572,7 +3572,7 @@ def check_for_valid_layout(builder, sector_list, builder_info): builder.exception_list = list(sector_list) return True, {}, package except (GenerationException, NeutralizingException, OtherGenException) as e: - logging.getLogger('').info(f'Bailing on this layout for {builder.name}', exc_info=1) + logging.getLogger('').debug(f'Bailing on this layout for {builder.name}', exc_info=1) builder.split_dungeon_map = None builder.valid_proposal = None if temp_builder.name == 'Hyrule Castle' and temp_builder.throne_door: From a6f5c3a1e6ae84ad77864ed6c607347d4a35e7fa Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 26 Feb 2023 13:11:30 -0600 Subject: [PATCH 142/146] Adding missing Mystery options in example --- mystery_example.yml | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/mystery_example.yml b/mystery_example.yml index a83cf5f5..a74a8914 100644 --- a/mystery_example.yml +++ b/mystery_example.yml @@ -31,6 +31,7 @@ door_shuffle: vanilla: 0 basic: 2 + partitioned: 1 crossed: 2 intensity: 1: 2 @@ -42,7 +43,8 @@ all: 1 chaos: 1 trap_door_mode: - vanilla: 1 + vanilla: 0 + optional: 1 boss: 0 oneway: 0 key_logic_algorithm: @@ -101,6 +103,9 @@ shuffleganon: on: 1 off: 1 + shuffletavern: + on: 1 + off: 1 overworld_map: # control how the overworld map operates when entrance shuffle is on default: 1 compass: 10 @@ -144,11 +149,20 @@ mcs: 2 full: 5 mcu: 1 # map, compass, universal smalls -# for use when you aren't using the dungeon_items above -# smallkey_shuffle: -# none: 5 -# wild: 1 -# universal: 1 + # for use when you aren't using the dungeon_items above + # map_shuffle: + # on: 1 + # off: 1 + # compass_shuffle: + # on: 1 + # off: 1 + # smallkey_shuffle: + # none: 5 + # wild: 1 + # universal: 1 + # bigkey_shuffle: + # on: 1 + # off: 1 dungeon_counters: on: 5 off: 0 @@ -225,6 +239,10 @@ startinventory: Pegasus Boots: on rom: + sprite: + 'Link': 1 + random: 0 + randomonhit: 0 quickswap: on heartcolor: red: 1 From e8b4d235952a518a5aacf0d29a050f3bee73de06 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 26 Feb 2023 13:13:13 -0600 Subject: [PATCH 143/146] Fixed Placeholder NoneType error --- BaseClasses.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BaseClasses.py b/BaseClasses.py index e37e412e..be3b7ac8 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2703,6 +2703,8 @@ class Item(object): return self.world.get_name_string_for_object(self) if self.world else f'{self.name} (Player {self.player})' def __eq__(self, other): + if type(other) is str: + return self.name == other return self.name == other.name and self.player == other.player From 129459f8714c3c3783afa3812557e1ef7c342a5e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 26 Feb 2023 13:40:36 -0600 Subject: [PATCH 144/146] Initial OWR/ER2 merge --- DoorShuffle.py | 4 + Main.py | 2 +- source/overworld/EntranceShuffle2.py | 2036 ++++++++++---------------- 3 files changed, 771 insertions(+), 1271 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 6e8c3e53..8e65a4cc 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -3273,6 +3273,10 @@ def find_inaccessible_regions(world, player): world.inaccessible_regions[player] = [] start_regions = ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] regs = convert_regions(start_regions, world, player) + if all(all(not e.connected_region for e in r.exits) for r in regs): + # if attempting to find inaccessible regions before any connections made above, assume eventual access to Pyramid S&Q + start_regions = ['Pyramid Area' if not world.is_tile_swapped(0x1b, player) else 'Hyrule Castle Ledge'] + regs = convert_regions(start_regions, world, player) all_regions = [r for r in world.regions if r.player == player and r.type is not RegionType.Dungeon] visited_regions = set() queue = deque(regs) diff --git a/Main.py b/Main.py index 117e75f1..468462b5 100644 --- a/Main.py +++ b/Main.py @@ -231,7 +231,7 @@ def main(args, seed=None, fish=None): logger.info(world.fish.translate("cli","cli","shuffling.world")) for player in range(1, world.players + 1): - link_entrances(world, player) + link_entrances_new(world, player) logger.info(world.fish.translate("cli", "cli", "shuffling.prep")) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 9b4b9464..f1c43281 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -2,7 +2,8 @@ import RaceRandom as random import logging import copy -from collections import defaultdict +from collections import defaultdict, OrderedDict +from BaseClasses import RegionType class EntrancePool(object): @@ -26,6 +27,9 @@ class EntrancePool(object): def is_standard(self): return self.world.mode[self.player] == 'standard' + def is_sanc_forced_in_hc(self): + return self.is_standard() or self.world.doorShuffle[self.player] in ['vanilla', 'basic'] or self.world.intensity[self.player] < 3 + class Restrictions(object): def __init__(self): @@ -40,14 +44,15 @@ def link_entrances_new(world, player): avail_pool = EntrancePool(world, player) i_drop_map = {x: y for x, y in drop_map.items() if not x.startswith('Inverted')} i_entrance_map = {x: y for x, y in entrance_map.items() if not x.startswith('Inverted')} - i_single_ent_map = {x: y for x, y in single_entrance_map.items() if not x.startswith('Inverted')} + i_single_ent_map = {x: y for x, y in single_entrance_map.items()} + + from OverworldShuffle import build_sectors + if not world.owsectors[player] and world.shuffle[player] != 'vanilla': + world.owsectors[player] = build_sectors(world, player) avail_pool.entrances = set(i_drop_map.keys()).union(i_entrance_map.keys()).union(i_single_ent_map.keys()) avail_pool.exits = set(i_entrance_map.values()).union(i_drop_map.values()).union(i_single_ent_map.values()) - avail_pool.exits.add('Chris Houlihan Room Exit') avail_pool.inverted = world.mode[player] == 'inverted' - if avail_pool.inverted: - avail_pool.exits.add('Inverted Dark Sanctuary Exit') inverted_substitution(avail_pool, avail_pool.entrances, True, True) inverted_substitution(avail_pool, avail_pool.exits, False, True) avail_pool.original_entrances.update(avail_pool.entrances) @@ -57,28 +62,21 @@ def link_entrances_new(world, player): one_way_map = {} one_way_map.update(drop_map) one_way_map.update(single_entrance_map) - if avail_pool.inverted: - default_map['Old Man Cave (West)'] = 'Bumper Cave Exit (Bottom)' - default_map['Death Mountain Return Cave (West)'] = 'Bumper Cave Exit (Top)' - default_map['Bumper Cave (Bottom)'] = 'Old Man Cave Exit (West)' - default_map['Dark Death Mountain Fairy'] = 'Old Man Cave Exit (East)' - del one_way_map['Dark Death Mountain Fairy'] - default_map['Old Man Cave (East)'] = 'Death Mountain Return Cave Exit (West)' - one_way_map['Bumper Cave (Top)'] = 'Dark Death Mountain Healer Fairy' - del default_map['Bumper Cave (Top)'] - del one_way_map['Big Bomb Shop'] - one_way_map['Inverted Big Bomb Shop'] = 'Inverted Big Bomb Shop' avail_pool.default_map = default_map avail_pool.one_way_map = one_way_map - # setup mandatory connections - if not avail_pool.inverted: - for exit_name, region_name in mandatory_connections: - connect_simple(world, exit_name, region_name, player) - else: - for exit_name, region_name in inverted_mandatory_connections: - connect_simple(world, exit_name, region_name, player) + global LW_Entrances, DW_Entrances + for e in [e for e in avail_pool.entrances if e not in drop_map]: + region = world.get_entrance(e, player).parent_region + if region.type == RegionType.LightWorld: + LW_Entrances.append(e) + else: + DW_Entrances.append(e) + # setup mandatory connections + for exit_name, region_name in mandatory_connections: + connect_simple(world, exit_name, region_name, player) + connect_custom(avail_pool, world, player) if world.shuffle[player] == 'vanilla': @@ -96,6 +94,10 @@ def link_entrances_new(world, player): if special_shuffle == 'drops': holes, targets = find_entrances_and_targets_drops(avail_pool, pool['entrances']) connect_random(holes, targets, avail_pool) + elif special_shuffle == 'normal_drops': + cross_world = mode_cfg['cross_world'] == 'on' if 'cross_world' in mode_cfg else False + keep_together = mode_cfg['keep_drops_together'] == 'on' if 'keep_drops_together' in mode_cfg else True + do_holes_and_linked_drops(set(avail_pool.entrances), set(avail_pool.exits), avail_pool, cross_world, keep_together) elif special_shuffle == 'fixed_shuffle': do_fixed_shuffle(avail_pool, pool['entrances']) elif special_shuffle == 'same_world': @@ -106,9 +108,6 @@ def link_entrances_new(world, player): exits = [x for x in pool['entrances'] if x in avail_pool.exits] cross_world = mode_cfg['cross_world'] == 'on' if 'cross_world' in mode_cfg else False do_old_man_cave_exit(set(avail_pool.entrances), exits, avail_pool, cross_world) - elif special_shuffle == 'inverted_fixed': - if avail_pool.inverted: - connect_two_way(pool['entrance'], pool['exit'], avail_pool) elif special_shuffle == 'limited': do_limited_shuffle(pool, avail_pool) elif special_shuffle == 'limited_lw': @@ -119,6 +118,14 @@ def link_entrances_new(world, player): do_vanilla_connect(pool, avail_pool) elif special_shuffle == 'skull': entrances, exits = find_entrances_and_exits(avail_pool, pool['entrances']) + rem_ent = None + if avail_pool.world.shuffle[avail_pool.player] in ['dungeons-simple', 'simple', 'restricted'] \ + and not avail_pool.world.is_tile_swapped(0x00, avail_pool.player): + rem_ent = random.choice(['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']) + entrances.remove(rem_ent) + exits.remove('Skull Woods First Section Exit') + connect_random(entrances, exits, avail_pool, True) + entrances, exits = [rem_ent], ['Skull Woods First Section Exit'] connect_random(entrances, exits, avail_pool, True) avail_pool.skull_handled = True else: @@ -132,6 +139,12 @@ def link_entrances_new(world, player): # afterward + # connect houlihan + if not world.get_entrance('Chris Houlihan Room Exit', player).connected_region: + lh = 'Big Bomb Shop' if world.is_bombshop_start(player) else 'Links House' + lh = world.get_region(lh, player).entrances[1].name + connect_exit('Chris Houlihan Room Exit', lh, avail_pool) + # check for swamp palace fix if (world.get_entrance('Dam', player).connected_region.name != 'Dam' or world.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Portal'): @@ -142,20 +155,17 @@ def link_entrances_new(world, player): world.powder_patch_required[player] = True # check for ganon location - pyramid_hole = 'Inverted Pyramid Hole' if avail_pool.inverted else 'Pyramid Hole' + pyramid_hole = 'Inverted Pyramid Hole' if avail_pool.world.is_tile_swapped(0x1b, avail_pool.player) else 'Pyramid Hole' if world.get_entrance(pyramid_hole, player).connected_region.name != 'Pyramid': world.ganon_at_pyramid[player] = False # check for Ganon's Tower location - gt = 'Inverted Ganons Tower' if avail_pool.inverted else 'Ganons Tower' + gt = 'Agahnims Tower' if avail_pool.world.is_atgt_swapped(avail_pool.player) else 'Ganons Tower' if world.get_entrance(gt, player).connected_region.name != 'Ganons Tower Portal': world.ganonstower_vanilla[player] = False def do_vanilla_connections(avail_pool): - if 'Chris Houlihan Room Exit' in avail_pool.exits: - lh = 'Inverted Links House' if avail_pool.inverted else 'Links House' - connect_exit('Chris Houlihan Room Exit', lh, avail_pool) for ent in list(avail_pool.entrances): if ent in avail_pool.default_map and avail_pool.default_map[ent] in avail_pool.exits: connect_vanilla_two_way(ent, avail_pool.default_map[ent], avail_pool) @@ -174,14 +184,15 @@ def do_main_shuffle(entrances, exits, avail, mode_def): avail.decoupled_entrances.extend(entrances) avail.decoupled_exits.extend(exits) - if not avail.world.shuffle_ganon: - if avail.inverted and 'Inverted Ganons Tower' in entrances: - connect_two_way('Inverted Ganons Tower', 'Inverted Ganons Tower Exit', avail) - entrances.remove('Inverted Ganons Tower') - exits.remove('Inverted Ganons Tower Exit') - if not avail.coupled: - avail.decoupled_entrances.remove('Inverted Ganons Tower') - avail.decoupled_exits.remove('Inverted Ganons Tower Exit') + if not avail.world.shuffle_ganon[avail.player]: + if avail.world.is_atgt_swapped(avail.player): + if 'Agahnims Tower' in entrances: + connect_two_way('Agahnims Tower', 'Ganons Tower Exit', avail) + entrances.remove('Agahnims Tower') + exits.remove('Ganons Tower Exit') + if not avail.coupled: + avail.decoupled_entrances.remove('Agahnims Tower') + avail.decoupled_exits.remove('Ganons Tower Exit') elif 'Ganons Tower' in entrances: connect_two_way('Ganons Tower', 'Ganons Tower Exit', avail) entrances.remove('Ganons Tower') @@ -198,40 +209,37 @@ def do_main_shuffle(entrances, exits, avail, mode_def): if not avail.coupled: avail.decoupled_entrances.remove('Tavern North') - # links house / houlihan - do_links_house(entrances, exits, avail, cross_world) - # inverted sanc - if avail.inverted and 'Inverted Dark Sanctuary Exit' in exits: - choices = [e for e in Inverted_Dark_Sanctuary_Doors if e in entrances] - choice = random.choice(choices) - entrances.remove(choice) - exits.remove('Inverted Dark Sanctuary Exit') - connect_entrance(choice, 'Inverted Dark Sanctuary', avail) - ext = avail.world.get_entrance('Inverted Dark Sanctuary Exit', avail.player) - ext.connect(avail.world.get_entrance(choice, avail.player).parent_region) - if not avail.coupled: - avail.decoupled_entrances.remove(choice) + do_dark_sanc(entrances, exits, avail) + + # links house + do_links_house(entrances, exits, avail, cross_world) # mandatory exits rem_entrances, rem_exits = set(), set() if not cross_world: mand_exits = figure_out_must_exits_same_world(entrances, exits, avail) - must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves, hyrule_forced = mand_exits - if hyrule_forced: - do_mandatory_connections(avail, lw_entrances, hyrule_forced, must_exit_lw) + must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves = mand_exits + if not avail.inverted: + do_mandatory_connections(avail, lw_entrances, multi_exit_caves, must_exit_lw) + else: + do_mandatory_connections(avail, dw_entrances, multi_exit_caves, must_exit_dw) + + new_mec = [] + for cave_option in multi_exit_caves: + # remove old man house as connector - not valid for dw must_exit if it is a spawn point + # remove HC exits as connector if sanc is guaranteed in HC + if any('Old Man House' in cave for cave in cave_option) \ + or (avail.is_sanc_forced_in_hc() and any('Hyrule Castle' in cave for cave in cave_option)): + rem_exits.update([item for item in cave_option]) + else: + new_mec.append(cave_option) + multi_exit_caves = new_mec + + if not avail.inverted: + do_mandatory_connections(avail, dw_entrances, multi_exit_caves, must_exit_dw) else: do_mandatory_connections(avail, lw_entrances, multi_exit_caves, must_exit_lw) - # remove old man house as connector - not valid for dw must_exit if it is a spawn point - if not avail.inverted: - new_mec = [] - for cave_option in multi_exit_caves: - if any('Old Man House' in cave for cave in cave_option): - rem_exits.update([item for item in cave_option]) - else: - new_mec.append(cave_option) - multi_exit_caves = new_mec - do_mandatory_connections(avail, dw_entrances, multi_exit_caves, must_exit_dw) rem_entrances.update(lw_entrances) rem_entrances.update(dw_entrances) else: @@ -241,33 +249,27 @@ def do_main_shuffle(entrances, exits, avail, mode_def): do_mandatory_connections(avail, entrance_list, multi_exit_caves, must_exit) rem_entrances.update(entrance_list) - rem_exits.update([x for item in multi_exit_caves for x in item]) + rem_exits.update([x for item in multi_exit_caves for x in item if x in avail.exits]) rem_exits.update(exits) # old man cave do_old_man_cave_exit(rem_entrances, rem_exits, avail, cross_world) # blacksmith - if 'Blacksmiths Hut' in rem_exits: - blacksmith_options = [x for x in Blacksmith_Options if x in rem_entrances] - blacksmith_choice = random.choice(blacksmith_options) - connect_entrance(blacksmith_choice, 'Blacksmiths Hut', avail) - rem_entrances.remove(blacksmith_choice) - if not avail.coupled: - avail.decoupled_exits.remove('Blacksmiths Hut') - rem_exits.remove('Blacksmiths Hut') + do_blacksmith(rem_entrances, rem_exits, avail) # bomb shop - bomb_shop = 'Inverted Big Bomb Shop' if avail.inverted else 'Big Bomb Shop' - if bomb_shop in rem_exits: - bomb_shop_options = Inverted_Bomb_Shop_Options if avail.inverted else Bomb_Shop_Options - bomb_shop_options = [x for x in bomb_shop_options if x in rem_entrances] - bomb_shop_choice = random.choice(bomb_shop_options) - connect_entrance(bomb_shop_choice, bomb_shop, avail) - rem_entrances.remove(bomb_shop_choice) - if not avail.coupled: - avail.decoupled_exits.remove(bomb_shop) - rem_exits.remove(bomb_shop) + if not avail.world.is_bombshop_start(avail.player): + bomb_shop = 'Big Bomb Shop' + if bomb_shop in rem_exits: + bomb_shop_options = [x for x in rem_entrances] + if avail.world.is_tile_swapped(0x03, avail.player): + bomb_shop_options = [x for x in bomb_shop_options if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] + bomb_shop_choice = random.choice(bomb_shop_options) + connect_entrance(bomb_shop_choice, bomb_shop, avail) + rem_entrances.remove(bomb_shop_choice) + if not avail.coupled: + avail.decoupled_exits.remove(bomb_shop) def bonk_fairy_exception(x): # (Bonk Fairy not eligible in standard) return not avail.is_standard() or x != 'Bonk Fairy (Light)' @@ -286,18 +288,18 @@ def do_main_shuffle(entrances, exits, avail, mode_def): rem_exits.remove('Old Man Cave Exit (West)') # OM House in lw/dw if cross_world off om_house = ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)'] - if not avail.inverted: # we don't really care where this ends up in inverted? - for ext in om_house: - if ext in rem_exits: - om_house_options = [x for x in rem_entrances if x in LW_Entrances and bonk_fairy_exception(x)] - om_house_choice = random.choice(om_house_options) - if not avail.coupled: - connect_exit(ext, om_house_choice, avail) - avail.decoupled_entrances.remove(om_house_choice) - else: - connect_two_way(om_house_choice, ext, avail) - rem_entrances.remove(om_house_choice) - rem_exits.remove(ext) + for ext in om_house: + if ext in rem_exits: + world_limiter = DW_Entrances if avail.inverted else LW_Entrances + om_house_options = [x for x in rem_entrances if x in world_limiter and bonk_fairy_exception(x)] + om_house_choice = random.choice(om_house_options) + if not avail.coupled: + connect_exit(ext, om_house_choice, avail) + avail.decoupled_entrances.remove(om_house_choice) + else: + connect_two_way(om_house_choice, ext, avail) + rem_entrances.remove(om_house_choice) + rem_exits.remove(ext) # the rest of the caves multi_exit_caves = figure_out_true_exits(rem_exits, avail) @@ -336,11 +338,21 @@ def do_main_shuffle(entrances, exits, avail, mode_def): def do_old_man_cave_exit(entrances, exits, avail, cross_world): if 'Old Man Cave Exit (East)' in exits: - om_cave_options = Inverted_Old_Man_Entrances if avail.inverted else Old_Man_Entrances - if avail.inverted and cross_world: - om_cave_options = Inverted_Old_Man_Entrances + Old_Man_Entrances - om_cave_options = [x for x in om_cave_options if x in entrances] - om_cave_choice = random.choice(om_cave_options) + from EntranceShuffle import build_accessible_region_list + if not avail.world.is_tile_swapped(0x03, avail.player): + region_name = 'West Death Mountain (Top)' + else: + region_name = 'West Dark Death Mountain (Top)' + om_cave_options = list(get_accessible_entrances(region_name, avail, [], cross_world, True, True, True)) + om_cave_options = [e for e in om_cave_options if e in entrances and e != 'Old Man House (Bottom)'] + assert len(om_cave_options), 'No available entrances left to place Old Man Cave' + random.shuffle(om_cave_options) + om_cave_choice = None + while not om_cave_choice: + om_cave_choice = om_cave_options.pop() + choice_region = avail.world.get_entrance(om_cave_choice, avail.player).parent_region.name + if 'West Death Mountain (Bottom)' not in build_accessible_region_list(avail.world, choice_region, avail.player, True, True): + om_cave_choice = None if not avail.coupled: connect_exit('Old Man Cave Exit (East)', om_cave_choice, avail) avail.decoupled_entrances.remove(om_cave_choice) @@ -350,13 +362,42 @@ def do_old_man_cave_exit(entrances, exits, avail, cross_world): exits.remove('Old Man Cave Exit (East)') +def do_blacksmith(entrances, exits, avail): + if 'Blacksmiths Hut' in exits: + assumed_inventory = list() + if avail.world.logic[avail.player] in ['noglitches', 'minorglitches'] and (avail.world.is_tile_swapped(0x29, avail.player) == avail.inverted): + assumed_inventory.append('Titans Mitts') + + if not avail.world.is_bombshop_start(avail.player): + links_region = avail.world.get_entrance('Links House Exit', avail.player).connected_region.name + else: + links_region = avail.world.get_entrance('Big Bomb Shop Exit', avail.player).connected_region.name + blacksmith_options = list(get_accessible_entrances(links_region, avail, assumed_inventory, False, True, True)) + + if avail.inverted: + dark_sanc = avail.world.get_entrance('Dark Sanctuary Hint Exit', avail.player).connected_region.name + blacksmith_options = list(OrderedDict.fromkeys(blacksmith_options + list(get_accessible_entrances(dark_sanc, avail, assumed_inventory, False, True, True)))) + elif avail.is_sanc_forced_in_hc(): + sanc_region = avail.world.get_entrance('Sanctuary Exit',avail. player).connected_region + if sanc_region: + blacksmith_options = list(OrderedDict.fromkeys(blacksmith_options + list(get_accessible_entrances(sanc_region.name, avail, assumed_inventory, False, True, True)))) + else: + logging.getLogger('').warning('Blacksmith is unable to use Sanctuary S&Q as initial accessibility because Sanctuary Exit has not been placed yet') + blacksmith_options = [x for x in blacksmith_options if x in entrances] + blacksmith_choice = random.choice(blacksmith_options) + connect_entrance(blacksmith_choice, 'Blacksmiths Hut', avail) + entrances.remove(blacksmith_choice) + if not avail.coupled: + avail.decoupled_exits.remove('Blacksmiths Hut') + exits.remove('Blacksmiths Hut') + + def do_standard_connections(avail): connect_two_way('Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', avail) # cannot move uncle cave connect_two_way('Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', avail) connect_entrance('Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', avail) connect_two_way('Links House', 'Links House Exit', avail) - connect_exit('Chris Houlihan Room Exit', 'Links House', avail) def remove_from_list(t_list, removals): @@ -368,7 +409,7 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe holes_to_shuffle = [x for x in entrances if x in drop_map] if not avail.world.shuffle_ganon: - if avail.inverted and 'Inverted Pyramid Hole' in holes_to_shuffle: + if avail.world.is_tile_swapped(0x1b, avail.player) and 'Inverted Pyramid Hole' in holes_to_shuffle: connect_entrance('Inverted Pyramid Hole', 'Pyramid', avail) connect_two_way('Pyramid Entrance', 'Pyramid Exit', avail) holes_to_shuffle.remove('Inverted Pyramid Hole') @@ -400,7 +441,7 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe hole_targets.append((target_exit, target_drop)) random.shuffle(hole_entrances) - if not cross_world and 'Sanctuary Grave' in holes_to_shuffle: + if not cross_world and avail.is_sanc_forced_in_hc() and 'Sanctuary Grave' in holes_to_shuffle: lw_entrance = next(entrance for entrance in hole_entrances if entrance[0] in LW_Entrances) hole_entrances.remove(lw_entrance) sanc_interior = next(target for target in hole_targets if target[0] == 'Sanctuary Exit') @@ -419,36 +460,70 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe remove_from_list(exits, [ext, target]) +def do_dark_sanc(entrances, exits, avail): + if avail.inverted: + ext = avail.world.get_entrance('Dark Sanctuary Hint Exit', avail.player) + if 'Dark Sanctuary Hint' in exits: + forbidden = list(Isolated_LH_Doors) + if not avail.world.is_tile_swapped(0x05, avail.player): + forbidden.append('Mimic Cave') + if avail.world.owShuffle[avail.player] == 'vanilla': + choices = [e for e in avail.world.districts[avail.player]['Northwest Dark World'].entrances if e not in forbidden and e in entrances] + else: + choices = [e for e in get_starting_entrances(avail) if e not in forbidden and e in entrances] + choice = random.choice(choices) + entrances.remove(choice) + exits.remove('Dark Sanctuary Hint') + connect_entrance(choice, 'Dark Sanctuary Hint', avail) + ext.connect(avail.world.get_entrance(choice, avail.player).parent_region) + if not avail.coupled: + avail.decoupled_entrances.remove(choice) + elif not ext.connected_region: + # default to output to vanilla area, assume vanilla connection + ext.connect(avail.world.get_region('Dark Chapel Area', avail.player)) + + def do_links_house(entrances, exits, avail, cross_world): - lh_exit = 'Inverted Links House Exit' if avail.inverted else 'Links House Exit' + lh_exit = 'Big Bomb Shop' if avail.world.is_bombshop_start(avail.player) else 'Links House Exit' if lh_exit in exits: if not avail.world.shufflelinks[avail.player]: - links_house = 'Inverted Links House' if avail.inverted else 'Links House' + links_house = 'Big Bomb Shop' if avail.world.is_bombshop_start(avail.player) else 'Links House' else: - forbidden = list(Isolated_LH_Doors_Inv + Inverted_Dark_Sanctuary_Doors - if avail.inverted else Isolated_LH_Doors_Open) - # simple shuffle - - if avail.world.shuffle[avail.player] == 'simple': - avail.links_on_mountain = True # taken care of by the logic below - if avail.inverted: # in inverted, links house cannot be on the mountain - forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy', 'Hookshot Fairy']) - else: - # links house cannot be on dm if there's no way off the mountain - ent = avail.world.get_entrance('Death Mountain Return Cave (West)', avail.player) - if ent.connected_region.name in Simple_DM_Non_Connectors: - forbidden.append('Hookshot Fairy') - # other cases it is fine - # can't have links house on eddm in restricted because Inverted Aga Tower isn't available - # todo: inverted full may have the same problem if both links house and a mandatory connector is chosen - # from the 3 inverted options - if avail.world.shuffle[avail.player] in ['restricted'] and avail.inverted: - avail.links_on_mountain = True - forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy']) - # lobby shuffle means you ought to keep links house in the same world sanc_spawn_can_be_dark = (not avail.inverted and avail.world.doorShuffle[avail.player] == 'crossed' - and avail.world.intensity[avail.player] >= 3) + and avail.world.intensity[avail.player] >= 3) entrance_pool = entrances if avail.coupled else avail.decoupled_entrances + + forbidden = list(Isolated_LH_Doors) + if not avail.world.is_tile_swapped(0x05, avail.player): + forbidden.append('Mimic Cave') + if avail.world.is_bombshop_start(avail.player) and (avail.inverted == avail.world.is_tile_swapped(0x03, avail.player)): + forbidden.extend(['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']) + if avail.inverted: + dark_sanc_region = avail.world.get_entrance('Dark Sanctuary Hint Exit', avail.player).connected_region.name + forbidden.extend(get_nearby_entrances(avail, dark_sanc_region)) + + if avail.world.owShuffle[avail.player] == 'vanilla': + # simple shuffle - + if avail.world.shuffle[avail.player] == 'simple': + avail.links_on_mountain = True # taken care of by the logic below + if avail.world.is_tile_swapped(0x03, avail.player): # in inverted, links house cannot be on the mountain + forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy', 'Hookshot Fairy']) + else: + # links house cannot be on dm if there's no way off the mountain + ent = avail.world.get_entrance('Death Mountain Return Cave (West)', avail.player) + if ent.connected_region.name in Simple_DM_Non_Connectors: + forbidden.append('Hookshot Fairy') + # other cases it is fine + # can't have links house on eddm in restricted because Inverted Aga Tower isn't available + # todo: inverted full may have the same problem if both links house and a mandatory connector is chosen + # from the 3 inverted options + if avail.world.shuffle[avail.player] in ['restricted'] and avail.world.is_tile_swapped(0x03, avail.player): + avail.links_on_mountain = True + forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy']) + else: + avail.links_on_mountain = True + if cross_world and not sanc_spawn_can_be_dark: possible = [e for e in entrance_pool if e not in forbidden] else: @@ -456,18 +531,21 @@ def do_links_house(entrances, exits, avail, cross_world): possible = [e for e in entrance_pool if e in world_list and e not in forbidden] possible.sort() links_house = random.choice(possible) - connect_two_way(links_house, lh_exit, avail) + if not avail.world.is_bombshop_start(avail.player): + connect_two_way(links_house, lh_exit, avail) + else: + connect_entrance(links_house, lh_exit, avail) + ext = avail.world.get_entrance('Big Bomb Shop Exit', avail.player) + ext.connect(avail.world.get_entrance(links_house, avail.player).parent_region) entrances.remove(links_house) - connect_exit('Chris Houlihan Room Exit', links_house, avail) # should match link's house exits.remove(lh_exit) - exits.remove('Chris Houlihan Room Exit') if not avail.coupled: avail.decoupled_entrances.remove(links_house) - avail.decoupled_exits.remove('Links House Exit') - avail.decoupled_exits.remove('Chris Houlihan Room Exit') + avail.decoupled_exits.remove(lh_exit) + # links on dm dm_spots = LH_DM_Connector_List.union(LH_DM_Exit_Forbidden) - if links_house in dm_spots: + if links_house in dm_spots and avail.world.owShuffle[avail.player] == 'vanilla': if avail.links_on_mountain: return # connector is fine multi_exit_caves = figure_out_connectors(exits) @@ -500,6 +578,118 @@ def do_links_house(entrances, exits, avail, cross_world): exits.update([x for item in multi_exit_caves for x in item]) +def get_starting_entrances(avail, force_starting_world=True): + from OWEdges import OWTileRegions + sector = None + invalid_sectors = list() + entrances = list() + while not len(entrances): + # find largest walkable sector + while (sector is None): + sector = max(avail.world.owsectors[avail.player], key=lambda x: len(x) - (0 if x not in invalid_sectors else 1000)) + if not ((avail.world.owCrossed[avail.player] == 'polar' and avail.world.owMixed[avail.player]) or avail.world.owCrossed[avail.player] not in ['none', 'polar']) \ + and avail.world.get_region(next(iter(next(iter(sector)))), avail.player).type != (RegionType.DarkWorld if avail.inverted else RegionType.LightWorld): + invalid_sectors.append(sector) + sector = None + regions = max(sector, key=lambda x: len(x)) + + # get entrances from list of regions + entrances = list() + for region_name in regions: + if avail.world.shuffle[avail.player] == 'simple' and region_name in OWTileRegions.keys() and OWTileRegions[region_name] in [0x03, 0x05, 0x07]: + continue + region = avail.world.get_region(region_name, avail.player) + if not force_starting_world or region.type == (RegionType.DarkWorld if avail.inverted else RegionType.LightWorld): + for exit in region.exits: + if not exit.connected_region and exit.spot_type == 'Entrance': + entrances.append(exit.name) + + invalid_sectors.append(sector) + sector = None + + return entrances + + +def get_nearby_entrances(avail, start_region): + from OverworldShuffle import one_way_ledges + from OWEdges import OWTileRegions + + # get walkable sector in which initial entrance was placed + regions = next(s for s in avail.world.owsectors[avail.player] if any(start_region in w for w in s)) + regions = next(w for w in regions if start_region in w) + + # eliminate regions surrounding the initial entrance until less than half of the candidate regions remain + explored_regions = list({start_region}) + was_progress = True + while was_progress and len(explored_regions) < len(regions) / 2: + was_progress = False + new_regions = list() + for region_name in explored_regions: + if region_name in one_way_ledges: + for ledge in one_way_ledges[region_name]: + if ledge not in explored_regions + new_regions: + new_regions.append(ledge) + was_progress = True + region = avail.world.get_region(region_name, avail.player) + for exit in region.exits: + if exit.connected_region and region.type == exit.connected_region.type and exit.connected_region.name in regions and exit.connected_region.name not in explored_regions + new_regions: + new_regions.append(exit.connected_region.name) + was_progress = True + explored_regions.extend(new_regions) + + # get entrances from remaining regions + candidates = list() + for region_name in [r for r in regions if r in explored_regions]: + if region_name in OWTileRegions.keys() and OWTileRegions[region_name] in [0x03, 0x05, 0x07]: + continue + region = avail.world.get_region(region_name, avail.player) + for exit in region.exits: + if not exit.connected_region and exit.spot_type == 'Entrance': + candidates.append(exit.name) + + return candidates + + +def get_accessible_entrances(start_region, avail, assumed_inventory=[], cross_world=False, region_rules=True, exit_rules=True, include_one_ways=False): + from Main import copy_world_premature + from BaseClasses import CollectionState + from Items import ItemFactory + from EntranceShuffle import build_accessible_region_list + from OverworldShuffle import one_way_ledges + + for p in range(1, avail.world.players + 1): + avail.world.key_logic[p] = {} + base_world = copy_world_premature(avail.world, avail.player) + base_world.override_bomb_check = True + + connect_simple(base_world, 'Links House S&Q', start_region, avail.player) + blank_state = CollectionState(base_world) + if base_world.mode[avail.player] == 'standard': + blank_state.collect(ItemFactory('Zelda Delivered', avail.player), True) + for item in assumed_inventory: + blank_state.collect(ItemFactory(item, avail.player), True) + + explored_regions = list(build_accessible_region_list(base_world, start_region, avail.player, False, cross_world, region_rules, False)) + + if include_one_ways: + new_regions = list() + for region_name in explored_regions: + if region_name in one_way_ledges: + for ledge in one_way_ledges[region_name]: + if ledge not in explored_regions + new_regions: + new_regions.append(ledge) + explored_regions.extend(new_regions) + + found_entrances = list() + for region_name in explored_regions: + region = base_world.get_region(region_name, avail.player) + for exit in region.exits: + if exit.spot_type == 'Entrance' and (not exit_rules or exit.access_rule(blank_state)): + found_entrances.append(exit.name) + + return found_entrances + + def figure_out_connectors(exits): multi_exit_caves = [] for item in Connector_List: @@ -522,45 +712,180 @@ def figure_out_true_exits(exits, avail): return multi_exit_caves -# todo: figure out hyrule forced better +def must_exits_helper(avail): + def find_inacessible_ow_regions(): + from DoorShuffle import find_inaccessible_regions + nonlocal inaccessible_regions + find_inaccessible_regions(avail.world, avail.player) + inaccessible_regions = list(avail.world.inaccessible_regions[avail.player]) + + # find OW regions that don't have a multi-entrance dungeon exit connected + glitch_regions = ['Central Cliffs', 'Eastern Cliff', 'Desert Northeast Cliffs', 'Hyrule Castle Water', + 'Dark Central Cliffs', 'Darkness Cliff', 'Mire Northeast Cliffs', 'Pyramid Water'] + multi_dungeon_exits = { + 'Hyrule Castle South Portal', 'Hyrule Castle West Portal', 'Hyrule Castle East Portal', 'Sanctuary Portal', + 'Desert South Portal', 'Desert West Portal', + 'Skull 2 East Portal', 'Skull 2 West Portal', + 'Turtle Rock Main Portal', 'Turtle Rock Lazy Eyes Portal', 'Turtle Rock Eye Bridge Portal' + } + for region_name in avail.world.inaccessible_regions[avail.player]: + if (avail.world.logic[avail.player] in ['noglitches', 'minorglitches'] and region_name in glitch_regions) \ + or (region_name == 'Pyramid Exit Ledge' and (avail.world.shuffle[avail.player] != 'insanity' or avail.world.is_tile_swapped(0x1b, avail.player))) \ + or (region_name == 'Spiral Mimic Ledge Extend' and not avail.world.is_tile_swapped(0x05, avail.player)): + # removing irrelevant and resolved regions + inaccessible_regions.remove(region_name) + continue + region = avail.world.get_region(region_name, avail.player) + if region.type not in [RegionType.LightWorld, RegionType.DarkWorld]: + inaccessible_regions.remove(region_name) + continue + if avail.world.shuffle[avail.player] != 'insanity': + for exit in region.exits: + # because dungeon regions haven't been connected yet, the inaccessibility check won't be able to know it's reachable yet + if exit.connected_region and exit.connected_region.name in multi_dungeon_exits: + resolved_regions.append(region_name) + break + + inaccessible_regions = list() + resolved_regions = list() + find_inacessible_ow_regions() + + # keep track of neighboring regions for later consolidation + must_exit_links = OrderedDict() + for region_name in inaccessible_regions: + region = avail.world.get_region(region_name, avail.player) + must_exit_links[region_name] = [x.connected_region.name for x in region.exits if x.connected_region and x.connected_region.name in inaccessible_regions] + + # group neighboring regions together, separated by one-ways + def consolidate_group(region): + processed_regions.append(region) + must_exit_links_copy.pop(region) + region_group.append(region) + for dest_region in must_exit_links[region]: + if region in must_exit_links[dest_region]: + if dest_region not in processed_regions: + consolidate_group(dest_region) + else: + one_ways.append(tuple((region, dest_region))) + + processed_regions = list() + must_exit_candidates = list() + one_ways = list() + must_exit_links_copy = must_exit_links.copy() + while len(must_exit_links_copy): + region_group = list() + region_name = next(iter(must_exit_links_copy)) + consolidate_group(region_name) + must_exit_candidates.append(region_group) + + # get available entrances in each group + for regions in must_exit_candidates: + entrances = list() + for region_name in regions: + region = avail.world.get_region(region_name, avail.player) + entrances = entrances + [x.name for x in region.exits if x.spot_type == 'Entrance' and not x.connected_region] + must_exit_candidates[must_exit_candidates.index(regions)] = tuple((regions, entrances)) + + # necessary for circular relations between region groups, it will pick the last group + # and fill one of those entrances, and we don't want it to bias the same group + random.shuffle(must_exit_candidates) + + # remove must exit candidates that would be made accessible thru other region groups + def find_group(region): + for group in must_exit_candidates: + regions, _ = group + if region in regions: + return group + raise Exception(f'Could not find region group for {region}') + + def cascade_ignore(group): + nonlocal ignored_regions, sector_entrances + regions, entrances = group + ignored_regions = ignored_regions + regions + sector_entrances.update(entrances) + for from_region, to_region in one_ways: + if from_region in regions: + if to_region not in ignored_regions: + sector_entrances.update(cascade_ignore(find_group(to_region))) + return sector_entrances + + def build_invalid(entrances): + # building lists of entrances that cannot fulfill must-exit scenarios + # this ensures must-exits connect to an area outside of this group + for e in entrances: + if not Must_Exit_Invalid_Connections[e]: + Must_Exit_Invalid_Connections[e] = set() + Must_Exit_Invalid_Connections[e].update(set(entrances)) + + def process_group(group): + nonlocal processed_regions, ignored_regions, sector_entrances + regions, entrances = group + must_exit_candidates_copy.remove(group) + processed_regions = processed_regions + regions + if regions[0] not in ignored_regions: + for from_region, to_region in one_ways: + if to_region in regions and from_region not in ignored_regions + processed_regions: + process_group(find_group(from_region)) # process the parent region group + if regions[0] not in ignored_regions: + # this is the top level region + sector_entrances = set() + if any(r in resolved_regions for r in regions): + cascade_ignore(group) + build_invalid(sector_entrances) + else: + if len(entrances): + # we will fulfill must exit here and cascade access to children + if len(entrances) == 1: + entrances = entrances[0] + else: + entrances = tuple(entrances) + must_exit_regions.append(tuple((regions, entrances))) + cascade_ignore(group) + build_invalid(sector_entrances) + else: + ignored_regions = ignored_regions + regions + + global Must_Exit_Invalid_Connections + Must_Exit_Invalid_Connections = defaultdict(set) + processed_regions = list() + ignored_regions = list() + sector_entrances = set() + must_exit_regions = list() + must_exit_candidates_copy = must_exit_candidates.copy() + while len(must_exit_candidates_copy): + region_group = next(iter(must_exit_candidates_copy)) + process_group(region_group) + + # build final must exit lists + must_exit_lw = list() + must_exit_dw = list() + for regions, entrances in must_exit_regions: + region = avail.world.get_region(regions[0], avail.player) + if region.type == RegionType.LightWorld: + must_exit_lw.append(entrances) + else: + must_exit_dw.append(entrances) + return must_exit_lw, must_exit_dw + + def figure_out_must_exits_same_world(entrances, exits, avail): lw_entrances, dw_entrances = [], [] - hyrule_forced = None - check_for_hc = (avail.is_standard() or avail.world.doorShuffle[avail.player] != 'vanilla') for x in entrances: lw_entrances.append(x) if x in LW_Entrances else dw_entrances.append(x) multi_exit_caves = figure_out_connectors(exits) - if check_for_hc: - for option in multi_exit_caves: - if any(x in option for x in ['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (East)', - 'Hyrule Castle Exit (West)']): - hyrule_forced = [option] - if hyrule_forced: - remove_from_list(multi_exit_caves, hyrule_forced) - must_exit_lw, must_exit_dw = must_exits_helper(avail, lw_entrances, dw_entrances) - - return must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves, hyrule_forced - - -def must_exits_helper(avail, lw_entrances, dw_entrances): - must_exit_lw = (Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit).copy() - must_exit_dw = (Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit).copy() - if not avail.inverted and not avail.skull_handled: - must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) + must_exit_lw, must_exit_dw = must_exits_helper(avail) must_exit_lw = must_exit_filter(avail, must_exit_lw, lw_entrances) must_exit_dw = must_exit_filter(avail, must_exit_dw, dw_entrances) - return must_exit_lw, must_exit_dw + + return must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves def figure_out_must_exits_cross_world(entrances, exits, avail): multi_exit_caves = figure_out_connectors(exits) - must_exit_lw = (Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit).copy() - must_exit_dw = (Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit).copy() - if not avail.inverted and not avail.skull_handled: - must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) + must_exit_lw, must_exit_dw = must_exits_helper(avail) must_exit = must_exit_filter(avail, must_exit_lw + must_exit_dw, entrances) return must_exit, multi_exit_caves @@ -632,10 +957,10 @@ def do_fixed_shuffle(avail, entrance_list): max_size = max(max_size, size) rules = Restrictions() rules.size = size - if ('Hyrule Castle Entrance (South)' in entrances and - avail.world.doorShuffle[avail.player] != 'vanilla'): + if ('Hyrule Castle Entrance (South)' in entrances and avail.is_sanc_forced_in_hc()): rules.must_exit_to_lw = True - if 'Inverted Ganons Tower' in entrances and not avail.world.shuffle_ganon: + if (avail.world.is_atgt_swapped(avail.player) and 'Agahnims Tower' in entrances and + not avail.world.shuffle_ganon[avail.player]): rules.fixed = True option = (i, entrances, targets, rules) options[i] = option @@ -647,10 +972,24 @@ def do_fixed_shuffle(avail, entrance_list): elif rules.fixed: choice = choices[i] elif rules.must_exit_to_lw: - filtered_choices = {i: opt for i, opt in choices.items() if all(t in default_lw for t in opt[2])} - index, choice = random.choice(list(filtered_choices.items())) + lw_exits = set() + for e, x in {**entrance_map, **single_entrance_map, **drop_map}.items(): + if x in avail.exits: + region = avail.world.get_entrance(e, avail.player).parent_region + if region.type == RegionType.LightWorld: + new_x = x + if avail.world.is_atgt_swapped(avail.player): + if x == 'Ganons Tower Exit': + new_x = 'Agahnims Tower Exit' + elif x == 'Agahnims Tower Exit': + new_x = 'Ganons Tower Exit' + lw_exits.add(new_x) + if avail.world.shufflelinks[avail.player] or avail.world.shuffle[avail.player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + lw_exits.update({'Big Bomb Shop'} if avail.world.is_bombshop_start(avail.player) else {'Links House Exit'}) + filtered_choices = {i: opt for i, opt in choices.items() if all(t in lw_exits for t in opt[2])} + _, choice = random.choice(list(filtered_choices.items())) else: - index, choice = random.choice(list(choices.items())) + _, choice = random.choice(list(choices.items())) del choices[choice[0]] for t, entrance in enumerate(entrances): target = choice[2][t] @@ -663,7 +1002,6 @@ def do_same_world_shuffle(avail, pool_def): # complete_entrance_set = set() lw_entrances, dw_entrances, multi_exits_caves, other_exits = [], [], [], [] hyrule_forced = None - check_for_hc = avail.is_standard() or avail.world.doorShuffle[avail.player] != 'vanilla' single_entrances, single_exits = find_entrances_and_exits(avail, single_exit) other_exits.extend(single_exits) @@ -673,25 +1011,25 @@ def do_same_world_shuffle(avail, pool_def): for option in multi_exit: multi_entrances, multi_exits = find_entrances_and_exits(avail, option) # complete_entrance_set.update(multi_entrances) - if check_for_hc and any(x in multi_entrances for x in ['Hyrule Castle Entrance (South)', + if avail.is_sanc_forced_in_hc() and any(x in multi_entrances for x in ['Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)']): hyrule_forced = [multi_exits] - else: - multi_exits_caves.append(multi_exits) + multi_exits_caves.append(multi_exits) for x in multi_entrances: (dw_entrances, lw_entrances)[x in LW_Entrances].append(x) - must_exit_lw = Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit - must_exit_dw = Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit + must_exit_lw, must_exit_dw = must_exits_helper(avail) must_exit_lw = must_exit_filter(avail, must_exit_lw, lw_entrances) must_exit_dw = must_exit_filter(avail, must_exit_dw, dw_entrances) - if hyrule_forced: - do_mandatory_connections(avail, lw_entrances, hyrule_forced, must_exit_lw) + do_mandatory_connections(avail, lw_entrances, multi_exits_caves, must_exit_lw) + if hyrule_forced and hyrule_forced[0] in multi_exits_caves: + remove_from_list(multi_exits_caves, hyrule_forced) + do_mandatory_connections(avail, dw_entrances, multi_exits_caves, must_exit_dw) + multi_exits_caves.append(hyrule_forced[0]) else: - do_mandatory_connections(avail, lw_entrances, multi_exits_caves, must_exit_lw) - do_mandatory_connections(avail, dw_entrances, multi_exits_caves, must_exit_dw) + do_mandatory_connections(avail, dw_entrances, multi_exits_caves, must_exit_dw) # connect caves random.shuffle(lw_entrances) @@ -699,12 +1037,18 @@ def do_same_world_shuffle(avail, pool_def): random.shuffle(multi_exits_caves) while multi_exits_caves: cave_candidate = (None, 0) - for i, cave in enumerate(multi_exits_caves): - if len(cave) > cave_candidate[1]: - cave_candidate = (i, len(cave)) - cave = multi_exits_caves.pop(cave_candidate[0]) + if hyrule_forced and hyrule_forced[0] in multi_exits_caves: + multi_exits_caves.remove(hyrule_forced[0]) + cave = hyrule_forced[0] + hyrule_forced = None + target = lw_entrances + else: + for i, cave in enumerate(multi_exits_caves): + if len(cave) > cave_candidate[1]: + cave_candidate = (i, len(cave)) + cave = multi_exits_caves.pop(cave_candidate[0]) + target = lw_entrances if random.randint(0, 1) == 0 else dw_entrances - target = lw_entrances if random.randint(0, 1) == 0 else dw_entrances if len(target) < len(cave): # swap because we ran out of entrances in that world target = lw_entrances if target is dw_entrances else dw_entrances @@ -715,35 +1059,35 @@ def do_same_world_shuffle(avail, pool_def): def do_connector_shuffle(avail, pool_def): - directional_list = pool_def['directional_inv' if avail.inverted else 'directional'] - connector_list = pool_def['connectors_inv' if avail.inverted else 'connectors'] + directional_list = pool_def['directional'] + connector_list = pool_def['connectors'] option_list = pool_def['options'] for connector in directional_list: chosen_option = random.choice(option_list) - ignored_ent, chosen_exits = find_entrances_and_exits(avail, chosen_option) + _, chosen_exits = find_entrances_and_exits(avail, chosen_option) if not chosen_exits: continue # nothing available # this shuffle ensures directionality shuffle_connector_exits(chosen_exits) - connector_ent, ignored_exits = find_entrances_and_exits(avail, connector) + connector_ent, _ = find_entrances_and_exits(avail, connector) for i, ent in enumerate(connector_ent): connect_two_way(ent, chosen_exits[i], avail) option_list.remove(chosen_option) for connector in connector_list: chosen_option = random.choice(option_list) - ignored_ent, chosen_exits = find_entrances_and_exits(avail, chosen_option) + _, chosen_exits = find_entrances_and_exits(avail, chosen_option) # directionality need not be preserved random.shuffle(chosen_exits) - connector_ent, ignored_exits = find_entrances_and_exits(avail, connector) + connector_ent, _ = find_entrances_and_exits(avail, connector) for i, ent in enumerate(connector_ent): connect_two_way(ent, chosen_exits[i], avail) option_list.remove(chosen_option) def do_limited_shuffle(pool_def, avail): - entrance_pool, ignored_exits = find_entrances_and_exits(avail, pool_def['entrances']) + entrance_pool, _ = find_entrances_and_exits(avail, pool_def['entrances']) exit_pool = [x for x in pool_def['options'] if x in avail.exits] random.shuffle(exit_pool) for entrance in entrance_pool: @@ -752,9 +1096,13 @@ def do_limited_shuffle(pool_def, avail): def do_limited_shuffle_exclude_drops(pool_def, avail, lw=True): - ignored_entrances, exits = find_entrances_and_exits(avail, pool_def['entrances']) + if avail.inverted: + lw = not lw + _, exits = find_entrances_and_exits(avail, pool_def['entrances']) reserved_drops = set(linked_drop_map.values()) - must_exit_lw, must_exit_dw = must_exits_helper(avail, LW_Entrances, DW_Entrances) + must_exit_lw, must_exit_dw = must_exits_helper(avail) + must_exit_lw = must_exit_filter(avail, must_exit_lw, LW_Entrances) + must_exit_dw = must_exit_filter(avail, must_exit_dw, DW_Entrances) must_exit = set(must_exit_lw if lw else must_exit_dw) base_set = LW_Entrances if lw else DW_Entrances entrance_pool = [x for x in base_set if x in avail.entrances and x not in reserved_drops] @@ -779,11 +1127,7 @@ def do_vanilla_connect(pool_def, avail): elif pool_def['condition'] == 'takeany': if avail.world.take_any[avail.player] == 'fixed': return - defaults = inverted_default_connections if avail.inverted else default_connections - if avail.inverted: - if 'Dark Death Mountain Fairy' in pool_def['entrances']: - pool_def['entrances'].remove('Dark Death Mountain Fairy') - pool_def['entrances'].append('Bumper Cave (top)') + defaults = {**default_connections, **(inverted_default_connections if avail.inverted != avail.world.is_tile_swapped(0x1b, avail.player) else open_default_connections)} for entrance in pool_def['entrances']: if entrance in avail.entrances: target = defaults[entrance] @@ -802,16 +1146,12 @@ def do_mandatory_connections(avail, entrances, cave_options, must_exit): do_mandatory_connections_decoupled(avail, cave_options, must_exit) return - # Keeps track of entrances that cannot be used to access each exit / cave - if avail.inverted: - invalid_connections = Inverted_Must_Exit_Invalid_Connections.copy() - else: - invalid_connections = Must_Exit_Invalid_Connections.copy() + invalid_connections = Must_Exit_Invalid_Connections.copy() invalid_cave_connections = defaultdict(set) if avail.world.logic[avail.player] in ['owglitches', 'nologic']: import OverworldGlitchRules - for entrance in OverworldGlitchRules.get_non_mandatory_exits(avail.inverted): + for entrance in OverworldGlitchRules.get_non_mandatory_exits(avail.world, avail.player): invalid_connections[entrance] = set() if entrance in must_exit: must_exit.remove(entrance) @@ -820,12 +1160,12 @@ def do_mandatory_connections(avail, entrances, cave_options, must_exit): random.shuffle(entrances) random.shuffle(cave_options) - if avail.inverted: - at = avail.world.get_region('Agahnims Tower Portal', avail.player) + if avail.world.is_tile_swapped(0x1b, avail.player): for entrance in invalid_connections: - if avail.world.get_entrance(entrance, avail.player).connected_region == at: + region = avail.world.get_entrance(entrance, avail.player).connected_region + if region and region.name == 'Agahnims Tower Portal': for ext in invalid_connections[entrance]: - invalid_connections[ext] = invalid_connections[ext].union({'Inverted Ganons Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}) + invalid_connections[ext] = invalid_connections[ext].union({'Agahnims Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}) break used_caves = [] @@ -965,11 +1305,11 @@ def find_entrances_and_exits(avail_pool, entrance_pool): entrances, targets = [], [] inverted_substitution(avail_pool, entrance_pool, True) for item in entrance_pool: + if item == 'Ganons Tower' and not avail_pool.world.shuffle_ganon[avail_pool.player]: + continue if item in avail_pool.entrances: entrances.append(item) if item in entrance_map and entrance_map[item] in avail_pool.exits: - if entrance_map[item] in ['Links House Exit', 'Inverted Links House Exit']: - targets.append('Chris Houlihan Room Exit') targets.append(entrance_map[item]) elif item in single_entrance_map and single_entrance_map[item] in avail_pool.exits: targets.append(single_entrance_map[item]) @@ -977,26 +1317,16 @@ def find_entrances_and_exits(avail_pool, entrance_pool): inverted_sub_table = { - 'Ganons Tower': 'Inverted Agahnims Tower', - 'Agahnims Tower': 'Inverted Ganons Tower', - 'Dark Sanctuary Hint': 'Inverted Dark Sanctuary', - 'Big Bomb Shop': 'Inverted Links House', - 'Links House': 'Inverted Big Bomb Shop', 'Pyramid Hole': 'Inverted Pyramid Hole', 'Pyramid Entrance': 'Inverted Pyramid Entrance' } inverted_exit_sub_table = { - 'Ganons Tower Exit': 'Inverted Agahnims Tower Exit', - 'Agahnims Tower Exit': 'Inverted Ganons Tower Exit', - 'Dark Sanctuary Hint': 'Inverted Dark Sanctuary Exit', - 'Big Bomb Shop': 'Inverted Links House Exit', - 'Links House Exit': 'Inverted Big Bomb Shop', } def inverted_substitution(avail_pool, collection, is_entrance, is_set=False): - if avail_pool.inverted: + if avail_pool.world.is_tile_swapped(0x1b, avail_pool.player): sub_table = inverted_sub_table if is_entrance else inverted_exit_sub_table for area, sub in sub_table.items(): if is_set: @@ -1087,10 +1417,7 @@ def connect_entrance(entrancename, exit_name, avail): entrance.connect(region, addresses, target) avail.entrances.remove(entrancename) if avail.coupled: - if exit_name == 'Inverted Dark Sanctuary': - avail.exits.remove('Inverted Dark Sanctuary Exit') - else: - avail.exits.remove(exit_name) + avail.exits.remove(exit_name) world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) logging.getLogger('').debug(f'Connected (entr) {entrance.name} to {exit.name if exit is not None else region.name}') @@ -1105,9 +1432,10 @@ def connect_exit(exit_name, entrancename, avail): exit.connected_region.entrances.remove(exit) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) - if exit_name != 'Chris Houlihan Room Exit' and avail.coupled: - avail.entrances.remove(entrancename) - avail.exits.remove(exit_name) + if exit_name != 'Chris Houlihan Room Exit': + if avail.coupled: + avail.entrances.remove(entrancename) + avail.exits.remove(exit_name) world.spoiler.set_entrance(entrance.name, exit.name, 'exit', player) logging.getLogger('').debug(f'Connected (exit) {entrance.name} to {exit.name}') @@ -1204,6 +1532,12 @@ modes = { 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] }, + 'drops': { + 'special': 'normal_drops', + 'entrances': ['Hyrule Castle Secret Entrance Drop', 'Kakariko Well Drop', 'Bat Cave Drop', + 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', + 'Sanctuary Grave', 'Pyramid Hole'] + }, 'fixed_non_items': { 'special': 'vanilla', 'condition': '', @@ -1241,13 +1575,14 @@ modes = { 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', 'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut', 'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout', - 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', + 'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', 'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Desert Hint', + 'Dark Desert Hint', 'Desert Fairy', 'Light Hype Fairy', 'Dark Death Mountain Fairy', + 'Dark Lake Hylia Ledge Fairy', 'Bonk Fairy (Dark)', 'Links House', 'Tavern North'] }, 'old_man_cave': { # have to do old man cave first so lw dungeon don't use up everything @@ -1284,6 +1619,12 @@ modes = { 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] }, + 'drops': { + 'special': 'normal_drops', + 'entrances': ['Hyrule Castle Secret Entrance Drop', 'Kakariko Well Drop', 'Bat Cave Drop', + 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', + 'Sanctuary Grave', 'Pyramid Hole'] + }, 'fixed_non_items': { 'special': 'vanilla', 'condition': '', @@ -1321,13 +1662,14 @@ modes = { 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', 'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut', 'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout', - 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', + 'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', 'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Desert Hint', + 'Dark Desert Hint', 'Desert Fairy', 'Light Hype Fairy', 'Dark Death Mountain Fairy', + 'Dark Lake Hylia Ledge Fairy', 'Bonk Fairy (Dark)', 'Links House', 'Tavern North'] # inverted links house gets substituted } } @@ -1371,15 +1713,6 @@ modes = { ['Two Brothers House (East)', 'Two Brothers House (West)'], ['Superbunny Cave (Bottom)', 'Superbunny Cave (Top)'] ], - 'directional_inv': [ - ['Old Man Cave (West)', 'Death Mountain Return Cave (West)'], - ['Two Brothers House (East)', 'Two Brothers House (West)'], - ], - 'connectors_inv': [ - ['Elder House (East)', 'Elder House (West)'], - ['Superbunny Cave (Bottom)', 'Superbunny Cave (Top)'], - ['Hookshot Cave', 'Hookshot Cave Back Entrance'] - ], 'options': [ ['Bumper Cave (Bottom)', 'Bumper Cave (Top)'], ['Hookshot Cave', 'Hookshot Cave Back Entrance'], @@ -1395,11 +1728,6 @@ modes = { 'special': 'old_man_cave_east', 'entrances': ['Old Man Cave Exit (East)'], }, - 'old_man_cave_inverted': { - 'special': 'inverted_fixed', - 'entrance': 'Bumper Cave (Bottom)', - 'exit': 'Old Man Cave Exit (West)' - }, 'light_death_mountain': { 'special': 'limited', 'entrances': ['Old Man Cave (West)', 'Old Man Cave (East)', 'Old Man House (Bottom)', @@ -1536,7 +1864,6 @@ entrance_map = { 'Hyrule Castle Entrance (West)': 'Hyrule Castle Exit (West)', 'Hyrule Castle Entrance (East)': 'Hyrule Castle Exit (East)', 'Agahnims Tower': 'Agahnims Tower Exit', - 'Inverted Agahnims Tower': 'Inverted Agahnims Tower Exit', 'Thieves Town': 'Thieves Town Exit', 'Skull Woods First Section Door': 'Skull Woods First Section Exit', @@ -1553,10 +1880,8 @@ entrance_map = { 'Dark Death Mountain Ledge (East)': 'Turtle Rock Ledge Exit (East)', 'Turtle Rock Isolated Ledge Entrance': 'Turtle Rock Isolated Ledge Exit', 'Ganons Tower': 'Ganons Tower Exit', - 'Inverted Ganons Tower': 'Inverted Ganons Tower Exit', 'Links House': 'Links House Exit', - 'Inverted Links House': 'Inverted Links House Exit', 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance Exit', @@ -1595,8 +1920,7 @@ entrance_map = { 'Spectacle Rock Cave': 'Spectacle Rock Cave Exit (Top)', 'Paradox Cave (Bottom)': 'Paradox Cave Exit (Bottom)', 'Paradox Cave (Middle)': 'Paradox Cave Exit (Middle)', - 'Paradox Cave (Top)': 'Paradox Cave Exit (Top)', - 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary Exit', + 'Paradox Cave (Top)': 'Paradox Cave Exit (Top)' } @@ -1631,113 +1955,18 @@ single_entrance_map = { 'Kings Grave': 'Kings Grave', 'Desert Fairy': 'Desert Healer Fairy', 'Light Hype Fairy': 'Swamp Healer Fairy', 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', 'Lumberjack House': 'Lumberjack House', 'Dam': 'Dam', - 'Blinds Hideout': 'Blinds Hideout', 'Waterfall of Wishing': 'Waterfall of Wishing', - 'Inverted Bomb Shop': 'Inverted Bomb Shop' + 'Blinds Hideout': 'Blinds Hideout', 'Waterfall of Wishing': 'Waterfall of Wishing' } -default_dw = { - 'Thieves Town Exit', 'Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', - 'Skull Woods Second Section Exit (West)', 'Skull Woods Final Section Exit', 'Ice Palace Exit', 'Misery Mire Exit', - 'Palace of Darkness Exit', 'Swamp Palace Exit', 'Turtle Rock Exit (Front)', 'Turtle Rock Ledge Exit (West)', - 'Turtle Rock Ledge Exit (East)', 'Turtle Rock Isolated Ledge Exit', 'Bumper Cave Exit (Top)', - 'Bumper Cave Exit (Bottom)', 'Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)', - 'Hookshot Cave Front Exit', 'Hookshot Cave Back Exit', 'Ganons Tower Exit', 'Pyramid Exit', - 'Dark Lake Hylia Healer Fairy', 'Dark Lake Hylia Ledge Healer Fairy', 'Dark Desert Healer Fairy', - 'Dark Death Mountain Healer Fairy', 'Cave Shop (Dark Death Mountain)', 'Pyramid Fairy', 'East Dark World Hint', - 'Palace of Darkness Hint', 'Big Bomb Shop', 'Village of Outcasts Shop', 'Dark Lake Hylia Shop', - 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Brewery', 'C-Shaped House', 'Chest Game', 'Dark World Hammer Peg Cave', - 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', - 'Spike Cave', 'Skull Back Drop', 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle', 'Pyramid', - 'Inverted Agahnims Tower Exit', 'Inverted Dark Sanctuary Exit', 'Inverted Links House Exit' -} +LW_Entrances = [] +DW_Entrances = [] -default_lw = { - 'Links House Exit', 'Desert Palace Exit (South)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', - 'Desert Palace Exit (North)', 'Eastern Palace Exit', 'Tower of Hera Exit', 'Hyrule Castle Exit (South)', - 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Agahnims Tower Exit', - 'Hyrule Castle Secret Entrance Exit', 'Kakariko Well Exit', 'Bat Cave Exit', 'Elder House Exit (East)', - 'Elder House Exit (West)', 'North Fairy Cave Exit', 'Lost Woods Hideout Exit', 'Lumberjack Tree Exit', - 'Two Brothers House Exit (East)', 'Two Brothers House Exit (West)', 'Sanctuary Exit', 'Old Man Cave Exit (East)', - 'Old Man Cave Exit (West)', 'Old Man House Exit (Bottom)', 'Old Man House Exit (Top)', - 'Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)', 'Spectacle Rock Cave Exit', - 'Spectacle Rock Cave Exit (Top)', 'Spectacle Rock Cave Exit (Peak)', 'Paradox Cave Exit (Bottom)', - 'Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Fairy Ascension Cave Exit (Bottom)', - 'Fairy Ascension Cave Exit (Top)', 'Spiral Cave Exit', 'Spiral Cave Exit (Top)', 'Waterfall of Wishing', 'Dam', - 'Blinds Hideout', 'Lumberjack House', 'Bonk Fairy (Light)', 'Bonk Fairy (Dark)', 'Lake Hylia Healer Fairy', - 'Swamp Healer Fairy', 'Desert Healer Fairy', 'Fortune Teller (Light)', 'Lake Hylia Fortune Teller', 'Kings Grave', 'Tavern', - 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Capacity Upgrade', 'Blacksmiths Hut', - 'Sick Kids House', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', - 'Tavern (Front)', 'Light World Bomb Hut', 'Kakariko Shop', 'Cave 45', 'Graveyard Cave', 'Checkerboard Cave', - 'Mini Moldorm Cave', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', '50 Rupee Cave', 'Ice Rod Cave', - 'Bonk Rock Cave', 'Library', 'Kakariko Gamble Game', 'Potion Shop', 'Hookshot Fairy', 'Mimic Cave', - 'Kakariko Well (top)', 'Hyrule Castle Secret Entrance', 'Bat Cave (right)', 'North Fairy Cave', - 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Inverted Ganons Tower Exit', - 'Inverted Big Bomb Shop' -} - -LW_Entrances = ['Elder House (East)', 'Elder House (West)', 'Two Brothers House (East)', 'Two Brothers House (West)', - 'Old Man Cave (West)', 'Old Man House (Bottom)', 'Death Mountain Return Cave (West)', - 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', - 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', - 'Desert Palace Entrance (South)', 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', - 'Desert Palace Entrance (East)', 'Eastern Palace', 'Tower of Hera', 'Hyrule Castle Entrance (West)', - 'Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (South)', 'Agahnims Tower', 'Blinds Hideout', - 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Tavern North', 'Chicken House', 'Aginahs Cave', - 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Blacksmiths Hut', 'Sick Kids House', 'Lost Woods Gamble', - 'Fortune Teller (Light)', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', - 'Tavern (Front)', 'Light World Bomb Hut', 'Kakariko Shop', 'Mini Moldorm Cave', 'Long Fairy Cave', - 'Good Bee Cave', '20 Rupee Cave', '50 Rupee Cave', 'Ice Rod Cave', 'Library', 'Potion Shop', 'Dam', - 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Waterfall of Wishing', - 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', 'Kings Grave', - 'Bonk Fairy (Light)', 'Hookshot Fairy', 'Mimic Cave', 'Links House', 'Old Man Cave (East)', - 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', - 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Hyrule Castle Secret Entrance Stairs', - 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Lost Woods Hideout Stump', - 'Lumberjack Tree Cave', 'Sanctuary', - 'Inverted Ganons Tower', 'Inverted Big Bomb Shop', 'Inverted Pyramid Entrance'] - -DW_Entrances = ['Bumper Cave (Bottom)', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', 'Hookshot Cave', - 'Thieves Town', 'Skull Woods Final Section', 'Ice Palace', 'Misery Mire', 'Palace of Darkness', - 'Swamp Palace', 'Turtle Rock', 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', - 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', - 'Bonk Fairy (Dark)', 'Dark Sanctuary Hint', 'Dark Lake Hylia Fairy', 'C-Shaped House', 'Big Bomb Shop', - 'Dark Death Mountain Fairy', 'Dark Lake Hylia Shop', 'Dark World Shop', 'Red Shield Shop', 'Mire Shed', - 'East Dark World Hint', 'Dark Desert Hint', 'Spike Cave', 'Palace of Darkness Hint', - 'Dark Lake Hylia Ledge Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', - 'Pyramid Fairy', 'Archery Game', 'Dark World Lumberjack Shop', 'Hype Cave', 'Brewery', - 'Dark Lake Hylia Ledge Hint', 'Chest Game', 'Dark Desert Fairy', 'Dark Lake Hylia Ledge Fairy', - 'Fortune Teller (Dark)', 'Dark World Hammer Peg Cave', 'Pyramid Entrance', - 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', - 'Skull Woods Second Section Door (West)', - 'Inverted Dark Sanctuary', 'Inverted Links House', 'Inverted Agahnims Tower'] - -LW_Must_Exit = ['Desert Palace Entrance (East)'] - -DW_Must_Exit = [('Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)'), - 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', - 'Pyramid Entrance'] - -Inverted_LW_Must_Exit = [('Desert Palace Entrance (North)', 'Desert Palace Entrance (West)'), - 'Desert Palace Entrance (East)', 'Death Mountain Return Cave (West)', - 'Two Brothers House (West)', - ('Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower')] - -Inverted_DW_Must_Exit = [] - -Isolated_LH_Doors_Open = ['Mimic Cave', 'Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', - 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', - 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', - 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', - 'Dark World Shop', 'Dark World Potion Shop'] - -Isolated_LH_Doors_Inv = ['Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', - 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', - 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', - 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', - 'Dark World Shop', 'Dark World Potion Shop'] +Isolated_LH_Doors = ['Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', + 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', + 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', + 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', + 'Dark World Shop', 'Dark World Potion Shop'] # inverted doesn't like really like - Paradox Top or Tower of Hera LH_DM_Connector_List = { @@ -1745,7 +1974,7 @@ LH_DM_Connector_List = { 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Tower of Hera', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Hookshot Fairy', 'Spike Cave', - 'Dark Death Mountain Fairy', 'Inverted Agahnims Tower', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', + 'Dark Death Mountain Fairy', 'Ganons Tower', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Cave Shop (Dark Death Mountain)', 'Turtle Rock'} LH_DM_Exit_Forbidden = { @@ -1755,12 +1984,6 @@ LH_DM_Exit_Forbidden = { 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)' } # omissions from Isolated Starts: 'Desert Palace Entrance (North)', 'Dark World Shop', 'Dark World Potion Shop' -# in inverted we put dark sanctuary in west dark world for now -Inverted_Dark_Sanctuary_Doors = [ - 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', - 'Dark World Lumberjack Shop', 'Red Shield Shop', 'Bumper Cave (Bottom)', 'Bumper Cave (Top)', 'Thieves Town' -] - Connector_List = [['Elder House Exit (East)', 'Elder House Exit (West)'], ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)'], ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)'], @@ -1793,192 +2016,41 @@ Connector_Exit_Set = { } # Entrances that cannot be used to access a must_exit entrance - symmetrical to allow reverse lookups -Must_Exit_Invalid_Connections = defaultdict(set, { - 'Dark Death Mountain Ledge (East)': {'Dark Death Mountain Ledge (West)', 'Mimic Cave'}, - 'Dark Death Mountain Ledge (West)': {'Dark Death Mountain Ledge (East)', 'Mimic Cave'}, - 'Mimic Cave': {'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)'}, - 'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'}, - 'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'}, - 'Skull Woods Second Section Door (West)': {'Skull Woods Final Section'}, - 'Skull Woods Final Section': {'Skull Woods Second Section Door (West)'}, -}) -Inverted_Must_Exit_Invalid_Connections = defaultdict(set, { - 'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'}, - 'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'}, - 'Desert Palace Entrance (North)': {'Desert Palace Entrance (West)'}, - 'Desert Palace Entrance (West)': {'Desert Palace Entrance (North)'}, - 'Inverted Ganons Tower': {'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}, - 'Hyrule Castle Entrance (West)': {'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower'}, - 'Hyrule Castle Entrance (East)': {'Hyrule Castle Entrance (West)', 'Inverted Ganons Tower'}, -}) - -Old_Man_Entrances = ['Old Man Cave (East)', - 'Old Man House (Top)', - 'Death Mountain Return Cave (East)', - 'Spectacle Rock Cave', - 'Spectacle Rock Cave Peak', - 'Spectacle Rock Cave (Bottom)', - 'Tower of Hera'] - -Inverted_Old_Man_Entrances = ['Dark Death Mountain Fairy', 'Spike Cave', 'Inverted Agahnims Tower'] +Must_Exit_Invalid_Connections = defaultdict(set) Simple_DM_Non_Connectors = {'Old Man Cave Ledge', 'Spiral Cave (Top)', 'Superbunny Cave (Bottom)', 'Spectacle Rock Cave (Peak)', 'Spectacle Rock Cave (Top)'} -Blacksmith_Options = [ - 'Blinds Hideout', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Tavern North', 'Chicken House', - 'Aginahs Cave', 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Blacksmiths Hut', 'Sick Kids House', 'Lost Woods Gamble', - 'Fortune Teller (Light)', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', 'Tavern (Front)', - 'Light World Bomb Hut', 'Kakariko Shop', 'Mini Moldorm Cave', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', - '50 Rupee Cave', 'Ice Rod Cave', 'Library', 'Potion Shop', 'Dam', 'Lumberjack House', 'Lake Hylia Fortune Teller', - 'Kakariko Gamble Game', 'Eastern Palace', 'Elder House (East)', 'Elder House (West)', 'Two Brothers House (East)', - 'Old Man Cave (West)', 'Sanctuary', 'Lumberjack Tree Cave', 'Lost Woods Hideout Stump', 'North Fairy Cave', - 'Bat Cave Cave', 'Kakariko Well Cave', 'Inverted Big Bomb Shop', 'Links House'] - -Bomb_Shop_Options = [ - 'Waterfall of Wishing', 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', - 'Kings Grave', 'Bonk Fairy (Light)', 'Hookshot Fairy', 'East Dark World Hint', 'Palace of Darkness Hint', - 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Bonk Fairy (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', - 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Shop', - 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', - 'Dark Desert Fairy', 'Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy', 'Mimic Cave', - 'Big Bomb Shop', 'Dark Lake Hylia Shop', 'Bumper Cave (Top)', 'Links House', - 'Hyrule Castle Entrance (South)', 'Misery Mire', 'Thieves Town', 'Bumper Cave (Bottom)', 'Swamp Palace', - 'Hyrule Castle Secret Entrance Stairs', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', - 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', 'Ice Palace', 'Turtle Rock', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', 'Superbunny Cave (Top)', - 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Ganons Tower', 'Desert Palace Entrance (South)', 'Tower of Hera', - 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', - 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', - 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Fairy Ascension Cave (Bottom)', - 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Palace of Darkness', - 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower', - 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', - 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)', 'Two Brothers House (West)'] + Blacksmith_Options - -Inverted_Bomb_Shop_Options = [ - 'Waterfall of Wishing', 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', - 'Kings Grave', 'Bonk Fairy (Light)', 'Hookshot Fairy', 'East Dark World Hint', 'Palace of Darkness Hint', - 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Bonk Fairy (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', - 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Fortune Teller (Dark)', 'Dark World Shop', - 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', - 'Dark Desert Fairy', 'Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy', 'Mimic Cave', - 'Dark Lake Hylia Shop', 'Bumper Cave (Top)', - 'Hyrule Castle Entrance (South)', 'Misery Mire', 'Thieves Town', 'Bumper Cave (Bottom)', 'Swamp Palace', - 'Hyrule Castle Secret Entrance Stairs', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', - 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', 'Ice Palace', 'Turtle Rock', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', 'Superbunny Cave (Top)', - 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Desert Palace Entrance (South)', 'Tower of Hera', - 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', - 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', - 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Fairy Ascension Cave (Bottom)', - 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Palace of Darkness', - 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', - 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', - 'Inverted Ganons Tower', 'Inverted Agahnims Tower', 'Inverted Dark Sanctuary', 'Inverted Links House', - 'Inverted Big Bomb Shop'] + Blacksmith_Options - # these are connections that cannot be shuffled and always exist. -# They link together separate parts of the world we need to divide into regions -mandatory_connections = [('Links House S&Q', 'Links House'), - ('Sanctuary S&Q', 'Sanctuary'), - ('Old Man S&Q', 'Old Man House'), - ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), - ('Lake Hylia Central Island Teleporter', 'Dark Lake Hylia Central Island'), - ('Zoras River', 'Zoras River'), - ('Zora Waterfall Entryway', 'Zora Waterfall Entryway'), - ('Zora Waterfall Water Drop', 'Light World'), - ('Kings Grave Outer Rocks', 'Kings Grave Area'), - ('Kings Grave Inner Rocks', 'Light World'), +# They link together underworld regions +mandatory_connections = [('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), + ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), ('Kakariko Well (top to back)', 'Kakariko Well (back)'), - ('Master Sword Meadow', 'Master Sword Meadow'), - ('Hobo Bridge', 'Hobo Bridge'), - ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), - ('Bat Cave Door', 'Bat Cave (left)'), - ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), - ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), ('Blinds Hideout N', 'Blinds Hideout (Top)'), - ('Desert Palace Stairs', 'Desert Palace Stairs'), - ('Desert Palace Stairs Drop', 'Light World'), - ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), - ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Hyrule Castle Ledge Courtyard Drop', 'Hyrule Castle Courtyard'), - ('Hyrule Castle Main Gate', 'Hyrule Castle Courtyard'), + ('Bat Cave Door', 'Bat Cave (left)'), ('Sewer Drop', 'Sewers Rat Path'), - ('Flute Spot 1', 'Death Mountain'), - ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), - ('Death Mountain Entrance Drop', 'Light World'), + ('Old Man Cave Dropdown', 'Old Man Cave'), + ('Old Man House Front to Back', 'Old Man House Back'), + ('Old Man House Back to Front', 'Old Man House'), ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), - ('Death Mountain Return Ledge Drop', 'Light World'), - ('Old Man Cave Dropdown', 'Old Man Cave'), - ('Old Man House Front to Back', 'Old Man House Back'), - ('Old Man House Back to Front', 'Old Man House'), - ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), - ('Broken Bridge (East)', 'Death Mountain'), - ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), - ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), - ('East Death Mountain (Top)', 'East Death Mountain (Top)'), - ('Death Mountain (Top)', 'Death Mountain (Top)'), - ('Death Mountain Drop', 'Death Mountain'), - ('Spectacle Rock Drop', 'Death Mountain (Top)'), - - ('Top of Pyramid', 'East Dark World'), - ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), - ('Dark Lake Hylia Ledge', 'Dark Lake Hylia Ledge'), - ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), - ('East Dark World Pier', 'East Dark World'), - ('South Dark World Bridge', 'South Dark World'), - ('East Dark World Bridge', 'East Dark World'), - ('Maze Race Mirror Spot', 'Maze Race Ledge'), - ('Village of Outcasts Heavy Rock', 'West Dark World'), - ('Village of Outcasts Drop', 'South Dark World'), - ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), - ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), - ('Peg Area Rocks', 'West Dark World'), - ('Grassy Lawn Pegs', 'West Dark World'), - ('East Dark World River Pier', 'East Dark World'), - ('West Dark World Gap', 'West Dark World'), - ('East Dark World Broken Bridge Pass', 'East Dark World'), - ('Catfish Exit Rock', 'Northeast Dark World'), - ('Catfish Entrance Rock', 'Catfish'), - ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), - ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), - ('Bumper Cave Entrance Drop', 'West Dark World'), - ('Bumper Cave Ledge Drop', 'West Dark World'), - ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), - ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), - ('Skull Woods Forest', 'Skull Woods Forest'), - ('Dark Desert Teleporter', 'Dark Desert'), - ('East Hyrule Teleporter', 'East Dark World'), - ('South Hyrule Teleporter', 'South Dark World'), - ('Kakariko Teleporter', 'West Dark World'), - ('Death Mountain Teleporter', 'Dark Death Mountain (West Bottom)'), + ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), ('Paradox Cave Push Block', 'Paradox Cave Front'), ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), ('Paradox Cave Bomb Jump', 'Paradox Cave'), ('Paradox Cave Drop', 'Paradox Cave Chest Area'), - ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), - ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), - ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), - ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), + ('Missing Smith', 'Missing Smith'), + ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), + ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), @@ -1986,174 +2058,12 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), - ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), - ('Floating Island Drop', 'Dark Death Mountain (Top)'), - ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), - ('Mirror To Bombos Tablet Ledge', 'Bombos Tablet Ledge'), - ('Ganon Drop', 'Bottom of Pyramid'), - ('Pyramid Drop', 'East Dark World'), - ('Maze Race Ledge Drop', 'Light World'), - ('Graveyard Ledge Drop', 'Light World'), - ('Cave 45 Ledge Drop', 'Light World'), - ('Checkerboard Ledge Drop', 'Light World'), - ('Desert Ledge Drop', 'Light World'), - ('Hyrule Castle Main Gate (North)', 'Light World'), - ('Hyrule Castle Ledge Drop', 'Light World'), - ] - -inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), - ('Dark Sanctuary S&Q', 'Inverted Dark Sanctuary'), - ('Old Man S&Q', 'Old Man House'), - ('Castle Ledge S&Q', 'Hyrule Castle Ledge'), - ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), - ('Lake Hylia Island Pier', 'Lake Hylia Island'), - ('Lake Hylia Warp', 'Northeast Light World'), - ('Northeast Light World Warp', 'Light World'), - ('Zoras River', 'Zoras River'), - ('Waterfall of Wishing Cave', 'Waterfall of Wishing Cave'), - ('Northeast Light World Return', 'Northeast Light World'), - ('Kings Grave Outer Rocks', 'Kings Grave Area'), - ('Kings Grave Inner Rocks', 'Light World'), - ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), - ('Kakariko Well (top to back)', 'Kakariko Well (back)'), - ('Master Sword Meadow', 'Master Sword Meadow'), - ('Hobo Bridge', 'Hobo Bridge'), - ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), - ('Bat Cave Door', 'Bat Cave (left)'), - ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), - ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), - ('Blinds Hideout N', 'Blinds Hideout (Top)'), - ('Desert Palace Stairs', 'Desert Palace Stairs'), - ('Desert Palace Stairs Drop', 'Light World'), - ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), - ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Sewer Drop', 'Sewers Rat Path'), - ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), - ('Death Mountain Entrance Drop', 'Light World'), - ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), - ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), - ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), - ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), - ('Death Mountain Return Ledge Drop', 'Light World'), - ('Old Man Cave Dropdown', 'Old Man Cave'), - ('Old Man House Front to Back', 'Old Man House Back'), - ('Old Man House Back to Front', 'Old Man House'), - ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), - ('Broken Bridge (East)', 'Death Mountain'), - ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), - ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), - ('East Death Mountain (Top)', 'East Death Mountain (Top)'), - ('Death Mountain (Top)', 'Death Mountain (Top)'), - ('Death Mountain Drop', 'Death Mountain'), - ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), - ('Dark Lake Hylia Ledge Pier', 'Dark Lake Hylia Ledge'), - ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), - ('Ice Palace Missing Wall', 'Dark Lake Hylia Central Island'), - ('Dark Lake Hylia Shallows', 'Dark Lake Hylia'), - ('East Dark World Pier', 'East Dark World'), - ('South Dark World Bridge', 'South Dark World'), - ('East Dark World Bridge', 'East Dark World'), - ('Village of Outcasts Heavy Rock', 'West Dark World'), - ('Village of Outcasts Drop', 'South Dark World'), - ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), - ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), - ('Peg Area Rocks', 'West Dark World'), - ('Grassy Lawn Pegs', 'West Dark World'), - ('East Dark World River Pier', 'Northeast Dark World'), - ('West Dark World Gap', 'West Dark World'), - ('East Dark World Broken Bridge Pass', 'East Dark World'), - ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), - ('Catfish Exit Rock', 'Northeast Dark World'), - ('Catfish Entrance Rock', 'Catfish'), - ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), - ('Bumper Cave Entrance Drop', 'West Dark World'), - ('Bumper Cave Ledge Drop', 'West Dark World'), - ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), - ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), - ('Skull Woods Forest', 'Skull Woods Forest'), - ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), - ('Paradox Cave Push Block', 'Paradox Cave Front'), - ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), - ('Paradox Cave Bomb Jump', 'Paradox Cave'), - ('Paradox Cave Drop', 'Paradox Cave Chest Area'), - ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), - ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), - ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), - ('Fairy Ascension Ledge Access', 'Fairy Ascension Ledge'), - ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), - ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), - ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Ganon Drop', 'Bottom of Pyramid'), - ('Pyramid Drop', 'East Dark World'), - ('Post Aga Teleporter', 'Light World'), - ('Secret Passage Inner Bushes', 'Light World'), - ('Secret Passage Outer Bushes', 'Hyrule Castle Secret Entrance Area'), - ('Potion Shop Inner Bushes', 'Light World'), - ('Potion Shop Outer Bushes', 'Potion Shop Area'), - ('Potion Shop Inner Rock', 'Northeast Light World'), - ('Potion Shop Outer Rock', 'Potion Shop Area'), - ('Potion Shop River Drop', 'River'), - ('Graveyard Cave Inner Bushes', 'Light World'), - ('Graveyard Cave Outer Bushes', 'Graveyard Cave Area'), - ('Light World River Drop', 'River'), - ('Light World Pier', 'Light World'), - ('Potion Shop Pier', 'Potion Shop Area'), - ('Hyrule Castle Ledge Courtyard Drop', 'Light World'), - ('Mimic Cave Ledge Access', 'Mimic Cave Ledge'), - ('Mimic Cave Ledge Drop', 'East Death Mountain (Bottom)'), - ('Turtle Rock Tail Drop', 'Turtle Rock (Top)'), - ('Turtle Rock Drop', 'Dark Death Mountain'), - ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), - ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), - ('Hookshot Cave Middle to Back', 'Hookshot Cave (Back)'), - ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), - ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Desert Ledge Drop', 'Light World'), - ('Floating Island Drop', 'Dark Death Mountain'), - ('Dark Lake Hylia Central Island Teleporter', 'Lake Hylia Central Island'), - ('Dark Desert Teleporter', 'Light World'), - ('East Dark World Teleporter', 'Light World'), - ('South Dark World Teleporter', 'Light World'), - ('West Dark World Teleporter', 'Light World'), - ('Dark Death Mountain Teleporter (West)', 'Death Mountain'), - ('Dark Death Mountain Teleporter (East)', 'East Death Mountain (Top)'), - ('Dark Death Mountain Teleporter (East Bottom)', 'East Death Mountain (Bottom)'), - ('Dark Desert Drop', 'Dark Desert'), - ('DDM Flute', 'The Sky'), - ('DDM Landing', 'Dark Death Mountain'), - ('NEDW Flute', 'The Sky'), - ('NEDW Landing', 'Northeast Dark World'), - ('WDW Flute', 'The Sky'), - ('WDW Landing', 'West Dark World'), - ('SDW Flute', 'The Sky'), - ('SDW Landing', 'South Dark World'), - ('EDW Flute', 'The Sky'), - ('EDW Landing', 'East Dark World'), - ('DLHL Flute', 'The Sky'), - ('DLHL Landing', 'Dark Lake Hylia Ledge'), - ('DD Flute', 'The Sky'), - ('DD Landing', 'Dark Desert Ledge'), - ('EDDM Flute', 'The Sky'), - ('Dark Grassy Lawn Flute', 'The Sky'), - ('Hammer Peg Area Flute', 'The Sky'), - ('Bush Covered Lawn Inner Bushes', 'Light World'), - ('Bush Covered Lawn Outer Bushes', 'Bush Covered Lawn'), - ('Bomb Hut Inner Bushes', 'Light World'), - ('Bomb Hut Outer Bushes', 'Bomb Hut Area'), - ('Maze Race Ledge Drop', 'Light World')] + ('Ganon Drop', 'Bottom of Pyramid') + ] # non-shuffled entrance links default_connections = {'Links House': 'Links House', - 'Links House Exit': 'Light World', + 'Links House Exit': 'Links House Area', 'Waterfall of Wishing': 'Waterfall of Wishing', 'Blinds Hideout': 'Blinds Hideout', 'Dam': 'Dam', @@ -2175,19 +2085,19 @@ default_connections = {'Links House': 'Links House', 'Capacity Upgrade': 'Capacity Upgrade', 'Kakariko Well Drop': 'Kakariko Well (top)', 'Kakariko Well Cave': 'Kakariko Well (bottom)', - 'Kakariko Well Exit': 'Light World', + 'Kakariko Well Exit': 'Kakariko Area', 'Blacksmiths Hut': 'Blacksmiths Hut', 'Bat Cave Drop': 'Bat Cave (right)', 'Bat Cave Cave': 'Bat Cave (left)', - 'Bat Cave Exit': 'Light World', + 'Bat Cave Exit': 'Blacksmith Area', 'Sick Kids House': 'Sick Kids House', 'Elder House (East)': 'Elder House', 'Elder House (West)': 'Elder House', - 'Elder House Exit (East)': 'Light World', - 'Elder House Exit (West)': 'Light World', + 'Elder House Exit (East)': 'Kakariko Area', + 'Elder House Exit (West)': 'Kakariko Area', 'North Fairy Cave Drop': 'North Fairy Cave', 'North Fairy Cave': 'North Fairy Cave', - 'North Fairy Cave Exit': 'Light World', + 'North Fairy Cave Exit': 'River Bend Area', 'Lost Woods Gamble': 'Lost Woods Gamble', 'Fortune Teller (Light)': 'Fortune Teller (Light)', 'Snitch Lady (East)': 'Snitch Lady (East)', @@ -2198,10 +2108,10 @@ default_connections = {'Links House': 'Links House', 'Kakariko Shop': 'Kakariko Shop', 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', 'Lost Woods Hideout Stump': 'Lost Woods Hideout (bottom)', - 'Lost Woods Hideout Exit': 'Light World', + 'Lost Woods Hideout Exit': 'Lost Woods East Area', 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', 'Lumberjack Tree Cave': 'Lumberjack Tree (bottom)', - 'Lumberjack Tree Exit': 'Light World', + 'Lumberjack Tree Exit': 'Lumberjack Area', 'Cave 45': 'Cave 45', 'Graveyard Cave': 'Graveyard Cave', 'Checkerboard Cave': 'Checkerboard Cave', @@ -2217,37 +2127,37 @@ default_connections = {'Links House': 'Links House', 'Potion Shop': 'Potion Shop', 'Two Brothers House (East)': 'Two Brothers House', 'Two Brothers House (West)': 'Two Brothers House', - 'Two Brothers House Exit (East)': 'Light World', + 'Two Brothers House Exit (East)': 'Kakariko Suburb Area', 'Two Brothers House Exit (West)': 'Maze Race Ledge', 'Sanctuary': 'Sanctuary Portal', 'Sanctuary Grave': 'Sewer Drop', - 'Sanctuary Exit': 'Light World', + 'Sanctuary Exit': 'Sanctuary Area', 'Old Man Cave (West)': 'Old Man Cave Ledge', 'Old Man Cave (East)': 'Old Man Cave', - 'Old Man Cave Exit (West)': 'Light World', - 'Old Man Cave Exit (East)': 'Death Mountain', + 'Old Man Cave Exit (West)': 'Mountain Entry Entrance', + 'Old Man Cave Exit (East)': 'West Death Mountain (Bottom)', 'Old Man House (Bottom)': 'Old Man House', - 'Old Man House Exit (Bottom)': 'Death Mountain', + 'Old Man House Exit (Bottom)': 'West Death Mountain (Bottom)', 'Old Man House (Top)': 'Old Man House Back', - 'Old Man House Exit (Top)': 'Death Mountain', + 'Old Man House Exit (Top)': 'West Death Mountain (Bottom)', 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', 'Death Mountain Return Cave (West)': 'Death Mountain Return Cave (left)', - 'Death Mountain Return Cave Exit (West)': 'Death Mountain Return Ledge', - 'Death Mountain Return Cave Exit (East)': 'Death Mountain', + 'Death Mountain Return Cave Exit (West)': 'Mountain Entry Ledge', + 'Death Mountain Return Cave Exit (East)': 'West Death Mountain (Bottom)', 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave': 'Spectacle Rock Cave (Top)', - 'Spectacle Rock Cave Exit': 'Death Mountain', - 'Spectacle Rock Cave Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Exit (Peak)': 'Death Mountain', + 'Spectacle Rock Cave Exit': 'West Death Mountain (Bottom)', + 'Spectacle Rock Cave Exit (Top)': 'West Death Mountain (Bottom)', + 'Spectacle Rock Cave Exit (Peak)': 'West Death Mountain (Bottom)', 'Paradox Cave (Bottom)': 'Paradox Cave Front', 'Paradox Cave (Middle)': 'Paradox Cave', 'Paradox Cave (Top)': 'Paradox Cave', 'Paradox Cave Exit (Bottom)': 'East Death Mountain (Bottom)', 'Paradox Cave Exit (Middle)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Top)': 'East Death Mountain (Top)', + 'Paradox Cave Exit (Top)': 'East Death Mountain (Top East)', 'Hookshot Fairy': 'Hookshot Fairy', 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave (Top)', @@ -2283,7 +2193,7 @@ default_connections = {'Links House': 'Links House', 'Dark World Potion Shop': 'Dark World Potion Shop', 'Archery Game': 'Archery Game', 'Bumper Cave Exit (Top)': 'Bumper Cave Ledge', - 'Bumper Cave Exit (Bottom)': 'West Dark World', + 'Bumper Cave Exit (Bottom)': 'Bumper Cave Entrance', 'Mire Shed': 'Mire Shed', 'Dark Desert Hint': 'Dark Desert Hint', 'Dark Desert Fairy': 'Dark Desert Healer Fairy', @@ -2293,291 +2203,21 @@ default_connections = {'Links House': 'Links House', 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy': 'Dark Death Mountain Healer Fairy', 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', - 'Superbunny Cave Exit (Top)': 'Dark Death Mountain (Top)', - 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', - 'Hookshot Cave Front Exit': 'Dark Death Mountain (Top)', - 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', + 'Superbunny Cave Exit (Top)': 'East Dark Death Mountain (Top)', + 'Superbunny Cave Exit (Bottom)': 'East Dark Death Mountain (Bottom)', + 'Hookshot Cave Front Exit': 'East Dark Death Mountain (Top)', + 'Hookshot Cave Back Exit': 'Dark Death Mountain Floating Island', 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', - 'Mimic Cave': 'Mimic Cave', + 'Mimic Cave': 'Mimic Cave'} - 'Pyramid Hole': 'Pyramid', - 'Pyramid Exit': 'Pyramid Ledge', - 'Pyramid Entrance': 'Bottom of Pyramid'} +open_default_connections = {'Pyramid Hole': 'Pyramid', + 'Pyramid Exit': 'Pyramid Ledge', + 'Pyramid Entrance': 'Bottom of Pyramid'} -inverted_default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', - 'Blinds Hideout': 'Blinds Hideout', - 'Dam': 'Dam', - 'Lumberjack House': 'Lumberjack House', - 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance', - 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance', - 'Hyrule Castle Secret Entrance Exit': 'Light World', - 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', - 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', - 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', - 'Light Hype Fairy': 'Swamp Healer Fairy', - 'Desert Fairy': 'Desert Healer Fairy', - 'Kings Grave': 'Kings Grave', - 'Tavern North': 'Tavern', - 'Chicken House': 'Chicken House', - 'Aginahs Cave': 'Aginahs Cave', - 'Sahasrahlas Hut': 'Sahasrahlas Hut', - 'Cave Shop (Lake Hylia)': 'Cave Shop (Lake Hylia)', - 'Capacity Upgrade': 'Capacity Upgrade', - 'Kakariko Well Drop': 'Kakariko Well (top)', - 'Kakariko Well Cave': 'Kakariko Well (bottom)', - 'Kakariko Well Exit': 'Light World', - 'Blacksmiths Hut': 'Blacksmiths Hut', - 'Bat Cave Drop': 'Bat Cave (right)', - 'Bat Cave Cave': 'Bat Cave (left)', - 'Bat Cave Exit': 'Light World', - 'Sick Kids House': 'Sick Kids House', - 'Elder House (East)': 'Elder House', - 'Elder House (West)': 'Elder House', - 'Elder House Exit (East)': 'Light World', - 'Elder House Exit (West)': 'Light World', - 'North Fairy Cave Drop': 'North Fairy Cave', - 'North Fairy Cave': 'North Fairy Cave', - 'North Fairy Cave Exit': 'Light World', - 'Lost Woods Gamble': 'Lost Woods Gamble', - 'Fortune Teller (Light)': 'Fortune Teller (Light)', - 'Snitch Lady (East)': 'Snitch Lady (East)', - 'Snitch Lady (West)': 'Snitch Lady (West)', - 'Bush Covered House': 'Bush Covered House', - 'Tavern (Front)': 'Tavern (Front)', - 'Light World Bomb Hut': 'Light World Bomb Hut', - 'Kakariko Shop': 'Kakariko Shop', - 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', - 'Lost Woods Hideout Stump': 'Lost Woods Hideout (bottom)', - 'Lost Woods Hideout Exit': 'Light World', - 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', - 'Lumberjack Tree Cave': 'Lumberjack Tree (bottom)', - 'Lumberjack Tree Exit': 'Light World', - 'Cave 45': 'Cave 45', - 'Graveyard Cave': 'Graveyard Cave', - 'Checkerboard Cave': 'Checkerboard Cave', - 'Mini Moldorm Cave': 'Mini Moldorm Cave', - 'Long Fairy Cave': 'Long Fairy Cave', - 'Good Bee Cave': 'Good Bee Cave', - '20 Rupee Cave': '20 Rupee Cave', - '50 Rupee Cave': '50 Rupee Cave', - 'Ice Rod Cave': 'Ice Rod Cave', - 'Bonk Rock Cave': 'Bonk Rock Cave', - 'Library': 'Library', - 'Kakariko Gamble Game': 'Kakariko Gamble Game', - 'Potion Shop': 'Potion Shop', - 'Two Brothers House (East)': 'Two Brothers House', - 'Two Brothers House (West)': 'Two Brothers House', - 'Two Brothers House Exit (East)': 'Light World', - 'Two Brothers House Exit (West)': 'Maze Race Ledge', - 'Sanctuary': 'Sanctuary Portal', - 'Sanctuary Grave': 'Sewer Drop', - 'Sanctuary Exit': 'Light World', - 'Old Man House (Bottom)': 'Old Man House', - 'Old Man House Exit (Bottom)': 'Death Mountain', - 'Old Man House (Top)': 'Old Man House Back', - 'Old Man House Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', - 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', - 'Spectacle Rock Cave': 'Spectacle Rock Cave (Top)', - 'Spectacle Rock Cave Exit': 'Death Mountain', - 'Spectacle Rock Cave Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Exit (Peak)': 'Death Mountain', - 'Paradox Cave (Bottom)': 'Paradox Cave Front', - 'Paradox Cave (Middle)': 'Paradox Cave', - 'Paradox Cave (Top)': 'Paradox Cave', - 'Paradox Cave Exit (Bottom)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Middle)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Top)': 'East Death Mountain (Top)', - 'Hookshot Fairy': 'Hookshot Fairy', - 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave (Bottom)', - 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave (Top)', - 'Fairy Ascension Cave Exit (Bottom)': 'Fairy Ascension Plateau', - 'Fairy Ascension Cave Exit (Top)': 'Fairy Ascension Ledge', - 'Spiral Cave': 'Spiral Cave (Top)', - 'Spiral Cave (Bottom)': 'Spiral Cave (Bottom)', - 'Spiral Cave Exit': 'East Death Mountain (Bottom)', - 'Spiral Cave Exit (Top)': 'Spiral Cave Ledge', - 'Pyramid Fairy': 'Pyramid Fairy', - 'East Dark World Hint': 'East Dark World Hint', - 'Palace of Darkness Hint': 'Palace of Darkness Hint', - 'Dark Lake Hylia Shop': 'Dark Lake Hylia Shop', - 'Dark Lake Hylia Fairy': 'Dark Lake Hylia Healer Fairy', - 'Dark Lake Hylia Ledge Fairy': 'Dark Lake Hylia Ledge Healer Fairy', - 'Dark Lake Hylia Ledge Spike Cave': 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint': 'Dark Lake Hylia Ledge Hint', - 'Hype Cave': 'Hype Cave', - 'Bonk Fairy (Dark)': 'Bonk Fairy (Dark)', - 'Brewery': 'Brewery', - 'C-Shaped House': 'C-Shaped House', - 'Chest Game': 'Chest Game', - 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', - 'Red Shield Shop': 'Red Shield Shop', - 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', - 'Dark World Shop': 'Village of Outcasts Shop', - 'Dark World Lumberjack Shop': 'Dark World Lumberjack Shop', - 'Dark World Potion Shop': 'Dark World Potion Shop', - 'Archery Game': 'Archery Game', - 'Mire Shed': 'Mire Shed', - 'Dark Desert Hint': 'Dark Desert Hint', - 'Dark Desert Fairy': 'Dark Desert Healer Fairy', - 'Spike Cave': 'Spike Cave', - 'Hookshot Cave': 'Hookshot Cave (Front)', - 'Superbunny Cave (Top)': 'Superbunny Cave (Top)', - 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', - 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', - 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', - 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', - 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', - 'Mimic Cave': 'Mimic Cave', - 'Inverted Pyramid Hole': 'Pyramid', - 'Inverted Links House': 'Inverted Links House', - 'Inverted Links House Exit': 'South Dark World', - 'Inverted Big Bomb Shop': 'Inverted Big Bomb Shop', - 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary', - 'Inverted Dark Sanctuary Exit': 'West Dark World', - 'Old Man Cave (West)': 'Bumper Cave (bottom)', - 'Old Man Cave (East)': 'Death Mountain Return Cave (left)', - 'Old Man Cave Exit (West)': 'West Dark World', - 'Old Man Cave Exit (East)': 'Dark Death Mountain', - 'Dark Death Mountain Fairy': 'Old Man Cave', - 'Bumper Cave (Bottom)': 'Old Man Cave Ledge', - 'Bumper Cave (Top)': 'Dark Death Mountain Healer Fairy', - 'Bumper Cave Exit (Top)': 'Death Mountain Return Ledge', - 'Bumper Cave Exit (Bottom)': 'Light World', - 'Death Mountain Return Cave (West)': 'Bumper Cave (top)', - 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', - 'Death Mountain Return Cave Exit (West)': 'Death Mountain', - 'Death Mountain Return Cave Exit (East)': 'Death Mountain', - 'Hookshot Cave Front Exit': 'Dark Death Mountain', - 'Superbunny Cave Exit (Top)': 'Dark Death Mountain', - 'Pyramid Exit': 'Light World', +inverted_default_connections = {'Inverted Pyramid Hole': 'Pyramid', + 'Pyramid Exit': 'Hyrule Castle Ledge', 'Inverted Pyramid Entrance': 'Bottom of Pyramid'} -# non shuffled dungeons -default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), - ('Desert Palace Entrance (West)', 'Desert West Portal'), - ('Desert Palace Entrance (North)', 'Desert Back Portal'), - ('Desert Palace Entrance (East)', 'Desert East Portal'), - ('Desert Palace Exit (South)', 'Desert Palace Stairs'), - ('Desert Palace Exit (West)', 'Desert Ledge'), - ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), - ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - - ('Eastern Palace', 'Eastern Portal'), - ('Eastern Palace Exit', 'Light World'), - ('Tower of Hera', 'Hera Portal'), - ('Tower of Hera Exit', 'Death Mountain (Top)'), - - ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), - ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), - ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Hyrule Castle Courtyard'), - ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), - ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), - ('Agahnims Tower', 'Agahnims Tower Portal'), - ('Agahnims Tower Exit', 'Hyrule Castle Ledge'), - - ('Thieves Town', 'Thieves Town Portal'), - ('Thieves Town Exit', 'West Dark World'), - ('Skull Woods First Section Hole (East)', 'Skull Pinball'), - ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), - ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), - ('Skull Woods First Section Door', 'Skull 1 Portal'), - ('Skull Woods First Section Exit', 'Skull Woods Forest'), - ('Skull Woods Second Section Hole', 'Skull Back Drop'), - ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), - ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), - ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), - ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), - ('Skull Woods Final Section', 'Skull 3 Portal'), - ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), - ('Ice Palace', 'Ice Portal'), - ('Ice Palace Exit', 'Dark Lake Hylia Central Island'), - ('Misery Mire', 'Mire Portal'), - ('Misery Mire Exit', 'Dark Desert'), - ('Palace of Darkness', 'Palace of Darkness Portal'), - ('Palace of Darkness Exit', 'East Dark World'), - ('Swamp Palace', 'Swamp Portal'), # requires additional patch for flooding moat if moved - ('Swamp Palace Exit', 'South Dark World'), - - ('Turtle Rock', 'Turtle Rock Main Portal'), - ('Turtle Rock Exit (Front)', 'Dark Death Mountain (Top)'), - ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), - ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), - ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), - ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), - ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), - - ('Ganons Tower', 'Ganons Tower Portal'), - ('Ganons Tower Exit', 'Dark Death Mountain (Top)') - ] - -inverted_default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), - ('Desert Palace Entrance (West)', 'Desert West Portal'), - ('Desert Palace Entrance (North)', 'Desert Back Portal'), - ('Desert Palace Entrance (East)', 'Desert East Portal'), - ('Desert Palace Exit (South)', 'Desert Palace Stairs'), - ('Desert Palace Exit (West)', 'Desert Ledge'), - ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), - ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - ('Eastern Palace', 'Eastern Portal'), - ('Eastern Palace Exit', 'Light World'), - ('Tower of Hera', 'Hera Portal'), - ('Tower of Hera Exit', 'Death Mountain (Top)'), - ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), - ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), - ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Light World'), - ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), - ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), - ('Thieves Town', 'Thieves Town Portal'), - ('Thieves Town Exit', 'West Dark World'), - ('Skull Woods First Section Hole (East)', 'Skull Pinball'), - ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), - ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), - ('Skull Woods First Section Door', 'Skull 1 Portal'), - ('Skull Woods First Section Exit', 'Skull Woods Forest'), - ('Skull Woods Second Section Hole', 'Skull Back Drop'), - ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), - ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), - ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), - ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), - ('Skull Woods Final Section', 'Skull 3 Portal'), - ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), - ('Ice Palace', 'Ice Portal'), - ('Misery Mire', 'Mire Portal'), - ('Misery Mire Exit', 'Dark Desert'), - ('Palace of Darkness', 'Palace of Darkness Portal'), - ('Palace of Darkness Exit', 'East Dark World'), - # requires additional patch for flooding moat if moved - ('Swamp Palace', 'Swamp Portal'), - ('Swamp Palace Exit', 'South Dark World'), - ('Turtle Rock', 'Turtle Rock Main Portal'), - ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), - ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), - ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), - ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), - ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), - ('Inverted Ganons Tower', 'Ganons Tower Portal'), - ('Inverted Ganons Tower Exit', 'Hyrule Castle Ledge'), - ('Inverted Agahnims Tower', 'Agahnims Tower Portal'), - ('Inverted Agahnims Tower Exit', 'Dark Death Mountain'), - ('Turtle Rock Exit (Front)', 'Dark Death Mountain'), - ('Ice Palace Exit', 'Dark Lake Hylia') - ] - -indirect_connections = { - 'Turtle Rock (Top)': 'Turtle Rock', - 'East Dark World': 'Pyramid Fairy', - 'Big Bomb Shop': 'Pyramid Fairy', - 'Dark Desert': 'Pyramid Fairy', - 'West Dark World': 'Pyramid Fairy', - 'South Dark World': 'Pyramid Fairy', - 'Light World': 'Pyramid Fairy', - 'Old Man Cave': 'Old Man S&Q' -} # format: # Key=Name # addr = (door_index, exitdata) # multiexit @@ -2585,160 +2225,154 @@ indirect_connections = { # exitdata = (room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2) # ToDo somehow merge this with creation of the locations -door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), - 'Inverted Big Bomb Shop': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), - 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000)), - 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000)), - 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000)), - 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), - 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000)), - 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be)), - 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124)), - 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158)), - 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x0418, 0x0679, 0x06b4, 0x06c6, 0x0728, 0x06e6, 0x0733, 0x07, 0xf9, 0x0000, 0x0000)), - 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), - 'Inverted Ganons Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), - 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000)), - 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000)), - 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000)), - 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000)), - 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000)), - 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000)), - 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), - 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000)), - 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000)), - 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000)), - 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000)), - 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000)), - 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000)), - 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000)), - 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000)), - 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000)), - 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000)), - 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000)), - 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa)), - 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000)), - 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000)), - 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000)), - 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000)), - 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000)), - 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000)), - 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)), - 'Inverted Agahnims Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)), - 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None), - 'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None), +door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000), 0x00), + 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000), 0x00), + 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x00), + 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be), 0x00), + 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124), 0x00), + 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158), 0x00), + 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x000e, 0x0600, 0x0676, 0x0604, 0x06e8, 0x066d, 0x06f3, 0x00, 0x0a, 0x0000, 0x811c), 0x00), + 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be), 0x40), + 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000), 0x00), + 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000), 0x00), + 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00), + 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000), 0x20), + 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000), 0x00), + 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000), 0x20), + 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x20), + 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000), 0x00), + 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000), 0x00), + 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000), 0x00), + 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000), 0x00), + 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000), 0x00), + 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000), 0x00), + 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000), 0x00), + 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00), + 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000), 0x00), + 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000), 0x00), + 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa), 0x00), + 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000), 0x00), + 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000), 0x00), + 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000), 0x00), + 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000), 0x00), + 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000), 0x20), + 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000), 0x00), + 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000), 0x20), + 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None), + 'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None), 'Skull Woods First Section Hole (North)': ([0xDB84C], None), - 'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None), - 'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None), - 'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None), - 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000)), - 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000)), - 'Hyrule Castle Secret Entrance Drop': ([0xDB858], None), - 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000)), - 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), - 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000)), - 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x091b, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), - 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000)), - 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000)), - 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000)), - 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None), - 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000)), - 'Bat Cave Drop': ([0xDB859, 0xDB85A], None), - 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000)), - 'North Fairy Cave Drop': ([0xDB857], None), - 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000)), - 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000)), - 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000)), - 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000)), - 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000)), - 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000)), - 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000)), - 'Lost Woods Hideout Drop': ([0xDB853], None), - 'Lumberjack Tree Tree': ([0xDB85B], None), - 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000)), - 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000)), - 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000)), - 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000)), - 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), - '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000)), - '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000)), - 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000)), - 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000)), - 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000)), - 'Sanctuary Grave': ([0xDB85E], None), - 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), - 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000)), - 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000)), - 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000)), - 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000)), - 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000)), - 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000)), - 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), - 'Inverted Dark Sanctuary': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), - 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000)), - 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000)), - 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000)), - 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000)), - 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000)), - 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), - 'Inverted Links House': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), - 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000)), - 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000))} + 'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None), + 'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None), + 'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None), + 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Secret Entrance Drop': ([0xDB858], None), + 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000), 0x02), + 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000), 0x20), + 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x091b, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000), 0x00), + 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000), 0x00), + 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000), 0x00), + 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None), + 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000), 0x00), + 'Bat Cave Drop': ([0xDB859, 0xDB85A], None), + 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000), 0x00), + 'North Fairy Cave Drop': ([0xDB857], None), + 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000), 0x00), + 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000), 0x00), + 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000), 0x00), + 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000), 0x00), + 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000), 0x02), + 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000), 0x00), + 'Lost Woods Hideout Drop': ([0xDB853], None), + 'Lumberjack Tree Tree': ([0xDB85B], None), + 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000), 0x00), + 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000), 0x02), + 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00), + '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000), 0x20), + '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02), + 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000), 0x00), + 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000), 0x00), + 'Sanctuary Grave': ([0xDB85E], None), + 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000), 0x02), + 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02), + 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000), 0x20), + 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000), 0x02), + 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000), 0x20), + 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000), 0x02), + 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000), 0x00), + 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000), 0x00), + 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000), 0x20), + 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000), 0x00), + 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000), 0x00), + 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00), + 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000), 0x00), + 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000), 0x00), + 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000), 0x00), + 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000), 0x00), + 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00)} # format: # Key=Name # value = entrance # # | (entrance #, exit #) exit_ids = {'Links House Exit': (0x01, 0x00), - 'Inverted Links House Exit': (0x01, 0x00), 'Chris Houlihan Room Exit': (None, 0x3D), 'Desert Palace Exit (South)': (0x09, 0x0A), 'Desert Palace Exit (West)': (0x0B, 0x0C), @@ -2750,7 +2384,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Hyrule Castle Exit (West)': (0x03, 0x02), 'Hyrule Castle Exit (East)': (0x05, 0x04), 'Agahnims Tower Exit': (0x24, 0x25), - 'Inverted Agahnims Tower Exit': (0x24, 0x25), 'Thieves Town Exit': (0x34, 0x35), 'Skull Woods First Section Exit': (0x2A, 0x2B), 'Skull Woods Second Section Exit (East)': (0x29, 0x2A), @@ -2798,7 +2431,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Hookshot Cave Front Exit': (0x3A, 0x3B), 'Hookshot Cave Back Exit': (0x3B, 0x3C), 'Ganons Tower Exit': (0x37, 0x38), - 'Inverted Ganons Tower Exit': (0x37, 0x38), 'Pyramid Exit': (0x36, 0x37), 'Waterfall of Wishing': 0x5C, 'Dam': 0x4E, @@ -2850,7 +2482,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'East Dark World Hint': 0x69, 'Palace of Darkness Hint': 0x68, 'Big Bomb Shop': 0x53, - 'Inverted Big Bomb Shop': 0x53, 'Village of Outcasts Shop': 0x60, 'Dark Lake Hylia Shop': 0x60, 'Dark World Lumberjack Shop': 0x60, @@ -2864,7 +2495,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Dark World Hammer Peg Cave': 0x83, 'Red Shield Shop': 0x57, 'Dark Sanctuary Hint': 0x5A, - 'Inverted Dark Sanctuary': 0x5A, 'Fortune Teller (Dark)': 0x66, 'Archery Game': 0x59, 'Mire Shed': 0x5F, @@ -2883,137 +2513,3 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Skull Pinball': 0x78, 'Skull Pot Circle': 0x76, 'Pyramid': 0x7B} - -ow_prize_table = {'Links House': (0x8b1, 0xb2d), 'Inverted Big Bomb Shop': (0x8b1, 0xb2d), - 'Desert Palace Entrance (South)': (0x108, 0xd70), 'Desert Palace Entrance (West)': (0x031, 0xca0), - 'Desert Palace Entrance (North)': (0x0e1, 0xba0), 'Desert Palace Entrance (East)': (0x191, 0xca0), - 'Eastern Palace': (0xf31, 0x620), 'Tower of Hera': (0x8D0, 0x080), - 'Hyrule Castle Entrance (South)': (0x7b0, 0x730), 'Hyrule Castle Entrance (West)': (0x700, 0x640), - 'Hyrule Castle Entrance (East)': (0x8a0, 0x640), 'Inverted Pyramid Entrance': (0x720, 0x700), - 'Agahnims Tower': (0x7e0, 0x640), 'Inverted Ganons Tower': (0x7e0, 0x640), - 'Thieves Town': (0x1d0, 0x780), 'Skull Woods First Section Door': (0x240, 0x280), - 'Skull Woods Second Section Door (East)': (0x1a0, 0x240), - 'Skull Woods Second Section Door (West)': (0x0c0, 0x1c0), 'Skull Woods Final Section': (0x082, 0x0b0), - 'Ice Palace': (0xca0, 0xda0), - 'Misery Mire': (0x100, 0xca0), - 'Palace of Darkness': (0xf40, 0x620), 'Swamp Palace': (0x759, 0xED0), - 'Turtle Rock': (0xf11, 0x103), - 'Dark Death Mountain Ledge (West)': (0xb80, 0x180), - 'Dark Death Mountain Ledge (East)': (0xc80, 0x180), - 'Turtle Rock Isolated Ledge Entrance': (0xc00, 0x240), - 'Hyrule Castle Secret Entrance Stairs': (0x850, 0x700), - 'Kakariko Well Cave': (0x060, 0x680), - 'Bat Cave Cave': (0x540, 0x8f0), - 'Elder House (East)': (0x2b0, 0x6a0), - 'Elder House (West)': (0x230, 0x6a0), - 'North Fairy Cave': (0xa80, 0x440), - 'Lost Woods Hideout Stump': (0x240, 0x280), - 'Lumberjack Tree Cave': (0x4e0, 0x004), - 'Two Brothers House (East)': (0x200, 0x0b60), - 'Two Brothers House (West)': (0x180, 0x0b60), - 'Sanctuary': (0x720, 0x4a0), - 'Old Man Cave (West)': (0x580, 0x2c0), - 'Old Man Cave (East)': (0x620, 0x2c0), - 'Old Man House (Bottom)': (0x720, 0x320), - 'Old Man House (Top)': (0x820, 0x220), - 'Death Mountain Return Cave (East)': (0x600, 0x220), - 'Death Mountain Return Cave (West)': (0x500, 0x1c0), - 'Spectacle Rock Cave Peak': (0x720, 0x0a0), - 'Spectacle Rock Cave': (0x790, 0x1a0), - 'Spectacle Rock Cave (Bottom)': (0x710, 0x0a0), - 'Paradox Cave (Bottom)': (0xd80, 0x180), - 'Paradox Cave (Middle)': (0xd80, 0x380), - 'Paradox Cave (Top)': (0xd80, 0x020), - 'Fairy Ascension Cave (Bottom)': (0xcc8, 0x2a0), - 'Fairy Ascension Cave (Top)': (0xc00, 0x240), - 'Spiral Cave': (0xb80, 0x180), - 'Spiral Cave (Bottom)': (0xb80, 0x2c0), - 'Bumper Cave (Bottom)': (0x580, 0x2c0), - 'Bumper Cave (Top)': (0x500, 0x1c0), - 'Superbunny Cave (Top)': (0xd80, 0x020), - 'Superbunny Cave (Bottom)': (0xd00, 0x180), - 'Hookshot Cave': (0xc80, 0x0c0), - 'Hookshot Cave Back Entrance': (0xcf0, 0x004), - 'Ganons Tower': (0x8D0, 0x080), - 'Inverted Agahnims Tower': (0x8D0, 0x080), - 'Pyramid Entrance': (0x640, 0x7c0), - 'Skull Woods First Section Hole (West)': None, - 'Skull Woods First Section Hole (East)': None, - 'Skull Woods First Section Hole (North)': None, - 'Skull Woods Second Section Hole': None, - 'Pyramid Hole': None, - 'Inverted Pyramid Hole': None, - 'Waterfall of Wishing': (0xe80, 0x280), - 'Dam': (0x759, 0xED0), - 'Blinds Hideout': (0x190, 0x6c0), - 'Hyrule Castle Secret Entrance Drop': None, - 'Bonk Fairy (Light)': (0x740, 0xa80), - 'Lake Hylia Fairy': (0xd40, 0x9f0), - 'Light Hype Fairy': (0x940, 0xc80), - 'Desert Fairy': (0x420, 0xe00), - 'Kings Grave': (0x920, 0x520), - 'Tavern North': (0x270, 0x900), - 'Chicken House': (0x120, 0x880), - 'Aginahs Cave': (0x2e0, 0xd00), - 'Sahasrahlas Hut': (0xcf0, 0x6c0), - 'Cave Shop (Lake Hylia)': (0xbc0, 0xc00), - 'Capacity Upgrade': (0xca0, 0xda0), - 'Kakariko Well Drop': None, - 'Blacksmiths Hut': (0x4a0, 0x880), - 'Bat Cave Drop': None, - 'Sick Kids House': (0x220, 0x880), - 'North Fairy Cave Drop': None, - 'Lost Woods Gamble': (0x240, 0x080), - 'Fortune Teller (Light)': (0x2c0, 0x4c0), - 'Snitch Lady (East)': (0x310, 0x7a0), - 'Snitch Lady (West)': (0x800, 0x7a0), - 'Bush Covered House': (0x2e0, 0x880), - 'Tavern (Front)': (0x270, 0x980), - 'Light World Bomb Hut': (0x070, 0x980), - 'Kakariko Shop': (0x170, 0x980), - 'Lost Woods Hideout Drop': None, - 'Lumberjack Tree Tree': None, - 'Cave 45': (0x440, 0xca0), 'Graveyard Cave': (0x8f0, 0x430), - 'Checkerboard Cave': (0x260, 0xc00), - 'Mini Moldorm Cave': (0xa40, 0xe80), - 'Long Fairy Cave': (0xf60, 0xb00), - 'Good Bee Cave': (0xec0, 0xc00), - '20 Rupee Cave': (0xe80, 0xca0), - '50 Rupee Cave': (0x4d0, 0xed0), - 'Ice Rod Cave': (0xe00, 0xc00), - 'Bonk Rock Cave': (0x5f0, 0x460), - 'Library': (0x270, 0xaa0), - 'Potion Shop': (0xc80, 0x4c0), - 'Sanctuary Grave': None, - 'Hookshot Fairy': (0xd00, 0x180), - 'Pyramid Fairy': (0x740, 0x740), - 'East Dark World Hint': (0xf60, 0xb00), - 'Palace of Darkness Hint': (0xd60, 0x7c0), - 'Dark Lake Hylia Fairy': (0xd40, 0x9f0), - 'Dark Lake Hylia Ledge Fairy': (0xe00, 0xc00), - 'Dark Lake Hylia Ledge Spike Cave': (0xe80, 0xca0), - 'Dark Lake Hylia Ledge Hint': (0xec0, 0xc00), - 'Hype Cave': (0x940, 0xc80), - 'Bonk Fairy (Dark)': (0x740, 0xa80), - 'Brewery': (0x170, 0x980), 'C-Shaped House': (0x310, 0x7a0), 'Chest Game': (0x800, 0x7a0), - 'Dark World Hammer Peg Cave': (0x4c0, 0x940), - 'Red Shield Shop': (0x500, 0x680), - 'Dark Sanctuary Hint': (0x720, 0x4a0), - 'Inverted Dark Sanctuary': (0x720, 0x4a0), - 'Fortune Teller (Dark)': (0x2c0, 0x4c0), - 'Dark World Shop': (0x2e0, 0x880), - 'Dark World Lumberjack Shop': (0x4e0, 0x0d0), - 'Dark World Potion Shop': (0xc80, 0x4c0), - 'Archery Game': (0x2f0, 0xaf0), - 'Mire Shed': (0x060, 0xc90), - 'Dark Desert Hint': (0x2e0, 0xd00), - 'Dark Desert Fairy': (0x1c0, 0xc90), - 'Spike Cave': (0x860, 0x180), - 'Cave Shop (Dark Death Mountain)': (0xd80, 0x180), - 'Dark Death Mountain Fairy': (0x620, 0x2c0), - 'Mimic Cave': (0xc80, 0x180), - 'Big Bomb Shop': (0x8b1, 0xb2d), 'Inverted Links House': (0x8b1, 0xb2d), - 'Dark Lake Hylia Shop': (0xa40, 0xc40), - 'Lumberjack House': (0x4e0, 0x0d0), - 'Lake Hylia Fortune Teller': (0xa40, 0xc40), - 'Kakariko Gamble Game': (0x2f0, 0xaf0)} From 90c68549191dae14e13958691ee0b5ec98b06c9e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 26 Feb 2023 13:44:30 -0600 Subject: [PATCH 145/146] Initial OWR/ER2 merge --- DoorShuffle.py | 4 + Main.py | 2 +- source/overworld/EntranceShuffle2.py | 2037 ++++++++++---------------- 3 files changed, 772 insertions(+), 1271 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index 6e8c3e53..8e65a4cc 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -3273,6 +3273,10 @@ def find_inaccessible_regions(world, player): world.inaccessible_regions[player] = [] start_regions = ['Links House' if not world.is_bombshop_start(player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint'] regs = convert_regions(start_regions, world, player) + if all(all(not e.connected_region for e in r.exits) for r in regs): + # if attempting to find inaccessible regions before any connections made above, assume eventual access to Pyramid S&Q + start_regions = ['Pyramid Area' if not world.is_tile_swapped(0x1b, player) else 'Hyrule Castle Ledge'] + regs = convert_regions(start_regions, world, player) all_regions = [r for r in world.regions if r.player == player and r.type is not RegionType.Dungeon] visited_regions = set() queue = deque(regs) diff --git a/Main.py b/Main.py index 117e75f1..468462b5 100644 --- a/Main.py +++ b/Main.py @@ -231,7 +231,7 @@ def main(args, seed=None, fish=None): logger.info(world.fish.translate("cli","cli","shuffling.world")) for player in range(1, world.players + 1): - link_entrances(world, player) + link_entrances_new(world, player) logger.info(world.fish.translate("cli", "cli", "shuffling.prep")) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 9b4b9464..fe3a2f89 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -2,7 +2,8 @@ import RaceRandom as random import logging import copy -from collections import defaultdict +from collections import defaultdict, OrderedDict +from BaseClasses import RegionType class EntrancePool(object): @@ -26,6 +27,9 @@ class EntrancePool(object): def is_standard(self): return self.world.mode[self.player] == 'standard' + def is_sanc_forced_in_hc(self): + return self.is_standard() or self.world.doorShuffle[self.player] in ['vanilla', 'basic'] or self.world.intensity[self.player] < 3 + class Restrictions(object): def __init__(self): @@ -40,14 +44,15 @@ def link_entrances_new(world, player): avail_pool = EntrancePool(world, player) i_drop_map = {x: y for x, y in drop_map.items() if not x.startswith('Inverted')} i_entrance_map = {x: y for x, y in entrance_map.items() if not x.startswith('Inverted')} - i_single_ent_map = {x: y for x, y in single_entrance_map.items() if not x.startswith('Inverted')} + i_single_ent_map = {x: y for x, y in single_entrance_map.items()} + + from OverworldShuffle import build_sectors + if not world.owsectors[player] and world.shuffle[player] != 'vanilla': + world.owsectors[player] = build_sectors(world, player) avail_pool.entrances = set(i_drop_map.keys()).union(i_entrance_map.keys()).union(i_single_ent_map.keys()) avail_pool.exits = set(i_entrance_map.values()).union(i_drop_map.values()).union(i_single_ent_map.values()) - avail_pool.exits.add('Chris Houlihan Room Exit') avail_pool.inverted = world.mode[player] == 'inverted' - if avail_pool.inverted: - avail_pool.exits.add('Inverted Dark Sanctuary Exit') inverted_substitution(avail_pool, avail_pool.entrances, True, True) inverted_substitution(avail_pool, avail_pool.exits, False, True) avail_pool.original_entrances.update(avail_pool.entrances) @@ -57,28 +62,21 @@ def link_entrances_new(world, player): one_way_map = {} one_way_map.update(drop_map) one_way_map.update(single_entrance_map) - if avail_pool.inverted: - default_map['Old Man Cave (West)'] = 'Bumper Cave Exit (Bottom)' - default_map['Death Mountain Return Cave (West)'] = 'Bumper Cave Exit (Top)' - default_map['Bumper Cave (Bottom)'] = 'Old Man Cave Exit (West)' - default_map['Dark Death Mountain Fairy'] = 'Old Man Cave Exit (East)' - del one_way_map['Dark Death Mountain Fairy'] - default_map['Old Man Cave (East)'] = 'Death Mountain Return Cave Exit (West)' - one_way_map['Bumper Cave (Top)'] = 'Dark Death Mountain Healer Fairy' - del default_map['Bumper Cave (Top)'] - del one_way_map['Big Bomb Shop'] - one_way_map['Inverted Big Bomb Shop'] = 'Inverted Big Bomb Shop' avail_pool.default_map = default_map avail_pool.one_way_map = one_way_map - # setup mandatory connections - if not avail_pool.inverted: - for exit_name, region_name in mandatory_connections: - connect_simple(world, exit_name, region_name, player) - else: - for exit_name, region_name in inverted_mandatory_connections: - connect_simple(world, exit_name, region_name, player) + global LW_Entrances, DW_Entrances + for e in [e for e in avail_pool.entrances if e not in drop_map]: + region = world.get_entrance(e, player).parent_region + if region.type == RegionType.LightWorld: + LW_Entrances.append(e) + else: + DW_Entrances.append(e) + # setup mandatory connections + for exit_name, region_name in mandatory_connections: + connect_simple(world, exit_name, region_name, player) + connect_custom(avail_pool, world, player) if world.shuffle[player] == 'vanilla': @@ -96,6 +94,10 @@ def link_entrances_new(world, player): if special_shuffle == 'drops': holes, targets = find_entrances_and_targets_drops(avail_pool, pool['entrances']) connect_random(holes, targets, avail_pool) + elif special_shuffle == 'normal_drops': + cross_world = mode_cfg['cross_world'] == 'on' if 'cross_world' in mode_cfg else False + keep_together = mode_cfg['keep_drops_together'] == 'on' if 'keep_drops_together' in mode_cfg else True + do_holes_and_linked_drops(set(avail_pool.entrances), set(avail_pool.exits), avail_pool, cross_world, keep_together) elif special_shuffle == 'fixed_shuffle': do_fixed_shuffle(avail_pool, pool['entrances']) elif special_shuffle == 'same_world': @@ -106,9 +108,6 @@ def link_entrances_new(world, player): exits = [x for x in pool['entrances'] if x in avail_pool.exits] cross_world = mode_cfg['cross_world'] == 'on' if 'cross_world' in mode_cfg else False do_old_man_cave_exit(set(avail_pool.entrances), exits, avail_pool, cross_world) - elif special_shuffle == 'inverted_fixed': - if avail_pool.inverted: - connect_two_way(pool['entrance'], pool['exit'], avail_pool) elif special_shuffle == 'limited': do_limited_shuffle(pool, avail_pool) elif special_shuffle == 'limited_lw': @@ -119,6 +118,14 @@ def link_entrances_new(world, player): do_vanilla_connect(pool, avail_pool) elif special_shuffle == 'skull': entrances, exits = find_entrances_and_exits(avail_pool, pool['entrances']) + rem_ent = None + if avail_pool.world.shuffle[avail_pool.player] in ['dungeons-simple', 'simple', 'restricted'] \ + and not avail_pool.world.is_tile_swapped(0x00, avail_pool.player): + rem_ent = random.choice(['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']) + entrances.remove(rem_ent) + exits.remove('Skull Woods First Section Exit') + connect_random(entrances, exits, avail_pool, True) + entrances, exits = [rem_ent], ['Skull Woods First Section Exit'] connect_random(entrances, exits, avail_pool, True) avail_pool.skull_handled = True else: @@ -132,6 +139,12 @@ def link_entrances_new(world, player): # afterward + # connect houlihan + if not world.get_entrance('Chris Houlihan Room Exit', player).connected_region: + lh = 'Big Bomb Shop' if world.is_bombshop_start(player) else 'Links House' + lh = world.get_region(lh, player).entrances[1].name + connect_exit('Chris Houlihan Room Exit', lh, avail_pool) + # check for swamp palace fix if (world.get_entrance('Dam', player).connected_region.name != 'Dam' or world.get_entrance('Swamp Palace', player).connected_region.name != 'Swamp Portal'): @@ -142,20 +155,17 @@ def link_entrances_new(world, player): world.powder_patch_required[player] = True # check for ganon location - pyramid_hole = 'Inverted Pyramid Hole' if avail_pool.inverted else 'Pyramid Hole' + pyramid_hole = 'Inverted Pyramid Hole' if avail_pool.world.is_tile_swapped(0x1b, avail_pool.player) else 'Pyramid Hole' if world.get_entrance(pyramid_hole, player).connected_region.name != 'Pyramid': world.ganon_at_pyramid[player] = False # check for Ganon's Tower location - gt = 'Inverted Ganons Tower' if avail_pool.inverted else 'Ganons Tower' + gt = 'Agahnims Tower' if avail_pool.world.is_atgt_swapped(avail_pool.player) else 'Ganons Tower' if world.get_entrance(gt, player).connected_region.name != 'Ganons Tower Portal': world.ganonstower_vanilla[player] = False def do_vanilla_connections(avail_pool): - if 'Chris Houlihan Room Exit' in avail_pool.exits: - lh = 'Inverted Links House' if avail_pool.inverted else 'Links House' - connect_exit('Chris Houlihan Room Exit', lh, avail_pool) for ent in list(avail_pool.entrances): if ent in avail_pool.default_map and avail_pool.default_map[ent] in avail_pool.exits: connect_vanilla_two_way(ent, avail_pool.default_map[ent], avail_pool) @@ -174,14 +184,15 @@ def do_main_shuffle(entrances, exits, avail, mode_def): avail.decoupled_entrances.extend(entrances) avail.decoupled_exits.extend(exits) - if not avail.world.shuffle_ganon: - if avail.inverted and 'Inverted Ganons Tower' in entrances: - connect_two_way('Inverted Ganons Tower', 'Inverted Ganons Tower Exit', avail) - entrances.remove('Inverted Ganons Tower') - exits.remove('Inverted Ganons Tower Exit') - if not avail.coupled: - avail.decoupled_entrances.remove('Inverted Ganons Tower') - avail.decoupled_exits.remove('Inverted Ganons Tower Exit') + if not avail.world.shuffle_ganon[avail.player]: + if avail.world.is_atgt_swapped(avail.player): + if 'Agahnims Tower' in entrances: + connect_two_way('Agahnims Tower', 'Ganons Tower Exit', avail) + entrances.remove('Agahnims Tower') + exits.remove('Ganons Tower Exit') + if not avail.coupled: + avail.decoupled_entrances.remove('Agahnims Tower') + avail.decoupled_exits.remove('Ganons Tower Exit') elif 'Ganons Tower' in entrances: connect_two_way('Ganons Tower', 'Ganons Tower Exit', avail) entrances.remove('Ganons Tower') @@ -198,40 +209,37 @@ def do_main_shuffle(entrances, exits, avail, mode_def): if not avail.coupled: avail.decoupled_entrances.remove('Tavern North') - # links house / houlihan - do_links_house(entrances, exits, avail, cross_world) - # inverted sanc - if avail.inverted and 'Inverted Dark Sanctuary Exit' in exits: - choices = [e for e in Inverted_Dark_Sanctuary_Doors if e in entrances] - choice = random.choice(choices) - entrances.remove(choice) - exits.remove('Inverted Dark Sanctuary Exit') - connect_entrance(choice, 'Inverted Dark Sanctuary', avail) - ext = avail.world.get_entrance('Inverted Dark Sanctuary Exit', avail.player) - ext.connect(avail.world.get_entrance(choice, avail.player).parent_region) - if not avail.coupled: - avail.decoupled_entrances.remove(choice) + do_dark_sanc(entrances, exits, avail) + + # links house + do_links_house(entrances, exits, avail, cross_world) # mandatory exits rem_entrances, rem_exits = set(), set() if not cross_world: mand_exits = figure_out_must_exits_same_world(entrances, exits, avail) - must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves, hyrule_forced = mand_exits - if hyrule_forced: - do_mandatory_connections(avail, lw_entrances, hyrule_forced, must_exit_lw) + must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves = mand_exits + if not avail.inverted: + do_mandatory_connections(avail, lw_entrances, multi_exit_caves, must_exit_lw) + else: + do_mandatory_connections(avail, dw_entrances, multi_exit_caves, must_exit_dw) + + new_mec = [] + for cave_option in multi_exit_caves: + # remove old man house as connector - not valid for dw must_exit if it is a spawn point + # remove HC exits as connector if sanc is guaranteed in HC + if any('Old Man House' in cave for cave in cave_option) \ + or (avail.is_sanc_forced_in_hc() and any('Hyrule Castle' in cave for cave in cave_option)): + rem_exits.update([item for item in cave_option]) + else: + new_mec.append(cave_option) + multi_exit_caves = new_mec + + if not avail.inverted: + do_mandatory_connections(avail, dw_entrances, multi_exit_caves, must_exit_dw) else: do_mandatory_connections(avail, lw_entrances, multi_exit_caves, must_exit_lw) - # remove old man house as connector - not valid for dw must_exit if it is a spawn point - if not avail.inverted: - new_mec = [] - for cave_option in multi_exit_caves: - if any('Old Man House' in cave for cave in cave_option): - rem_exits.update([item for item in cave_option]) - else: - new_mec.append(cave_option) - multi_exit_caves = new_mec - do_mandatory_connections(avail, dw_entrances, multi_exit_caves, must_exit_dw) rem_entrances.update(lw_entrances) rem_entrances.update(dw_entrances) else: @@ -241,33 +249,28 @@ def do_main_shuffle(entrances, exits, avail, mode_def): do_mandatory_connections(avail, entrance_list, multi_exit_caves, must_exit) rem_entrances.update(entrance_list) - rem_exits.update([x for item in multi_exit_caves for x in item]) + rem_exits.update([x for item in multi_exit_caves for x in item if x in avail.exits]) rem_exits.update(exits) # old man cave do_old_man_cave_exit(rem_entrances, rem_exits, avail, cross_world) # blacksmith - if 'Blacksmiths Hut' in rem_exits: - blacksmith_options = [x for x in Blacksmith_Options if x in rem_entrances] - blacksmith_choice = random.choice(blacksmith_options) - connect_entrance(blacksmith_choice, 'Blacksmiths Hut', avail) - rem_entrances.remove(blacksmith_choice) - if not avail.coupled: - avail.decoupled_exits.remove('Blacksmiths Hut') - rem_exits.remove('Blacksmiths Hut') + do_blacksmith(rem_entrances, rem_exits, avail) # bomb shop - bomb_shop = 'Inverted Big Bomb Shop' if avail.inverted else 'Big Bomb Shop' - if bomb_shop in rem_exits: - bomb_shop_options = Inverted_Bomb_Shop_Options if avail.inverted else Bomb_Shop_Options - bomb_shop_options = [x for x in bomb_shop_options if x in rem_entrances] - bomb_shop_choice = random.choice(bomb_shop_options) - connect_entrance(bomb_shop_choice, bomb_shop, avail) - rem_entrances.remove(bomb_shop_choice) - if not avail.coupled: - avail.decoupled_exits.remove(bomb_shop) - rem_exits.remove(bomb_shop) + if not avail.world.is_bombshop_start(avail.player): + bomb_shop = 'Big Bomb Shop' + if bomb_shop in rem_exits: + bomb_shop_options = [x for x in rem_entrances] + if avail.world.is_tile_swapped(0x03, avail.player): + bomb_shop_options = [x for x in bomb_shop_options if x not in ['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']] + bomb_shop_choice = random.choice(bomb_shop_options) + connect_entrance(bomb_shop_choice, bomb_shop, avail) + rem_entrances.remove(bomb_shop_choice) + if not avail.coupled: + avail.decoupled_exits.remove(bomb_shop) + rem_exits.remove(bomb_shop) def bonk_fairy_exception(x): # (Bonk Fairy not eligible in standard) return not avail.is_standard() or x != 'Bonk Fairy (Light)' @@ -286,18 +289,18 @@ def do_main_shuffle(entrances, exits, avail, mode_def): rem_exits.remove('Old Man Cave Exit (West)') # OM House in lw/dw if cross_world off om_house = ['Old Man House Exit (Bottom)', 'Old Man House Exit (Top)'] - if not avail.inverted: # we don't really care where this ends up in inverted? - for ext in om_house: - if ext in rem_exits: - om_house_options = [x for x in rem_entrances if x in LW_Entrances and bonk_fairy_exception(x)] - om_house_choice = random.choice(om_house_options) - if not avail.coupled: - connect_exit(ext, om_house_choice, avail) - avail.decoupled_entrances.remove(om_house_choice) - else: - connect_two_way(om_house_choice, ext, avail) - rem_entrances.remove(om_house_choice) - rem_exits.remove(ext) + for ext in om_house: + if ext in rem_exits: + world_limiter = DW_Entrances if avail.inverted else LW_Entrances + om_house_options = [x for x in rem_entrances if x in world_limiter and bonk_fairy_exception(x)] + om_house_choice = random.choice(om_house_options) + if not avail.coupled: + connect_exit(ext, om_house_choice, avail) + avail.decoupled_entrances.remove(om_house_choice) + else: + connect_two_way(om_house_choice, ext, avail) + rem_entrances.remove(om_house_choice) + rem_exits.remove(ext) # the rest of the caves multi_exit_caves = figure_out_true_exits(rem_exits, avail) @@ -336,11 +339,21 @@ def do_main_shuffle(entrances, exits, avail, mode_def): def do_old_man_cave_exit(entrances, exits, avail, cross_world): if 'Old Man Cave Exit (East)' in exits: - om_cave_options = Inverted_Old_Man_Entrances if avail.inverted else Old_Man_Entrances - if avail.inverted and cross_world: - om_cave_options = Inverted_Old_Man_Entrances + Old_Man_Entrances - om_cave_options = [x for x in om_cave_options if x in entrances] - om_cave_choice = random.choice(om_cave_options) + from EntranceShuffle import build_accessible_region_list + if not avail.world.is_tile_swapped(0x03, avail.player): + region_name = 'West Death Mountain (Top)' + else: + region_name = 'West Dark Death Mountain (Top)' + om_cave_options = list(get_accessible_entrances(region_name, avail, [], cross_world, True, True, True)) + om_cave_options = [e for e in om_cave_options if e in entrances and e != 'Old Man House (Bottom)'] + assert len(om_cave_options), 'No available entrances left to place Old Man Cave' + random.shuffle(om_cave_options) + om_cave_choice = None + while not om_cave_choice: + om_cave_choice = om_cave_options.pop() + choice_region = avail.world.get_entrance(om_cave_choice, avail.player).parent_region.name + if 'West Death Mountain (Bottom)' not in build_accessible_region_list(avail.world, choice_region, avail.player, True, True): + om_cave_choice = None if not avail.coupled: connect_exit('Old Man Cave Exit (East)', om_cave_choice, avail) avail.decoupled_entrances.remove(om_cave_choice) @@ -350,13 +363,42 @@ def do_old_man_cave_exit(entrances, exits, avail, cross_world): exits.remove('Old Man Cave Exit (East)') +def do_blacksmith(entrances, exits, avail): + if 'Blacksmiths Hut' in exits: + assumed_inventory = list() + if avail.world.logic[avail.player] in ['noglitches', 'minorglitches'] and (avail.world.is_tile_swapped(0x29, avail.player) == avail.inverted): + assumed_inventory.append('Titans Mitts') + + if not avail.world.is_bombshop_start(avail.player): + links_region = avail.world.get_entrance('Links House Exit', avail.player).connected_region.name + else: + links_region = avail.world.get_entrance('Big Bomb Shop Exit', avail.player).connected_region.name + blacksmith_options = list(get_accessible_entrances(links_region, avail, assumed_inventory, False, True, True)) + + if avail.inverted: + dark_sanc = avail.world.get_entrance('Dark Sanctuary Hint Exit', avail.player).connected_region.name + blacksmith_options = list(OrderedDict.fromkeys(blacksmith_options + list(get_accessible_entrances(dark_sanc, avail, assumed_inventory, False, True, True)))) + elif avail.is_sanc_forced_in_hc(): + sanc_region = avail.world.get_entrance('Sanctuary Exit',avail. player).connected_region + if sanc_region: + blacksmith_options = list(OrderedDict.fromkeys(blacksmith_options + list(get_accessible_entrances(sanc_region.name, avail, assumed_inventory, False, True, True)))) + else: + logging.getLogger('').warning('Blacksmith is unable to use Sanctuary S&Q as initial accessibility because Sanctuary Exit has not been placed yet') + blacksmith_options = [x for x in blacksmith_options if x in entrances] + blacksmith_choice = random.choice(blacksmith_options) + connect_entrance(blacksmith_choice, 'Blacksmiths Hut', avail) + entrances.remove(blacksmith_choice) + if not avail.coupled: + avail.decoupled_exits.remove('Blacksmiths Hut') + exits.remove('Blacksmiths Hut') + + def do_standard_connections(avail): connect_two_way('Hyrule Castle Entrance (South)', 'Hyrule Castle Exit (South)', avail) # cannot move uncle cave connect_two_way('Hyrule Castle Secret Entrance Stairs', 'Hyrule Castle Secret Entrance Exit', avail) connect_entrance('Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', avail) connect_two_way('Links House', 'Links House Exit', avail) - connect_exit('Chris Houlihan Room Exit', 'Links House', avail) def remove_from_list(t_list, removals): @@ -368,7 +410,7 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe holes_to_shuffle = [x for x in entrances if x in drop_map] if not avail.world.shuffle_ganon: - if avail.inverted and 'Inverted Pyramid Hole' in holes_to_shuffle: + if avail.world.is_tile_swapped(0x1b, avail.player) and 'Inverted Pyramid Hole' in holes_to_shuffle: connect_entrance('Inverted Pyramid Hole', 'Pyramid', avail) connect_two_way('Pyramid Entrance', 'Pyramid Exit', avail) holes_to_shuffle.remove('Inverted Pyramid Hole') @@ -400,7 +442,7 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe hole_targets.append((target_exit, target_drop)) random.shuffle(hole_entrances) - if not cross_world and 'Sanctuary Grave' in holes_to_shuffle: + if not cross_world and avail.is_sanc_forced_in_hc() and 'Sanctuary Grave' in holes_to_shuffle: lw_entrance = next(entrance for entrance in hole_entrances if entrance[0] in LW_Entrances) hole_entrances.remove(lw_entrance) sanc_interior = next(target for target in hole_targets if target[0] == 'Sanctuary Exit') @@ -419,36 +461,70 @@ def do_holes_and_linked_drops(entrances, exits, avail, cross_world, keep_togethe remove_from_list(exits, [ext, target]) +def do_dark_sanc(entrances, exits, avail): + if avail.inverted: + ext = avail.world.get_entrance('Dark Sanctuary Hint Exit', avail.player) + if 'Dark Sanctuary Hint' in exits: + forbidden = list(Isolated_LH_Doors) + if not avail.world.is_tile_swapped(0x05, avail.player): + forbidden.append('Mimic Cave') + if avail.world.owShuffle[avail.player] == 'vanilla': + choices = [e for e in avail.world.districts[avail.player]['Northwest Dark World'].entrances if e not in forbidden and e in entrances] + else: + choices = [e for e in get_starting_entrances(avail) if e not in forbidden and e in entrances] + choice = random.choice(choices) + entrances.remove(choice) + exits.remove('Dark Sanctuary Hint') + connect_entrance(choice, 'Dark Sanctuary Hint', avail) + ext.connect(avail.world.get_entrance(choice, avail.player).parent_region) + if not avail.coupled: + avail.decoupled_entrances.remove(choice) + elif not ext.connected_region: + # default to output to vanilla area, assume vanilla connection + ext.connect(avail.world.get_region('Dark Chapel Area', avail.player)) + + def do_links_house(entrances, exits, avail, cross_world): - lh_exit = 'Inverted Links House Exit' if avail.inverted else 'Links House Exit' + lh_exit = 'Big Bomb Shop' if avail.world.is_bombshop_start(avail.player) else 'Links House Exit' if lh_exit in exits: if not avail.world.shufflelinks[avail.player]: - links_house = 'Inverted Links House' if avail.inverted else 'Links House' + links_house = 'Big Bomb Shop' if avail.world.is_bombshop_start(avail.player) else 'Links House' else: - forbidden = list(Isolated_LH_Doors_Inv + Inverted_Dark_Sanctuary_Doors - if avail.inverted else Isolated_LH_Doors_Open) - # simple shuffle - - if avail.world.shuffle[avail.player] == 'simple': - avail.links_on_mountain = True # taken care of by the logic below - if avail.inverted: # in inverted, links house cannot be on the mountain - forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy', 'Hookshot Fairy']) - else: - # links house cannot be on dm if there's no way off the mountain - ent = avail.world.get_entrance('Death Mountain Return Cave (West)', avail.player) - if ent.connected_region.name in Simple_DM_Non_Connectors: - forbidden.append('Hookshot Fairy') - # other cases it is fine - # can't have links house on eddm in restricted because Inverted Aga Tower isn't available - # todo: inverted full may have the same problem if both links house and a mandatory connector is chosen - # from the 3 inverted options - if avail.world.shuffle[avail.player] in ['restricted'] and avail.inverted: - avail.links_on_mountain = True - forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy']) - # lobby shuffle means you ought to keep links house in the same world sanc_spawn_can_be_dark = (not avail.inverted and avail.world.doorShuffle[avail.player] == 'crossed' - and avail.world.intensity[avail.player] >= 3) + and avail.world.intensity[avail.player] >= 3) entrance_pool = entrances if avail.coupled else avail.decoupled_entrances + + forbidden = list(Isolated_LH_Doors) + if not avail.world.is_tile_swapped(0x05, avail.player): + forbidden.append('Mimic Cave') + if avail.world.is_bombshop_start(avail.player) and (avail.inverted == avail.world.is_tile_swapped(0x03, avail.player)): + forbidden.extend(['Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)']) + if avail.inverted: + dark_sanc_region = avail.world.get_entrance('Dark Sanctuary Hint Exit', avail.player).connected_region.name + forbidden.extend(get_nearby_entrances(avail, dark_sanc_region)) + + if avail.world.owShuffle[avail.player] == 'vanilla': + # simple shuffle - + if avail.world.shuffle[avail.player] == 'simple': + avail.links_on_mountain = True # taken care of by the logic below + if avail.world.is_tile_swapped(0x03, avail.player): # in inverted, links house cannot be on the mountain + forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy', 'Hookshot Fairy']) + else: + # links house cannot be on dm if there's no way off the mountain + ent = avail.world.get_entrance('Death Mountain Return Cave (West)', avail.player) + if ent.connected_region.name in Simple_DM_Non_Connectors: + forbidden.append('Hookshot Fairy') + # other cases it is fine + # can't have links house on eddm in restricted because Inverted Aga Tower isn't available + # todo: inverted full may have the same problem if both links house and a mandatory connector is chosen + # from the 3 inverted options + if avail.world.shuffle[avail.player] in ['restricted'] and avail.world.is_tile_swapped(0x03, avail.player): + avail.links_on_mountain = True + forbidden.extend(['Spike Cave', 'Dark Death Mountain Fairy']) + else: + avail.links_on_mountain = True + if cross_world and not sanc_spawn_can_be_dark: possible = [e for e in entrance_pool if e not in forbidden] else: @@ -456,18 +532,21 @@ def do_links_house(entrances, exits, avail, cross_world): possible = [e for e in entrance_pool if e in world_list and e not in forbidden] possible.sort() links_house = random.choice(possible) - connect_two_way(links_house, lh_exit, avail) + if not avail.world.is_bombshop_start(avail.player): + connect_two_way(links_house, lh_exit, avail) + else: + connect_entrance(links_house, lh_exit, avail) + ext = avail.world.get_entrance('Big Bomb Shop Exit', avail.player) + ext.connect(avail.world.get_entrance(links_house, avail.player).parent_region) entrances.remove(links_house) - connect_exit('Chris Houlihan Room Exit', links_house, avail) # should match link's house exits.remove(lh_exit) - exits.remove('Chris Houlihan Room Exit') if not avail.coupled: avail.decoupled_entrances.remove(links_house) - avail.decoupled_exits.remove('Links House Exit') - avail.decoupled_exits.remove('Chris Houlihan Room Exit') + avail.decoupled_exits.remove(lh_exit) + # links on dm dm_spots = LH_DM_Connector_List.union(LH_DM_Exit_Forbidden) - if links_house in dm_spots: + if links_house in dm_spots and avail.world.owShuffle[avail.player] == 'vanilla': if avail.links_on_mountain: return # connector is fine multi_exit_caves = figure_out_connectors(exits) @@ -500,6 +579,118 @@ def do_links_house(entrances, exits, avail, cross_world): exits.update([x for item in multi_exit_caves for x in item]) +def get_starting_entrances(avail, force_starting_world=True): + from OWEdges import OWTileRegions + sector = None + invalid_sectors = list() + entrances = list() + while not len(entrances): + # find largest walkable sector + while (sector is None): + sector = max(avail.world.owsectors[avail.player], key=lambda x: len(x) - (0 if x not in invalid_sectors else 1000)) + if not ((avail.world.owCrossed[avail.player] == 'polar' and avail.world.owMixed[avail.player]) or avail.world.owCrossed[avail.player] not in ['none', 'polar']) \ + and avail.world.get_region(next(iter(next(iter(sector)))), avail.player).type != (RegionType.DarkWorld if avail.inverted else RegionType.LightWorld): + invalid_sectors.append(sector) + sector = None + regions = max(sector, key=lambda x: len(x)) + + # get entrances from list of regions + entrances = list() + for region_name in regions: + if avail.world.shuffle[avail.player] == 'simple' and region_name in OWTileRegions.keys() and OWTileRegions[region_name] in [0x03, 0x05, 0x07]: + continue + region = avail.world.get_region(region_name, avail.player) + if not force_starting_world or region.type == (RegionType.DarkWorld if avail.inverted else RegionType.LightWorld): + for exit in region.exits: + if not exit.connected_region and exit.spot_type == 'Entrance': + entrances.append(exit.name) + + invalid_sectors.append(sector) + sector = None + + return entrances + + +def get_nearby_entrances(avail, start_region): + from OverworldShuffle import one_way_ledges + from OWEdges import OWTileRegions + + # get walkable sector in which initial entrance was placed + regions = next(s for s in avail.world.owsectors[avail.player] if any(start_region in w for w in s)) + regions = next(w for w in regions if start_region in w) + + # eliminate regions surrounding the initial entrance until less than half of the candidate regions remain + explored_regions = list({start_region}) + was_progress = True + while was_progress and len(explored_regions) < len(regions) / 2: + was_progress = False + new_regions = list() + for region_name in explored_regions: + if region_name in one_way_ledges: + for ledge in one_way_ledges[region_name]: + if ledge not in explored_regions + new_regions: + new_regions.append(ledge) + was_progress = True + region = avail.world.get_region(region_name, avail.player) + for exit in region.exits: + if exit.connected_region and region.type == exit.connected_region.type and exit.connected_region.name in regions and exit.connected_region.name not in explored_regions + new_regions: + new_regions.append(exit.connected_region.name) + was_progress = True + explored_regions.extend(new_regions) + + # get entrances from remaining regions + candidates = list() + for region_name in [r for r in regions if r in explored_regions]: + if region_name in OWTileRegions.keys() and OWTileRegions[region_name] in [0x03, 0x05, 0x07]: + continue + region = avail.world.get_region(region_name, avail.player) + for exit in region.exits: + if not exit.connected_region and exit.spot_type == 'Entrance': + candidates.append(exit.name) + + return candidates + + +def get_accessible_entrances(start_region, avail, assumed_inventory=[], cross_world=False, region_rules=True, exit_rules=True, include_one_ways=False): + from Main import copy_world_premature + from BaseClasses import CollectionState + from Items import ItemFactory + from EntranceShuffle import build_accessible_region_list + from OverworldShuffle import one_way_ledges + + for p in range(1, avail.world.players + 1): + avail.world.key_logic[p] = {} + base_world = copy_world_premature(avail.world, avail.player) + base_world.override_bomb_check = True + + connect_simple(base_world, 'Links House S&Q', start_region, avail.player) + blank_state = CollectionState(base_world) + if base_world.mode[avail.player] == 'standard': + blank_state.collect(ItemFactory('Zelda Delivered', avail.player), True) + for item in assumed_inventory: + blank_state.collect(ItemFactory(item, avail.player), True) + + explored_regions = list(build_accessible_region_list(base_world, start_region, avail.player, False, cross_world, region_rules, False)) + + if include_one_ways: + new_regions = list() + for region_name in explored_regions: + if region_name in one_way_ledges: + for ledge in one_way_ledges[region_name]: + if ledge not in explored_regions + new_regions: + new_regions.append(ledge) + explored_regions.extend(new_regions) + + found_entrances = list() + for region_name in explored_regions: + region = base_world.get_region(region_name, avail.player) + for exit in region.exits: + if exit.spot_type == 'Entrance' and (not exit_rules or exit.access_rule(blank_state)): + found_entrances.append(exit.name) + + return found_entrances + + def figure_out_connectors(exits): multi_exit_caves = [] for item in Connector_List: @@ -522,45 +713,180 @@ def figure_out_true_exits(exits, avail): return multi_exit_caves -# todo: figure out hyrule forced better +def must_exits_helper(avail): + def find_inacessible_ow_regions(): + from DoorShuffle import find_inaccessible_regions + nonlocal inaccessible_regions + find_inaccessible_regions(avail.world, avail.player) + inaccessible_regions = list(avail.world.inaccessible_regions[avail.player]) + + # find OW regions that don't have a multi-entrance dungeon exit connected + glitch_regions = ['Central Cliffs', 'Eastern Cliff', 'Desert Northeast Cliffs', 'Hyrule Castle Water', + 'Dark Central Cliffs', 'Darkness Cliff', 'Mire Northeast Cliffs', 'Pyramid Water'] + multi_dungeon_exits = { + 'Hyrule Castle South Portal', 'Hyrule Castle West Portal', 'Hyrule Castle East Portal', 'Sanctuary Portal', + 'Desert South Portal', 'Desert West Portal', + 'Skull 2 East Portal', 'Skull 2 West Portal', + 'Turtle Rock Main Portal', 'Turtle Rock Lazy Eyes Portal', 'Turtle Rock Eye Bridge Portal' + } + for region_name in avail.world.inaccessible_regions[avail.player]: + if (avail.world.logic[avail.player] in ['noglitches', 'minorglitches'] and region_name in glitch_regions) \ + or (region_name == 'Pyramid Exit Ledge' and (avail.world.shuffle[avail.player] != 'insanity' or avail.world.is_tile_swapped(0x1b, avail.player))) \ + or (region_name == 'Spiral Mimic Ledge Extend' and not avail.world.is_tile_swapped(0x05, avail.player)): + # removing irrelevant and resolved regions + inaccessible_regions.remove(region_name) + continue + region = avail.world.get_region(region_name, avail.player) + if region.type not in [RegionType.LightWorld, RegionType.DarkWorld]: + inaccessible_regions.remove(region_name) + continue + if avail.world.shuffle[avail.player] != 'insanity': + for exit in region.exits: + # because dungeon regions haven't been connected yet, the inaccessibility check won't be able to know it's reachable yet + if exit.connected_region and exit.connected_region.name in multi_dungeon_exits: + resolved_regions.append(region_name) + break + + inaccessible_regions = list() + resolved_regions = list() + find_inacessible_ow_regions() + + # keep track of neighboring regions for later consolidation + must_exit_links = OrderedDict() + for region_name in inaccessible_regions: + region = avail.world.get_region(region_name, avail.player) + must_exit_links[region_name] = [x.connected_region.name for x in region.exits if x.connected_region and x.connected_region.name in inaccessible_regions] + + # group neighboring regions together, separated by one-ways + def consolidate_group(region): + processed_regions.append(region) + must_exit_links_copy.pop(region) + region_group.append(region) + for dest_region in must_exit_links[region]: + if region in must_exit_links[dest_region]: + if dest_region not in processed_regions: + consolidate_group(dest_region) + else: + one_ways.append(tuple((region, dest_region))) + + processed_regions = list() + must_exit_candidates = list() + one_ways = list() + must_exit_links_copy = must_exit_links.copy() + while len(must_exit_links_copy): + region_group = list() + region_name = next(iter(must_exit_links_copy)) + consolidate_group(region_name) + must_exit_candidates.append(region_group) + + # get available entrances in each group + for regions in must_exit_candidates: + entrances = list() + for region_name in regions: + region = avail.world.get_region(region_name, avail.player) + entrances = entrances + [x.name for x in region.exits if x.spot_type == 'Entrance' and not x.connected_region] + must_exit_candidates[must_exit_candidates.index(regions)] = tuple((regions, entrances)) + + # necessary for circular relations between region groups, it will pick the last group + # and fill one of those entrances, and we don't want it to bias the same group + random.shuffle(must_exit_candidates) + + # remove must exit candidates that would be made accessible thru other region groups + def find_group(region): + for group in must_exit_candidates: + regions, _ = group + if region in regions: + return group + raise Exception(f'Could not find region group for {region}') + + def cascade_ignore(group): + nonlocal ignored_regions, sector_entrances + regions, entrances = group + ignored_regions = ignored_regions + regions + sector_entrances.update(entrances) + for from_region, to_region in one_ways: + if from_region in regions: + if to_region not in ignored_regions: + sector_entrances.update(cascade_ignore(find_group(to_region))) + return sector_entrances + + def build_invalid(entrances): + # building lists of entrances that cannot fulfill must-exit scenarios + # this ensures must-exits connect to an area outside of this group + for e in entrances: + if not Must_Exit_Invalid_Connections[e]: + Must_Exit_Invalid_Connections[e] = set() + Must_Exit_Invalid_Connections[e].update(set(entrances)) + + def process_group(group): + nonlocal processed_regions, ignored_regions, sector_entrances + regions, entrances = group + must_exit_candidates_copy.remove(group) + processed_regions = processed_regions + regions + if regions[0] not in ignored_regions: + for from_region, to_region in one_ways: + if to_region in regions and from_region not in ignored_regions + processed_regions: + process_group(find_group(from_region)) # process the parent region group + if regions[0] not in ignored_regions: + # this is the top level region + sector_entrances = set() + if any(r in resolved_regions for r in regions): + cascade_ignore(group) + build_invalid(sector_entrances) + else: + if len(entrances): + # we will fulfill must exit here and cascade access to children + if len(entrances) == 1: + entrances = entrances[0] + else: + entrances = tuple(entrances) + must_exit_regions.append(tuple((regions, entrances))) + cascade_ignore(group) + build_invalid(sector_entrances) + else: + ignored_regions = ignored_regions + regions + + global Must_Exit_Invalid_Connections + Must_Exit_Invalid_Connections = defaultdict(set) + processed_regions = list() + ignored_regions = list() + sector_entrances = set() + must_exit_regions = list() + must_exit_candidates_copy = must_exit_candidates.copy() + while len(must_exit_candidates_copy): + region_group = next(iter(must_exit_candidates_copy)) + process_group(region_group) + + # build final must exit lists + must_exit_lw = list() + must_exit_dw = list() + for regions, entrances in must_exit_regions: + region = avail.world.get_region(regions[0], avail.player) + if region.type == RegionType.LightWorld: + must_exit_lw.append(entrances) + else: + must_exit_dw.append(entrances) + return must_exit_lw, must_exit_dw + + def figure_out_must_exits_same_world(entrances, exits, avail): lw_entrances, dw_entrances = [], [] - hyrule_forced = None - check_for_hc = (avail.is_standard() or avail.world.doorShuffle[avail.player] != 'vanilla') for x in entrances: lw_entrances.append(x) if x in LW_Entrances else dw_entrances.append(x) multi_exit_caves = figure_out_connectors(exits) - if check_for_hc: - for option in multi_exit_caves: - if any(x in option for x in ['Hyrule Castle Exit (South)', 'Hyrule Castle Exit (East)', - 'Hyrule Castle Exit (West)']): - hyrule_forced = [option] - if hyrule_forced: - remove_from_list(multi_exit_caves, hyrule_forced) - must_exit_lw, must_exit_dw = must_exits_helper(avail, lw_entrances, dw_entrances) - - return must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves, hyrule_forced - - -def must_exits_helper(avail, lw_entrances, dw_entrances): - must_exit_lw = (Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit).copy() - must_exit_dw = (Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit).copy() - if not avail.inverted and not avail.skull_handled: - must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) + must_exit_lw, must_exit_dw = must_exits_helper(avail) must_exit_lw = must_exit_filter(avail, must_exit_lw, lw_entrances) must_exit_dw = must_exit_filter(avail, must_exit_dw, dw_entrances) - return must_exit_lw, must_exit_dw + + return must_exit_lw, must_exit_dw, lw_entrances, dw_entrances, multi_exit_caves def figure_out_must_exits_cross_world(entrances, exits, avail): multi_exit_caves = figure_out_connectors(exits) - must_exit_lw = (Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit).copy() - must_exit_dw = (Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit).copy() - if not avail.inverted and not avail.skull_handled: - must_exit_dw.append(('Skull Woods Second Section Door (West)', 'Skull Woods Final Section')) + must_exit_lw, must_exit_dw = must_exits_helper(avail) must_exit = must_exit_filter(avail, must_exit_lw + must_exit_dw, entrances) return must_exit, multi_exit_caves @@ -632,10 +958,10 @@ def do_fixed_shuffle(avail, entrance_list): max_size = max(max_size, size) rules = Restrictions() rules.size = size - if ('Hyrule Castle Entrance (South)' in entrances and - avail.world.doorShuffle[avail.player] != 'vanilla'): + if ('Hyrule Castle Entrance (South)' in entrances and avail.is_sanc_forced_in_hc()): rules.must_exit_to_lw = True - if 'Inverted Ganons Tower' in entrances and not avail.world.shuffle_ganon: + if (avail.world.is_atgt_swapped(avail.player) and 'Agahnims Tower' in entrances and + not avail.world.shuffle_ganon[avail.player]): rules.fixed = True option = (i, entrances, targets, rules) options[i] = option @@ -647,10 +973,24 @@ def do_fixed_shuffle(avail, entrance_list): elif rules.fixed: choice = choices[i] elif rules.must_exit_to_lw: - filtered_choices = {i: opt for i, opt in choices.items() if all(t in default_lw for t in opt[2])} - index, choice = random.choice(list(filtered_choices.items())) + lw_exits = set() + for e, x in {**entrance_map, **single_entrance_map, **drop_map}.items(): + if x in avail.exits: + region = avail.world.get_entrance(e, avail.player).parent_region + if region.type == RegionType.LightWorld: + new_x = x + if avail.world.is_atgt_swapped(avail.player): + if x == 'Ganons Tower Exit': + new_x = 'Agahnims Tower Exit' + elif x == 'Agahnims Tower Exit': + new_x = 'Ganons Tower Exit' + lw_exits.add(new_x) + if avail.world.shufflelinks[avail.player] or avail.world.shuffle[avail.player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']: + lw_exits.update({'Big Bomb Shop'} if avail.world.is_bombshop_start(avail.player) else {'Links House Exit'}) + filtered_choices = {i: opt for i, opt in choices.items() if all(t in lw_exits for t in opt[2])} + _, choice = random.choice(list(filtered_choices.items())) else: - index, choice = random.choice(list(choices.items())) + _, choice = random.choice(list(choices.items())) del choices[choice[0]] for t, entrance in enumerate(entrances): target = choice[2][t] @@ -663,7 +1003,6 @@ def do_same_world_shuffle(avail, pool_def): # complete_entrance_set = set() lw_entrances, dw_entrances, multi_exits_caves, other_exits = [], [], [], [] hyrule_forced = None - check_for_hc = avail.is_standard() or avail.world.doorShuffle[avail.player] != 'vanilla' single_entrances, single_exits = find_entrances_and_exits(avail, single_exit) other_exits.extend(single_exits) @@ -673,25 +1012,25 @@ def do_same_world_shuffle(avail, pool_def): for option in multi_exit: multi_entrances, multi_exits = find_entrances_and_exits(avail, option) # complete_entrance_set.update(multi_entrances) - if check_for_hc and any(x in multi_entrances for x in ['Hyrule Castle Entrance (South)', + if avail.is_sanc_forced_in_hc() and any(x in multi_entrances for x in ['Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (West)']): hyrule_forced = [multi_exits] - else: - multi_exits_caves.append(multi_exits) + multi_exits_caves.append(multi_exits) for x in multi_entrances: (dw_entrances, lw_entrances)[x in LW_Entrances].append(x) - must_exit_lw = Inverted_LW_Must_Exit if avail.inverted else LW_Must_Exit - must_exit_dw = Inverted_DW_Must_Exit if avail.inverted else DW_Must_Exit + must_exit_lw, must_exit_dw = must_exits_helper(avail) must_exit_lw = must_exit_filter(avail, must_exit_lw, lw_entrances) must_exit_dw = must_exit_filter(avail, must_exit_dw, dw_entrances) - if hyrule_forced: - do_mandatory_connections(avail, lw_entrances, hyrule_forced, must_exit_lw) + do_mandatory_connections(avail, lw_entrances, multi_exits_caves, must_exit_lw) + if hyrule_forced and hyrule_forced[0] in multi_exits_caves: + remove_from_list(multi_exits_caves, hyrule_forced) + do_mandatory_connections(avail, dw_entrances, multi_exits_caves, must_exit_dw) + multi_exits_caves.append(hyrule_forced[0]) else: - do_mandatory_connections(avail, lw_entrances, multi_exits_caves, must_exit_lw) - do_mandatory_connections(avail, dw_entrances, multi_exits_caves, must_exit_dw) + do_mandatory_connections(avail, dw_entrances, multi_exits_caves, must_exit_dw) # connect caves random.shuffle(lw_entrances) @@ -699,12 +1038,18 @@ def do_same_world_shuffle(avail, pool_def): random.shuffle(multi_exits_caves) while multi_exits_caves: cave_candidate = (None, 0) - for i, cave in enumerate(multi_exits_caves): - if len(cave) > cave_candidate[1]: - cave_candidate = (i, len(cave)) - cave = multi_exits_caves.pop(cave_candidate[0]) + if hyrule_forced and hyrule_forced[0] in multi_exits_caves: + multi_exits_caves.remove(hyrule_forced[0]) + cave = hyrule_forced[0] + hyrule_forced = None + target = lw_entrances + else: + for i, cave in enumerate(multi_exits_caves): + if len(cave) > cave_candidate[1]: + cave_candidate = (i, len(cave)) + cave = multi_exits_caves.pop(cave_candidate[0]) + target = lw_entrances if random.randint(0, 1) == 0 else dw_entrances - target = lw_entrances if random.randint(0, 1) == 0 else dw_entrances if len(target) < len(cave): # swap because we ran out of entrances in that world target = lw_entrances if target is dw_entrances else dw_entrances @@ -715,35 +1060,35 @@ def do_same_world_shuffle(avail, pool_def): def do_connector_shuffle(avail, pool_def): - directional_list = pool_def['directional_inv' if avail.inverted else 'directional'] - connector_list = pool_def['connectors_inv' if avail.inverted else 'connectors'] + directional_list = pool_def['directional'] + connector_list = pool_def['connectors'] option_list = pool_def['options'] for connector in directional_list: chosen_option = random.choice(option_list) - ignored_ent, chosen_exits = find_entrances_and_exits(avail, chosen_option) + _, chosen_exits = find_entrances_and_exits(avail, chosen_option) if not chosen_exits: continue # nothing available # this shuffle ensures directionality shuffle_connector_exits(chosen_exits) - connector_ent, ignored_exits = find_entrances_and_exits(avail, connector) + connector_ent, _ = find_entrances_and_exits(avail, connector) for i, ent in enumerate(connector_ent): connect_two_way(ent, chosen_exits[i], avail) option_list.remove(chosen_option) for connector in connector_list: chosen_option = random.choice(option_list) - ignored_ent, chosen_exits = find_entrances_and_exits(avail, chosen_option) + _, chosen_exits = find_entrances_and_exits(avail, chosen_option) # directionality need not be preserved random.shuffle(chosen_exits) - connector_ent, ignored_exits = find_entrances_and_exits(avail, connector) + connector_ent, _ = find_entrances_and_exits(avail, connector) for i, ent in enumerate(connector_ent): connect_two_way(ent, chosen_exits[i], avail) option_list.remove(chosen_option) def do_limited_shuffle(pool_def, avail): - entrance_pool, ignored_exits = find_entrances_and_exits(avail, pool_def['entrances']) + entrance_pool, _ = find_entrances_and_exits(avail, pool_def['entrances']) exit_pool = [x for x in pool_def['options'] if x in avail.exits] random.shuffle(exit_pool) for entrance in entrance_pool: @@ -752,9 +1097,13 @@ def do_limited_shuffle(pool_def, avail): def do_limited_shuffle_exclude_drops(pool_def, avail, lw=True): - ignored_entrances, exits = find_entrances_and_exits(avail, pool_def['entrances']) + if avail.inverted: + lw = not lw + _, exits = find_entrances_and_exits(avail, pool_def['entrances']) reserved_drops = set(linked_drop_map.values()) - must_exit_lw, must_exit_dw = must_exits_helper(avail, LW_Entrances, DW_Entrances) + must_exit_lw, must_exit_dw = must_exits_helper(avail) + must_exit_lw = must_exit_filter(avail, must_exit_lw, LW_Entrances) + must_exit_dw = must_exit_filter(avail, must_exit_dw, DW_Entrances) must_exit = set(must_exit_lw if lw else must_exit_dw) base_set = LW_Entrances if lw else DW_Entrances entrance_pool = [x for x in base_set if x in avail.entrances and x not in reserved_drops] @@ -779,11 +1128,7 @@ def do_vanilla_connect(pool_def, avail): elif pool_def['condition'] == 'takeany': if avail.world.take_any[avail.player] == 'fixed': return - defaults = inverted_default_connections if avail.inverted else default_connections - if avail.inverted: - if 'Dark Death Mountain Fairy' in pool_def['entrances']: - pool_def['entrances'].remove('Dark Death Mountain Fairy') - pool_def['entrances'].append('Bumper Cave (top)') + defaults = {**default_connections, **(inverted_default_connections if avail.inverted != avail.world.is_tile_swapped(0x1b, avail.player) else open_default_connections)} for entrance in pool_def['entrances']: if entrance in avail.entrances: target = defaults[entrance] @@ -802,16 +1147,12 @@ def do_mandatory_connections(avail, entrances, cave_options, must_exit): do_mandatory_connections_decoupled(avail, cave_options, must_exit) return - # Keeps track of entrances that cannot be used to access each exit / cave - if avail.inverted: - invalid_connections = Inverted_Must_Exit_Invalid_Connections.copy() - else: - invalid_connections = Must_Exit_Invalid_Connections.copy() + invalid_connections = Must_Exit_Invalid_Connections.copy() invalid_cave_connections = defaultdict(set) if avail.world.logic[avail.player] in ['owglitches', 'nologic']: import OverworldGlitchRules - for entrance in OverworldGlitchRules.get_non_mandatory_exits(avail.inverted): + for entrance in OverworldGlitchRules.get_non_mandatory_exits(avail.world, avail.player): invalid_connections[entrance] = set() if entrance in must_exit: must_exit.remove(entrance) @@ -820,12 +1161,12 @@ def do_mandatory_connections(avail, entrances, cave_options, must_exit): random.shuffle(entrances) random.shuffle(cave_options) - if avail.inverted: - at = avail.world.get_region('Agahnims Tower Portal', avail.player) + if avail.world.is_tile_swapped(0x1b, avail.player): for entrance in invalid_connections: - if avail.world.get_entrance(entrance, avail.player).connected_region == at: + region = avail.world.get_entrance(entrance, avail.player).connected_region + if region and region.name == 'Agahnims Tower Portal': for ext in invalid_connections[entrance]: - invalid_connections[ext] = invalid_connections[ext].union({'Inverted Ganons Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}) + invalid_connections[ext] = invalid_connections[ext].union({'Agahnims Tower', 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}) break used_caves = [] @@ -965,11 +1306,11 @@ def find_entrances_and_exits(avail_pool, entrance_pool): entrances, targets = [], [] inverted_substitution(avail_pool, entrance_pool, True) for item in entrance_pool: + if item == 'Ganons Tower' and not avail_pool.world.shuffle_ganon[avail_pool.player]: + continue if item in avail_pool.entrances: entrances.append(item) if item in entrance_map and entrance_map[item] in avail_pool.exits: - if entrance_map[item] in ['Links House Exit', 'Inverted Links House Exit']: - targets.append('Chris Houlihan Room Exit') targets.append(entrance_map[item]) elif item in single_entrance_map and single_entrance_map[item] in avail_pool.exits: targets.append(single_entrance_map[item]) @@ -977,26 +1318,16 @@ def find_entrances_and_exits(avail_pool, entrance_pool): inverted_sub_table = { - 'Ganons Tower': 'Inverted Agahnims Tower', - 'Agahnims Tower': 'Inverted Ganons Tower', - 'Dark Sanctuary Hint': 'Inverted Dark Sanctuary', - 'Big Bomb Shop': 'Inverted Links House', - 'Links House': 'Inverted Big Bomb Shop', 'Pyramid Hole': 'Inverted Pyramid Hole', 'Pyramid Entrance': 'Inverted Pyramid Entrance' } inverted_exit_sub_table = { - 'Ganons Tower Exit': 'Inverted Agahnims Tower Exit', - 'Agahnims Tower Exit': 'Inverted Ganons Tower Exit', - 'Dark Sanctuary Hint': 'Inverted Dark Sanctuary Exit', - 'Big Bomb Shop': 'Inverted Links House Exit', - 'Links House Exit': 'Inverted Big Bomb Shop', } def inverted_substitution(avail_pool, collection, is_entrance, is_set=False): - if avail_pool.inverted: + if avail_pool.world.is_tile_swapped(0x1b, avail_pool.player): sub_table = inverted_sub_table if is_entrance else inverted_exit_sub_table for area, sub in sub_table.items(): if is_set: @@ -1087,10 +1418,7 @@ def connect_entrance(entrancename, exit_name, avail): entrance.connect(region, addresses, target) avail.entrances.remove(entrancename) if avail.coupled: - if exit_name == 'Inverted Dark Sanctuary': - avail.exits.remove('Inverted Dark Sanctuary Exit') - else: - avail.exits.remove(exit_name) + avail.exits.remove(exit_name) world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) logging.getLogger('').debug(f'Connected (entr) {entrance.name} to {exit.name if exit is not None else region.name}') @@ -1105,9 +1433,10 @@ def connect_exit(exit_name, entrancename, avail): exit.connected_region.entrances.remove(exit) exit.connect(entrance.parent_region, door_addresses[entrance.name][1], exit_ids[exit.name][1]) - if exit_name != 'Chris Houlihan Room Exit' and avail.coupled: - avail.entrances.remove(entrancename) - avail.exits.remove(exit_name) + if exit_name != 'Chris Houlihan Room Exit': + if avail.coupled: + avail.entrances.remove(entrancename) + avail.exits.remove(exit_name) world.spoiler.set_entrance(entrance.name, exit.name, 'exit', player) logging.getLogger('').debug(f'Connected (exit) {entrance.name} to {exit.name}') @@ -1204,6 +1533,12 @@ modes = { 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] }, + 'drops': { + 'special': 'normal_drops', + 'entrances': ['Hyrule Castle Secret Entrance Drop', 'Kakariko Well Drop', 'Bat Cave Drop', + 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', + 'Sanctuary Grave', 'Pyramid Hole'] + }, 'fixed_non_items': { 'special': 'vanilla', 'condition': '', @@ -1241,13 +1576,14 @@ modes = { 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', 'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut', 'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout', - 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', + 'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', 'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Desert Hint', + 'Dark Desert Hint', 'Desert Fairy', 'Light Hype Fairy', 'Dark Death Mountain Fairy', + 'Dark Lake Hylia Ledge Fairy', 'Bonk Fairy (Dark)', 'Links House', 'Tavern North'] }, 'old_man_cave': { # have to do old man cave first so lw dungeon don't use up everything @@ -1284,6 +1620,12 @@ modes = { 'entrances': ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] }, + 'drops': { + 'special': 'normal_drops', + 'entrances': ['Hyrule Castle Secret Entrance Drop', 'Kakariko Well Drop', 'Bat Cave Drop', + 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', + 'Sanctuary Grave', 'Pyramid Hole'] + }, 'fixed_non_items': { 'special': 'vanilla', 'condition': '', @@ -1321,13 +1663,14 @@ modes = { 'Ice Rod Cave', 'Dam', 'Bonk Rock Cave', 'Library', 'Potion Shop', 'Mini Moldorm Cave', 'Checkerboard Cave', 'Graveyard Cave', 'Cave 45', 'Sick Kids House', 'Blacksmiths Hut', 'Sahasrahlas Hut', 'Aginahs Cave', 'Chicken House', 'Kings Grave', 'Blinds Hideout', - 'Waterfall of Wishing', 'Inverted Bomb Shop', 'Cave Shop (Dark Death Mountain)', + 'Waterfall of Wishing', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', 'Dark World Lumberjack Shop', 'Dark World Shop', 'Red Shield Shop', 'Kakariko Shop', 'Capacity Upgrade', 'Cave Shop (Lake Hylia)', 'Lumberjack House', 'Snitch Lady (West)', 'Snitch Lady (East)', 'Tavern (Front)', 'Light World Bomb Hut', '20 Rupee Cave', '50 Rupee Cave', 'Hookshot Fairy', 'Palace of Darkness Hint', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Desert Hint', + 'Dark Desert Hint', 'Desert Fairy', 'Light Hype Fairy', 'Dark Death Mountain Fairy', + 'Dark Lake Hylia Ledge Fairy', 'Bonk Fairy (Dark)', 'Links House', 'Tavern North'] # inverted links house gets substituted } } @@ -1371,15 +1714,6 @@ modes = { ['Two Brothers House (East)', 'Two Brothers House (West)'], ['Superbunny Cave (Bottom)', 'Superbunny Cave (Top)'] ], - 'directional_inv': [ - ['Old Man Cave (West)', 'Death Mountain Return Cave (West)'], - ['Two Brothers House (East)', 'Two Brothers House (West)'], - ], - 'connectors_inv': [ - ['Elder House (East)', 'Elder House (West)'], - ['Superbunny Cave (Bottom)', 'Superbunny Cave (Top)'], - ['Hookshot Cave', 'Hookshot Cave Back Entrance'] - ], 'options': [ ['Bumper Cave (Bottom)', 'Bumper Cave (Top)'], ['Hookshot Cave', 'Hookshot Cave Back Entrance'], @@ -1395,11 +1729,6 @@ modes = { 'special': 'old_man_cave_east', 'entrances': ['Old Man Cave Exit (East)'], }, - 'old_man_cave_inverted': { - 'special': 'inverted_fixed', - 'entrance': 'Bumper Cave (Bottom)', - 'exit': 'Old Man Cave Exit (West)' - }, 'light_death_mountain': { 'special': 'limited', 'entrances': ['Old Man Cave (West)', 'Old Man Cave (East)', 'Old Man House (Bottom)', @@ -1536,7 +1865,6 @@ entrance_map = { 'Hyrule Castle Entrance (West)': 'Hyrule Castle Exit (West)', 'Hyrule Castle Entrance (East)': 'Hyrule Castle Exit (East)', 'Agahnims Tower': 'Agahnims Tower Exit', - 'Inverted Agahnims Tower': 'Inverted Agahnims Tower Exit', 'Thieves Town': 'Thieves Town Exit', 'Skull Woods First Section Door': 'Skull Woods First Section Exit', @@ -1553,10 +1881,8 @@ entrance_map = { 'Dark Death Mountain Ledge (East)': 'Turtle Rock Ledge Exit (East)', 'Turtle Rock Isolated Ledge Entrance': 'Turtle Rock Isolated Ledge Exit', 'Ganons Tower': 'Ganons Tower Exit', - 'Inverted Ganons Tower': 'Inverted Ganons Tower Exit', 'Links House': 'Links House Exit', - 'Inverted Links House': 'Inverted Links House Exit', 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance Exit', @@ -1595,8 +1921,7 @@ entrance_map = { 'Spectacle Rock Cave': 'Spectacle Rock Cave Exit (Top)', 'Paradox Cave (Bottom)': 'Paradox Cave Exit (Bottom)', 'Paradox Cave (Middle)': 'Paradox Cave Exit (Middle)', - 'Paradox Cave (Top)': 'Paradox Cave Exit (Top)', - 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary Exit', + 'Paradox Cave (Top)': 'Paradox Cave Exit (Top)' } @@ -1631,113 +1956,18 @@ single_entrance_map = { 'Kings Grave': 'Kings Grave', 'Desert Fairy': 'Desert Healer Fairy', 'Light Hype Fairy': 'Swamp Healer Fairy', 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', 'Lumberjack House': 'Lumberjack House', 'Dam': 'Dam', - 'Blinds Hideout': 'Blinds Hideout', 'Waterfall of Wishing': 'Waterfall of Wishing', - 'Inverted Bomb Shop': 'Inverted Bomb Shop' + 'Blinds Hideout': 'Blinds Hideout', 'Waterfall of Wishing': 'Waterfall of Wishing' } -default_dw = { - 'Thieves Town Exit', 'Skull Woods First Section Exit', 'Skull Woods Second Section Exit (East)', - 'Skull Woods Second Section Exit (West)', 'Skull Woods Final Section Exit', 'Ice Palace Exit', 'Misery Mire Exit', - 'Palace of Darkness Exit', 'Swamp Palace Exit', 'Turtle Rock Exit (Front)', 'Turtle Rock Ledge Exit (West)', - 'Turtle Rock Ledge Exit (East)', 'Turtle Rock Isolated Ledge Exit', 'Bumper Cave Exit (Top)', - 'Bumper Cave Exit (Bottom)', 'Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)', - 'Hookshot Cave Front Exit', 'Hookshot Cave Back Exit', 'Ganons Tower Exit', 'Pyramid Exit', - 'Dark Lake Hylia Healer Fairy', 'Dark Lake Hylia Ledge Healer Fairy', 'Dark Desert Healer Fairy', - 'Dark Death Mountain Healer Fairy', 'Cave Shop (Dark Death Mountain)', 'Pyramid Fairy', 'East Dark World Hint', - 'Palace of Darkness Hint', 'Big Bomb Shop', 'Village of Outcasts Shop', 'Dark Lake Hylia Shop', - 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Brewery', 'C-Shaped House', 'Chest Game', 'Dark World Hammer Peg Cave', - 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', - 'Spike Cave', 'Skull Back Drop', 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle', 'Pyramid', - 'Inverted Agahnims Tower Exit', 'Inverted Dark Sanctuary Exit', 'Inverted Links House Exit' -} +LW_Entrances = [] +DW_Entrances = [] -default_lw = { - 'Links House Exit', 'Desert Palace Exit (South)', 'Desert Palace Exit (West)', 'Desert Palace Exit (East)', - 'Desert Palace Exit (North)', 'Eastern Palace Exit', 'Tower of Hera Exit', 'Hyrule Castle Exit (South)', - 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)', 'Agahnims Tower Exit', - 'Hyrule Castle Secret Entrance Exit', 'Kakariko Well Exit', 'Bat Cave Exit', 'Elder House Exit (East)', - 'Elder House Exit (West)', 'North Fairy Cave Exit', 'Lost Woods Hideout Exit', 'Lumberjack Tree Exit', - 'Two Brothers House Exit (East)', 'Two Brothers House Exit (West)', 'Sanctuary Exit', 'Old Man Cave Exit (East)', - 'Old Man Cave Exit (West)', 'Old Man House Exit (Bottom)', 'Old Man House Exit (Top)', - 'Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)', 'Spectacle Rock Cave Exit', - 'Spectacle Rock Cave Exit (Top)', 'Spectacle Rock Cave Exit (Peak)', 'Paradox Cave Exit (Bottom)', - 'Paradox Cave Exit (Middle)', 'Paradox Cave Exit (Top)', 'Fairy Ascension Cave Exit (Bottom)', - 'Fairy Ascension Cave Exit (Top)', 'Spiral Cave Exit', 'Spiral Cave Exit (Top)', 'Waterfall of Wishing', 'Dam', - 'Blinds Hideout', 'Lumberjack House', 'Bonk Fairy (Light)', 'Bonk Fairy (Dark)', 'Lake Hylia Healer Fairy', - 'Swamp Healer Fairy', 'Desert Healer Fairy', 'Fortune Teller (Light)', 'Lake Hylia Fortune Teller', 'Kings Grave', 'Tavern', - 'Chicken House', 'Aginahs Cave', 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Capacity Upgrade', 'Blacksmiths Hut', - 'Sick Kids House', 'Lost Woods Gamble', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', - 'Tavern (Front)', 'Light World Bomb Hut', 'Kakariko Shop', 'Cave 45', 'Graveyard Cave', 'Checkerboard Cave', - 'Mini Moldorm Cave', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', '50 Rupee Cave', 'Ice Rod Cave', - 'Bonk Rock Cave', 'Library', 'Kakariko Gamble Game', 'Potion Shop', 'Hookshot Fairy', 'Mimic Cave', - 'Kakariko Well (top)', 'Hyrule Castle Secret Entrance', 'Bat Cave (right)', 'North Fairy Cave', - 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Inverted Ganons Tower Exit', - 'Inverted Big Bomb Shop' -} - -LW_Entrances = ['Elder House (East)', 'Elder House (West)', 'Two Brothers House (East)', 'Two Brothers House (West)', - 'Old Man Cave (West)', 'Old Man House (Bottom)', 'Death Mountain Return Cave (West)', - 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', - 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', - 'Desert Palace Entrance (South)', 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', - 'Desert Palace Entrance (East)', 'Eastern Palace', 'Tower of Hera', 'Hyrule Castle Entrance (West)', - 'Hyrule Castle Entrance (East)', 'Hyrule Castle Entrance (South)', 'Agahnims Tower', 'Blinds Hideout', - 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Tavern North', 'Chicken House', 'Aginahs Cave', - 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Blacksmiths Hut', 'Sick Kids House', 'Lost Woods Gamble', - 'Fortune Teller (Light)', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', - 'Tavern (Front)', 'Light World Bomb Hut', 'Kakariko Shop', 'Mini Moldorm Cave', 'Long Fairy Cave', - 'Good Bee Cave', '20 Rupee Cave', '50 Rupee Cave', 'Ice Rod Cave', 'Library', 'Potion Shop', 'Dam', - 'Lumberjack House', 'Lake Hylia Fortune Teller', 'Kakariko Gamble Game', 'Waterfall of Wishing', - 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', 'Kings Grave', - 'Bonk Fairy (Light)', 'Hookshot Fairy', 'Mimic Cave', 'Links House', 'Old Man Cave (East)', - 'Old Man House (Top)', 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave', - 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Hyrule Castle Secret Entrance Stairs', - 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Lost Woods Hideout Stump', - 'Lumberjack Tree Cave', 'Sanctuary', - 'Inverted Ganons Tower', 'Inverted Big Bomb Shop', 'Inverted Pyramid Entrance'] - -DW_Entrances = ['Bumper Cave (Bottom)', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', 'Hookshot Cave', - 'Thieves Town', 'Skull Woods Final Section', 'Ice Palace', 'Misery Mire', 'Palace of Darkness', - 'Swamp Palace', 'Turtle Rock', 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', - 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', - 'Bonk Fairy (Dark)', 'Dark Sanctuary Hint', 'Dark Lake Hylia Fairy', 'C-Shaped House', 'Big Bomb Shop', - 'Dark Death Mountain Fairy', 'Dark Lake Hylia Shop', 'Dark World Shop', 'Red Shield Shop', 'Mire Shed', - 'East Dark World Hint', 'Dark Desert Hint', 'Spike Cave', 'Palace of Darkness Hint', - 'Dark Lake Hylia Ledge Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark World Potion Shop', - 'Pyramid Fairy', 'Archery Game', 'Dark World Lumberjack Shop', 'Hype Cave', 'Brewery', - 'Dark Lake Hylia Ledge Hint', 'Chest Game', 'Dark Desert Fairy', 'Dark Lake Hylia Ledge Fairy', - 'Fortune Teller (Dark)', 'Dark World Hammer Peg Cave', 'Pyramid Entrance', - 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', - 'Skull Woods Second Section Door (West)', - 'Inverted Dark Sanctuary', 'Inverted Links House', 'Inverted Agahnims Tower'] - -LW_Must_Exit = ['Desert Palace Entrance (East)'] - -DW_Must_Exit = [('Dark Death Mountain Ledge (East)', 'Dark Death Mountain Ledge (West)'), - 'Turtle Rock Isolated Ledge Entrance', 'Bumper Cave (Top)', 'Hookshot Cave Back Entrance', - 'Pyramid Entrance'] - -Inverted_LW_Must_Exit = [('Desert Palace Entrance (North)', 'Desert Palace Entrance (West)'), - 'Desert Palace Entrance (East)', 'Death Mountain Return Cave (West)', - 'Two Brothers House (West)', - ('Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower')] - -Inverted_DW_Must_Exit = [] - -Isolated_LH_Doors_Open = ['Mimic Cave', 'Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', - 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', - 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', - 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', - 'Dark World Shop', 'Dark World Potion Shop'] - -Isolated_LH_Doors_Inv = ['Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', - 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', - 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', - 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', - 'Dark World Shop', 'Dark World Potion Shop'] +Isolated_LH_Doors = ['Kings Grave', 'Waterfall of Wishing', 'Desert Palace Entrance (South)', + 'Desert Palace Entrance (North)', 'Capacity Upgrade', 'Ice Palace', + 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)', + 'Dark World Hammer Peg Cave', 'Turtle Rock Isolated Ledge Entrance', + 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', + 'Dark World Shop', 'Dark World Potion Shop'] # inverted doesn't like really like - Paradox Top or Tower of Hera LH_DM_Connector_List = { @@ -1745,7 +1975,7 @@ LH_DM_Connector_List = { 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Tower of Hera', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Hookshot Fairy', 'Spike Cave', - 'Dark Death Mountain Fairy', 'Inverted Agahnims Tower', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', + 'Dark Death Mountain Fairy', 'Ganons Tower', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Cave Shop (Dark Death Mountain)', 'Turtle Rock'} LH_DM_Exit_Forbidden = { @@ -1755,12 +1985,6 @@ LH_DM_Exit_Forbidden = { 'Skull Woods Final Section', 'Skull Woods Second Section Door (West)' } # omissions from Isolated Starts: 'Desert Palace Entrance (North)', 'Dark World Shop', 'Dark World Potion Shop' -# in inverted we put dark sanctuary in west dark world for now -Inverted_Dark_Sanctuary_Doors = [ - 'Inverted Dark Sanctuary', 'Fortune Teller (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', - 'Dark World Lumberjack Shop', 'Red Shield Shop', 'Bumper Cave (Bottom)', 'Bumper Cave (Top)', 'Thieves Town' -] - Connector_List = [['Elder House Exit (East)', 'Elder House Exit (West)'], ['Two Brothers House Exit (East)', 'Two Brothers House Exit (West)'], ['Death Mountain Return Cave Exit (West)', 'Death Mountain Return Cave Exit (East)'], @@ -1793,192 +2017,41 @@ Connector_Exit_Set = { } # Entrances that cannot be used to access a must_exit entrance - symmetrical to allow reverse lookups -Must_Exit_Invalid_Connections = defaultdict(set, { - 'Dark Death Mountain Ledge (East)': {'Dark Death Mountain Ledge (West)', 'Mimic Cave'}, - 'Dark Death Mountain Ledge (West)': {'Dark Death Mountain Ledge (East)', 'Mimic Cave'}, - 'Mimic Cave': {'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)'}, - 'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'}, - 'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'}, - 'Skull Woods Second Section Door (West)': {'Skull Woods Final Section'}, - 'Skull Woods Final Section': {'Skull Woods Second Section Door (West)'}, -}) -Inverted_Must_Exit_Invalid_Connections = defaultdict(set, { - 'Bumper Cave (Top)': {'Death Mountain Return Cave (West)'}, - 'Death Mountain Return Cave (West)': {'Bumper Cave (Top)'}, - 'Desert Palace Entrance (North)': {'Desert Palace Entrance (West)'}, - 'Desert Palace Entrance (West)': {'Desert Palace Entrance (North)'}, - 'Inverted Ganons Tower': {'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)'}, - 'Hyrule Castle Entrance (West)': {'Hyrule Castle Entrance (East)', 'Inverted Ganons Tower'}, - 'Hyrule Castle Entrance (East)': {'Hyrule Castle Entrance (West)', 'Inverted Ganons Tower'}, -}) - -Old_Man_Entrances = ['Old Man Cave (East)', - 'Old Man House (Top)', - 'Death Mountain Return Cave (East)', - 'Spectacle Rock Cave', - 'Spectacle Rock Cave Peak', - 'Spectacle Rock Cave (Bottom)', - 'Tower of Hera'] - -Inverted_Old_Man_Entrances = ['Dark Death Mountain Fairy', 'Spike Cave', 'Inverted Agahnims Tower'] +Must_Exit_Invalid_Connections = defaultdict(set) Simple_DM_Non_Connectors = {'Old Man Cave Ledge', 'Spiral Cave (Top)', 'Superbunny Cave (Bottom)', 'Spectacle Rock Cave (Peak)', 'Spectacle Rock Cave (Top)'} -Blacksmith_Options = [ - 'Blinds Hideout', 'Lake Hylia Fairy', 'Light Hype Fairy', 'Desert Fairy', 'Tavern North', 'Chicken House', - 'Aginahs Cave', 'Sahasrahlas Hut', 'Cave Shop (Lake Hylia)', 'Blacksmiths Hut', 'Sick Kids House', 'Lost Woods Gamble', - 'Fortune Teller (Light)', 'Snitch Lady (East)', 'Snitch Lady (West)', 'Bush Covered House', 'Tavern (Front)', - 'Light World Bomb Hut', 'Kakariko Shop', 'Mini Moldorm Cave', 'Long Fairy Cave', 'Good Bee Cave', '20 Rupee Cave', - '50 Rupee Cave', 'Ice Rod Cave', 'Library', 'Potion Shop', 'Dam', 'Lumberjack House', 'Lake Hylia Fortune Teller', - 'Kakariko Gamble Game', 'Eastern Palace', 'Elder House (East)', 'Elder House (West)', 'Two Brothers House (East)', - 'Old Man Cave (West)', 'Sanctuary', 'Lumberjack Tree Cave', 'Lost Woods Hideout Stump', 'North Fairy Cave', - 'Bat Cave Cave', 'Kakariko Well Cave', 'Inverted Big Bomb Shop', 'Links House'] - -Bomb_Shop_Options = [ - 'Waterfall of Wishing', 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', - 'Kings Grave', 'Bonk Fairy (Light)', 'Hookshot Fairy', 'East Dark World Hint', 'Palace of Darkness Hint', - 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Bonk Fairy (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', - 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Dark Sanctuary Hint', 'Fortune Teller (Dark)', 'Dark World Shop', - 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', - 'Dark Desert Fairy', 'Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy', 'Mimic Cave', - 'Big Bomb Shop', 'Dark Lake Hylia Shop', 'Bumper Cave (Top)', 'Links House', - 'Hyrule Castle Entrance (South)', 'Misery Mire', 'Thieves Town', 'Bumper Cave (Bottom)', 'Swamp Palace', - 'Hyrule Castle Secret Entrance Stairs', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', - 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', 'Ice Palace', 'Turtle Rock', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', 'Superbunny Cave (Top)', - 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Ganons Tower', 'Desert Palace Entrance (South)', 'Tower of Hera', - 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', - 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', - 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Fairy Ascension Cave (Bottom)', - 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Palace of Darkness', - 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', 'Agahnims Tower', - 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', - 'Spectacle Rock Cave', 'Spectacle Rock Cave (Bottom)', 'Two Brothers House (West)'] + Blacksmith_Options - -Inverted_Bomb_Shop_Options = [ - 'Waterfall of Wishing', 'Capacity Upgrade', 'Bonk Rock Cave', 'Graveyard Cave', 'Checkerboard Cave', 'Cave 45', - 'Kings Grave', 'Bonk Fairy (Light)', 'Hookshot Fairy', 'East Dark World Hint', 'Palace of Darkness Hint', - 'Dark Lake Hylia Fairy', 'Dark Lake Hylia Ledge Fairy', 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint', 'Hype Cave', 'Bonk Fairy (Dark)', 'Brewery', 'C-Shaped House', 'Chest Game', - 'Dark World Hammer Peg Cave', 'Red Shield Shop', 'Fortune Teller (Dark)', 'Dark World Shop', - 'Dark World Lumberjack Shop', 'Dark World Potion Shop', 'Archery Game', 'Mire Shed', 'Dark Desert Hint', - 'Dark Desert Fairy', 'Spike Cave', 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy', 'Mimic Cave', - 'Dark Lake Hylia Shop', 'Bumper Cave (Top)', - 'Hyrule Castle Entrance (South)', 'Misery Mire', 'Thieves Town', 'Bumper Cave (Bottom)', 'Swamp Palace', - 'Hyrule Castle Secret Entrance Stairs', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', - 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', 'Ice Palace', 'Turtle Rock', - 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', 'Superbunny Cave (Top)', - 'Superbunny Cave (Bottom)', 'Hookshot Cave', 'Desert Palace Entrance (South)', 'Tower of Hera', - 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', - 'Death Mountain Return Cave (East)', 'Death Mountain Return Cave (West)', 'Spectacle Rock Cave Peak', - 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', 'Paradox Cave (Top)', 'Fairy Ascension Cave (Bottom)', - 'Fairy Ascension Cave (Top)', 'Spiral Cave', 'Spiral Cave (Bottom)', 'Palace of Darkness', - 'Hyrule Castle Entrance (West)', 'Hyrule Castle Entrance (East)', - 'Desert Palace Entrance (West)', 'Desert Palace Entrance (North)', - 'Inverted Ganons Tower', 'Inverted Agahnims Tower', 'Inverted Dark Sanctuary', 'Inverted Links House', - 'Inverted Big Bomb Shop'] + Blacksmith_Options - # these are connections that cannot be shuffled and always exist. -# They link together separate parts of the world we need to divide into regions -mandatory_connections = [('Links House S&Q', 'Links House'), - ('Sanctuary S&Q', 'Sanctuary'), - ('Old Man S&Q', 'Old Man House'), - ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), - ('Lake Hylia Central Island Teleporter', 'Dark Lake Hylia Central Island'), - ('Zoras River', 'Zoras River'), - ('Zora Waterfall Entryway', 'Zora Waterfall Entryway'), - ('Zora Waterfall Water Drop', 'Light World'), - ('Kings Grave Outer Rocks', 'Kings Grave Area'), - ('Kings Grave Inner Rocks', 'Light World'), +# They link together underworld regions +mandatory_connections = [('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), + ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), ('Kakariko Well (top to back)', 'Kakariko Well (back)'), - ('Master Sword Meadow', 'Master Sword Meadow'), - ('Hobo Bridge', 'Hobo Bridge'), - ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), - ('Bat Cave Door', 'Bat Cave (left)'), - ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), - ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), ('Blinds Hideout N', 'Blinds Hideout (Top)'), - ('Desert Palace Stairs', 'Desert Palace Stairs'), - ('Desert Palace Stairs Drop', 'Light World'), - ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), - ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Hyrule Castle Ledge Courtyard Drop', 'Hyrule Castle Courtyard'), - ('Hyrule Castle Main Gate', 'Hyrule Castle Courtyard'), + ('Bat Cave Door', 'Bat Cave (left)'), ('Sewer Drop', 'Sewers Rat Path'), - ('Flute Spot 1', 'Death Mountain'), - ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), - ('Death Mountain Entrance Drop', 'Light World'), + ('Old Man Cave Dropdown', 'Old Man Cave'), + ('Old Man House Front to Back', 'Old Man House Back'), + ('Old Man House Back to Front', 'Old Man House'), ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), - ('Death Mountain Return Ledge Drop', 'Light World'), - ('Old Man Cave Dropdown', 'Old Man Cave'), - ('Old Man House Front to Back', 'Old Man House Back'), - ('Old Man House Back to Front', 'Old Man House'), - ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), - ('Broken Bridge (East)', 'Death Mountain'), - ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), - ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), - ('East Death Mountain (Top)', 'East Death Mountain (Top)'), - ('Death Mountain (Top)', 'Death Mountain (Top)'), - ('Death Mountain Drop', 'Death Mountain'), - ('Spectacle Rock Drop', 'Death Mountain (Top)'), - - ('Top of Pyramid', 'East Dark World'), - ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), - ('Dark Lake Hylia Ledge', 'Dark Lake Hylia Ledge'), - ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), - ('East Dark World Pier', 'East Dark World'), - ('South Dark World Bridge', 'South Dark World'), - ('East Dark World Bridge', 'East Dark World'), - ('Maze Race Mirror Spot', 'Maze Race Ledge'), - ('Village of Outcasts Heavy Rock', 'West Dark World'), - ('Village of Outcasts Drop', 'South Dark World'), - ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), - ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), - ('Peg Area Rocks', 'West Dark World'), - ('Grassy Lawn Pegs', 'West Dark World'), - ('East Dark World River Pier', 'East Dark World'), - ('West Dark World Gap', 'West Dark World'), - ('East Dark World Broken Bridge Pass', 'East Dark World'), - ('Catfish Exit Rock', 'Northeast Dark World'), - ('Catfish Entrance Rock', 'Catfish'), - ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), - ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), - ('Bumper Cave Entrance Drop', 'West Dark World'), - ('Bumper Cave Ledge Drop', 'West Dark World'), - ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), - ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), - ('Skull Woods Forest', 'Skull Woods Forest'), - ('Dark Desert Teleporter', 'Dark Desert'), - ('East Hyrule Teleporter', 'East Dark World'), - ('South Hyrule Teleporter', 'South Dark World'), - ('Kakariko Teleporter', 'West Dark World'), - ('Death Mountain Teleporter', 'Dark Death Mountain (West Bottom)'), + ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), ('Paradox Cave Push Block', 'Paradox Cave Front'), ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), ('Paradox Cave Bomb Jump', 'Paradox Cave'), ('Paradox Cave Drop', 'Paradox Cave Chest Area'), - ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), - ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), - ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), - ('Fairy Ascension Ledge', 'Fairy Ascension Ledge'), ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Dark Death Mountain Drop (West)', 'Dark Death Mountain (West Bottom)'), + ('Missing Smith', 'Missing Smith'), + ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), + ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), @@ -1986,174 +2059,12 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Turtle Rock Teleporter', 'Turtle Rock (Top)'), - ('Turtle Rock Drop', 'Dark Death Mountain (Top)'), - ('Floating Island Drop', 'Dark Death Mountain (Top)'), - ('East Death Mountain Teleporter', 'Dark Death Mountain (East Bottom)'), - ('Mirror To Bombos Tablet Ledge', 'Bombos Tablet Ledge'), - ('Ganon Drop', 'Bottom of Pyramid'), - ('Pyramid Drop', 'East Dark World'), - ('Maze Race Ledge Drop', 'Light World'), - ('Graveyard Ledge Drop', 'Light World'), - ('Cave 45 Ledge Drop', 'Light World'), - ('Checkerboard Ledge Drop', 'Light World'), - ('Desert Ledge Drop', 'Light World'), - ('Hyrule Castle Main Gate (North)', 'Light World'), - ('Hyrule Castle Ledge Drop', 'Light World'), - ] - -inverted_mandatory_connections = [('Links House S&Q', 'Inverted Links House'), - ('Dark Sanctuary S&Q', 'Inverted Dark Sanctuary'), - ('Old Man S&Q', 'Old Man House'), - ('Castle Ledge S&Q', 'Hyrule Castle Ledge'), - ('Lake Hylia Central Island Pier', 'Lake Hylia Central Island'), - ('Lake Hylia Island Pier', 'Lake Hylia Island'), - ('Lake Hylia Warp', 'Northeast Light World'), - ('Northeast Light World Warp', 'Light World'), - ('Zoras River', 'Zoras River'), - ('Waterfall of Wishing Cave', 'Waterfall of Wishing Cave'), - ('Northeast Light World Return', 'Northeast Light World'), - ('Kings Grave Outer Rocks', 'Kings Grave Area'), - ('Kings Grave Inner Rocks', 'Light World'), - ('Kakariko Well (top to bottom)', 'Kakariko Well (bottom)'), - ('Kakariko Well (top to back)', 'Kakariko Well (back)'), - ('Master Sword Meadow', 'Master Sword Meadow'), - ('Hobo Bridge', 'Hobo Bridge'), - ('Bat Cave Drop Ledge', 'Bat Cave Drop Ledge'), - ('Bat Cave Door', 'Bat Cave (left)'), - ('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'), - ('Lumberjack Tree (top to bottom)', 'Lumberjack Tree (bottom)'), - ('Blinds Hideout N', 'Blinds Hideout (Top)'), - ('Desert Palace Stairs', 'Desert Palace Stairs'), - ('Desert Palace Stairs Drop', 'Light World'), - ('Desert Palace Entrance (North) Rocks', 'Desert Palace Entrance (North) Spot'), - ('Desert Ledge Return Rocks', 'Desert Ledge'), - ('Sewer Drop', 'Sewers Rat Path'), - ('Death Mountain Entrance Rock', 'Death Mountain Entrance'), - ('Death Mountain Entrance Drop', 'Light World'), - ('Death Mountain Return Cave E', 'Death Mountain Return Cave (right)'), - ('Death Mountain Return Cave W', 'Death Mountain Return Cave (left)'), - ('Spectacle Rock Cave Drop', 'Spectacle Rock Cave (Bottom)'), - ('Spectacle Rock Cave Peak Drop', 'Spectacle Rock Cave (Bottom)'), - ('Death Mountain Return Ledge Drop', 'Light World'), - ('Old Man Cave Dropdown', 'Old Man Cave'), - ('Old Man House Front to Back', 'Old Man House Back'), - ('Old Man House Back to Front', 'Old Man House'), - ('Broken Bridge (West)', 'East Death Mountain (Bottom)'), - ('Broken Bridge (East)', 'Death Mountain'), - ('East Death Mountain Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave Ledge Access', 'Spiral Cave Ledge'), - ('Spiral Cave Ledge Drop', 'East Death Mountain (Bottom)'), - ('Spiral Cave (top to bottom)', 'Spiral Cave (Bottom)'), - ('East Death Mountain (Top)', 'East Death Mountain (Top)'), - ('Death Mountain (Top)', 'Death Mountain (Top)'), - ('Death Mountain Drop', 'Death Mountain'), - ('Dark Lake Hylia Drop (East)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Drop (South)', 'Dark Lake Hylia'), - ('Dark Lake Hylia Teleporter', 'Dark Lake Hylia'), - ('Dark Lake Hylia Ledge Pier', 'Dark Lake Hylia Ledge'), - ('Dark Lake Hylia Ledge Drop', 'Dark Lake Hylia'), - ('Ice Palace Missing Wall', 'Dark Lake Hylia Central Island'), - ('Dark Lake Hylia Shallows', 'Dark Lake Hylia'), - ('East Dark World Pier', 'East Dark World'), - ('South Dark World Bridge', 'South Dark World'), - ('East Dark World Bridge', 'East Dark World'), - ('Village of Outcasts Heavy Rock', 'West Dark World'), - ('Village of Outcasts Drop', 'South Dark World'), - ('Village of Outcasts Eastern Rocks', 'Hammer Peg Area'), - ('Village of Outcasts Pegs', 'Dark Grassy Lawn'), - ('Peg Area Rocks', 'West Dark World'), - ('Grassy Lawn Pegs', 'West Dark World'), - ('East Dark World River Pier', 'Northeast Dark World'), - ('West Dark World Gap', 'West Dark World'), - ('East Dark World Broken Bridge Pass', 'East Dark World'), - ('Northeast Dark World Broken Bridge Pass', 'Northeast Dark World'), - ('Catfish Exit Rock', 'Northeast Dark World'), - ('Catfish Entrance Rock', 'Catfish'), - ('Bumper Cave Entrance Rock', 'Bumper Cave Entrance'), - ('Bumper Cave Entrance Drop', 'West Dark World'), - ('Bumper Cave Ledge Drop', 'West Dark World'), - ('Bumper Cave Top To Bottom', 'Bumper Cave (bottom)'), - ('Bumper Cave Bottom to Top', 'Bumper Cave (top)'), - ('Skull Woods Forest', 'Skull Woods Forest'), - ('Paradox Cave Push Block Reverse', 'Paradox Cave Chest Area'), - ('Paradox Cave Push Block', 'Paradox Cave Front'), - ('Paradox Cave Chest Area NE', 'Paradox Cave Bomb Area'), - ('Paradox Cave Bomb Jump', 'Paradox Cave'), - ('Paradox Cave Drop', 'Paradox Cave Chest Area'), - ('Light World Death Mountain Shop', 'Light World Death Mountain Shop'), - ('Fairy Ascension Rocks', 'Fairy Ascension Plateau'), - ('Fairy Ascension Drop', 'East Death Mountain (Bottom)'), - ('Fairy Ascension Ledge Drop', 'Fairy Ascension Plateau'), - ('Fairy Ascension Ledge Access', 'Fairy Ascension Ledge'), - ('Fairy Ascension Cave Climb', 'Fairy Ascension Cave (Top)'), - ('Fairy Ascension Cave Pots', 'Fairy Ascension Cave (Bottom)'), - ('Fairy Ascension Cave Drop', 'Fairy Ascension Cave (Drop)'), - ('Dark Death Mountain Drop (East)', 'Dark Death Mountain (East Bottom)'), - ('Ganon Drop', 'Bottom of Pyramid'), - ('Pyramid Drop', 'East Dark World'), - ('Post Aga Teleporter', 'Light World'), - ('Secret Passage Inner Bushes', 'Light World'), - ('Secret Passage Outer Bushes', 'Hyrule Castle Secret Entrance Area'), - ('Potion Shop Inner Bushes', 'Light World'), - ('Potion Shop Outer Bushes', 'Potion Shop Area'), - ('Potion Shop Inner Rock', 'Northeast Light World'), - ('Potion Shop Outer Rock', 'Potion Shop Area'), - ('Potion Shop River Drop', 'River'), - ('Graveyard Cave Inner Bushes', 'Light World'), - ('Graveyard Cave Outer Bushes', 'Graveyard Cave Area'), - ('Light World River Drop', 'River'), - ('Light World Pier', 'Light World'), - ('Potion Shop Pier', 'Potion Shop Area'), - ('Hyrule Castle Ledge Courtyard Drop', 'Light World'), - ('Mimic Cave Ledge Access', 'Mimic Cave Ledge'), - ('Mimic Cave Ledge Drop', 'East Death Mountain (Bottom)'), - ('Turtle Rock Tail Drop', 'Turtle Rock (Top)'), - ('Turtle Rock Drop', 'Dark Death Mountain'), - ('Superbunny Cave Climb', 'Superbunny Cave (Top)'), - ('Hookshot Cave Front to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Middle to Front', 'Hookshot Cave (Front)'), - ('Hookshot Cave Middle to Back', 'Hookshot Cave (Back)'), - ('Hookshot Cave Back to Middle', 'Hookshot Cave (Middle)'), - ('Hookshot Cave Bonk Path', 'Hookshot Cave (Bonk Islands)'), - ('Hookshot Cave Hook Path', 'Hookshot Cave (Hook Islands)'), - ('Desert Ledge Drop', 'Light World'), - ('Floating Island Drop', 'Dark Death Mountain'), - ('Dark Lake Hylia Central Island Teleporter', 'Lake Hylia Central Island'), - ('Dark Desert Teleporter', 'Light World'), - ('East Dark World Teleporter', 'Light World'), - ('South Dark World Teleporter', 'Light World'), - ('West Dark World Teleporter', 'Light World'), - ('Dark Death Mountain Teleporter (West)', 'Death Mountain'), - ('Dark Death Mountain Teleporter (East)', 'East Death Mountain (Top)'), - ('Dark Death Mountain Teleporter (East Bottom)', 'East Death Mountain (Bottom)'), - ('Dark Desert Drop', 'Dark Desert'), - ('DDM Flute', 'The Sky'), - ('DDM Landing', 'Dark Death Mountain'), - ('NEDW Flute', 'The Sky'), - ('NEDW Landing', 'Northeast Dark World'), - ('WDW Flute', 'The Sky'), - ('WDW Landing', 'West Dark World'), - ('SDW Flute', 'The Sky'), - ('SDW Landing', 'South Dark World'), - ('EDW Flute', 'The Sky'), - ('EDW Landing', 'East Dark World'), - ('DLHL Flute', 'The Sky'), - ('DLHL Landing', 'Dark Lake Hylia Ledge'), - ('DD Flute', 'The Sky'), - ('DD Landing', 'Dark Desert Ledge'), - ('EDDM Flute', 'The Sky'), - ('Dark Grassy Lawn Flute', 'The Sky'), - ('Hammer Peg Area Flute', 'The Sky'), - ('Bush Covered Lawn Inner Bushes', 'Light World'), - ('Bush Covered Lawn Outer Bushes', 'Bush Covered Lawn'), - ('Bomb Hut Inner Bushes', 'Light World'), - ('Bomb Hut Outer Bushes', 'Bomb Hut Area'), - ('Maze Race Ledge Drop', 'Light World')] + ('Ganon Drop', 'Bottom of Pyramid') + ] # non-shuffled entrance links default_connections = {'Links House': 'Links House', - 'Links House Exit': 'Light World', + 'Links House Exit': 'Links House Area', 'Waterfall of Wishing': 'Waterfall of Wishing', 'Blinds Hideout': 'Blinds Hideout', 'Dam': 'Dam', @@ -2175,19 +2086,19 @@ default_connections = {'Links House': 'Links House', 'Capacity Upgrade': 'Capacity Upgrade', 'Kakariko Well Drop': 'Kakariko Well (top)', 'Kakariko Well Cave': 'Kakariko Well (bottom)', - 'Kakariko Well Exit': 'Light World', + 'Kakariko Well Exit': 'Kakariko Area', 'Blacksmiths Hut': 'Blacksmiths Hut', 'Bat Cave Drop': 'Bat Cave (right)', 'Bat Cave Cave': 'Bat Cave (left)', - 'Bat Cave Exit': 'Light World', + 'Bat Cave Exit': 'Blacksmith Area', 'Sick Kids House': 'Sick Kids House', 'Elder House (East)': 'Elder House', 'Elder House (West)': 'Elder House', - 'Elder House Exit (East)': 'Light World', - 'Elder House Exit (West)': 'Light World', + 'Elder House Exit (East)': 'Kakariko Area', + 'Elder House Exit (West)': 'Kakariko Area', 'North Fairy Cave Drop': 'North Fairy Cave', 'North Fairy Cave': 'North Fairy Cave', - 'North Fairy Cave Exit': 'Light World', + 'North Fairy Cave Exit': 'River Bend Area', 'Lost Woods Gamble': 'Lost Woods Gamble', 'Fortune Teller (Light)': 'Fortune Teller (Light)', 'Snitch Lady (East)': 'Snitch Lady (East)', @@ -2198,10 +2109,10 @@ default_connections = {'Links House': 'Links House', 'Kakariko Shop': 'Kakariko Shop', 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', 'Lost Woods Hideout Stump': 'Lost Woods Hideout (bottom)', - 'Lost Woods Hideout Exit': 'Light World', + 'Lost Woods Hideout Exit': 'Lost Woods East Area', 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', 'Lumberjack Tree Cave': 'Lumberjack Tree (bottom)', - 'Lumberjack Tree Exit': 'Light World', + 'Lumberjack Tree Exit': 'Lumberjack Area', 'Cave 45': 'Cave 45', 'Graveyard Cave': 'Graveyard Cave', 'Checkerboard Cave': 'Checkerboard Cave', @@ -2217,37 +2128,37 @@ default_connections = {'Links House': 'Links House', 'Potion Shop': 'Potion Shop', 'Two Brothers House (East)': 'Two Brothers House', 'Two Brothers House (West)': 'Two Brothers House', - 'Two Brothers House Exit (East)': 'Light World', + 'Two Brothers House Exit (East)': 'Kakariko Suburb Area', 'Two Brothers House Exit (West)': 'Maze Race Ledge', 'Sanctuary': 'Sanctuary Portal', 'Sanctuary Grave': 'Sewer Drop', - 'Sanctuary Exit': 'Light World', + 'Sanctuary Exit': 'Sanctuary Area', 'Old Man Cave (West)': 'Old Man Cave Ledge', 'Old Man Cave (East)': 'Old Man Cave', - 'Old Man Cave Exit (West)': 'Light World', - 'Old Man Cave Exit (East)': 'Death Mountain', + 'Old Man Cave Exit (West)': 'Mountain Entry Entrance', + 'Old Man Cave Exit (East)': 'West Death Mountain (Bottom)', 'Old Man House (Bottom)': 'Old Man House', - 'Old Man House Exit (Bottom)': 'Death Mountain', + 'Old Man House Exit (Bottom)': 'West Death Mountain (Bottom)', 'Old Man House (Top)': 'Old Man House Back', - 'Old Man House Exit (Top)': 'Death Mountain', + 'Old Man House Exit (Top)': 'West Death Mountain (Bottom)', 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', 'Death Mountain Return Cave (West)': 'Death Mountain Return Cave (left)', - 'Death Mountain Return Cave Exit (West)': 'Death Mountain Return Ledge', - 'Death Mountain Return Cave Exit (East)': 'Death Mountain', + 'Death Mountain Return Cave Exit (West)': 'Mountain Entry Ledge', + 'Death Mountain Return Cave Exit (East)': 'West Death Mountain (Bottom)', 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', 'Spectacle Rock Cave': 'Spectacle Rock Cave (Top)', - 'Spectacle Rock Cave Exit': 'Death Mountain', - 'Spectacle Rock Cave Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Exit (Peak)': 'Death Mountain', + 'Spectacle Rock Cave Exit': 'West Death Mountain (Bottom)', + 'Spectacle Rock Cave Exit (Top)': 'West Death Mountain (Bottom)', + 'Spectacle Rock Cave Exit (Peak)': 'West Death Mountain (Bottom)', 'Paradox Cave (Bottom)': 'Paradox Cave Front', 'Paradox Cave (Middle)': 'Paradox Cave', 'Paradox Cave (Top)': 'Paradox Cave', 'Paradox Cave Exit (Bottom)': 'East Death Mountain (Bottom)', 'Paradox Cave Exit (Middle)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Top)': 'East Death Mountain (Top)', + 'Paradox Cave Exit (Top)': 'East Death Mountain (Top East)', 'Hookshot Fairy': 'Hookshot Fairy', 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave (Top)', @@ -2283,7 +2194,7 @@ default_connections = {'Links House': 'Links House', 'Dark World Potion Shop': 'Dark World Potion Shop', 'Archery Game': 'Archery Game', 'Bumper Cave Exit (Top)': 'Bumper Cave Ledge', - 'Bumper Cave Exit (Bottom)': 'West Dark World', + 'Bumper Cave Exit (Bottom)': 'Bumper Cave Entrance', 'Mire Shed': 'Mire Shed', 'Dark Desert Hint': 'Dark Desert Hint', 'Dark Desert Fairy': 'Dark Desert Healer Fairy', @@ -2293,291 +2204,21 @@ default_connections = {'Links House': 'Links House', 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy': 'Dark Death Mountain Healer Fairy', 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', - 'Superbunny Cave Exit (Top)': 'Dark Death Mountain (Top)', - 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', - 'Hookshot Cave Front Exit': 'Dark Death Mountain (Top)', - 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', + 'Superbunny Cave Exit (Top)': 'East Dark Death Mountain (Top)', + 'Superbunny Cave Exit (Bottom)': 'East Dark Death Mountain (Bottom)', + 'Hookshot Cave Front Exit': 'East Dark Death Mountain (Top)', + 'Hookshot Cave Back Exit': 'Dark Death Mountain Floating Island', 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', - 'Mimic Cave': 'Mimic Cave', + 'Mimic Cave': 'Mimic Cave'} - 'Pyramid Hole': 'Pyramid', - 'Pyramid Exit': 'Pyramid Ledge', - 'Pyramid Entrance': 'Bottom of Pyramid'} +open_default_connections = {'Pyramid Hole': 'Pyramid', + 'Pyramid Exit': 'Pyramid Ledge', + 'Pyramid Entrance': 'Bottom of Pyramid'} -inverted_default_connections = {'Waterfall of Wishing': 'Waterfall of Wishing', - 'Blinds Hideout': 'Blinds Hideout', - 'Dam': 'Dam', - 'Lumberjack House': 'Lumberjack House', - 'Hyrule Castle Secret Entrance Drop': 'Hyrule Castle Secret Entrance', - 'Hyrule Castle Secret Entrance Stairs': 'Hyrule Castle Secret Entrance', - 'Hyrule Castle Secret Entrance Exit': 'Light World', - 'Bonk Fairy (Light)': 'Bonk Fairy (Light)', - 'Lake Hylia Fairy': 'Lake Hylia Healer Fairy', - 'Lake Hylia Fortune Teller': 'Lake Hylia Fortune Teller', - 'Light Hype Fairy': 'Swamp Healer Fairy', - 'Desert Fairy': 'Desert Healer Fairy', - 'Kings Grave': 'Kings Grave', - 'Tavern North': 'Tavern', - 'Chicken House': 'Chicken House', - 'Aginahs Cave': 'Aginahs Cave', - 'Sahasrahlas Hut': 'Sahasrahlas Hut', - 'Cave Shop (Lake Hylia)': 'Cave Shop (Lake Hylia)', - 'Capacity Upgrade': 'Capacity Upgrade', - 'Kakariko Well Drop': 'Kakariko Well (top)', - 'Kakariko Well Cave': 'Kakariko Well (bottom)', - 'Kakariko Well Exit': 'Light World', - 'Blacksmiths Hut': 'Blacksmiths Hut', - 'Bat Cave Drop': 'Bat Cave (right)', - 'Bat Cave Cave': 'Bat Cave (left)', - 'Bat Cave Exit': 'Light World', - 'Sick Kids House': 'Sick Kids House', - 'Elder House (East)': 'Elder House', - 'Elder House (West)': 'Elder House', - 'Elder House Exit (East)': 'Light World', - 'Elder House Exit (West)': 'Light World', - 'North Fairy Cave Drop': 'North Fairy Cave', - 'North Fairy Cave': 'North Fairy Cave', - 'North Fairy Cave Exit': 'Light World', - 'Lost Woods Gamble': 'Lost Woods Gamble', - 'Fortune Teller (Light)': 'Fortune Teller (Light)', - 'Snitch Lady (East)': 'Snitch Lady (East)', - 'Snitch Lady (West)': 'Snitch Lady (West)', - 'Bush Covered House': 'Bush Covered House', - 'Tavern (Front)': 'Tavern (Front)', - 'Light World Bomb Hut': 'Light World Bomb Hut', - 'Kakariko Shop': 'Kakariko Shop', - 'Lost Woods Hideout Drop': 'Lost Woods Hideout (top)', - 'Lost Woods Hideout Stump': 'Lost Woods Hideout (bottom)', - 'Lost Woods Hideout Exit': 'Light World', - 'Lumberjack Tree Tree': 'Lumberjack Tree (top)', - 'Lumberjack Tree Cave': 'Lumberjack Tree (bottom)', - 'Lumberjack Tree Exit': 'Light World', - 'Cave 45': 'Cave 45', - 'Graveyard Cave': 'Graveyard Cave', - 'Checkerboard Cave': 'Checkerboard Cave', - 'Mini Moldorm Cave': 'Mini Moldorm Cave', - 'Long Fairy Cave': 'Long Fairy Cave', - 'Good Bee Cave': 'Good Bee Cave', - '20 Rupee Cave': '20 Rupee Cave', - '50 Rupee Cave': '50 Rupee Cave', - 'Ice Rod Cave': 'Ice Rod Cave', - 'Bonk Rock Cave': 'Bonk Rock Cave', - 'Library': 'Library', - 'Kakariko Gamble Game': 'Kakariko Gamble Game', - 'Potion Shop': 'Potion Shop', - 'Two Brothers House (East)': 'Two Brothers House', - 'Two Brothers House (West)': 'Two Brothers House', - 'Two Brothers House Exit (East)': 'Light World', - 'Two Brothers House Exit (West)': 'Maze Race Ledge', - 'Sanctuary': 'Sanctuary Portal', - 'Sanctuary Grave': 'Sewer Drop', - 'Sanctuary Exit': 'Light World', - 'Old Man House (Bottom)': 'Old Man House', - 'Old Man House Exit (Bottom)': 'Death Mountain', - 'Old Man House (Top)': 'Old Man House Back', - 'Old Man House Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Peak': 'Spectacle Rock Cave (Peak)', - 'Spectacle Rock Cave (Bottom)': 'Spectacle Rock Cave (Bottom)', - 'Spectacle Rock Cave': 'Spectacle Rock Cave (Top)', - 'Spectacle Rock Cave Exit': 'Death Mountain', - 'Spectacle Rock Cave Exit (Top)': 'Death Mountain', - 'Spectacle Rock Cave Exit (Peak)': 'Death Mountain', - 'Paradox Cave (Bottom)': 'Paradox Cave Front', - 'Paradox Cave (Middle)': 'Paradox Cave', - 'Paradox Cave (Top)': 'Paradox Cave', - 'Paradox Cave Exit (Bottom)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Middle)': 'East Death Mountain (Bottom)', - 'Paradox Cave Exit (Top)': 'East Death Mountain (Top)', - 'Hookshot Fairy': 'Hookshot Fairy', - 'Fairy Ascension Cave (Bottom)': 'Fairy Ascension Cave (Bottom)', - 'Fairy Ascension Cave (Top)': 'Fairy Ascension Cave (Top)', - 'Fairy Ascension Cave Exit (Bottom)': 'Fairy Ascension Plateau', - 'Fairy Ascension Cave Exit (Top)': 'Fairy Ascension Ledge', - 'Spiral Cave': 'Spiral Cave (Top)', - 'Spiral Cave (Bottom)': 'Spiral Cave (Bottom)', - 'Spiral Cave Exit': 'East Death Mountain (Bottom)', - 'Spiral Cave Exit (Top)': 'Spiral Cave Ledge', - 'Pyramid Fairy': 'Pyramid Fairy', - 'East Dark World Hint': 'East Dark World Hint', - 'Palace of Darkness Hint': 'Palace of Darkness Hint', - 'Dark Lake Hylia Shop': 'Dark Lake Hylia Shop', - 'Dark Lake Hylia Fairy': 'Dark Lake Hylia Healer Fairy', - 'Dark Lake Hylia Ledge Fairy': 'Dark Lake Hylia Ledge Healer Fairy', - 'Dark Lake Hylia Ledge Spike Cave': 'Dark Lake Hylia Ledge Spike Cave', - 'Dark Lake Hylia Ledge Hint': 'Dark Lake Hylia Ledge Hint', - 'Hype Cave': 'Hype Cave', - 'Bonk Fairy (Dark)': 'Bonk Fairy (Dark)', - 'Brewery': 'Brewery', - 'C-Shaped House': 'C-Shaped House', - 'Chest Game': 'Chest Game', - 'Dark World Hammer Peg Cave': 'Dark World Hammer Peg Cave', - 'Red Shield Shop': 'Red Shield Shop', - 'Fortune Teller (Dark)': 'Fortune Teller (Dark)', - 'Dark World Shop': 'Village of Outcasts Shop', - 'Dark World Lumberjack Shop': 'Dark World Lumberjack Shop', - 'Dark World Potion Shop': 'Dark World Potion Shop', - 'Archery Game': 'Archery Game', - 'Mire Shed': 'Mire Shed', - 'Dark Desert Hint': 'Dark Desert Hint', - 'Dark Desert Fairy': 'Dark Desert Healer Fairy', - 'Spike Cave': 'Spike Cave', - 'Hookshot Cave': 'Hookshot Cave (Front)', - 'Superbunny Cave (Top)': 'Superbunny Cave (Top)', - 'Cave Shop (Dark Death Mountain)': 'Cave Shop (Dark Death Mountain)', - 'Superbunny Cave (Bottom)': 'Superbunny Cave (Bottom)', - 'Superbunny Cave Exit (Bottom)': 'Dark Death Mountain (East Bottom)', - 'Hookshot Cave Back Exit': 'Death Mountain Floating Island (Dark World)', - 'Hookshot Cave Back Entrance': 'Hookshot Cave (Back)', - 'Mimic Cave': 'Mimic Cave', - 'Inverted Pyramid Hole': 'Pyramid', - 'Inverted Links House': 'Inverted Links House', - 'Inverted Links House Exit': 'South Dark World', - 'Inverted Big Bomb Shop': 'Inverted Big Bomb Shop', - 'Inverted Dark Sanctuary': 'Inverted Dark Sanctuary', - 'Inverted Dark Sanctuary Exit': 'West Dark World', - 'Old Man Cave (West)': 'Bumper Cave (bottom)', - 'Old Man Cave (East)': 'Death Mountain Return Cave (left)', - 'Old Man Cave Exit (West)': 'West Dark World', - 'Old Man Cave Exit (East)': 'Dark Death Mountain', - 'Dark Death Mountain Fairy': 'Old Man Cave', - 'Bumper Cave (Bottom)': 'Old Man Cave Ledge', - 'Bumper Cave (Top)': 'Dark Death Mountain Healer Fairy', - 'Bumper Cave Exit (Top)': 'Death Mountain Return Ledge', - 'Bumper Cave Exit (Bottom)': 'Light World', - 'Death Mountain Return Cave (West)': 'Bumper Cave (top)', - 'Death Mountain Return Cave (East)': 'Death Mountain Return Cave (right)', - 'Death Mountain Return Cave Exit (West)': 'Death Mountain', - 'Death Mountain Return Cave Exit (East)': 'Death Mountain', - 'Hookshot Cave Front Exit': 'Dark Death Mountain', - 'Superbunny Cave Exit (Top)': 'Dark Death Mountain', - 'Pyramid Exit': 'Light World', +inverted_default_connections = {'Inverted Pyramid Hole': 'Pyramid', + 'Pyramid Exit': 'Hyrule Castle Ledge', 'Inverted Pyramid Entrance': 'Bottom of Pyramid'} -# non shuffled dungeons -default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), - ('Desert Palace Entrance (West)', 'Desert West Portal'), - ('Desert Palace Entrance (North)', 'Desert Back Portal'), - ('Desert Palace Entrance (East)', 'Desert East Portal'), - ('Desert Palace Exit (South)', 'Desert Palace Stairs'), - ('Desert Palace Exit (West)', 'Desert Ledge'), - ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), - ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - - ('Eastern Palace', 'Eastern Portal'), - ('Eastern Palace Exit', 'Light World'), - ('Tower of Hera', 'Hera Portal'), - ('Tower of Hera Exit', 'Death Mountain (Top)'), - - ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), - ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), - ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Hyrule Castle Courtyard'), - ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), - ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), - ('Agahnims Tower', 'Agahnims Tower Portal'), - ('Agahnims Tower Exit', 'Hyrule Castle Ledge'), - - ('Thieves Town', 'Thieves Town Portal'), - ('Thieves Town Exit', 'West Dark World'), - ('Skull Woods First Section Hole (East)', 'Skull Pinball'), - ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), - ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), - ('Skull Woods First Section Door', 'Skull 1 Portal'), - ('Skull Woods First Section Exit', 'Skull Woods Forest'), - ('Skull Woods Second Section Hole', 'Skull Back Drop'), - ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), - ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), - ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), - ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), - ('Skull Woods Final Section', 'Skull 3 Portal'), - ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), - ('Ice Palace', 'Ice Portal'), - ('Ice Palace Exit', 'Dark Lake Hylia Central Island'), - ('Misery Mire', 'Mire Portal'), - ('Misery Mire Exit', 'Dark Desert'), - ('Palace of Darkness', 'Palace of Darkness Portal'), - ('Palace of Darkness Exit', 'East Dark World'), - ('Swamp Palace', 'Swamp Portal'), # requires additional patch for flooding moat if moved - ('Swamp Palace Exit', 'South Dark World'), - - ('Turtle Rock', 'Turtle Rock Main Portal'), - ('Turtle Rock Exit (Front)', 'Dark Death Mountain (Top)'), - ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), - ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), - ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), - ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), - ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), - - ('Ganons Tower', 'Ganons Tower Portal'), - ('Ganons Tower Exit', 'Dark Death Mountain (Top)') - ] - -inverted_default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert South Portal'), - ('Desert Palace Entrance (West)', 'Desert West Portal'), - ('Desert Palace Entrance (North)', 'Desert Back Portal'), - ('Desert Palace Entrance (East)', 'Desert East Portal'), - ('Desert Palace Exit (South)', 'Desert Palace Stairs'), - ('Desert Palace Exit (West)', 'Desert Ledge'), - ('Desert Palace Exit (East)', 'Desert Palace Lone Stairs'), - ('Desert Palace Exit (North)', 'Desert Palace Entrance (North) Spot'), - ('Eastern Palace', 'Eastern Portal'), - ('Eastern Palace Exit', 'Light World'), - ('Tower of Hera', 'Hera Portal'), - ('Tower of Hera Exit', 'Death Mountain (Top)'), - ('Hyrule Castle Entrance (South)', 'Hyrule Castle South Portal'), - ('Hyrule Castle Entrance (West)', 'Hyrule Castle West Portal'), - ('Hyrule Castle Entrance (East)', 'Hyrule Castle East Portal'), - ('Hyrule Castle Exit (South)', 'Light World'), - ('Hyrule Castle Exit (West)', 'Hyrule Castle Ledge'), - ('Hyrule Castle Exit (East)', 'Hyrule Castle Ledge'), - ('Thieves Town', 'Thieves Town Portal'), - ('Thieves Town Exit', 'West Dark World'), - ('Skull Woods First Section Hole (East)', 'Skull Pinball'), - ('Skull Woods First Section Hole (West)', 'Skull Left Drop'), - ('Skull Woods First Section Hole (North)', 'Skull Pot Circle'), - ('Skull Woods First Section Door', 'Skull 1 Portal'), - ('Skull Woods First Section Exit', 'Skull Woods Forest'), - ('Skull Woods Second Section Hole', 'Skull Back Drop'), - ('Skull Woods Second Section Door (East)', 'Skull 2 East Portal'), - ('Skull Woods Second Section Door (West)', 'Skull 2 West Portal'), - ('Skull Woods Second Section Exit (East)', 'Skull Woods Forest'), - ('Skull Woods Second Section Exit (West)', 'Skull Woods Forest (West)'), - ('Skull Woods Final Section', 'Skull 3 Portal'), - ('Skull Woods Final Section Exit', 'Skull Woods Forest (West)'), - ('Ice Palace', 'Ice Portal'), - ('Misery Mire', 'Mire Portal'), - ('Misery Mire Exit', 'Dark Desert'), - ('Palace of Darkness', 'Palace of Darkness Portal'), - ('Palace of Darkness Exit', 'East Dark World'), - # requires additional patch for flooding moat if moved - ('Swamp Palace', 'Swamp Portal'), - ('Swamp Palace Exit', 'South Dark World'), - ('Turtle Rock', 'Turtle Rock Main Portal'), - ('Turtle Rock Ledge Exit (West)', 'Dark Death Mountain Ledge'), - ('Turtle Rock Ledge Exit (East)', 'Dark Death Mountain Ledge'), - ('Dark Death Mountain Ledge (West)', 'Turtle Rock Lazy Eyes Portal'), - ('Dark Death Mountain Ledge (East)', 'Turtle Rock Chest Portal'), - ('Turtle Rock Isolated Ledge Exit', 'Dark Death Mountain Isolated Ledge'), - ('Turtle Rock Isolated Ledge Entrance', 'Turtle Rock Eye Bridge Portal'), - ('Inverted Ganons Tower', 'Ganons Tower Portal'), - ('Inverted Ganons Tower Exit', 'Hyrule Castle Ledge'), - ('Inverted Agahnims Tower', 'Agahnims Tower Portal'), - ('Inverted Agahnims Tower Exit', 'Dark Death Mountain'), - ('Turtle Rock Exit (Front)', 'Dark Death Mountain'), - ('Ice Palace Exit', 'Dark Lake Hylia') - ] - -indirect_connections = { - 'Turtle Rock (Top)': 'Turtle Rock', - 'East Dark World': 'Pyramid Fairy', - 'Big Bomb Shop': 'Pyramid Fairy', - 'Dark Desert': 'Pyramid Fairy', - 'West Dark World': 'Pyramid Fairy', - 'South Dark World': 'Pyramid Fairy', - 'Light World': 'Pyramid Fairy', - 'Old Man Cave': 'Old Man S&Q' -} # format: # Key=Name # addr = (door_index, exitdata) # multiexit @@ -2585,160 +2226,154 @@ indirect_connections = { # exitdata = (room_id, ow_area, vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x, unknown_1, unknown_2, door_1, door_2) # ToDo somehow merge this with creation of the locations -door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), - 'Inverted Big Bomb Shop': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000)), - 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000)), - 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000)), - 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000)), - 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), - 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000)), - 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be)), - 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124)), - 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158)), - 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x0418, 0x0679, 0x06b4, 0x06c6, 0x0728, 0x06e6, 0x0733, 0x07, 0xf9, 0x0000, 0x0000)), - 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), - 'Inverted Ganons Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be)), - 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000)), - 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000)), - 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000)), - 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000)), - 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000)), - 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000)), - 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000)), - 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000)), - 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000)), - 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000)), - 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000)), - 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000)), - 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000)), - 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000)), - 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000)), - 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000)), - 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000)), - 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000)), - 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa)), - 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000)), - 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000)), - 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000)), - 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000)), - 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000)), - 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000)), - 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000)), - 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000)), - 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000)), - 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000)), - 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000)), - 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)), - 'Inverted Agahnims Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000)), - 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000)), - 'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None), - 'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None), +door_addresses = {'Links House': (0x00, (0x0104, 0x2c, 0x0506, 0x0a9a, 0x0832, 0x0ae8, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfe, 0x0816, 0x0000), 0x00), + 'Desert Palace Entrance (South)': (0x08, (0x0084, 0x30, 0x0314, 0x0c56, 0x00a6, 0x0ca8, 0x0128, 0x0cc3, 0x0133, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (West)': (0x0A, (0x0083, 0x30, 0x0280, 0x0c46, 0x0003, 0x0c98, 0x0088, 0x0cb3, 0x0090, 0x0a, 0xfd, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (North)': (0x0B, (0x0063, 0x30, 0x0016, 0x0c00, 0x00a2, 0x0c28, 0x0128, 0x0c6d, 0x012f, 0x00, 0x0e, 0x0000, 0x0000), 0x00), + 'Desert Palace Entrance (East)': (0x09, (0x0085, 0x30, 0x02a8, 0x0c4a, 0x0142, 0x0c98, 0x01c8, 0x0cb7, 0x01cf, 0x06, 0xfe, 0x0000, 0x0000), 0x00), + 'Eastern Palace': (0x07, (0x00c9, 0x1e, 0x005a, 0x0600, 0x0ed6, 0x0618, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x00), + 'Tower of Hera': (0x32, (0x0077, 0x03, 0x0050, 0x0014, 0x087c, 0x0068, 0x08f0, 0x0083, 0x08fb, 0x0a, 0xf4, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Entrance (South)': (0x03, (0x0061, 0x1b, 0x0530, 0x0692, 0x0784, 0x06cc, 0x07f8, 0x06ff, 0x0803, 0x0e, 0xfa, 0x0000, 0x87be), 0x00), + 'Hyrule Castle Entrance (West)': (0x02, (0x0060, 0x1b, 0x0016, 0x0600, 0x06ae, 0x0604, 0x0728, 0x066d, 0x0733, 0x00, 0x02, 0x0000, 0x8124), 0x00), + 'Hyrule Castle Entrance (East)': (0x04, (0x0062, 0x1b, 0x004a, 0x0600, 0x0856, 0x0604, 0x08c8, 0x066d, 0x08d3, 0x00, 0xfa, 0x0000, 0x8158), 0x00), + 'Inverted Pyramid Entrance': (0x35, (0x0010, 0x1b, 0x000e, 0x0600, 0x0676, 0x0604, 0x06e8, 0x066d, 0x06f3, 0x00, 0x0a, 0x0000, 0x811c), 0x00), + 'Agahnims Tower': (0x23, (0x00e0, 0x1b, 0x0032, 0x0600, 0x0784, 0x0634, 0x07f8, 0x066d, 0x0803, 0x00, 0x0a, 0x0000, 0x82be), 0x40), + 'Thieves Town': (0x33, (0x00db, 0x58, 0x0b2e, 0x075a, 0x0176, 0x07a8, 0x01f8, 0x07c7, 0x0203, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Skull Woods First Section Door': (0x29, (0x0058, 0x40, 0x0f4c, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0xfe, 0x0000, 0x0000), 0x00), + 'Skull Woods Second Section Door (East)': (0x28, (0x0057, 0x40, 0x0eb8, 0x01e6, 0x01c2, 0x0238, 0x0248, 0x0253, 0x024f, 0x0a, 0xfe, 0x0000, 0x0000), 0x00), + 'Skull Woods Second Section Door (West)': (0x27, (0x0056, 0x40, 0x0c8e, 0x01a6, 0x0062, 0x01f8, 0x00e8, 0x0213, 0x00ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00), + 'Skull Woods Final Section': (0x2A, (0x0059, 0x40, 0x0282, 0x0066, 0x0016, 0x00b8, 0x0098, 0x00d3, 0x00a3, 0x0a, 0xfa, 0x0000, 0x0000), 0x20), + 'Ice Palace': (0x2C, (0x000e, 0x75, 0x0bc6, 0x0d6a, 0x0c3e, 0x0db8, 0x0cb8, 0x0dd7, 0x0cc3, 0x06, 0xf2, 0x0000, 0x0000), 0x00), + 'Misery Mire': (0x26, (0x0098, 0x70, 0x0414, 0x0c79, 0x00a6, 0x0cc7, 0x0128, 0x0ce6, 0x0133, 0x07, 0xfa, 0x0000, 0x0000), 0x20), + 'Palace of Darkness': (0x25, (0x004a, 0x5e, 0x005a, 0x0600, 0x0ed6, 0x0628, 0x0f50, 0x066d, 0x0f5b, 0x00, 0xfa, 0x0000, 0x0000), 0x20), + 'Swamp Palace': (0x24, (0x0028, 0x7b, 0x049e, 0x0e8c, 0x06f2, 0x0ed8, 0x0778, 0x0ef9, 0x077f, 0x04, 0xfe, 0x0000, 0x0000), 0x00), + 'Turtle Rock': (0x34, (0x00d6, 0x47, 0x0712, 0x00da, 0x0e96, 0x0128, 0x0f08, 0x0147, 0x0f13, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Dark Death Mountain Ledge (West)': (0x14, (0x0023, 0x45, 0x07ca, 0x0103, 0x0c46, 0x0157, 0x0cb8, 0x0172, 0x0cc3, 0x0b, 0x0a, 0x0000, 0x0000), 0x00), + 'Dark Death Mountain Ledge (East)': (0x18, (0x0024, 0x45, 0x07e0, 0x0103, 0x0d00, 0x0157, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Turtle Rock Isolated Ledge Entrance': (0x17, (0x00d5, 0x45, 0x0ad4, 0x0164, 0x0ca6, 0x01b8, 0x0d18, 0x01d3, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Secret Entrance Stairs': (0x31, (0x0055, 0x1b, 0x044a, 0x067a, 0x0854, 0x06c8, 0x08c8, 0x06e7, 0x08d3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Kakariko Well Cave': (0x38, (0x002f, 0x18, 0x0386, 0x0665, 0x0032, 0x06b7, 0x00b8, 0x06d2, 0x00bf, 0x0b, 0xfe, 0x0000, 0x0000), 0x00), + 'Bat Cave Cave': (0x10, (0x00e3, 0x22, 0x0412, 0x087a, 0x048e, 0x08c8, 0x0508, 0x08e7, 0x0513, 0x06, 0x02, 0x0000, 0x0000), 0x00), + 'Elder House (East)': (0x0D, (0x00f3, 0x18, 0x02c4, 0x064a, 0x0222, 0x0698, 0x02a8, 0x06b7, 0x02af, 0x06, 0xfe, 0x05d4, 0x0000), 0x00), + 'Elder House (West)': (0x0C, (0x00f2, 0x18, 0x02bc, 0x064c, 0x01e2, 0x0698, 0x0268, 0x06b9, 0x026f, 0x04, 0xfe, 0x05cc, 0x0000), 0x00), + 'North Fairy Cave': (0x37, (0x0008, 0x15, 0x0088, 0x0400, 0x0a36, 0x0448, 0x0aa8, 0x046f, 0x0ab3, 0x00, 0x0a, 0x0000, 0x0000), 0x00), + 'Lost Woods Hideout Stump': (0x2B, (0x00e1, 0x00, 0x0f4e, 0x01f6, 0x0262, 0x0248, 0x02e8, 0x0263, 0x02ef, 0x0a, 0x0e, 0x0000, 0x0000), 0x00), + 'Lumberjack Tree Cave': (0x11, (0x00e2, 0x02, 0x0118, 0x0015, 0x04c6, 0x0067, 0x0548, 0x0082, 0x0553, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Two Brothers House (East)': (0x0F, (0x00f5, 0x29, 0x0880, 0x0b07, 0x0200, 0x0b58, 0x0238, 0x0b74, 0x028d, 0x09, 0x00, 0x0b86, 0x0000), 0x00), + 'Two Brothers House (West)': (0x0E, (0x00f4, 0x28, 0x08a0, 0x0b06, 0x0100, 0x0b58, 0x01b8, 0x0b73, 0x018d, 0x0a, 0x00, 0x0bb6, 0x0000), 0x00), + 'Sanctuary': (0x01, (0x0012, 0x13, 0x001c, 0x0400, 0x06de, 0x0414, 0x0758, 0x046d, 0x0763, 0x00, 0x02, 0x0000, 0x01aa), 0x00), + 'Old Man Cave (West)': (0x05, (0x00f0, 0x0a, 0x03a0, 0x0264, 0x0500, 0x02b8, 0x05a8, 0x02d3, 0x058d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Old Man Cave (East)': (0x06, (0x00f1, 0x03, 0x1402, 0x0294, 0x0604, 0x02e8, 0x0678, 0x0303, 0x0683, 0x0a, 0xfc, 0x0000, 0x0000), 0x00), + 'Old Man House (Bottom)': (0x2F, (0x00e4, 0x03, 0x181a, 0x031e, 0x06b4, 0x03a7, 0x0728, 0x038d, 0x0733, 0x00, 0x0c, 0x0000, 0x0000), 0x00), + 'Old Man House (Top)': (0x30, (0x00e5, 0x03, 0x10c6, 0x0224, 0x0814, 0x0278, 0x0888, 0x0293, 0x0893, 0x0a, 0x0c, 0x0000, 0x0000), 0x00), + 'Death Mountain Return Cave (East)': (0x2E, (0x00e7, 0x03, 0x0d82, 0x01c4, 0x0600, 0x0218, 0x0648, 0x0233, 0x067f, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Death Mountain Return Cave (West)': (0x2D, (0x00e6, 0x0a, 0x00a0, 0x0205, 0x0500, 0x0257, 0x05b8, 0x0272, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave Peak': (0x22, (0x00ea, 0x03, 0x092c, 0x0133, 0x0754, 0x0187, 0x07c8, 0x01a2, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave': (0x21, (0x00fa, 0x03, 0x0eac, 0x01e3, 0x0754, 0x0237, 0x07c8, 0x0252, 0x07d3, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Spectacle Rock Cave (Bottom)': (0x20, (0x00f9, 0x03, 0x0d9c, 0x01c3, 0x06d4, 0x0217, 0x0748, 0x0232, 0x0753, 0x0b, 0xfc, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Bottom)': (0x1D, (0x00ff, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0237, 0x0da8, 0x0252, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Middle)': (0x1E, (0x00ef, 0x05, 0x17e0, 0x0304, 0x0d00, 0x0358, 0x0dc8, 0x0373, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Paradox Cave (Top)': (0x1F, (0x00df, 0x05, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Fairy Ascension Cave (Bottom)': (0x19, (0x00fd, 0x05, 0x0dd4, 0x01c4, 0x0ca6, 0x0218, 0x0d18, 0x0233, 0x0d23, 0x0a, 0xfa, 0x0000, 0x0000), 0x00), + 'Fairy Ascension Cave (Top)': (0x1A, (0x00ed, 0x05, 0x0ad4, 0x0163, 0x0ca6, 0x01b7, 0x0d18, 0x01d2, 0x0d23, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Spiral Cave': (0x1C, (0x00ee, 0x05, 0x07c8, 0x0108, 0x0c46, 0x0158, 0x0cb8, 0x0177, 0x0cc3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Spiral Cave (Bottom)': (0x1B, (0x00fe, 0x05, 0x0cca, 0x01a3, 0x0c56, 0x01f7, 0x0cc8, 0x0212, 0x0cd3, 0x0b, 0xfa, 0x0000, 0x0000), 0x00), + 'Bumper Cave (Bottom)': (0x15, (0x00fb, 0x4a, 0x03a0, 0x0263, 0x0500, 0x02b7, 0x05a8, 0x02d2, 0x058d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Bumper Cave (Top)': (0x16, (0x00eb, 0x4a, 0x00a0, 0x020a, 0x0500, 0x0258, 0x05b8, 0x0277, 0x058d, 0x06, 0x00, 0x0000, 0x0000), 0x00), + 'Superbunny Cave (Top)': (0x13, (0x00e8, 0x45, 0x0460, 0x0093, 0x0d00, 0x00e7, 0x0db8, 0x0102, 0x0d7d, 0x0b, 0x00, 0x0000, 0x0000), 0x00), + 'Superbunny Cave (Bottom)': (0x12, (0x00f8, 0x45, 0x0ee0, 0x01e4, 0x0d00, 0x0238, 0x0d78, 0x0253, 0x0d7d, 0x0a, 0x00, 0x0000, 0x0000), 0x00), + 'Hookshot Cave': (0x39, (0x003c, 0x45, 0x04da, 0x00a3, 0x0cd6, 0x0107, 0x0d48, 0x0112, 0x0d53, 0x0b, 0xfa, 0x0000, 0x0000), 0x20), + 'Hookshot Cave Back Entrance': (0x3A, (0x002c, 0x45, 0x004c, 0x0000, 0x0c56, 0x0038, 0x0cc8, 0x006f, 0x0cd3, 0x00, 0x0a, 0x0000, 0x0000), 0x00), + 'Ganons Tower': (0x36, (0x000c, 0x43, 0x0052, 0x0000, 0x0884, 0x0028, 0x08f8, 0x006f, 0x0903, 0x00, 0xfc, 0x0000, 0x0000), 0x20), + 'Pyramid Entrance': (0x35, (0x0010, 0x5b, 0x0b0e, 0x075a, 0x0674, 0x07a8, 0x06e8, 0x07c7, 0x06f3, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Skull Woods First Section Hole (West)': ([0xDB84D, 0xDB84E], None), + 'Skull Woods First Section Hole (East)': ([0xDB84F, 0xDB850], None), 'Skull Woods First Section Hole (North)': ([0xDB84C], None), - 'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None), - 'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None), - 'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None), - 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000)), - 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000)), - 'Hyrule Castle Secret Entrance Drop': ([0xDB858], None), - 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000)), - 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), - 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000)), - 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x091b, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000)), - 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000)), - 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000)), - 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000)), - 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None), - 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000)), - 'Bat Cave Drop': ([0xDB859, 0xDB85A], None), - 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000)), - 'North Fairy Cave Drop': ([0xDB857], None), - 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000)), - 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000)), - 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000)), - 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000)), - 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000)), - 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000)), - 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000)), - 'Lost Woods Hideout Drop': ([0xDB853], None), - 'Lumberjack Tree Tree': ([0xDB85B], None), - 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000)), - 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000)), - 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000)), - 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000)), - 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), - '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000)), - '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000)), - 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000)), - 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000)), - 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000)), - 'Sanctuary Grave': ([0xDB85E], None), - 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000)), - 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000)), - 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000)), - 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000)), - 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000)), - 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000)), - 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000)), - 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000)), - 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), - 'Inverted Dark Sanctuary': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000)), - 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000)), - 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000)), - 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000)), - 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000)), - 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000)), - 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000)), - 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000)), - 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), - 'Inverted Links House': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000)), - 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000)), - 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000)), - 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000))} + 'Skull Woods Second Section Hole': ([0xDB851, 0xDB852], None), + 'Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856], None), + 'Inverted Pyramid Hole': ([0xDB854, 0xDB855, 0xDB856, 0x180340], None), + 'Waterfall of Wishing': (0x5B, (0x0114, 0x0f, 0x0080, 0x0200, 0x0e00, 0x0207, 0x0e60, 0x026f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Dam': (0x4D, (0x010b, 0x3b, 0x04a0, 0x0e8a, 0x06fa, 0x0ed8, 0x0778, 0x0ef7, 0x077f, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Blinds Hideout': (0x60, (0x0119, 0x18, 0x02b2, 0x064a, 0x0186, 0x0697, 0x0208, 0x06b7, 0x0213, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Hyrule Castle Secret Entrance Drop': ([0xDB858], None), + 'Bonk Fairy (Light)': (0x76, (0x0126, 0x2b, 0x00a0, 0x0a0a, 0x0700, 0x0a67, 0x0788, 0x0a77, 0x0785, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Lake Hylia Fairy': (0x5D, (0x0115, 0x2e, 0x0016, 0x0a00, 0x0cb6, 0x0a37, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Light Hype Fairy': (0x6B, (0x0115, 0x34, 0x00a0, 0x0c04, 0x0900, 0x0c58, 0x0988, 0x0c73, 0x0985, 0x0a, 0xf6, 0x0000, 0x0000), 0x02), + 'Desert Fairy': (0x71, (0x0115, 0x3a, 0x0000, 0x0e00, 0x0400, 0x0e26, 0x0468, 0x0e6d, 0x0485, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Kings Grave': (0x5A, (0x0113, 0x14, 0x0320, 0x0456, 0x0900, 0x04a6, 0x0998, 0x04c3, 0x097d, 0x0a, 0xf6, 0x0000, 0x0000), 0x20), + 'Tavern North': (0x42, (0x0103, 0x18, 0x1440, 0x08a7, 0x0206, 0x091b, 0x0288, 0x0914, 0x0293, 0xf7, 0x09, 0xFFFF, 0x0000), 0x00), + 'Chicken House': (0x4A, (0x0108, 0x18, 0x1120, 0x0837, 0x0106, 0x0888, 0x0188, 0x08a4, 0x0193, 0x07, 0xf9, 0x1530, 0x0000), 0x00), + 'Aginahs Cave': (0x70, (0x010a, 0x30, 0x0656, 0x0cc6, 0x02aa, 0x0d18, 0x0328, 0x0d33, 0x032f, 0x08, 0xf8, 0x0000, 0x0000), 0x00), + 'Sahasrahlas Hut': (0x44, (0x0105, 0x1e, 0x0610, 0x06d4, 0x0c76, 0x0727, 0x0cf0, 0x0743, 0x0cfb, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Cave Shop (Lake Hylia)': (0x57, (0x0112, 0x35, 0x0022, 0x0c00, 0x0b1a, 0x0c26, 0x0b98, 0x0c6d, 0x0b9f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Capacity Upgrade': (0x5C, (0x0115, 0x35, 0x0a46, 0x0d36, 0x0c2a, 0x0d88, 0x0ca8, 0x0da3, 0x0caf, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Kakariko Well Drop': ([0xDB85C, 0xDB85D], None), + 'Blacksmiths Hut': (0x63, (0x0121, 0x22, 0x010c, 0x081a, 0x0466, 0x0868, 0x04d8, 0x0887, 0x04e3, 0x06, 0xfa, 0x041A, 0x0000), 0x00), + 'Bat Cave Drop': ([0xDB859, 0xDB85A], None), + 'Sick Kids House': (0x3F, (0x0102, 0x18, 0x10be, 0x0826, 0x01f6, 0x0877, 0x0278, 0x0893, 0x0283, 0x08, 0xf8, 0x14CE, 0x0000), 0x00), + 'North Fairy Cave Drop': ([0xDB857], None), + 'Lost Woods Gamble': (0x3B, (0x0100, 0x00, 0x004e, 0x0000, 0x0272, 0x0008, 0x02f0, 0x006f, 0x02f7, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Fortune Teller (Light)': (0x64, (0x0122, 0x11, 0x060e, 0x04b4, 0x027d, 0x0508, 0x02f8, 0x0523, 0x0302, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Snitch Lady (East)': (0x3D, (0x0101, 0x18, 0x0ad8, 0x074a, 0x02c6, 0x0798, 0x0348, 0x07b7, 0x0353, 0x06, 0xfa, 0x0DE8, 0x0000), 0x00), + 'Snitch Lady (West)': (0x3E, (0x0101, 0x18, 0x0788, 0x0706, 0x0046, 0x0758, 0x00c8, 0x0773, 0x00d3, 0x08, 0xf8, 0x0B98, 0x0000), 0x00), + 'Bush Covered House': (0x43, (0x0103, 0x18, 0x1156, 0x081a, 0x02b6, 0x0868, 0x0338, 0x0887, 0x0343, 0x06, 0xfa, 0x1466, 0x0000), 0x00), + 'Tavern (Front)': (0x41, (0x0103, 0x18, 0x1842, 0x0916, 0x0206, 0x0967, 0x0288, 0x0983, 0x0293, 0x08, 0xf8, 0x1C50, 0x0000), 0x00), + 'Light World Bomb Hut': (0x49, (0x0107, 0x18, 0x1800, 0x0916, 0x0000, 0x0967, 0x0068, 0x0983, 0x008d, 0x08, 0xf8, 0x9C0C, 0x0000), 0x02), + 'Kakariko Shop': (0x45, (0x011f, 0x18, 0x16a8, 0x08e7, 0x0136, 0x0937, 0x01b8, 0x0954, 0x01c3, 0x07, 0xf9, 0x1AB6, 0x0000), 0x00), + 'Lost Woods Hideout Drop': ([0xDB853], None), + 'Lumberjack Tree Tree': ([0xDB85B], None), + 'Cave 45': (0x50, (0x011b, 0x32, 0x0680, 0x0cc9, 0x0400, 0x0d16, 0x0438, 0x0d36, 0x0485, 0x07, 0xf9, 0x0000, 0x0000), 0x00), + 'Graveyard Cave': (0x51, (0x011b, 0x14, 0x0016, 0x0400, 0x08a2, 0x0446, 0x0918, 0x046d, 0x091f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Checkerboard Cave': (0x7D, (0x0126, 0x30, 0x00c8, 0x0c0a, 0x024a, 0x0c67, 0x02c8, 0x0c77, 0x02cf, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Mini Moldorm Cave': (0x7C, (0x0123, 0x35, 0x1480, 0x0e96, 0x0a00, 0x0ee8, 0x0a68, 0x0f03, 0x0a85, 0x08, 0xf8, 0x0000, 0x0000), 0x02), + 'Long Fairy Cave': (0x54, (0x011e, 0x2f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Good Bee Cave': (0x6A, (0x0120, 0x37, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00), + '20 Rupee Cave': (0x7A, (0x0125, 0x37, 0x0200, 0x0c23, 0x0e00, 0x0c86, 0x0e68, 0x0c92, 0x0e7d, 0x0d, 0xf3, 0x0000, 0x0000), 0x20), + '50 Rupee Cave': (0x78, (0x0124, 0x3a, 0x0790, 0x0eea, 0x047a, 0x0f47, 0x04f8, 0x0f57, 0x04ff, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Ice Rod Cave': (0x7F, (0x0120, 0x37, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02), + 'Bonk Rock Cave': (0x79, (0x0124, 0x13, 0x0280, 0x044a, 0x0600, 0x04a7, 0x0638, 0x04b7, 0x067d, 0x06, 0xfa, 0x0000, 0x0000), 0x20), + 'Library': (0x48, (0x0107, 0x29, 0x0100, 0x0a14, 0x0200, 0x0a67, 0x0278, 0x0a83, 0x0285, 0x0a, 0xf6, 0x040E, 0x0000), 0x00), + 'Potion Shop': (0x4B, (0x0109, 0x16, 0x070a, 0x04e6, 0x0c56, 0x0538, 0x0cc8, 0x0553, 0x0cd3, 0x08, 0xf8, 0x0A98, 0x0000), 0x00), + 'Sanctuary Grave': ([0xDB85E], None), + 'Hookshot Fairy': (0x4F, (0x010c, 0x05, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0d78, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Pyramid Fairy': (0x62, (0x0116, 0x5b, 0x0b1e, 0x0754, 0x06fa, 0x07a7, 0x0778, 0x07c3, 0x077f, 0x0a, 0xf6, 0x0000, 0x0000), 0x02), + 'East Dark World Hint': (0x68, (0x010e, 0x6f, 0x06a0, 0x0aca, 0x0f00, 0x0b18, 0x0fa8, 0x0b37, 0x0f85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Palace of Darkness Hint': (0x67, (0x011a, 0x5e, 0x0c24, 0x0794, 0x0d12, 0x07e8, 0x0d90, 0x0803, 0x0d97, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark Lake Hylia Fairy': (0x6C, (0x0115, 0x6e, 0x0016, 0x0a00, 0x0cb6, 0x0a36, 0x0d28, 0x0a6d, 0x0d33, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Dark Lake Hylia Ledge Fairy': (0x80, (0x0115, 0x77, 0x0080, 0x0c00, 0x0e00, 0x0c37, 0x0e48, 0x0c6f, 0x0e7d, 0x00, 0x00, 0x0000, 0x0000), 0x02), + 'Dark Lake Hylia Ledge Spike Cave': (0x7B, (0x0125, 0x77, 0x0200, 0x0c27, 0x0e00, 0x0c86, 0x0e68, 0x0c96, 0x0e7d, 0x09, 0xf7, 0x0000, 0x0000), 0x20), + 'Dark Lake Hylia Ledge Hint': (0x69, (0x010e, 0x77, 0x0084, 0x0c00, 0x0e26, 0x0c36, 0x0e98, 0x0c6f, 0x0ea3, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Hype Cave': (0x3C, (0x011e, 0x74, 0x00a0, 0x0c0a, 0x0900, 0x0c58, 0x0988, 0x0c77, 0x097d, 0x06, 0xfa, 0x0000, 0x0000), 0x02), + 'Bonk Fairy (Dark)': (0x77, (0x0126, 0x6b, 0x00a0, 0x0a05, 0x0700, 0x0a66, 0x0788, 0x0a72, 0x0785, 0x0b, 0xf5, 0x0000, 0x0000), 0x20), + 'Brewery': (0x47, (0x0106, 0x58, 0x16a8, 0x08e4, 0x013e, 0x0938, 0x01b8, 0x0953, 0x01c3, 0x0a, 0xf6, 0x1AB6, 0x0000), 0x02), + 'C-Shaped House': (0x53, (0x011c, 0x58, 0x09d8, 0x0744, 0x02ce, 0x0797, 0x0348, 0x07b3, 0x0353, 0x0a, 0xf6, 0x0DE8, 0x0000), 0x00), + 'Chest Game': (0x46, (0x0106, 0x58, 0x078a, 0x0705, 0x004e, 0x0758, 0x00c8, 0x0774, 0x00d3, 0x09, 0xf7, 0x0B98, 0x0000), 0x00), + 'Dark World Hammer Peg Cave': (0x7E, (0x0127, 0x62, 0x0894, 0x091e, 0x0492, 0x09a6, 0x0508, 0x098b, 0x050f, 0x00, 0x00, 0x0000, 0x0000), 0x20), + 'Red Shield Shop': (0x74, (0x0110, 0x5a, 0x079a, 0x06e8, 0x04d6, 0x0738, 0x0548, 0x0755, 0x0553, 0x08, 0xf8, 0x0AA8, 0x0000), 0x00), + 'Dark Sanctuary Hint': (0x59, (0x0112, 0x53, 0x001e, 0x0400, 0x06e2, 0x0446, 0x0758, 0x046d, 0x075f, 0x00, 0x00, 0x0000, 0x0000), 0x00), + 'Fortune Teller (Dark)': (0x65, (0x0122, 0x51, 0x0610, 0x04b4, 0x027e, 0x0507, 0x02f8, 0x0523, 0x0303, 0x0a, 0xf6, 0x091E, 0x0000), 0x00), + 'Dark World Shop': (0x5F, (0x010f, 0x58, 0x1058, 0x0814, 0x02be, 0x0868, 0x0338, 0x0883, 0x0343, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark World Lumberjack Shop': (0x56, (0x010f, 0x42, 0x041c, 0x0074, 0x04e2, 0x00c7, 0x0558, 0x00e3, 0x055f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Dark World Potion Shop': (0x6E, (0x010f, 0x56, 0x080e, 0x04f4, 0x0c66, 0x0548, 0x0cd8, 0x0563, 0x0ce3, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Archery Game': (0x58, (0x0111, 0x69, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00), + 'Mire Shed': (0x5E, (0x010d, 0x70, 0x0384, 0x0c69, 0x001e, 0x0cb6, 0x0098, 0x0cd6, 0x00a3, 0x07, 0xf9, 0x0000, 0x0000), 0x00), + 'Dark Desert Hint': (0x61, (0x0114, 0x70, 0x0654, 0x0cc5, 0x02aa, 0x0d16, 0x0328, 0x0d32, 0x032f, 0x09, 0xf7, 0x0000, 0x0000), 0x00), + 'Dark Desert Fairy': (0x55, (0x0115, 0x70, 0x03a8, 0x0c6a, 0x013a, 0x0cb7, 0x01b8, 0x0cd7, 0x01bf, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Spike Cave': (0x40, (0x0117, 0x43, 0x0ed4, 0x01e4, 0x08aa, 0x0236, 0x0928, 0x0253, 0x092f, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Cave Shop (Dark Death Mountain)': (0x6D, (0x0112, 0x45, 0x0ee0, 0x01e3, 0x0d00, 0x0236, 0x0daa, 0x0252, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Dark Death Mountain Fairy': (0x6F, (0x0115, 0x43, 0x1400, 0x0294, 0x0600, 0x02e8, 0x0678, 0x0303, 0x0685, 0x0a, 0xf6, 0x0000, 0x0000), 0x00), + 'Mimic Cave': (0x4E, (0x010c, 0x05, 0x07e0, 0x0103, 0x0d00, 0x0156, 0x0d78, 0x0172, 0x0d7d, 0x0b, 0xf5, 0x0000, 0x0000), 0x00), + 'Big Bomb Shop': (0x52, (0x011c, 0x6c, 0x0506, 0x0a9a, 0x0832, 0x0ae7, 0x08b8, 0x0b07, 0x08bf, 0x06, 0xfa, 0x0816, 0x0000), 0x00), + 'Dark Lake Hylia Shop': (0x73, (0x010f, 0x75, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Lumberjack House': (0x75, (0x011f, 0x02, 0x049c, 0x0088, 0x04e6, 0x00d8, 0x0558, 0x00f7, 0x0563, 0x08, 0xf8, 0x07AA, 0x0000), 0x00), + 'Lake Hylia Fortune Teller': (0x72, (0x0122, 0x35, 0x0380, 0x0c6a, 0x0a00, 0x0cb8, 0x0a58, 0x0cd7, 0x0a85, 0x06, 0xfa, 0x0000, 0x0000), 0x00), + 'Kakariko Gamble Game': (0x66, (0x0118, 0x29, 0x069e, 0x0ac4, 0x02ea, 0x0b18, 0x0368, 0x0b33, 0x036f, 0x0a, 0xf6, 0x09AC, 0x0000), 0x00)} # format: # Key=Name # value = entrance # # | (entrance #, exit #) exit_ids = {'Links House Exit': (0x01, 0x00), - 'Inverted Links House Exit': (0x01, 0x00), 'Chris Houlihan Room Exit': (None, 0x3D), 'Desert Palace Exit (South)': (0x09, 0x0A), 'Desert Palace Exit (West)': (0x0B, 0x0C), @@ -2750,7 +2385,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Hyrule Castle Exit (West)': (0x03, 0x02), 'Hyrule Castle Exit (East)': (0x05, 0x04), 'Agahnims Tower Exit': (0x24, 0x25), - 'Inverted Agahnims Tower Exit': (0x24, 0x25), 'Thieves Town Exit': (0x34, 0x35), 'Skull Woods First Section Exit': (0x2A, 0x2B), 'Skull Woods Second Section Exit (East)': (0x29, 0x2A), @@ -2798,7 +2432,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Hookshot Cave Front Exit': (0x3A, 0x3B), 'Hookshot Cave Back Exit': (0x3B, 0x3C), 'Ganons Tower Exit': (0x37, 0x38), - 'Inverted Ganons Tower Exit': (0x37, 0x38), 'Pyramid Exit': (0x36, 0x37), 'Waterfall of Wishing': 0x5C, 'Dam': 0x4E, @@ -2850,7 +2483,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'East Dark World Hint': 0x69, 'Palace of Darkness Hint': 0x68, 'Big Bomb Shop': 0x53, - 'Inverted Big Bomb Shop': 0x53, 'Village of Outcasts Shop': 0x60, 'Dark Lake Hylia Shop': 0x60, 'Dark World Lumberjack Shop': 0x60, @@ -2864,7 +2496,6 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Dark World Hammer Peg Cave': 0x83, 'Red Shield Shop': 0x57, 'Dark Sanctuary Hint': 0x5A, - 'Inverted Dark Sanctuary': 0x5A, 'Fortune Teller (Dark)': 0x66, 'Archery Game': 0x59, 'Mire Shed': 0x5F, @@ -2883,137 +2514,3 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Skull Pinball': 0x78, 'Skull Pot Circle': 0x76, 'Pyramid': 0x7B} - -ow_prize_table = {'Links House': (0x8b1, 0xb2d), 'Inverted Big Bomb Shop': (0x8b1, 0xb2d), - 'Desert Palace Entrance (South)': (0x108, 0xd70), 'Desert Palace Entrance (West)': (0x031, 0xca0), - 'Desert Palace Entrance (North)': (0x0e1, 0xba0), 'Desert Palace Entrance (East)': (0x191, 0xca0), - 'Eastern Palace': (0xf31, 0x620), 'Tower of Hera': (0x8D0, 0x080), - 'Hyrule Castle Entrance (South)': (0x7b0, 0x730), 'Hyrule Castle Entrance (West)': (0x700, 0x640), - 'Hyrule Castle Entrance (East)': (0x8a0, 0x640), 'Inverted Pyramid Entrance': (0x720, 0x700), - 'Agahnims Tower': (0x7e0, 0x640), 'Inverted Ganons Tower': (0x7e0, 0x640), - 'Thieves Town': (0x1d0, 0x780), 'Skull Woods First Section Door': (0x240, 0x280), - 'Skull Woods Second Section Door (East)': (0x1a0, 0x240), - 'Skull Woods Second Section Door (West)': (0x0c0, 0x1c0), 'Skull Woods Final Section': (0x082, 0x0b0), - 'Ice Palace': (0xca0, 0xda0), - 'Misery Mire': (0x100, 0xca0), - 'Palace of Darkness': (0xf40, 0x620), 'Swamp Palace': (0x759, 0xED0), - 'Turtle Rock': (0xf11, 0x103), - 'Dark Death Mountain Ledge (West)': (0xb80, 0x180), - 'Dark Death Mountain Ledge (East)': (0xc80, 0x180), - 'Turtle Rock Isolated Ledge Entrance': (0xc00, 0x240), - 'Hyrule Castle Secret Entrance Stairs': (0x850, 0x700), - 'Kakariko Well Cave': (0x060, 0x680), - 'Bat Cave Cave': (0x540, 0x8f0), - 'Elder House (East)': (0x2b0, 0x6a0), - 'Elder House (West)': (0x230, 0x6a0), - 'North Fairy Cave': (0xa80, 0x440), - 'Lost Woods Hideout Stump': (0x240, 0x280), - 'Lumberjack Tree Cave': (0x4e0, 0x004), - 'Two Brothers House (East)': (0x200, 0x0b60), - 'Two Brothers House (West)': (0x180, 0x0b60), - 'Sanctuary': (0x720, 0x4a0), - 'Old Man Cave (West)': (0x580, 0x2c0), - 'Old Man Cave (East)': (0x620, 0x2c0), - 'Old Man House (Bottom)': (0x720, 0x320), - 'Old Man House (Top)': (0x820, 0x220), - 'Death Mountain Return Cave (East)': (0x600, 0x220), - 'Death Mountain Return Cave (West)': (0x500, 0x1c0), - 'Spectacle Rock Cave Peak': (0x720, 0x0a0), - 'Spectacle Rock Cave': (0x790, 0x1a0), - 'Spectacle Rock Cave (Bottom)': (0x710, 0x0a0), - 'Paradox Cave (Bottom)': (0xd80, 0x180), - 'Paradox Cave (Middle)': (0xd80, 0x380), - 'Paradox Cave (Top)': (0xd80, 0x020), - 'Fairy Ascension Cave (Bottom)': (0xcc8, 0x2a0), - 'Fairy Ascension Cave (Top)': (0xc00, 0x240), - 'Spiral Cave': (0xb80, 0x180), - 'Spiral Cave (Bottom)': (0xb80, 0x2c0), - 'Bumper Cave (Bottom)': (0x580, 0x2c0), - 'Bumper Cave (Top)': (0x500, 0x1c0), - 'Superbunny Cave (Top)': (0xd80, 0x020), - 'Superbunny Cave (Bottom)': (0xd00, 0x180), - 'Hookshot Cave': (0xc80, 0x0c0), - 'Hookshot Cave Back Entrance': (0xcf0, 0x004), - 'Ganons Tower': (0x8D0, 0x080), - 'Inverted Agahnims Tower': (0x8D0, 0x080), - 'Pyramid Entrance': (0x640, 0x7c0), - 'Skull Woods First Section Hole (West)': None, - 'Skull Woods First Section Hole (East)': None, - 'Skull Woods First Section Hole (North)': None, - 'Skull Woods Second Section Hole': None, - 'Pyramid Hole': None, - 'Inverted Pyramid Hole': None, - 'Waterfall of Wishing': (0xe80, 0x280), - 'Dam': (0x759, 0xED0), - 'Blinds Hideout': (0x190, 0x6c0), - 'Hyrule Castle Secret Entrance Drop': None, - 'Bonk Fairy (Light)': (0x740, 0xa80), - 'Lake Hylia Fairy': (0xd40, 0x9f0), - 'Light Hype Fairy': (0x940, 0xc80), - 'Desert Fairy': (0x420, 0xe00), - 'Kings Grave': (0x920, 0x520), - 'Tavern North': (0x270, 0x900), - 'Chicken House': (0x120, 0x880), - 'Aginahs Cave': (0x2e0, 0xd00), - 'Sahasrahlas Hut': (0xcf0, 0x6c0), - 'Cave Shop (Lake Hylia)': (0xbc0, 0xc00), - 'Capacity Upgrade': (0xca0, 0xda0), - 'Kakariko Well Drop': None, - 'Blacksmiths Hut': (0x4a0, 0x880), - 'Bat Cave Drop': None, - 'Sick Kids House': (0x220, 0x880), - 'North Fairy Cave Drop': None, - 'Lost Woods Gamble': (0x240, 0x080), - 'Fortune Teller (Light)': (0x2c0, 0x4c0), - 'Snitch Lady (East)': (0x310, 0x7a0), - 'Snitch Lady (West)': (0x800, 0x7a0), - 'Bush Covered House': (0x2e0, 0x880), - 'Tavern (Front)': (0x270, 0x980), - 'Light World Bomb Hut': (0x070, 0x980), - 'Kakariko Shop': (0x170, 0x980), - 'Lost Woods Hideout Drop': None, - 'Lumberjack Tree Tree': None, - 'Cave 45': (0x440, 0xca0), 'Graveyard Cave': (0x8f0, 0x430), - 'Checkerboard Cave': (0x260, 0xc00), - 'Mini Moldorm Cave': (0xa40, 0xe80), - 'Long Fairy Cave': (0xf60, 0xb00), - 'Good Bee Cave': (0xec0, 0xc00), - '20 Rupee Cave': (0xe80, 0xca0), - '50 Rupee Cave': (0x4d0, 0xed0), - 'Ice Rod Cave': (0xe00, 0xc00), - 'Bonk Rock Cave': (0x5f0, 0x460), - 'Library': (0x270, 0xaa0), - 'Potion Shop': (0xc80, 0x4c0), - 'Sanctuary Grave': None, - 'Hookshot Fairy': (0xd00, 0x180), - 'Pyramid Fairy': (0x740, 0x740), - 'East Dark World Hint': (0xf60, 0xb00), - 'Palace of Darkness Hint': (0xd60, 0x7c0), - 'Dark Lake Hylia Fairy': (0xd40, 0x9f0), - 'Dark Lake Hylia Ledge Fairy': (0xe00, 0xc00), - 'Dark Lake Hylia Ledge Spike Cave': (0xe80, 0xca0), - 'Dark Lake Hylia Ledge Hint': (0xec0, 0xc00), - 'Hype Cave': (0x940, 0xc80), - 'Bonk Fairy (Dark)': (0x740, 0xa80), - 'Brewery': (0x170, 0x980), 'C-Shaped House': (0x310, 0x7a0), 'Chest Game': (0x800, 0x7a0), - 'Dark World Hammer Peg Cave': (0x4c0, 0x940), - 'Red Shield Shop': (0x500, 0x680), - 'Dark Sanctuary Hint': (0x720, 0x4a0), - 'Inverted Dark Sanctuary': (0x720, 0x4a0), - 'Fortune Teller (Dark)': (0x2c0, 0x4c0), - 'Dark World Shop': (0x2e0, 0x880), - 'Dark World Lumberjack Shop': (0x4e0, 0x0d0), - 'Dark World Potion Shop': (0xc80, 0x4c0), - 'Archery Game': (0x2f0, 0xaf0), - 'Mire Shed': (0x060, 0xc90), - 'Dark Desert Hint': (0x2e0, 0xd00), - 'Dark Desert Fairy': (0x1c0, 0xc90), - 'Spike Cave': (0x860, 0x180), - 'Cave Shop (Dark Death Mountain)': (0xd80, 0x180), - 'Dark Death Mountain Fairy': (0x620, 0x2c0), - 'Mimic Cave': (0xc80, 0x180), - 'Big Bomb Shop': (0x8b1, 0xb2d), 'Inverted Links House': (0x8b1, 0xb2d), - 'Dark Lake Hylia Shop': (0xa40, 0xc40), - 'Lumberjack House': (0x4e0, 0x0d0), - 'Lake Hylia Fortune Teller': (0xa40, 0xc40), - 'Kakariko Gamble Game': (0x2f0, 0xaf0)} From bb3b51f1d6c8049a77f8e5bcdb6155e900553b9e Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sun, 26 Feb 2023 14:04:21 -0600 Subject: [PATCH 146/146] Version bump 0.3.0.0 --- CHANGELOG.md | 6 ++++++ OverworldShuffle.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5301933..48a0a29b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.3.0.0 +- Merged in all DR Customizer features since its initial release up to v1.2.0.9 +- Major revamp of Aerinon's ER 2.0 to better support OWR modes +- Fixed various incorrect logic issues (Inverted flute spots, Bomb Shop start, etc) +- Flute is disabled in rain state except glitched modes + ## 0.2.11.4 - Fixed broken OWG logic issues - Gave chickens a base price for shopsanity diff --git a/OverworldShuffle.py b/OverworldShuffle.py index d916d711..c73c5ea6 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -7,7 +7,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType from OverworldGlitchRules import create_owg_connections from Utils import bidict -version_number = '0.2.11.4' +version_number = '0.3.0.0' # branch indicator is intentionally different across branches version_branch = '-u'

    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�CwkiY2o)~5RVhA%BtYbJs0 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�fo`KGcTj$F9tWBTnhFJ}m7j{RfX-7g2! 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