From 50c40cedd59dd0b6ff2c2a26eaa8d6fd9bc331dd Mon Sep 17 00:00:00 2001 From: codemann8 Date: Fri, 4 Nov 2022 11:14:08 -0500 Subject: [PATCH 1/7] Splitting up Stone Bridge region in prep for Mixed Districts --- OWEdges.py | 5 ++++- OverworldGlitchRules.py | 6 +++--- OverworldShuffle.py | 16 +++++++++------- Regions.py | 3 ++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 98736c08..4bdd95bd 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1113,7 +1113,8 @@ OWTileRegions = bidict({ 'Links House Area': 0x2c, - 'Stone Bridge Area': 0x2d, + 'Stone Bridge North Area': 0x2d, + 'Stone Bridge South Area': 0x2d, 'Stone Bridge Water': 0x2d, 'Tree Line Area': 0x2e, @@ -1606,6 +1607,8 @@ OWExitTypes = { 'Bat Cave Ledge Peg', 'Bat Cave Ledge Peg (East)', 'Maze Race Game', + 'Stone Bridge Northbound', + 'Stone Bridge Southbound', 'Desert Palace Statue Move', 'Checkerboard Ledge Approach', 'Desert Ledge Outer Rocks', diff --git a/OverworldGlitchRules.py b/OverworldGlitchRules.py index 29986c80..f0aecbef 100644 --- a/OverworldGlitchRules.py +++ b/OverworldGlitchRules.py @@ -447,13 +447,13 @@ boots_clips = [ (['Suburb To Cliff Clip', 'Archery Game To Cliff Clip'], ['Kakariko Suburb Area', 'Archery Game Area'], ['Desert Northeast Cliffs', 'Mire Northeast Cliffs']), (['Central Bonk Rocks To Cliff Clip', 'Dark Bonk Rocks To Cliff Clip'], ['Central Bonk Rocks Area', 'Dark Bonk Rocks Area'], ['Central Cliffs', 'Dark Central Cliffs']), (['Links House To Cliff Clip', 'Bomb Shop To Cliff Clip'], ['Links House Area', 'Big Bomb Shop Area'], ['Central Cliffs', 'Dark Central Cliffs']), - (['Stone Bridge To Cliff Clip', 'Hammer Bridge To Cliff Clip'], ['Stone Bridge Area', 'Hammer Bridge South Area'], ['Central Cliffs', 'Dark Central Cliffs']), + (['Stone Bridge To Cliff Clip', 'Hammer Bridge To Cliff Clip'], ['Stone Bridge South Area', 'Hammer Bridge South Area'], ['Central Cliffs', 'Dark Central Cliffs']), (['Eastern Nook To Eastern Clip', None], ['Eastern Nook Area', None], ['Eastern Palace Area', 'Palace of Darkness Area']), (['Eastern Nook To Ice Cave FAWT Clip', 'PoD Nook To Shopping Mall FAWT Clip'], ['Eastern Nook Area', 'Palace of Darkness Nook Area'], ['Ice Cave Area', 'Shopping Mall Area']), - (['Links To Bridge FAWT Clip', 'Bomb Shop To Hammer Bridge FAWT Clip'], ['Links House Area', 'Big Bomb Shop Area'], ['Stone Bridge Area', 'Hammer Bridge North Area']), #fake flipper + (['Links To Bridge FAWT Clip', 'Bomb Shop To Hammer Bridge FAWT Clip'], ['Links House Area', 'Big Bomb Shop Area'], ['Stone Bridge North Area', 'Hammer Bridge North Area']), #fake flipper - (['Stone Bridge To Water Clip', 'Hammer Bridge To Water Clip'], ['Stone Bridge Area', 'Hammer Bridge North Area'], [None, 'Pyramid Water']), #fake flipper + (['Stone Bridge To Water Clip', 'Hammer Bridge To Water Clip'], ['Stone Bridge North Area', 'Hammer Bridge North Area'], [None, 'Pyramid Water']), #fake flipper (['Desert To Maze Race Clip', None], ['Desert Ledge', None], ['Maze Race Area', 'Dig Game Area']), (['Desert To Cliff Clip', 'Mire To Cliff Clip'], ['Desert Area', 'Misery Mire Area'], ['Desert Northeast Cliffs', 'Mire Northeast Cliffs']), diff --git a/OverworldShuffle.py b/OverworldShuffle.py index a2254434..4329bdc4 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -1219,6 +1219,8 @@ mandatory_connections = [# Intra-tile OW Connections ('Bat Cave Ledge Peg (East)', 'Blacksmith Area'), #hammer ('Maze Race Game', 'Maze Race Prize'), #pearl ('Maze Race Ledge Drop', 'Maze Race Area'), + ('Stone Bridge Southbound', 'Stone Bridge South Area'), + ('Stone Bridge Northbound', 'Stone Bridge North Area'), ('Desert Palace Statue Move', 'Desert Palace Stairs'), #book ('Desert Ledge Drop', 'Desert Area'), ('Desert Ledge Outer Rocks', 'Desert Palace Entrance (North) Spot'), #glove @@ -1611,21 +1613,21 @@ ow_connections = { ('Bomb Shop Cliff Ledge Drop', 'Links House Area') # OWG ]), 0x2d: ([ - ('Stone Bridge Mirror Spot', 'Stone Bridge Area'), - ('Stone Bridge South Mirror Spot', 'Stone Bridge Area'), + ('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 Area'), # OWG + ('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 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 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 Area') # OWG + ('Hammer Bridge South Cliff Ledge Drop', 'Stone Bridge South Area') # OWG ]), 0x2e: ([ ('Tree Line Mirror Spot', 'Tree Line Area'), @@ -1976,7 +1978,7 @@ flute_data = { 0x2a: (['Flute Boy Area', 'Stumpy Area'], 0x2a, 0x058e, 0x0aac, 0x046e, 0x0b10, 0x04e8, 0x0b1b, 0x04f3, 0x0002, 0x0002, 0x0b10, 0x04e8), 0x2b: (['Central Bonk Rocks Area', 'Dark Bonk Rocks Area'], 0x2b, 0x0620, 0x0acc, 0x0700, 0x0b30, 0x0790, 0x0b3b, 0x0785, 0xfff2, 0x0000, 0x0b30, 0x0770), 0x2c: (['Links House Area', 'Big Bomb Shop Area'], 0x2c, 0x0588, 0x0ab9, 0x0840, 0x0b17, 0x08b8, 0x0b26, 0x08bf, 0xfff7, 0x0000, 0x0b20, 0x08b8), - 0x2d: (['Stone Bridge Area', 'Hammer Bridge South Area'], 0x2d, 0x0886, 0x0b1e, 0x0a2a, 0x0ba0, 0x0aa8, 0x0b8b, 0x0aaf, 0x0000, 0x0006, 0x0bc4, 0x0ad0), + 0x2d: (['Stone Bridge South Area', 'Hammer Bridge South Area'], 0x2d, 0x0886, 0x0b1e, 0x0a2a, 0x0ba0, 0x0aa8, 0x0b8b, 0x0aaf, 0x0000, 0x0006, 0x0bc4, 0x0ad0), 0x2e: (['Tree Line Area', 'Dark Tree Line Area'], 0x2e, 0x0100, 0x0a1a, 0x0c00, 0x0a78, 0x0c30, 0x0a87, 0x0c7d, 0x0006, 0x0000, 0x0a78, 0x0c58), 0x2f: (['Eastern Nook Area', 'Palace of Darkness Nook Area'], 0x2f, 0x0798, 0x0afa, 0x0eb2, 0x0b58, 0x0f30, 0x0b67, 0x0f37, 0xfff6, 0x000e, 0x0b50, 0x0f30), 0x38: (['Desert Palace Teleporter Ledge', 'Misery Mire Teleporter Ledge'], 0x30, 0x1880, 0x0f1e, 0x0000, 0x0fa8, 0x0078, 0x0f8d, 0x008d, 0x0000, 0x0000, 0x0fb0, 0x0070), diff --git a/Regions.py b/Regions.py index d568497c..cb3eef6d 100644 --- a/Regions.py +++ b/Regions.py @@ -84,7 +84,8 @@ def create_regions(world, player): 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 Area', None, ['Hammer Bridge North Mirror Spot', 'Hammer Bridge South Mirror Spot', 'Stone Bridge NC', 'Stone Bridge EN', 'Stone Bridge WS', 'Stone Bridge SC']), + 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, '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', 'Statues Cliff Ledge Drop']), From f762d982a2e062a4809af8180cf698139a778a0d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 5 Nov 2022 18:26:52 -0500 Subject: [PATCH 2/7] Mixed Districts Initial Implementation --- OWEdges.py | 53 ++++++++++++++++ source/item/District.py | 137 +++++++++++++++++----------------------- 2 files changed, 111 insertions(+), 79 deletions(-) diff --git a/OWEdges.py b/OWEdges.py index 4bdd95bd..320f555b 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1910,4 +1910,57 @@ OWExitTypes = { 'South Pass Mirror Spot', 'Octoballoon Mirror Spot' ] +} + +OWTileDistricts = { + 0x00: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x02: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x03: (None, None, ('Death Mountain', 'Dark Death Mountain')), + 0x05: (None, None, ('Death Mountain', 'Dark Death Mountain')), + 0x07: (None, None, ('Death Mountain', 'Dark Death Mountain')), + 0x0a: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x0f: (None, None, ('Eastern Hyrule', 'East Dark World')), + 0x10: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x11: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x12: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x13: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x14: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x15: (['River Bend Area', 'Qirn Jump Area'], # if region in this list + ('Northwest Hyrule', 'Northwest Dark World'), # use this district + ('Eastern Hyrule', 'East Dark World')), # else this district + 0x16: (None, None, ('Eastern Hyrule', 'East Dark World')), + 0x17: (None, None, ('Eastern Hyrule', 'East Dark World')), + 0x18: (None, None, ('Kakariko', 'Northwest Dark World')), + 0x1a: (None, None, ('Northwest Hyrule', 'Northwest Dark World')), + 0x1b: (None, None, ('Central Hyrule', 'East Dark World')), + 0x1d: (None, None, ('Eastern Hyrule', 'East Dark World')), + 0x1e: (None, None, ('Eastern Hyrule', 'East Dark World')), + 0x22: (None, None, ('Kakariko', 'Northwest Dark World')), + 0x25: (None, None, ('Eastern Hyrule', 'East Dark World')), + 0x28: (None, None, ('Kakariko', 'South Dark World')), + 0x29: (None, None, ('Kakariko', 'South Dark World')), + 0x2a: (None, None, ('Central Hyrule', 'South Dark World')), + 0x2b: (None, None, ('Central Hyrule', 'South Dark World')), + 0x2c: (None, None, ('Central Hyrule', 'South Dark World')), + 0x2d: (['Stone Bridge North Area', 'Hammer Bridge North Area'], + ('Eastern Hyrule', 'East Dark World'), + ('Lake Hylia', 'South Dark World')), + 0x2e: (['Tree Line Area', 'Dark Tree Line Area'], + ('Eastern Hyrule', 'East Dark World'), + ('Lake Hylia', 'South Dark World')), + 0x2f: (None, None, ('Eastern Hyrule', 'East Dark World')), + 0x30: (None, None, ('The Desert Area', 'The Mire Area')), + 0x32: (None, None, ('Central Hyrule', 'South Dark World')), + 0x33: (None, None, ('Central Hyrule', 'South Dark World')), + 0x34: (None, None, ('Central Hyrule', 'South Dark World')), + 0x35: (None, None, ('Lake Hylia', 'South Dark World')), + 0x37: (None, None, ('Lake Hylia', 'South Dark World')), + 0x3a: (None, None, ('The Desert Area', 'South Dark World')), + 0x3b: (None, None, ('Central Hyrule', 'South Dark World')), + 0x3c: (None, None, ('Central Hyrule', 'South Dark World')), + 0x3f: (None, None, ('Lake Hylia', 'South Dark World')), + 0x80: (['Master Sword Meadow'], + ('Northwest Hyrule', 'Northwest Dark World'), + ('Lake Hylia', 'South Dark World')), + 0x81: (None, None, ('Eastern Hyrule', 'East Dark World')) } \ No newline at end of file diff --git a/source/item/District.py b/source/item/District.py index 375138a3..d9e9e23e 100644 --- a/source/item/District.py +++ b/source/item/District.py @@ -2,15 +2,16 @@ from collections import deque from BaseClasses import CollectionState, RegionType from Dungeons import dungeon_table -from OWEdges import OWTileRegions +from OWEdges import OWTileRegions, OWTileDistricts class District(object): - def __init__(self, name, locations, entrances=None, dungeon=None): + def __init__(self, name, dungeon=None): self.name = name self.dungeon = dungeon - self.locations = locations - self.entrances = entrances if entrances else [] + self.regions = list() + self.locations = set() + self.entrances = list() self.sphere_one = False self.dungeons = set() @@ -25,86 +26,33 @@ def create_districts(world): def create_district_helper(world, player): districts = {} - kak_locations = {'Bottle Merchant', 'Kakariko Tavern', 'Maze Race'} - nw_lw_locations = {'Mushroom', 'Master Sword Pedestal'} - central_lw_locations = {'Sunken Treasure', 'Flute Spot'} - desert_locations = {'Purple Chest', 'Desert Ledge', 'Bombos Tablet'} - lake_locations = {'Hobo', 'Lake Hylia Island'} - east_lw_locations = {"Zora's Ledge", 'King Zora'} - lw_dm_locations = {'Old Man', 'Spectacle Rock', 'Ether Tablet', 'Floating Island'} - east_dw_locations = {'Pyramid', 'Catfish'} - south_dw_locations = {'Stumpy', 'Digging Game'} - voo_north_locations = {'Bumper Cave Ledge'} - ddm_locations = set() - - kak_entrances = ['Kakariko Well Cave', 'Bat Cave Cave', 'Elder House (East)', 'Elder House (West)', - 'Two Brothers House (East)', 'Two Brothers House (West)', 'Blinds Hideout', 'Chicken House', - 'Blacksmiths Hut', 'Sick Kids House', 'Snitch Lady (East)', 'Snitch Lady (West)', - 'Bush Covered House', 'Tavern (Front)', 'Light World Bomb Hut', 'Kakariko Shop', 'Library', - 'Kakariko Gamble Game', 'Kakariko Well Drop', 'Bat Cave Drop', 'Tavern North'] - nw_lw_entrances = ['North Fairy Cave', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Sanctuary', - 'Old Man Cave (West)', 'Death Mountain Return Cave (West)', 'Kings Grave', 'Lost Woods Gamble', - 'Fortune Teller (Light)', 'Bonk Rock Cave', 'Lumberjack House', 'North Fairy Cave Drop', - 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', 'Graveyard Cave'] - central_lw_entrances = ['Links House', 'Hyrule Castle Entrance (South)', 'Hyrule Castle Entrance (West)', - 'Hyrule Castle Entrance (East)', 'Agahnims Tower', 'Hyrule Castle Secret Entrance Stairs', - 'Dam', 'Bonk Fairy (Light)', 'Light Hype Fairy', 'Hyrule Castle Secret Entrance Drop', - 'Cave 45'] - desert_entrances = ['Desert Palace Entrance (South)', 'Desert Palace Entrance (West)', - 'Desert Palace Entrance (North)', 'Desert Palace Entrance (East)', 'Desert Fairy', - 'Aginahs Cave', '50 Rupee Cave', 'Checkerboard Cave'] - lake_entrances = ['Capacity Upgrade', 'Mini Moldorm Cave', 'Good Bee Cave', '20 Rupee Cave', 'Ice Rod Cave', - 'Cave Shop (Lake Hylia)', 'Lake Hylia Fortune Teller'] - east_lw_entrances = ['Eastern Palace', 'Waterfall of Wishing', 'Lake Hylia Fairy', 'Sahasrahlas Hut', - 'Long Fairy Cave', 'Potion Shop'] - lw_dm_entrances = ['Tower of Hera', 'Old Man Cave (East)', 'Old Man House (Bottom)', 'Old Man House (Top)', - 'Death Mountain Return Cave (East)', 'Spectacle Rock Cave Peak', 'Spectacle Rock Cave', - 'Spectacle Rock Cave (Bottom)', 'Paradox Cave (Bottom)', 'Paradox Cave (Middle)', - 'Paradox Cave (Top)', 'Fairy Ascension Cave (Bottom)', 'Fairy Ascension Cave (Top)', - 'Spiral Cave', 'Spiral Cave (Bottom)', 'Hookshot Fairy', 'Mimic Cave'] - east_dw_entrances = ['Palace of Darkness', 'Pyramid Entrance', 'Pyramid Fairy', 'East Dark World Hint', - 'Palace of Darkness Hint', 'Dark Lake Hylia Fairy', 'Dark World Potion Shop', 'Pyramid Hole'] - south_dw_entrances = ['Ice Palace', 'Swamp Palace', 'Dark Lake Hylia Ledge Fairy', - 'Dark Lake Hylia Ledge Spike Cave', 'Dark Lake Hylia Ledge Hint', 'Hype Cave', - 'Bonk Fairy (Dark)', 'Archery Game', 'Big Bomb Shop', 'Dark Lake Hylia Shop', ] - voo_north_entrances = ['Thieves Town', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', - 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section', - 'Bumper Cave (Bottom)', 'Bumper Cave (Top)', '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', - 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (East)', - 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] - mire_entrances = ['Misery Mire', 'Mire Shed', 'Dark Desert Hint', 'Dark Desert Fairy'] - ddm_entrances = ['Turtle Rock', 'Dark Death Mountain Ledge (West)', 'Dark Death Mountain Ledge (East)', - 'Turtle Rock Isolated Ledge Entrance', 'Superbunny Cave (Top)', 'Superbunny Cave (Bottom)', - 'Hookshot Cave', 'Hookshot Cave Back Entrance', 'Ganons Tower', 'Spike Cave', - 'Cave Shop (Dark Death Mountain)', 'Dark Death Mountain Fairy'] - - if world.is_tile_swapped(0x1b, player): - east_dw_entrances.remove('Pyramid Entrance') - east_dw_entrances.remove('Pyramid Hole') - central_lw_entrances.append('Inverted Pyramid Entrance') - central_lw_entrances.append('Inverted Pyramid Hole') - - districts['Kakariko'] = District('Kakariko', kak_locations, entrances=kak_entrances) - districts['Northwest Hyrule'] = District('Northwest Hyrule', nw_lw_locations, entrances=nw_lw_entrances) - districts['Central Hyrule'] = District('Central Hyrule', central_lw_locations, entrances=central_lw_entrances) - districts['The Desert Area'] = District('Desert', desert_locations, entrances=desert_entrances) - districts['Lake Hylia'] = District('Lake Hylia', lake_locations, entrances=lake_entrances) - districts['Eastern Hyrule'] = District('Eastern Hyrule', east_lw_locations, entrances=east_lw_entrances) - districts['Death Mountain'] = District('Death Mountain', lw_dm_locations, entrances=lw_dm_entrances) - districts['East Dark World'] = District('East Dark World', east_dw_locations, entrances=east_dw_entrances) - districts['South Dark World'] = District('South Dark World', south_dw_locations, entrances=south_dw_entrances) - districts['Northwest Dark World'] = District('Northwest Dark World', voo_north_locations, - entrances=voo_north_entrances) - districts['The Mire Area'] = District('The Mire', set(), entrances=mire_entrances) - districts['Dark Death Mountain'] = District('Dark Death Mountain', ddm_locations, entrances=ddm_entrances) - districts.update({x: District(x, set(), dungeon=x) for x in dungeon_table.keys()}) + districts['Kakariko'] = District('Kakariko') + districts['Northwest Hyrule'] = District('Northwest Hyrule') + districts['Central Hyrule'] = District('Central Hyrule') + districts['The Desert Area'] = District('Desert') + districts['Lake Hylia'] = District('Lake Hylia') + districts['Eastern Hyrule'] = District('Eastern Hyrule') + districts['Death Mountain'] = District('Death Mountain') + districts['East Dark World'] = District('East Dark World') + districts['South Dark World'] = District('South Dark World') + districts['Northwest Dark World'] = District('Northwest Dark World') + districts['The Mire Area'] = District('The Mire') + districts['Dark Death Mountain'] = District('Dark Death Mountain') + districts.update({x: District(x, dungeon=x) for x in dungeon_table.keys()}) world.districts[player] = districts def resolve_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'] + inv_regions = ['Spiral Mimic Ledge Extend', 'Inverted Pyramid Hole', 'Inverted Pyramid Entrance'] + if (area in inv_regions and not world.is_tile_swapped(owid, player)) \ + or (area in std_regions and world.is_tile_swapped(owid, player)): + return True + return False + create_districts(world) state = CollectionState(world) state.sweep_for_events() @@ -113,18 +61,49 @@ def resolve_districts(world): 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 + if owid in OWTileRegions.inverse.keys(): + for region in OWTileRegions.inverse[owid]: + if exclude_area(world, owid, region, player): + continue + if alt_regions and region in alt_regions: + world.districts[player][alt_districts[idx]].regions.append(region) + else: + world.districts[player][default_districts[idx]].regions.append(region) + if owid + 0x40 in OWTileRegions.inverse.keys(): + for region in OWTileRegions.inverse[owid + 0x40]: + if exclude_area(world, owid, region, player): + continue + if alt_regions and region in alt_regions: + world.districts[player][alt_districts[(idx + 1) % 2]].regions.append(region) + else: + world.districts[player][default_districts[(idx + 1) % 2]].regions.append(region) + for name, district in world.districts[player].items(): if district.dungeon: layout = world.dungeon_layouts[player][district.dungeon] district.locations.update([l.name for r in layout.master_sector.regions for l in r.locations if not l.item and l.real]) else: + for region_name in district.regions: + region = world.get_region(region_name, player) + 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]) visited = set() while len(queue) > 0: region = queue.pop() + if not region: + RuntimeError(f'No region connected to entrance: {ent.name} Likely a missing entry in OWExitTypes') visited.add(region) if region.type == RegionType.Cave: for location in region.locations: From 47b92997df38c6444356f75fc86e562f4810051d Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 5 Nov 2022 18:27:44 -0500 Subject: [PATCH 3/7] Adding missing OWG exits to classification list --- OWEdges.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OWEdges.py b/OWEdges.py index 320f555b..0a7126b6 100644 --- a/OWEdges.py +++ b/OWEdges.py @@ -1602,6 +1602,7 @@ 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', @@ -1664,6 +1665,7 @@ 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', @@ -1673,6 +1675,7 @@ 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', From 757fee822062224422c55dd2645cf47c5d594403 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 5 Nov 2022 21:56:40 -0500 Subject: [PATCH 4/7] Fixing spoiler log suppression for OW locations --- BaseClasses.py | 4 ++-- Fill.py | 2 +- ItemList.py | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 61cede10..b773438f 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2876,11 +2876,11 @@ class Spoiler(object): self.locations = OrderedDict() listed_locations = set() - lw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.LightWorld] + lw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.LightWorld and not loc.skip] self.locations['Light World'] = OrderedDict([(location.gen_name(), str(location.item) if location.item is not None else 'Nothing') for location in lw_locations]) listed_locations.update(lw_locations) - dw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.DarkWorld] + dw_locations = [loc for loc in self.world.get_locations() if loc not in listed_locations and loc.parent_region and loc.parent_region.type == RegionType.DarkWorld and not loc.skip] self.locations['Dark World'] = OrderedDict([(location.gen_name(), str(location.item) if location.item is not None else 'Nothing') for location in dw_locations]) listed_locations.update(dw_locations) diff --git a/Fill.py b/Fill.py index a4468e7d..701a2c7c 100644 --- a/Fill.py +++ b/Fill.py @@ -511,7 +511,7 @@ def ensure_good_pots(world, write_skips=False): loc.item = ItemFactory('Rupees (5)', loc.item.player) # don't write out all pots to spoiler if write_skips: - if loc.type == LocationType.Pot and loc.item.name in valid_pot_items: + if loc.type in [LocationType.Pot, LocationType.Bonk] and loc.item.name in valid_pot_items: loc.skip = True diff --git a/ItemList.py b/ItemList.py index 86dfd92f..6be2606c 100644 --- a/ItemList.py +++ b/ItemList.py @@ -563,6 +563,7 @@ def create_farm_locations(world, player): loc.event = True loc.locked = True loc.address = None + loc.skip = True world.push_item(loc, ItemFactory(item_name, player), False) From 1756d22b5d1118c1a83f1eab5e6315a910bfcded Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 5 Nov 2022 21:57:15 -0500 Subject: [PATCH 5/7] Fixed Bonk Drop Locations in Districts --- ItemList.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ItemList.py b/ItemList.py index 6be2606c..5115f7fa 100644 --- a/ItemList.py +++ b/ItemList.py @@ -620,6 +620,7 @@ def create_dynamic_bonkdrop_locations(world, player): region = world.get_region(region_name, player) loc = Location(player, bonk_location, 0, region, hint_text) loc.type = LocationType.Bonk + loc.real = True loc.parent_region = region loc.address = 0x2abb00 + (bonk_prize_table[loc.name][0] * 6) + 3 From 371fe9f24fec3088c910ef34875d13c7cca60716 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Sat, 5 Nov 2022 22:18:11 -0500 Subject: [PATCH 6/7] Adding pre-aga Farmable locations to optional location list --- Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Main.py b/Main.py index 48218a27..a5708194 100644 --- a/Main.py +++ b/Main.py @@ -735,7 +735,7 @@ def create_playthrough(world): prog_locations = [location for location in world.get_filled_locations() if location.item.advancement] optional_locations = ['Trench 1 Switch', 'Trench 2 Switch', 'Ice Block Drop', 'Skull Star Tile'] optional_locations.extend(['Hyrule Castle Courtyard Tree Pull', 'Mountain Entry Area Tree Pull']) # adding pre-aga tree pulls - optional_locations.extend(['Lumberjack Area Bush Crab', 'South Pass Area Bush Crab']) # adding pre-aga bush crabs + optional_locations.extend(['Lumberjack Area Crab Drop', 'South Pass Area Crab Drop']) # adding pre-aga bush crabs state_cache = [None] collection_spheres = [] state = CollectionState(world) From 4872f78b94e8f2da0ddca2ed25026520b9ee60f1 Mon Sep 17 00:00:00 2001 From: codemann8 Date: Mon, 7 Nov 2022 10:59:56 -0600 Subject: [PATCH 7/7] Version bump 0.2.11.2 --- CHANGELOG.md | 4 ++++ OverworldShuffle.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 211f24a2..bfb1bf50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.2.11.2 +- Implemented proper Districting with Mixed OWR, affecting Hints and District modes +- Suppressed item locations in spoiler log that are junk or logical + ## 0.2.11.1 - Renamed mode: Tile Swap (Mixed) is now called Tile Flip (Mixed) - Fixed generation errors due to issue with new Farmable item locations diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 4329bdc4..9f8152e6 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.1' +version_number = '0.2.11.2' # branch indicator is intentionally different across branches version_branch = '-u'