Allow Zelda escape to use TT Maiden Cell as checkpoint
This commit is contained in:
@@ -76,6 +76,7 @@ class World(object):
|
|||||||
self.can_take_damage = True
|
self.can_take_damage = True
|
||||||
self.hints = hints.copy()
|
self.hints = hints.copy()
|
||||||
self.prizes = {}
|
self.prizes = {}
|
||||||
|
self.default_zelda_region = {}
|
||||||
self.dynamic_regions = []
|
self.dynamic_regions = []
|
||||||
self.dynamic_locations = []
|
self.dynamic_locations = []
|
||||||
self.spoiler_mode = spoiler_mode
|
self.spoiler_mode = spoiler_mode
|
||||||
@@ -185,6 +186,7 @@ class World(object):
|
|||||||
set_player_attr('standardize_palettes', 'standardize')
|
set_player_attr('standardize_palettes', 'standardize')
|
||||||
set_player_attr('force_fix', {'gt': False, 'sw': False, 'pod': False, 'tr': False})
|
set_player_attr('force_fix', {'gt': False, 'sw': False, 'pod': False, 'tr': False})
|
||||||
set_player_attr('prizes', {'dig;': [], 'pull': [0, 0, 0], 'crab': [0, 0], 'stun': 0, 'fish': 0, 'enemies': []})
|
set_player_attr('prizes', {'dig;': [], 'pull': [0, 0, 0], 'crab': [0, 0], 'stun': 0, 'fish': 0, 'enemies': []})
|
||||||
|
set_player_attr('default_zelda_region', 'Hyrule Dungeon Cellblock')
|
||||||
|
|
||||||
set_player_attr('exp_cache', defaultdict(dict))
|
set_player_attr('exp_cache', defaultdict(dict))
|
||||||
set_player_attr('enabled_entrances', {})
|
set_player_attr('enabled_entrances', {})
|
||||||
|
|||||||
8
Doors.py
8
Doors.py
@@ -1302,8 +1302,12 @@ def create_doors(world, player):
|
|||||||
world.get_door('Swamp Flooded Room Ladder', player).event('Swamp Drain')
|
world.get_door('Swamp Flooded Room Ladder', player).event('Swamp Drain')
|
||||||
|
|
||||||
if world.mode[player] == 'standard' and 'Zelda Herself' not in [i.name for i in world.precollected_items if i.player == player]:
|
if world.mode[player] == 'standard' and 'Zelda Herself' not in [i.name for i in world.precollected_items if i.player == player]:
|
||||||
world.get_door('Hyrule Castle Throne Room Tapestry', player).event('Zelda Pickup')
|
if world.default_zelda_region[player] == 'Thieves Blind\'s Cell':
|
||||||
world.get_door('Hyrule Castle Tapestry Backwards', player).event('Zelda Pickup')
|
zelda_location = 'Suspicious Maiden'
|
||||||
|
else:
|
||||||
|
zelda_location = 'Zelda Pickup'
|
||||||
|
world.get_door('Hyrule Castle Throne Room Tapestry', player).event(zelda_location)
|
||||||
|
world.get_door('Hyrule Castle Tapestry Backwards', player).event(zelda_location)
|
||||||
|
|
||||||
# crystal switches and barriers
|
# crystal switches and barriers
|
||||||
world.get_door('Hera Lobby Crystal Exit', player).c_switch()
|
world.get_door('Hera Lobby Crystal Exit', player).c_switch()
|
||||||
|
|||||||
@@ -586,13 +586,13 @@ def determine_paths_for_dungeon(world, player, all_regions, name):
|
|||||||
paths.append(portal.door.entrance.parent_region.name)
|
paths.append(portal.door.entrance.parent_region.name)
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard':
|
||||||
if name == 'Hyrule Castle':
|
if name == 'Hyrule Castle':
|
||||||
paths.append('Hyrule Dungeon Cellblock')
|
paths.append(world.default_zelda_region[player])
|
||||||
paths.append(('Hyrule Dungeon Cellblock', 'Sanctuary'))
|
paths.append((world.default_zelda_region[player], 'Sanctuary'))
|
||||||
if name == 'Hyrule Castle Sewers':
|
if name == 'Hyrule Castle Sewers':
|
||||||
paths.append('Sanctuary')
|
paths.append('Sanctuary')
|
||||||
if name == 'Hyrule Castle Dungeon':
|
if name == 'Hyrule Castle Dungeon':
|
||||||
paths.append('Hyrule Dungeon Cellblock')
|
paths.append(world.default_zelda_region[player])
|
||||||
paths.append(('Hyrule Dungeon Cellblock', 'Hyrule Castle Throne Room'))
|
paths.append((world.default_zelda_region[player], 'Hyrule Castle Throne Room'))
|
||||||
if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town':
|
if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town':
|
||||||
paths.append('Thieves Attic Window')
|
paths.append('Thieves Attic Window')
|
||||||
elif 'Thieves Attic Window' in all_r_names:
|
elif 'Thieves Attic Window' in all_r_names:
|
||||||
@@ -1322,7 +1322,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge
|
|||||||
for r_name in dungeon_boss_sectors[key]:
|
for r_name in dungeon_boss_sectors[key]:
|
||||||
assign_sector(find_sector(r_name, candidate_sectors), current_dungeon, candidate_sectors, global_pole)
|
assign_sector(find_sector(r_name, candidate_sectors), current_dungeon, candidate_sectors, global_pole)
|
||||||
if key == 'Hyrule Castle' and world.mode[player] == 'standard':
|
if key == 'Hyrule Castle' and world.mode[player] == 'standard':
|
||||||
for r_name in ['Hyrule Dungeon Cellblock', 'Sanctuary', 'Hyrule Castle Throne Room']: # need to deliver zelda
|
for r_name in [world.default_zelda_region[player], 'Sanctuary', 'Hyrule Castle Throne Room']: # need to deliver zelda
|
||||||
assign_sector(find_sector(r_name, candidate_sectors), current_dungeon,
|
assign_sector(find_sector(r_name, candidate_sectors), current_dungeon,
|
||||||
candidate_sectors, global_pole)
|
candidate_sectors, global_pole)
|
||||||
if key == 'Thieves Town' and (world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind'
|
if key == 'Thieves Town' and (world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind'
|
||||||
@@ -3091,7 +3091,7 @@ def split_dungeon_builder(builder, split_list, builder_info):
|
|||||||
if builder.name == 'Hyrule Castle':
|
if builder.name == 'Hyrule Castle':
|
||||||
assign_sector(find_sector('Hyrule Castle Throne Room', candidate_sectors),
|
assign_sector(find_sector('Hyrule Castle Throne Room', candidate_sectors),
|
||||||
dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole)
|
dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole)
|
||||||
assign_sector(find_sector('Hyrule Dungeon Cellblock', candidate_sectors),
|
assign_sector(find_sector(world.default_zelda_region[player], candidate_sectors),
|
||||||
dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole)
|
dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole)
|
||||||
dungeon_map['Hyrule Castle Dungeon'].throne_door = world.get_door('Hyrule Castle Throne Room N', player)
|
dungeon_map['Hyrule Castle Dungeon'].throne_door = world.get_door('Hyrule Castle Throne Room N', player)
|
||||||
dungeon_map['Hyrule Castle Sewers'].sewers_access = builder.throne_door
|
dungeon_map['Hyrule Castle Sewers'].sewers_access = builder.throne_door
|
||||||
|
|||||||
15
ItemList.py
15
ItemList.py
@@ -1676,7 +1676,7 @@ def set_event_item(world, player, location_name, item_name=None):
|
|||||||
|
|
||||||
|
|
||||||
def shuffle_event_items(world, player):
|
def shuffle_event_items(world, player):
|
||||||
if (world.shuffle_followers[player]):
|
if world.shuffle_followers[player]:
|
||||||
available_quests = follower_quests.copy()
|
available_quests = follower_quests.copy()
|
||||||
available_pickups = [quests[0] for quests in available_quests.values()]
|
available_pickups = [quests[0] for quests in available_quests.values()]
|
||||||
|
|
||||||
@@ -1688,11 +1688,14 @@ def shuffle_event_items(world, player):
|
|||||||
available_pickups.remove(loc.item.name)
|
available_pickups.remove(loc.item.name)
|
||||||
|
|
||||||
|
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard' and 'Zelda Herself' in available_pickups:
|
||||||
if 'Zelda Herself' in available_pickups:
|
zelda_dropoff = 'Zelda Pickup'
|
||||||
zelda_pickup = available_quests.pop('Zelda Pickup')[0]
|
if world.default_zelda_region[player] == 'Thieves Blind\'s Cell':
|
||||||
available_pickups.remove(zelda_pickup)
|
zelda_dropoff = 'Suspicious Maiden'
|
||||||
set_event_item(world, player, 'Zelda Pickup', zelda_pickup)
|
available_quests.pop(zelda_dropoff)
|
||||||
|
zelda_pickup = 'Zelda Herself'
|
||||||
|
available_pickups.remove(zelda_pickup)
|
||||||
|
set_event_item(world, player, zelda_dropoff, zelda_pickup)
|
||||||
|
|
||||||
random.shuffle(available_pickups)
|
random.shuffle(available_pickups)
|
||||||
|
|
||||||
|
|||||||
@@ -1805,7 +1805,10 @@ def imp_locations_factory(world, player):
|
|||||||
return imp_locations
|
return imp_locations
|
||||||
imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden']
|
imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden']
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard':
|
||||||
imp_locations.append('Zelda Pickup')
|
if world.default_zelda_region[player] == 'Thieves Blinds\' Cell':
|
||||||
|
imp_locations.append('Suspicious Maiden')
|
||||||
|
else:
|
||||||
|
imp_locations.append('Zelda Pickup')
|
||||||
imp_locations.append('Zelda Drop Off')
|
imp_locations.append('Zelda Drop Off')
|
||||||
return imp_locations
|
return imp_locations
|
||||||
|
|
||||||
|
|||||||
14
Rom.py
14
Rom.py
@@ -43,7 +43,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = '93386b05ee4b5de6b9165941b9e14e97'
|
RANDOMIZERBASEHASH = '20e588b832011dcf15dbd31dff6955ce'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -1581,6 +1581,18 @@ def patch_rom(world, rom, player, team, is_mystery=False):
|
|||||||
rom.write_bytes(snes_to_pc(0x09A045), [0xEA, 0xEA]) # allow super bomb to follow into UW holes
|
rom.write_bytes(snes_to_pc(0x09A045), [0xEA, 0xEA]) # allow super bomb to follow into UW holes
|
||||||
rom.write_byte(snes_to_pc(0x09ACDF), 0x6B) # allow kiki/locksmith to follow after screen transition
|
rom.write_byte(snes_to_pc(0x09ACDF), 0x6B) # allow kiki/locksmith to follow after screen transition
|
||||||
|
|
||||||
|
if world.default_zelda_region[player] == 'Thieves Blind\'s Cell':
|
||||||
|
write_int16(rom, snes_to_pc(0x02D8D6), 0x45) # change zelda spawn point to maiden cell
|
||||||
|
rom.write_bytes(snes_to_pc(0x02D8F0), [0x08, 0x08, 0x08, 0x09, 0x0B, 0x0A, 0x0B, 0x0B])
|
||||||
|
write_int16(rom, snes_to_pc(0x02D91C), 0x0B00)
|
||||||
|
write_int16(rom, snes_to_pc(0x02D92A), 0x0800)
|
||||||
|
write_int16(rom, snes_to_pc(0x02D938), 0x0860)
|
||||||
|
write_int16(rom, snes_to_pc(0x02D946), 0x0B90)
|
||||||
|
write_int16(rom, snes_to_pc(0x02D954), 0x0078)
|
||||||
|
write_int16(rom, snes_to_pc(0x02D962), 0x017F)
|
||||||
|
rom.write_byte(snes_to_pc(0x02D975), 0x00)
|
||||||
|
rom.write_byte(snes_to_pc(0x02D98A), 0x02)
|
||||||
|
|
||||||
if world.enemy_shuffle[player] != 'none':
|
if world.enemy_shuffle[player] != 'none':
|
||||||
# informs zelda and maiden to draw over gfx slots that are guaranteed unused
|
# informs zelda and maiden to draw over gfx slots that are guaranteed unused
|
||||||
rom.write_bytes(0x1802C1, world.data_tables[player].room_headers[0x80].free_gfx[0:2])
|
rom.write_bytes(0x1802C1, world.data_tables[player].room_headers[0x80].free_gfx[0:2])
|
||||||
|
|||||||
2
Rules.py
2
Rules.py
@@ -1669,7 +1669,7 @@ def standard_rules(world, player):
|
|||||||
|
|
||||||
def find_rules_for_zelda_delivery(world, player):
|
def find_rules_for_zelda_delivery(world, player):
|
||||||
# path rules for backtracking
|
# path rules for backtracking
|
||||||
start_region = world.get_region('Hyrule Dungeon Cellblock', player)
|
start_region = world.get_region(world.default_zelda_region[player], player)
|
||||||
queue = deque([(start_region, [], [])])
|
queue = deque([(start_region, [], [])])
|
||||||
visited = {start_region}
|
visited = {start_region}
|
||||||
blank_state = CollectionState(world)
|
blank_state = CollectionState(world)
|
||||||
|
|||||||
Binary file not shown.
@@ -333,13 +333,13 @@ def determine_paths_for_dungeon(world, player, all_regions, name):
|
|||||||
if portal.destination:
|
if portal.destination:
|
||||||
paths.append(portal.door.entrance.parent_region.name)
|
paths.append(portal.door.entrance.parent_region.name)
|
||||||
if world.mode[player] == 'standard' and name == 'Hyrule Castle Dungeon':
|
if world.mode[player] == 'standard' and name == 'Hyrule Castle Dungeon':
|
||||||
paths.append('Hyrule Dungeon Cellblock')
|
paths.append(world.default_zelda_region[player])
|
||||||
paths.append(('Hyrule Dungeon Cellblock', 'Hyrule Castle Throne Room'))
|
paths.append((world.default_zelda_region[player], 'Hyrule Castle Throne Room'))
|
||||||
entrance = next(x for x in world.dungeon_portals[player] if x.name == 'Hyrule Castle South')
|
entrance = next(x for x in world.dungeon_portals[player] if x.name == 'Hyrule Castle South')
|
||||||
# todo: in non-er, we can use the other portals too
|
# todo: in non-er, we can use the other portals too
|
||||||
paths.append(('Hyrule Dungeon Cellblock', entrance.door.entrance.parent_region.name))
|
paths.append((world.default_zelda_region[player], entrance.door.entrance.parent_region.name))
|
||||||
paths.append(('Hyrule Castle Throne Room', [entrance.door.entrance.parent_region.name,
|
paths.append(('Hyrule Castle Throne Room', [entrance.door.entrance.parent_region.name,
|
||||||
'Hyrule Dungeon Cellblock']))
|
world.default_zelda_region[player]]))
|
||||||
if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town':
|
if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town':
|
||||||
paths.append('Thieves Attic Window')
|
paths.append('Thieves Attic Window')
|
||||||
elif 'Thieves Attic Window' in all_r_names:
|
elif 'Thieves Attic Window' in all_r_names:
|
||||||
|
|||||||
@@ -521,6 +521,21 @@ def randomize_enemies(world, player):
|
|||||||
green_mail, blue_mail, red_mail = original_table[idx]
|
green_mail, blue_mail, red_mail = original_table[idx]
|
||||||
del original_table[idx]
|
del original_table[idx]
|
||||||
world.data_tables[player].enemy_damage[i] = [green_mail, blue_mail, red_mail]
|
world.data_tables[player].enemy_damage[i] = [green_mail, blue_mail, red_mail]
|
||||||
|
# determine default zelda follower location
|
||||||
|
if world.mode[player] == 'standard' and world.doorShuffle[player] == 'crossed' and world.shuffle_followers[player]:
|
||||||
|
def random_zelda():
|
||||||
|
world.default_zelda_region[player] = random.choice(['Hyrule Dungeon Cellblock', 'Thieves Blind\'s Cell'])
|
||||||
|
if world.customizer:
|
||||||
|
placements = world.customizer.get_placements()
|
||||||
|
if placements and player in placements and 'Zelda Herself' in placements[player].values():
|
||||||
|
location = [l for (l, item) in placements[player].items() if item == 'Zelda Herself'][0]
|
||||||
|
if location == 'Suspicious Maiden':
|
||||||
|
world.default_zelda_region[player] = 'Thieves Blind\'s Cell'
|
||||||
|
else:
|
||||||
|
random_zelda()
|
||||||
|
else:
|
||||||
|
random_zelda()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def write_enemy_shuffle_settings(world, player, rom):
|
def write_enemy_shuffle_settings(world, player, rom):
|
||||||
|
|||||||
Reference in New Issue
Block a user