From c3c6cabea69dee1cf45bf4004d19ff527a79e47c Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sat, 24 Oct 2020 09:57:27 +1100 Subject: [PATCH 1/3] Find accessible entrances for key logic and later steps by exploring the entire world including other dungeons. Dungeon generation will still use the old method, since it needs to dynamically change as dungeons are added. --- DoorShuffle.py | 77 +++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index b4b91adb..88f93941 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -136,39 +136,20 @@ def vanilla_key_logic(world, player): world.dungeon_layouts[player][builder.name] = builder overworld_prep(world, player) - entrances_map, potentials, connections = determine_entrance_list(world, player) - - enabled_entrances = {} - sector_queue = deque(builders) - last_key, loops = None, 0 - while len(sector_queue) > 0: - builder = sector_queue.popleft() - - split_dungeon = builder.name.startswith('Desert Palace') or builder.name.startswith('Skull Woods') - origin_list = list(entrances_map[builder.name]) - find_enabled_origins(builder.sectors, enabled_entrances, origin_list, entrances_map, builder.name) - 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 Exception('Infinite loop detected for "%s" located at %s' % (builder.name, origin_name)) - sector_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('').warning('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 - log_key_logic(builder.name, key_layout.key_logic) - last_key = None + for builder in builders: + origin_list = find_accessible_entrances(world, player, default_dungeon_entrances[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('').warning('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 + log_key_logic(builder.name, key_layout.key_logic) if world.shuffle[player] == 'vanilla' and world.accessibility[player] == 'items' and not world.retro[player]: validate_vanilla_key_logic(world, player) @@ -391,8 +372,7 @@ def main_dungeon_generation(dungeon_builders, recombinant_builders, connections_ combine_layouts(recombinant_builders, dungeon_builders, entrances_map) world.dungeon_layouts[player] = {} for builder in dungeon_builders.values(): - find_enabled_origins([builder.master_sector], enabled_entrances, builder.layout_starts, entrances_map, builder.name) - builder.path_entrances = entrances_map[builder.name] + builder.entrance_list = builder.layout_starts = builder.path_entrances = find_accessible_entrances(world, player, builder.all_entrances) world.dungeon_layouts[player] = dungeon_builders @@ -1165,6 +1145,33 @@ def find_inaccessible_regions(world, player): logger.debug('%s', r) +def find_accessible_entrances(world, player, entrances): + if world.mode[player] != 'inverted': + start_regions = ['Links House', 'Sanctuary'] + else: + start_regions = ['Inverted Links House', 'Inverted Dark Sanctuary'] + regs = convert_regions(start_regions, world, player) + visited_regions = set() + visited_entrances = [] + queue = deque(regs) + while len(queue) > 0: + next_region = queue.popleft() + visited_regions.add(next_region) + if world.mode[player] == 'inverted' and next_region.name == 'Tower Agahnim 1': + connect = world.get_region('Hyrule Castle Ledge', player) + if connect not in queue and connect not in visited_regions: + queue.append(connect) + for ext in next_region.exits: + connect = ext.connected_region + if connect is None or ext.door and ext.door.blocked: + continue + if connect.name in entrances: + visited_entrances.append(connect.name) + elif connect and connect not in queue and connect not in visited_regions: + queue.append(connect) + return visited_entrances + + def valid_inaccessible_region(r): return r.type is not RegionType.Cave or (len(r.exits) > 0 and r.name not in ['Links House', 'Chris Houlihan Room']) From 8f2b068313710462d7aa3195e00375ab6d58bf2d Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Mon, 26 Oct 2020 18:01:19 +1100 Subject: [PATCH 2/3] Refine hints for crossed dungeon shuffle regardless of the hints setting, since they are also used for the Ganon silvers hint. Move Hera Basement to the list of inconvenient dungeon locations to exclude it from crossed shuffle. --- DoorShuffle.py | 3 +-- Dungeons.py | 4 ++-- Rom.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index b4b91adb..8134f73b 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -545,8 +545,7 @@ def cross_dungeon(world, player): reassign_boss('GT Lanmolas 2', 'middle', builder, gt, world, player) reassign_boss('GT Moldorm', 'top', builder, gt, world, player) - if world.hints[player]: - refine_hints(dungeon_builders) + refine_hints(dungeon_builders) def assign_cross_keys(dungeon_builders, world, player): diff --git a/Dungeons.py b/Dungeons.py index b85b6b61..007392f5 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -390,9 +390,9 @@ dungeon_hints = { 'Tower of Hera': 'in Tower of Hera', 'Agahnims Tower': 'in Castle Tower', 'Palace of Darkness': 'in Palace of Darkness', - 'Swamp Palace': 'in Swamp Palace)', + 'Swamp Palace': 'in Swamp Palace', 'Skull Woods': 'in Skull Woods', - 'Thieves Town': 'in Thieves\' Town)', + 'Thieves Town': 'in Thieves\' Town', 'Ice Palace': 'in Ice Palace', 'Misery Mire': 'in Misery Mire', 'Turtle Rock': 'in Turtle Rock', diff --git a/Rom.py b/Rom.py index f967e00a..3af7222f 100644 --- a/Rom.py +++ b/Rom.py @@ -2358,12 +2358,12 @@ HintLocations = ['telepathic_tile_eastern_palace', InconvenientLocations = ['Spike Cave', 'Sahasrahla', 'Purple Chest', - 'Tower of Hera - Big Key Chest', 'Magic Bat'] InconvenientDungeonLocations = ['Swamp Left', 'Mire Left', 'Eastern Palace - Big Key Chest', + 'Tower of Hera - Big Key Chest', 'Thieves\' Town - Big Chest', 'Ice Palace - Big Chest', 'Ganons Tower - Big Chest'] From 62d7ae0327f8cfee2abe9e233c45b6778d25a873 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 27 Oct 2020 11:39:24 -0600 Subject: [PATCH 3/3] Version bump - auto-assign reviewers to PRs --- .github/auto-assign.yml | 17 +++++++++++++++++ Main.py | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .github/auto-assign.yml diff --git a/.github/auto-assign.yml b/.github/auto-assign.yml new file mode 100644 index 00000000..1e876e88 --- /dev/null +++ b/.github/auto-assign.yml @@ -0,0 +1,17 @@ +# Set to true to add reviewers to pull requests +addReviewers: true + +# Set to true to add assignees to pull requests +addAssignees: true + +# A list of reviewers to be added to pull requests (GitHub user name) +reviewers: + - aerinon + +# A list of keywords to be skipped the process that add reviewers if pull requests include it +skipKeywords: + - wip + +# A number of reviewers added to the pull request +# Set 0 to add all the reviewers (default: 0) +numberOfReviewers: 0 \ No newline at end of file diff --git a/Main.py b/Main.py index f5696e3c..a80713cb 100644 --- a/Main.py +++ b/Main.py @@ -24,7 +24,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute from ItemList import generate_itempool, difficulties, fill_prizes from Utils import output_path, parse_player_names -__version__ = '0.1.0-dev' +__version__ = '0.1.1-dev' class EnemizerError(RuntimeError): pass