Start in BBS in Inverted, replacing LH/BBS entrance swap

This commit is contained in:
codemann8
2022-01-13 19:49:08 -06:00
parent f083a41045
commit af00bdec1e
5 changed files with 109 additions and 80 deletions

View File

@@ -1661,7 +1661,7 @@ class Entrance(object):
# 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 = start_region.entrances[0].parent_region
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

View File

@@ -1815,10 +1815,7 @@ def remove_pair_type_if_present(door, world, player):
def find_inaccessible_regions(world, player):
world.inaccessible_regions[player] = []
if world.mode[player] != 'inverted':
start_regions = ['Links House', 'Sanctuary']
else:
start_regions = ['Links House', 'Dark Sanctuary Hint']
start_regions = ['Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop', 'Sanctuary' if world.mode[player] != 'inverted' else 'Dark Sanctuary Hint']
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()

View File

@@ -54,32 +54,32 @@ def link_entrances(world, player):
for exitname, regionname in mandatory_connections:
connect_simple(world, exitname, regionname, player)
if not invFlag:
for exitname, regionname in open_mandatory_connections:
connect_simple(world, exitname, regionname, player)
if not world.is_tile_swapped(0x2c, player):
connect_simple(world, 'Links House S&Q', 'Links House', player)
else:
for exitname, regionname in inverted_mandatory_connections:
connect_simple(world, exitname, regionname, player)
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
connect_custom(world, player)
suppress_spoiler = True
# if we do not shuffle, set default connections
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
for entrancename, exitname in default_connections + drop_connections + default_item_connections + default_shop_connections:
connect_logical(world, entrancename, exitname, player, False)
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)
if invFlag:
world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance('Dark Sanctuary Hint', player).parent_region)
if not invFlag:
for entrancename, exitname in open_default_connections:
connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit'))
else:
for entrancename, exitname in inverted_default_connections:
connect_logical(world, entrancename, exitname, player, exitname.endswith(' Exit'))
if world.is_tile_swapped(0x2c, player):
world.get_entrance('Big Bomb Shop Exit', player).connect(world.get_entrance('Big Bomb Shop', player).parent_region)
ignore_pool = False
@@ -215,6 +215,7 @@ def link_entrances(world, player):
junk_fill_inaccessible(world, player)
# place bomb shop, has limited options
if not world.is_tile_swapped(0x2c, 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']]
@@ -260,6 +261,7 @@ def link_entrances(world, player):
place_old_man(world, lw_entrances if not invFlag else dw_entrances, player)
# place bomb shop, has limited options
if not world.is_tile_swapped(0x2c, 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']]
@@ -317,6 +319,7 @@ def link_entrances(world, player):
place_old_man(world, lw_entrances if not invFlag else dw_entrances, player, list(zip(*drop_connections + dropexit_connections))[0])
# place bomb shop, has limited options
if not world.is_tile_swapped(0x2c, 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']]
@@ -419,6 +422,7 @@ def link_entrances(world, player):
connect_caves(world, lw_entrances, dw_entrances, caves, player)
# place bomb shop, has limited options
if not world.is_tile_swapped(0x2c, 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']]
@@ -473,6 +477,7 @@ def link_entrances(world, player):
connect_caves(world, connector_entrances, [], caves, player)
# place bomb shop, has limited options
if not world.is_tile_swapped(0x2c, 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']]
@@ -522,6 +527,7 @@ def link_entrances(world, player):
place_old_man(world, pool, player)
# place bomb shop, has limited options
if not world.is_tile_swapped(0x2c, 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']]
@@ -605,6 +611,7 @@ def link_entrances(world, player):
caves.append('Old Man Cave Exit (West)')
# place bomb shop, has limited options
if not world.is_tile_swapped(0x2c, 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']]
@@ -635,8 +642,8 @@ def link_entrances(world, player):
# ensure Houlihan exits where Links House does
# TODO: Plando should overrule this
if not links_house:
for links_house in world.get_entrance('Links House Exit', player).connected_region.exits:
if links_house.connected_region and links_house.connected_region.name == 'Links House':
for links_house in world.get_entrance('Links House Exit' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop Exit', player).connected_region.exits:
if links_house.connected_region and links_house.connected_region.name == ('Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop'):
links_house = links_house.name
break
connect_exit(world, 'Chris Houlihan Room Exit', links_house, player)
@@ -1335,7 +1342,7 @@ def full_shuffle_dungeons(world, Dungeon_Exits, player):
def place_links_house(world, player, ignore_list=[]):
invFlag = world.mode[player] == 'inverted'
if world.mode[player] == 'standard' or not world.shufflelinks[player]:
links_house = 'Links House' if not invFlag else 'Big Bomb Shop'
links_house = 'Links House' if not world.is_tile_swapped(0x2c, player) else 'Big Bomb Shop'
else:
if invFlag:
for dark_sanc in world.get_entrance('Dark Sanctuary Hint Exit', player).connected_region.exits:
@@ -1354,7 +1361,11 @@ def place_links_house(world, player, ignore_list=[]):
links_house_doors = [e for e in links_house_doors if e not in ignore_list]
assert len(links_house_doors), 'No valid candidates to place Links House'
links_house = random.choice(links_house_doors)
if not world.is_tile_swapped(0x2c, player):
connect_two_way(world, links_house, 'Links House Exit', player)
else:
connect_entrance(world, links_house, 'Big Bomb Shop', player)
world.get_entrance('Big Bomb Shop Exit', player).connect(world.get_entrance(links_house, player).parent_region)
return links_house
@@ -2037,8 +2048,7 @@ 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 = [('Links House S&Q', 'Links House'),
('Old Man S&Q', 'Old Man House'),
mandatory_connections = [('Old Man S&Q', 'Old Man House'),
# UW Connections
('Lost Woods Hideout (top to bottom)', 'Lost Woods Hideout (bottom)'),
@@ -2069,10 +2079,6 @@ mandatory_connections = [('Links House S&Q', 'Links House'),
('Ganon Drop', 'Bottom of Pyramid')
]
open_mandatory_connections = [('Sanctuary S&Q', 'Sanctuary')]
inverted_mandatory_connections = [('Sanctuary S&Q', 'Dark Sanctuary Hint')]
# non-shuffled entrance links
default_connections = [('Lumberjack House', 'Lumberjack House'),
('Bonk Fairy (Light)', 'Bonk Fairy (Light)'),
@@ -2137,7 +2143,8 @@ default_connector_connections = [('Old Man Cave (West)', 'Old Man Cave Exit (Wes
('Hookshot Cave Back Entrance', 'Hookshot Cave Back Exit')
]
default_item_connections = [('Mimic Cave', 'Mimic Cave'),
default_item_connections = [('Links House', 'Links House Exit'),
('Mimic Cave', 'Mimic Cave'),
('Waterfall of Wishing', 'Waterfall of Wishing'),
('Bonk Rock Cave', 'Bonk Rock Cave'),
('Graveyard Cave', 'Graveyard Cave'),
@@ -2161,6 +2168,7 @@ default_item_connections = [('Mimic Cave', 'Mimic Cave'),
('Brewery', 'Brewery'),
('Pyramid Fairy', 'Pyramid Fairy'),
('Dark World Hammer Peg Cave', 'Dark World Hammer Peg Cave'),
('Big Bomb Shop', 'Big Bomb Shop'),
('Mire Shed', 'Mire Shed'),
('Hype Cave', 'Hype Cave')
]
@@ -2196,14 +2204,6 @@ default_dropexit_connections = [('Lost Woods Hideout Stump', 'Lost Woods Hideout
#('Pyramid Entrance', 'Pyramid Exit') # this is dynamically added because of Inverted/OW Mixed
]
open_default_connections = [('Links House', 'Links House Exit'),
('Big Bomb Shop', 'Big Bomb Shop')
]
inverted_default_connections = [('Big Bomb Shop', 'Links House Exit'),
('Links House', 'Big Bomb Shop')
]
# non shuffled dungeons
default_dungeon_connections = [('Desert Palace Entrance (South)', 'Desert Palace Exit (South)'),
('Desert Palace Entrance (West)', 'Desert Palace Exit (West)'),

View File

@@ -326,7 +326,7 @@ def create_regions(world, player):
create_cave_region(player, 'Dark World Hammer Peg Cave', 'a cave with an item', ['Peg Cave']),
create_cave_region(player, 'Archery Game', 'a game of skill'),
create_cave_region(player, 'Bonk Fairy (Dark)', 'a fairy fountain'),
create_cave_region(player, 'Big Bomb Shop', 'the bomb shop', ['Big Bomb']),
create_cave_region(player, 'Big Bomb Shop', 'the bomb shop', ['Big Bomb'], ['Big Bomb Shop Exit']),
create_cave_region(player, 'Dark Lake Hylia Healer Fairy', 'a fairy fountain'),
create_cave_region(player, 'East Dark World Hint', 'a storyteller'),
create_cave_region(player, 'Hype Cave', 'a bounty of five items', ['Hype Cave - Top', 'Hype Cave - Middle Right', 'Hype Cave - Middle Left',

40
Rom.py
View File

@@ -800,7 +800,10 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
if should_be_bunny(sanc_region, world.mode[player]):
rom.write_bytes(0x13fff2, [0x12, 0x00])
if not world.is_tile_swapped(0x2c, player):
lh_name = 'Links House'
else:
lh_name = 'Big Bomb Shop'
links_house = world.get_region(lh_name, player)
if should_be_bunny(links_house, world.mode[player]):
rom.write_bytes(0x13fff0, [0x04, 0x01])
@@ -2625,10 +2628,24 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
if world.is_tile_swapped(0x29, player):
rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact
if world.is_tile_swapped(0x2c, player):
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
rom.write_byte(0x15B8C, 0x6C) # exit links at bomb shop area
rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house
rom.write_byte(0xDBB73 + 0x52, 0x01)
rom.write_bytes(snes_to_pc(0x03F484), [0xFD, 0x4B, 0x68]) # place bed in bomb shop
# spawn in bomb shop
patch_shuffled_bomb_shop(world, rom, player)
rom.write_byte(snes_to_pc(0x02D8D2), 0x1C)
rom.write_bytes(snes_to_pc(0x02D8E0), [0x23, 0x22, 0x23, 0x23, 0x18, 0x18, 0x18, 0x19])
rom.write_byte(snes_to_pc(0x02D919), 0x18)
rom.write_byte(snes_to_pc(0x02D927), 0x23)
write_int16(rom, snes_to_pc(0x02D934), 0x2398)
rom.write_byte(snes_to_pc(0x02D943), 0x18)
write_int16(rom, snes_to_pc(0x02D950), 0x0087)
write_int16(rom, snes_to_pc(0x02D95E), 0x0081)
rom.write_byte(snes_to_pc(0x02D9A4), 0x53)
# disable custom exit on links house exit
rom.write_byte(snes_to_pc(0x02E225), 0x1C)
rom.write_byte(snes_to_pc(0x02DAEE), 0x1C)
rom.write_byte(snes_to_pc(0x02DB8C), 0x6C)
if world.is_tile_swapped(0x2f, player):
rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock
rom.write_byte(snes_to_pc(0x1BC590), 0x00) # remove secret portal
@@ -2661,6 +2678,21 @@ def patch_shuffled_dark_sanc(world, rom, player):
rom.write_bytes(0x180262, [unknown_1, unknown_2, 0x00])
def patch_shuffled_bomb_shop(world, rom, player):
bomb_shop = world.get_region('Big Bomb Shop', player)
bomb_shop_entrance = str([i for i in bomb_shop.entrances if i.parent_region.name != 'Menu'][0].name)
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 = door_addresses[bomb_shop_entrance][1]
door_index = door_addresses[str(bomb_shop_entrance)][0]
rom.write_byte(0x180240, 0x02)
rom.write_byte(0x180247, door_index + 1)
write_int16(rom, 0x180264, room_id)
rom.write_byte(0x180266, ow_area)
write_int16s(rom, 0x180267, [vram_loc, scroll_y, scroll_x, link_y, link_x, camera_y, camera_x])
rom.write_bytes(0x180275, [unknown_1, unknown_2, 0x00])
write_int16(rom, snes_to_pc(0x02D996), door_1)
def update_compasses(rom, world, player):
layouts = world.dungeon_layouts[player]
provided_dungeon = False