Individual settings: shuffle

This commit is contained in:
Bonta-kun 2019-12-16 18:24:34 +01:00
parent 203147dda1
commit ec1b9eca43
8 changed files with 67 additions and 67 deletions

View File

@ -10,7 +10,7 @@ class World(object):
def __init__(self, players, shuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer, progressive, goal, algorithm, accessibility, shuffle_ganon, quickswap, fastmenu, disable_music, retro, custom, customitemarray, boss_shuffle, hints): def __init__(self, players, shuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer, progressive, goal, algorithm, accessibility, shuffle_ganon, quickswap, fastmenu, disable_music, retro, custom, customitemarray, boss_shuffle, hints):
self.players = players self.players = players
self.shuffle = shuffle self.shuffle = shuffle.copy()
self.logic = logic.copy() self.logic = logic.copy()
self.mode = mode.copy() self.mode = mode.copy()
self.swords = swords.copy() self.swords = swords.copy()
@ -48,12 +48,12 @@ class World(object):
self.rupoor_cost = 10 self.rupoor_cost = 10
self.aga_randomness = True self.aga_randomness = True
self.lock_aga_door_in_escape = False self.lock_aga_door_in_escape = False
self.fix_trock_doors = {player: self.shuffle != 'vanilla' or self.mode[player] == 'inverted' for player in range(1, players + 1)} self.fix_trock_doors = {player: self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted' for player in range(1, players + 1)}
self.save_and_quit_from_boss = True self.save_and_quit_from_boss = True
self.accessibility = accessibility self.accessibility = accessibility
self.fix_skullwoods_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] self.fix_skullwoods_exit = {player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] for player in range(1, players + 1)}
self.fix_palaceofdarkness_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] self.fix_palaceofdarkness_exit = {player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] for player in range(1, players + 1)}
self.fix_trock_exit = self.shuffle not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] self.fix_trock_exit = {player: self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] for player in range(1, players + 1)}
self.shuffle_ganon = shuffle_ganon self.shuffle_ganon = shuffle_ganon
self.fix_gtower_exit = self.shuffle_ganon self.fix_gtower_exit = self.shuffle_ganon
self.can_access_trock_eyebridge = None self.can_access_trock_eyebridge = None

View File

@ -278,7 +278,7 @@ def parse_arguments(argv, no_defaults=False):
for player in range(1, multiargs.multi + 1): for player in range(1, multiargs.multi + 1):
playerargs = parse_arguments(shlex.split(getattr(ret,f"p{player}")), True) playerargs = parse_arguments(shlex.split(getattr(ret,f"p{player}")), True)
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality']: for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'shuffle']:
value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name)
if player == 1: if player == 1:
setattr(ret, name, {1: value}) setattr(ret, name, {1: value})

View File

@ -19,17 +19,17 @@ def link_entrances(world, player):
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
# if we do not shuffle, set default connections # if we do not shuffle, set default connections
if world.shuffle == 'vanilla': if world.shuffle[player] == 'vanilla':
for exitname, regionname in default_connections: for exitname, regionname in default_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
for exitname, regionname in default_dungeon_connections: for exitname, regionname in default_dungeon_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
elif world.shuffle == 'dungeonssimple': elif world.shuffle[player] == 'dungeonssimple':
for exitname, regionname in default_connections: for exitname, regionname in default_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
simple_shuffle_dungeons(world, player) simple_shuffle_dungeons(world, player)
elif world.shuffle == 'dungeonsfull': elif world.shuffle[player] == 'dungeonsfull':
for exitname, regionname in default_connections: for exitname, regionname in default_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
@ -59,7 +59,7 @@ def link_entrances(world, player):
connect_mandatory_exits(world, lw_entrances, dungeon_exits, list(LW_Dungeon_Entrances_Must_Exit), player) connect_mandatory_exits(world, lw_entrances, dungeon_exits, list(LW_Dungeon_Entrances_Must_Exit), player)
connect_mandatory_exits(world, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player) connect_mandatory_exits(world, dw_entrances, dungeon_exits, list(DW_Dungeon_Entrances_Must_Exit), player)
connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player) connect_caves(world, lw_entrances, dw_entrances, dungeon_exits, player)
elif world.shuffle == 'simple': elif world.shuffle[player] == 'simple':
simple_shuffle_dungeons(world, player) simple_shuffle_dungeons(world, player)
old_man_entrances = list(Old_Man_Entrances) old_man_entrances = list(Old_Man_Entrances)
@ -130,7 +130,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, single_doors, door_targets, player) connect_doors(world, single_doors, door_targets, player)
elif world.shuffle == 'restricted': elif world.shuffle[player] == 'restricted':
simple_shuffle_dungeons(world, player) simple_shuffle_dungeons(world, player)
lw_entrances = list(LW_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances) lw_entrances = list(LW_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances)
@ -201,7 +201,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, doors, door_targets, player) connect_doors(world, doors, door_targets, player)
elif world.shuffle == 'restricted_legacy': elif world.shuffle[player] == 'restricted_legacy':
simple_shuffle_dungeons(world, player) simple_shuffle_dungeons(world, player)
lw_entrances = list(LW_Entrances) lw_entrances = list(LW_Entrances)
@ -256,7 +256,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, single_doors, door_targets, player) connect_doors(world, single_doors, door_targets, player)
elif world.shuffle == 'full': elif world.shuffle[player] == 'full':
skull_woods_shuffle(world, player) skull_woods_shuffle(world, player)
lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances) lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances)
@ -361,7 +361,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, doors, door_targets, player) connect_doors(world, doors, door_targets, player)
elif world.shuffle == 'crossed': elif world.shuffle[player] == 'crossed':
skull_woods_shuffle(world, player) skull_woods_shuffle(world, player)
entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances + DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors) entrances = list(LW_Entrances + LW_Dungeon_Entrances + LW_Single_Cave_Doors + Old_Man_Entrances + DW_Entrances + DW_Dungeon_Entrances + DW_Single_Cave_Doors)
@ -437,7 +437,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, entrances, door_targets, player) connect_doors(world, entrances, door_targets, player)
elif world.shuffle == 'full_legacy': elif world.shuffle[player] == 'full_legacy':
skull_woods_shuffle(world, player) skull_woods_shuffle(world, player)
lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances) lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances)
@ -513,7 +513,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, single_doors, door_targets, player) connect_doors(world, single_doors, door_targets, player)
elif world.shuffle == 'madness_legacy': elif world.shuffle[player] == 'madness_legacy':
# here lie dragons, connections are no longer two way # here lie dragons, connections are no longer two way
lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances) lw_entrances = list(LW_Entrances + LW_Dungeon_Entrances + Old_Man_Entrances)
dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances) dw_entrances = list(DW_Entrances + DW_Dungeon_Entrances)
@ -755,7 +755,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, single_doors, door_targets, player) connect_doors(world, single_doors, door_targets, player)
elif world.shuffle == 'insanity': elif world.shuffle[player] == 'insanity':
# beware ye who enter here # beware ye who enter here
entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave']
@ -902,7 +902,7 @@ def link_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, doors, door_targets, player) connect_doors(world, doors, door_targets, player)
elif world.shuffle == 'insanity_legacy': elif world.shuffle[player] == 'insanity_legacy':
world.fix_fake_world = False world.fix_fake_world = False
# beware ye who enter here # beware ye who enter here
@ -1079,17 +1079,17 @@ def link_inverted_entrances(world, player):
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
# if we do not shuffle, set default connections # if we do not shuffle, set default connections
if world.shuffle == 'vanilla': if world.shuffle[player] == 'vanilla':
for exitname, regionname in inverted_default_connections: for exitname, regionname in inverted_default_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
for exitname, regionname in inverted_default_dungeon_connections: for exitname, regionname in inverted_default_dungeon_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
elif world.shuffle == 'dungeonssimple': elif world.shuffle[player] == 'dungeonssimple':
for exitname, regionname in inverted_default_connections: for exitname, regionname in inverted_default_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
simple_shuffle_dungeons(world, player) simple_shuffle_dungeons(world, player)
elif world.shuffle == 'dungeonsfull': elif world.shuffle[player] == 'dungeonsfull':
for exitname, regionname in inverted_default_connections: for exitname, regionname in inverted_default_connections:
connect_simple(world, exitname, regionname, player) connect_simple(world, exitname, regionname, player)
@ -1151,7 +1151,7 @@ def link_inverted_entrances(world, player):
remaining_lw_entrances = [i for i in all_dungeon_entrances if i in lw_entrances] remaining_lw_entrances = [i for i in all_dungeon_entrances if i in lw_entrances]
connect_caves(world, remaining_lw_entrances, remaining_dw_entrances, dungeon_exits, player) connect_caves(world, remaining_lw_entrances, remaining_dw_entrances, dungeon_exits, player)
elif world.shuffle == 'simple': elif world.shuffle[player] == 'simple':
simple_shuffle_dungeons(world, player) simple_shuffle_dungeons(world, player)
old_man_entrances = list(Inverted_Old_Man_Entrances) old_man_entrances = list(Inverted_Old_Man_Entrances)
@ -1243,7 +1243,7 @@ def link_inverted_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, single_doors, door_targets, player) connect_doors(world, single_doors, door_targets, player)
elif world.shuffle == 'restricted': elif world.shuffle[player] == 'restricted':
simple_shuffle_dungeons(world, player) simple_shuffle_dungeons(world, player)
lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Single_Cave_Doors) lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Single_Cave_Doors)
@ -1326,7 +1326,7 @@ def link_inverted_entrances(world, player):
doors = lw_entrances + dw_entrances doors = lw_entrances + dw_entrances
# place remaining doors # place remaining doors
connect_doors(world, doors, door_targets, player) connect_doors(world, doors, door_targets, player)
elif world.shuffle == 'full': elif world.shuffle[player] == 'full':
skull_woods_shuffle(world, player) skull_woods_shuffle(world, player)
lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors) lw_entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors)
@ -1477,7 +1477,7 @@ def link_inverted_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, doors, door_targets, player) connect_doors(world, doors, door_targets, player)
elif world.shuffle == 'crossed': elif world.shuffle[player] == 'crossed':
skull_woods_shuffle(world, player) skull_woods_shuffle(world, player)
entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors + Inverted_Old_Man_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors) entrances = list(Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Single_Cave_Doors + Inverted_Old_Man_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_DW_Single_Cave_Doors)
@ -1587,7 +1587,7 @@ def link_inverted_entrances(world, player):
# place remaining doors # place remaining doors
connect_doors(world, entrances, door_targets, player) connect_doors(world, entrances, door_targets, player)
elif world.shuffle == 'insanity': elif world.shuffle[player] == 'insanity':
# beware ye who enter here # beware ye who enter here
entrances = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)'] entrances = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)']
@ -1840,14 +1840,14 @@ def scramble_holes(world, player):
hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance')) hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance'))
# do not shuffle sanctuary into pyramid hole unless shuffle is crossed # do not shuffle sanctuary into pyramid hole unless shuffle is crossed
if world.shuffle == 'crossed': if world.shuffle[player] == 'crossed':
hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
if world.shuffle_ganon: if world.shuffle_ganon:
random.shuffle(hole_targets) random.shuffle(hole_targets)
exit, target = hole_targets.pop() exit, target = hole_targets.pop()
connect_two_way(world, 'Pyramid Entrance', exit, player) connect_two_way(world, 'Pyramid Entrance', exit, player)
connect_entrance(world, 'Pyramid Hole', target, player) connect_entrance(world, 'Pyramid Hole', target, player)
if world.shuffle != 'crossed': if world.shuffle[player] != 'crossed':
hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
random.shuffle(hole_targets) random.shuffle(hole_targets)
@ -1882,14 +1882,14 @@ def scramble_inverted_holes(world, player):
hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance')) hole_targets.append(('Hyrule Castle Secret Entrance Exit', 'Hyrule Castle Secret Entrance'))
# do not shuffle sanctuary into pyramid hole unless shuffle is crossed # do not shuffle sanctuary into pyramid hole unless shuffle is crossed
if world.shuffle == 'crossed': if world.shuffle[player] == 'crossed':
hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
if world.shuffle_ganon: if world.shuffle_ganon:
random.shuffle(hole_targets) random.shuffle(hole_targets)
exit, target = hole_targets.pop() exit, target = hole_targets.pop()
connect_two_way(world, 'Inverted Pyramid Entrance', exit, player) connect_two_way(world, 'Inverted Pyramid Entrance', exit, player)
connect_entrance(world, 'Inverted Pyramid Hole', target, player) connect_entrance(world, 'Inverted Pyramid Hole', target, player)
if world.shuffle != 'crossed': if world.shuffle[player] != 'crossed':
hole_targets.append(('Sanctuary Exit', 'Sewer Drop')) hole_targets.append(('Sanctuary Exit', 'Sewer Drop'))
random.shuffle(hole_targets) random.shuffle(hole_targets)

View File

@ -174,10 +174,10 @@ def generate_itempool(world, player):
# set up item pool # set up item pool
if world.custom: if world.custom:
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle, world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro, world.customitemarray) (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro, world.customitemarray)
world.rupoor_cost = min(world.customitemarray[69], 9999) world.rupoor_cost = min(world.customitemarray[69], 9999)
else: else:
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle, world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro) (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro)
for item in precollected_items: for item in precollected_items:
world.push_precollected(ItemFactory(item, player)) world.push_precollected(ItemFactory(item, player))

View File

@ -187,7 +187,7 @@ def main(args, seed=None):
world.logic[player], world.difficulty[player], world.difficulty_adjustments[player], world.logic[player], world.difficulty[player], world.difficulty_adjustments[player],
world.mode[player], world.goal[player], world.mode[player], world.goal[player],
"" if world.timer in ['none', 'display'] else "-" + world.timer, "" if world.timer in ['none', 'display'] else "-" + world.timer,
world.shuffle, world.algorithm, mcsb_name, world.shuffle[player], world.algorithm, mcsb_name,
"-retro" if world.retro else "", "-retro" if world.retro else "",
"-prog_" + world.progressive if world.progressive in ['off', 'random'] else "", "-prog_" + world.progressive if world.progressive in ['off', 'random'] else "",
"-nohints" if not world.hints else "")) if not args.outputname else '' "-nohints" if not world.hints else "")) if not args.outputname else ''

View File

@ -137,16 +137,16 @@ def fill_world(world, plando, text_patches):
world.fix_trock_doors = {1: trdstr.strip().lower() == 'true'} world.fix_trock_doors = {1: trdstr.strip().lower() == 'true'}
elif line.startswith('!fix_trock_exit'): elif line.startswith('!fix_trock_exit'):
_, trfstr = line.split(':', 1) _, trfstr = line.split(':', 1)
world.fix_trock_exit = trfstr.strip().lower() == 'true' world.fix_trock_exit = {1: trfstr.strip().lower() == 'true'}
elif line.startswith('!fix_gtower_exit'): elif line.startswith('!fix_gtower_exit'):
_, gtfstr = line.split(':', 1) _, gtfstr = line.split(':', 1)
world.fix_gtower_exit = gtfstr.strip().lower() == 'true' world.fix_gtower_exit = gtfstr.strip().lower() == 'true'
elif line.startswith('!fix_pod_exit'): elif line.startswith('!fix_pod_exit'):
_, podestr = line.split(':', 1) _, podestr = line.split(':', 1)
world.fix_palaceofdarkness_exit = podestr.strip().lower() == 'true' world.fix_palaceofdarkness_exit = {1: podestr.strip().lower() == 'true'}
elif line.startswith('!fix_skullwoods_exit'): elif line.startswith('!fix_skullwoods_exit'):
_, swestr = line.split(':', 1) _, swestr = line.split(':', 1)
world.fix_skullwoods_exit = swestr.strip().lower() == 'true' world.fix_skullwoods_exit = {1: swestr.strip().lower() == 'true'}
elif line.startswith('!check_beatable_only'): elif line.startswith('!check_beatable_only'):
_, chkbtstr = line.split(':', 1) _, chkbtstr = line.split(':', 1)
world.check_beatable_only = chkbtstr.strip().lower() == 'true' world.check_beatable_only = chkbtstr.strip().lower() == 'true'

54
Rom.py
View File

@ -519,17 +519,17 @@ def patch_rom(world, player, rom, enemized):
# Thanks to Zarby89 for originally finding these values # Thanks to Zarby89 for originally finding these values
# todo fix screen scrolling # todo fix screen scrolling
if world.shuffle not in ['insanity', 'insanity_legacy', 'madness_legacy'] and \ if world.shuffle[player] not in ['insanity', 'insanity_legacy', 'madness_legacy'] and \
exit.name in ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Ice Palace Exit', 'Misery Mire Exit', exit.name in ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Ice Palace Exit', 'Misery Mire Exit',
'Palace of Darkness Exit', 'Swamp Palace Exit', 'Ganons Tower Exit', 'Desert Palace Exit (North)', 'Agahnims Tower Exit', 'Spiral Cave Exit (Top)', 'Palace of Darkness Exit', 'Swamp Palace Exit', 'Ganons Tower Exit', 'Desert Palace Exit (North)', 'Agahnims Tower Exit', 'Spiral Cave Exit (Top)',
'Superbunny Cave Exit (Bottom)', 'Turtle Rock Ledge Exit (East)']: 'Superbunny Cave Exit (Bottom)', 'Turtle Rock Ledge Exit (East)']:
# For exits that connot be reached from another, no need to apply offset fixes. # For exits that connot be reached from another, no need to apply offset fixes.
write_int16(rom, 0x15DB5 + 2 * offset, link_y) # same as final else write_int16(rom, 0x15DB5 + 2 * offset, link_y) # same as final else
elif room_id == 0x0059 and world.fix_skullwoods_exit: elif room_id == 0x0059 and world.fix_skullwoods_exit[player]:
write_int16(rom, 0x15DB5 + 2 * offset, 0x00F8) write_int16(rom, 0x15DB5 + 2 * offset, 0x00F8)
elif room_id == 0x004a and world.fix_palaceofdarkness_exit: elif room_id == 0x004a and world.fix_palaceofdarkness_exit[player]:
write_int16(rom, 0x15DB5 + 2 * offset, 0x0640) write_int16(rom, 0x15DB5 + 2 * offset, 0x0640)
elif room_id == 0x00d6 and world.fix_trock_exit: elif room_id == 0x00d6 and world.fix_trock_exit[player]:
write_int16(rom, 0x15DB5 + 2 * offset, 0x0134) write_int16(rom, 0x15DB5 + 2 * offset, 0x0134)
elif room_id == 0x000c and world.fix_gtower_exit: # fix ganons tower exit point elif room_id == 0x000c and world.fix_gtower_exit: # fix ganons tower exit point
write_int16(rom, 0x15DB5 + 2 * offset, 0x00A4) write_int16(rom, 0x15DB5 + 2 * offset, 0x00A4)
@ -581,7 +581,7 @@ def patch_rom(world, player, rom, enemized):
if world.mode[player] in ['open', 'inverted']: if world.mode[player] in ['open', 'inverted']:
rom.write_byte(0x180032, 0x01) # open mode rom.write_byte(0x180032, 0x01) # open mode
if world.mode[player] == 'inverted': if world.mode[player] == 'inverted':
set_inverted_mode(world, rom) set_inverted_mode(world, player, rom)
elif world.mode[player] == 'standard': elif world.mode[player] == 'standard':
rom.write_byte(0x180032, 0x00) # standard mode rom.write_byte(0x180032, 0x00) # standard mode
@ -833,9 +833,9 @@ def patch_rom(world, player, rom, enemized):
rom.write_byte(0x180044, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer activates tablets rom.write_byte(0x180044, 0x01 if world.swords[player] == 'swordless' else 0x00) # hammer activates tablets
# set up clocks for timed modes # set up clocks for timed modes
if world.shuffle == 'vanilla': if world.shuffle[player] == 'vanilla':
ERtimeincrease = 0 ERtimeincrease = 0
elif world.shuffle in ['dungeonssimple', 'dungeonsfull']: elif world.shuffle[player] in ['dungeonssimple', 'dungeonsfull']:
ERtimeincrease = 10 ERtimeincrease = 10
else: else:
ERtimeincrease = 20 ERtimeincrease = 20
@ -883,7 +883,7 @@ def patch_rom(world, player, rom, enemized):
rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed rom.write_bytes(0x180213, [0x00, 0x01]) # Not a Tournament Seed
gametype = 0x04 # item gametype = 0x04 # item
if world.shuffle != 'vanilla': if world.shuffle[player] != 'vanilla':
gametype |= 0x02 # entrance gametype |= 0x02 # entrance
if enemized: if enemized:
gametype |= 0x01 # enemizer gametype |= 0x01 # enemizer
@ -1057,7 +1057,7 @@ def patch_rom(world, player, rom, enemized):
rom.write_bytes(0x02F539, [0xEA, 0xEA, 0xEA, 0xEA, 0xEA] if world.powder_patch_required[player] else [0xAD, 0xBF, 0x0A, 0xF0, 0x4F]) rom.write_bytes(0x02F539, [0xEA, 0xEA, 0xEA, 0xEA, 0xEA] if world.powder_patch_required[player] else [0xAD, 0xBF, 0x0A, 0xF0, 0x4F])
# allow smith into multi-entrance caves in appropriate shuffles # allow smith into multi-entrance caves in appropriate shuffles
if world.shuffle in ['restricted', 'full', 'crossed', 'insanity']: if world.shuffle[player] in ['restricted', 'full', 'crossed', 'insanity']:
rom.write_byte(0x18004C, 0x01) rom.write_byte(0x18004C, 0x01)
# set correct flag for hera basement item # set correct flag for hera basement item
@ -1348,7 +1348,7 @@ def write_strings(rom, world, player):
tt.removeUnwantedText() tt.removeUnwantedText()
# Let's keep this guy's text accurate to the shuffle setting. # Let's keep this guy's text accurate to the shuffle setting.
if world.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple']: if world.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple']:
tt['kakariko_flophouse_man_no_flippers'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.' tt['kakariko_flophouse_man_no_flippers'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.'
tt['kakariko_flophouse_man'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.' tt['kakariko_flophouse_man'] = 'I really hate mowing my yard.\n{PAGEBREAK}\nI should move.'
@ -1379,7 +1379,7 @@ def write_strings(rom, world, player):
entrances_to_hint.update({'Inverted Ganons Tower': 'The sealed castle door'}) entrances_to_hint.update({'Inverted Ganons Tower': 'The sealed castle door'})
else: else:
entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'}) entrances_to_hint.update({'Ganons Tower': 'Ganon\'s Tower'})
if world.shuffle in ['simple', 'restricted', 'restricted_legacy']: if world.shuffle[player] in ['simple', 'restricted', 'restricted_legacy']:
for entrance in all_entrances: for entrance in all_entrances:
if entrance.name in entrances_to_hint: if entrance.name in entrances_to_hint:
this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(entrance.connected_region) + '.' this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(entrance.connected_region) + '.'
@ -1388,9 +1388,9 @@ def write_strings(rom, world, player):
break break
#Now we write inconvenient locations for most shuffles and finish taking care of the less chaotic ones. #Now we write inconvenient locations for most shuffles and finish taking care of the less chaotic ones.
entrances_to_hint.update(InconvenientOtherEntrances) entrances_to_hint.update(InconvenientOtherEntrances)
if world.shuffle in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
hint_count = 0 hint_count = 0
elif world.shuffle in ['simple', 'restricted', 'restricted_legacy']: elif world.shuffle[player] in ['simple', 'restricted', 'restricted_legacy']:
hint_count = 2 hint_count = 2
else: else:
hint_count = 4 hint_count = 4
@ -1405,14 +1405,14 @@ def write_strings(rom, world, player):
break break
#Next we handle hints for randomly selected other entrances, curating the selection intelligently based on shuffle. #Next we handle hints for randomly selected other entrances, curating the selection intelligently based on shuffle.
if world.shuffle not in ['simple', 'restricted', 'restricted_legacy']: if world.shuffle[player] not in ['simple', 'restricted', 'restricted_legacy']:
entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(ConnectorEntrances)
entrances_to_hint.update(DungeonEntrances) entrances_to_hint.update(DungeonEntrances)
if world.mode[player] == 'inverted': if world.mode[player] == 'inverted':
entrances_to_hint.update({'Inverted Agahnims Tower': 'The dark mountain tower'}) entrances_to_hint.update({'Inverted Agahnims Tower': 'The dark mountain tower'})
else: else:
entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'})
elif world.shuffle == 'restricted': elif world.shuffle[player] == 'restricted':
entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(ConnectorEntrances)
entrances_to_hint.update(OtherEntrances) entrances_to_hint.update(OtherEntrances)
if world.mode[player] == 'inverted': if world.mode[player] == 'inverted':
@ -1422,14 +1422,14 @@ def write_strings(rom, world, player):
else: else:
entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'}) entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'})
entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'}) entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'})
if world.shuffle in ['insanity', 'madness_legacy', 'insanity_legacy']: if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']:
entrances_to_hint.update(InsanityEntrances) entrances_to_hint.update(InsanityEntrances)
if world.shuffle_ganon: if world.shuffle_ganon:
if world.mode[player] == 'inverted': if world.mode[player] == 'inverted':
entrances_to_hint.update({'Inverted Pyramid Entrance': 'The extra castle passage'}) entrances_to_hint.update({'Inverted Pyramid Entrance': 'The extra castle passage'})
else: else:
entrances_to_hint.update({'Pyramid Ledge': 'The pyramid ledge'}) entrances_to_hint.update({'Pyramid Ledge': 'The pyramid ledge'})
hint_count = 4 if world.shuffle not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 0 hint_count = 4 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 0
for entrance in all_entrances: for entrance in all_entrances:
if entrance.name in entrances_to_hint: if entrance.name in entrances_to_hint:
if hint_count > 0: if hint_count > 0:
@ -1442,10 +1442,10 @@ def write_strings(rom, world, player):
# Next we write a few hints for specific inconvenient locations. We don't make many because in entrance this is highly unpredictable. # Next we write a few hints for specific inconvenient locations. We don't make many because in entrance this is highly unpredictable.
locations_to_hint = InconvenientLocations.copy() locations_to_hint = InconvenientLocations.copy()
if world.shuffle in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
locations_to_hint.extend(InconvenientVanillaLocations) locations_to_hint.extend(InconvenientVanillaLocations)
random.shuffle(locations_to_hint) random.shuffle(locations_to_hint)
hint_count = 3 if world.shuffle not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 5 hint_count = 3 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 5
del locations_to_hint[hint_count:] del locations_to_hint[hint_count:]
for location in locations_to_hint: for location in locations_to_hint:
if location == 'Swamp Left': if location == 'Swamp Left':
@ -1498,7 +1498,7 @@ def write_strings(rom, world, player):
if world.bigkeyshuffle: if world.bigkeyshuffle:
items_to_hint.extend(BigKeys) items_to_hint.extend(BigKeys)
random.shuffle(items_to_hint) random.shuffle(items_to_hint)
hint_count = 5 if world.shuffle not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 8 hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 8
while hint_count > 0: while hint_count > 0:
this_item = items_to_hint.pop(0) this_item = items_to_hint.pop(0)
this_location = world.find_items(this_item, player) this_location = world.find_items(this_item, player)
@ -1641,7 +1641,7 @@ def write_strings(rom, world, player):
rom.write_bytes(0x181500, data) rom.write_bytes(0x181500, data)
rom.write_bytes(0x76CC0, [byte for p in pointers for byte in [p & 0xFF, p >> 8 & 0xFF]]) rom.write_bytes(0x76CC0, [byte for p in pointers for byte in [p & 0xFF, p >> 8 & 0xFF]])
def set_inverted_mode(world, rom): def set_inverted_mode(world, player, rom):
rom.write_byte(snes_to_pc(0x0283E0), 0xF0) # residual portals rom.write_byte(snes_to_pc(0x0283E0), 0xF0) # residual portals
rom.write_byte(snes_to_pc(0x02B34D), 0xF0) rom.write_byte(snes_to_pc(0x02B34D), 0xF0)
rom.write_byte(snes_to_pc(0x06DB78), 0x8B) rom.write_byte(snes_to_pc(0x06DB78), 0x8B)
@ -1654,12 +1654,12 @@ def set_inverted_mode(world, rom):
rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph proof rom.write_byte(snes_to_pc(0x08D40C), 0xD0) # morph proof
# the following bytes should only be written in vanilla # the following bytes should only be written in vanilla
# or they'll overwrite the randomizer's shuffles # or they'll overwrite the randomizer's shuffles
if world.shuffle == 'vanilla': if world.shuffle[player] == 'vanilla':
rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT rom.write_byte(0xDBB73 + 0x23, 0x37) # switch AT and GT
rom.write_byte(0xDBB73 + 0x36, 0x24) rom.write_byte(0xDBB73 + 0x36, 0x24)
write_int16(rom, 0x15AEE + 2*0x38, 0x00E0) write_int16(rom, 0x15AEE + 2*0x38, 0x00E0)
write_int16(rom, 0x15AEE + 2*0x25, 0x000C) write_int16(rom, 0x15AEE + 2*0x25, 0x000C)
if world.shuffle in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
rom.write_byte(0x15B8C, 0x6C) rom.write_byte(0x15B8C, 0x6C)
rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house rom.write_byte(0xDBB73 + 0x00, 0x53) # switch bomb shop and links house
rom.write_byte(0xDBB73 + 0x52, 0x01) rom.write_byte(0xDBB73 + 0x52, 0x01)
@ -1717,7 +1717,7 @@ def set_inverted_mode(world, rom):
write_int16(rom, snes_to_pc(0x02D9A6), 0x005A) write_int16(rom, snes_to_pc(0x02D9A6), 0x005A)
rom.write_byte(snes_to_pc(0x02D9B3), 0x12) rom.write_byte(snes_to_pc(0x02D9B3), 0x12)
# keep the old man spawn point at old man house unless shuffle is vanilla # keep the old man spawn point at old man house unless shuffle is vanilla
if world.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple']: if world.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple']:
rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01])
write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1)
rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03]) rom.write_bytes(snes_to_pc(0x02D910), [0x1F, 0x1E, 0x1F, 0x1F, 0x03, 0x02, 0x03, 0x03])
@ -1780,7 +1780,7 @@ def set_inverted_mode(world, rom):
write_int16s(rom, snes_to_pc(0x1bb836), [0x001B, 0x001B, 0x001B]) write_int16s(rom, snes_to_pc(0x1bb836), [0x001B, 0x001B, 0x001B])
write_int16(rom, snes_to_pc(0x308300), 0x0140) # new pyramid hole entrance write_int16(rom, snes_to_pc(0x308300), 0x0140) # new pyramid hole entrance
write_int16(rom, snes_to_pc(0x308320), 0x001B) write_int16(rom, snes_to_pc(0x308320), 0x001B)
if world.shuffle in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
rom.write_byte(snes_to_pc(0x308340), 0x7B) rom.write_byte(snes_to_pc(0x308340), 0x7B)
write_int16(rom, snes_to_pc(0x1af504), 0x148B) write_int16(rom, snes_to_pc(0x1af504), 0x148B)
write_int16(rom, snes_to_pc(0x1af50c), 0x149B) write_int16(rom, snes_to_pc(0x1af50c), 0x149B)
@ -1817,10 +1817,10 @@ def set_inverted_mode(world, rom):
rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82])
write_int16(rom, 0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door write_int16(rom, 0xDB96F + 2 * 0x35, 0x001B) # move pyramid exit door
write_int16(rom, 0xDBA71 + 2 * 0x35, 0x06A4) write_int16(rom, 0xDBA71 + 2 * 0x35, 0x06A4)
if world.shuffle in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
rom.write_byte(0xDBB73 + 0x35, 0x36) rom.write_byte(0xDBB73 + 0x35, 0x36)
rom.write_byte(snes_to_pc(0x09D436), 0xF3) # remove castle gate warp rom.write_byte(snes_to_pc(0x09D436), 0xF3) # remove castle gate warp
if world.shuffle in ['vanilla', 'dungeonssimple', 'dungeonsfull']: if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area
rom.write_byte(0x15B8C + 0x37, 0x1B) rom.write_byte(0x15B8C + 0x37, 0x1B)
write_int16(rom, 0x15BDB + 2 * 0x37, 0x0418) write_int16(rom, 0x15BDB + 2 * 0x37, 0x0418)

View File

@ -16,7 +16,7 @@ def set_rules(world, player):
else: else:
world.get_region('Inverted Links House', player).can_reach_private = lambda state: True world.get_region('Inverted Links House', player).can_reach_private = lambda state: True
world.get_region('Inverted Dark Sanctuary', player).entrances[0].parent_region.can_reach_private = lambda state: True world.get_region('Inverted Dark Sanctuary', player).entrances[0].parent_region.can_reach_private = lambda state: True
if world.shuffle != 'vanilla': if world.shuffle[player] != 'vanilla':
old_rule = world.get_region('Old Man House', player).can_reach old_rule = world.get_region('Old Man House', player).can_reach
world.get_region('Old Man House', player).can_reach_private = lambda state: state.can_reach('Old Man', 'Location', player) or old_rule(state) world.get_region('Old Man House', player).can_reach_private = lambda state: state.can_reach('Old Man', 'Location', player) or old_rule(state)
return return