Mixed Districts Initial Implementation

This commit is contained in:
codemann8
2022-11-05 18:26:52 -05:00
parent 50c40cedd5
commit f762d982a2
2 changed files with 111 additions and 79 deletions

View File

@@ -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: