Merge branch 'OverworldShuffleDev' into OverworldShuffle

This commit is contained in:
codemann8
2021-11-09 14:57:33 -06:00
8 changed files with 168 additions and 71 deletions

View File

@@ -1618,7 +1618,7 @@ class Entrance(object):
def can_reach_thru(self, state, start_region, ignore_underworld=False, ignore_ledges=False, allow_save_quit=False): def can_reach_thru(self, state, start_region, ignore_underworld=False, ignore_ledges=False, allow_save_quit=False):
def explore_region(region, path = []): def explore_region(region, path = []):
nonlocal found nonlocal found
if region not in explored_regions or len(explored_regions[region]) > len(path): if region not in explored_regions:
explored_regions[region] = path explored_regions[region] = path
for exit in region.exits: for exit in region.exits:
if exit.connected_region and (not ignore_ledges or exit.spot_type != 'Ledge') \ if exit.connected_region and (not ignore_ledges or exit.spot_type != 'Ledge') \
@@ -1628,19 +1628,27 @@ class Entrance(object):
found = True found = True
explored_regions[self.parent_region] = path + [exit] explored_regions[self.parent_region] = path + [exit]
elif not ignore_underworld or region.type == exit.connected_region.type or exit.connected_region.type not in [RegionType.Cave, RegionType.Dungeon]: elif not ignore_underworld or region.type == exit.connected_region.type or exit.connected_region.type not in [RegionType.Cave, RegionType.Dungeon]:
explore_region(exit.connected_region, path + [exit]) exits_to_traverse.append(tuple((exit, path)))
def traverse_paths(region, start_path=[]):
explore_region(region, start_path)
while not found and len(exits_to_traverse):
exit, path = exits_to_traverse.pop(0)
explore_region(exit.connected_region, path + [exit])
if found:
self.temp_path = explored_regions[self.parent_region]
found = False found = False
explored_regions = {} explored_regions = {}
explore_region(start_region.entrances[0].parent_region) exits_to_traverse = list()
if found: traverse_paths(start_region.entrances[0].parent_region)
self.temp_path = explored_regions[self.parent_region]
elif allow_save_quit: if not found and allow_save_quit:
explored_regions = {}
exits_to_traverse = list()
world = self.parent_region.world if self.parent_region else None world = self.parent_region.world if self.parent_region else None
exit = world.get_entrance('Links House S&Q', self.player) exit = world.get_entrance('Links House S&Q', self.player)
explore_region(exit.connected_region, [exit]) traverse_paths(exit.connected_region, [exit])
if found:
self.temp_path = explored_regions[self.parent_region]
#TODO: Implement residual mirror portal placing for the previous leg, to be used for the final destination #TODO: Implement residual mirror portal placing for the previous leg, to be used for the final destination
@@ -2910,8 +2918,33 @@ class Spoiler(object):
outfile.write(f'{fairy}: {bottle}\n') outfile.write(f'{fairy}: {bottle}\n')
if self.overworlds: if self.overworlds:
# overworlds: overworld transitions;
outfile.write('\n\nOverworld:\n\n') outfile.write('\n\nOverworld:\n\n')
# overworld tile swaps
swap_output = False
for player in range(1, self.world.players + 1):
if self.world.owMixed[player]:
from OverworldShuffle import tile_swap_spoiler_table
if not swap_output:
swap_output = True
outfile.write('OW Tile Swaps:\n')
outfile.write(('' if self.world.players == 1 else str('(Player ' + str(player) + ')')).ljust(11)) # player name
s = list(map(lambda x: ' ' if x not in self.world.owswaps[player][0] else 'S', [i for i in range(0x40)]))
outfile.write((tile_swap_spoiler_table + '\n\n') % ( s[0x02], s[0x07], \
s[0x00], s[0x03], s[0x05], \
s[0x00], s[0x02],s[0x03], s[0x05], s[0x07], s[0x0a], s[0x0f], \
s[0x0a], s[0x0f],
s[0x10],s[0x11],s[0x12],s[0x13],s[0x14],s[0x15],s[0x16],s[0x17], s[0x10],s[0x11],s[0x12],s[0x13],s[0x14],s[0x15],s[0x16],s[0x17],
s[0x18], s[0x1a],s[0x1b], s[0x1d],s[0x1e], \
s[0x22], s[0x25], s[0x1a], s[0x1d], \
s[0x28],s[0x29],s[0x2a],s[0x2b],s[0x2c],s[0x2d],s[0x2e],s[0x2f], s[0x18], s[0x1b], s[0x1e], \
s[0x30], s[0x32],s[0x33],s[0x34],s[0x35], s[0x37], s[0x22], s[0x25], \
s[0x3a],s[0x3b],s[0x3c], s[0x3f], \
s[0x28],s[0x29],s[0x2a],s[0x2b],s[0x2c],s[0x2d],s[0x2e],s[0x2f], \
s[0x32],s[0x33],s[0x34], s[0x37], \
s[0x30], s[0x35],
s[0x3a],s[0x3b],s[0x3c], s[0x3f]))
# overworld transitions
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'.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: if self.entrances:

View File

@@ -1,5 +1,13 @@
# Changelog # Changelog
### 0.2.2.1
- Allow normal Link speed with Old Man following if not in his cave or WDM
- Fixed issue with Flute exits not getting placed on the correct tiles
- Hints in Lite/Lean ER no longer refer to entrances that are guaranteed vanilla
- Added Links House entrance to hint candidate list in ER when it is shuffled
- Added Tile Swaps ASCII map to Spoiler Log when Tile Swap is enabled
- Fixed issue with Whirlpool Shuffle not abiding by Polar rules
### 0.2.2.0 ### 0.2.2.0
- Delivering Big Red Bomb is now in logic - Delivering Big Red Bomb is now in logic
- Smith/Purple Chest have proper dynamic pathing to fix logical issues - Smith/Purple Chest have proper dynamic pathing to fix logical issues

View File

@@ -428,13 +428,21 @@ def link_entrances(world, player):
caves = Cave_Base + (dw_dungeons if not invFlag else lw_dungeons) caves = Cave_Base + (dw_dungeons if not invFlag else lw_dungeons)
connector_entrances = [e for e in list(zip(*default_connector_connections + default_dungeon_connections + open_default_dungeon_connections))[0] if e in (dw_entrances if not invFlag else lw_entrances)] connector_entrances = [e for e in list(zip(*default_connector_connections + default_dungeon_connections + open_default_dungeon_connections))[0] if e in (dw_entrances if not invFlag else lw_entrances)]
connect_inaccessible_regions(world, [], connector_entrances, caves, player) connect_inaccessible_regions(world, [], connector_entrances, caves, player)
if invFlag:
lw_dungeons = list(set(lw_dungeons) & set(caves))
else:
dw_dungeons = list(set(dw_dungeons) & set(caves))
caves = list(set(Cave_Base) & set(caves)) + (lw_dungeons if not invFlag else dw_dungeons) caves = list(set(Cave_Base) & set(caves)) + (lw_dungeons if not invFlag else dw_dungeons)
connector_entrances = [e for e in list(zip(*default_connector_connections + default_dungeon_connections + open_default_dungeon_connections))[0] if e in (lw_entrances if not invFlag else dw_entrances)] connector_entrances = [e for e in list(zip(*default_connector_connections + default_dungeon_connections + open_default_dungeon_connections))[0] if e in (lw_entrances if not invFlag else dw_entrances)]
connect_inaccessible_regions(world, connector_entrances, [], caves, player) connect_inaccessible_regions(world, connector_entrances, [], caves, player)
if not invFlag:
lw_dungeons = list(set(lw_dungeons) & set(caves))
else:
dw_dungeons = list(set(dw_dungeons) & set(caves))
lw_dungeons = list(set(lw_dungeons) & set(caves)) + (Old_Man_House if not invFlag else []) lw_dungeons = lw_dungeons + (Old_Man_House if not invFlag else [])
dw_dungeons = list(set(dw_dungeons) & set(caves)) + ([] if not invFlag else Old_Man_House) dw_dungeons = dw_dungeons + ([] if not invFlag else Old_Man_House)
caves = list(set(Cave_Base) & set(caves)) + DW_Mid_Dungeon_Exits caves = list(set(Cave_Base) & set(caves)) + DW_Mid_Dungeon_Exits
# place old man, has limited options # place old man, has limited options

