Merge branch 'OverworldShuffleDev' into OverworldShuffle
This commit is contained in:
+57
-39
@@ -120,7 +120,7 @@ class World(object):
|
|||||||
set_player_attr('can_access_trock_front', None)
|
set_player_attr('can_access_trock_front', None)
|
||||||
set_player_attr('can_access_trock_big_chest', None)
|
set_player_attr('can_access_trock_big_chest', None)
|
||||||
set_player_attr('can_access_trock_middle', None)
|
set_player_attr('can_access_trock_middle', None)
|
||||||
set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'nologic'] or shuffle[player] in ['crossed', 'insanity', 'madness_legacy'])
|
set_player_attr('fix_fake_world', logic[player] not in ['owglitches', 'nologic'] or shuffle[player] in ['lite', 'lean', 'crossed', 'insanity', 'madness_legacy'])
|
||||||
set_player_attr('mapshuffle', False)
|
set_player_attr('mapshuffle', False)
|
||||||
set_player_attr('compassshuffle', False)
|
set_player_attr('compassshuffle', False)
|
||||||
set_player_attr('keyshuffle', False)
|
set_player_attr('keyshuffle', False)
|
||||||
@@ -606,7 +606,7 @@ class CollectionState(object):
|
|||||||
queue.append((new_entrance, new_crystal_state))
|
queue.append((new_entrance, new_crystal_state))
|
||||||
# else those connections that are not accessible yet
|
# else those connections that are not accessible yet
|
||||||
if self.is_small_door(connection):
|
if self.is_small_door(connection):
|
||||||
door = connection.door
|
door = connection.door if connection.door.smallKey else connection.door.controller
|
||||||
dungeon_name = connection.parent_region.dungeon.name
|
dungeon_name = connection.parent_region.dungeon.name
|
||||||
key_logic = self.world.key_logic[player][dungeon_name]
|
key_logic = self.world.key_logic[player][dungeon_name]
|
||||||
if door.name not in self.reached_doors[player]:
|
if door.name not in self.reached_doors[player]:
|
||||||
@@ -620,7 +620,7 @@ class CollectionState(object):
|
|||||||
checklist[connection.name] = (connection, crystal_state)
|
checklist[connection.name] = (connection, crystal_state)
|
||||||
elif door.name not in self.opened_doors[player]:
|
elif door.name not in self.opened_doors[player]:
|
||||||
opened_doors = self.opened_doors[player]
|
opened_doors = self.opened_doors[player]
|
||||||
door = connection.door
|
door = connection.door if connection.door.smallKey else connection.door.controller
|
||||||
if door.name not in opened_doors:
|
if door.name not in opened_doors:
|
||||||
self.door_counter[player][1][dungeon_name] += 1
|
self.door_counter[player][1][dungeon_name] += 1
|
||||||
opened_doors.add(door.name)
|
opened_doors.add(door.name)
|
||||||
@@ -1003,7 +1003,12 @@ class CollectionState(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_small_door(connection):
|
def is_small_door(connection):
|
||||||
return connection and connection.door and connection.door.smallKey
|
return connection and connection.door and (connection.door.smallKey or
|
||||||
|
CollectionState.is_controlled_by_small(connection))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_controlled_by_small(connection):
|
||||||
|
return connection.door.controller and connection.door.controller.smallKey
|
||||||
|
|
||||||
def is_door_open(self, door_name, player):
|
def is_door_open(self, door_name, player):
|
||||||
return door_name in self.opened_doors[player]
|
return door_name in self.opened_doors[player]
|
||||||
@@ -1234,7 +1239,7 @@ class CollectionState(object):
|
|||||||
|
|
||||||
# In the future, this can be used to check if the player starts without bombs
|
# In the future, this can be used to check if the player starts without bombs
|
||||||
def can_use_bombs(self, player):
|
def can_use_bombs(self, player):
|
||||||
return (not self.world.bombbag[player] or self.has('Bomb Upgrade (+10)', player)) and self.can_farm_bombs(player)
|
return (not self.world.bombbag[player] or self.has('Bomb Upgrade (+10)', player)) and ((hasattr(self.world,"override_bomb_check") and self.world.override_bomb_check) or self.can_farm_bombs(player))
|
||||||
|
|
||||||
def can_hit_crystal(self, player):
|
def can_hit_crystal(self, player):
|
||||||
return (self.can_use_bombs(player)
|
return (self.can_use_bombs(player)
|
||||||
@@ -1296,6 +1301,8 @@ class CollectionState(object):
|
|||||||
return self.has('Fire Rod', player) or self.has('Lamp', player)
|
return self.has('Fire Rod', player) or self.has('Lamp', player)
|
||||||
|
|
||||||
def can_flute(self, player):
|
def can_flute(self, player):
|
||||||
|
if any(map(lambda i: i.name == 'Ocarina', self.world.precollected_items)):
|
||||||
|
return True
|
||||||
lw = self.world.get_region('Kakariko Area', player)
|
lw = self.world.get_region('Kakariko Area', player)
|
||||||
return self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player)
|
return self.has('Ocarina', player) and lw.can_reach(self) and self.is_not_bunny(lw, player)
|
||||||
|
|
||||||
@@ -1833,6 +1840,7 @@ class Door(object):
|
|||||||
self.bk_shuffle_req = False
|
self.bk_shuffle_req = False
|
||||||
self.standard_restricted = False # flag if portal is not allowed in HC in standard
|
self.standard_restricted = False # flag if portal is not allowed in HC in standard
|
||||||
self.lw_restricted = False # flag if portal is not allowed in DW
|
self.lw_restricted = False # flag if portal is not allowed in DW
|
||||||
|
self.rupee_bow_restricted = False # flag if portal is not allowed in HC in standard+rupee_bow
|
||||||
# self.incognitoPos = -1
|
# self.incognitoPos = -1
|
||||||
# self.sectorLink = False
|
# self.sectorLink = False
|
||||||
|
|
||||||
@@ -2687,6 +2695,8 @@ class Spoiler(object):
|
|||||||
'ow_mixed': self.world.owMixed,
|
'ow_mixed': self.world.owMixed,
|
||||||
'ow_fluteshuffle': self.world.owFluteShuffle,
|
'ow_fluteshuffle': self.world.owFluteShuffle,
|
||||||
'shuffle': self.world.shuffle,
|
'shuffle': self.world.shuffle,
|
||||||
|
'shuffleganon': self.world.shuffle_ganon,
|
||||||
|
'shufflelinks': self.world.shufflelinks,
|
||||||
'door_shuffle': self.world.doorShuffle,
|
'door_shuffle': self.world.doorShuffle,
|
||||||
'intensity': self.world.intensity,
|
'intensity': self.world.intensity,
|
||||||
'item_pool': self.world.difficulty,
|
'item_pool': self.world.difficulty,
|
||||||
@@ -2762,8 +2772,13 @@ class Spoiler(object):
|
|||||||
if self.metadata['goal'][player] == 'triforcehunt':
|
if self.metadata['goal'][player] == 'triforcehunt':
|
||||||
outfile.write('Triforce Pieces Required:'.ljust(line_width) + '%s\n' % self.metadata['triforcegoal'][player])
|
outfile.write('Triforce Pieces Required:'.ljust(line_width) + '%s\n' % self.metadata['triforcegoal'][player])
|
||||||
outfile.write('Triforce Pieces Total:'.ljust(line_width) + '%s\n' % self.metadata['triforcepool'][player])
|
outfile.write('Triforce Pieces Total:'.ljust(line_width) + '%s\n' % self.metadata['triforcepool'][player])
|
||||||
|
outfile.write('Crystals Required for GT:'.ljust(line_width) + '%s\n' % str(self.world.crystals_gt_orig[player]))
|
||||||
|
outfile.write('Crystals Required for Ganon:'.ljust(line_width) + '%s\n' % str(self.world.crystals_ganon_orig[player]))
|
||||||
|
outfile.write('Accessibility:'.ljust(line_width) + '%s\n' % self.metadata['accessibility'][player])
|
||||||
outfile.write('Difficulty:'.ljust(line_width) + '%s\n' % self.metadata['item_pool'][player])
|
outfile.write('Difficulty:'.ljust(line_width) + '%s\n' % self.metadata['item_pool'][player])
|
||||||
outfile.write('Item Functionality:'.ljust(line_width) + '%s\n' % self.metadata['item_functionality'][player])
|
outfile.write('Item Functionality:'.ljust(line_width) + '%s\n' % self.metadata['item_functionality'][player])
|
||||||
|
outfile.write('Shopsanity:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shopsanity'][player] else 'No'))
|
||||||
|
outfile.write('Bombbag:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['bombbag'][player] else 'No'))
|
||||||
outfile.write('Overworld Layout Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_shuffle'][player])
|
outfile.write('Overworld Layout Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_shuffle'][player])
|
||||||
if self.metadata['ow_shuffle'][player] != 'vanilla':
|
if self.metadata['ow_shuffle'][player] != 'vanilla':
|
||||||
outfile.write('Keep Similar OW Edges Together:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_keepsimilar'][player] else 'No'))
|
outfile.write('Keep Similar OW Edges Together:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_keepsimilar'][player] else 'No'))
|
||||||
@@ -2771,28 +2786,45 @@ class Spoiler(object):
|
|||||||
outfile.write('Swapped OW (Mixed):'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_mixed'][player] else 'No'))
|
outfile.write('Swapped OW (Mixed):'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['ow_mixed'][player] else 'No'))
|
||||||
outfile.write('Flute Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_fluteshuffle'][player])
|
outfile.write('Flute Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['ow_fluteshuffle'][player])
|
||||||
outfile.write('Entrance Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['shuffle'][player])
|
outfile.write('Entrance Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['shuffle'][player])
|
||||||
|
outfile.write('Shuffle GT/Ganon:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shuffleganon'][player] else 'No'))
|
||||||
|
outfile.write('Shuffle Links:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shufflelinks'][player] else 'No'))
|
||||||
|
outfile.write('Pyramid Hole Pre-opened:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No'))
|
||||||
outfile.write('Door Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['door_shuffle'][player])
|
outfile.write('Door Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['door_shuffle'][player])
|
||||||
outfile.write('Intensity:'.ljust(line_width) + '%s\n' % self.metadata['intensity'][player])
|
outfile.write('Intensity:'.ljust(line_width) + '%s\n' % self.metadata['intensity'][player])
|
||||||
addition = ' (Random)' if self.world.crystals_gt_orig[player] == 'random' else ''
|
|
||||||
outfile.write('Crystals required for GT:'.ljust(line_width) + '%s\n' % (str(self.metadata['gt_crystals'][player]) + addition))
|
|
||||||
addition = ' (Random)' if self.world.crystals_ganon_orig[player] == 'random' else ''
|
|
||||||
outfile.write('Crystals required for Ganon:'.ljust(line_width) + '%s\n' % (str(self.metadata['ganon_crystals'][player]) + addition))
|
|
||||||
outfile.write('Pyramid hole pre-opened:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No'))
|
|
||||||
outfile.write('Accessibility:'.ljust(line_width) + '%s\n' % self.metadata['accessibility'][player])
|
|
||||||
outfile.write('Map shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No'))
|
|
||||||
outfile.write('Compass shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['compassshuffle'][player] else 'No'))
|
|
||||||
outfile.write('Small Key shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['keyshuffle'][player] else 'No'))
|
|
||||||
outfile.write('Big Key shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['bigkeyshuffle'][player] else 'No'))
|
|
||||||
outfile.write('Boss shuffle:'.ljust(line_width) + '%s\n' % self.metadata['boss_shuffle'][player])
|
|
||||||
outfile.write('Enemy shuffle:'.ljust(line_width) + '%s\n' % self.metadata['enemy_shuffle'][player])
|
|
||||||
outfile.write('Enemy health:'.ljust(line_width) + '%s\n' % self.metadata['enemy_health'][player])
|
|
||||||
outfile.write('Enemy damage:'.ljust(line_width) + '%s\n' % self.metadata['enemy_damage'][player])
|
|
||||||
outfile.write('Pot shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['potshuffle'][player] else 'No'))
|
|
||||||
outfile.write('Hints:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['hints'][player] else 'No'))
|
|
||||||
outfile.write('Experimental:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['experimental'][player] else 'No'))
|
outfile.write('Experimental:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['experimental'][player] else 'No'))
|
||||||
outfile.write('Key Drops shuffled:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['keydropshuffle'][player] else 'No'))
|
outfile.write('Pot Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['potshuffle'][player] else 'No'))
|
||||||
outfile.write('Shopsanity:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['shopsanity'][player] else 'No'))
|
outfile.write('Key Drop Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['keydropshuffle'][player] else 'No'))
|
||||||
outfile.write('Bombbag:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['bombbag'][player] else 'No'))
|
outfile.write('Map Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['mapshuffle'][player] else 'No'))
|
||||||
|
outfile.write('Compass Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['compassshuffle'][player] else 'No'))
|
||||||
|
outfile.write('Small Key Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['keyshuffle'][player] else 'No'))
|
||||||
|
outfile.write('Big Key Shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['bigkeyshuffle'][player] else 'No'))
|
||||||
|
outfile.write('Boss Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['boss_shuffle'][player])
|
||||||
|
outfile.write('Enemy Shuffle:'.ljust(line_width) + '%s\n' % self.metadata['enemy_shuffle'][player])
|
||||||
|
outfile.write('Enemy Health:'.ljust(line_width) + '%s\n' % self.metadata['enemy_health'][player])
|
||||||
|
outfile.write('Enemy Damage:'.ljust(line_width) + '%s\n' % self.metadata['enemy_damage'][player])
|
||||||
|
outfile.write('Hints:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['hints'][player] else 'No'))
|
||||||
|
|
||||||
|
if self.startinventory:
|
||||||
|
outfile.write('Starting Inventory:'.ljust(line_width))
|
||||||
|
outfile.write('\n'.ljust(line_width+1).join(self.startinventory))
|
||||||
|
outfile.write('\n\nRequirements:\n\n')
|
||||||
|
for dungeon, medallion in self.medallions.items():
|
||||||
|
outfile.write(f'{dungeon}:'.ljust(line_width) + '%s Medallion\n' % medallion)
|
||||||
|
if self.world.crystals_gt_orig[player] == 'random':
|
||||||
|
outfile.write('Crystals Required for GT:'.ljust(line_width) + '%s\n' % (str(self.metadata['gt_crystals'][player])))
|
||||||
|
if self.world.crystals_ganon_orig[player] == 'random':
|
||||||
|
outfile.write('Crystals Required for Ganon:'.ljust(line_width) + '%s\n' % (str(self.metadata['ganon_crystals'][player])))
|
||||||
|
|
||||||
|
if self.overworlds:
|
||||||
|
# overworlds: overworld transitions;
|
||||||
|
outfile.write('\n\nOverworld:\n\n')
|
||||||
|
outfile.write('\n'.join(['%s%s %s %s' % (f'{self.world.get_player_names(entry["player"])}: ' if self.world.players > 1 else '', self.world.fish.translate("meta","overworlds",entry['entrance']), '<=>' if entry['direction'] == 'both' else '<=' if entry['direction'] == 'exit' else '=>', self.world.fish.translate("meta","overworlds",entry['exit'])) for entry in self.overworlds.values()]))
|
||||||
|
|
||||||
|
if self.entrances:
|
||||||
|
# entrances: To/From overworld; Checking w/ & w/out "Exit" and translating accordingly
|
||||||
|
outfile.write('\n\nEntrances:\n\n')
|
||||||
|
outfile.write('\n'.join(['%s%s %s %s' % (f'{self.world.get_player_names(entry["player"])}: ' if self.world.players > 1 else '', self.world.fish.translate("meta","entrances",entry['entrance']), '<=>' if entry['direction'] == 'both' else '<=' if entry['direction'] == 'exit' else '=>', self.world.fish.translate("meta","entrances",entry['exit'])) for entry in self.entrances.values()]))
|
||||||
|
|
||||||
if self.doors:
|
if self.doors:
|
||||||
outfile.write('\n\nDoors:\n\n')
|
outfile.write('\n\nDoors:\n\n')
|
||||||
outfile.write('\n'.join(
|
outfile.write('\n'.join(
|
||||||
@@ -2813,20 +2845,6 @@ class Spoiler(object):
|
|||||||
# doorTypes: Small Key, Bombable, Bonkable
|
# doorTypes: Small Key, Bombable, Bonkable
|
||||||
outfile.write('\n\nDoor Types:\n\n')
|
outfile.write('\n\nDoor Types:\n\n')
|
||||||
outfile.write('\n'.join(['%s%s %s' % ('Player {0}: '.format(entry['player']) if self.world.players > 1 else '', self.world.fish.translate("meta","doors",entry['doorNames']), self.world.fish.translate("meta","doorTypes",entry['type'])) for entry in self.doorTypes.values()]))
|
outfile.write('\n'.join(['%s%s %s' % ('Player {0}: '.format(entry['player']) if self.world.players > 1 else '', self.world.fish.translate("meta","doors",entry['doorNames']), self.world.fish.translate("meta","doorTypes",entry['type'])) for entry in self.doorTypes.values()]))
|
||||||
if self.entrances:
|
|
||||||
# entrances: To/From overworld; Checking w/ & w/out "Exit" and translating accordingly
|
|
||||||
outfile.write('\n\nEntrances:\n\n')
|
|
||||||
outfile.write('\n'.join(['%s%s %s %s' % (f'{self.world.get_player_names(entry["player"])}: ' if self.world.players > 1 else '', self.world.fish.translate("meta","entrances",entry['entrance']), '<=>' if entry['direction'] == 'both' else '<=' if entry['direction'] == 'exit' else '=>', self.world.fish.translate("meta","entrances",entry['exit'])) for entry in self.entrances.values()]))
|
|
||||||
if self.overworlds:
|
|
||||||
# overworlds: overworld transitions;
|
|
||||||
outfile.write('\n\nOverworld:\n\n')
|
|
||||||
outfile.write('\n'.join(['%s%s %s %s' % (f'{self.world.get_player_names(entry["player"])}: ' if self.world.players > 1 else '', self.world.fish.translate("meta","overworlds",entry['entrance']), '<=>' if entry['direction'] == 'both' else '<=' if entry['direction'] == 'exit' else '=>', self.world.fish.translate("meta","overworlds",entry['exit'])) for entry in self.overworlds.values()]))
|
|
||||||
outfile.write('\n\nMedallions:\n')
|
|
||||||
for dungeon, medallion in self.medallions.items():
|
|
||||||
outfile.write(f'\n{dungeon}: {medallion} Medallion')
|
|
||||||
if self.startinventory:
|
|
||||||
outfile.write('\n\nStarting Inventory:\n\n')
|
|
||||||
outfile.write('\n'.join(self.startinventory))
|
|
||||||
|
|
||||||
# locations: Change up location names; in the instance of a location with multiple sections, it'll try to translate the room name
|
# locations: Change up location names; in the instance of a location with multiple sections, it'll try to translate the room name
|
||||||
# items: Item names
|
# items: Item names
|
||||||
@@ -2948,7 +2966,7 @@ class Pot(object):
|
|||||||
# byte 0: DDOO OEEE (DR, OR, ER)
|
# byte 0: DDOO OEEE (DR, OR, ER)
|
||||||
dr_mode = {"basic": 1, "crossed": 2, "vanilla": 0}
|
dr_mode = {"basic": 1, "crossed": 2, "vanilla": 0}
|
||||||
or_mode = {"vanilla": 0, "parallel": 1, "full": 1}
|
or_mode = {"vanilla": 0, "parallel": 1, "full": 1}
|
||||||
er_mode = {"vanilla": 0, "simple": 1, "restricted": 3, "full": 3, "crossed": 4, "insanity": 5, "dungeonsfull": 7, "dungeonssimple": 7}
|
er_mode = {"vanilla": 0, "simple": 1, "restricted": 2, "full": 3, "lite": 4, "lean": 5, "crossed": 6, "insanity": 7, "dungeonsfull": 8, "dungeonssimple": 9}
|
||||||
|
|
||||||
# byte 1: LLLW WSSR (logic, mode, sword, retro)
|
# byte 1: LLLW WSSR (logic, mode, sword, retro)
|
||||||
logic_mode = {"noglitches": 0, "minorglitches": 1, "nologic": 2, "owglitches": 3, "majorglitches": 4}
|
logic_mode = {"noglitches": 0, "minorglitches": 1, "nologic": 2, "owglitches": 3, "majorglitches": 4}
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
### 0.2.0.0
|
||||||
|
- Massive overhaul of ER algorithm
|
||||||
|
- Added 2 new ER modes (Lite and Lean)
|
||||||
|
- Added new mystery options (Logic/Shuffle Ganon)
|
||||||
|
- Smith deletion on S+Q only occurs if Blacksmith not reachable from starting locations
|
||||||
|
- Various minor fixes and improvements
|
||||||
|
- ~~Merged DR v0.5.1.4 - ROM bug fixes/keylogic improvements~~
|
||||||
|
|
||||||
### 0.1.9.4
|
### 0.1.9.4
|
||||||
- Hotfix for bad 0.1.9.3 version
|
- Hotfix for bad 0.1.9.3 version
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
'ow_shuffle', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_fluteshuffle',
|
'ow_shuffle', 'ow_crossed', 'ow_keepsimilar', 'ow_mixed', 'ow_fluteshuffle',
|
||||||
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
||||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
||||||
'bombbag',
|
'bombbag', 'shuffleganon',
|
||||||
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
|
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
|
||||||
'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'pseudoboots',
|
'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'pseudoboots',
|
||||||
'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters',
|
'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters',
|
||||||
|
|||||||
+12
-8
@@ -368,7 +368,8 @@ def choose_portals(world, player):
|
|||||||
|
|
||||||
if world.doorShuffle[player] in ['basic', 'crossed']:
|
if world.doorShuffle[player] in ['basic', 'crossed']:
|
||||||
cross_flag = world.doorShuffle[player] == 'crossed'
|
cross_flag = world.doorShuffle[player] == 'crossed'
|
||||||
bk_shuffle = world.bigkeyshuffle[player]
|
# key drops allow the big key in the right place in Desert Tiles 2
|
||||||
|
bk_shuffle = world.bigkeyshuffle[player] or world.keydropshuffle[player]
|
||||||
std_flag = world.mode[player] == 'standard'
|
std_flag = world.mode[player] == 'standard'
|
||||||
# roast incognito doors
|
# roast incognito doors
|
||||||
world.get_room(0x60, player).delete(5)
|
world.get_room(0x60, player).delete(5)
|
||||||
@@ -415,6 +416,7 @@ def choose_portals(world, player):
|
|||||||
for dungeon, info in shuffled_info:
|
for dungeon, info in shuffled_info:
|
||||||
outstanding_portals = list(dungeon_portals[dungeon])
|
outstanding_portals = list(dungeon_portals[dungeon])
|
||||||
hc_flag = std_flag and dungeon == 'Hyrule Castle'
|
hc_flag = std_flag and dungeon == 'Hyrule Castle'
|
||||||
|
rupee_bow_flag = hc_flag and world.retro[player] # rupee bow
|
||||||
if hc_flag:
|
if hc_flag:
|
||||||
sanc = world.get_portal('Sanctuary', player)
|
sanc = world.get_portal('Sanctuary', player)
|
||||||
sanc.destination = True
|
sanc.destination = True
|
||||||
@@ -424,14 +426,14 @@ def choose_portals(world, player):
|
|||||||
info.required_passage = {x: y for x, y in info.required_passage.items() if len(y) > 0}
|
info.required_passage = {x: y for x, y in info.required_passage.items() if len(y) > 0}
|
||||||
for target_region, possible_portals in info.required_passage.items():
|
for target_region, possible_portals in info.required_passage.items():
|
||||||
candidates = find_portal_candidates(master_door_list, dungeon, need_passage=True, crossed=cross_flag,
|
candidates = find_portal_candidates(master_door_list, dungeon, need_passage=True, crossed=cross_flag,
|
||||||
bk_shuffle=bk_shuffle)
|
bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag)
|
||||||
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
||||||
portal.destination = True
|
portal.destination = True
|
||||||
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
||||||
dead_end_choices = info.total - 1 - len(portal_assignment[dungeon])
|
dead_end_choices = info.total - 1 - len(portal_assignment[dungeon])
|
||||||
for i in range(0, dead_end_choices):
|
for i in range(0, dead_end_choices):
|
||||||
candidates = find_portal_candidates(master_door_list, dungeon, dead_end_allowed=True,
|
candidates = find_portal_candidates(master_door_list, dungeon, dead_end_allowed=True,
|
||||||
crossed=cross_flag, bk_shuffle=bk_shuffle)
|
crossed=cross_flag, bk_shuffle=bk_shuffle, rupee_bow=rupee_bow_flag)
|
||||||
possible_portals = outstanding_portals if not info.sole_entrance else [x for x in outstanding_portals if x != info.sole_entrance]
|
possible_portals = outstanding_portals if not info.sole_entrance else [x for x in outstanding_portals if x != info.sole_entrance]
|
||||||
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
choice, portal = assign_portal(candidates, possible_portals, world, player)
|
||||||
if choice.deadEnd:
|
if choice.deadEnd:
|
||||||
@@ -443,7 +445,7 @@ def choose_portals(world, player):
|
|||||||
the_rest = info.total - len(portal_assignment[dungeon])
|
the_rest = info.total - len(portal_assignment[dungeon])
|
||||||
for i in range(0, the_rest):
|
for i in range(0, the_rest):
|
||||||
candidates = find_portal_candidates(master_door_list, dungeon, crossed=cross_flag,
|
candidates = find_portal_candidates(master_door_list, dungeon, crossed=cross_flag,
|
||||||
bk_shuffle=bk_shuffle, standard=hc_flag)
|
bk_shuffle=bk_shuffle, standard=hc_flag, rupee_bow=rupee_bow_flag)
|
||||||
choice, portal = assign_portal(candidates, outstanding_portals, world, player)
|
choice, portal = assign_portal(candidates, outstanding_portals, world, player)
|
||||||
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
clean_up_portal_assignment(portal_assignment, dungeon, portal, master_door_list, outstanding_portals)
|
||||||
|
|
||||||
@@ -562,7 +564,7 @@ def disconnect_portal(portal, world, player):
|
|||||||
|
|
||||||
|
|
||||||
def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False,
|
def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allowed=False, crossed=False,
|
||||||
bk_shuffle=False, standard=False):
|
bk_shuffle=False, standard=False, rupee_bow=False):
|
||||||
ret = [x for x in door_list if bk_shuffle or not x.bk_shuffle_req]
|
ret = [x for x in door_list if bk_shuffle or not x.bk_shuffle_req]
|
||||||
if crossed:
|
if crossed:
|
||||||
ret = [x for x in ret if not x.dungeonLink or x.dungeonLink == dungeon or x.dungeonLink.startswith('link')]
|
ret = [x for x in ret if not x.dungeonLink or x.dungeonLink == dungeon or x.dungeonLink.startswith('link')]
|
||||||
@@ -574,6 +576,8 @@ def find_portal_candidates(door_list, dungeon, need_passage=False, dead_end_allo
|
|||||||
ret = [x for x in ret if not x.deadEnd]
|
ret = [x for x in ret if not x.deadEnd]
|
||||||
if standard:
|
if standard:
|
||||||
ret = [x for x in ret if not x.standard_restricted]
|
ret = [x for x in ret if not x.standard_restricted]
|
||||||
|
if rupee_bow:
|
||||||
|
ret = [x for x in ret if not x.rupee_bow_restricted]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@@ -1833,8 +1837,8 @@ def find_inaccessible_regions(world, player):
|
|||||||
queue.append(connect)
|
queue.append(connect)
|
||||||
world.inaccessible_regions[player].extend([r.name for r in all_regions.difference(visited_regions) if valid_inaccessible_region(r)])
|
world.inaccessible_regions[player].extend([r.name for r in all_regions.difference(visited_regions) if valid_inaccessible_region(r)])
|
||||||
if (world.mode[player] == 'inverted') != (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x1b in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
ledge = world.get_region('Hyrule Castle Ledge', 1)
|
ledge = world.get_region('Hyrule Castle Ledge', player)
|
||||||
if any(x for x in ledge.exits if x.connected_region.name == 'Agahnims Tower Portal'):
|
if any(x for x in ledge.exits if x.connected_region and x.connected_region.name == 'Agahnims Tower Portal'):
|
||||||
world.inaccessible_regions[player].append('Hyrule Castle Ledge')
|
world.inaccessible_regions[player].append('Hyrule Castle Ledge')
|
||||||
logger = logging.getLogger('')
|
logger = logging.getLogger('')
|
||||||
logger.debug('Inaccessible Regions:')
|
logger.debug('Inaccessible Regions:')
|
||||||
@@ -2047,7 +2051,7 @@ class DROptions(Flag):
|
|||||||
Town_Portal = 0x02 # If on, Players will start with mirror scroll
|
Town_Portal = 0x02 # If on, Players will start with mirror scroll
|
||||||
Map_Info = 0x04
|
Map_Info = 0x04
|
||||||
Debug = 0x08
|
Debug = 0x08
|
||||||
# Rails = 0x10 # Unused bit now
|
Fix_EG = 0x10 # used to be Rails = 0x10 # Unused bit now
|
||||||
OriginalPalettes = 0x20
|
OriginalPalettes = 0x20
|
||||||
# Open_PoD_Wall = 0x40 # No longer pre-opening pod wall - unused
|
# Open_PoD_Wall = 0x40 # No longer pre-opening pod wall - unused
|
||||||
# Open_Desert_Wall = 0x80 # No longer pre-opening desert wall - unused
|
# Open_Desert_Wall = 0x80 # No longer pre-opening desert wall - unused
|
||||||
|
|||||||
@@ -1490,8 +1490,11 @@ def create_doors(world, player):
|
|||||||
world.get_door('GT Petting Zoo SE', player).dead_end()
|
world.get_door('GT Petting Zoo SE', player).dead_end()
|
||||||
world.get_door('GT DMs Room SW', player).dead_end()
|
world.get_door('GT DMs Room SW', player).dead_end()
|
||||||
world.get_door("GT Bob\'s Room SE", player).passage = False
|
world.get_door("GT Bob\'s Room SE", player).passage = False
|
||||||
world.get_door('Desert Tiles 2 SE', player).bk_shuffle_req = True # key-drop note (todo)
|
world.get_door('Desert Tiles 2 SE', player).bk_shuffle_req = True # key-drop note: allows this to be a portal
|
||||||
world.get_door('Swamp Lobby S', player).standard_restricted = True # key-drop note (todo)
|
world.get_door('Swamp Lobby S', player).standard_restricted = True
|
||||||
|
world.get_door('PoD Mimics 2 SW', player).rupee_bow_restricted = True # bow statue
|
||||||
|
# enemizer logic could get rid of the following restriction
|
||||||
|
world.get_door('PoD Pit Room S', player).rupee_bow_restricted = True # so mimics 1 shouldn't be required
|
||||||
|
|
||||||
# can't unlink from boss right now
|
# can't unlink from boss right now
|
||||||
world.get_door('Hera Lobby S', player).dungeonLink = 'Tower of Hera'
|
world.get_door('Hera Lobby S', player).dungeonLink = 'Tower of Hera'
|
||||||
|
|||||||
+1267
-1509
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -709,7 +709,7 @@ def balance_prices(world, player):
|
|||||||
|
|
||||||
|
|
||||||
def check_hints(world, player):
|
def check_hints(world, player):
|
||||||
if world.shuffle[player] in ['simple', 'restricted', 'full', 'crossed', 'insanity']:
|
if world.shuffle[player] in ['simple', 'restricted', 'full', 'lite', 'lean', 'crossed', 'insanity']:
|
||||||
for shop, location_list in shop_to_location_table.items():
|
for shop, location_list in shop_to_location_table.items():
|
||||||
if shop in ['Capacity Upgrade', 'Light World Death Mountain Shop', 'Potion Shop']:
|
if shop in ['Capacity Upgrade', 'Light World Death Mountain Shop', 'Potion Shop']:
|
||||||
continue # near the queen, near potions, and near 7 chests are fine
|
continue # near the queen, near potions, and near 7 chests are fine
|
||||||
|
|||||||
+1
-1
@@ -171,7 +171,7 @@ class PlacementRule(object):
|
|||||||
if loc.item and loc.item.bigkey:
|
if loc.item and loc.item.bigkey:
|
||||||
bk_blocked = True
|
bk_blocked = True
|
||||||
break
|
break
|
||||||
else:
|
elif len(self.check_locations_w_bk) > self.needed_keys_w_bk:
|
||||||
def loc_has_bk(l):
|
def loc_has_bk(l):
|
||||||
return (big_key_loc is not None and big_key_loc == l) or (l.item and l.item.bigkey)
|
return (big_key_loc is not None and big_key_loc == l) or (l.item and l.item.bigkey)
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc
|
|||||||
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops
|
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops
|
||||||
from Utils import output_path, parse_player_names
|
from Utils import output_path, parse_player_names
|
||||||
|
|
||||||
__version__ = '0.5.1.2-u'
|
__version__ = '0.5.1.4-u'
|
||||||
|
|
||||||
from source.classes.BabelFish import BabelFish
|
from source.classes.BabelFish import BabelFish
|
||||||
|
|
||||||
@@ -513,7 +513,9 @@ def copy_world(world):
|
|||||||
connect_portal(portal, ret, player)
|
connect_portal(portal, ret, player)
|
||||||
ret.sanc_portal = world.sanc_portal
|
ret.sanc_portal = world.sanc_portal
|
||||||
|
|
||||||
|
from OverworldShuffle import categorize_world_regions
|
||||||
for player in range(1, world.players + 1):
|
for player in range(1, world.players + 1):
|
||||||
|
categorize_world_regions(ret, player)
|
||||||
set_rules(ret, player)
|
set_rules(ret, player)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
+3
-1
@@ -120,7 +120,7 @@ def roll_settings(weights):
|
|||||||
if glitches_required not in ['none', 'no_logic']:
|
if glitches_required not in ['none', 'no_logic']:
|
||||||
print("Only NMG and No Logic supported")
|
print("Only NMG and No Logic supported")
|
||||||
glitches_required = 'none'
|
glitches_required = 'none'
|
||||||
ret.logic = {'none': 'noglitches', 'no_logic': 'nologic'}[glitches_required]
|
ret.logic = {'none': 'noglitches', 'owg': 'owglitches', 'no_logic': 'nologic'}[glitches_required]
|
||||||
|
|
||||||
item_placement = get_choice('item_placement')
|
item_placement = get_choice('item_placement')
|
||||||
# not supported in ER
|
# not supported in ER
|
||||||
@@ -167,6 +167,8 @@ def roll_settings(weights):
|
|||||||
}[goal]
|
}[goal]
|
||||||
ret.openpyramid = goal == 'fast_ganon' if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
ret.openpyramid = goal == 'fast_ganon' if ret.shuffle in ['vanilla', 'dungeonsfull', 'dungeonssimple'] else False
|
||||||
|
|
||||||
|
ret.shuffleganon = get_choice('shuffleganon') == 'on'
|
||||||
|
|
||||||
ret.crystals_gt = get_choice('tower_open')
|
ret.crystals_gt = get_choice('tower_open')
|
||||||
|
|
||||||
ret.crystals_ganon = get_choice('ganon_open')
|
ret.crystals_ganon = get_choice('ganon_open')
|
||||||
|
|||||||
+456
@@ -1354,3 +1354,459 @@ parallel_links = bidict({'Lost Woods SW': 'Skull Woods SW',
|
|||||||
'Octoballoon WC': 'Bomber Corner WC',
|
'Octoballoon WC': 'Bomber Corner WC',
|
||||||
'Octoballoon WS': 'Bomber Corner WS'
|
'Octoballoon WS': 'Bomber Corner WS'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
OWExitTypes = {
|
||||||
|
'Ledge': ['West Death Mountain Drop',
|
||||||
|
'Spectacle Rock Drop',
|
||||||
|
'East Death Mountain Spiral Ledge Drop',
|
||||||
|
'East Death Mountain Fairy Ledge Drop',
|
||||||
|
'East Death Mountain Mimic Ledge Drop',
|
||||||
|
'Spiral Ledge Drop',
|
||||||
|
'Mimic Ledge Drop',
|
||||||
|
'Fairy Ascension Ledge Drop',
|
||||||
|
'Fairy Ascension Plateau Ledge Drop',
|
||||||
|
'TR Pegs Ledge Drop',
|
||||||
|
'Mountain Entry Entrance Ledge Drop',
|
||||||
|
'Mountain Entry Ledge Drop',
|
||||||
|
'Zora Waterfall Water Drop',
|
||||||
|
'Bonk Rock Ledge Drop',
|
||||||
|
'Graveyard Ledge Drop',
|
||||||
|
'River Bend Water Drop',
|
||||||
|
'River Bend East Water Drop',
|
||||||
|
'Potion Shop Water Drop',
|
||||||
|
'Potion Shop Northeast Water Drop',
|
||||||
|
'Zora Approach Bottom Ledge Drop',
|
||||||
|
'Zora Approach Water Drop',
|
||||||
|
'Zora Approach Ledge Drop',
|
||||||
|
'Hyrule Castle Ledge Drop',
|
||||||
|
'Hyrule Castle Ledge Courtyard Drop',
|
||||||
|
'Wooden Bridge Water Drop',
|
||||||
|
'Wooden Bridge Northeast Water Drop',
|
||||||
|
'Sand Dunes Ledge Drop',
|
||||||
|
'Stone Bridge East Ledge Drop',
|
||||||
|
'Tree Line Ledge Drop',
|
||||||
|
'Eastern Palace Ledge Drop',
|
||||||
|
'Maze Race Ledge Drop',
|
||||||
|
'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',
|
||||||
|
'South Teleporter Cliff Ledge Drop',
|
||||||
|
'Statues Cliff Ledge Drop',
|
||||||
|
'Desert Ledge Drop',
|
||||||
|
'Checkerboard Ledge Drop',
|
||||||
|
'Desert Mouth Drop',
|
||||||
|
'Desert Teleporter Drop',
|
||||||
|
'Desert Boss Cliff Ledge Drop',
|
||||||
|
'Checkerboard Cliff Ledge Drop',
|
||||||
|
'Suburb Cliff Ledge Drop',
|
||||||
|
'Cave 45 Cliff Ledge Drop',
|
||||||
|
'Desert C Whirlpool Cliff Ledge Drop',
|
||||||
|
'Desert Pass Cliff Ledge Drop',
|
||||||
|
'Desert Pass Southeast Cliff Ledge Drop',
|
||||||
|
'Dam Cliff Ledge Drop',
|
||||||
|
'Bombos Tablet Drop',
|
||||||
|
'Cave 45 Ledge Drop',
|
||||||
|
'Lake Hylia Water Drop',
|
||||||
|
'Lake Hylia South Water Drop',
|
||||||
|
'Lake Hylia Northeast Water Drop',
|
||||||
|
'Lake Hylia Central Water Drop',
|
||||||
|
'Lake Hylia Island Water Drop',
|
||||||
|
'Desert Pass Ledge Drop',
|
||||||
|
'Octoballoon Water Drop',
|
||||||
|
'Octoballoon Waterfall Water Drop',
|
||||||
|
'Dark Death Mountain Drop (West)',
|
||||||
|
'Dark Death Mountain Drop (East)',
|
||||||
|
'Floating Island Drop',
|
||||||
|
'Turtle Rock Tail Ledge Drop',
|
||||||
|
'Turtle Rock Ledge Drop',
|
||||||
|
'Bumper Cave Ledge Drop',
|
||||||
|
'Bumper Cave Entrance Drop',
|
||||||
|
'Qirn Jump Water Drop',
|
||||||
|
'Qirn Jump East Water Drop',
|
||||||
|
'Dark Witch Water Drop',
|
||||||
|
'Dark Witch Northeast Water Drop',
|
||||||
|
'Catfish Approach Bottom Ledge Drop',
|
||||||
|
'Catfish Approach Water Drop',
|
||||||
|
'Catfish Approach Ledge Drop',
|
||||||
|
'Shield Shop Fence (Outer) Ledge Drop',
|
||||||
|
'Shield Shop Fence (Inner) Ledge Drop',
|
||||||
|
'Pyramid Exit Ledge Drop',
|
||||||
|
'Broken Bridge Water Drop',
|
||||||
|
'Broken Bridge Northeast Water Drop',
|
||||||
|
'Broken Bridge West Water Drop',
|
||||||
|
'Dark Dunes Ledge Drop',
|
||||||
|
'Hammer Bridge North Ledge Drop',
|
||||||
|
'Dark Tree Line Ledge Drop',
|
||||||
|
'Palace of Darkness Ledge Drop',
|
||||||
|
'Dig Game To Ledge Drop',
|
||||||
|
'Dig Game Ledge Drop',
|
||||||
|
'Frog Ledge Drop',
|
||||||
|
'Hammer Bridge Water Drop',
|
||||||
|
'Dark Bonk Rocks Cliff Ledge Drop',
|
||||||
|
'Bomb Shop Cliff Ledge Drop',
|
||||||
|
'Hammer Bridge South Cliff Ledge Drop',
|
||||||
|
'Ice Lake Area Cliff Ledge Drop',
|
||||||
|
'Ice Palace Island FAWT Ledge Drop',
|
||||||
|
'Hammer Bridge EC Cliff Water Drop',
|
||||||
|
'Dark Tree Line WC Cliff Water Drop',
|
||||||
|
'Dark C Whirlpool Outer Cliff Ledge Drop',
|
||||||
|
'Dark C Whirlpool Cliff Ledge Drop',
|
||||||
|
'Hype Cliff Ledge Drop',
|
||||||
|
'Dark South Teleporter Cliff Ledge Drop',
|
||||||
|
'Misery Mire Teleporter Ledge Drop',
|
||||||
|
'Mire Cliff Ledge Drop',
|
||||||
|
'Archery Game Cliff Ledge Drop',
|
||||||
|
'Stumpy Approach Cliff Ledge Drop',
|
||||||
|
'Mire C Whirlpool Cliff Ledge Drop',
|
||||||
|
'Swamp Nook Cliff Ledge Drop',
|
||||||
|
'Swamp Cliff Ledge Drop',
|
||||||
|
'Ice Lake Water Drop',
|
||||||
|
'Ice Lake Northeast Water Drop',
|
||||||
|
'Ice Lake Southwest Water Drop',
|
||||||
|
'Ice Lake Southeast Water Drop',
|
||||||
|
'Bomber Corner Water Drop',
|
||||||
|
'Bomber Corner Waterfall Water Drop'
|
||||||
|
],
|
||||||
|
'OWTerrain': ['Lost Woods Bush (West)',
|
||||||
|
'Lost Woods Bush (East)',
|
||||||
|
'Spectacle Rock Approach',
|
||||||
|
'Spectacle Rock Leave',
|
||||||
|
'DM Hammer Bridge (West)',
|
||||||
|
'DM Hammer Bridge (East)',
|
||||||
|
'Floating Island Bridge (East)',
|
||||||
|
'Fairy Ascension Rocks (North)',
|
||||||
|
'DM Broken Bridge (West)',
|
||||||
|
'DM Broken Bridge (East)',
|
||||||
|
'Fairy Ascension Rocks (South)',
|
||||||
|
'Floating Island Bridge (West)',
|
||||||
|
'TR Pegs Ledge Entry',
|
||||||
|
'TR Pegs Ledge Leave',
|
||||||
|
'Mountain Entry Entrance Rock (West)',
|
||||||
|
'Mountain Entry Entrance Rock (East)',
|
||||||
|
'Zora Waterfall Water Entry',
|
||||||
|
'Waterfall of Wishing Cave Entry',
|
||||||
|
'Zora Waterfall Landing',
|
||||||
|
'Kings Grave Outer Rocks',
|
||||||
|
'Graveyard Ladder (Bottom)',
|
||||||
|
'Graveyard Ladder (Top)',
|
||||||
|
'Kings Grave Inner Rocks',
|
||||||
|
'River Bend West Pier',
|
||||||
|
'River Bend East Pier',
|
||||||
|
'Potion Shop Rock (South)',
|
||||||
|
'Potion Shop Rock (North)',
|
||||||
|
'Zora Approach Rocks (West)',
|
||||||
|
'Zora Approach Rocks (East)',
|
||||||
|
'Kakariko Southwest Bush (North)',
|
||||||
|
'Kakariko Yard Bush (South)',
|
||||||
|
'Kakariko Southwest Bush (South)',
|
||||||
|
'Kakariko Yard Bush (North)',
|
||||||
|
'Hyrule Castle Main Gate (South)',
|
||||||
|
'Hyrule Castle Inner East Rock',
|
||||||
|
'Hyrule Castle Southwest Bush (North)',
|
||||||
|
'Hyrule Castle Southwest Bush (South)',
|
||||||
|
'Hyrule Castle Courtyard Bush (South)',
|
||||||
|
'Hyrule Castle Main Gate (North)',
|
||||||
|
'Hyrule Castle Courtyard Bush (North)',
|
||||||
|
'Hyrule Castle Outer East Rock',
|
||||||
|
'Wooden Bridge Bush (South)',
|
||||||
|
'Wooden Bridge Bush (North)',
|
||||||
|
'Bat Cave Ledge Peg',
|
||||||
|
'Bat Cave Ledge Peg (East)',
|
||||||
|
'Maze Race Game',
|
||||||
|
'Desert Palace Statue Move',
|
||||||
|
'Checkerboard Ledge Approach',
|
||||||
|
'Desert Ledge Outer Rocks',
|
||||||
|
'Desert Ledge Inner Rocks',
|
||||||
|
'Checkerboard Ledge Leave',
|
||||||
|
'Flute Boy Bush (South)',
|
||||||
|
'Cave 45 Inverted Approach',
|
||||||
|
'Flute Boy Bush (North)',
|
||||||
|
'Cave 45 Inverted Leave',
|
||||||
|
'C Whirlpool Rock (Bottom)',
|
||||||
|
'C Whirlpool Water Entry',
|
||||||
|
'C Whirlpool Landing',
|
||||||
|
'C Whirlpool Rock (Top)',
|
||||||
|
'Statues Water Entry',
|
||||||
|
'Statues Landing',
|
||||||
|
'Lake Hylia Central Island Pier',
|
||||||
|
'Lake Hylia Island Pier',
|
||||||
|
'Lake Hylia West Pier',
|
||||||
|
'Lake Hylia East Pier',
|
||||||
|
'Desert Pass Ladder (South)',
|
||||||
|
'Desert Pass Rocks (North)',
|
||||||
|
'Desert Pass Rocks (South)',
|
||||||
|
'Desert Pass Ladder (North)',
|
||||||
|
'Octoballoon Pier',
|
||||||
|
'Skull Woods Bush Rock (East)',
|
||||||
|
'Skull Woods Bush Rock (West)',
|
||||||
|
'Skull Woods Forgotten Bush (West)',
|
||||||
|
'Skull Woods Forgotten Bush (East)',
|
||||||
|
'GT Entry Approach',
|
||||||
|
'Dark Death Mountain Ladder (North)',
|
||||||
|
'GT Entry Leave',
|
||||||
|
'Dark Death Mountain Ladder (South)',
|
||||||
|
'Bumper Cave Entrance Rock',
|
||||||
|
'Skull Woods Pass Bush Row (West)',
|
||||||
|
'Skull Woods Pass Bush Row (East)',
|
||||||
|
'Skull Woods Pass Rock (Top)',
|
||||||
|
'Skull Woods Pass Rock (Bottom)',
|
||||||
|
'Dark Graveyard Bush (South)',
|
||||||
|
'Dark Graveyard Bush (North)',
|
||||||
|
'Qirn Jump Pier',
|
||||||
|
'Dark Witch Rock (South)',
|
||||||
|
'Dark Witch Rock (North)',
|
||||||
|
'Catfish Approach Rocks (West)',
|
||||||
|
'Catfish Approach Rocks (East)',
|
||||||
|
'Village of Outcasts Pegs',
|
||||||
|
'Grassy Lawn Pegs',
|
||||||
|
'Broken Bridge Hammer Rock (South)',
|
||||||
|
'Broken Bridge Hammer Rock (North)',
|
||||||
|
'Broken Bridge Hookshot Gap',
|
||||||
|
'Peg Area Rocks (West)',
|
||||||
|
'Peg Area Rocks (East)',
|
||||||
|
'Frog Rock (Outer)',
|
||||||
|
'Archery Game Rock (North)',
|
||||||
|
'Frog Rock (Inner)',
|
||||||
|
'Archery Game Rock (South)',
|
||||||
|
'Hammer Bridge Pegs (North)',
|
||||||
|
'Hammer Bridge Pegs (South)',
|
||||||
|
'Hammer Bridge Pier',
|
||||||
|
'Stumpy Approach Bush (South)',
|
||||||
|
'Stumpy Approach Bush (North)',
|
||||||
|
'Dark C Whirlpool Rock (Bottom)',
|
||||||
|
'Dark C Whirlpool Water Entry',
|
||||||
|
'Dark C Whirlpool Landing',
|
||||||
|
'Dark C Whirlpool Rock (Top)',
|
||||||
|
'Hype Cave Water Entry',
|
||||||
|
'Hype Cave Landing',
|
||||||
|
'Ice Lake Northeast Pier',
|
||||||
|
'Ice Lake Moat Water Entry',
|
||||||
|
'Ice Lake Northeast Pier Bomb Jump',
|
||||||
|
'Ice Palace Approach',
|
||||||
|
'Ice Palace Leave',
|
||||||
|
'Bomber Corner Pier'
|
||||||
|
],
|
||||||
|
'Portal': ['West Death Mountain Teleporter',
|
||||||
|
'East Death Mountain Teleporter',
|
||||||
|
'TR Pegs Teleporter',
|
||||||
|
'Kakariko Teleporter (Hammer)',
|
||||||
|
'Kakariko Teleporter (Rock)',
|
||||||
|
'Top of Pyramid',
|
||||||
|
'Top of Pyramid (Inner)',
|
||||||
|
'East Hyrule Teleporter',
|
||||||
|
'Desert Teleporter',
|
||||||
|
'South Hyrule Teleporter',
|
||||||
|
'Lake Hylia Teleporter',
|
||||||
|
'Dark Death Mountain Teleporter (West)',
|
||||||
|
'Dark Death Mountain Teleporter (East)',
|
||||||
|
'Turtle Rock Teleporter',
|
||||||
|
'West Dark World Teleporter (Hammer)',
|
||||||
|
'West Dark World Teleporter (Rock)',
|
||||||
|
'Post Aga Inverted Teleporter',
|
||||||
|
'East Dark World Teleporter',
|
||||||
|
'Misery Mire Teleporter',
|
||||||
|
'South Dark World Teleporter',
|
||||||
|
'Ice Palace Teleporter'
|
||||||
|
],
|
||||||
|
'Whirlpool': ['Zora Whirlpool',
|
||||||
|
'Kakariko Pond Whirlpool',
|
||||||
|
'River Bend Whirlpool',
|
||||||
|
'C Whirlpool',
|
||||||
|
'Lake Hylia Whirlpool',
|
||||||
|
'Octoballoon Whirlpool',
|
||||||
|
'Qirn Jump Whirlpool',
|
||||||
|
'Bomber Corner Whirlpool'
|
||||||
|
],
|
||||||
|
'Mirror': ['Skull Woods Back Mirror Spot',
|
||||||
|
'Skull Woods Forgotten (West) Mirror Spot',
|
||||||
|
'Skull Woods Forgotten (East) Mirror Spot',
|
||||||
|
'Skull Woods Portal Entry Mirror Spot',
|
||||||
|
'Skull Woods Forgotten (Middle) Mirror Spot',
|
||||||
|
'Skull Woods Front Mirror Spot',
|
||||||
|
'Dark Lumberjack Mirror Spot',
|
||||||
|
'West Dark Death Mountain (Top) Mirror Spot',
|
||||||
|
'Bubble Boy Mirror Spot',
|
||||||
|
'West Dark Death Mountain (Bottom) Mirror Spot',
|
||||||
|
'East Dark Death Mountain (Top West) Mirror Spot',
|
||||||
|
'East Dark Death Mountain (Top East) Mirror Spot',
|
||||||
|
'TR Ledge (West) Mirror Spot',
|
||||||
|
'TR Ledge (East) Mirror Spot',
|
||||||
|
'TR Isolated Mirror Spot',
|
||||||
|
'East Dark Death Mountain (Bottom Plateau) Mirror Spot',
|
||||||
|
'East Dark Death Mountain (Bottom Left) Mirror Spot',
|
||||||
|
'East Dark Death Mountain (Bottom) Mirror Spot',
|
||||||
|
'Dark Floating Island Mirror Spot',
|
||||||
|
'Turtle Rock Mirror Spot',
|
||||||
|
'Turtle Rock Ledge Mirror Spot',
|
||||||
|
'Bumper Cave Area Mirror Spot',
|
||||||
|
'Bumper Cave Entry Mirror Spot',
|
||||||
|
'Bumper Cave Ledge Mirror Spot',
|
||||||
|
'Catfish Mirror Spot',
|
||||||
|
'Skull Woods Pass West Mirror Spot',
|
||||||
|
'Skull Woods Pass East Top Mirror Spot',
|
||||||
|
'Skull Woods Pass East Bottom Mirror Spot',
|
||||||
|
'Outcast Fortune Mirror Spot',
|
||||||
|
'Outcast Pond Mirror Spot',
|
||||||
|
'Dark Chapel Mirror Spot',
|
||||||
|
'Dark Chapel Ledge Mirror Spot',
|
||||||
|
'Dark Graveyard Mirror Spot',
|
||||||
|
'Dark Graveyard Ledge Mirror Spot',
|
||||||
|
'Dark Graveyard Grave Mirror Spot',
|
||||||
|
'Qirn Jump Mirror Spot',
|
||||||
|
'Qirn Jump East Mirror Spot',
|
||||||
|
'Dark Witch Mirror Spot',
|
||||||
|
'Dark Witch Northeast Mirror Spot',
|
||||||
|
'Catfish Approach Mirror Spot',
|
||||||
|
'Catfish Approach Ledge Mirror Spot',
|
||||||
|
'Village of Outcasts Mirror Spot',
|
||||||
|
'Village of Outcasts Southwest Mirror Spot',
|
||||||
|
'Hammer House Mirror Spot',
|
||||||
|
'Shield Shop Mirror Spot',
|
||||||
|
'Pyramid Mirror Spot',
|
||||||
|
'Pyramid Pass Mirror Spot',
|
||||||
|
'Pyramid Courtyard Mirror Spot',
|
||||||
|
'Pyramid Uncle Mirror Spot',
|
||||||
|
'Pyramid From Ledge Mirror Spot',
|
||||||
|
'Pyramid Entry Mirror Spot',
|
||||||
|
'Broken Bridge West Mirror Spot',
|
||||||
|
'Broken Bridge East Mirror Spot',
|
||||||
|
'Broken Bridge Northeast Mirror Spot',
|
||||||
|
'Palace of Darkness Mirror Spot',
|
||||||
|
'Hammer Pegs Mirror Spot',
|
||||||
|
'Hammer Pegs Entry Mirror Spot',
|
||||||
|
'Dark Dunes Mirror Spot',
|
||||||
|
'Dig Game Mirror Spot',
|
||||||
|
'Dig Game Ledge Mirror Spot',
|
||||||
|
'Frog Mirror Spot',
|
||||||
|
'Frog Prison Mirror Spot',
|
||||||
|
'Archery Game Mirror Spot',
|
||||||
|
'Stumpy Mirror Spot',
|
||||||
|
'Stumpy Pass Mirror Spot',
|
||||||
|
'Dark Bonk Rocks Mirror Spot',
|
||||||
|
'Big Bomb Shop Mirror Spot',
|
||||||
|
'Hammer Bridge North Mirror Spot',
|
||||||
|
'Hammer Bridge South Mirror Spot',
|
||||||
|
'Dark Hobo Mirror Spot',
|
||||||
|
'Dark Tree Line Mirror Spot',
|
||||||
|
'Darkness Nook Mirror Spot',
|
||||||
|
'Misery Mire Mirror Spot',
|
||||||
|
'Misery Mire Ledge Mirror Spot',
|
||||||
|
'Misery Mire Blocked Mirror Spot',
|
||||||
|
'Misery Mire Main Mirror Spot',
|
||||||
|
'Stumpy Approach Mirror Spot',
|
||||||
|
'Stumpy Bush Entry Mirror Spot',
|
||||||
|
'Dark C Whirlpool Mirror Spot',
|
||||||
|
'Dark C Whirlpool Outer Mirror Spot',
|
||||||
|
'Hype Cave Mirror Spot',
|
||||||
|
'Ice Lake Mirror Spot',
|
||||||
|
'Ice Lake Southwest Mirror Spot',
|
||||||
|
'Ice Lake Southeast Mirror Spot',
|
||||||
|
'Ice Lake Northeast Mirror Spot',
|
||||||
|
'Ice Palace Mirror Spot',
|
||||||
|
'Shopping Mall Mirror Spot',
|
||||||
|
'Swamp Nook Mirror Spot',
|
||||||
|
'Swamp Nook Southeast Mirror Spot',
|
||||||
|
'Swamp Nook Pegs Mirror Spot',
|
||||||
|
'Swamp Mirror Spot',
|
||||||
|
'Dark South Pass Mirror Spot',
|
||||||
|
'Bomber Corner Mirror Spot',
|
||||||
|
'Lost Woods East Mirror Spot',
|
||||||
|
'Lost Woods Entry Mirror Spot',
|
||||||
|
'Lost Woods Pedestal Mirror Spot',
|
||||||
|
'Lost Woods Southwest Mirror Spot',
|
||||||
|
'Lost Woods East (Forgotten) Mirror Spot',
|
||||||
|
'Lost Woods West (Forgotten) Mirror Spot',
|
||||||
|
'Lumberjack Mirror Spot',
|
||||||
|
'West Death Mountain (Top) Mirror Spot',
|
||||||
|
'Spectacle Rock Mirror Spot',
|
||||||
|
'East Death Mountain (Top West) Mirror Spot',
|
||||||
|
'East Death Mountain (Top East) Mirror Spot',
|
||||||
|
'Fairy Ascension Mirror Spot',
|
||||||
|
'Death Mountain Bridge Mirror Spot',
|
||||||
|
'Spiral Cave Mirror Spot',
|
||||||
|
'Mimic Cave Mirror Spot',
|
||||||
|
'Isolated Ledge Mirror Spot',
|
||||||
|
'Floating Island Mirror Spot',
|
||||||
|
'TR Pegs Area Mirror Spot',
|
||||||
|
'Mountain Entry Mirror Spot',
|
||||||
|
'Mountain Entry Entrance Mirror Spot',
|
||||||
|
'Mountain Entry Ledge Mirror Spot',
|
||||||
|
'Zora Waterfall Mirror Spot',
|
||||||
|
'Lost Woods Pass West Mirror Spot',
|
||||||
|
'Lost Woods Pass East Top Mirror Spot',
|
||||||
|
'Lost Woods Pass East Bottom Mirror Spot',
|
||||||
|
'Kakariko Fortune Mirror Spot',
|
||||||
|
'Kakariko Pond Mirror Spot',
|
||||||
|
'Sanctuary Mirror Spot',
|
||||||
|
'Bonk Rock Ledge Mirror Spot',
|
||||||
|
'Graveyard Ledge Mirror Spot',
|
||||||
|
'Kings Grave Mirror Spot',
|
||||||
|
'River Bend Mirror Spot',
|
||||||
|
'River Bend East Mirror Spot',
|
||||||
|
'Potion Shop Mirror Spot',
|
||||||
|
'Potion Shop Northeast Mirror Spot',
|
||||||
|
'Zora Approach Mirror Spot',
|
||||||
|
'Zora Approach Ledge Mirror Spot',
|
||||||
|
'Kakariko Mirror Spot',
|
||||||
|
'Kakariko Grass Mirror Spot',
|
||||||
|
'Forgotton Forest Mirror Spot',
|
||||||
|
'Forgotton Forest Fence Mirror Spot',
|
||||||
|
'HC Ledge Mirror Spot',
|
||||||
|
'HC Courtyard Mirror Spot',
|
||||||
|
'HC Area Mirror Spot',
|
||||||
|
'HC East Entry Mirror Spot',
|
||||||
|
'HC Courtyard Left Mirror Spot',
|
||||||
|
'HC Area South Mirror Spot',
|
||||||
|
'Wooden Bridge Mirror Spot',
|
||||||
|
'Wooden Bridge Northeast Mirror Spot',
|
||||||
|
'Wooden Bridge West Mirror Spot',
|
||||||
|
'Eastern Palace Mirror Spot',
|
||||||
|
'Blacksmith Entry Mirror Spot',
|
||||||
|
'Blacksmith Mirror Spot',
|
||||||
|
'Bat Cave Ledge Mirror Spot',
|
||||||
|
'Sand Dunes Mirror Spot',
|
||||||
|
'Maze Race Mirror Spot',
|
||||||
|
'Maze Race Ledge Mirror Spot',
|
||||||
|
'Kakariko Suburb Mirror Spot',
|
||||||
|
'Kakariko Suburb South Mirror Spot',
|
||||||
|
'Flute Boy Mirror Spot',
|
||||||
|
'Flute Boy Pass Mirror Spot',
|
||||||
|
'Central Bonk Rocks Mirror Spot',
|
||||||
|
'Links House Mirror Spot',
|
||||||
|
'Stone Bridge Mirror Spot',
|
||||||
|
'Stone Bridge South Mirror Spot',
|
||||||
|
'Hobo Mirror Spot',
|
||||||
|
'Tree Line Mirror Spot',
|
||||||
|
'Eastern Nook Mirror Spot',
|
||||||
|
'Desert Mirror Spot',
|
||||||
|
'Desert Ledge Mirror Spot',
|
||||||
|
'Checkerboard Mirror Spot',
|
||||||
|
'DP Stairs Mirror Spot',
|
||||||
|
'DP Entrance (North) Mirror Spot',
|
||||||
|
'Bombos Tablet Ledge Mirror Spot',
|
||||||
|
'Cave 45 Mirror Spot',
|
||||||
|
'Flute Boy Entry Mirror Spot',
|
||||||
|
'C Whirlpool Mirror Spot',
|
||||||
|
'C Whirlpool Outer Mirror Spot',
|
||||||
|
'Statues Mirror Spot',
|
||||||
|
'Lake Hylia Mirror Spot',
|
||||||
|
'Lake Hylia Northeast Mirror Spot',
|
||||||
|
'South Shore Mirror Spot',
|
||||||
|
'South Shore East Mirror Spot',
|
||||||
|
'Lake Hylia Island Mirror Spot',
|
||||||
|
'Lake Hylia Water Mirror Spot',
|
||||||
|
'Lake Hylia Central Island Mirror Spot',
|
||||||
|
'Ice Cave Mirror Spot',
|
||||||
|
'Desert Pass Ledge Mirror Spot',
|
||||||
|
'Desert Pass Mirror Spot',
|
||||||
|
'Dam Mirror Spot',
|
||||||
|
'South Pass Mirror Spot',
|
||||||
|
'Octoballoon Mirror Spot'
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -152,8 +152,8 @@ def get_boots_clip_exits_lw(inverted = False):
|
|||||||
yield ('TR Pegs Ledge Clip', 'Death Mountain TR Pegs', 'Death Mountain TR Pegs Ledge')
|
yield ('TR Pegs Ledge Clip', 'Death Mountain TR Pegs', 'Death Mountain TR Pegs Ledge')
|
||||||
yield ('TR Pegs To EDM Clip', 'Death Mountain TR Pegs', 'East Death Mountain (Top East)')
|
yield ('TR Pegs To EDM Clip', 'Death Mountain TR Pegs', 'East Death Mountain (Top East)')
|
||||||
yield ('Zora DMD Clip', 'Death Mountain TR Pegs', 'Zora Waterfall Area')
|
yield ('Zora DMD Clip', 'Death Mountain TR Pegs', 'Zora Waterfall Area')
|
||||||
yield ('Mountain Entry To Ledge Clip', 'Mountain Entry Area', 'Death Mountain Return Ledge')
|
yield ('Mountain Entry To Ledge Clip', 'Mountain Entry Area', 'Mountain Entry Ledge')
|
||||||
yield ('Mountain Ledge Drop Clip', 'Death Mountain Return Ledge', 'Death Mountain Entrance')
|
yield ('Mountain Ledge Drop Clip', 'Mountain Entry Ledge', 'Mountain Entry Entrance')
|
||||||
yield ('Mountain Entry To Pond Clip', 'Mountain Entry Area', 'Kakariko Pond Area')
|
yield ('Mountain Entry To Pond Clip', 'Mountain Entry Area', 'Kakariko Pond Area')
|
||||||
yield ('Zora Waterfall Ledge Clip', 'Zora Waterfall Area', 'Zora Approach Area')
|
yield ('Zora Waterfall Ledge Clip', 'Zora Waterfall Area', 'Zora Approach Area')
|
||||||
|
|
||||||
@@ -225,12 +225,12 @@ def get_boots_clip_exits_dw(inverted):
|
|||||||
yield ('DDM Glitched Bridge Clip', 'West Dark Death Mountain (Bottom)', 'East Dark Death Mountain (Top)')
|
yield ('DDM Glitched Bridge Clip', 'West Dark Death Mountain (Bottom)', 'East Dark Death Mountain (Top)')
|
||||||
yield ('Chapel DMD Clip', 'West Dark Death Mountain (Bottom)', 'Dark Chapel Area')
|
yield ('Chapel DMD Clip', 'West Dark Death Mountain (Bottom)', 'Dark Chapel Area')
|
||||||
yield ('Dark Graveyard DMD Clip', 'West Dark Death Mountain (Bottom)', 'Dark Graveyard Area')
|
yield ('Dark Graveyard DMD Clip', 'West Dark Death Mountain (Bottom)', 'Dark Graveyard Area')
|
||||||
yield ('EDDM West Dropdown Clip', 'East Dark Death Mountain (Top)', 'East Dark Death Mountain (West Lip)')
|
yield ('EDDM West Dropdown Clip', 'East Dark Death Mountain (Top)', 'East Dark Death Mountain (Bottom Left)')
|
||||||
yield ('EDDM To WDDM Clip', 'East Dark Death Mountain (Top)', 'West Dark Death Mountain (Top)')
|
yield ('EDDM To WDDM Clip', 'East Dark Death Mountain (Top)', 'West Dark Death Mountain (Top)')
|
||||||
yield ('TR Bridge Clip', 'East Dark Death Mountain (Top)', 'Dark Death Mountain Ledge')
|
yield ('TR Bridge Clip', 'East Dark Death Mountain (Top)', 'Dark Death Mountain Ledge')
|
||||||
yield ('Dark Witch DMD FAWT Clip', 'East Dark Death Mountain (Bottom)', 'Dark Witch Area')
|
yield ('Dark Witch DMD FAWT Clip', 'East Dark Death Mountain (Bottom)', 'Dark Witch Area')
|
||||||
yield ('Qirn Jump DMD Clip', 'East Dark Death Mountain (West Lip)', 'Qirn Jump Area')
|
yield ('Qirn Jump DMD Clip', 'East Dark Death Mountain (Bottom Left)', 'Qirn Jump Area')
|
||||||
yield ('WDDM To EDDM Clip', 'East Dark Death Mountain (West Lip)', 'East Dark Death Mountain (Bottom)')
|
yield ('WDDM To EDDM Clip', 'East Dark Death Mountain (Bottom Left)', 'East Dark Death Mountain (Bottom)')
|
||||||
#yield ('DW Floating Island Clip', 'East Dark Death Mountain (Bottom)', 'Dark Death Mountain Floating Island') #cannot guarantee camera correction
|
#yield ('DW Floating Island Clip', 'East Dark Death Mountain (Bottom)', 'Dark Death Mountain Floating Island') #cannot guarantee camera correction
|
||||||
yield ('TR To EDDM Clip', 'Turtle Rock Area', 'East Dark Death Mountain (Top)')
|
yield ('TR To EDDM Clip', 'Turtle Rock Area', 'East Dark Death Mountain (Top)')
|
||||||
yield ('Catfish DMD Clip', 'Turtle Rock Area', 'Catfish Area')
|
yield ('Catfish DMD Clip', 'Turtle Rock Area', 'Catfish Area')
|
||||||
@@ -312,8 +312,8 @@ def get_mirror_clip_spots_dw():
|
|||||||
"""
|
"""
|
||||||
Out of bounds transitions using the mirror
|
Out of bounds transitions using the mirror
|
||||||
"""
|
"""
|
||||||
yield ('Qirn Jump Bunny DMD Clip', 'East Dark Death Mountain (West Lip)', 'Qirn Jump Area')
|
yield ('Qirn Jump Bunny DMD Clip', 'East Dark Death Mountain (Bottom Left)', 'Qirn Jump Area')
|
||||||
yield ('EDDM Mirror Clip', 'East Dark Death Mountain (West Lip)', 'East Dark Death Mountain (Bottom)')
|
yield ('EDDM Mirror Clip', 'East Dark Death Mountain (Bottom Left)', 'East Dark Death Mountain (Bottom)')
|
||||||
yield ('Desert East Mirror Clip', 'Misery Mire Area', 'Desert Palace Mouth')
|
yield ('Desert East Mirror Clip', 'Misery Mire Area', 'Desert Palace Mouth')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+75
-10
@@ -1,8 +1,9 @@
|
|||||||
import RaceRandom as random, logging, copy
|
import RaceRandom as random, logging, copy
|
||||||
from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSlot, Entrance
|
from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSlot, Entrance
|
||||||
from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OpenStd, parallel_links, IsParallel
|
from Regions import mark_dark_world_regions, mark_light_world_regions
|
||||||
|
from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel
|
||||||
|
|
||||||
__version__ = '0.1.9.4-u'
|
__version__ = '0.2.0.0-u'
|
||||||
|
|
||||||
def link_overworld(world, player):
|
def link_overworld(world, player):
|
||||||
# setup mandatory connections
|
# setup mandatory connections
|
||||||
@@ -146,6 +147,8 @@ def link_overworld(world, player):
|
|||||||
for (exitname, regionname) in ow_connections[owid][1]:
|
for (exitname, regionname) in ow_connections[owid][1]:
|
||||||
connect_simple(world, exitname, regionname, player)
|
connect_simple(world, exitname, regionname, player)
|
||||||
|
|
||||||
|
categorize_world_regions(world, player)
|
||||||
|
|
||||||
# crossed shuffle
|
# crossed shuffle
|
||||||
logging.getLogger('').debug('Crossing overworld edges')
|
logging.getLogger('').debug('Crossing overworld edges')
|
||||||
if world.owCrossed[player] in ['grouped', 'limited', 'chaos']:
|
if world.owCrossed[player] in ['grouped', 'limited', 'chaos']:
|
||||||
@@ -169,7 +172,7 @@ def link_overworld(world, player):
|
|||||||
if world.owCrossed[player] == 'chaos' and random.randint(0, 1):
|
if world.owCrossed[player] == 'chaos' and random.randint(0, 1):
|
||||||
crossed_edges.append(edge)
|
crossed_edges.append(edge)
|
||||||
elif world.owCrossed[player] == 'limited':
|
elif world.owCrossed[player] == 'limited':
|
||||||
crossed_candidates.append(edge)
|
crossed_candidates.append([edge])
|
||||||
if world.owCrossed[player] == 'limited':
|
if world.owCrossed[player] == 'limited':
|
||||||
random.shuffle(crossed_candidates)
|
random.shuffle(crossed_candidates)
|
||||||
for edge_set in crossed_candidates[:9]:
|
for edge_set in crossed_candidates[:9]:
|
||||||
@@ -253,6 +256,8 @@ def link_overworld(world, player):
|
|||||||
logging.getLogger('').warning("Edge '%s' could not find a valid connection" % back_set[0])
|
logging.getLogger('').warning("Edge '%s' could not find a valid connection" % back_set[0])
|
||||||
assert len(connected_edges) == len(default_connections) * 2, connected_edges
|
assert len(connected_edges) == len(default_connections) * 2, connected_edges
|
||||||
|
|
||||||
|
# TODO: Reshuffle some areas if impossible to reach, exception if non-dungeon ER enabled or if area is LW with no portal and flute shuffle is enabled
|
||||||
|
|
||||||
# flute shuffle
|
# flute shuffle
|
||||||
def connect_flutes(flute_destinations):
|
def connect_flutes(flute_destinations):
|
||||||
for o in range(0, len(flute_destinations)):
|
for o in range(0, len(flute_destinations)):
|
||||||
@@ -276,7 +281,7 @@ def link_overworld(world, player):
|
|||||||
region = world.get_region(regionname, player)
|
region = world.get_region(regionname, player)
|
||||||
for exit in region.exits:
|
for exit in region.exits:
|
||||||
if exit.connected_region is not None and exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld] and exit.connected_region.name not in new_ignored:
|
if exit.connected_region is not None and exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld] and exit.connected_region.name not in new_ignored:
|
||||||
if OWTileRegions[exit.connected_region.name] in [base_owid, owid] or OWTileRegions[regionname] == base_owid:
|
if exit.connected_region.name in OWTileRegions and (OWTileRegions[exit.connected_region.name] in [base_owid, owid] or OWTileRegions[regionname] == base_owid):
|
||||||
new_ignored.add(exit.connected_region.name)
|
new_ignored.add(exit.connected_region.name)
|
||||||
getIgnored(exit.connected_region.name, base_owid, OWTileRegions[exit.connected_region.name])
|
getIgnored(exit.connected_region.name, base_owid, OWTileRegions[exit.connected_region.name])
|
||||||
|
|
||||||
@@ -422,16 +427,18 @@ def shuffle_tiles(world, groups, result_list, player):
|
|||||||
def reorganize_tile_groups(world, player):
|
def reorganize_tile_groups(world, player):
|
||||||
groups = {}
|
groups = {}
|
||||||
for (name, groupType) in OWTileGroups.keys():
|
for (name, groupType) in OWTileGroups.keys():
|
||||||
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks']:
|
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks'] \
|
||||||
if world.shuffle[player] in ['vanilla', 'simple', 'dungeonssimple']:
|
or (world.mode[player] == 'standard' and world.shuffle[player] in ['lite', 'lean', 'crossed', 'insanity'] and name == 'Castle' and groupType == 'Entrance'):
|
||||||
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
||||||
groups[(name,)] = ([], [], [])
|
groups[(name,)] = ([], [], [])
|
||||||
else:
|
else:
|
||||||
groups[(name, groupType)] = ([], [], [])
|
groups[(name, groupType)] = ([], [], [])
|
||||||
|
|
||||||
for (name, groupType) in OWTileGroups.keys():
|
for (name, groupType) in OWTileGroups.keys():
|
||||||
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks']:
|
if world.mode[player] != 'standard' or name not in ['Castle', 'Links', 'Central Bonk Rocks'] \
|
||||||
|
or (world.mode[player] == 'standard' and world.shuffle[player] in ['lite', 'lean', 'crossed', 'insanity'] and name == 'Castle' and groupType == 'Entrance'):
|
||||||
(lw_owids, dw_owids) = OWTileGroups[(name, groupType,)]
|
(lw_owids, dw_owids) = OWTileGroups[(name, groupType,)]
|
||||||
if world.shuffle[player] in ['vanilla', 'simple', 'dungeonssimple']:
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'simple', 'restricted']:
|
||||||
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name,)]
|
(exist_owids, exist_lw_regions, exist_dw_regions) = groups[(name,)]
|
||||||
exist_owids.extend(lw_owids)
|
exist_owids.extend(lw_owids)
|
||||||
exist_owids.extend(dw_owids)
|
exist_owids.extend(dw_owids)
|
||||||
@@ -646,11 +653,20 @@ def create_flute_exits(world, player):
|
|||||||
and (region.name not in world.owswaps[player][1] or region.name in world.owswaps[player][2])):
|
and (region.name not in world.owswaps[player][1] or region.name in world.owswaps[player][2])):
|
||||||
exitname = 'Flute From ' + region.name
|
exitname = 'Flute From ' + region.name
|
||||||
exit = Entrance(region.player, exitname, region)
|
exit = Entrance(region.player, exitname, region)
|
||||||
|
exit.spot_type = 'Flute'
|
||||||
exit.access_rule = lambda state: state.can_flute(player)
|
exit.access_rule = lambda state: state.can_flute(player)
|
||||||
exit.connect(world.get_region('Flute Sky', player))
|
exit.connect(world.get_region('Flute Sky', player))
|
||||||
region.exits.append(exit)
|
region.exits.append(exit)
|
||||||
world.initialize_regions()
|
world.initialize_regions()
|
||||||
|
|
||||||
|
def categorize_world_regions(world, player):
|
||||||
|
for type in OWExitTypes:
|
||||||
|
for exitname in OWExitTypes[type]:
|
||||||
|
world.get_entrance(exitname, player).spot_type = type
|
||||||
|
|
||||||
|
mark_light_world_regions(world, player)
|
||||||
|
mark_dark_world_regions(world, player)
|
||||||
|
|
||||||
def update_world_regions(world, player):
|
def update_world_regions(world, player):
|
||||||
if world.owMixed[player]:
|
if world.owMixed[player]:
|
||||||
for name in world.owswaps[player][1]:
|
for name in world.owswaps[player][1]:
|
||||||
@@ -658,6 +674,52 @@ def update_world_regions(world, player):
|
|||||||
for name in world.owswaps[player][2]:
|
for name in world.owswaps[player][2]:
|
||||||
world.get_region(name, player).type = RegionType.LightWorld
|
world.get_region(name, player).type = RegionType.LightWorld
|
||||||
|
|
||||||
|
def can_reach_smith(world, player):
|
||||||
|
from Items import ItemFactory
|
||||||
|
from BaseClasses import CollectionState
|
||||||
|
|
||||||
|
invFlag = world.mode[player] == 'inverted'
|
||||||
|
|
||||||
|
def explore_region(region_name, region=None):
|
||||||
|
nonlocal found
|
||||||
|
explored_regions.add(region_name)
|
||||||
|
if not found:
|
||||||
|
if not region:
|
||||||
|
region = world.get_region(region_name, player)
|
||||||
|
for exit in region.exits:
|
||||||
|
if not found and exit.connected_region is not None:
|
||||||
|
if any(map(lambda i: i.name == 'Ocarina', world.precollected_items)) and exit.spot_type == 'Flute':
|
||||||
|
fluteregion = exit.connected_region
|
||||||
|
for flutespot in fluteregion.exits:
|
||||||
|
if flutespot.connected_region and flutespot.connected_region.name not in explored_regions:
|
||||||
|
explore_region(flutespot.connected_region.name, flutespot.connected_region)
|
||||||
|
elif exit.connected_region.name not in explored_regions \
|
||||||
|
and exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld] \
|
||||||
|
and exit.access_rule(blank_state):
|
||||||
|
explore_region(exit.connected_region.name, exit.connected_region)
|
||||||
|
elif exit.name == 'Sanctuary S':
|
||||||
|
sanc_region = exit.connected_region
|
||||||
|
if len(sanc_region.exits) and sanc_region.exits[0].name == 'Sanctuary Exit':
|
||||||
|
explore_region(sanc_region.exits[0].connected_region.name, sanc_region.exits[0].connected_region)
|
||||||
|
elif exit.connected_region.name == 'Blacksmiths Hut' and exit.access_rule(blank_state):
|
||||||
|
found = True
|
||||||
|
|
||||||
|
blank_state = CollectionState(world)
|
||||||
|
if world.mode[player] == 'standard':
|
||||||
|
blank_state.collect(ItemFactory('Zelda Delivered', player), True)
|
||||||
|
if world.logic[player] in ['noglitches', 'minorglitches'] and world.get_region('Frog Prison', player).type == (RegionType.DarkWorld if not invFlag else RegionType.LightWorld):
|
||||||
|
blank_state.collect(ItemFactory('Titans Mitts', player), True)
|
||||||
|
|
||||||
|
found = False
|
||||||
|
explored_regions = set()
|
||||||
|
explore_region('Links House')
|
||||||
|
if not found:
|
||||||
|
if not invFlag:
|
||||||
|
explore_region('Sanctuary')
|
||||||
|
else:
|
||||||
|
explore_region('Dark Sanctuary Hint')
|
||||||
|
return found
|
||||||
|
|
||||||
test_connections = [
|
test_connections = [
|
||||||
#('Links House ES', 'Octoballoon WS'),
|
#('Links House ES', 'Octoballoon WS'),
|
||||||
#('Links House NE', 'Lost Woods Pass SW')
|
#('Links House NE', 'Lost Woods Pass SW')
|
||||||
@@ -744,6 +806,7 @@ mandatory_connections = [# Whirlpool Connections
|
|||||||
('Wooden Bridge Water Drop', 'Wooden Bridge Water'), #flippers
|
('Wooden Bridge Water Drop', 'Wooden Bridge Water'), #flippers
|
||||||
('Wooden Bridge Northeast Water Drop', 'Wooden Bridge Water'), #flippers
|
('Wooden Bridge Northeast Water Drop', 'Wooden Bridge Water'), #flippers
|
||||||
('Bat Cave Ledge Peg', 'Bat Cave Ledge'), #hammer
|
('Bat Cave Ledge Peg', 'Bat Cave Ledge'), #hammer
|
||||||
|
('Bat Cave Ledge Peg (East)', 'Blacksmith Area'), #hammer
|
||||||
('Maze Race Game', 'Maze Race Prize'), #pearl
|
('Maze Race Game', 'Maze Race Prize'), #pearl
|
||||||
('Maze Race Ledge Drop', 'Maze Race Area'),
|
('Maze Race Ledge Drop', 'Maze Race Area'),
|
||||||
('Desert Palace Statue Move', 'Desert Palace Stairs'), #book
|
('Desert Palace Statue Move', 'Desert Palace Stairs'), #book
|
||||||
@@ -813,7 +876,7 @@ mandatory_connections = [# Whirlpool Connections
|
|||||||
('Grassy Lawn Pegs', 'Village of Outcasts Area'), #hammer
|
('Grassy Lawn Pegs', 'Village of Outcasts Area'), #hammer
|
||||||
('Shield Shop Fence (Outer) Ledge Drop', 'Shield Shop Fence'),
|
('Shield Shop Fence (Outer) Ledge Drop', 'Shield Shop Fence'),
|
||||||
('Shield Shop Fence (Inner) Ledge Drop', 'Shield Shop Area'),
|
('Shield Shop Fence (Inner) Ledge Drop', 'Shield Shop Area'),
|
||||||
('Pyramid Exit Ledge Drop', 'Pyramid Area'), #hammer(inverted)
|
('Pyramid Exit Ledge Drop', 'Pyramid Area'),
|
||||||
('Broken Bridge Hammer Rock (South)', 'Broken Bridge Northeast'), #hammer/glove
|
('Broken Bridge Hammer Rock (South)', 'Broken Bridge Northeast'), #hammer/glove
|
||||||
('Broken Bridge Hammer Rock (North)', 'Broken Bridge Area'), #hammer/glove
|
('Broken Bridge Hammer Rock (North)', 'Broken Bridge Area'), #hammer/glove
|
||||||
('Broken Bridge Hookshot Gap', 'Broken Bridge West'), #hookshot
|
('Broken Bridge Hookshot Gap', 'Broken Bridge West'), #hookshot
|
||||||
@@ -1071,6 +1134,7 @@ ow_connections = {
|
|||||||
('HC Ledge Mirror Spot', 'Hyrule Castle Ledge'),
|
('HC Ledge Mirror Spot', 'Hyrule Castle Ledge'),
|
||||||
('HC Courtyard Mirror Spot', 'Hyrule Castle Courtyard'),
|
('HC Courtyard Mirror Spot', 'Hyrule Castle Courtyard'),
|
||||||
('HC Area Mirror Spot', 'Hyrule Castle Area'),
|
('HC Area Mirror Spot', 'Hyrule Castle Area'),
|
||||||
|
('HC Courtyard Left Mirror Spot', 'Hyrule Castle Courtyard'),
|
||||||
('HC Area South Mirror Spot', 'Hyrule Castle Area'),
|
('HC Area South Mirror Spot', 'Hyrule Castle Area'),
|
||||||
('HC East Entry Mirror Spot', 'Hyrule Castle East Entry'),
|
('HC East Entry Mirror Spot', 'Hyrule Castle East Entry'),
|
||||||
('Top of Pyramid', 'Pyramid Area'),
|
('Top of Pyramid', 'Pyramid Area'),
|
||||||
@@ -1439,9 +1503,10 @@ flute_data = {
|
|||||||
0x2e: (['Tree Line Area', 'Dark Tree Line Area'], 0x2e, 0x0100, 0x0a1a, 0x0c00, 0x0a78, 0x0c30, 0x0a87, 0x0c7d, 0x0006, 0x0000, 0x0a78, 0x0c58),
|
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),
|
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),
|
0x38: (['Desert Palace Teleporter Ledge', 'Misery Mire Teleporter Ledge'], 0x30, 0x1880, 0x0f1e, 0x0000, 0x0fa8, 0x0078, 0x0f8d, 0x008d, 0x0000, 0x0000, 0x0fb0, 0x0070),
|
||||||
0x32: (['Flute Boy Approach Area', 'Stumpy Approach Area'], 0x32, 0x03a0, 0x0c6c, 0x0500, 0x0cd0, 0x05a8, 0x0cdb, 0x0585, 0x0002, 0x0000, 0x0cd6, 0x05a8),
|
0x32: (['Flute Boy Approach Area', 'Stumpy Approach Area'], 0x32, 0x03a0, 0x0c6c, 0x0500, 0x0cd0, 0x05a8, 0x0cdb, 0x0585, 0x0002, 0x0000, 0x0cd6, 0x0568),
|
||||||
0x33: (['C Whirlpool Outer Area', 'Dark C Whirlpool Outer Area'], 0x33, 0x0180, 0x0c20, 0x0600, 0x0c80, 0x0628, 0x0c8f, 0x067d, 0x0000, 0x0000, 0x0c80, 0x0628),
|
0x33: (['C Whirlpool Outer Area', 'Dark C Whirlpool Outer Area'], 0x33, 0x0180, 0x0c20, 0x0600, 0x0c80, 0x0628, 0x0c8f, 0x067d, 0x0000, 0x0000, 0x0c80, 0x0628),
|
||||||
0x34: (['Statues Area', 'Hype Cave Area'], 0x34, 0x088e, 0x0d00, 0x0866, 0x0d60, 0x08d8, 0x0d6f, 0x08e3, 0x0000, 0x000a, 0x0d60, 0x08d8),
|
0x34: (['Statues Area', 'Hype Cave Area'], 0x34, 0x088e, 0x0d00, 0x0866, 0x0d60, 0x08d8, 0x0d6f, 0x08e3, 0x0000, 0x000a, 0x0d60, 0x08d8),
|
||||||
|
#0x35: (['Lake Hylia Area', 'Ice Lake Area'], 0x35, 0x0d00, 0x0da6, 0x0a06, 0x0e08, 0x0a80, 0x0e13, 0x0a8b, 0xfffa, 0xfffa, 0x0d88, 0x0a88),
|
||||||
0x3e: (['Lake Hylia South Shore', 'Ice Lake Ledge (East)'], 0x35, 0x1860, 0x0f1e, 0x0d00, 0x0f98, 0x0da8, 0x0f8b, 0x0d85, 0x0000, 0x0000, 0x0f90, 0x0da4),
|
0x3e: (['Lake Hylia South Shore', 'Ice Lake Ledge (East)'], 0x35, 0x1860, 0x0f1e, 0x0d00, 0x0f98, 0x0da8, 0x0f8b, 0x0d85, 0x0000, 0x0000, 0x0f90, 0x0da4),
|
||||||
0x37: (['Ice Cave Area', 'Shopping Mall Area'], 0x37, 0x0786, 0x0cf6, 0x0e2e, 0x0d58, 0x0ea0, 0x0d63, 0x0eab, 0x000a, 0x0002, 0x0d48, 0x0ed0),
|
0x37: (['Ice Cave Area', 'Shopping Mall Area'], 0x37, 0x0786, 0x0cf6, 0x0e2e, 0x0d58, 0x0ea0, 0x0d63, 0x0eab, 0x000a, 0x0002, 0x0d48, 0x0ed0),
|
||||||
0x3a: (['Desert Pass Area', 'Swamp Nook Area'], 0x3a, 0x001a, 0x0e08, 0x04c6, 0x0e70, 0x0540, 0x0e7d, 0x054b, 0x0006, 0x000a, 0x0e70, 0x0540),
|
0x3a: (['Desert Pass Area', 'Swamp Nook Area'], 0x3a, 0x001a, 0x0e08, 0x04c6, 0x0e70, 0x0540, 0x0e7d, 0x054b, 0x0006, 0x000a, 0x0e70, 0x0540),
|
||||||
|
|||||||
@@ -129,6 +129,42 @@ New flute spots are chosen at random, with restrictions that limit the promixity
|
|||||||
|
|
||||||
New flute spots are chosen at random with minimum bias.
|
New flute spots are chosen at random with minimum bias.
|
||||||
|
|
||||||
|
## New Entrance Shuffle Options (--shuffle)
|
||||||
|
|
||||||
|
### Lite
|
||||||
|
|
||||||
|
This mode is intended to be a beginner-friendly introduction to playing ER. It focuses on reducing low% world traversal in late-game dungeons while reducing the number of entrances needing to be checked.
|
||||||
|
|
||||||
|
This mode groups entrances into types and shuffles them freely within those groups.
|
||||||
|
- Dungeons and Connectors (Multi-Entrance Caves)
|
||||||
|
- Item Locations (Single-Entrance Caves with an item, includes Potion Shop and Red Bomb Shop, includes Shops only if Shopsanity is enabled)
|
||||||
|
- Dropdowns and their associated exits (Skull Woods dropdowns are handled the same as in Crossed)
|
||||||
|
- Non-item locations (junk locations) all remain vanilla
|
||||||
|
|
||||||
|
Lite mode shuffles all connectors same-world, to limit bunny traversal. And to prevent Low% enemy and boss combat, some dungeons are confined to specific worlds.
|
||||||
|
|
||||||
|
The following dungeons are guaranteed to be in the Light World:
|
||||||
|
- Hyrule Castle
|
||||||
|
- Eastern Palace
|
||||||
|
- Desert Palace
|
||||||
|
- Tower of Hera
|
||||||
|
- Agahnim's Tower
|
||||||
|
|
||||||
|
The following are guaranteed to be in the Dark World:
|
||||||
|
- Ice Palace
|
||||||
|
- Misery Mire
|
||||||
|
- Turtle Rock
|
||||||
|
- Ganon's Tower
|
||||||
|
|
||||||
|
### Lean
|
||||||
|
|
||||||
|
This mode is intended to be a more refined and more competitive format to Crossed ER. It focuses on reducing the number of entrances needing to be checked, while giving the player unique routing options based on the entrance pools defined below, as opposed to mindlessly checking all the remaining entrances. The Dungeons/Connectors can connect cross-world.
|
||||||
|
|
||||||
|
This mode groups entrances into types and shuffles them freely within those groups.
|
||||||
|
- Dungeons and Connectors (Multi-Entrance Caves)
|
||||||
|
- Item Locations (Single-Entrance Caves with an item, includes Potion Shop and Red Bomb Shop, includes Shops only if Shopsanity is enabled)
|
||||||
|
- Dropdowns and their associated exits (Skull Woods dropdowns are handled the same as in Crossed)
|
||||||
|
- Non-item locations (junk locations) all remain vanilla
|
||||||
|
|
||||||
# Command Line Options
|
# Command Line Options
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,14 @@ CLI: ```--bombbag```
|
|||||||
|
|
||||||
# Bug Fixes and Notes.
|
# Bug Fixes and Notes.
|
||||||
|
|
||||||
|
* 0.5.1.4
|
||||||
|
* Revert quadrant glitch fix for baserom
|
||||||
|
* Fix for inverted
|
||||||
|
* 0.5.1.3
|
||||||
|
* Certain lobbies forbidden in standard when rupee bow is enabled
|
||||||
|
* PoD EG disarmed when mirroring (except in nologic)
|
||||||
|
* Fixed issue with key logic
|
||||||
|
* Updated baserom
|
||||||
* 0.5.1.2
|
* 0.5.1.2
|
||||||
* Allowed Blind's Cell to be shuffled anywhere if Blind is not the boss of Thieves Town
|
* Allowed Blind's Cell to be shuffled anywhere if Blind is not the boss of Thieves Town
|
||||||
* Remove unique annotation from a FastEnum that was causing problems
|
* Remove unique annotation from a FastEnum that was causing problems
|
||||||
|
|||||||
+3
-3
@@ -70,7 +70,7 @@ def create_regions(world, player):
|
|||||||
create_lw_region(player, 'Eastern Palace Area', None, ['Sahasrahlas Hut', 'Eastern Palace', 'Palace of Darkness Mirror Spot', 'Eastern Palace SW', 'Eastern Palace SE']),
|
create_lw_region(player, 'Eastern Palace Area', None, ['Sahasrahlas Hut', 'Eastern Palace', 'Palace of Darkness Mirror Spot', 'Eastern Palace SW', 'Eastern Palace SE']),
|
||||||
create_lw_region(player, 'Eastern Cliff', None, ['Sand Dunes Ledge Drop', 'Stone Bridge East Ledge Drop', 'Tree Line Ledge Drop', 'Eastern Palace Ledge Drop']),
|
create_lw_region(player, 'Eastern Cliff', None, ['Sand Dunes Ledge Drop', 'Stone Bridge East Ledge Drop', 'Tree Line Ledge Drop', 'Eastern Palace Ledge Drop']),
|
||||||
create_lw_region(player, 'Blacksmith Area', None, ['Blacksmiths Hut', 'Bat Cave Cave', 'Bat Cave Ledge Peg', 'Hammer Pegs Mirror Spot', 'Hammer Pegs Entry Mirror Spot', 'Blacksmith WS']),
|
create_lw_region(player, 'Blacksmith Area', None, ['Blacksmiths Hut', 'Bat Cave Cave', 'Bat Cave Ledge Peg', 'Hammer Pegs Mirror Spot', 'Hammer Pegs Entry Mirror Spot', 'Blacksmith WS']),
|
||||||
create_lw_region(player, 'Bat Cave Ledge', None, ['Bat Cave Drop']),
|
create_lw_region(player, 'Bat Cave Ledge', None, ['Bat Cave Ledge Peg (East)', 'Bat Cave Drop']),
|
||||||
create_lw_region(player, 'Sand Dunes Area', None, ['Dark Dunes Mirror Spot', 'Sand Dunes NW', 'Sand Dunes WN', 'Sand Dunes SC']),
|
create_lw_region(player, 'Sand Dunes Area', None, ['Dark Dunes Mirror Spot', 'Sand Dunes NW', 'Sand Dunes WN', 'Sand Dunes SC']),
|
||||||
create_lw_region(player, 'Maze Race Area', None, ['Dig Game Mirror Spot', 'Maze Race ES']),
|
create_lw_region(player, 'Maze Race Area', None, ['Dig Game Mirror Spot', 'Maze Race ES']),
|
||||||
create_lw_region(player, 'Maze Race Ledge', None, ['Two Brothers House (West)', 'Maze Race Game', 'Dig Game Ledge Mirror Spot']),
|
create_lw_region(player, 'Maze Race Ledge', None, ['Two Brothers House (West)', 'Maze Race Game', 'Dig Game Ledge Mirror Spot']),
|
||||||
@@ -82,7 +82,7 @@ def create_regions(world, player):
|
|||||||
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, '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 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 Water', None, ['Dark Hobo Mirror Spot', 'Stone Bridge WC', 'Stone Bridge EC'], Terrain.Water),
|
create_lw_region(player, 'Stone Bridge Water', None, ['Dark Hobo Mirror Spot', 'Stone Bridge WC', 'Stone Bridge EC'], Terrain.Water),
|
||||||
create_lw_region(player, 'Hobo Bridge', ['Hobo'], ['Hobo EC']),
|
create_lw_region(player, 'Hobo Bridge', ['Hobo'], ['Hobo EC'], 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', 'South Teleporter Cliff Ledge Drop', 'Statues Cliff Ledge Drop']),
|
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', 'South Teleporter Cliff Ledge Drop', 'Statues Cliff Ledge Drop']),
|
||||||
create_lw_region(player, 'Tree Line Area', None, ['Lake Hylia Fairy', 'Dark Tree Line Mirror Spot', 'Tree Line WN', 'Tree Line NW', 'Tree Line SE']),
|
create_lw_region(player, 'Tree Line Area', None, ['Lake Hylia Fairy', 'Dark Tree Line Mirror Spot', 'Tree Line WN', 'Tree Line NW', 'Tree Line SE']),
|
||||||
create_lw_region(player, 'Tree Line Water', None, ['Tree Line WC', 'Tree Line SC'], Terrain.Water),
|
create_lw_region(player, 'Tree Line Water', None, ['Tree Line WC', 'Tree Line SC'], Terrain.Water),
|
||||||
@@ -164,7 +164,7 @@ def create_regions(world, player):
|
|||||||
create_dw_region(player, 'Shield Shop Area', None, ['Shield Shop Fence (Outer) Ledge Drop', 'Forgotton Forest Mirror Spot', 'Shield Shop NW', 'Shield Shop NE']),
|
create_dw_region(player, 'Shield Shop Area', None, ['Shield Shop Fence (Outer) Ledge Drop', 'Forgotton Forest Mirror Spot', 'Shield Shop NW', 'Shield Shop NE']),
|
||||||
create_dw_region(player, 'Shield Shop Fence', None, ['Shield Shop Fence (Inner) Ledge Drop', 'Red Shield Shop', 'Forgotton Forest Fence Mirror Spot']),
|
create_dw_region(player, 'Shield Shop Fence', None, ['Shield Shop Fence (Inner) Ledge Drop', 'Red Shield Shop', 'Forgotton Forest Fence Mirror Spot']),
|
||||||
create_dw_region(player, 'Pyramid Area', ['Pyramid'], ['Pyramid Fairy', 'Pyramid Hole', 'HC Ledge Mirror Spot', 'HC Courtyard Mirror Spot', 'HC Area Mirror Spot', 'HC East Entry Mirror Spot', 'Pyramid ES']),
|
create_dw_region(player, 'Pyramid Area', ['Pyramid'], ['Pyramid Fairy', 'Pyramid Hole', 'HC Ledge Mirror Spot', 'HC Courtyard Mirror Spot', 'HC Area Mirror Spot', 'HC East Entry Mirror Spot', 'Pyramid ES']),
|
||||||
create_dw_region(player, 'Pyramid Exit Ledge', None, ['Pyramid Exit Ledge Drop', 'Pyramid Entrance']),
|
create_dw_region(player, 'Pyramid Exit Ledge', None, ['Pyramid Exit Ledge Drop', 'HC Courtyard Left Mirror Spot', 'Pyramid Entrance']),
|
||||||
create_dw_region(player, 'Pyramid Pass', None, ['Post Aga Inverted Teleporter', 'HC Area South Mirror Spot', 'Pyramid SW', 'Pyramid SE']),
|
create_dw_region(player, 'Pyramid Pass', None, ['Post Aga Inverted Teleporter', 'HC Area South Mirror Spot', 'Pyramid SW', 'Pyramid SE']),
|
||||||
create_dw_region(player, 'Broken Bridge Area', None, ['Broken Bridge Hammer Rock (South)', 'Broken Bridge Water Drop', 'Wooden Bridge Mirror Spot', 'Broken Bridge SW']),
|
create_dw_region(player, 'Broken Bridge Area', None, ['Broken Bridge Hammer Rock (South)', 'Broken Bridge Water Drop', 'Wooden Bridge Mirror Spot', 'Broken Bridge SW']),
|
||||||
create_dw_region(player, 'Broken Bridge Northeast', None, ['Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', 'Broken Bridge Northeast Water Drop', 'Wooden Bridge Northeast Mirror Spot', 'Broken Bridge NE']),
|
create_dw_region(player, 'Broken Bridge Northeast', None, ['Broken Bridge Hammer Rock (North)', 'Broken Bridge Hookshot Gap', 'Broken Bridge Northeast Water Drop', 'Wooden Bridge Northeast Mirror Spot', 'Broken Bridge NE']),
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = 'c81153d8bb571e41fe472d36274f47b3'
|
RANDOMIZERBASEHASH = 'c6c2a2d5d89a3c84871f58806bbb3acf'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -646,8 +646,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
|
|
||||||
# patch overworld edges
|
# patch overworld edges
|
||||||
inverted_buffer = [0] * 0x82
|
inverted_buffer = [0] * 0x82
|
||||||
if world.owShuffle[player] != 'vanilla' or world.owCrossed[player] not in ['none', 'polar'] or world.owMixed[player]:
|
|
||||||
owMode = 0
|
owMode = 0
|
||||||
|
if world.owShuffle[player] != 'vanilla' or world.owCrossed[player] not in ['none', 'polar'] or world.owMixed[player]:
|
||||||
if world.owShuffle[player] == 'parallel':
|
if world.owShuffle[player] == 'parallel':
|
||||||
owMode = 1
|
owMode = 1
|
||||||
elif world.owShuffle[player] == 'full':
|
elif world.owShuffle[player] == 'full':
|
||||||
@@ -661,12 +661,6 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
if world.owMixed[player]:
|
if world.owMixed[player]:
|
||||||
owMode |= 0x400
|
owMode |= 0x400
|
||||||
|
|
||||||
write_int16(rom, 0x150002, owMode)
|
|
||||||
|
|
||||||
write_int16(rom, 0x150004, owFlags)
|
|
||||||
|
|
||||||
rom.write_byte(0x18004C, 0x01) # patch for allowing Frogsmith to enter multi-entrance caves
|
|
||||||
|
|
||||||
# patches map data specific for OW Shuffle
|
# patches map data specific for OW Shuffle
|
||||||
#inverted_buffer[0x03] = inverted_buffer[0x03] | 0x2 # convenient portal on WDM
|
#inverted_buffer[0x03] = inverted_buffer[0x03] | 0x2 # convenient portal on WDM
|
||||||
inverted_buffer[0x1A] = inverted_buffer[0x1A] | 0x2 # rocks added to prevent OWG hardlock
|
inverted_buffer[0x1A] = inverted_buffer[0x1A] | 0x2 # rocks added to prevent OWG hardlock
|
||||||
@@ -692,6 +686,12 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
write_int16(rom, edge.getAddress() + 0x0a, edge.vramLoc)
|
write_int16(rom, edge.getAddress() + 0x0a, edge.vramLoc)
|
||||||
write_int16(rom, edge.getAddress() + 0x0e, edge.getTarget())
|
write_int16(rom, edge.getAddress() + 0x0e, edge.getTarget())
|
||||||
|
|
||||||
|
write_int16(rom, 0x150002, owMode)
|
||||||
|
write_int16(rom, 0x150004, owFlags)
|
||||||
|
|
||||||
|
from OverworldShuffle import can_reach_smith
|
||||||
|
if not can_reach_smith(world, player):
|
||||||
|
rom.write_byte(0x18005d, 0x01) # patch for deleting smith on S+Q
|
||||||
|
|
||||||
# patch entrance/exits/holes
|
# patch entrance/exits/holes
|
||||||
for region in world.regions:
|
for region in world.regions:
|
||||||
@@ -771,6 +771,8 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
dr_flags |= DROptions.OriginalPalettes
|
dr_flags |= DROptions.OriginalPalettes
|
||||||
if world.experimental[player]:
|
if world.experimental[player]:
|
||||||
dr_flags |= DROptions.DarkWorld_Spawns
|
dr_flags |= DROptions.DarkWorld_Spawns
|
||||||
|
if world.logic[player] != 'nologic':
|
||||||
|
dr_flags |= DROptions.Fix_EG
|
||||||
|
|
||||||
|
|
||||||
# fix hc big key problems (map and compass too)
|
# fix hc big key problems (map and compass too)
|
||||||
@@ -1601,7 +1603,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
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[player] in ['restricted', 'full', 'crossed', 'insanity'] or (world.shuffle[player] == 'simple' and world.mode[player] == 'inverted'):
|
if world.shuffle[player] in ['restricted', 'full', 'lite', 'lean', 'crossed', 'insanity'] or (world.shuffle[player] == 'simple' and world.mode[player] == 'inverted'):
|
||||||
rom.write_byte(0x18004C, 0x01)
|
rom.write_byte(0x18004C, 0x01)
|
||||||
|
|
||||||
# set correct flag for hera basement item
|
# set correct flag for hera basement item
|
||||||
@@ -2478,7 +2480,8 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
|||||||
write_int16(rom, 0x15AEE + 2*0x25, 0x000C)
|
write_int16(rom, 0x15AEE + 2*0x25, 0x000C)
|
||||||
|
|
||||||
if (world.mode[player] == 'inverted') != (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x03 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
if world.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple']:
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] \
|
||||||
|
or (world.shuffle[player] == 'simple' and (world.mode[player] == 'inverted' != (0x05 in world.owswaps[player][0] and world.owMixed[player]))):
|
||||||
rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) # mountain cave starts on OW
|
rom.write_bytes(snes_to_pc(0x308350), [0x00, 0x00, 0x01]) # mountain cave starts on OW
|
||||||
|
|
||||||
write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) # change mountain cave spawn point to just outside old man cave
|
write_int16(rom, snes_to_pc(0x02D8DE), 0x00F1) # change mountain cave spawn point to just outside old man cave
|
||||||
@@ -2502,6 +2505,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
|||||||
rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) # indicates the overworld door being used for the single entrance spawn point
|
rom.write_bytes(0x180247, [0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00]) # indicates the overworld door being used for the single entrance spawn point
|
||||||
if (world.mode[player] == 'inverted') != (0x05 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x05 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock
|
rom.write_bytes(snes_to_pc(0x1BC655), [0x4A, 0x1D, 0x82]) # add warp under rock
|
||||||
|
rom.write_byte(snes_to_pc(0x1BC428), 0x00) # remove secret portal
|
||||||
if (world.mode[player] == 'inverted') != (0x07 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x07 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x1BC387), [0xDD, 0xD1]) # add warps under rocks
|
rom.write_bytes(snes_to_pc(0x1BC387), [0xDD, 0xD1]) # add warps under rocks
|
||||||
rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks
|
rom.write_bytes(snes_to_pc(0x1BD1DD), [0xA4, 0x06, 0x82, 0x9E, 0x06, 0x82, 0xFF, 0xFF]) # add warps under rocks
|
||||||
@@ -2511,6 +2515,7 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
|||||||
world.fix_trock_doors[player] = True
|
world.fix_trock_doors[player] = True
|
||||||
if (world.mode[player] == 'inverted') != (0x10 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x10 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warp under rock
|
rom.write_bytes(snes_to_pc(0x1BC67A), [0x2E, 0x0B, 0x82]) # add warp under rock
|
||||||
|
rom.write_byte(snes_to_pc(0x1BC43A), 0x00) # remove secret portal
|
||||||
if (world.mode[player] == 'inverted') != (0x1B in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x1B in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
write_int16(rom, 0x15AEE + 2 * 0x06, 0x0020) # post aga hyrule castle spawn
|
write_int16(rom, 0x15AEE + 2 * 0x06, 0x0020) # post aga hyrule castle spawn
|
||||||
rom.write_byte(0x15B8C + 0x06, 0x1B)
|
rom.write_byte(0x15B8C + 0x06, 0x1B)
|
||||||
@@ -2599,6 +2604,23 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
|||||||
|
|
||||||
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, 0x011C)
|
write_int16(rom, 0xDBA71 + 2 * 0x35, 0x011C)
|
||||||
|
|
||||||
|
if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
|
||||||
|
rom.write_byte(0xDBB73 + 0x35, 0x36) # move pyramid exit door
|
||||||
|
|
||||||
|
write_int16(rom, 0x15AEE + 2 * 0x37, 0x0010) # pyramid exit to new hc area
|
||||||
|
rom.write_byte(0x15B8C + 0x37, 0x1B)
|
||||||
|
write_int16(rom, 0x15BDB + 2 * 0x37, 0x000E)
|
||||||
|
write_int16(rom, 0x15C79 + 2 * 0x37, 0x0600)
|
||||||
|
write_int16(rom, 0x15D17 + 2 * 0x37, 0x0676)
|
||||||
|
write_int16(rom, 0x15DB5 + 2 * 0x37, 0x0604)
|
||||||
|
write_int16(rom, 0x15E53 + 2 * 0x37, 0x06E8)
|
||||||
|
write_int16(rom, 0x15EF1 + 2 * 0x37, 0x066D)
|
||||||
|
write_int16(rom, 0x15F8F + 2 * 0x37, 0x06F3)
|
||||||
|
rom.write_byte(0x1602D + 0x37, 0x00)
|
||||||
|
rom.write_byte(0x1607C + 0x37, 0x0A)
|
||||||
|
write_int16(rom, 0x160CB + 2 * 0x37, 0x0000)
|
||||||
|
write_int16(rom, 0x16169 + 2 * 0x37, 0x811C)
|
||||||
if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x29 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact
|
rom.write_bytes(snes_to_pc(0x06B2AB), [0xF0, 0xE1, 0x05]) # frog pickup on contact
|
||||||
if (world.mode[player] == 'inverted') != (0x2C in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x2C in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
@@ -2608,13 +2630,17 @@ def set_inverted_mode(world, player, rom, inverted_buffer):
|
|||||||
rom.write_byte(0xDBB73 + 0x52, 0x01)
|
rom.write_byte(0xDBB73 + 0x52, 0x01)
|
||||||
if (world.mode[player] == 'inverted') != (0x2F in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x2F in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x1BC80D), [0xB2, 0x0B, 0x82]) # add warp under rock
|
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
|
||||||
if (world.mode[player] == 'inverted') != (0x30 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x30 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x1BC81E), [0x94, 0x1D, 0x82]) # add warp under rock
|
rom.write_bytes(snes_to_pc(0x1BC81E), [0x94, 0x1D, 0x82]) # add warp under rock
|
||||||
|
rom.write_byte(snes_to_pc(0x1BC5A1), 0x00) # remove secret portal
|
||||||
if (world.mode[player] == 'inverted') != (0x33 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x33 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x1BC3DF), [0xD8, 0xD1]) # add warp under rock
|
rom.write_bytes(snes_to_pc(0x1BC3DF), [0xD8, 0xD1]) # add warp under rock
|
||||||
rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) # add warp under rock
|
rom.write_bytes(snes_to_pc(0x1BD1D8), [0xA8, 0x02, 0x82, 0xFF, 0xFF]) # add warp under rock
|
||||||
|
rom.write_byte(snes_to_pc(0x1BC5B1), 0x00) # remove secret portal
|
||||||
if (world.mode[player] == 'inverted') != (0x35 in world.owswaps[player][0] and world.owMixed[player]):
|
if (world.mode[player] == 'inverted') != (0x35 in world.owswaps[player][0] and world.owMixed[player]):
|
||||||
rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock
|
rom.write_bytes(snes_to_pc(0x1BC85A), [0x50, 0x0F, 0x82]) # add warp under rock
|
||||||
|
rom.write_byte(snes_to_pc(0x1BC5C7), 0x00) # remove secret portal
|
||||||
|
|
||||||
# apply inverted map changes
|
# apply inverted map changes
|
||||||
for b in range(0x00, len(inverted_buffer)):
|
for b in range(0x00, len(inverted_buffer)):
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ def set_rules(world, player):
|
|||||||
ow_bunny_rules(world, player)
|
ow_bunny_rules(world, player)
|
||||||
|
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard':
|
||||||
|
if world.get_region('Big Bomb Shop', player).entrances: # just some location that is placed late in the ER algorithm, prevent standard rules from applying when trying to search reachability in the overworld
|
||||||
standard_rules(world, player)
|
standard_rules(world, player)
|
||||||
elif world.mode[player] == 'open' or world.mode[player] == 'inverted':
|
elif world.mode[player] == 'open' or world.mode[player] == 'inverted':
|
||||||
open_rules(world, player)
|
open_rules(world, player)
|
||||||
@@ -106,6 +107,7 @@ def mirrorless_path_to_castle_courtyard(world, player):
|
|||||||
queue = collections.deque([(start.connected_region, [])])
|
queue = collections.deque([(start.connected_region, [])])
|
||||||
while queue:
|
while queue:
|
||||||
(current, path) = queue.popleft()
|
(current, path) = queue.popleft()
|
||||||
|
if current:
|
||||||
for entrance in current.exits:
|
for entrance in current.exits:
|
||||||
if entrance.connected_region not in seen:
|
if entrance.connected_region not in seen:
|
||||||
new_path = path + [entrance.access_rule]
|
new_path = path + [entrance.access_rule]
|
||||||
@@ -340,7 +342,11 @@ def global_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Mire Lobby Gap', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player))
|
set_rule(world.get_entrance('Mire Lobby Gap', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Mire Post-Gap Gap', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player))
|
set_rule(world.get_entrance('Mire Post-Gap Gap', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Mire Falling Bridge WN', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player)) # this is due to the fact the the door opposite is blocked
|
set_rule(world.get_entrance('Mire Falling Bridge WN', player), lambda state: state.has_Boots(player) or state.has('Hookshot', player)) # this is due to the fact the the door opposite is blocked
|
||||||
set_rule(world.get_entrance('Mire 2 NE', player), lambda state: state.has_sword(player) or state.has('Fire Rod', player) or state.has('Ice Rod', player) or state.has('Hammer', player) or state.has('Cane of Somaria', player) or state.can_shoot_arrows(player)) # need to defeat wizzrobes, bombs don't work ...
|
set_rule(world.get_entrance('Mire 2 NE', player), lambda state: state.has_sword(player) or
|
||||||
|
(state.has('Fire Rod', player) and (state.can_use_bombs(player) or state.can_extend_magic(player, 9))) or # 9 fr shots or 8 with some bombs
|
||||||
|
(state.has('Ice Rod', player) and state.can_use_bombs(player)) or # freeze popo and throw, bomb to finish
|
||||||
|
state.has('Hammer', player) or state.has('Cane of Somaria', player) or state.can_shoot_arrows(player)) # need to defeat wizzrobes, bombs don't work ...
|
||||||
|
# byrna could work with sufficient magic
|
||||||
set_rule(world.get_location('Misery Mire - Spike Chest', player), lambda state: (state.world.can_take_damage and state.has_hearts(player, 4)) or state.has('Cane of Byrna', player) or state.has('Cape', player))
|
set_rule(world.get_location('Misery Mire - Spike Chest', player), lambda state: (state.world.can_take_damage and state.has_hearts(player, 4)) or state.has('Cane of Byrna', player) or state.has('Cape', player))
|
||||||
set_rule(world.get_entrance('Mire Left Bridge Hook Path', player), lambda state: state.has('Hookshot', player))
|
set_rule(world.get_entrance('Mire Left Bridge Hook Path', player), lambda state: state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Mire Tile Room NW', player), lambda state: state.has_fire_source(player))
|
set_rule(world.get_entrance('Mire Tile Room NW', player), lambda state: state.has_fire_source(player))
|
||||||
@@ -759,6 +765,7 @@ def default_rules(world, player):
|
|||||||
set_rule(world.get_entrance('Hyrule Castle Inner East Rock', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('Hyrule Castle Inner East Rock', player), lambda state: state.can_lift_rocks(player))
|
||||||
set_rule(world.get_entrance('Hyrule Castle Outer East Rock', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('Hyrule Castle Outer East Rock', player), lambda state: state.can_lift_rocks(player))
|
||||||
set_rule(world.get_entrance('Bat Cave Ledge Peg', player), lambda state: state.has('Hammer', player))
|
set_rule(world.get_entrance('Bat Cave Ledge Peg', player), lambda state: state.has('Hammer', player))
|
||||||
|
set_rule(world.get_entrance('Bat Cave Ledge Peg (East)', player), lambda state: state.has('Hammer', player))
|
||||||
set_rule(world.get_entrance('Desert Palace Statue Move', player), lambda state: state.has('Book of Mudora', player))
|
set_rule(world.get_entrance('Desert Palace Statue Move', player), lambda state: state.has('Book of Mudora', player))
|
||||||
set_rule(world.get_entrance('Desert Ledge Outer Rocks', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('Desert Ledge Outer Rocks', player), lambda state: state.can_lift_rocks(player))
|
||||||
set_rule(world.get_entrance('Desert Ledge Inner Rocks', player), lambda state: state.can_lift_rocks(player))
|
set_rule(world.get_entrance('Desert Ledge Inner Rocks', player), lambda state: state.can_lift_rocks(player))
|
||||||
@@ -841,7 +848,7 @@ def ow_rules(world, player):
|
|||||||
if world.mode[player] != 'inverted':
|
if world.mode[player] != 'inverted':
|
||||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player) or state.has('Beat Agahnim 1', player)) # barrier gets removed after killing agahnim, relevant for entrance shuffle
|
||||||
set_rule(world.get_entrance('GT Entry Approach', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player))
|
set_rule(world.get_entrance('GT Entry Approach', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player))
|
||||||
set_rule(world.get_entrance('GT Entry Leave', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player) or state.world.shuffle[player] in ('restricted', 'full', 'crossed', 'insanity'))
|
set_rule(world.get_entrance('GT Entry Leave', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player) or state.world.shuffle[player] in ('restricted', 'full', 'lite', 'lean', 'crossed', 'insanity'))
|
||||||
else:
|
else:
|
||||||
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player))
|
set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player))
|
||||||
|
|
||||||
@@ -1001,6 +1008,7 @@ def ow_rules(world, player):
|
|||||||
set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('HC Ledge Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('HC Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('HC Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('HC East Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('HC East Entry Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
|
set_rule(world.get_entrance('HC Courtyard Left Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('HC Area South Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('HC Area South Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player))
|
set_rule(world.get_entrance('Top of Pyramid', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||||
set_rule(world.get_entrance('Top of Pyramid (Inner)', player), lambda state: state.has('Beat Agahnim 1', player))
|
set_rule(world.get_entrance('Top of Pyramid (Inner)', player), lambda state: state.has('Beat Agahnim 1', player))
|
||||||
@@ -1009,7 +1017,6 @@ def ow_rules(world, player):
|
|||||||
add_rule(world.get_entrance('Pyramid Hole', player), lambda state: False)
|
add_rule(world.get_entrance('Pyramid Hole', player), lambda state: False)
|
||||||
set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False)
|
set_rule(world.get_entrance('Pyramid Entrance', player), lambda state: False)
|
||||||
|
|
||||||
set_rule(world.get_entrance('Pyramid Exit Ledge Drop', player), lambda state: state.has('Hammer', player))
|
|
||||||
set_rule(world.get_entrance('Pyramid Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Pyramid Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Pyramid Pass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Pyramid Pass Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
set_rule(world.get_entrance('Pyramid Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player))
|
set_rule(world.get_entrance('Pyramid Courtyard Mirror Spot', player), lambda state: state.has_Mirror(player))
|
||||||
@@ -1246,6 +1253,7 @@ def ow_bunny_rules(world, player):
|
|||||||
add_bunny_rule(world.get_entrance('Wooden Bridge Bush (North)', player), player)
|
add_bunny_rule(world.get_entrance('Wooden Bridge Bush (North)', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Wooden Bridge Bush (South)', player), player)
|
add_bunny_rule(world.get_entrance('Wooden Bridge Bush (South)', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Bat Cave Ledge Peg', player), player)
|
add_bunny_rule(world.get_entrance('Bat Cave Ledge Peg', player), player)
|
||||||
|
add_bunny_rule(world.get_entrance('Bat Cave Ledge Peg (East)', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Desert Ledge Outer Rocks', player), player)
|
add_bunny_rule(world.get_entrance('Desert Ledge Outer Rocks', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Desert Ledge Inner Rocks', player), player)
|
add_bunny_rule(world.get_entrance('Desert Ledge Inner Rocks', player), player)
|
||||||
add_bunny_rule(world.get_entrance('Flute Boy Bush (North)', player), player)
|
add_bunny_rule(world.get_entrance('Flute Boy Bush (North)', player), player)
|
||||||
@@ -1339,6 +1347,7 @@ def no_glitches_rules(world, player):
|
|||||||
# add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player))
|
# add_rule(world.get_location(location, player), lambda state: state.has('Hookshot', player))
|
||||||
set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False) # no glitches does not require block override
|
set_rule(world.get_entrance('Paradox Cave Push Block Reverse', player), lambda state: False) # no glitches does not require block override
|
||||||
forbid_bomb_jump_requirements(world, player)
|
forbid_bomb_jump_requirements(world, player)
|
||||||
|
if world.get_region('Big Bomb Shop', player).entrances: # just some location that is placed late in the ER algorithm, prevent underworld rules from applying when trying to search reachability in the overworld
|
||||||
add_conditional_lamps(world, player)
|
add_conditional_lamps(world, player)
|
||||||
|
|
||||||
|
|
||||||
@@ -1860,7 +1869,7 @@ def set_big_bomb_rules(world, player):
|
|||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)))
|
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.has('Flippers', player) or state.can_flute(player)))
|
||||||
|
|
||||||
#TODO: Fix red bomb rules, artifically adding a bunch of rules to help reduce unbeatable seeds in OW shuffle
|
#TODO: Fix red bomb rules, artifically adding a bunch of rules to help reduce unbeatable seeds in OW shuffle
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False)
|
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False)
|
||||||
#add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Pyramid Area', 'Region', player))
|
#add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: state.can_reach('Pyramid Area', 'Region', player))
|
||||||
#add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has('Flippers', player) and state.can_flute(player) and state.has('Hammer', player) and state.has('Hookshot', player) and state.has_Pearl(player) and state.has_Mirror(player)))
|
#add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: (state.can_lift_heavy_rocks(player) and state.has('Flippers', player) and state.can_flute(player) and state.has('Hammer', player) and state.has('Hookshot', player) and state.has_Pearl(player) and state.has_Mirror(player)))
|
||||||
|
|
||||||
@@ -2057,8 +2066,8 @@ def set_inverted_big_bomb_rules(world, player):
|
|||||||
else:
|
else:
|
||||||
raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name)
|
raise Exception('No logic found for routing from %s to the pyramid.' % bombshop_entrance.name)
|
||||||
|
|
||||||
if world.owShuffle[player] != 'vanilla' or world.owMixed[player] or world.owCrossed[player] != 'none':
|
if world.owShuffle[player] != 'vanilla' or world.owMixed[player] or world.owCrossed[player] not in ['none', 'polar']:
|
||||||
add_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False) #temp disable progression until routing to Pyramid get be guaranteed
|
set_rule(world.get_entrance('Pyramid Fairy', player), lambda state: False) #temp disable progression until routing to Pyramid get be guaranteed
|
||||||
|
|
||||||
|
|
||||||
def set_bunny_rules(world, player, inverted):
|
def set_bunny_rules(world, player, inverted):
|
||||||
@@ -2197,7 +2206,7 @@ def set_bunny_rules(world, player, inverted):
|
|||||||
|
|
||||||
for ent_name in bunny_impassible_doors:
|
for ent_name in bunny_impassible_doors:
|
||||||
bunny_exit = world.get_entrance(ent_name, player)
|
bunny_exit = world.get_entrance(ent_name, player)
|
||||||
if is_bunny(bunny_exit.parent_region):
|
if bunny_exit.connected_region and is_bunny(bunny_exit.parent_region):
|
||||||
add_rule(bunny_exit, get_rule_to_add(bunny_exit.parent_region))
|
add_rule(bunny_exit, get_rule_to_add(bunny_exit.parent_region))
|
||||||
|
|
||||||
doors_to_check = [x for x in world.doors if x.player == player and x not in bunny_impassible_doors]
|
doors_to_check = [x for x in world.doors if x.player == player and x not in bunny_impassible_doors]
|
||||||
@@ -2334,7 +2343,11 @@ def add_key_logic_rules(world, player):
|
|||||||
key_logic = world.key_logic[player]
|
key_logic = world.key_logic[player]
|
||||||
for d_name, d_logic in key_logic.items():
|
for d_name, d_logic in key_logic.items():
|
||||||
for door_name, rule in d_logic.door_rules.items():
|
for door_name, rule in d_logic.door_rules.items():
|
||||||
add_rule(world.get_entrance(door_name, player), eval_small_key_door(door_name, d_name, player))
|
door_entrance = world.get_entrance(door_name, player)
|
||||||
|
add_rule(door_entrance, eval_small_key_door(door_name, d_name, player))
|
||||||
|
if door_entrance.door.dependents:
|
||||||
|
for dep in door_entrance.door.dependents:
|
||||||
|
add_rule(dep.entrance, eval_small_key_door(door_name, d_name, player))
|
||||||
for location in d_logic.bk_restricted:
|
for location in d_logic.bk_restricted:
|
||||||
if not location.forced_item:
|
if not location.forced_item:
|
||||||
forbid_item(location, d_logic.bk_name, player)
|
forbid_item(location, d_logic.bk_name, player)
|
||||||
|
|||||||
@@ -125,6 +125,11 @@ org $07a955 ; <- Bank07.asm : around 6564 (JP is a bit different) (STZ $05FC : S
|
|||||||
jsl BlockEraseFix
|
jsl BlockEraseFix
|
||||||
nop #2
|
nop #2
|
||||||
|
|
||||||
|
org $02A0A8
|
||||||
|
Mirror_SaveRoomData:
|
||||||
|
org $07A95B ; < bank_07.asm ; #_07A95B: JSL Mirror_SaveRoomData
|
||||||
|
jsl EGFixOnMirror
|
||||||
|
|
||||||
org $02b82a
|
org $02b82a
|
||||||
jsl FixShopCode
|
jsl FixShopCode
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -73,8 +73,9 @@ TrapDoorFixer:
|
|||||||
rts
|
rts
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
lda.l DRFlags : and #$10 : beq +
|
||||||
stz $047a
|
stz $047a
|
||||||
inc $11
|
+ inc $11
|
||||||
lda $ef
|
lda $ef
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ MirrorCheckOverride:
|
|||||||
rtl
|
rtl
|
||||||
+ lda.l DRScroll : rtl
|
+ lda.l DRScroll : rtl
|
||||||
|
|
||||||
|
EGFixOnMirror:
|
||||||
|
lda.l DRFlags : and #$10 : beq +
|
||||||
|
stz $047a
|
||||||
|
+ jsl Mirror_SaveRoomData
|
||||||
|
rtl
|
||||||
|
|
||||||
BlockEraseFix:
|
BlockEraseFix:
|
||||||
lda $7ef353 : and #$02 : beq +
|
lda $7ef353 : and #$02 : beq +
|
||||||
stz $05fc : stz $05fd
|
stz $05fc : stz $05fd
|
||||||
|
|||||||
Binary file not shown.
@@ -46,8 +46,15 @@
|
|||||||
simple: 2
|
simple: 2
|
||||||
restricted: 2
|
restricted: 2
|
||||||
full: 2
|
full: 2
|
||||||
|
lite: 2
|
||||||
crossed: 3
|
crossed: 3
|
||||||
insanity: 1
|
insanity: 1
|
||||||
|
shufflelinks:
|
||||||
|
on: 1
|
||||||
|
off: 1
|
||||||
|
shuffleganon:
|
||||||
|
on: 1
|
||||||
|
off: 1
|
||||||
world_state:
|
world_state:
|
||||||
standard: 1
|
standard: 1
|
||||||
open: 1
|
open: 1
|
||||||
@@ -81,6 +88,7 @@
|
|||||||
off: 1
|
off: 1
|
||||||
glitches_required:
|
glitches_required:
|
||||||
none: 1
|
none: 1
|
||||||
|
owg: 0
|
||||||
no_logic: 0
|
no_logic: 0
|
||||||
accessibility:
|
accessibility:
|
||||||
items: 1
|
items: 1
|
||||||
|
|||||||
@@ -146,6 +146,8 @@
|
|||||||
"simple",
|
"simple",
|
||||||
"restricted",
|
"restricted",
|
||||||
"full",
|
"full",
|
||||||
|
"lite",
|
||||||
|
"lean",
|
||||||
"crossed",
|
"crossed",
|
||||||
"insanity",
|
"insanity",
|
||||||
"dungeonsfull",
|
"dungeonsfull",
|
||||||
|
|||||||
@@ -173,14 +173,18 @@
|
|||||||
],
|
],
|
||||||
"shuffle": [
|
"shuffle": [
|
||||||
"Select Entrance Shuffling Algorithm. (default: %(default)s)",
|
"Select Entrance Shuffling Algorithm. (default: %(default)s)",
|
||||||
"Full: Mix cave and dungeon entrances freely while limiting",
|
|
||||||
" multi-entrance caves to one world.",
|
|
||||||
"Simple: Shuffle Dungeon Entrances/Exits between each other",
|
"Simple: Shuffle Dungeon Entrances/Exits between each other",
|
||||||
" and keep all 4-entrance dungeons confined to one",
|
" and keep all 4-entrance dungeons confined to one",
|
||||||
" location. All caves outside of death mountain are",
|
" location. All caves outside of death mountain are",
|
||||||
" shuffled in pairs and matched by original type.",
|
" shuffled in pairs and matched by original type.",
|
||||||
"Restricted: Use Dungeons shuffling from Simple but freely",
|
"Restricted: Use Dungeons shuffling from Simple but freely",
|
||||||
" connect remaining entrances.",
|
" connect remaining entrances.",
|
||||||
|
"Full: Mix cave and dungeon entrances freely while limiting",
|
||||||
|
" multi-entrance caves to one world.",
|
||||||
|
"Lite: Entrances are put into separate pools based on their",
|
||||||
|
" vanilla location. Dungeons, dropdowns, connector caves,",
|
||||||
|
" and locations that have an item are shuffled from",
|
||||||
|
" individual pools. Non-item locations remain vanilla.",
|
||||||
"Crossed: Mix cave and dungeon entrances freely while allowing",
|
"Crossed: Mix cave and dungeon entrances freely while allowing",
|
||||||
" caves to cross between worlds.",
|
" caves to cross between worlds.",
|
||||||
"Insanity: Decouple entrances and exits from each other and",
|
"Insanity: Decouple entrances and exits from each other and",
|
||||||
|
|||||||
@@ -140,6 +140,8 @@
|
|||||||
"randomizer.entrance.entranceshuffle.simple": "Simple",
|
"randomizer.entrance.entranceshuffle.simple": "Simple",
|
||||||
"randomizer.entrance.entranceshuffle.restricted": "Restricted",
|
"randomizer.entrance.entranceshuffle.restricted": "Restricted",
|
||||||
"randomizer.entrance.entranceshuffle.full": "Full",
|
"randomizer.entrance.entranceshuffle.full": "Full",
|
||||||
|
"randomizer.entrance.entranceshuffle.lite": "Lite",
|
||||||
|
"randomizer.entrance.entranceshuffle.lean": "Lean",
|
||||||
"randomizer.entrance.entranceshuffle.crossed": "Crossed",
|
"randomizer.entrance.entranceshuffle.crossed": "Crossed",
|
||||||
"randomizer.entrance.entranceshuffle.insanity": "Insanity",
|
"randomizer.entrance.entranceshuffle.insanity": "Insanity",
|
||||||
"randomizer.entrance.entranceshuffle.restricted_legacy": "Restricted (Legacy)",
|
"randomizer.entrance.entranceshuffle.restricted_legacy": "Restricted (Legacy)",
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
"simple",
|
"simple",
|
||||||
"restricted",
|
"restricted",
|
||||||
"full",
|
"full",
|
||||||
|
"lite",
|
||||||
|
"lean",
|
||||||
"crossed",
|
"crossed",
|
||||||
"insanity",
|
"insanity",
|
||||||
"dungeonsfull",
|
"dungeonsfull",
|
||||||
|
|||||||
Reference in New Issue
Block a user