diff --git a/.gitignore b/.gitignore index d6649e6d..ebaefc6a 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ weights/ /MultiMystery/ /Players/ /QUsb2Snes/ +/tests resources/user/* !resources/user/.gitkeep diff --git a/DoorShuffle.py b/DoorShuffle.py index cae9b651..b20a8237 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -1986,6 +1986,7 @@ logical_connections = [ ('Desert Main Lobby Right Path', 'Desert Right Alcove'), ('Desert Left Alcove Path', 'Desert Main Lobby'), ('Desert Right Alcove Path', 'Desert Main Lobby'), + ('Hera Lobby to Front Barrier - Blue', 'Hera Front'), ('Hera Front to Lobby Barrier - Blue', 'Hera Lobby'), ('Hera Lobby to Crystal', 'Hera Lobby Crystal'), @@ -1996,16 +1997,22 @@ logical_connections = [ ('Hera Front to Up Stairs Barrier - Orange', 'Hera Up Stairs Landing'), ('Hera Front to Back Barrier - Orange', 'Hera Back'), ('Hera Down Stairs to Front Barrier - Blue', 'Hera Front'), + ('Hera Down Stairs Landing to Ranged Crystal', 'Hera Down Stairs Landing - Ranged Crystal'), + ('Hera Down Stairs Landing Ranged Crystal Exit', 'Hera Down Stairs Landing'), ('Hera Up Stairs to Front Barrier - Orange', 'Hera Front'), + ('Hera Up Stairs Landing to Ranged Crystal', 'Hera Up Stairs Landing - Ranged Crystal'), + ('Hera Up Stairs Landing Ranged Crystal Exit', 'Hera Up Stairs Landing'), ('Hera Back to Front Barrier - Orange', 'Hera Front'), + ('Hera Back to Ranged Crystal', 'Hera Back - Ranged Crystal'), + ('Hera Back Ranged Crystal Exit', 'Hera Back'), ('Hera Big Chest Hook Path', 'Hera Big Chest Landing'), ('Hera Big Chest Landing Exit', 'Hera 4F'), + ('PoD Pit Room Block Path N', 'PoD Pit Room Blocked'), ('PoD Pit Room Block Path S', 'PoD Pit Room'), ('PoD Arena Landing Bonk Path', 'PoD Arena Bridge'), ('PoD Arena North Drop Down', 'PoD Arena Main'), ('PoD Arena Bridge Drop Down', 'PoD Arena Main'), - ('PoD Arena North to Landing Barrier - Orange', 'PoD Arena Landing'), ('PoD Arena Main to Ranged Crystal', 'PoD Arena Main - Ranged Crystal'), ('PoD Arena Main to Landing Barrier - Blue', 'PoD Arena Landing'), diff --git a/Doors.py b/Doors.py index 9f4dbbfc..184520d7 100644 --- a/Doors.py +++ b/Doors.py @@ -260,10 +260,16 @@ def create_doors(world, player): create_door(player, 'Hera Front Crystal Exit', Lgcl), create_door(player, 'Hera Front to Down Stairs Barrier - Blue', Lgcl), create_door(player, 'Hera Down Stairs to Front Barrier - Blue', Lgcl), + create_door(player, 'Hera Down Stairs Landing to Ranged Crystal', Lgcl), + create_door(player, 'Hera Down Stairs Landing Ranged Crystal Exit', Lgcl), create_door(player, 'Hera Front to Up Stairs Barrier - Orange', Lgcl), create_door(player, 'Hera Up Stairs to Front Barrier - Orange', Lgcl), + create_door(player, 'Hera Up Stairs Landing to Ranged Crystal', Lgcl), + create_door(player, 'Hera Up Stairs Landing Ranged Crystal Exit', Lgcl), create_door(player, 'Hera Front to Back Barrier - Orange', Lgcl), create_door(player, 'Hera Back to Front Barrier - Orange', Lgcl), + create_door(player, 'Hera Back to Ranged Crystal', Lgcl), + create_door(player, 'Hera Back Ranged Crystal Exit', Lgcl), create_door(player, 'Hera Lobby Down Stairs', Sprl).dir(Dn, 0x77, 3, HTL).ss(Z, 0x21, 0x90, False, True), create_door(player, 'Hera Lobby Key Stairs', Sprl).dir(Dn, 0x77, 1, HTL).ss(A, 0x12, 0x80).small_key().pos(1), create_door(player, 'Hera Lobby Up Stairs', Sprl).dir(Up, 0x77, 2, HTL).ss(X, 0x2b, 0x5c, False, True), @@ -1198,10 +1204,13 @@ def create_doors(world, player): world.get_door('Hera Front Crystal Exit', player).c_switch() world.get_door('Hera Front to Down Stairs Barrier - Blue', player).barrier(CrystalBarrier.Blue) world.get_door('Hera Down Stairs to Front Barrier - Blue', player).barrier(CrystalBarrier.Blue) + world.get_door('Hera Down Stairs Landing Ranged Crystal Exit', player).c_switch() world.get_door('Hera Front to Up Stairs Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('Hera Up Stairs to Front Barrier - Orange', player).barrier(CrystalBarrier.Orange) + world.get_door('Hera Up Stairs Landing Ranged Crystal Exit', player).c_switch() world.get_door('Hera Front to Back Barrier - Orange', player).barrier(CrystalBarrier.Orange) world.get_door('Hera Back to Front Barrier - Orange', player).barrier(CrystalBarrier.Orange) + world.get_door('Hera Back Ranged Crystal Exit', player).c_switch() world.get_door('Hera Basement Cage Up Stairs', player).c_switch() world.get_door('Hera Tile Room Up Stairs', player).c_switch() world.get_door('Hera Tile Room EN', player).c_switch() @@ -1259,7 +1268,6 @@ def create_doors(world, player): world.get_door('Thieves Triple Bypass EN', player).barrier(CrystalBarrier.Blue) world.get_door('Thieves Hellway Orange Barrier', player).barrier(CrystalBarrier.Orange) world.get_door('Thieves Hellway Crystal Orange Barrier', player).barrier(CrystalBarrier.Orange) - world.get_door('Thieves Hellway Crystal Orange Barrier', player).barrier(CrystalBarrier.Orange) world.get_door('Thieves Attic Orange Barrier', player).barrier(CrystalBarrier.Orange) world.get_door('Thieves Attic Hint Orange Barrier', player).barrier(CrystalBarrier.Orange) diff --git a/DungeonGenerator.py b/DungeonGenerator.py index d14715b2..c088370d 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -1631,7 +1631,7 @@ def ensure_crystal_switches_reachable(dungeon_map, crystal_switches, polarized_s valid, sector, which_list = False, None, None while not valid: if len(candidates) <= 0: - raise GenerationException(f'need to provide more sophisticatedted crystal connection for {entrance_sector}') + raise GenerationException(f'need to provide more sophisticated crystal connection for {entrance_sector}') sector, which_list = random.choice(list(candidates.items())) del candidates[sector] valid = global_pole.is_valid_choice(dungeon_map, builder, [sector]) diff --git a/Dungeons.py b/Dungeons.py index 5490cbbd..82de5e27 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -195,8 +195,9 @@ desert_regions = [ ] hera_regions = [ - 'Hera Lobby', 'Hera Lobby Crystal', 'Hera Front', 'Hera Back', 'Hera Front Crystal', 'Hera Down Stairs Landing', 'Hera Up Stairs Landing', - 'Hera Basement Cage', 'Hera Tile Room', 'Hera Tridorm', 'Hera Torches', 'Hera Beetles', + 'Hera Lobby', 'Hera Lobby Crystal', 'Hera Front', 'Hera Back', 'Hera Front Crystal', 'Hera Down Stairs Landing', + 'Hera Down Stairs Landing - Ranged Crystal', 'Hera Up Stairs Landing', 'Hera Up Stairs Landing - Ranged Crystal', + 'Hera Back - Ranged Crystal', 'Hera Basement Cage', 'Hera Tile Room', 'Hera Tridorm', 'Hera Torches', 'Hera Beetles', 'Hera Startile Corner', 'Hera Startile Wide', 'Hera 4F', 'Hera Big Chest Landing', 'Hera 5F', 'Hera Fairies', 'Hera Boss', 'Hera Portal' ] diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 3718d0a3..8a00acc2 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2271,7 +2271,7 @@ Cave_Exits_Base = [['Elder House Exit (East)', 'Elder 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 Exit (South)', 'Hookshot Cave Back Exit']] + ['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']] Cave_Exits_Base += [('Superbunny Cave Exit (Bottom)', 'Superbunny Cave Exit (Top)'), ('Spiral Cave Exit (Top)', 'Spiral Cave Exit')] @@ -3254,10 +3254,8 @@ default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing'), ('Superbunny Cave Exit (Bottom)', 'Dark Death Mountain (East Bottom)'), ('Hookshot Cave Exit (South)', 'Dark Death Mountain (Top)'), - ('Hookshot Cave Bombable Wall', 'Hookshot Cave Back'), - ('Hookshot Cave Back Exit', 'Death Mountain Floating Island (Dark World)'), - ('Hookshot Cave Back Bombable Wall', 'Hookshot Cave'), - ('Hookshot Cave Back Entrance', 'Hookshot Cave Back'), + ('Hookshot Cave Exit (North)', 'Death Mountain Floating Island (Dark World)'), + ('Hookshot Cave Back Entrance', 'Hookshot Cave'), ('Mimic Cave', 'Mimic Cave'), @@ -3388,10 +3386,8 @@ inverted_default_connections = [('Waterfall of Wishing', 'Waterfall of Wishing' ('Cave Shop (Dark Death Mountain)', 'Cave Shop (Dark Death Mountain)'), ('Superbunny Cave (Bottom)', 'Superbunny Cave'), ('Superbunny Cave Exit (Bottom)', 'Dark Death Mountain (East Bottom)'), - ('Hookshot Cave Bombable Wall', 'Hookshot Cave Back'), - ('Hookshot Cave Back Bombable Wall', 'Hookshot Cave'), - ('Hookshot Cave Back Exit', 'Death Mountain Floating Island (Dark World'), - ('Hookshot Cave Back Entrance', 'Hookshot Cave Back'), + ('Hookshot Cave Exit (North)', 'Death Mountain Floating Island (Dark World)'), + ('Hookshot Cave Back Entrance', 'Hookshot Cave'), ('Mimic Cave', 'Mimic Cave'), ('Inverted Pyramid Hole', 'Pyramid'), ('Inverted Links House', 'Inverted Links House'), @@ -3761,7 +3757,7 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Superbunny Cave Exit (Top)': (0x14, 0x15), 'Superbunny Cave Exit (Bottom)': (0x13, 0x14), 'Hookshot Cave Exit (South)': (0x3A, 0x3B), - 'Hookshot Cave Back Exit': (0x3B, 0x3C), + 'Hookshot Cave Exit (North)': (0x3B, 0x3C), 'Ganons Tower Exit': (0x37, 0x38), 'Inverted Ganons Tower Exit': (0x37, 0x38), 'Pyramid Exit': (0x36, 0x37), diff --git a/InvertedRegions.py b/InvertedRegions.py index c911d4e9..71c26fc9 100644 --- a/InvertedRegions.py +++ b/InvertedRegions.py @@ -197,8 +197,7 @@ def create_inverted_regions(world, player): ['Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)']), create_cave_region(player, 'Spike Cave', 'Spike Cave', ['Spike Cave']), create_cave_region(player, 'Hookshot Cave', 'a connector', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'], - ['Hookshot Cave Exit (South)', 'Hookshot Cave Bombable Wall']), - create_cave_region(player, 'Hookshot Cave Back', 'a connector', None, ['Hookshot Cave Back Exit', 'Hookshot Cave Back Bombable Wall']), + ['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']), create_dw_region(player, 'Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance']), create_cave_region(player, 'Mimic Cave', 'Mimic Cave', ['Mimic Cave']), diff --git a/Regions.py b/Regions.py index 7233336d..5c646f5f 100644 --- a/Regions.py +++ b/Regions.py @@ -187,8 +187,7 @@ def create_regions(world, player): ['Superbunny Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)']), create_cave_region(player, 'Spike Cave', 'Spike Cave', ['Spike Cave']), create_cave_region(player, 'Hookshot Cave', 'a connector', ['Hookshot Cave - Top Right', 'Hookshot Cave - Top Left', 'Hookshot Cave - Bottom Right', 'Hookshot Cave - Bottom Left'], - ['Hookshot Cave Exit (South)', 'Hookshot Cave Bombable Wall']), - create_cave_region(player, 'Hookshot Cave Back', 'a connector', None, ['Hookshot Cave Back Exit', 'Hookshot Cave Back Bombable Wall']), + ['Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)']), create_dw_region(player, 'Death Mountain Floating Island (Dark World)', None, ['Floating Island Drop', 'Hookshot Cave Back Entrance', 'Floating Island Mirror Spot']), create_lw_region(player, 'Death Mountain Floating Island (Light World)', ['Floating Island']), create_dw_region(player, 'Turtle Rock (Top)', None, ['Turtle Rock Drop']), @@ -342,9 +341,12 @@ def create_dungeon_regions(world, player): create_dungeon_region(player, 'Hera Lobby Crystal', 'Tower of Hera', None, ['Hera Lobby Crystal Exit']), create_dungeon_region(player, 'Hera Front', 'Tower of Hera', None, ['Hera Front to Crystal', 'Hera Front to Lobby Barrier - Blue', 'Hera Front to Down Stairs Barrier - Blue', 'Hera Front to Up Stairs Barrier - Orange', 'Hera Front to Back Barrier - Orange']), create_dungeon_region(player, 'Hera Front Crystal', 'Tower of Hera', None, ['Hera Front Crystal Exit']), - create_dungeon_region(player, 'Hera Down Stairs Landing', 'Tower of Hera', None, ['Hera Lobby Down Stairs', 'Hera Down Stairs to Front Barrier - Blue']), - create_dungeon_region(player, 'Hera Up Stairs Landing', 'Tower of Hera', None, ['Hera Up Stairs to Front Barrier - Orange', 'Hera Lobby Up Stairs']), - create_dungeon_region(player, 'Hera Back', 'Tower of Hera', ['Tower of Hera - Map Chest'], ['Hera Back to Front Barrier - Orange', 'Hera Lobby Key Stairs']), + create_dungeon_region(player, 'Hera Down Stairs Landing', 'Tower of Hera', None, ['Hera Lobby Down Stairs', 'Hera Down Stairs to Front Barrier - Blue', 'Hera Down Stairs Landing to Ranged Crystal']), + create_dungeon_region(player, 'Hera Down Stairs Landing - Ranged Crystal', 'Tower of Hera', None, ['Hera Down Stairs Landing Ranged Crystal Exit']), + create_dungeon_region(player, 'Hera Up Stairs Landing', 'Tower of Hera', None, ['Hera Up Stairs to Front Barrier - Orange', 'Hera Lobby Up Stairs', 'Hera Up Stairs Landing to Ranged Crystal']), + create_dungeon_region(player, 'Hera Up Stairs Landing - Ranged Crystal', 'Tower of Hera', None, ['Hera Up Stairs Landing Ranged Crystal Exit']), + create_dungeon_region(player, 'Hera Back', 'Tower of Hera', ['Tower of Hera - Map Chest'], ['Hera Back to Front Barrier - Orange', 'Hera Lobby Key Stairs', 'Hera Back to Ranged Crystal']), + create_dungeon_region(player, 'Hera Back - Ranged Crystal', 'Tower of Hera', None, ['Hera Back Ranged Crystal Exit']), create_dungeon_region(player, 'Hera Basement Cage', 'Tower of Hera', ['Tower of Hera - Basement Cage'], ['Hera Basement Cage Up Stairs']), create_dungeon_region(player, 'Hera Tile Room', 'Tower of Hera', None, ['Hera Tile Room Up Stairs', 'Hera Tile Room EN']), create_dungeon_region(player, 'Hera Tridorm', 'Tower of Hera', None, ['Hera Tridorm WN', 'Hera Tridorm SE']), @@ -793,6 +795,9 @@ def create_dungeon_regions(world, player): world.initialize_regions() world.get_region('Hera Lobby Crystal', player).crystal_switch = True world.get_region('Hera Front Crystal', player).crystal_switch = True + world.get_region('Hera Down Stairs Landing - Ranged Crystal', player).crystal_switch = True + world.get_region('Hera Up Stairs Landing - Ranged Crystal', player).crystal_switch = True + world.get_region('Hera Back - Ranged Crystal', player).crystal_switch = True world.get_region('Hera Basement Cage', player).crystal_switch = True world.get_region('Hera Tile Room', player).crystal_switch = True # INTERIOR not accessible (maybe with cane) world.get_region('Hera Tridorm', player).crystal_switch = True diff --git a/Rules.py b/Rules.py index 118ae95b..54cc1dc5 100644 --- a/Rules.py +++ b/Rules.py @@ -354,10 +354,13 @@ def global_rules(world, player): set_rule(world.get_entrance('Hera Front to Lobby Barrier - Blue', player), lambda state: state.can_reach_blue(world.get_region('Hera Front', player), player)) set_rule(world.get_entrance('Hera Front to Down Stairs Barrier - Blue', player), lambda state: state.can_reach_blue(world.get_region('Hera Front', player), player)) set_rule(world.get_entrance('Hera Down Stairs to Front Barrier - Blue', player), lambda state: state.can_reach_blue(world.get_region('Hera Down Stairs Landing', player), player)) + set_rule(world.get_entrance('Hera Down Stairs Landing to Ranged Crystal', player), lambda state: state.can_hit_switch_through_barrier(player)) set_rule(world.get_entrance('Hera Front to Up Stairs Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('Hera Front', player), player)) set_rule(world.get_entrance('Hera Up Stairs to Front Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('Hera Up Stairs Landing', player), player)) + set_rule(world.get_entrance('Hera Up Stairs Landing to Ranged Crystal', player), lambda state: state.can_hit_switch_through_barrier(player)) set_rule(world.get_entrance('Hera Front to Back Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('Hera Front', player), player)) set_rule(world.get_entrance('Hera Back to Front Barrier - Orange', player), lambda state: state.can_reach_orange(world.get_region('Hera Back', player), player)) + set_rule(world.get_entrance('Hera Back to Ranged Crystal', player), lambda state: state.has_beam_sword(player) or state.can_shoot_arrows(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player)) set_rule(world.get_entrance('PoD Arena Main to Ranged Crystal', player), lambda state: state.can_hit_switch_through_barrier(player) or state.has('Hookshot', player)) set_rule(world.get_entrance('PoD Arena Bridge to Ranged Crystal', player), lambda state: state.has_beam_sword(player) or state.can_shoot_arrows(player) or state.has('Red Boomerang', player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Cane of Somaria', player)) @@ -406,7 +409,7 @@ def global_rules(world, player): set_rule(world.get_entrance('Mire Crystal Dead End Right Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire Crystal Dead End', player), player)) set_rule(world.get_entrance('Mire South Fish Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire South Fish', player), player)) set_rule(world.get_entrance('Mire Compass Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire Compass Room', player), player)) - set_rule(world.get_entrance('Mire Tall Dark and Roomy to Ranged Crystal', player), lambda state: state.can_hit_switch_through_barrier(player) or state.has('Hookshot') or state.has_Boots(player)) + set_rule(world.get_entrance('Mire Tall Dark and Roomy to Ranged Crystal', player), lambda state: state.can_hit_switch_through_barrier(player) or state.has('Hookshot', player) or state.has_Boots(player)) set_rule(world.get_entrance('Mire Crystal Mid Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire Crystal Mid', player), player)) set_rule(world.get_entrance('Mire Crystal Left Blue Barrier', player), lambda state: state.can_reach_blue(world.get_region('Mire Crystal Left', player), player)) @@ -460,7 +463,7 @@ def global_rules(world, player): 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 Bombable Wall', 'Hookshot Cave Back Bombable Wall', 'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery'] + 'Hookshot Cave Exit (South)', 'Hookshot Cave Exit (North)', 'Dark Lake Hylia Ledge Fairy', 'Hype Cave', 'Brewery'] 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: diff --git a/TestSuite.py b/TestSuite.py index f22aa177..24cf54a5 100644 --- a/TestSuite.py +++ b/TestSuite.py @@ -29,7 +29,7 @@ def main(args=None): ['Std ', ' --mode standard'], ['Inv ', ' --mode inverted']]: - basecommand = f"python3.8 DungeonRandomizer.py --door_shuffle {args.dr} --intensity {args.tense} --suppress_rom --suppress_spoiler" + basecommand = f"py -3.8 DungeonRandomizer.py --door_shuffle {args.dr} --intensity {args.tense} --suppress_rom --suppress_spoiler" def gen_seed(): taskcommand = basecommand + " " + command + mode[1]