View File

@@ -1478,7 +1478,6 @@ OWExitTypes = {
'Dark Bonk Rocks Cliff Ledge Drop', 'Dark Bonk Rocks Cliff Ledge Drop',
'Bomb Shop Cliff Ledge Drop', 'Bomb Shop Cliff Ledge Drop',
'Hammer Bridge South Cliff Ledge Drop', 'Hammer Bridge South Cliff Ledge Drop',
'Ice Lake Northeast Pier Hop',
'Ice Lake Moat Bomb Jump', 'Ice Lake Moat Bomb Jump',
'Ice Lake Area Cliff Ledge Drop', 'Ice Lake Area Cliff Ledge Drop',
'Ice Palace Island FAWT Ledge Drop', 'Ice Palace Island FAWT Ledge Drop',
@@ -1623,6 +1622,7 @@ OWExitTypes = {
'Hype Cave Landing', 'Hype Cave Landing',
'Ice Lake Northeast Water Drop', 'Ice Lake Northeast Water Drop',
'Ice Lake Northeast Pier', 'Ice Lake Northeast Pier',
'Ice Lake Northeast Pier Hop',
'Ice Lake Moat Water Entry', 'Ice Lake Moat Water Entry',
'Ice Palace Approach', 'Ice Palace Approach',
'Ice Palace Leave', 'Ice Palace Leave',

View File

@@ -3,7 +3,7 @@ from BaseClasses import OWEdge, WorldType, RegionType, Direction, Terrain, PolSl
from Regions import mark_dark_world_regions, mark_light_world_regions from Regions import mark_dark_world_regions, mark_light_world_regions
from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel from OWEdges import OWTileRegions, OWTileGroups, OWEdgeGroups, OWExitTypes, OpenStd, parallel_links, IsParallel
__version__ = '0.2.2.0-u' __version__ = '0.2.2.1-u'
def link_overworld(world, player): def link_overworld(world, player):
# setup mandatory connections # setup mandatory connections
@@ -197,16 +197,17 @@ def link_overworld(world, player):
else: else:
whirlpool_candidates = [[],[]] whirlpool_candidates = [[],[]]
for (from_owid, from_whirlpool, from_region), (to_owid, to_whirlpool, to_region) in default_whirlpool_connections: for (from_owid, from_whirlpool, from_region), (to_owid, to_whirlpool, to_region) in default_whirlpool_connections:
if world.owCrossed[player] != 'none': if world.owCrossed[player] == 'polar' and world.owMixed[player] and from_owid == 0x55:
whirlpool_candidates[0].append(tuple((from_owid, from_whirlpool, from_region))) # connect the 2 DW whirlpools in Polar Mixed
whirlpool_candidates[0].append(tuple((to_owid, to_whirlpool, to_region))) connect_simple(world, from_whirlpool, to_region, player)
connect_simple(world, to_whirlpool, from_region, player)
else: else:
if world.get_region(from_region, player).type == RegionType.LightWorld: if world.owCrossed[player] != 'none' or world.get_region(from_region, player).type == RegionType.LightWorld:
whirlpool_candidates[0].append(tuple((from_owid, from_whirlpool, from_region))) whirlpool_candidates[0].append(tuple((from_owid, from_whirlpool, from_region)))
else: else:
whirlpool_candidates[1].append(tuple((from_owid, from_whirlpool, from_region))) whirlpool_candidates[1].append(tuple((from_owid, from_whirlpool, from_region)))
if world.get_region(to_region, player).type == RegionType.LightWorld: if world.owCrossed[player] != 'none' or world.get_region(to_region, player).type == RegionType.LightWorld:
whirlpool_candidates[0].append(tuple((to_owid, to_whirlpool, to_region))) whirlpool_candidates[0].append(tuple((to_owid, to_whirlpool, to_region)))
else: else:
whirlpool_candidates[1].append(tuple((to_owid, to_whirlpool, to_region))) whirlpool_candidates[1].append(tuple((to_owid, to_whirlpool, to_region)))
@@ -723,9 +724,7 @@ def reorganize_groups(world, groups, player):
def create_flute_exits(world, player): def create_flute_exits(world, player):
for region in (r for r in world.regions if r.player == player and r.terrain == Terrain.Land and r.name not in ['Zoras Domain', 'Master Sword Meadow', 'Hobo Bridge']): for region in (r for r in world.regions if r.player == player and r.terrain == Terrain.Land and r.name not in ['Zoras Domain', 'Master Sword Meadow', 'Hobo Bridge']):
if (not world.owMixed[player] and region.type == RegionType.LightWorld) \ if region.type == (RegionType.LightWorld if world.mode != 'inverted' else RegionType.DarkWorld):
or (world.owMixed[player] and region.type in [RegionType.LightWorld, RegionType.DarkWorld] \
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.spot_type = 'Flute'
@@ -1589,3 +1588,23 @@ flute_data = {
0x3c: (['South Pass Area', 'Dark South Pass Area'], 0x3c, 0x0584, 0x0ed0, 0x081e, 0x0f38, 0x0898, 0x0f45, 0x08a3, 0xfffe, 0x0002, 0x0f38, 0x0898), 0x3c: (['South Pass Area', 'Dark South Pass Area'], 0x3c, 0x0584, 0x0ed0, 0x081e, 0x0f38, 0x0898, 0x0f45, 0x08a3, 0xfffe, 0x0002, 0x0f38, 0x0898),
0x3f: (['Octoballoon Area', 'Bomber Corner Area'], 0x3f, 0x0810, 0x0f05, 0x0e75, 0x0f67, 0x0ef3, 0x0f72, 0x0efa, 0xfffb, 0x000b, 0x0f80, 0x0ef0) 0x3f: (['Octoballoon Area', 'Bomber Corner Area'], 0x3f, 0x0810, 0x0f05, 0x0e75, 0x0f67, 0x0ef3, 0x0f72, 0x0efa, 0xfffb, 0x000b, 0x0f80, 0x0ef0)
} }
tile_swap_spoiler_table = \
""" 0 1 2 3 4 5 6 7
+---+-+---+---+-+
01234567 A(00)| |%s| | |%s|
+--------+ | %s +-+ %s | %s +-+
A(00)|%s %s%s %s %s| B(08)| |%s| | |%s|
B(08)| %s %s| +-+-+-+-+-+-+-+-+
C(10)|%s%s%s%s%s%s%s%s| C(10)|%s|%s|%s|%s|%s|%s|%s|%s|
D(18)|%s %s%s %s%s | +-+-+-+-+-+-+-+-+
E(20)| %s %s | D(18)| |%s| |%s| |
F(28)|%s%s%s%s%s%s%s%s| | %s +-+ %s +-+ %s |
G(30)|%s %s%s%s%s %s| E(20)| |%s| |%s| |
H(38)| %s%s%s %s| +-+-+-+-+-+-+-+-+
+--------+ F(28)|%s|%s|%s|%s|%s|%s|%s|%s|
+-+-+-+-+-+-+-+-+
G(30)| |%s|%s|%s| |%s|
| %s +-+-+-+ %s +-+
H(38)| |%s|%s|%s| |%s|
+---+-+-+-+---+-+"""

101
Rom.py
View File

@@ -33,7 +33,7 @@ from source.classes.SFX import randomize_sfx
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = 'e3373be98af9d6de1cb1ab12176ecb0e' RANDOMIZERBASEHASH = '9df10796c8a8fe07d81fc0012700934a'
class JsonRom(object): class JsonRom(object):
@@ -2161,14 +2161,14 @@ def write_strings(rom, world, player, team):
else: else:
hint_count = 4 hint_count = 4
for entrance in all_entrances: for entrance in all_entrances:
if entrance.name in entrances_to_hint: if hint_count > 0:
if hint_count > 0: if entrance.name in entrances_to_hint:
this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(entrance.connected_region) + '.' this_hint = entrances_to_hint[entrance.name] + ' leads to ' + hint_text(entrance.connected_region) + '.'
tt[hint_locations.pop(0)] = this_hint tt[hint_locations.pop(0)] = this_hint
entrances_to_hint.pop(entrance.name) entrances_to_hint.pop(entrance.name)
hint_count -= 1 hint_count -= 1
else: else:
break break
#Next we handle hints for randomly selected other entrances, curating the selection intelligently based on shuffle. #Next we handle hints for randomly selected other entrances, curating the selection intelligently based on shuffle.
if world.shuffle[player] not in ['simple', 'restricted', 'restricted_legacy']: if world.shuffle[player] not in ['simple', 'restricted', 'restricted_legacy']:
@@ -2180,9 +2180,15 @@ def write_strings(rom, world, player, team):
entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'}) entrances_to_hint.update({'Agahnims Tower': 'The sealed castle door'})
elif world.shuffle[player] == 'restricted': elif world.shuffle[player] == 'restricted':
entrances_to_hint.update(ConnectorEntrances) entrances_to_hint.update(ConnectorEntrances)
entrances_to_hint.update(OtherEntrances) entrances_to_hint.update(ItemEntrances)
if world.shuffle[player] not in ['lite', 'lean']:
entrances_to_hint.update(ShopEntrances)
entrances_to_hint.update(OtherEntrances)
elif world.shopsanity[player]:
entrances_to_hint.update(ShopEntrances)
if world.shufflelinks[player] and world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull']:
entrances_to_hint.update({'Links House': 'The hero\'s old residence'})
entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'}) entrances_to_hint.update({'Dark Sanctuary Hint': 'The dark sanctuary cave'})
entrances_to_hint.update({'Big Bomb Shop': 'The old bomb shop'})
if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']: if world.shuffle[player] in ['insanity', 'madness_legacy', 'insanity_legacy']:
entrances_to_hint.update(InsanityEntrances) entrances_to_hint.update(InsanityEntrances)
if world.shuffle_ganon: if world.shuffle_ganon:
@@ -2255,16 +2261,14 @@ def write_strings(rom, world, player, team):
this_hint = location + ' contains ' + hint_text(world.get_location(location, player).item) + '.' this_hint = location + ' contains ' + hint_text(world.get_location(location, player).item) + '.'
tt[hint_locations.pop(0)] = this_hint tt[hint_locations.pop(0)] = this_hint
# Adding a guaranteed hint for the Flute in overworld shuffle. # Lastly we write hints to show where certain interesting items are. It is done the way it is to re-use the silver code and also to give one hint per each type of item regardless of how many exist. This supports many settings well.
items_to_hint = RelevantItems.copy()
if world.owShuffle[player] != 'vanilla' or world.owMixed[player]: if world.owShuffle[player] != 'vanilla' or world.owMixed[player]:
# Adding a guaranteed hint for the Flute in overworld shuffle.
this_location = world.find_items_not_key_only('Ocarina', player) this_location = world.find_items_not_key_only('Ocarina', player)
if this_location: if this_location:
this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.' this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.'
tt[hint_locations.pop(0)] = this_hint tt[hint_locations.pop(0)] = this_hint
# Lastly we write hints to show where certain interesting items are. It is done the way it is to re-use the silver code and also to give one hint per each type of item regardless of how many exist. This supports many settings well.
items_to_hint = RelevantItems.copy()
if world.owShuffle[player] != 'vanilla' or world.owMixed[player]:
items_to_hint.remove('Ocarina') items_to_hint.remove('Ocarina')
if world.keyshuffle[player]: if world.keyshuffle[player]:
items_to_hint.extend(SmallKeys) items_to_hint.extend(SmallKeys)
@@ -2273,7 +2277,7 @@ def write_strings(rom, world, player, team):
random.shuffle(items_to_hint) random.shuffle(items_to_hint)
hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 8 hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull'] else 8
hint_count += 2 if world.doorShuffle[player] == 'crossed' else 0 hint_count += 2 if world.doorShuffle[player] == 'crossed' else 0
hint_count += 1 if world.owShuffle[player] != 'vanilla' or world.owMixed[player] else 0 hint_count += 1 if world.owShuffle[player] != 'vanilla' or world.owCrossed[player] != 'none' or world.owMixed[player] else 0
while hint_count > 0: while hint_count > 0:
this_item = items_to_hint.pop(0) this_item = items_to_hint.pop(0)
this_location = world.find_items_not_key_only(this_item, player) this_location = world.find_items_not_key_only(this_item, player)
@@ -2734,16 +2738,46 @@ DungeonEntrances = {'Eastern Palace': 'Eastern Palace',
'Desert Palace Entrance (North)': 'The northmost cave in the desert' 'Desert Palace Entrance (North)': 'The northmost cave in the desert'
} }
OtherEntrances = {'Blinds Hideout': 'Blind\'s old house', ItemEntrances = {'Blinds Hideout': 'Blind\'s old house',
'Lake Hylia Fairy': 'A cave NE of Lake Hylia', 'Chicken House': 'The chicken lady\'s house',
'Aginahs Cave': 'The open desert cave',
'Sahasrahlas Hut': 'The house near armos',
'Blacksmiths Hut': 'The old smithery',
'Sick Kids House': 'The central house in Kakariko',
'Mini Moldorm Cave': 'The cave south of Lake Hylia',
'Ice Rod Cave': 'The sealed cave SE Lake Hylia',
'Library': 'The old library',
'Potion Shop': 'The witch\'s building',
'Dam': 'The old dam',
'Waterfall of Wishing': 'Going behind the waterfall',
'Bonk Rock Cave': 'The rock pile near Sanctuary',
'Graveyard Cave': 'The graveyard ledge',
'Checkerboard Cave': 'The NE desert ledge',
'Cave 45': 'The ledge south of haunted grove',
'Kings Grave': 'The northeastmost grave',
'C-Shaped House': 'The NE house in Village of Outcasts',
'Mire Shed': 'The western hut in the mire',
'Spike Cave': 'The ledge cave on west dark DM',
'Hype Cave': 'The cave south of the old bomb shop',
'Brewery': 'The Village of Outcasts building with no door',
'Chest Game': 'The westmost building in the Village of Outcasts',
'Big Bomb Shop': 'The old bomb shop'
}
ShopEntrances = {'Cave Shop (Lake Hylia)': 'The cave NW Lake Hylia',
'Kakariko Shop': 'The old Kakariko shop',
'Capacity Upgrade': 'The cave on the island',
'Dark Lake Hylia Shop': 'The building NW dark Lake Hylia',
'Dark World Shop': 'The hammer sealed building',
'Red Shield Shop': 'The fenced in building',
'Cave Shop (Dark Death Mountain)': 'The base of east dark DM',
'Dark World Potion Shop': 'The building near the catfish',
'Dark World Lumberjack Shop': 'The northmost Dark World building'
}
OtherEntrances = {'Lake Hylia Fairy': 'A cave NE of Lake Hylia',
'Light Hype Fairy': 'The cave south of your house', 'Light Hype Fairy': 'The cave south of your house',
'Desert Fairy': 'The cave near the desert', 'Desert Fairy': 'The cave near the desert',
'Chicken House': 'The chicken lady\'s house',
'Aginahs Cave': 'The open desert cave',
'Sahasrahlas Hut': 'The house near armos',
'Cave Shop (Lake Hylia)': 'The cave NW Lake Hylia',
'Blacksmiths Hut': 'The old smithery',
'Sick Kids House': 'The central house in Kakariko',
'Lost Woods Gamble': 'A tree trunk door', 'Lost Woods Gamble': 'A tree trunk door',
'Fortune Teller (Light)': 'A building NE of Kakariko', 'Fortune Teller (Light)': 'A building NE of Kakariko',
'Snitch Lady (East)': 'A house guarded by a snitch', 'Snitch Lady (East)': 'A house guarded by a snitch',
@@ -2751,49 +2785,24 @@ OtherEntrances = {'Blinds Hideout': 'Blind\'s old house',
'Bush Covered House': 'A house with an uncut lawn', 'Bush Covered House': 'A house with an uncut lawn',
'Tavern (Front)': 'A building with a backdoor', 'Tavern (Front)': 'A building with a backdoor',
'Light World Bomb Hut': 'A Kakariko building with no door', 'Light World Bomb Hut': 'A Kakariko building with no door',
'Kakariko Shop': 'The old Kakariko shop',
'Mini Moldorm Cave': 'The cave south of Lake Hylia',
'Long Fairy Cave': 'The eastmost portal cave', 'Long Fairy Cave': 'The eastmost portal cave',
'Good Bee Cave': 'The open cave SE Lake Hylia', 'Good Bee Cave': 'The open cave SE Lake Hylia',
'20 Rupee Cave': 'The rock SE Lake Hylia', '20 Rupee Cave': 'The rock SE Lake Hylia',
'50 Rupee Cave': 'The rock near the desert', '50 Rupee Cave': 'The rock near the desert',
'Ice Rod Cave': 'The sealed cave SE Lake Hylia',
'Library': 'The old library',
'Potion Shop': 'The witch\'s building',
'Dam': 'The old dam',
'Lumberjack House': 'The lumberjack house', 'Lumberjack House': 'The lumberjack house',
'Lake Hylia Fortune Teller': 'The building NW Lake Hylia', 'Lake Hylia Fortune Teller': 'The building NW Lake Hylia',
'Kakariko Gamble Game': 'The old Kakariko gambling den', 'Kakariko Gamble Game': 'The old Kakariko gambling den',
'Waterfall of Wishing': 'Going behind the waterfall',
'Capacity Upgrade': 'The cave on the island',
'Bonk Rock Cave': 'The rock pile near Sanctuary',
'Graveyard Cave': 'The graveyard ledge',
'Checkerboard Cave': 'The NE desert ledge',
'Cave 45': 'The ledge south of haunted grove',
'Kings Grave': 'The northeastmost grave',
'Bonk Fairy (Light)': 'The rock pile near your home', 'Bonk Fairy (Light)': 'The rock pile near your home',
'Hookshot Fairy': 'The left paired cave on east DM', 'Hookshot Fairy': 'The left paired cave on east DM',
'Bonk Fairy (Dark)': 'The rock pile near the old bomb shop', 'Bonk Fairy (Dark)': 'The rock pile near the old bomb shop',
'Dark Lake Hylia Fairy': 'The cave NE dark Lake Hylia', 'Dark Lake Hylia Fairy': 'The cave NE dark Lake Hylia',
'C-Shaped House': 'The NE house in Village of Outcasts',
'Dark Death Mountain Fairy': 'The SW cave on dark DM', 'Dark Death Mountain Fairy': 'The SW cave on dark DM',
'Dark Lake Hylia Shop': 'The building NW dark Lake Hylia',
'Dark World Shop': 'The hammer sealed building',
'Red Shield Shop': 'The fenced in building',
'Mire Shed': 'The western hut in the mire',
'East Dark World Hint': 'The dark cave near the eastmost portal', 'East Dark World Hint': 'The dark cave near the eastmost portal',
'Dark Desert Hint': 'The cave east of the mire', 'Dark Desert Hint': 'The cave east of the mire',
'Spike Cave': 'The ledge cave on west dark DM',
'Palace of Darkness Hint': 'The building south of Kiki', 'Palace of Darkness Hint': 'The building south of Kiki',
'Dark Lake Hylia Ledge Spike Cave': 'The rock SE dark Lake Hylia', 'Dark Lake Hylia Ledge Spike Cave': 'The rock SE dark Lake Hylia',
'Cave Shop (Dark Death Mountain)': 'The base of east dark DM',
'Dark World Potion Shop': 'The building near the catfish',
'Archery Game': 'The old archery game', 'Archery Game': 'The old archery game',
'Dark World Lumberjack Shop': 'The northmost Dark World building',
'Hype Cave': 'The cave south of the old bomb shop',
'Brewery': 'The Village of Outcasts building with no door',
'Dark Lake Hylia Ledge Hint': 'The open cave SE dark Lake Hylia', 'Dark Lake Hylia Ledge Hint': 'The open cave SE dark Lake Hylia',
'Chest Game': 'The westmost building in the Village of Outcasts',
'Dark Desert Fairy': 'The eastern hut in the mire', 'Dark Desert Fairy': 'The eastern hut in the mire',
'Dark Lake Hylia Ledge Fairy': 'The sealed cave SE dark Lake Hylia', 'Dark Lake Hylia Ledge Fairy': 'The sealed cave SE dark Lake Hylia',
'Fortune Teller (Dark)': 'The building NE the Village of Outcasts' 'Fortune Teller (Dark)': 'The building NE the Village of Outcasts'

View File

@@ -37,6 +37,10 @@ db #$b0 ; BCS to replace BEQ
org $06907f ; < 3107f - sprite_prep.asm:2170 (LDA $7EF3CA) org $06907f ; < 3107f - sprite_prep.asm:2170 (LDA $7EF3CA)
lda $8a : and.b #$40 lda $8a : and.b #$40
; override Link speed with Old Man following
org $09a32e ; < bank_09.asm:7457 (LDA.b #$0C : STA.b $5E)
jsl OWOldManSpeed
; Dark Bonk Rocks Rain Sequence Guards (allowing Tile Swap on Dark Bonk Rocks) ; Dark Bonk Rocks Rain Sequence Guards (allowing Tile Swap on Dark Bonk Rocks)
;org $09c957 ; <- 4c957 ;org $09c957 ; <- 4c957
;dw #$cb5f ; matches value on Central Bonk Rocks screen ;dw #$cb5f ; matches value on Central Bonk Rocks screen
@@ -162,6 +166,22 @@ OWSmithAccept:
clc : rtl clc : rtl
+ sec : rtl + sec : rtl
} }
OWOldManSpeed:
{
lda $1b : beq .outdoors
lda $a0 : and #$fe : cmp #$f0 : beq .vanilla ; if in cave where you find Old Man
bra .normalspeed
.outdoors
lda $8a : cmp #$03 : beq .vanilla ; if on WDM screen
.normalspeed
lda $5e : cmp #$0c : rtl
stz $5e : rtl
.vanilla
lda #$0c : sta $5e ; what we wrote over
rtl
}
org $aa9000 org $aa9000
OWEdgeTransition: OWEdgeTransition:

Binary file not shown.