diff --git a/Adjuster.py b/Adjuster.py index 68ac73ad..ba502c8a 100755 --- a/Adjuster.py +++ b/Adjuster.py @@ -47,6 +47,7 @@ def main(): Alternatively, can be a ALttP Rom patched with a Link sprite that will be extracted. ''') + parser.add_argument('--triforce_gfx', help='Name of the triforce graphics to use.') parser.add_argument('--names', default='', type=str) args = parser.parse_args() diff --git a/AdjusterMain.py b/AdjusterMain.py index 803bed24..6b886a4b 100644 --- a/AdjusterMain.py +++ b/AdjusterMain.py @@ -30,9 +30,11 @@ def adjust(args): if not hasattr(args,"sprite"): args.sprite = None + if not hasattr(args,"triforce_gfx"): + args.triforce_gfx = None apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic, - args.sprite, args.ow_palettes, args.uw_palettes, args.reduce_flashing, args.shuffle_sfx, + args.sprite, args.triforce_gfx, args.ow_palettes, args.uw_palettes, args.reduce_flashing, args.shuffle_sfx, args.shuffle_sfxinstruments, args.shuffle_songinstruments, args.msu_resume) output_path.cached_path = args.outputpath @@ -65,10 +67,12 @@ def patch(args): if not hasattr(args, "sprite"): args.sprite = None + if not hasattr(args, "triforce_gfx"): + args.triforce_gfx = None apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic, - args.sprite, args.ow_palettes, args.uw_palettes, args.reduce_flashing, args.shuffle_sfx, - args.shuffle_sfxinstruments, args.shuffle_songinstruments, args.msu_resume) + args.sprite, args.triforce_gfx, args.ow_palettes, args.uw_palettes, args.reduce_flashing, + args.shuffle_sfx, args.shuffle_sfxinstruments, args.shuffle_songinstruments, args.msu_resume) output_path.cached_path = args.outputpath rom.write_to_file(output_path('%s.sfc' % outfile_base)) diff --git a/BaseClasses.py b/BaseClasses.py index 3a0a1204..02b8a2b1 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -65,7 +65,7 @@ class World(object): self.lock_aga_door_in_escape = False self.save_and_quit_from_boss = True self.override_bomb_check = False - self.is_copied_world = False + self.is_premature_copied_world = False self.accessibility = accessibility.copy() self.fix_skullwoods_exit = {} self.fix_palaceofdarkness_exit = {} @@ -81,11 +81,11 @@ class World(object): self.can_take_damage = {} self.hints = hints.copy() self.prizes = {} + self.default_zelda_region = {} self.dynamic_regions = [] self.dynamic_locations = [] self.spoiler_mode = spoiler_mode self.spoiler = Spoiler(self) - self.lamps_needed_for_dark_rooms = 1 self.owedges = [] self._owedge_cache = {} self.owswaps = {} @@ -153,12 +153,15 @@ class World(object): set_player_attr('bombbag', False) set_player_attr('flute_mode', False) set_player_attr('bow_mode', False) + set_player_attr('free_lamp_cone', False) + set_player_attr('difficulty_requirements', None) set_player_attr('boss_shuffle', 'none') set_player_attr('enemy_shuffle', 'none') set_player_attr('enemy_health', 'default') set_player_attr('enemy_damage', 'default') set_player_attr('any_enemy_logic', 'allow_all') + set_player_attr('force_enemy', None) set_player_attr('beemizer', '0') set_player_attr('escape_assist', []) set_player_attr('crystals_needed_for_ganon', 7) @@ -197,6 +200,8 @@ class World(object): set_player_attr('standardize_palettes', 'standardize') set_player_attr('force_fix', {'gt': False, 'sw': False, 'pod': False, 'tr': False}) set_player_attr('prizes', {'dig;': [], 'pull': [0, 0, 0], 'crab': [0, 0], 'stun': 0, 'fish': 0, 'enemies': []}) + set_player_attr('default_zelda_region', 'Hyrule Dungeon Cellblock') + set_player_attr('custom_goals', {'gtentry': None, 'ganongoal': None, 'pedgoal': None, 'murahgoal': None}) set_player_attr('exp_cache', defaultdict(dict)) set_player_attr('enabled_entrances', {}) @@ -1221,16 +1226,35 @@ class CollectionState(object): def item_count(self, item, player): return self.prog_items[item, player] - def everything(self, player): - all_locations = self.world.get_filled_locations(player) - all_locations.remove(self.world.get_location('Ganon', player)) - return (len([x for x in self.locations_checked if x.player == player]) + def everything(self, player, all_except=0): + all_locations = [x for x in self.world.get_filled_locations(player) if not x.locked] + return (len([x for x in self.locations_checked if x.player == player and not x.locked]) + all_except >= len(all_locations)) def has_crystals(self, count, player): crystals = ['Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'] return len([crystal for crystal in crystals if self.has(crystal, player)]) >= count + def has_pendants(self, count, player): + pendants = ['Green Pendant', 'Red Pendant', 'Blue Pendant'] + return len([pendant for pendant in pendants if self.has(pendant, player)]) >= count + + def has_bosses(self, count, player, prize_type=None): + dungeons = 'Eastern Palace', 'Desert Palace', 'Tower of Hera', 'Palace of Darkness', 'Swamp Palace', "Thieves' Town", 'Skull Woods', 'Ice Palace', 'Misery Mire', 'Turtle Rock' + reachable_bosses = 0 + for d in dungeons: + region = self.world.get_region(f'{d} - Boss Kill', player) + if prize_type is None or prize_type in region.dungeon.prize.name: + if self.can_reach(region, None, player): + reachable_bosses += 1 + return reachable_bosses >= count + + def has_crystal_bosses(self, count, player): + return self.has_bosses(count, player, 'Crystal') + + def has_pendant_bosses(self, count, player): + return self.has_bosses(count, player, 'Pendant') + def can_lift_rocks(self, player): return self.has('Power Glove', player) or self.has('Titans Mitts', player) @@ -2728,7 +2752,7 @@ class Location(object): self.staleness_count = 0 self.locked = False self.real = True - self.always_allow = lambda item, state: False + self.always_allow = None self.access_rule = lambda state: True self.verbose_rule = None self.item_rule = lambda item: True @@ -2742,7 +2766,7 @@ class Location(object): def can_fill(self, state, item, check_access=True): if not self.valid_multiworld(state, item): return False - return self.always_allow(state, item) or (self.parent_region.can_fill(item) and self.item_rule(item) and (not check_access or self.can_reach(state))) + return (self.always_allow and self.always_allow(state, item)) or (self.parent_region.can_fill(item) and self.item_rule(item) and (not check_access or self.can_reach(state))) def valid_multiworld(self, state, item): if self.type == LocationType.Pot and self.player != item.player: @@ -3061,6 +3085,7 @@ class Spoiler(object): 'flute_mode': self.world.flute_mode, 'bow_mode': self.world.bow_mode, 'goal': self.world.goal, + 'custom_goals': self.world.custom_goals, 'ow_shuffle': self.world.owShuffle, 'ow_terrain': self.world.owTerrain, 'ow_crossed': self.world.owCrossed, @@ -3302,8 +3327,23 @@ class Spoiler(object): if self.metadata['goal'][player] in ['triforcehunt', 'trinity', 'ganonhunt']: 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('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])) + custom = self.metadata['custom_goals'][player] + if custom['gtentry'] and 'requirements' in custom['gtentry']: + outfile.write('GT Entry Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['gtentry']['goaltext']) + else: + outfile.write('GT Entry Requirement:'.ljust(line_width) + '%s crystals\n' % str(self.world.crystals_gt_orig[player])) + if custom['ganongoal'] and 'requirements' in custom['ganongoal']: + outfile.write('Ganon Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['ganongoal']['goaltext']) + else: + outfile.write('Ganon Requirement:'.ljust(line_width) + '%s crystals\n' % str(self.world.crystals_ganon_orig[player])) + if custom['pedgoal'] and 'requirements' in custom['pedgoal']: + outfile.write('Pedestal Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['pedgoal']['goaltext']) + if custom['murahgoal'] and 'requirements' in custom['murahgoal']: + outfile.write('Murahdahla Requirement:'.ljust(line_width) + 'custom\n') + outfile.write(' %s\n' % custom['murahgoal']['goaltext']) outfile.write('Item Required for Ganon:'.ljust(line_width) + '%s\n' % str(self.world.ganon_item_orig[player])) outfile.write('Swords:'.ljust(line_width) + '%s\n' % self.metadata['weapons'][player]) outfile.write('\n') @@ -3419,10 +3459,24 @@ class Spoiler(object): outfile.write(f'{dungeon}:'.ljust(line_width) + '%s Medallion\n' % medallion) for player in range(1, self.world.players + 1): player_name = '' if self.world.players == 1 else str(' (Player ' + str(player) + ')') - if self.world.crystals_gt_orig[player] == 'random': + goal = self.world.custom_goals[player]['gtentry'] + if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: + pass + # outfile.write(str('GT Entry Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) + elif self.world.crystals_gt_orig[player] == 'random': outfile.write(str('Crystals Required for GT' + player_name + ':').ljust(line_width) + '%s\n' % (str(self.metadata['gt_crystals'][player]))) - if self.world.crystals_ganon_orig[player] == 'random': - outfile.write(str('Crystals Required for Ganon' + player_name + ':').ljust(line_width) + '%s\n' % (str(self.metadata['ganon_crystals'][player]))) + goal = self.world.custom_goals[player]['ganongoal'] + if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: + pass + # outfile.write(str('Ganon Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) + elif self.world.crystals_ganon_orig[player] == 'random': + outfile.write(str('Crystals Required for Ganon' + player_name + ':').ljust(line_width) + '%s\n' % (str(self.metadata['ganon_crystals'][player]))) + # goal = self.world.custom_goals[player]['pedgoal'] + # if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: + # outfile.write(str('Pedestal Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) + # goal = self.world.custom_goals[player]['murahgoal'] + # if goal and 'requirements' in goal and goal['requirements'][0]['condition'] != 0x00: + # outfile.write(str('Murahdahla Sign Text' + player_name + ':').ljust(line_width) + '%s\n' % goal['goaltext']) outfile.write('\n\nPrizes:\n\n') for dungeon, prize in self.prizes.items(): outfile.write(str(dungeon + ':').ljust(line_width) + '%s\n' % prize) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28128e2b..277596e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,63 @@ # Changelog +## 0.6.1.7 +- \~Merged in DR v1.5.2~ + - Reverted key count update + +## 0.6.1.6 +- Fixed bonk drop sparkles in DW +- \~Merged in DR v1.5.1~ + - Fixed key count issues + +## 0.6.1.5 +- Fixed error with non-prize shuffle + +## 0.6.1.4 +- Fixes for Glitched Rain State (Bonk Shuffle included) +- \~Merged in DR v1.5.0~ + - GT Key Logic fix + - New HUD key count behavior + - Pot uncoloring on collection + +## 0.6.1.3 +- Added new post-gen option to change Triforce Piece GFX +- Added new GFX for 10/11 keys to replace the A/B GFX +- Fixed issue with Follower Sprite GFX after mirroring +- Fixed VRAM issue with Crystal Maiden cutscene +- Some performance updates +- \~Merged in DR v1.4.11~ + - Enemizer bans update + +## 0.6.1.2 +- Various fixes for Custom Goal Framework +- Added custom gfx for Pedestal and Murahdahla +- Re-fixed purple chest follower dupe +- Updated tournament winners texts + +## 0.6.1.1 +- Fixed issue with Bosses goals in Custom Goal Framework +- Fixed error when using Custom Goals with no extra values +- Added more Custom Goal detail in Spoiler Log + +## 0.6.1.0 +- New Custom Goal framework (see Customizer.md) +- New 'logic' hint terminology to replace vital/useful terminology +- Removed possibility of duplicated hints +- New fix for hammering pot drops when at sprite limit +- Fixed issue with incorrect Ganon silvers hint +- Fixed issue with Locksmith despawning after purple chest if a follower is stored +- Fixed pogdor glitch (frogdor but at PoD entrance and Kiki following) +- Fixed issue with Duck gfx overwriting GT Cutscene gfx +- New CLI argument to allow external generators to supply a custom ROM Header +- Fixed error with extra argument in MultiServer call +- Added new text if Link's House is placed at any Snitch Lady house + +## 0.6.0.8 +- Re-fixed issue with Old Man spawning on pyramid +- Allowing Zelda to be in TT Prison for follower shuffle escape +- Fixed error with placing Old Man Cave in ER +- Fixed error when plando'ing followers at locations + ## 0.6.0.7 - Emergency fix for GT cutscene GFX diff --git a/CLI.py b/CLI.py index 4bedd4fd..5db1fc78 100644 --- a/CLI.py +++ b/CLI.py @@ -141,7 +141,7 @@ def parse_cli(argv, no_defaults=False): 'skullwoods', 'linked_drops', 'pseudoboots', 'mirrorscroll', 'dark_rooms', 'damage_challenge', 'shuffle_damage_table', 'crystal_book', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', - 'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', + 'ow_palettes', 'uw_palettes', 'sprite', 'triforce_gfx', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep', 'remote_items', 'shopsanity', 'dropshuffle', 'pottery', 'keydropshuffle', 'mixed_travel', 'standardize_palettes', 'code', 'reduce_flashing', 'shuffle_sfx', 'shuffle_sfxinstruments', 'shuffle_songinstruments', 'msu_resume', 'collection_rate', 'colorizepots', 'decoupledoors', 'door_type_mode', @@ -269,6 +269,7 @@ def parse_settings(): "heartcolor": "red", "heartbeep": "normal", "sprite": None, + "triforce_gfx": None, "fastmenu": "normal", "ow_palettes": "default", "uw_palettes": "default", diff --git a/DoorShuffle.py b/DoorShuffle.py index 65f33a7a..3ba2584f 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -291,7 +291,12 @@ def vanilla_key_logic(world, player): create_alternative_door_rules('Mire Map Spike Side Blue Barrier', 2, 'Misery Mire', world, player) create_alternative_door_rules('Mire Crystal Dead End Left Barrier', 2, 'Misery Mire', world, player) create_alternative_door_rules('Mire Crystal Dead End Right Barrier', 2, 'Misery Mire', world, player) - # gt logic? I'm unsure it needs adjusting + # gt logic + conveyor_star_pits_door = world.key_logic[player]['Ganons Tower'].door_rules['GT Conveyor Star Pits EN'] + firesnake_door = world.key_logic[player]['Ganons Tower'].door_rules['GT Firesnake Room SW'] + firesnake_door.alternate_big_key_loc.update(conveyor_star_pits_door.alternate_big_key_loc) + tile_door = world.key_logic[player]['Ganons Tower'].door_rules['GT Tile Room EN'] + tile_door.alternate_big_key_loc.update(conveyor_star_pits_door.alternate_big_key_loc) def create_alternative_door_rules(door, amount, dungeon, world, player): diff --git a/Doors.py b/Doors.py index aa55cf0c..909fe40b 100644 --- a/Doors.py +++ b/Doors.py @@ -1302,8 +1302,12 @@ def create_doors(world, player): world.get_door('Swamp Flooded Room Ladder', player).event('Swamp Drain') if world.mode[player] == 'standard' and 'Zelda Herself' not in [i.name for i in world.precollected_items if i.player == player]: - world.get_door('Hyrule Castle Throne Room Tapestry', player).event('Zelda Pickup') - world.get_door('Hyrule Castle Tapestry Backwards', player).event('Zelda Pickup') + if world.default_zelda_region[player] == 'Thieves Blind\'s Cell': + zelda_location = 'Suspicious Maiden' + else: + zelda_location = 'Zelda Pickup' + world.get_door('Hyrule Castle Throne Room Tapestry', player).event(zelda_location) + world.get_door('Hyrule Castle Tapestry Backwards', player).event(zelda_location) # crystal switches and barriers world.get_door('Hera Lobby Crystal Exit', player).c_switch() diff --git a/DungeonGenerator.py b/DungeonGenerator.py index d3e33bb8..3306b71d 100644 --- a/DungeonGenerator.py +++ b/DungeonGenerator.py @@ -586,13 +586,13 @@ def determine_paths_for_dungeon(world, player, all_regions, name): paths.append(portal.door.entrance.parent_region.name) if world.mode[player] == 'standard': if name == 'Hyrule Castle': - paths.append('Hyrule Dungeon Cellblock') - paths.append(('Hyrule Dungeon Cellblock', 'Sanctuary')) + paths.append(world.default_zelda_region[player]) + paths.append((world.default_zelda_region[player], 'Sanctuary')) if name == 'Hyrule Castle Sewers': paths.append('Sanctuary') if name == 'Hyrule Castle Dungeon': - paths.append('Hyrule Dungeon Cellblock') - paths.append(('Hyrule Dungeon Cellblock', 'Hyrule Castle Throne Room')) + paths.append(world.default_zelda_region[player]) + paths.append((world.default_zelda_region[player], 'Hyrule Castle Throne Room')) if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town': paths.append('Thieves Attic Window') elif 'Thieves Attic Window' in all_r_names: @@ -1322,7 +1322,7 @@ def create_dungeon_builders(all_sectors, connections_tuple, world, player, dunge for r_name in dungeon_boss_sectors[key]: assign_sector(find_sector(r_name, candidate_sectors), current_dungeon, candidate_sectors, global_pole) if key == 'Hyrule Castle' and world.mode[player] == 'standard': - for r_name in ['Hyrule Dungeon Cellblock', 'Sanctuary', 'Hyrule Castle Throne Room']: # need to deliver zelda + for r_name in [world.default_zelda_region[player], 'Sanctuary', 'Hyrule Castle Throne Room']: # need to deliver zelda assign_sector(find_sector(r_name, candidate_sectors), current_dungeon, candidate_sectors, global_pole) if key == 'Thieves Town' and (world.get_dungeon("Thieves Town", player).boss.enemizer_name == 'Blind' @@ -3091,7 +3091,7 @@ def split_dungeon_builder(builder, split_list, builder_info): if builder.name == 'Hyrule Castle': assign_sector(find_sector('Hyrule Castle Throne Room', candidate_sectors), dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole) - assign_sector(find_sector('Hyrule Dungeon Cellblock', candidate_sectors), + assign_sector(find_sector(world.default_zelda_region[player], candidate_sectors), dungeon_map['Hyrule Castle Dungeon'], candidate_sectors, global_pole) dungeon_map['Hyrule Castle Dungeon'].throne_door = world.get_door('Hyrule Castle Throne Room N', player) dungeon_map['Hyrule Castle Sewers'].sewers_access = builder.throne_door diff --git a/Fill.py b/Fill.py index b6b793db..c47a2f3d 100644 --- a/Fill.py +++ b/Fill.py @@ -183,6 +183,8 @@ def fill_restrictive(world, base_state, locations, itempool, key_pool=None, sing spot_to_fill = None item_locations = filter_locations(item_to_place, locations, world, vanilla) + if is_dungeon_item(item_to_place, world) and not (item_to_place.prize and world.prizeshuffle[item_to_place.player] == 'none'): + item_locations = [l for l in item_locations if valid_dungeon_placement(item_to_place, l, world)] verify(item_to_place, item_locations, maximum_exploration_state, single_player_placement, perform_access_check, key_pool, world) for location in item_locations: diff --git a/ItemList.py b/ItemList.py index 693fa96d..2ddc0d8f 100644 --- a/ItemList.py +++ b/ItemList.py @@ -231,12 +231,18 @@ def generate_itempool(world, player): if world.damage_challenge[player] in ['ohko', 'gloom']: world.can_take_damage[player] = False - if world.goal[player] in ['pedestal', 'triforcehunt', 'sanctuary']: + goal_req = None + if world.custom_goals[player]['ganongoal'] and 'requirements' in world.custom_goals[player]['ganongoal']: + goal_req = world.custom_goals[player]['ganongoal']['requirements'][0] + if world.goal[player] in ['pedestal', 'triforcehunt', 'sanctuary'] or (goal_req and goal_req['condition'] == 0x00): set_event_item(world, player, 'Ganon', 'Nothing') else: set_event_item(world, player, 'Ganon', 'Triforce') - if world.goal[player] in ['triforcehunt', 'trinity']: + goal_req = None + if world.custom_goals[player]['murahgoal'] and 'requirements' in world.custom_goals[player]['murahgoal']: + goal_req = world.custom_goals[player]['murahgoal']['requirements'][0] + if world.goal[player] in ['triforcehunt', 'trinity'] or (goal_req and goal_req['condition'] != 0x00): region = world.get_region('Hyrule Castle Courtyard', player) loc = Location(player, "Murahdahla", parent=region) region.locations.append(loc) @@ -278,13 +284,13 @@ def generate_itempool(world, player): # set up item pool skip_pool_adjustments = False if world.customizer and world.customizer.get_item_pool() and player in world.customizer.get_item_pool(): - (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = make_customizer_pool(world, player) + (pool, placed_items, precollected_items, clock_mode) = make_customizer_pool(world, player) skip_pool_adjustments = True elif world.custom and player in world.customitemarray: - (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world, player, world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.bombbag[player], world.customitemarray[player]) + (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon) = make_custom_item_pool(world, player, world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.bombbag[player], world.customitemarray[player]) world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999) else: - (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world, player, world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.flute_mode[player] == 'active' or world.is_tile_swapped(0x18, player)) + (pool, placed_items, precollected_items, clock_mode) = get_pool_core(world, player, world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.bombbag[player], world.doorShuffle[player], world.logic[player], world.flute_mode[player] == 'active' or world.is_tile_swapped(0x18, player)) if player in world.pool_adjustment.keys() and not skip_pool_adjustments: amt = world.pool_adjustment[player] @@ -364,8 +370,6 @@ def generate_itempool(world, player): if item.name == 'Bomb Upgrade (+10)' and item.player == player: item.advancement = True - world.lamps_needed_for_dark_rooms = lamps_needed_for_dark_rooms - if clock_mode is not None: world.clock_mode = clock_mode @@ -1109,8 +1113,6 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt else: pool.extend(basicgloves) - lamps_needed_for_dark_rooms = 1 - # old insanity shuffle didn't have fake LW/DW logic so this used to be conditional pool.extend(['Magic Mirror', 'Moon Pearl']) @@ -1162,11 +1164,17 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt place_item('Link\'s Uncle', swords_to_use.pop()) place_item('Blacksmith', swords_to_use.pop()) place_item('Pyramid Fairy - Left', swords_to_use.pop()) - if goal not in ['pedestal', 'trinity']: - place_item('Master Sword Pedestal', swords_to_use.pop()) - else: - place_item('Master Sword Pedestal', 'Triforce') + if world.custom_goals[player]['pedgoal'] and 'requirements' in world.custom_goals[player]['pedgoal'] and world.custom_goals[player]['pedgoal']['requirements'][0]['condition'] == 0x00: + place_item('Master Sword Pedestal', 'Nothing') + world.get_location('Master Sword Pedestal', player).locked = True pool.append(swords_to_use.pop()) + else: + if goal not in ['pedestal', 'trinity']: + place_item('Master Sword Pedestal', swords_to_use.pop()) + else: + place_item('Master Sword Pedestal', 'Triforce') + world.get_location('Master Sword Pedestal', player).locked = True + pool.append(swords_to_use.pop()) else: pool.extend(diff.progressivesword if want_progressives() else diff.basicsword) if swords == 'assured': @@ -1194,8 +1202,12 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt if goal in ['sanctuary']: place_item('Sanctuary', 'Triforce') - if goal in ['pedestal', 'trinity'] and swords != 'vanilla': + if world.custom_goals[player]['pedgoal'] and 'requirements' in world.custom_goals[player]['pedgoal'] and world.custom_goals[player]['pedgoal']['requirements'][0]['condition'] == 0x00: + place_item('Master Sword Pedestal', 'Nothing') + world.get_location('Master Sword Pedestal', player).locked = True + elif goal in ['pedestal', 'trinity'] and swords != 'vanilla': place_item('Master Sword Pedestal', 'Triforce') + world.get_location('Master Sword Pedestal', player).locked = True if world.bow_mode[player].startswith('retro'): pool = [item.replace('Single Arrow', 'Rupees (5)') for item in pool] pool = [item.replace('Arrows (10)', 'Rupees (5)') for item in pool] @@ -1213,7 +1225,7 @@ def get_pool_core(world, player, progressive, shuffle, difficulty, treasure_hunt pool.extend(['Small Key (Universal)']) else: pool.extend(['Small Key (Universal)']) - return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) + return (pool, placed_items, precollected_items, clock_mode) item_alternates = { @@ -1329,8 +1341,6 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer diff = difficulties[difficulty] - lamps_needed_for_dark_rooms = 1 - # expert+ difficulties produce the same contents for # all bottles, since only one bottle is available if diff.same_bottle: @@ -1359,8 +1369,12 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer if goal in ['sanctuary']: place_item('Sanctuary', 'Triforce') - if goal in ['pedestal', 'trinity']: + if world.custom_goals[player]['pedgoal'] and 'requirements' in world.custom_goals[player]['pedgoal'] and world.custom_goals[player]['pedgoal']['requirements'][0]['condition'] == 0x00: + place_item('Master Sword Pedestal', 'Nothing') + world.get_location('Master Sword Pedestal', player).locked = True + elif goal in ['pedestal', 'trinity']: place_item('Master Sword Pedestal', 'Triforce') + world.get_location('Master Sword Pedestal', player).locked = True if mode == 'standard': if world.keyshuffle[player] == 'universal': @@ -1392,7 +1406,7 @@ def make_custom_item_pool(world, player, progressive, shuffle, difficulty, timer pool.remove('Fighter Sword') pool.append('Rupees (50)') - return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon, lamps_needed_for_dark_rooms) + return (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_total, treasure_hunt_icon) def make_customizer_pool(world, player): pool = [] @@ -1475,8 +1489,12 @@ def make_customizer_pool(world, player): if goal in ['sanctuary']: place_item('Sanctuary', 'Triforce') - if world.goal[player] in ['pedestal', 'trinity']: + if world.custom_goals[player]['pedgoal'] and 'requirements' in world.custom_goals[player]['pedgoal'] and world.custom_goals[player]['pedgoal']['requirements'][0]['condition'] == 0x00: + place_item('Master Sword Pedestal', 'Nothing') + world.get_location('Master Sword Pedestal', player).locked = True + elif world.goal[player] in ['pedestal', 'trinity']: place_item('Master Sword Pedestal', 'Triforce') + world.get_location('Master Sword Pedestal', player).locked = True guaranteed_items = alwaysitems + ['Magic Mirror', 'Moon Pearl'] if world.is_tile_swapped(0x18, player) or world.flute_mode[player] == 'active': @@ -1539,7 +1557,7 @@ def make_customizer_pool(world, player): pool.remove('Fighter Sword') pool.append('Rupees (50)') - return pool, placed_items, precollected_items, clock_mode, 1 + return pool, placed_items, precollected_items, clock_mode filler_items = { @@ -1685,7 +1703,7 @@ def set_event_item(world, player, location_name, item_name=None): def shuffle_event_items(world, player): - if (world.shuffle_followers[player]): + if world.shuffle_followers[player]: available_quests = follower_quests.copy() available_pickups = [quests[0] for quests in available_quests.values()] @@ -1697,11 +1715,14 @@ def shuffle_event_items(world, player): available_pickups.remove(loc.item.name) - if world.mode[player] == 'standard': - if 'Zelda Herself' in available_pickups: - zelda_pickup = available_quests.pop('Zelda Pickup')[0] - available_pickups.remove(zelda_pickup) - set_event_item(world, player, 'Zelda Pickup', zelda_pickup) + if world.mode[player] == 'standard' and 'Zelda Herself' in available_pickups: + zelda_dropoff = 'Zelda Pickup' + if world.default_zelda_region[player] == 'Thieves Blind\'s Cell': + zelda_dropoff = 'Suspicious Maiden' + available_quests.pop(zelda_dropoff) + zelda_pickup = 'Zelda Herself' + available_pickups.remove(zelda_pickup) + set_event_item(world, player, zelda_dropoff, zelda_pickup) random.shuffle(available_pickups) @@ -1724,10 +1745,11 @@ def get_item_and_event_flag(item, world, player, dungeon_pool, prize_set, prize_ item_player = player if len(item_parts) < 2 else int(item_parts[1]) item_name = item_parts[0] event_flag = False - if item_name in prize_set: - item_player = player # prizes must be for that player + if item_name in prize_set or item_name in follower_pickups: + item_player = player # must be for that player item_to_place = ItemFactory(item_name, item_player) - prize_pool.remove(item_name) + if item_name in prize_set: + prize_pool.remove(item_name) event_flag = True elif is_dungeon_item(item_name, world, item_player): item_to_place = next(x for x in dungeon_pool diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index d9c837b9..65ad0faf 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -1805,7 +1805,10 @@ def imp_locations_factory(world, player): return imp_locations imp_locations = ['Agahnim 1', 'Agahnim 2', 'Attic Cracked Floor', 'Suspicious Maiden'] if world.mode[player] == 'standard': - imp_locations.append('Zelda Pickup') + if world.default_zelda_region[player] == 'Thieves Blinds\' Cell': + imp_locations.append('Suspicious Maiden') + else: + imp_locations.append('Zelda Pickup') imp_locations.append('Zelda Drop Off') return imp_locations diff --git a/Main.py b/Main.py index 4f476a6a..f9c03012 100644 --- a/Main.py +++ b/Main.py @@ -17,7 +17,7 @@ from OverworldGlitchRules import create_owg_connections from PotShuffle import shuffle_pots, shuffle_pot_switches from Regions import create_regions, create_shops, mark_light_dark_world_regions, create_dungeon_regions, adjust_locations from OWEdges import create_owedges -from OverworldShuffle import link_overworld, update_world_regions, create_dynamic_exits +from OverworldShuffle import link_overworld, update_world_regions, create_dynamic_flute_exits, create_dynamic_mirror_exits from Rom import patch_rom, patch_race_rom, apply_rom_settings, LocalRom, JsonRom, get_hash_string from Doors import create_doors from DoorShuffle import link_doors, connect_portal, link_doors_prep @@ -40,7 +40,7 @@ from source.enemizer.DamageTables import DamageTable from source.enemizer.Enemizer import randomize_enemies from source.rom.DataTables import init_data_tables -version_number = '1.4.10' +version_number = '1.5.0' version_branch = '-u' __version__ = f'{version_number}{version_branch}' @@ -117,31 +117,7 @@ def main(args, seed=None, fish=None): if args.securerandom: world.seed = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(9)) - world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)} - world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)} - world.ganon_item = {player: random_ganon_item(args.swords[player]) if args.ganon_item[player] == 'random' else args.ganon_item[player] for player in range(1, world.players + 1)} - - world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)} - - world.treasure_hunt_count = {} - world.treasure_hunt_total = {} - for p in args.triforce_goal: - if int(args.triforce_goal[p]) != 0 or int(args.triforce_pool[p]) != 0 or int(args.triforce_goal_min[p]) != 0 or int(args.triforce_goal_max[p]) != 0 or int(args.triforce_pool_min[p]) != 0 or int(args.triforce_pool_max[p]) != 0: - if int(args.triforce_goal[p]) != 0: - world.treasure_hunt_count[p] = int(args.triforce_goal[p]) - elif int(args.triforce_goal_min[p]) != 0 and int(args.triforce_goal_max[p]) != 0: - world.treasure_hunt_count[p] = random.randint(int(args.triforce_goal_min[p]), int(args.triforce_goal_max[p])) - else: - world.treasure_hunt_count[p] = 8 if world.goal[p] == 'trinity' else 20 - if int(args.triforce_pool[p]) != 0: - world.treasure_hunt_total[p] = int(args.triforce_pool[p]) - elif int(args.triforce_pool_min[p]) != 0 and int(args.triforce_pool_max[p]) != 0: - world.treasure_hunt_total[p] = random.randint(max(int(args.triforce_pool_min[p]), world.treasure_hunt_count[p] + int(args.triforce_min_difference[p])), min(int(args.triforce_pool_max[p]), world.treasure_hunt_count[p] + int(args.triforce_max_difference[p]))) - else: - world.treasure_hunt_total[p] = 10 if world.goal[p] == 'trinity' else 30 - else: - # this will be handled in ItemList.py and custom item pool is used to determine the numbers - world.treasure_hunt_count[p], world.treasure_hunt_total[p] = 0, 0 + resolve_random_settings(world, args) world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)} world.finish_init() @@ -215,9 +191,7 @@ def main(args, seed=None, fish=None): for player in range(1, world.players + 1): link_overworld(world, player) create_shops(world, player) - update_world_regions(world, player) mark_light_dark_world_regions(world, player) - create_dynamic_exits(world, player) init_districts(world) @@ -335,7 +309,7 @@ def main(args, seed=None, fish=None): for player in range(1, world.players + 1): rom = JsonRom() if args.jsonout else LocalRom(args.rom) - patch_rom(world, rom, player, team, bool(args.mystery)) + patch_rom(world, rom, player, team, bool(args.mystery), str(args.rom_header) if args.rom_header else None) if args.race: patch_race_rom(rom) @@ -344,7 +318,7 @@ def main(args, seed=None, fish=None): world.spoiler.hashes[(player, team)] = get_hash_string(rom.hash) apply_rom_settings(rom, args.heartbeep[player], args.heartcolor[player], args.quickswap[player], - args.fastmenu[player], args.disablemusic[player], args.sprite[player], + args.fastmenu[player], args.disablemusic[player], args.sprite[player], args.triforce_gfx[player], args.ow_palettes[player], args.uw_palettes[player], args.reduce_flashing[player], args.shuffle_sfx[player], args.shuffle_sfxinstruments[player], args.shuffle_songinstruments[player], args.msu_resume[player]) @@ -548,10 +522,200 @@ def init_world(args, fish): world.aga_randomness = args.aga_randomness.copy() world.money_balance = args.money_balance.copy() - + # custom settings - these haven't been promoted to full settings yet + in_progress_settings = ['force_enemy', 'free_lamp_cone'] + for player in range(1, world.players + 1): + for setting in in_progress_settings: + if world.customizer and world.customizer.has_setting(player, setting): + getattr(world, setting)[player] = world.customizer.get_setting(player, setting) + return world +def resolve_random_settings(world, args): + world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)} + world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)} + world.ganon_item = {player: random_ganon_item(args.swords[player]) if args.ganon_item[player] == 'random' else args.ganon_item[player] for player in range(1, world.players + 1)} + world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)} + + world.treasure_hunt_count = {} + world.treasure_hunt_total = {} + for p in args.triforce_goal: + if int(args.triforce_goal[p]) != 0 or int(args.triforce_pool[p]) != 0 or int(args.triforce_goal_min[p]) != 0 or int(args.triforce_goal_max[p]) != 0 or int(args.triforce_pool_min[p]) != 0 or int(args.triforce_pool_max[p]) != 0: + if int(args.triforce_goal[p]) != 0: + world.treasure_hunt_count[p] = int(args.triforce_goal[p]) + elif int(args.triforce_goal_min[p]) != 0 and int(args.triforce_goal_max[p]) != 0: + world.treasure_hunt_count[p] = random.randint(int(args.triforce_goal_min[p]), int(args.triforce_goal_max[p])) + else: + world.treasure_hunt_count[p] = 8 if world.goal[p] == 'trinity' else 20 + if int(args.triforce_pool[p]) != 0: + world.treasure_hunt_total[p] = int(args.triforce_pool[p]) + elif int(args.triforce_pool_min[p]) != 0 and int(args.triforce_pool_max[p]) != 0: + world.treasure_hunt_total[p] = random.randint(max(int(args.triforce_pool_min[p]), world.treasure_hunt_count[p] + int(args.triforce_min_difference[p])), min(int(args.triforce_pool_max[p]), world.treasure_hunt_count[p] + int(args.triforce_max_difference[p]))) + else: + world.treasure_hunt_total[p] = 10 if world.goal[p] == 'trinity' else 30 + else: + # this will be handled in ItemList.py and custom item pool is used to determine the numbers + world.treasure_hunt_count[p], world.treasure_hunt_total[p] = 0, 0 + + if world.customizer: + def process_goal(goal_type): + goal_input = goals[player][goal_type] + world.custom_goals[player][goal_type] = goal = {} + if 'cutscene_gfx' in goal_input and goal_type in ['gtentry', 'pedgoal', 'murahgoal']: + gfx = goal_input['cutscene_gfx'] + if type(gfx) is str: + from Tables import item_gfx_table + if gfx.lower() == 'random': + gfx = random.choice(list(item_gfx_table.keys())) + if gfx in item_gfx_table: + goal['cutscene_gfx'] = (item_gfx_table[gfx][1] + (0x8000 if not item_gfx_table[gfx][0] else 0), item_gfx_table[gfx][2]) + else: + raise Exception(f'Invalid name "{gfx}" in customized {goal_type} cutscene gfx') + else: + goal['cutscene_gfx'] = gfx + if 'requirements' in goal_input: + if goal_type == 'ganongoal' and world.goal[player] == 'pedestal': + goal['requirements'] = [0x00] + goal['logic'] = False + return + goal['requirements'] = [] + goal['logic'] = {} + if 'goaltext' in goal_input: + goal['goaltext'] = goal_input['goaltext'] + else: + raise Exception(f'Missing goal text for {goal_type}') + + req_table = { + 'Invulnerable': 0x00, + 'Disabled': 0x00, + 'Pendants': 0x01, + 'Crystals': 0x02, + 'PendantBosses': 0x03, + 'CrystalBosses': 0x04, + 'PrizeBosses': 0x05, + 'Bosses': 0x05, + 'Agahnim1Defeated': 0x06, + 'Agahnim1': 0x06, + 'Aga1': 0x06, + 'Agahnim2Defeated': 0x07, + 'Agahnim2': 0x07, + 'Aga2': 0x07, + 'GoalItemsCollected': 0x08, + 'GoalItems': 0x08, + 'TriforcePieces': 0x08, + 'TriforceHunt': 0x08, + 'MaxCollectionRate': 0x09, + 'CollectionRate': 0x09, + 'Collection': 0x09, + 'CustomGoal': 0x0A, + 'Custom': 0x0A, + } + if isinstance(goal_input['requirements'], list): + for r in list(goal_input['requirements']): + req = {} + try: + if isinstance(r, str): + req['condition'] = req_table[r] + else: + req['condition'] = req_table[list(r.keys())[0]] + if req['condition'] == req_table['Invulnerable']: + goal['requirements']= [req] + goal['logic'] = False + break + elif req['condition'] == req_table['CustomGoal']: + if isinstance(r['address'], int) and 0x7E0000 <= r['address'] <= 0x7FFFFF: + compare_table = { + 'minimum': 0x00, + 'at least': 0x00, + 'equal': 0x01, + 'equals': 0x01, + 'equal to': 0x01, + 'any flag': 0x02, + 'all flags': 0x03, + 'flags match': 0x03, + 'count bits': 0x04, + 'count flags': 0x04, + } + if r['comparison'] in compare_table: + options = compare_table[r['comparison']] + if r['address'] >= 0x7F0000: + options |= 0x10 + if isinstance(r['target'], int) and 0 <= r['target'] <= 0xFFFF: + if 'size' in r and r['size'] in ['word', '16-bit', '16bit', '16 bit', '16', '2-byte', '2byte', '2 byte', '2-bytes', '2 bytes']: + options |= 0x08 + req['target'] = r['target'] + elif 0 <= r['target'] <= 0xFF: + req['target'] = r['target'] + else: + raise Exception(f'Invalid custom goal target for {goal_type}, must be an 8-bit integer') + req.update({'address': r['address'] & 0xFFFF, 'options': options}) + goal['requirements'].append(req) + else: + raise Exception(f'Invalid custom goal target for {goal_type}, must be a 16-bit integer') + else: + raise KeyError(f'Invalid custom goal comparison for {goal_type}') + else: + raise Exception(f'Custom goal address for {goal_type} only allows 0x7Exxxx and 0x7Fxxxx addresses') + else: + if req['condition'] not in [req_table['Aga1'], req_table['Aga2']]: + if 'target' not in r: + req['condition'] |= 0x80 + else: + if isinstance(r['target'], int): + if req['condition'] < req_table['TriforcePieces']: + if 0 <= r['target'] <= 0xFF: + req['target'] = r['target'] + else: + raise Exception(f'Invalid {list(r.keys())[0]} requirement target for {goal_type}, must be an 8-bit integer') + else: + if 0 <= r['target'] <= 0xFFFF: + req['target'] = r['target'] + else: + raise Exception(f'Invalid {list(r.keys())[0]} requirement target for {goal_type}, must be a 16-bit integer') + elif isinstance(r['target'], str): + if r['target'].lower() == 'random': + req['target'] = 'random' + elif r['target'].endswith('%') and 1 <= int(r['target'][:-1]) <= 100: + req['target'] = req['target'] + else: + raise Exception(f'Invalid {list(r.keys())[0]} requirement target for {goal_type}') + if req['condition'] & 0x7F == req_table['Pendants']: + goal['logic']['pendants'] = req['target'] = req.get('target', 3) + elif req['condition'] & 0x7F == req_table['Crystals']: + goal['logic']['crystals'] = req['target'] = req.get('target', 7) + elif req['condition'] & 0x7F == req_table['PendantBosses']: + goal['logic']['pendant_bosses'] = req['target'] = req.get('target', 3) + elif req['condition'] & 0x7F == req_table['CrystalBosses']: + goal['logic']['crystal_bosses'] = req['target'] = req.get('target', 7) + elif req['condition'] & 0x7F == req_table['PrizeBosses']: + goal['logic']['bosses'] = req['target'] = req.get('target', 10) + elif req['condition'] & 0x7F == req_table['Aga1']: + goal['logic']['aga1'] = True + elif req['condition'] & 0x7F == req_table['Aga2']: + goal['logic']['aga2'] = True + elif req['condition'] & 0x7F == req_table['TriforcePieces']: + goal['logic']['goal_items'] = req['target'] = req.get('target', None) + elif req['condition'] & 0x7F == req_table['CollectionRate']: + goal['logic']['collection'] = req['target'] = req.get('target', None) + goal['requirements'].append(req) + except KeyError: + raise KeyError(f'Invalid {goal_type} requirement: {r}') + else: + raise KeyError(f'Invalid {goal_type} requirement definition') + if 'logic' in goal_input and goal['logic'] and goal['logic'] is not None: + goal['logic'].update(goal_input['logic']) + return + + goals = world.customizer.get_goals() + for player in range(1, world.players + 1): + if goals and player in goals: + for g in ['gtentry', 'ganongoal', 'pedgoal', 'murahgoal']: + if g in goals[player]: + process_goal(g) + return + + def set_starting_inventory(world, args): for player in range(1, world.players + 1): if args.usestartinventory[player]: @@ -616,7 +780,6 @@ def copy_world(world): ret.can_take_damage = world.can_take_damage ret.difficulty_requirements = world.difficulty_requirements.copy() ret.fix_fake_world = world.fix_fake_world.copy() - ret.lamps_needed_for_dark_rooms = world.lamps_needed_for_dark_rooms ret.mapshuffle = world.mapshuffle.copy() ret.compassshuffle = world.compassshuffle.copy() ret.keyshuffle = world.keyshuffle.copy() @@ -625,6 +788,7 @@ def copy_world(world): ret.bombbag = world.bombbag.copy() ret.flute_mode = world.flute_mode.copy() ret.bow_mode = world.bow_mode.copy() + ret.free_lamp_cone = world.free_lamp_cone.copy() ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy() ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy() ret.ganon_item = world.ganon_item.copy() @@ -687,13 +851,13 @@ def copy_world(world): update_world_regions(ret, player) if world.logic[player] in ('owglitches', 'hybridglitches', 'nologic'): create_owg_connections(ret, player) - create_dynamic_exits(ret, player) create_dungeon_regions(ret, player) create_owedges(ret, player) create_shops(ret, player) - #create_doors(ret, player) create_rooms(ret, player) create_dungeons(ret, player) + create_dynamic_mirror_exits(ret, player) + create_dynamic_flute_exits(ret, player) # there are region references here they must be migrated to preserve integrity # ret.exp_cache = world.exp_cache.copy() @@ -818,7 +982,7 @@ def copy_world(world): return ret -def copy_world_premature(world, player): +def copy_world_premature(world, player, create_flute_exits=True): # ToDo: Not good yet ret = World(world.players, world.owShuffle, world.owCrossed, world.owMixed, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, @@ -843,7 +1007,6 @@ def copy_world_premature(world, player): ret.can_take_damage = world.can_take_damage ret.difficulty_requirements = world.difficulty_requirements.copy() ret.fix_fake_world = world.fix_fake_world.copy() - ret.lamps_needed_for_dark_rooms = world.lamps_needed_for_dark_rooms ret.mapshuffle = world.mapshuffle.copy() ret.compassshuffle = world.compassshuffle.copy() ret.keyshuffle = world.keyshuffle.copy() @@ -852,6 +1015,7 @@ def copy_world_premature(world, player): ret.bombbag = world.bombbag.copy() ret.flute_mode = world.flute_mode.copy() ret.bow_mode = world.bow_mode.copy() + ret.free_lamp_cone = world.free_lamp_cone.copy() ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy() ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy() ret.ganon_item = world.ganon_item.copy() @@ -910,19 +1074,21 @@ def copy_world_premature(world, player): ret.key_logic = world.key_logic.copy() ret.settings = world.settings - ret.is_copied_world = True + ret.is_premature_copied_world = True create_regions(ret, player) update_world_regions(ret, player) if world.logic[player] in ('owglitches', 'hybridglitches', 'nologic'): create_owg_connections(ret, player) - create_dynamic_exits(ret, player) create_dungeon_regions(ret, player) create_owedges(ret, player) create_shops(ret, player) create_doors(ret, player) create_rooms(ret, player) create_dungeons(ret, player) + create_dynamic_mirror_exits(ret, player) # assumes these have already been added to world + if create_flute_exits: + create_dynamic_flute_exits(ret, player) if world.mode[player] == 'standard': parent = ret.get_region('Menu', player) diff --git a/MultiServer.py b/MultiServer.py index c92f9989..44559953 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -83,7 +83,7 @@ def notify_client(client : Client, text : str): logging.info("Notice (Player %s in team %d): %s" % (client.name, client.team+1, text)) asyncio.create_task(send_msgs(client.socket, [['Print', text]])) -async def server(websocket, path, ctx : Context): +async def server(websocket, ctx : Context): client = Client(websocket) ctx.clients.append(client) diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 27c16ca1..616a85a2 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -8,7 +8,7 @@ from OWEdges import OWTileRegions, OWEdgeGroups, OWEdgeGroupsTerrain, OWExitType from OverworldGlitchRules import create_owg_connections from Utils import bidict -version_number = '0.6.0.7' +version_number = '0.6.1.7' # branch indicator is intentionally different across branches version_branch = '' @@ -200,6 +200,7 @@ def link_overworld(world, player): connect_simple(world, exitname, regionname, player) categorize_world_regions(world, player) + create_dynamic_mirror_exits(world, player) if world.logic[player] in ('owglitches', 'hybridglitches', 'nologic'): create_owg_connections(world, player) @@ -424,8 +425,6 @@ def link_overworld(world, player): assert len(forward_set) == len(back_set) for (forward_edge, back_edge) in zip(forward_set, back_set): connect_two_way(world, forward_edge, back_edge, player, connected_edges) - - world.owsectors[player] = build_sectors(world, player) else: if world.owKeepSimilar[player] and world.owShuffle[player] == 'parallel': for exitname, destname in parallelsimilar_connections: @@ -557,13 +556,14 @@ def link_overworld(world, player): connect_set(forward_edge_sets[0], back_edge_sets[0], connected_edges) remove_connected(forward_edge_sets, back_edge_sets) assert len(connected_edges) == len(default_connections) * 2, connected_edges - - world.owsectors[player] = build_sectors(world, player) + valid_layout = validate_layout(world, player) tries -= 1 assert valid_layout, 'Could not find a valid OW layout' + world.owsectors[player] = build_sectors(world, player) + # flute shuffle logging.getLogger('').debug('Shuffling flute spots') def connect_flutes(flute_destinations): @@ -725,6 +725,8 @@ def link_overworld(world, player): s[0x3a],s[0x3b],s[0x3c], s[0x3f]) world.spoiler.set_map('flute', text_output, new_spots, player) + create_dynamic_flute_exits(world, player) + def connect_custom(world, connected_edges, groups, forced, player): forced_crossed, forced_noncrossed = forced def remove_pair_from_pool(edgename1, edgename2, is_crossed): @@ -1292,7 +1294,7 @@ def adjust_edge_groups(world, trimmed_groups, edges_to_swap, player): groups[(mode, wrld, dir, terrain, parallel, count, group_name)][i].extend(matches) return groups -def create_flute_exits(world, player): +def create_dynamic_flute_exits(world, player): flute_in_pool = True if player not in world.customitemarray else any(i for i, n in world.customitemarray[player].items() if i == 'flute' and n > 0) if not flute_in_pool: return @@ -1303,6 +1305,7 @@ def create_flute_exits(world, player): exit.spot_type = 'Flute' exit.connect(world.get_region('Flute Sky', player)) region.exits.append(exit) + world.initialize_regions() def get_mirror_exit_name(from_region, to_region): if from_region in mirror_connections and to_region in mirror_connections[from_region]: @@ -1329,7 +1332,7 @@ def get_mirror_edges(world, region, player): mirror_exits.append(tuple([get_mirror_exit_name(other_world_region_name, region.name), region.name])) return mirror_exits -def create_mirror_exits(world, player): +def create_dynamic_mirror_exits(world, player): mirror_exits = set() for region in (r for r in world.regions if r.player == player and r.name not in ['Zoras Domain', 'Master Sword Meadow', 'Hobo Bridge']): if region.type == (RegionType.DarkWorld if world.mode[player] != 'inverted' else RegionType.LightWorld): @@ -1350,12 +1353,6 @@ def create_mirror_exits(world, player): region.exits.append(exit) mirror_exits.add(exitname) - elif region.terrain == Terrain.Land: - pass - -def create_dynamic_exits(world, player): - create_flute_exits(world, player) - create_mirror_exits(world, player) world.initialize_regions() def categorize_world_regions(world, player): @@ -1433,7 +1430,7 @@ def build_sectors(world, player): # perform accessibility check on duplicate world for p in range(1, world.players + 1): world.key_logic[p] = {} - base_world = copy_world_premature(world, player) + base_world = copy_world_premature(world, player, create_flute_exits=False) # build lists of contiguous regions accessible with full inventory (excl portals/mirror/flute/entrances) regions = list(OWTileRegions.copy().keys()) @@ -1510,7 +1507,7 @@ def build_accessible_region_list(world, start_region, player, build_copy_world=F if build_copy_world: for p in range(1, world.players + 1): world.key_logic[p] = {} - base_world = copy_world_premature(world, player) + base_world = copy_world_premature(world, player, create_flute_exits=True) base_world.override_bomb_check = True else: base_world = world @@ -1554,11 +1551,9 @@ def validate_layout(world, player): 'Pyramid Area': ['Pyramid Exit Ledge'] } - from Main import copy_world_premature - from Utils import stack_size3a # TODO: Find a better source for the below lists, original sourced was deprecated from source.overworld.EntranceData import default_dungeon_connections, default_connector_connections, default_item_connections, default_shop_connections, default_drop_connections, default_dropexit_connections - + dungeon_entrances = list(zip(*default_dungeon_connections + [('Ganons Tower', '')]))[0] connector_entrances = list(zip(*default_connector_connections))[0] item_entrances = list(zip(*default_item_connections))[0] @@ -1567,12 +1562,11 @@ def validate_layout(world, player): flute_in_pool = True if player not in world.customitemarray else any(i for i, n in world.customitemarray[player].items() if i == 'flute' and n > 0) def explore_region(region_name, region=None): - if stack_size3a() > 500: - raise GenerationException(f'Infinite loop detected for "{region_name}" located at \'validate_layout\'') - - explored_regions.append(region_name) + if region_name in explored_regions: + return + explored_regions.add(region_name) if not region: - region = base_world.get_region(region_name, player) + region = world.get_region(region_name, player) for exit in region.exits: if exit.connected_region is not None and exit.connected_region.name not in explored_regions \ and exit.connected_region.type in [RegionType.LightWorld, RegionType.DarkWorld]: @@ -1586,11 +1580,8 @@ def validate_layout(world, player): for dest_region in sane_connectors[region_name]: if dest_region not in explored_regions: explore_region(dest_region) - - for p in range(1, world.players + 1): - world.key_logic[p] = {} - base_world = copy_world_premature(world, player) - explored_regions = list() + + explored_regions = set() if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull'] or not world.shufflelinks[player]: if not world.is_bombshop_start(player): @@ -1616,14 +1607,14 @@ def validate_layout(world, player): start_region = 'Hyrule Castle Ledge' explore_region(start_region) - unreachable_regions = OrderedDict() + unreachable_regions = {} unreachable_count = -1 while unreachable_count != len(unreachable_regions): # find unreachable regions unreachable_regions = {} for region_name in list(OWTileRegions.copy().keys()): if region_name not in explored_regions and region_name not in isolated_regions: - region = base_world.get_region(region_name, player) + region = world.get_region(region_name, player) unreachable_regions[region_name] = region # loop thru unreachable regions to check if some can be excluded diff --git a/PastReleaseNotes.md b/PastReleaseNotes.md index 68b6b381..dbdc2f12 100644 --- a/PastReleaseNotes.md +++ b/PastReleaseNotes.md @@ -5,7 +5,21 @@ # Patch Notes Changelog archive - +* 1.4.11 + * Rom fixes (all thanks to Codemann, I believe) + * Pot bug when at sprite limit + * Kodongo AI vanilla in vanilla rooms + * Issue with music silencing across certain room transitions + * Glitched: Some HMG logic fixed. Thanks Muffins! (Sorry it took me forever to get this PR in) + * Glitched: Blind fight VRAM fix. Thanks Mufffins! + * Text: Updated tourney winners. Thanks clearmouse! + * Enemizer: Banned Swamola enemy everywhere as they may be causing crashes + * Enemizer: Enemy bans from Q2 and Q3. Thank you for all the reports. +* 1.4.10 + * Logic: Changed the rule surrounding the Bumper Cave Ledge Drop (the murderdactyl) to only require Pearl AND (Cape OR Byrna OR a Sword) in OHKO mode for now. This is a temporary solution until a better way to prevent needing to use a framerule to get past the bird is invented. + * Helmacopter Fix. + * Fixed a bug in shopsanity that caused the generation to fail with certain prices. + * Enemizer: fairies were invalid on the overworld (unless a bonk occurred nearby), so they will no longer be randomized there. * 1.4.9 * Attempted fix for Moth conveyor room timing. Thanks for many people's input. Unsure if Helmacopter is still acceptable. * Mirror scroll will show up on file start screen if enabled (thanks Clearmouse!) diff --git a/Plando.py b/Plando.py index cc97562f..25003f24 100755 --- a/Plando.py +++ b/Plando.py @@ -74,9 +74,9 @@ def main(args): logger.info('Patching ROM.') rom = LocalRom(args.rom) - patch_rom(world, rom, 1, 1, False) + patch_rom(world, rom, 1, 1, False, str(args.rom_header) if args.rom_header else None) - apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic, args.sprite, args.ow_palettes, args.uw_palettes) + apply_rom_settings(rom, args.heartbeep, args.heartcolor, args.quickswap, args.fastmenu, args.disablemusic, args.sprite, args.triforce_gfx, args.ow_palettes, args.uw_palettes) for textname, texttype, text in text_patches: if texttype == 'text': diff --git a/RELEASENOTES.md b/RELEASENOTES.md index cd40aeaf..b43278d1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -141,8 +141,19 @@ These are now independent of retro mode and have three options: None, Random, an # Patch Notes -* 1.4.10 - * Logic: Changed the rule surrounding the Bumper Cave Ledge Drop (the murderdactyl) to only require Pearl AND (Cape OR Byrna OR a Sword) in OHKO mode for now. This is a temporary solution until a better way to prevent needing to use a framerule to get past the bird is invented. - * Helmacopter Fix. - * Fixed a bug in shopsanity that caused the generation to fail with certain prices. - * Enemizer: fairies were invalid on the overworld (unless a bonk occurred nearby), so they will no longer be randomized there. +* 1.5.0 + * Logic: Fixed vanilla key logic for GT basement + * Logic (Playthrough): Fixed an issue where enemy kill rules were not applied during playthrough calculation. (Thanks Catobat for the catch) + * Enemy Drop: Added "spies" and shadows for hidden enemies when enemy drop shuffled is enabled + * Pottery: Pots will uncolor when the item inside is collected next time the room is loaded + * Keysanity/Keydrop Menu for DR: + * Map key information is now controlled by the Dungeon Chest Counts setting. If set to always on, this information will be available right away in the menu and will be on the HUD even when the map is not obtained. + * The key counter on the HUD for the current dungeon now accounts for keys from enemies or pots that are from vanilla key locations. + * The first number on the HUD represents all keys collected either in that dungeon or elsewhere. + * The second number on the HUD is the total keys that can be collected either in that dungeon or elsewhere. + * The key counter on inside the Menu is unchanged. (At the bottom near A button items) + * The first number in the Menu is the current number of keys in your inventory + * The second number is how many keys left to find in chests (not those from pots/enemies unless those item pools are enabled) + * Customizer: free_lamp_cone option added. The logic will account for this, and place the lamp without regard to dark rooms. + * Customizer: force_enemy option added that makes all enemies the specified type if possible. There are known gfx glitches in the overworld. + * Optimization: Improved generation performance (Thanks Catobat!) diff --git a/Rom.py b/Rom.py index d8322b63..b9561dee 100644 --- a/Rom.py +++ b/Rom.py @@ -44,7 +44,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '664f23f393710f2235779dbcce78236f' +RANDOMIZERBASEHASH = 'e188d59e5925d7ac84222b4e1cd5de6a' class JsonRom(object): @@ -419,7 +419,7 @@ def handle_native_dungeon(location, itemid): return itemid -def patch_rom(world, rom, player, team, is_mystery=False): +def patch_rom(world, rom, player, team, is_mystery=False, rom_header=None): random.seed(world.rom_seeds[player]) # progressive bow silver arrow hint hack @@ -1242,8 +1242,6 @@ def patch_rom(world, rom, player, team, is_mystery=False): rom.write_bytes(0xE9A5, [0x7E, 0x00, 0x24]) # disable below ganon chest if world.is_pyramid_open(player): rom.initial_sram.pre_open_pyramid_hole() - if world.crystals_needed_for_gt[player] == 0: - rom.initial_sram.pre_open_ganons_tower() rom.write_byte(0x18008F, 0x01 if world.is_atgt_swapped(player) else 0x00) # AT/GT swapped rom.write_byte(0xF5D73, 0xF0) # bees are catchable rom.write_byte(0xF5F10, 0xF0) # bees are catchable @@ -1275,22 +1273,115 @@ def patch_rom(world, rom, player, team, is_mystery=False): (0x02 if 'bombs' in world.escape_assist[player] else 0x00) | (0x04 if 'magic' in world.escape_assist[player] else 0x00))) # Escape assist - if world.goal[player] in ['pedestal', 'triforcehunt', 'sanctuary']: - rom.write_byte(0x1801A8, 0x01) # make ganon invincible - elif world.goal[player] in ['dungeons']: - rom.write_byte(0x1801A8, 0x02) # make ganon invincible until all dungeons are beat - elif world.goal[player] in ['crystals', 'trinity']: - rom.write_byte(0x1801A8, 0x04) # make ganon invincible until all crystals - elif world.goal[player] in ['ganonhunt']: - rom.write_byte(0x1801A8, 0x05) # make ganon invincible until all triforce pieces collected - elif world.goal[player] in ['completionist']: - rom.write_byte(0x1801A8, 0x0B) # make ganon invincible until everything is collected - else: - rom.write_byte(0x1801A8, 0x03) # make ganon invincible until all crystals and aga 2 are collected + gt_entry, ped_pull, ganon_goal, murah_goal = [], [], [], [] + # 00: Invulnerable + # 01: All pendants + # 02: All crystals + # 03: Pendant bosses + # 04: Crystal bosses + # 05: Prize bosses + # 06: Agahnim 1 defeated + # 07: Agahnim 2 defeated + # 08: Goal items collected (ie. Triforce Pieces) + # 09: Max collection rate + # 0A: Custom goal - rom.write_byte(0x18019A, world.crystals_needed_for_gt[player]) - rom.write_byte(0x1801A6, world.crystals_needed_for_ganon[player]) - rom.write_byte(0x1801A2, 0x00) # ped requirement is vanilla, set to 0x1 for special requirements + def get_goal_bytes(type): + goal_bytes = [] + for req in world.custom_goals[player][type]['requirements']: + goal_bytes += [req['condition']] + if req['condition'] == 0x0A: + # custom goal + goal_bytes += [req['options']] + goal_bytes += int16_as_bytes(req['address']) + if 0x08 & req['options'] == 0: + goal_bytes += [req['target']] + else: + goal_bytes += int16_as_bytes(req['target']) + elif req['condition'] & 0x80 == 0: + if req['condition'] & 0x7F == 0x06 or req['condition'] & 0x7F == 0x07: + # agahnims have no target value + pass + elif req['condition'] & 0x7F < 0x08: + goal_bytes += [req['target']] + else: + goal_bytes += int16_as_bytes(req['target']) + return goal_bytes + + if world.custom_goals[player]['gtentry'] and 'requirements' in world.custom_goals[player]['gtentry']: + gt_entry += get_goal_bytes('gtentry') + else: + gt_entry += [0x02, world.crystals_needed_for_gt[player]] + if len(gt_entry) == 0 or gt_entry == [0x02, 0x00]: + rom.initial_sram.pre_open_ganons_tower() + + if world.custom_goals[player]['pedgoal'] and 'requirements' in world.custom_goals[player]['pedgoal']: + ped_pull += get_goal_bytes('pedgoal') + else: + ped_pull += [0x81] + + if world.custom_goals[player]['murahgoal'] and 'requirements' in world.custom_goals[player]['murahgoal']: + murah_goal += get_goal_bytes('murahgoal') + else: + if world.goal[player] in ['triforcehunt', 'trinity']: + murah_goal += [0x88] + else: + murah_goal += [0x00] + + if world.custom_goals[player]['ganongoal'] and 'requirements' in world.custom_goals[player]['ganongoal']: + ganon_goal += get_goal_bytes('ganongoal') + else: + if world.goal[player] in ['pedestal', 'triforcehunt', 'sanctuary']: + ganon_goal = [0x00] + elif world.goal[player] in ['dungeons']: + ganon_goal += [0x81, 0x82, 0x06, 0x07] # pendants, crystals, and agas + elif world.goal[player] in ['crystals', 'trinity']: + ganon_goal += [0x02, world.crystals_needed_for_ganon[player]] + elif world.goal[player] in ['ganonhunt']: + ganon_goal += [0x88] # triforce pieces + elif world.goal[player] in ['completionist']: + ganon_goal += [0x81, 0x82, 0x06, 0x07, 0x89] # AD and max collection rate + else: + ganon_goal += [0x02, world.crystals_needed_for_ganon[player], 0x07] # crystals and aga2 + + gt_entry += [0xFF] + ped_pull += [0xFF] + ganon_goal += [0xFF] + murah_goal += [0xFF] + start_address = 0x8198 + 8 + + write_int16(rom, 0x180198, start_address) + rom.write_bytes(snes_to_pc(0xB00000 + start_address), gt_entry) + start_address += len(gt_entry) + + write_int16(rom, 0x18019A, start_address) + rom.write_bytes(snes_to_pc(0xB00000 + start_address), ganon_goal) + start_address += len(ganon_goal) + + write_int16(rom, 0x18019C, start_address) + rom.write_bytes(snes_to_pc(0xB00000 + start_address), ped_pull) + start_address += len(ped_pull) + + write_int16(rom, 0x18019E, start_address) + rom.write_bytes(snes_to_pc(0xB00000 + start_address), murah_goal) + start_address += len(murah_goal) + + if start_address > 0x81D8: + raise Exception("Custom Goal data too long to fit in allocated space, try reducing the amount of requirements.") + + # goal cutscene gfx + goals = { + #goal: gfx addr, palette addr + 'gtentry': (0x3081D8, 0x3081E6), + 'pedgoal': (0x3081ED, 0x3081F3), + 'murahgoal': (0x3081F6, 0x3081FC), + } + for goal_type, gfx_addr in goals.items(): + goal = world.custom_goals[player][goal_type] + if goal and 'cutscene_gfx' in goal: + gfx = goal['cutscene_gfx'] + write_int16(rom, snes_to_pc(gfx_addr[0]), gfx[0]) + rom.write_byte(snes_to_pc(gfx_addr[1]), gfx[1]) ganon_item_byte = { "silver": 0x00, @@ -1628,6 +1719,18 @@ def patch_rom(world, rom, player, team, is_mystery=False): rom.write_bytes(snes_to_pc(0x09A045), [0xEA, 0xEA]) # allow super bomb to follow into UW holes rom.write_byte(snes_to_pc(0x09ACDF), 0x6B) # allow kiki/locksmith to follow after screen transition + if world.default_zelda_region[player] == 'Thieves Blind\'s Cell': + write_int16(rom, snes_to_pc(0x02D8D6), 0x45) # change zelda spawn point to maiden cell + rom.write_bytes(snes_to_pc(0x02D8F0), [0x08, 0x08, 0x08, 0x09, 0x0B, 0x0A, 0x0B, 0x0B]) + write_int16(rom, snes_to_pc(0x02D91C), 0x0B00) + write_int16(rom, snes_to_pc(0x02D92A), 0x0800) + write_int16(rom, snes_to_pc(0x02D938), 0x0860) + write_int16(rom, snes_to_pc(0x02D946), 0x0B90) + write_int16(rom, snes_to_pc(0x02D954), 0x0078) + write_int16(rom, snes_to_pc(0x02D962), 0x017F) + rom.write_byte(snes_to_pc(0x02D975), 0x00) + rom.write_byte(snes_to_pc(0x02D98A), 0x02) + if world.enemy_shuffle[player] != 'none': # informs zelda and maiden to draw over gfx slots that are guaranteed unused rom.write_bytes(0x1802C1, world.data_tables[player].room_headers[0x80].free_gfx[0:2]) @@ -1690,26 +1793,6 @@ def patch_rom(world, rom, player, team, is_mystery=False): randomize_damage_table(rom, world, player) write_strings(rom, world, player, team) - # gt entry - if world.customizer: - gtentry = world.customizer.get_gtentry() - if gtentry and player in gtentry: - gtentry = gtentry[player] - if 'cutscene_gfx' in gtentry: - gfx = gtentry['cutscene_gfx'] - if type(gfx) is str: - from Tables import item_gfx_table - if gfx.lower() == 'random': - gfx = random.choice(list(item_gfx_table.keys())) - if gfx in item_gfx_table: - write_int16(rom, snes_to_pc(0x3081AA), item_gfx_table[gfx][1] + (0x8000 if not item_gfx_table[gfx][0] else 0)) - rom.write_byte(snes_to_pc(0x3081AC), item_gfx_table[gfx][2]) - else: - logging.getLogger('').warning('Invalid name "%s" in customized GT entry cutscene gfx', gfx) - else: - write_int16(rom, snes_to_pc(0x3081AA), gfx[0]) - rom.write_byte(snes_to_pc(0x3081AC), gfx[1]) - # write initial sram rom.write_initial_sram() @@ -1719,8 +1802,23 @@ def patch_rom(world, rom, player, team, is_mystery=False): # 21 bytes from Main import __version__ from OverworldShuffle import __version__ as ORVersion - seedstring = f'{world.seed:09}' if isinstance(world.seed, int) else world.seed - rom.name = bytearray(f'OR{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{seedstring}\0', 'utf8')[:21] + if rom_header: + if len(rom_header) > 21: + raise Exception('ROM header too long. Max 21 bytes, found %d bytes.' % len(rom_header)) + elif '|' in rom_header: + gen, seedstring = rom_header.split('|', 1) + gen = f'{gen:<3}' + seedstring = f'{int(seedstring):09}' if seedstring.isdigit() else seedstring[:9] + rom.name = bytearray(f'OR{gen}_{team+1}_{player}_{seedstring}\0', 'utf8')[:21] + elif len(rom_header) <= 9: + seedstring = f'{int(rom_header):09}' if rom_header.isdigit() else rom_header + rom.name = bytearray(f'OR{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{seedstring}\0', 'utf8')[:21] + else: + rom.name = bytearray(rom_header, 'utf8')[:21] + else: + seedstring = f'{world.seed:09}' if isinstance(world.seed, int) else world.seed + rom.name = bytearray(f'OR{__version__.split("-")[0].replace(".","")[0:3]}_{team+1}_{player}_{seedstring}\0', 'utf8')[:21] + rom.name.extend([0] * (21 - len(rom.name))) rom.write_bytes(0x7FC0, rom.name) @@ -1838,7 +1936,7 @@ def hud_format_text(text): return output[:32] -def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, sprite, +def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, sprite, triforce_gfx, ow_palettes, uw_palettes, reduce_flashing, shuffle_sfx, shuffle_sfxinstruments, shuffle_songinstruments, msu_resume): @@ -1896,6 +1994,20 @@ def apply_rom_settings(rom, beep, color, quickswap, fastmenu, disable_music, spr # write link sprite if required if sprite is not None: write_sprite(rom, sprite) + + if triforce_gfx is not None: + from Tables import item_gfx_table + if triforce_gfx in item_gfx_table.keys(): + (is_custom, address, palette, pal_addr, size) = item_gfx_table[triforce_gfx] + address = address if is_custom else 0x8000 + address + write_int16(rom, snes_to_pc(0xA2C600+(0x6C*2)), address) + write_int16(rom, snes_to_pc(0xA2C800+(0x6C*2)), address) + rom.write_byte(snes_to_pc(0xA2B100+0x6C), 0 if size == 2 else 4) + rom.write_byte(snes_to_pc(0xA2BA00+0x6C), size) + rom.write_byte(snes_to_pc(0xA2BB00+0x6C), size) + rom.write_byte(snes_to_pc(0xA2BC00+0x6C), palette) + rom.write_byte(snes_to_pc(0xA2BD00+0x6C), palette) + write_int16(rom, snes_to_pc(0xA2BE00+(0x6C*2)), pal_addr) # sprite author credits padded_author = sprite.author_name if sprite is not None else "Nintendo" @@ -2152,6 +2264,14 @@ def write_strings(rom, world, player, team): " ~~~2020~~~\n Linlinlin\n\n" " ~~~2019~~~\n Kohrek\n" ) + if not world.is_bombshop_start(player): + links_house = 'Links House' + else: + links_house = 'Big Bomb Shop' + links_house = world.get_region(links_house, player) + links_house = next(e for e in links_house.entrances if e.name != 'Links House S&Q') + if 'Snitch Lady' in links_house.name: + tt['kakariko_alert_guards'] = CompressedTextMapper.convert("Hey @! I'm taking your house!\nk.thx.bye") # Let's keep this guy's text accurate to the shuffle setting. if world.shuffle[player] in ['vanilla', 'dungeonsfull', 'dungeonssimple', 'lite', 'lean']: @@ -2270,6 +2390,7 @@ def write_strings(rom, world, player, team): # Next we write a few hints for specific inconvenient locations. We don't make many because in entrance this is highly unpredictable. locations_to_hint = InconvenientLocations.copy() + hinted_locations = [] if world.doorShuffle[player] == 'vanilla': locations_to_hint.extend(InconvenientDungeonLocations) if world.shuffle[player] in ['vanilla', 'dungeonssimple', 'dungeonsfull']: @@ -2287,7 +2408,6 @@ def write_strings(rom, world, player, team): second_item = hint_text(world.get_location('Swamp Palace - West Chest', player).item) first_item = hint_text(world.get_location('Swamp Palace - Big Key Chest', player).item) this_hint = f'The westmost chests in Swamp Palace contain {first_item} and {second_item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Mire Left': if random.randint(0, 1) == 0: first_item = hint_text(world.get_location('Misery Mire - Compass Chest', player).item) @@ -2296,38 +2416,31 @@ def write_strings(rom, world, player, team): second_item = hint_text(world.get_location('Misery Mire - Compass Chest', player).item) first_item = hint_text(world.get_location('Misery Mire - Big Key Chest', player).item) this_hint = f'The westmost chests in Misery Mire contain {first_item} and {second_item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Tower of Hera - Big Key Chest': item = hint_text(world.get_location(location, player).item) this_hint = f'Waiting in the Tower of Hera basement leads to {item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Ganons Tower - Big Chest': item = hint_text(world.get_location(location, player).item) this_hint = f'The big chest in Ganon\'s Tower contains {item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Thieves\' Town - Big Chest': item = hint_text(world.get_location(location, player).item) this_hint = f'The big chest in Thieves\' Town contains {item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Ice Palace - Big Chest': item = hint_text(world.get_location(location, player).item) this_hint = f'The big chest in Ice Palace contains {item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Eastern Palace - Big Key Chest': item = hint_text(world.get_location(location, player).item) this_hint = f'The antifairy guarded chest in Eastern Palace contains {item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Sahasrahla': item = hint_text(world.get_location(location, player).item) this_hint = f'Sahasrahla seeks a green pendant for {item}.' - tt[hint_locations.pop(0)] = this_hint elif location == 'Graveyard Cave': item = hint_text(world.get_location(location, player).item) this_hint = f'The cave north of the graveyard contains {item}.' - tt[hint_locations.pop(0)] = this_hint else: this_hint = f'{location} contains {hint_text(world.get_location(location, player).item)}.' - tt[hint_locations.pop(0)] = this_hint + hinted_locations.append(location) + 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 @@ -2340,9 +2453,10 @@ def write_strings(rom, world, player, team): 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(flute_item, player) - if this_location: + if this_location and this_location not in hinted_locations: this_hint = this_location[0].item.hint_text + ' can be found ' + hint_text(this_location[0]) + '.' this_hint = this_hint[0].upper() + this_hint[1:] + hinted_locations.append(this_location) tt[hint_locations.pop(0)] = this_hint items_to_hint.remove(flute_item) if world.keyshuffle[player] not in ['none', 'nearby', 'universal']: @@ -2358,11 +2472,12 @@ def write_strings(rom, world, player, team): while hint_count > 0 and len(items_to_hint) > 0: this_item = items_to_hint.pop(0) this_location = world.find_items_not_key_only(this_item, player) - if this_location: + if this_location and this_location not in hinted_locations: random.shuffle(this_location) item_name = this_location[0].item.hint_text item_name = item_name[0].upper() + item_name[1:] this_hint = f'{item_name} can be found {hint_text(this_location[0])}.' + hinted_locations.append(this_location) tt[hint_locations.pop(0)] = this_hint hint_count -= 1 @@ -2379,13 +2494,13 @@ def write_strings(rom, world, player, team): for name, district in world.districts[player].items(): hint_type = 'foolish' choices = [] - item_count, item_type = 0, 'useful' + item_count, item_type = 0, 'logic' for loc_name in district.locations: location_item = world.get_location(loc_name, player).item if location_item.advancement: if 'Heart Container' in location_item.name or location_item.compass or location_item.map: continue - itm_type = 'useful' if useful_item_for_hint(location_item, world) else 'vital' + itm_type = 'logic' hint_type = 'path' if item_type == itm_type: choices.append(location_item) @@ -2587,6 +2702,23 @@ def write_strings(rom, world, player, team): tt['ganon_fall_in'] = Ganon1_texts[random.randint(0, len(Ganon1_texts) - 1)] tt['ganon_fall_in_alt'] = 'You cannot defeat me until you finish your goal!' tt['ganon_phase_3_alt'] = 'Got wax in\nyour ears?\nI can not die!' + + def get_custom_goal_text(type): + goal_text = world.custom_goals[player][type]['goaltext'] + placeholder_count = goal_text.count('%d') + if placeholder_count > 0: + targets = [req['target'] for req in world.custom_goals[player][type]['requirements'] if 'target' in req][:placeholder_count] + return goal_text % tuple(targets) + return goal_text + + if world.custom_goals[player]['gtentry'] and 'goaltext' in world.custom_goals[player]['gtentry']: + tt['sign_ganons_tower'] = get_custom_goal_text('gtentry') + if world.custom_goals[player]['ganongoal'] and 'goaltext' in world.custom_goals[player]['ganongoal']: + tt['sign_ganon'] = get_custom_goal_text('ganongoal') + if world.custom_goals[player]['pedgoal'] and 'goaltext' in world.custom_goals[player]['pedgoal']: + tt['mastersword_pedestal_goal'] = get_custom_goal_text('pedgoal') + if world.custom_goals[player]['murahgoal'] and 'goaltext' in world.custom_goals[player]['murahgoal']: + tt['murahdahla'] = get_custom_goal_text('murahgoal') tt['kakariko_tavern_fisherman'] = TavernMan_texts[random.randint(0, len(TavernMan_texts) - 1)] diff --git a/Rules.py b/Rules.py index c548646f..ea14bab8 100644 --- a/Rules.py +++ b/Rules.py @@ -50,9 +50,11 @@ def set_rules(world, player): ow_bunny_rules(world, player) ow_terrain_rules(world, player) + if world.is_premature_copied_world: + return + if world.mode[player] == 'standard': - if not world.is_copied_world: - standard_rules(world, player) + standard_rules(world, player) else: misc_key_rules(world, player) @@ -61,45 +63,50 @@ def set_rules(world, player): drop_rules(world, player) challenge_room_rules(world, player) - if world.goal[player] == 'dungeons': - # require all dungeons to beat ganon - add_rule(world.get_location('Ganon', player), lambda state: state.has_beaten_aga(player) and state.has('Beat Agahnim 2', player) and state.has('Beat Boss', player, 10)) - elif world.goal[player] in ['crystals', 'ganon']: - add_rule(world.get_location('Ganon', player), lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player)) - if world.goal[player] == 'ganon': - # require aga2 to beat ganon - add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player)) - elif world.goal[player] in ['triforcehunt', 'trinity']: - if world.goal[player] == 'trinity': + if world.custom_goals[player]['ganongoal'] and 'requirements' in world.custom_goals[player]['ganongoal']: + rule = get_goal_rule('ganongoal', world, player) + add_rule(world.get_location('Ganon', player), rule) + else: + if world.goal[player] == 'dungeons': + # require all dungeons to beat ganon + add_rule(world.get_location('Ganon', player), lambda state: state.has_beaten_aga(player) and state.has('Beat Agahnim 2', player) and state.has('Beat Boss', player, 10)) + elif world.goal[player] in ['crystals', 'ganon']: add_rule(world.get_location('Ganon', player), lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player)) - for location in world.get_region('Hyrule Castle Courtyard', player).locations: - if location.name == 'Murahdahla': - add_rule(location, lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player])) - elif world.goal[player] == 'ganonhunt': - add_rule(world.get_location('Ganon', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player])) - elif world.goal[player] == 'completionist': - add_rule(world.get_location('Ganon', player), lambda state: state.everything(player)) + if world.goal[player] == 'ganon': + # require aga2 to beat ganon + add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player)) + elif world.goal[player] in ['triforcehunt', 'trinity']: + if world.goal[player] == 'trinity': + add_rule(world.get_location('Ganon', player), lambda state: state.has_crystals(world.crystals_needed_for_ganon[player], player)) + elif world.goal[player] == 'ganonhunt': + add_rule(world.get_location('Ganon', player), lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player])) + elif world.goal[player] == 'completionist': + add_rule(world.get_location('Ganon', player), lambda state: state.everything(player)) + for location in world.get_region('Hyrule Castle Courtyard', player).locations: + if location.name == 'Murahdahla': + if world.custom_goals[player]['murahgoal'] and 'requirements' in world.custom_goals[player]['murahgoal']: + rule = get_goal_rule('murahgoal', world, player) + add_rule(location, rule) + else: + add_rule(location, lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player])) if (world.flute_mode[player] != 'active' and not world.is_tile_swapped(0x18, player) and 'Ocarina (Activated)' not in list(map(str, [i for i in world.precollected_items if i.player == player]))): - if not world.is_copied_world: - # Commented out below, this would be needed for rando implementations where Inverted requires flute activation in bunny territory - # kak_region = self.world.get_region('Kakariko Village', player) - # add_rule(world.get_location('Flute Activation', player), lambda state: state.has('Ocarina', player) and state.is_not_bunny(kak_region, player)) - add_rule(world.get_location('Flute Activation', player), lambda state: state.has('Ocarina', player)) + # Commented out below, this would be needed for rando implementations where Inverted requires flute activation in bunny territory + # kak_region = self.world.get_region('Kakariko Village', player) + # add_rule(world.get_location('Flute Activation', player), lambda state: state.has('Ocarina', player) and state.is_not_bunny(kak_region, player)) + add_rule(world.get_location('Flute Activation', player), lambda state: state.has('Ocarina', player)) # if swamp and dam have not been moved we require mirror for swamp palace if not world.swamp_patch_required[player]: add_rule(world.get_entrance('Swamp Lobby Moat', player), lambda state: state.has_Mirror(player)) - if not world.is_copied_world: - set_bunny_rules(world, player, world.mode[player] == 'inverted') + set_bunny_rules(world, player, world.mode[player] == 'inverted') # These rules go here because they overwrite/add to some of the above rules if world.logic[player] == 'hybridglitches': - if not world.is_copied_world: - underworld_glitches_rules(world, player) + underworld_glitches_rules(world, player) def mirrorless_path_to_location(world, startName, targetName, player): # If Agahnim is defeated then the courtyard needs to be accessible without using the mirror for the mirror offset glitch. @@ -175,6 +182,132 @@ def add_rule(spot, rule, combine='and'): else: spot.access_rule = lambda state: rule(state) and old_rule(state) + +def get_goal_rule(goal_type, world, player): + goal_data = world.custom_goals[player][goal_type] + if goal_data['requirements'][0]['condition'] == 0x00: + return lambda state: False + rule = None + def add_to_rule(new_rule): + nonlocal rule + if rule is None: + rule = new_rule + else: + rule = and_rule(rule, new_rule) + if 'logic' in goal_data: + for logic, data in goal_data['logic'].items(): + if logic == 'pendants': + pendants = int(data) + add_to_rule(lambda state: state.has_pendants(pendants, player)) + elif logic == 'crystals': + crystals = int(data) + add_to_rule(lambda state: state.has_crystals(crystals, player)) + elif logic == 'pendant_bosses': + pendant_bosses = int(data) + add_to_rule(lambda state: state.has_pendant_bosses(pendant_bosses, player)) + elif logic == 'crystal_bosses': + crystal_bosses = int(data) + add_to_rule(lambda state: state.has_crystal_bosses(crystal_bosses, player)) + elif logic == 'bosses': + bosses = int(data) + add_to_rule(lambda state: state.has('Beat Boss', player, bosses)) + elif logic == 'aga1': + add_to_rule(lambda state: state.has('Beat Agahnim 1', player)) + elif logic == 'aga2': + add_to_rule(lambda state: state.has('Beat Agahnim 2', player)) + elif logic == 'goal_items': + if data is not None: + goal_items = int(data) + add_to_rule(lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= goal_items) + else: + add_to_rule(lambda state: state.item_count('Triforce Piece', player) + state.item_count('Power Star', player) >= int(state.world.treasure_hunt_count[player])) + elif logic == 'collection': + if data is not None: + all_locations = [x for x in world.get_filled_locations(player) if not x.locked] + collection = int(data) - len(all_locations) + add_to_rule(lambda state: state.everything(player, collection)) + else: + add_to_rule(lambda state: state.everything(player)) + elif logic == 'item': + for item in data: + item_name = item + if '(' in item_name: + item_name, region_name = item_name.rsplit(' (', 1) + region_name = region_name.rstrip(')') + region = world.get_region(region_name, player) + if region and region.dungeon: + region_name = region.dungeon.name + else: + try: + if world.get_dungeon(region_name, player): + pass + except: + raise Exception(f'Invalid dungeon/region name in custom goal logic for item {item}') + item_name = f'{item_name} ({region_name})' + if '=' in item_name: + item_name, count = item_name.rsplit('=', 1) + count = int(count) + add_to_rule(lambda state: state.has(item_name, player, count)) + else: + add_to_rule(lambda state: state.has(item_name, player)) + elif logic == 'access': + for region_name in data: + region = world.get_region(region_name, player) + if not region: + raise Exception(f'Invalid region name in custom goal logic for region: {region_name}') + add_to_rule(lambda state: state.can_reach(region, None, player)) + elif logic == 'ability': + for ability in data: + param = None + if '(' in ability: + ability, param = ability.split('(', 1) + param = param.rstrip(')') + if ability == 'FarmBombs': + add_to_rule(lambda state: state.can_farm_bombs(player)) + elif ability == 'FarmRupees': + add_to_rule(lambda state: state.can_farm_rupees(player)) + elif ability == 'NoBunny': + if not param: + raise Exception(f'NoBunny ability requires a region argument in custom goal logic') + bunny_region = param + region = world.get_region(bunny_region, player) + if region: + add_to_rule(lambda state: state.is_not_bunny(bunny_region, player)) + else: + raise Exception(f'Invalid region name in custom goal logic for NoBunny ability: {param}') + elif ability == 'CanUseBombs': + add_to_rule(lambda state: state.can_use_bombs(player)) + elif ability == 'CanBonkDrop': + add_to_rule(lambda state: state.can_collect_bonkdrops(player)) + elif ability == 'CanLift': + add_to_rule(lambda state: state.can_lift_rocks(player)) + elif ability == 'MagicExtension': + magic_count = 16 + if param: + magic_count = int(param) + add_to_rule(lambda state: state.can_extend_magic(player, magic_count)) + elif ability == 'CanStun': + add_to_rule(lambda state: state.can_stun_enemies(player)) + elif ability == 'CanKill': + if param: + enemy_count = int(param) + add_to_rule(lambda state: state.can_kill_most_things(player, enemy_count)) + else: + add_to_rule(lambda state: state.can_kill_most_things(player)) + elif ability == 'CanShootArrows': + add_to_rule(lambda state: state.can_shoot_arrows(player)) + elif ability == 'CanFlute': + add_to_rule(lambda state: state.can_flute(player)) + elif ability == 'HasFire': + add_to_rule(lambda state: state.has_fire_source(player)) + elif ability == 'CanMelt': + add_to_rule(lambda state: state.can_melt_things(player)) + elif ability == 'HasMMMedallion': + add_to_rule(lambda state: state.has_misery_mire_medallion(player)) + elif ability == 'HasTRMedallion': + add_to_rule(lambda state: state.has_turtle_rock_medallion(player)) + return rule if rule is not None else lambda state: True + def add_bunny_rule(spot, player): if spot.can_cause_bunny(player): add_rule(spot, lambda state: state.has_Pearl(player)) @@ -189,7 +322,7 @@ def and_rule(rule1, rule2): def add_lamp_requirement(spot, player): - add_rule(spot, lambda state: state.world.dark_rooms[player] not in ['require_lamp'] or state.has('Lamp', player, state.world.lamps_needed_for_dark_rooms)) + add_rule(spot, lambda state: state.world.dark_rooms[player] not in ['require_lamp'] or state.has('Lamp', player)) def forbid_item(location, item, player): @@ -244,7 +377,11 @@ def global_rules(world, player): set_rule(world.get_entrance('Flute Spot 8', player), lambda state: state.can_flute(player)) # overworld location rules - set_rule(world.get_location('Master Sword Pedestal', player), lambda state: state.has('Red Pendant', player) and state.has('Blue Pendant', player) and state.has('Green Pendant', player)) + if world.custom_goals[player]['pedgoal'] and 'requirements' in world.custom_goals[player]['pedgoal']: + rule = get_goal_rule('pedgoal', world, player) + set_rule(world.get_location('Master Sword Pedestal', player), rule) + else: + set_rule(world.get_location('Master Sword Pedestal', player), lambda state: state.has('Red Pendant', player) and state.has('Blue Pendant', player) and state.has('Green Pendant', player)) set_rule(world.get_location('Ether Tablet', player), lambda state: state.has('Book of Mudora', player) and state.has_beam_sword(player)) set_rule(world.get_location('Old Man', player), lambda state: state.has('Return Old Man', player)) set_rule(world.get_location('Old Man Drop Off', player), lambda state: state.has('Escort Old Man', player)) @@ -261,7 +398,7 @@ def global_rules(world, player): # bonk items if world.shuffle_bonk_drops[player]: - if not world.is_copied_world: + if not world.is_premature_copied_world: from Regions import bonk_prize_table for location_name, (_, _, aga_required, _, _, _) in bonk_prize_table.items(): loc = world.get_location(location_name, player) @@ -412,9 +549,13 @@ def global_rules(world, player): set_rule(world.get_entrance('Misery Mire', player), lambda state: state.has_sword(player) and state.has_misery_mire_medallion(player)) # sword required to cast magic (!) set_rule(world.get_entrance('Turtle Rock', player), lambda state: state.has('Turtle Opened', player)) + if world.custom_goals[player]['gtentry'] and 'requirements' in world.custom_goals[player]['gtentry']: + rule = get_goal_rule('gtentry', world, player) + set_rule(world.get_entrance('Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', player), rule) + else: + set_rule(world.get_entrance('Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) if not world.is_atgt_swapped(player): set_rule(world.get_entrance('Agahnims Tower', player), lambda state: state.has('Cape', player) or state.has_beam_sword(player)) - set_rule(world.get_entrance('Ganons Tower' if not world.is_atgt_swapped(player) else 'Agahnims Tower', player), lambda state: state.has_crystals(world.crystals_needed_for_gt[player], player)) # Start of door rando rules # TODO: Do these need to flag off when door rando is off? - some of them, yes @@ -841,7 +982,7 @@ def global_rules(world, player): add_key_logic_rules(world, player) - if world.logic[player] == 'hybridglitches' and not world.is_copied_world: + if world.logic[player] == 'hybridglitches' and not world.is_premature_copied_world: add_hmg_key_logic_rules(world, player) # End of door rando rules. @@ -1041,13 +1182,14 @@ def drop_rules(world, player): for super_tile, enemy_list in data_tables.uw_enemy_table.room_map.items(): for enemy in enemy_list: if enemy.location: - rule = defeat_rule_single(world, player, enemy, enemy.location.parent_region) - if enemy.location.parent_region.name in special_rules_check: - rule = special_rules_for_region(world, player, enemy.location.parent_region.name, - enemy.location, rule) + true_location = world.get_location(enemy.location.name, player) + rule = defeat_rule_single(world, player, enemy, true_location.parent_region) + if true_location.parent_region.name in special_rules_check: + rule = special_rules_for_region(world, player, true_location.parent_region.name, + true_location, rule) if rule.rule_lambda is None: raise Exception(f'Bad rule for enemy drop. Need to inspect this case: {hex(enemy.kind)}') - add_rule_new(enemy.location, rule) + add_rule_new(true_location, rule) def ow_inverted_rules(world, player): @@ -1355,7 +1497,7 @@ def no_glitches_rules(world, 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('Ice Lake Northeast Pier Hop', player), lambda state: False) forbid_bomb_jump_requirements(world, player) - if not world.is_copied_world: + if not world.is_premature_copied_world: add_conditional_lamps(world, player) @@ -1666,17 +1808,20 @@ def standard_rules(world, player): add_rule(world.get_entrance(entrance, player), lambda state: state.has('Zelda Delivered', player)) if world.shuffle_bonk_drops[player]: - if not world.is_copied_world: + if not world.is_premature_copied_world: add_rule(world.get_location('Hyrule Castle Tree', player), lambda state: state.has('Zelda Delivered', player)) add_rule(world.get_location('Central Bonk Rocks Tree', player), lambda state: state.has('Zelda Delivered', player)) + if not world.is_premature_copied_world: + add_rule(world.get_location('Hyrule Castle Courtyard Tree Pull', player), lambda state: state.has('Zelda Delivered', player)) + # don't allow bombs to get past here before zelda is rescued set_rule(world.get_entrance('GT Hookshot South Entry to Ranged Crystal', player), lambda state: (state.can_use_bombs(player) and state.has('Zelda Delivered', player)) or state.has('Blue Boomerang', player) or state.has('Red Boomerang', player)) # or state.has('Cane of Somaria', player)) def find_rules_for_zelda_delivery(world, player): # path rules for backtracking - start_region = world.get_region('Hyrule Dungeon Cellblock', player) + start_region = world.get_region(world.default_zelda_region[player], player) queue = deque([(start_region, [], [])]) visited = {start_region} blank_state = CollectionState(world) @@ -2133,6 +2278,9 @@ def eval_small_key_door_partial_main(state, door_name, dungeon, player): number = min(number, door_rule.alternate_small_key) door_openable |= state.has_sm_key(key_logic.small_key_name, player, number) break + if state.placing_items and any(lock_item == item.name for item in state.placing_items): + number = min(number, door_rule.alternate_small_key) + door_openable |= state.has_sm_key(key_logic.small_key_name, player, number) return door_openable diff --git a/Tables.py b/Tables.py index 33e1e230..5272f586 100644 --- a/Tables.py +++ b/Tables.py @@ -147,101 +147,140 @@ bonk_prize_lookup = { 'Fairy': (0xe3, 15, None) } -# item name: (custom gfx, address offset, palette) +# item name: (custom gfx, address offset, palette, palette address, size) # decompressed gfx loaded at $7F8000 # custom gfx loaded at $228000 item_gfx_table = { - 'Green Rupees (20)': (False, 0x0000, 0x04), - 'Pegasus Boots': (False, 0x0040, 0x01), - 'Psuedoboots': (False, 0x0040, 0x02), - 'Blue Pendant': (False, 0x0080, 0x02), - 'Red Pendant': (False, 0x0080, 0x01), - 'Warp Tile': (False, 0x00C0, 0x04), - 'Open Chest': (False, 0x0100, 0x02), - 'Chicken': (False, 0x0140, 0x04), - 'Duck': (False, 0x0180, 0x01), - 'Chest': (False, 0x0400, 0x02), - 'Frog': (False, 0x0440, 0x04), - 'Kiki (Head)': (False, 0x0480, 0x04), - 'Purple Chest': (False, 0x0500, 0x04), - 'Super Bomb': (False, 0x0540, 0x04), - 'Blacksmith': (False, 0x0580, 0x04), - 'Bug Net': (False, 0x0860, 0x01), - 'Crystal': (False, 0x08A0, 0x06), - 'Silver Arrows': (False, 0x08E0, 0x01), - 'Bow': (False, 0x0920, 0x02), - 'Bottle (Fairy)': (False, 0x0960, 0x02), - 'Bottle (Bee)': (False, 0x09A0, 0x02), - 'Piece of Heart': (False, 0x0C00, 0x01), - 'Ocarina': (False, 0x0C40, 0x02), - 'Mirror Shield': (False, 0x0C80, 0x04), - 'Rupees (100)': (False, 0x0D20, 0x04), - 'Rupees (50)': (False, 0x0D60, 0x04), - 'Rupees (300)': (False, 0x0DA0, 0x04), - 'Flippers': (False, 0x1000, 0x02), - 'Mirror': (False, 0x1040, 0x02), - 'Bomb': (False, 0x1080, 0x02), - 'Lamp': (False, 0x10C0, 0x01), - 'Psuedolamp': (False, 0x10C0, 0x02), - 'Magic Cape': (False, 0x1100, 0x01), - 'Compass': (False, 0x1140, 0x02), - 'Moon Pearl': (False, 0x1180, 0x01), - 'Ether': (False, 0x1400, 0x04), - 'Bombos': (False, 0x1440, 0x04), - 'Quake': (False, 0x1480, 0x04), - 'Bottle': (False, 0x14C0, 0x01), - 'Bottle (Red Potion)': (False, 0x1500, 0x01), - 'Bottle (Green Potion)': (False, 0x1500, 0x04), - 'Bottle (Blue Potion)': (False, 0x1500, 0x02), - 'Mushroom': (False, 0x1540, 0x04), - 'Map': (False, 0x1580, 0x04), - 'Big Key': (False, 0x15C0, 0x04), - 'Bombs (3)': (False, 0x1840, 0x02), - 'Arrows (10)': (False, 0x1880, 0x02), - 'Heart Container': (False, 0x18C0, 0x01), - 'Green Mail': (False, 0x1900, 0x04), - 'Blue Mail': (False, 0x1900, 0x02), - 'Red Mail': (False, 0x1900, 0x01), - 'Fire Sheild': (False, 0x1980, 0x04), - 'Blue Shield': (False, 0x19C0, 0x02), - 'Magic Powder': (False, 0x1CC0, 0x02), - 'Bombs (10)': (False, 0x1D00, 0x02), - 'Power Glove': (False, 0x1D40, 0x01), - 'Titans Mitts': (False, 0x1D40, 0x04), - 'Book of Mudora': (False, 0x1D80, 0x04), - 'Maiden (Head)': (False, 0x2000, 0x04), - 'Zelda (Head)': (False, 0x2080, 0x04), - 'Old Man (Head)': (False, 0x2140, 0x04), - 'Locksmith (Head)': (False, 0x2180, 0x04), - 'Fire': (False, 0x25C0, 0x04), - 'Apples': (False, 0x30A0, 0x04), - 'Fairy': (False, 0x3140, 0x01), - 'Whirlpool': (False, 0x31C0, 0x01), + 'Green Rupees (20)': (False, 0x0000, 0x04, 0x0000, 2), + 'Pegasus Boots': (False, 0x0040, 0x01, 0x0000, 2), + 'Psuedoboots': (False, 0x0040, 0x02, 0x0000, 2), + 'Blue Pendant': (False, 0x0080, 0x02, 0x0000, 2), + 'Red Pendant': (False, 0x0080, 0x01, 0x0000, 2), + 'Warp Tile': (False, 0x00C0, 0x04, 0x0000, 2), + 'Open Chest': (False, 0x0100, 0x02, 0x0000, 2), + 'Chicken': (False, 0x0140, 0x04, 0x0000, 2), + 'Duck': (False, 0x0180, 0x01, 0x0000, 2), + 'Chest': (False, 0x0400, 0x02, 0x0000, 2), + 'Frog': (False, 0x0440, 0x04, 0x0000, 2), + 'Kiki (Head)': (False, 0x0480, 0x04, 0x0000, 2), + 'Purple Chest': (False, 0x0500, 0x04, 0x0000, 2), + 'Super Bomb': (False, 0x0540, 0x04, 0x0000, 2), + 'Blacksmith': (False, 0x0580, 0x04, 0x0000, 2), + 'Bug Net': (False, 0x0860, 0x01, 0x0000, 2), + 'Crystal': (False, 0x08A0, 0x86, 0xB240, 2), + 'Silver Arrows': (False, 0x08E0, 0x01, 0x0000, 2), + 'Progressive Bow': (False, 0x0920, 0x02, 0x0000, 2), + 'Bottle (Fairy)': (False, 0x0960, 0x02, 0x0000, 2), + 'Bottle (Bee)': (False, 0x09A0, 0x02, 0x0000, 2), + 'Piece of Heart': (False, 0x0C00, 0x01, 0x0000, 2), + 'Ocarina': (False, 0x0C40, 0x02, 0x0000, 2), + 'Mirror Shield': (False, 0x0C80, 0x80, 0xB230, 2), + 'Rupees (100)': (False, 0x0D20, 0x04, 0x0000, 2), + 'Rupees (50)': (False, 0x0D60, 0x04, 0x0000, 2), + 'Rupees (300)': (False, 0x0DA0, 0x04, 0x0000, 2), + 'Flippers': (False, 0x1000, 0x02, 0x0000, 2), + 'Magic Mirror': (False, 0x1040, 0x02, 0x0000, 2), + 'Bomb': (False, 0x1080, 0x02, 0x0000, 2), + 'Lamp': (False, 0x10C0, 0x01, 0x0000, 2), + 'Psuedolamp': (False, 0x10C0, 0x02, 0x0000, 2), + 'Magic Cape': (False, 0x1100, 0x01, 0x0000, 2), + 'Compass': (False, 0x1140, 0x02, 0x0000, 2), + 'Moon Pearl': (False, 0x1180, 0x01, 0x0000, 2), + 'Ether': (False, 0x1400, 0x04, 0x0000, 2), + 'Bombos': (False, 0x1440, 0x04, 0x0000, 2), + 'Quake': (False, 0x1480, 0x04, 0x0000, 2), + 'Bottle': (False, 0x14C0, 0x01, 0x0000, 2), + 'Bottle (Red Potion)': (False, 0x1500, 0x01, 0x0000, 2), + 'Bottle (Green Potion)': (False, 0x1500, 0x04, 0x0000, 2), + 'Bottle (Blue Potion)': (False, 0x1500, 0x02, 0x0000, 2), + 'Mushroom': (False, 0x1540, 0x04, 0x0000, 2), + 'Map': (False, 0x1580, 0x04, 0x0000, 2), + 'Big Key': (False, 0x15C0, 0x04, 0x0000, 2), + 'Green Potion': (False, 0x1800, 0x04, 0x0000, 2), + 'Blue Potion': (False, 0x1800, 0x02, 0x0000, 2), + 'Red Potion': (False, 0x1800, 0x01, 0x0000, 2), + 'Bombs (3)': (False, 0x1840, 0x02, 0x0000, 2), + 'Arrows (10)': (False, 0x1880, 0x02, 0x0000, 2), + 'Heart Container': (False, 0x18C0, 0x01, 0x0000, 2), + 'Heart Container (Green)': (False, 0x18C0, 0x04, 0x0000, 2), + 'Heart Container (Blue)': (False, 0x18C0, 0x02, 0x0000, 2), + 'Green Mail': (False, 0x1900, 0x04, 0x0000, 2), + 'Blue Mail': (False, 0x1900, 0x02, 0x0000, 2), + 'Red Mail': (False, 0x1900, 0x01, 0x0000, 2), + 'Fire Shield': (False, 0x1940, 0x80, 0xB220, 2), + 'Blue Shield': (False, 0x19C0, 0x02, 0x0000, 2), + 'Magic Powder': (False, 0x1CC0, 0x02, 0x0000, 2), + 'Bombs (10)': (False, 0x1D00, 0x02, 0x0000, 2), + 'Power Glove': (False, 0x1D40, 0x01, 0x0000, 2), + 'Titans Mitt': (False, 0x1D40, 0x04, 0x0000, 2), + 'Book of Mudora': (False, 0x1D80, 0x04, 0x0000, 2), + 'Maiden (Head)': (False, 0x2000, 0x04, 0x0000, 2), + 'Zelda (Head)': (False, 0x2080, 0x04, 0x0000, 2), + 'Old Man (Head)': (False, 0x2140, 0x04, 0x0000, 2), + 'Locksmith (Head)': (False, 0x2180, 0x04, 0x0000, 2), + 'Fire': (False, 0x25C0, 0x04, 0x0000, 2), + 'Apples': (False, 0x30A0, 0x04, 0x0000, 2), + 'Fairy': (False, 0x3140, 0x01, 0x0000, 2), + 'Whirlpool': (False, 0x31C0, 0x02, 0x0000, 2), - 'Triforce': (True, 0x0060, 0x04), - 'Fighter Sword': (True, 0x00A0, 0x02), - 'Master Sword': (True, 0x00E0, 0x02), - 'Tempered Sword': (True, 0x0120, 0x01), - 'Golden Sword': (True, 0x0160, 0x04), - 'Half Magic': (True, 0x01A0, 0x04), - 'Quarter Magic': (True, 0x01E0, 0x04), - 'Bomb Upgrade (+5)': (True, 0x0420, 0x04), - 'Bomb Upgrade (+10)': (True, 0x0460, 0x04), - 'Bomb Upgrade (50)': (True, 0x04A0, 0x04), - 'Bombbag': (True, 0x04E0, 0x02), - 'Arrow Upgrade (+5)': (True, 0x0520, 0x02), - 'Arrow Upgrade (+10)': (True, 0x0560, 0x02), - 'Arrows (70)': (True, 0x05A0, 0x02), - 'Silver Arrows (Ag)': (True, 0x05E0, 0x01), - 'Green Pendant': (True, 0x0820, 0x04), - 'Sword and Shield': (True, 0x0860, 0x02), - 'Green Potion': (True, 0x08A0, 0x04), - 'Blue Potion': (True, 0x08E0, 0x02), - 'Red Potion': (True, 0x0920, 0x01), - 'Bee Trap': (True, 0x0960, 0x02), - 'Red Crystal': (True, 0x0C60, 0x01), - 'Egg': (True, 0x1020, 0x02), - 'Master Key': (True, 0x1060, 0x02), - 'Lumberjack (Head)': (True, 0x11A0, 0x02), - 'Power Star': (True, 0x11E0, 0x04), + 'Nothing': (True, 0x0020, 0x01, 0x0000, 2), + 'Triforce': (True, 0x0060, 0x04, 0x0000, 2), + 'Fighter Sword': (True, 0x00A0, 0x02, 0x0000, 2), + 'Master Sword': (True, 0x00E0, 0x02, 0x0000, 2), + 'Tempered Sword': (True, 0x0120, 0x01, 0x0000, 2), + 'Golden Sword': (True, 0x0160, 0x04, 0x0000, 2), + 'Half Magic': (True, 0x01A0, 0x04, 0x0000, 2), + 'Quarter Magic': (True, 0x01E0, 0x04, 0x0000, 2), + 'Bomb Upgrade (+5)': (True, 0x0420, 0x04, 0x0000, 2), + 'Bomb Upgrade (+10)': (True, 0x0460, 0x04, 0x0000, 2), + 'Bomb Upgrade (50)': (True, 0x04A0, 0x04, 0x0000, 2), + 'Bombbag': (True, 0x04E0, 0x02, 0x0000, 2), + 'Arrow Upgrade (+5)': (True, 0x0520, 0x02, 0x0000, 2), + 'Arrow Upgrade (+10)': (True, 0x0560, 0x02, 0x0000, 2), + 'Arrow Upgrade (70)': (True, 0x05A0, 0x02, 0x0000, 2), + 'Silver Arrows (Ag)': (True, 0x05E0, 0x01, 0x0000, 2), + 'Green Pendant': (True, 0x0820, 0x04, 0x0000, 2), + 'Sword and Shield': (True, 0x0860, 0x02, 0xD244, 2), + 'Green Potion (G)': (True, 0x08A0, 0x04, 0x0000, 2), + 'Blue Potion (B)': (True, 0x08E0, 0x02, 0x0000, 2), + 'Red Potion (R)': (True, 0x0920, 0x01, 0x0000, 2), + 'Bee Trap': (True, 0x0960, 0x02, 0x0000, 2), + 'Red Crystal': (True, 0x0C60, 0x01, 0x0000, 2), + 'Green Clock': (True, 0x0DE0, 0x04, 0x0000, 2), + 'Blue Clock': (True, 0x0DE0, 0x02, 0x0000, 2), + 'Red Clock': (True, 0x0DE0, 0x01, 0x0000, 2), + 'Egg': (True, 0x1020, 0x02, 0x0000, 2), + 'Master Key': (True, 0x1060, 0x02, 0x0000, 2), + 'Lumberjack (Head)': (True, 0x11A0, 0x02, 0x0000, 2), + 'Power Star': (True, 0x11E0, 0x04, 0x0000, 2), + + # Thin GFX + 'Rupee (1)': (False, 0x0800, 0x04, 0x0000, 0), + 'Rupees (5)': (False, 0x0800, 0x02, 0x0000, 0), + 'Rupees (20)': (False, 0x0800, 0x01, 0x0000, 0), + 'Blue Shield (Thin)': (False, 0x09E0, 0x02, 0x0000, 0), + 'Heart': (False, 0x0CC0, 0x01, 0x0000, 0), + 'Heart (Green)': (False, 0x0CC0, 0x04, 0x0000, 0), + 'Heart (Blue)': (False, 0x0CC0, 0x02, 0x0000, 0), + 'Small Magic': (False, 0x0CE0, 0x04, 0x0000, 0), + 'Arrow': (False, 0x0D00, 0x02, 0x0000, 0), + 'Nothing (Thin)': (False, 0x0DE0, 0x01, 0x0000, 0), + 'Master Sword (Thin)': (False, 0x11C0, 0x05, 0x0000, 0), + 'Tempered Sword (Thin)': (False, 0x11C0, 0x01, 0x0000, 0), + 'Golden Sword (Thin)': (False, 0x11C0, 0x04, 0x0000, 0), + 'Shovel': (False, 0x11E0, 0x01, 0x0000, 0), + 'Bow': (False, 0x1C00, 0x01, 0x0000, 0), + 'Fighter Sword (Thin)': (False, 0x1C20, 0x02, 0x0000, 0), + 'Somaria': (False, 0x1C40, 0x01, 0x0000, 0), + 'Byrna': (False, 0x1C40, 0x02, 0x0000, 0), + 'Hookshot': (False, 0x1C60, 0x01, 0x0000, 0), + 'Fire Rod': (False, 0x1C80, 0x01, 0x0000, 0), + 'Ice Rod': (False, 0x1C80, 0x02, 0x0000, 0), + 'Hammer': (False, 0x1CA0, 0x01, 0x0000, 0), + 'Small Key': (False, 0x1DC0, 0x04, 0x0000, 0), + 'Boomerang': (False, 0x1DE0, 0x02, 0x0000, 0), + 'Red Boomerang': (False, 0x1DE0, 0x01, 0x0000, 0), + + 'Full Magic': (True, 0x01A0, 0x04, 0x0000, 0), } + \ No newline at end of file diff --git a/Text.py b/Text.py index eb7af9b6..0cec5777 100644 --- a/Text.py +++ b/Text.py @@ -192,7 +192,7 @@ Blind_texts = [ "Gloves open\na handful\nof checks", "Red mail?\nReturn to\nsender.", "For sale:\nBaby boots,\nNever found", - "SRL or rtGG?\nI prefer the\nLadder", + "SRL or rtGG?\nI prefer the\nStepladder", "Ladders are\nalways up\nto something", "Zelda's\nfashion is\nvery chic", "Zombie geese\nare waterfoul.\n", @@ -1789,6 +1789,8 @@ class TextTable(object): text['hylian_text_2'] = CompressedTextMapper.convert("%%^= %==%\n ^ =%^=\n==%= ^^%^") text['desert_entry_translated'] = CompressedTextMapper.convert("Kneel before this stone, and magic will move around you.") text['telepathic_tile_under_ganon'] = CompressedTextMapper.convert("Doors Async League winners\n{HARP}\n" + " ~~~2025~~~\nSchulzer\n\n" + " ~~~2024~~~\nhumbugh\n\n" " ~~~2023~~~\nEriror\n\n" " ~~~2022~~~\nAndy\n\n" " ~~~2021~~~\nprdwong") @@ -1802,7 +1804,8 @@ class TextTable(object): text['telepathic_tile_ice_stalfos_knights_room'] = CompressedTextMapper.convert("{NOBORDER}\nKnock 'em down and then bomb them dead.") text['telepathic_tile_tower_of_hera_entrance'] = CompressedTextMapper.convert("{NOBORDER}\nThis is a bad place, with a guy who will make you fall…\n\n\na lot.") text['houlihan_room'] = CompressedTextMapper.convert("Randomizer tournament winners\n{HARP}\n" - " ~~~2023~~~\nnGanonsGoneWild\n\n" + " ~~~2024~~~\nGammachuu\n\n" + " ~~~2023~~~\nGanonsGoneWild\n\n" " ~~~2022~~~\nObscure\n\n" " ~~~2021~~~\nDaaanty\n\n" " ~~~2019~~~\nJet082\n\n" @@ -2036,6 +2039,7 @@ class TextTable(object): text['ganon_phase_3_alt'] = CompressedTextMapper.convert("Got wax in your ears? I cannot die!") # 190 text['sign_east_death_mountain_bridge'] = CompressedTextMapper.convert("Glitched\ntournament\nwinners\n{HARP}\n" + "~~~HMG 2025~~~\nSkele\n" "~~~No Logic 2024~~~\ntam\n\n" "~~~HMG 2023~~~\ntam\n\n" "~~~No Logic 2022~~~\nChexhuman\n\n" @@ -2050,5 +2054,6 @@ class TextTable(object): text['ganon_phase_3_no_silvers'] = CompressedTextMapper.convert("You can't best me without silver arrows!") text['ganon_phase_3_silvers'] = CompressedTextMapper.convert("Oh no! Silver! My one true weakness!") text['murahdahla'] = CompressedTextMapper.convert("Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n{PAUSE3}\n… … …\nWait! You can see me? I knew I should have\nhidden in a hollow tree.") + text['mastersword_pedestal_goal'] = CompressedTextMapper.convert("To claim thy reward, you must present all 3 Pendants of Virtue.") text['end_pad_data'] = bytearray([0xfb]) text['terminator'] = bytearray([0xFF, 0xFF]) diff --git a/asm/asm_investigations.txt b/asm/asm_investigations.txt deleted file mode 100644 index 9d0cce24..00000000 --- a/asm/asm_investigations.txt +++ /dev/null @@ -1,213 +0,0 @@ - -Dungeon_InterRoomTrans 7.2 -> (01) -> Dungeon_LoadRoom - Dungeon_InitStarTileCh - **Load and and Prep Here - Dungeon_ResetSprites -$028908 (PC: 10908) is the jump tample - -hook points 7.2.1 -22 32 f4 a0 -$028961 (PC: 10961) 22 a4 fd 00 -22 39 d7 00 -e6 b0 -9c 00 02 -a5 a2 -48 -a5 a0 - - - - -Modules 04 and 05 skip the PaletteFiltering right above it - moving the pointers slightly might help - didn't help -mostly for the black fade out - -60 a5 b0 c9 07 90 ?? ?? -jsl ?? ?? ?? -jsl ?? ?? ?? -jsl 07 ?? ?? -lda b0 -jsl 00 ?? ?? -pointers!!! -SpiralStaircase - (00) 290C6 - (01) 28B7A - (02) 28FA3 -> Fixed Color see 110A1-$110C6 JUMP LOCATION in Bank02 e944 is PaletteFiltering (Fade out!) (.doFiltering) - (03) 28BE4 -> Dungeon_LoadRoom, Dungeon_InitStarTileChr, LoadTransAuxGfx, Dungeon_LoadCustomTileAttr - (04) 28D11 -> PrepTransAuxGfx - (05) 28D1F -> Sets $17 to #$0A - (06) 28C12 -> Dungeon_ResetSprites - - these guys called each other a ton - c9* b5 ca* b5* ca* b1* b5 c6* ca b1* b5 c6* ca 96--------- - (07) 28FC9 -> 5 jumps in here, sets $a4 floor - 112B1 -> may be related to straight staircase only - 13B7B - 135DC - 10EC9 - 10AB3 - right before b5 - - (08) 289CA -> calls $113F (above .copyTilemap in Bank 00) - (09) 289B5 -> calls $11C4 (updates all tiles in a room) - (0a) 289CA -> go through the tilemap.... - (0b) 289B1 -> runs a filter - new color?, then $11C4 (didn't see call to 289B5) - (0c) 289C6 -> runs a filter then $113F - (0d) 289B1 -> repeat last two steps - (0e) 289C6 - (0f) 28F96 -> Fade in - - (10) 2905D - (11) 2909D - (12) 290B7 - (13) 290DF -SpiralStaircase -> (03) 10CE2 -> Dungeon_LoadRoom - Dungeon_InitStarTileChr - LoadTransAuxGfx - Dungeon_LoadCustomTileAttr - (04) 10E0F -> PrepTransAuxGfx - (06) 10D10 -> Dungeon_ResetSprites - - -; Upward floor transition -Dungeon -> x06 -> $10C14 -> 10CE2 -> Dungeon_LoadRoom - Dungeon_InitStarTileChr - LoadTransAuxGfx - Dungeon_LoadCustomTileAttr - 10E0F -> PrepTransAuxGfx - 10D10 -> Dungeon_ResetSprites - -; Downward floor transition -Dungeon -> x07 -> $10E27 -> 10CE2 -> Dungeon_LoadRoom - Dungeon_InitStarTileChr - LoadTransAuxGfx - Dungeon_LoadCustomTileAttr - 10E0F -> PrepTransAuxGfx - 10D10 -> Dungeon_ResetSprites - - -StraightStairs_2 -> Dungeon_LoadRoom - -> LoadTransAuxGfx -StraightStairs_3 -> 10E0F -> PrepTransAuxGfx -StraightStairs_4 -> Dungeon_ResetSprites - - -Dungeon_Teleport -> 10CE2 -> Dungeon_LoadRoom - 10CE2 -> LoadTransAuxGfx - 10D10 -> Dungeon_ResetSprites - - - -Hook points -org $00d6ae (PC: 56ae) -LoadTransAuxGfx -8b 4b ab 64 00 - -org $00df5a (PC: 5f5a) -PrepTransAuxGfx -a9 7e 85 02 85 05 c2 31 - -org $0ffd65 (PC: 07fd65) -Dungeon_LoadCustomTileAttr -8b 4b ab c2 30 ad A2 0A 29 FF 00 - -Palette_DungBgMain -c2 21 ae b6 0a bf 1b -; This is the palette index for a certain background - LDX $0AB6 - - LDA $1BEC4B, X : ADC.w #$D734 : STA $00 : PHA - - REP #$10 - - LDA.w #$0042 ; Target BP-2 through BP-7 (full) - LDX.w #$000E ; (Length - 1) (in words) of the palettes. - LDY.w #$0005 - - - -Trap doors: - -0468 - flag is set when doors are down (1 = down? 0 = up?) -$690 - 7 for open - 0 for down - -IntraRoom: -> -Dungeon_IntraRoomTransShutDoors (maybe should be Open) -stz $0468 -#$07 -> $0690 - -Dungeon_IntraRoomTransOpenDoors (maybe should be Shut) - -10D71 -> A -A -> 0468 -0468++ -0 -> 0690 - -InterRoom: - -pre -01b6b5 sta $0468 (01) in this case -01b7ce stz 468 x2 -post -028acc inc $0468 -028ad2 stz $0690 -01d391 inc $0690 x 10 during animation - - -Other transition stuff - -Overworld_LoadTransGfx -> LoadTransAuxGfx -Overworld_LoadTransGfx -> PrepTransAuxGfx -Module_LoadFile -> Dungeon_ResetSprites -Module_HoleToDungeon -> 10D10 -> Dungeon_ResetSprites - - - - -Camera work: -Places where sta $e2 happens -02ba5d 13A31 - - -028750 Module_Dungeon -0286ef Module_Dungeon - - -Stuff about big key door south - 1e -> Y - this is at 00ce24 or pc 004e24 - org 00ce24 - dw 2ac8 - 1aab1 ldx ce06,y (where y is 1e = ce24) loads 2a80, but should be 2ac8 for the gfx - not detected as big key door - need to look into tile attributes - -extraneous keydoors -$5b - GT 91 idx 0 -$99 - EP 153 idx 1 -$a2 - MM 162 idx 0 -$a8 - EP 168 idx 2 -$bc - TT 188 idx 1 - -;SRAM corruption investigation -;call stack -; 110c7 7.e.7 (Dungeon_SpiralStaircase_7) -; 112b1 - -; dw $8CE2 ; = $10CE2* -; dw $8E0F ; = $10E0F* -; dw $8E1D ; = $10E1D* -; dw $8D10 ; = $10D10* -; dw $90C7 ; = $110C7* - -;bank2 line 3323 - x is d422 - comes from 048c - -; called by 10CE2, (Dungeon_SpiralStaircase_3) -;122f0 - - -Link's position after screen transition and auto-walk (from $02C034): - -0C 20 30 38 48 ; down -D4 D8 C0 C0 A8 ; up -0C 18 28 30 40 ; right -E4 D8 C8 C0 B0 ; left - -Effectively indexed by $0418*#$05+$4E. -Row ($0418) is the direction and column ($4E) determines how far to auto-walk (depends on tile attribute at edge of screen). -From left to right: edge, inside high door, outside high door, inside low door and outside low door. diff --git a/asm/doorrando.asm b/asm/doorrando.asm deleted file mode 100644 index 346b943c..00000000 --- a/asm/doorrando.asm +++ /dev/null @@ -1,47 +0,0 @@ -!add = "clc : adc" -!addl = "clc : adc.l" -!sub = "sec : sbc" -!bge = "bcs" -!blt = "bcc" - -; Free RAM notes -; Normal doors use $AB-AC for scrolling indicator -; Normal doors use $FE to store the trap door indicator -; Normal doors use $045e to store Y coordinate when transitioning to in-room stairs -; Normal doors use $045f to determine the order in which supertile quadrants are drawn -; Straight stairs use $046d to store X coordinate on animation start -; Spiral doors use $045e to store stair type -; Gfx uses $b1 to for sub-sub-sub-module thing - -; Hooks into various routines -incsrc drhooks.asm - -;Main Code -org $278000 ;138000 -db $44, $52 ;DR -DRMode: -dw 0 -DRFlags: -dw 0 -DRScroll: -db 0 -OffsetTable: -dw -8, 8 - -incsrc normal.asm -incsrc scroll.asm -incsrc spiral.asm -incsrc gfx.asm -incsrc keydoors.asm -incsrc overrides.asm -incsrc edges.asm -incsrc math.asm -incsrc hudadditions.asm -incsrc dr_lobby.asm -warnpc $279C00 - -incsrc doortables.asm -warnpc $288000 - -; deals with own hooks -incsrc owrando.asm diff --git a/asm/doortables.asm b/asm/doortables.asm deleted file mode 100644 index 90678ca3..00000000 --- a/asm/doortables.asm +++ /dev/null @@ -1,696 +0,0 @@ -org $279C00 -KeyDoorOffset: -; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler -dw $0000,$0001,$0003,$0000,$0006,$0000,$000b,$0000,$0000,$0000,$000c,$000d,$0010,$0011,$0012,$0000 -dw $0000,$0015,$0018,$001c,$001e,$0025,$0027,$0000,$0000,$002b,$002d,$0033,$0035,$0038,$0039,$003d -dw $003f,$0040,$0043,$0045,$0047,$0000,$004f,$0000,$0053,$0000,$0055,$005b,$0000,$0000,$005f,$0000 -dw $0060,$0062,$0064,$0065,$0066,$0068,$006e,$0074,$007a,$007c,$007e,$0081,$0000,$0082,$0086,$0088 -dw $0089,$008a,$0000,$008b,$008e,$0092,$0096,$0000,$0000,$0099,$009d,$00a2,$00a5,$00a6,$00a8,$00aa -dw $00ab,$00ad,$00af,$00b2,$0000,$0000,$00b5,$00b9,$00bf,$00c5,$00c9,$00ca,$00cc,$00ce,$00d1,$00d5 -dw $00d6,$00dc,$00e3,$00e9,$00ec,$00ed,$00ee,$00f2,$00f5,$0000,$00f7,$00f8,$00fc,$00ff,$0102,$0000 -dw $0000,$0103,$0106,$0107,$010a,$010c,$010e,$0112,$0000,$0000,$0000,$0114,$0117,$011b,$011e,$0121 -dw $0000,$0123,$0000,$0124,$0127,$0128,$0000,$012c,$0000,$0000,$0000,$012e,$0133,$0139,$013e,$0000 -dw $013f,$0140,$0141,$0146,$0000,$0149,$014b,$014d,$014f,$0150,$0000,$0153,$0156,$015a,$015d,$0161 -dw $0163,$0164,$0166,$016a,$016c,$016d,$0000,$0000,$0170,$0176,$017c,$0182,$0184,$0000,$0185,$0186 -dw $0188,$018b,$018f,$0197,$019c,$019d,$019e,$01a3,$01a4,$01a6,$01aa,$01ad,$01b3,$0000,$01bb,$01be -dw $01bf,$01c2,$01ca,$01d2,$01d9,$01da,$01dd,$01e3,$01e6,$01e7,$0000,$01ec,$01ed,$0000,$01f0,$0000 -dw $01f1,$01f3,$01f7,$0000,$0000,$01f8,$01fa,$0000,$01fd,$0200,$0203,$0204,$0206,$0000,$0000,$0000 -dw $0207 - - -org $279E00 -SpiralOffset: -; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler -db $00,$01,$02,$00,$03,$00,$00,$04,$00,$05,$07,$00,$08,$00,$0b,$00 -db $00,$0c,$00,$00,$00,$0d,$0e,$0f,$00,$00,$11,$00,$13,$14,$15,$00 -db $00,$00,$00,$00,$00,$00,$16,$19,$1b,$00,$00,$00,$00,$00,$00,$00 -db $00,$1c,$00,$00,$1f,$00,$00,$00,$20,$00,$21,$00,$00,$00,$00,$22 -db $23,$24,$25,$00,$00,$26,$00,$00,$00,$00,$27,$00,$29,$2a,$2b,$00 -db $00,$00,$00,$2c,$2d,$00,$00,$00,$00,$00,$00,$00,$2e,$2f,$00,$30 -db $00,$00,$00,$35,$36,$00,$37,$00,$00,$00,$38,$3a,$3b,$00,$3c,$00 -db $3d,$40,$41,$00,$00,$00,$42,$45,$00,$00,$00,$00,$00,$00,$00,$49 -db $4a,$00,$00,$00,$00,$00,$00,$4b,$00,$00,$00,$00,$4f,$00,$53,$00 -db $00,$54,$00,$55,$00,$00,$00,$56,$57,$58,$00,$00,$00,$00,$59,$00 -db $5a,$00,$5b,$00,$00,$5c,$5d,$00,$00,$00,$00,$5e,$00,$00,$5f,$00 -db $60,$00,$00,$00,$00,$63,$64,$00,$00,$00,$00,$00,$65,$00,$66,$00 -db $67,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -db $6a,$6d,$6e,$00,$00,$00,$00,$00,$00,$00,$6f,$00,$00,$00,$00,$00 -db $70 - -org $279F00 -DoorOffset: -db $00,$01,$02,$00,$03,$00,$04,$00,$00,$00,$00,$00,$9A,$05,$99,$00 -db $00,$06,$07,$08,$09,$0A,$0B,$00,$00,$0C,$0D,$0E,$00,$0F,$10,$11 -db $12,$13,$14,$15,$16,$00,$17,$00,$98,$00,$18,$19,$00,$00,$1A,$00 -db $1B,$00,$1C,$1D,$1E,$1F,$20,$21,$22,$23,$24,$25,$00,$26,$27,$00 -db $96,$28,$97,$29,$2A,$2B,$2C,$00,$00,$2D,$2E,$2F,$30,$31,$32,$00 -db $33,$34,$35,$36,$00,$00,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F,$40 -db $41,$42,$43,$A0,$00,$00,$44,$45,$46,$00,$47,$48,$49,$4A,$4B,$00 -; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler -db $00,$4C,$00,$00,$00,$4D,$4E,$9E,$00,$00,$00,$4F,$50,$51,$52,$53 -db $00,$54,$00,$9C,$9D,$55,$00,$00,$00,$00,$00,$56,$57,$58,$59,$00 -db $5A,$5B,$5C,$5D,$00,$5E,$5F,$00,$9B,$60,$00,$61,$62,$63,$64,$65 -db $66,$67,$68,$69,$6A,$6B,$00,$00,$6C,$6D,$6E,$6F,$70,$00,$71,$72 -db $00,$73,$74,$75,$76,$77,$78,$79,$7A,$7B,$7C,$7D,$7E,$00,$7F,$80 -db $00,$81,$82,$83,$84,$85,$86,$87,$88,$89,$00,$8A,$8B,$00,$8C,$00 -db $00,$8D,$8E,$00,$00,$8F,$90,$00,$91,$92,$93,$94,$95,$00,$00,$00 -db $9f - -org $27A000 -DoorTable: -;; NW 00 N 01 NE 02 WN 00 W 01 WS 02 SW 00 S 01 SE 02 EN 00 E 01 ES 02 - Door ruler -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Default/Garbage row -dw $0003, $0003, $0003, $0450, $0003, $0003, $0003, $0003, $0003, $0452, $0003, $0003 ; HC Back Hall (x01) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Switches (x02) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Crystaroller -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Arghus -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Aga 2 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Secret Room -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sanc -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Pokey -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Lava Pipe -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Pipes n Ledge -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swap Canal -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod dark Maze -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Bridge -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Eye Statue -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Pre Aga -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Cross -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice BK -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x20 Aga1 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Key Rat -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewer Waters -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Eye Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Chest Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Statue -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; PoD Arena (x2a) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; PoD Statue (x2b) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Compass -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x30 Aga's Altar -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Dark Cross -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Lanmolas -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp West Wing -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Flooded Key -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Main Hub (x36) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Hammer Time -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp First Basement -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Drop to the Moth -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod 3 Catwalks -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Conveyor -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Minihelma -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Conveyor -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewers -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Torches -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Big Chest -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Cellblock -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Compass Loop -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull3 Torches -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Pod Mimics 1 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Conveyor Ice -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Moldorm -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; IPBJ -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0401, $0003, $0003 ; HC West Hall (x50) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Throne Room (x51) -dw $0003, $0003, $0003, $0401, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC East Hall (x52) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Tiles 1 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 2 Left Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 2 Right Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 1 Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Skull 3 Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Helmasaur -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Spike Switch -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Cannonball -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Gauntlet 1 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Choice Cross -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Iced U -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC West Lobby (x60) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Main Lobby (x61) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC East Lobby (x62) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x66 Swamp Waterfall -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x67 Skull 1 Left Drop -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x68 Skull 1 Pinball -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6a Pod Rupees -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6b GT Mimics -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6c GT Lanmolas -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6d Gauntlet 2 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; x6e Ice Gators -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Armory -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert BK Chest -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Flooded Chests -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT DM's Tile -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Randoroom -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Warp Maze -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Freezors -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Hookpit -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; HC Catawalk -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Right Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Left -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Hopeful Torch -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Right -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Lonely Freezor -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Vitreous (x90) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Rain -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Dark Crystals -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Blockswitch -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Fallbridge -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Torch Cross -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Darkness -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Warp Maze 2 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Invis Bridge -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Compass Room -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Big Chests -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Icy Pots -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Pre-Vitreous (xa0) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Fishbone -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Bridges -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Corner -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Trinexx (xa4) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Wizzrobes -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Compass (xa8) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Courtyard (xa9) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Map (xaa) -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Switch -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Blind -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Iced T -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Slipway -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Warpzone -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire ???? -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Spikes -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Refill -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Dark Maze -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Chainchomp -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Rollers -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Big Key -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Easter Cannonball -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Dark Circle -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Hellway -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Bossway -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Blockswitch -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Backtracker -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Tiles -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Main Hub -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Big Chest -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Switch Maze -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Narrow -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Early Hub -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Floating Torches -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Armos -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT NW Quad -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT NE Quad -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Boss Drop -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire BK -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire 2 -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Laser Bridge -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TR Main Entrance -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Eyegores -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Attic Switches -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Eastern Attic Start -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT Entrance Quad -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; TT SE Quad -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Aga 6F -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Sewers Rope -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Swamp Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Ice Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; GT Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Mire Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert West Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Main Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Hera Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Tower Lobby -dw $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003, $0003 ; Desert Back Lobby -; this should end at 27AF18 about (160 * 24 bytes = 3840 or F18) -; some values you can hardcode for spirals -;dw $0070, $36a0 ; ->HC Stairwell -;dw $0072, $4ff8 ; ->HC Map Room -;dw $0080, $1f50 ; ->zelda's cellblock - -org $27B000 -SpiralTable: ;113 4 byte entries - should end at 27B1C4 -dw $0203, $8080 ;null row -dw $0203, $8080 ;HC Backhallway -dw $0203, $8080 ;Sewer Pull -dw $0203, $8080 ;Crystaroller -dw $0203, $8080 ;Moldorm -dw $0203, $8080, $0203, $8080 ;Pod Basement -dw $0203, $8080 ;Pod Stalfos -dw $0203, $8080, $0203, $8080, $0203, $8080 ;GT Entrance -dw $0203, $8080 ;Ice Entrance -dw $0203, $8080 ;Escape -dw $0203, $8080 ;TR Pipe Ledge -dw $0203, $8080 ;Swamp Way -dw $0203, $8080, $0203, $8080 ;Hera Fallplace -dw $0203, $8080, $0203, $8080 ;PoD Bridge -dw $0203, $8080 ;GT Ice -dw $0203, $8080 ;GT F8 -dw $0203, $8080 ;Ice Cross -dw $0203, $8080, $0203, $8080, $0203, $8080 ;Swamp Statue -dw $0203, $8080, $0203, $8080 ;Hera Big -dw $0203, $8080 ;Swamp Ent -dw $0203, $8080, $0203, $8080, $0203, $8080 ;Hera Startiles (middle value unused) -dw $0203, $8080 ;West Swamp -dw $0203, $8080 ;Swamp Basement -dw $0203, $8080 ;Pod Drops -dw $0203, $8080 ;Ice Hammer -dw $0203, $8080 ;Aga Guards -dw $0203, $8080 ;Sewer Begin -dw $0203, $8080 ;Sewer Rope -dw $0203, $8080 ;TT Cellblock -dw $0203, $8080, $0203, $8080 ;Pod Entrance -dw $0203, $8080 ;GT Icespike -dw $0203, $8080 ;GT Moldorm -dw $0203, $8080 ;IPBJ -dw $0203, $8080 ;Desert Prep -dw $0203, $8080 ;Swamp Attic -dw $0203, $8080 ;GT Cannonball -dw $0203, $8080 ;GT Gauntlet1 -dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;Ice U (1st three values unused) -dw $0203, $8080 ;Desert Back -dw $0203, $8080 ;TT Attic L -dw $0203, $8080 ;Swamp Waterf -dw $0203, $8080 ;Pod Rupees -dw $0203, $8080 ;Pod Rupees -dw $0203, $8080 ;GT Mimics -dw $0203, $8080 ;GT Lanmo -dw $0203, $8080 ;Ice Gators -dw $0203, $8080, $0203, $8080, $0203, $8080 ;HC Tiny (first value placeholder) -dw $0203, $8080 ;HC Boomer -dw $0203, $8080 ;HC Pits1 -dw $0203, $8080, $0203, $8080, $0203, $8080 ;Swamp Sunken -dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;Hera Entrance (first value unused) -dw $0203, $8080 ;Ice Hookshot -dw $0203, $8080 ;HC Cellblock -dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;Hera Basement (first and third values unused) -dw $0203, $8080, $0203, $8080, $0203, $8080, $0203, $8080 ;GT Circle (third value unused) -dw $0203, $8080 ;Ice Last Freeze -dw $0203, $8080 ;Mire Drops -dw $0203, $8080 ;Mire Block -dw $0203, $8080 ;Mire Attic -dw $0203, $8080 ;Mire Entrance -dw $0203, $8080 ;East Dark -dw $0203, $8080 ;Ice Big -dw $0203, $8080 ;Mire Previtreous -dw $0203, $8080 ;Mire Bridges -dw $0203, $8080 ;GT Wizzrobes -dw $0203, $8080 ;GT Spikepit -dw $0203, $8080 ;TT Switch -dw $0203, $8080 ;Ice T -dw $0203, $8080, $0203, $8080, $0203, $8080 ;Tower Usains (2nd value unused) -dw $0203, $8080 ;TR PlatMaze -dw $0203, $8080 ;TR Chainchomp -dw $0203, $8080 ;TT Bossway -dw $0203, $8080 ;Ice FallZone -dw $0203, $8080, $0203, $8080, $0203, $8080 ;Tower Dark2 (2nd value unused) -dw $0203, $8080, $0203, $8080, $0203, $8080 ;Tower Dark1 (2nd value unused) -dw $0203, $8080 ;Mire BK Thang -dw $0203, $8080 ;Mire2 -dw $0203, $8080 ;East Attic Start -dw $0203, $8080 ;Tower Entrance - - -org $27C000 ;ends around 27C418 -PairedDoorTable: -dw $0000 ; the bad template -dw $0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000 -dw $0000 -dw $0000 -dw $0000,$0000,$0000 -dw $0000 -dw $0000 -dw $0000,$0000,$0000 - -dw $0000,$0000,$8021 -dw $0000,$0000,$0000,$0000 -dw $4014,$0000 -dw $8024,$8013,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000 -dw $0000,$0000,$0000,$0000 -dw $201a,$401a -dw $0000,$4019,$8019,$402a,$0000,$0000 -dw $0000,$0000 -dw $0000,$0000,$0000 -dw $0000 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000 - -dw $0000 -dw $2011,$0000,$0000 -dw $8032,$0000 -dw $0000,$0000 -dw $8014,$0000,$0000,$0000,$0000,$0000,$0000,$0000 -dw $4036,$0000,$0000,$0000 -dw $0000,$0000 -dw $0000,$101a,$402b,$0000,$0000,$0000 -dw $0000,$202a,$0000,$0000 -dw $0000 - -dw $0000,$0000 -dw $0000,$0000 -dw $8022 -dw $0000 -dw $0000,$0000 -dw $2036,$0000,$0000,$0000,$0000,$0000 -dw $8037,$8026,$8035,$0000,$0000,$0000 -dw $8036,$8038,$0000,$4038,$0000,$0000 -dw $4037,$1037 -dw $0000,$0000 -dw $204a,$0000,$0000 -dw $0000 -dw $0000,$0000,$804d,$0000 -dw $0000,$404e -dw $0000 - -dw $0000 -dw $0000 -dw $0000,$0000,$2053 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$8059,$0000 -dw $0000,$0000,$803a,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000 -dw $203d,$0000 -dw $0000,$403e -dw $0000 ; this is the odd extra room - shouldn't be used - -dw $0000,$0000 -dw $0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$2043 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000,$4058,$0000,$0000,$0000 -dw $0000,$2057,$4068,$0000,$0000,$0000 -dw $2049,$0000,$0000,$0000 -dw $0000 -dw $806b,$0000 -dw $0000,$0000 -dw $0000,$0000,$0000 -dw $805f,$0000,$0000,$0000 -dw $805e - -dw $0000,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000 -dw $0000 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$2058 -dw $0000 -dw $805b,$0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000 - -dw $0000,$0000,$0000 -dw $0000 -dw $0000,$0000,$0000 -dw $0000,$0000 -dw $0000,$0000 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000 -dw $0000,$207c,$0000 -dw $0000,$407d,$407b,$0000 -dw $0000,$407c,$0000 -dw $808e,$0000,$0000 -dw $0000,$0000 - -dw $0000 -dw $0000,$0000,$0000 -dw $0000 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000 -dw $0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000 -dw $807e - -dw $0000 -dw $0000 -dw $0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000 -dw $0000,$0000 -dw $0000,$0000 -dw $0000 -dw $0000,$20a9,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$0000,$0000 -dw $0000,$0000 - -dw $0000 -dw $40b1,$0000 -dw $80b2,$0000,$0000,$0000 -dw $0000,$0000 -dw $0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$80b8,$0000,$0000,$0000 -dw $0000,$0000,$4099,$0000,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000 -dw $0000 -dw $0000 -dw $0000,$0000 - -dw $0000,$0000,$0000 -dw $0000,$80a1,$0000,$0000 -dw $80a2,$0000,$0000,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000 -dw $0000 -dw $0000 -dw $0000,$0000,$80c6,$0000,$0000 -dw $0000 -dw $20a8,$0000 -dw $80ba,$0000,$0000,$0000 -dw $80b9,$0000,$0000 -dw $0000,$0000,$0000,$0000,$0000,$0000 -dw $0000,$80cc,$0000,$40cc,$0000,$0000,$0000,$0000 -dw $0000,$80bf,$0000 -dw $40be - -dw $0000,$0000,$0000 -dw $0000,$40c2,$0000,$0000,$0000,$0000,$0000,$0000 -dw $80c3,$40c1,$0000,$0000,$0000,$0000,$0000,$0000 -dw $80c2,$0000,$0000,$0000,$0000,$0000,$0000 -dw $80c5 -dw $80c4,$0000,$0000 -dw $20b6,$0000,$0000,$0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000 -dw $0000,$0000,$0000,$0000,$0000 -dw $20cc -dw $40bc,$10bc,$80cb -dw $0000 - -dw $0000,$0000 -dw $0000,$0000,$0000,$0000 -dw $0000 -dw $0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000,$0000,$0000 -dw $0000 -dw $0000,$0000 -dw $0000 -dw $0000,$0000,$0000,$0000 -dw $ffff ; indicates the end - we can drop this - -; Edge Transition Table (Target Room, Flags, MultiDiv ratio for edges) -org $27C500 ;ends around 27C5F(9) 4 bytes would be 27C649 -;I kind of want to split the 3rd byte into two -NorthOpenEdge: -db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -SouthOpenEdge: -db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -WestOpenEdge: -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -EastOpenEdge: -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -db $00,$80,$11, $00,$80,$11, $00,$80,$11 -; Edge Info Table (Midpoint, Width, Min Coord) -; I kind of want to add a fourth byte to help indicate quadrant info on min coord -NorthEdgeInfo: -db $a8,$10,$a0, $2c,$08,$28 ;HC -db $b8,$20,$a8 ; DP West Wing -db $38,$20,$28, $f8,$a0,$a8, $b8,$20,$a8 ; DP Main -db $78,$20,$68 ; DP East Wing -db $f8,$10,$f0, $7c,$18,$70 ; TT Lobby -db $74,$18,$68, $f8,$10,$f0 ; TT Compass -SouthEdgeInfo: -db $a8,$10,$a0, $2c,$08,$28 ; HC -db $b8,$20,$a8 ; DP Sandworm -db $38,$20,$28, $f8,$a0,$a8, $b8,$20,$a8 ; DP North Hall & Dead End -db $78,$20,$68 ; DP Arrow Pot -db $f8,$10,$f0, $7c,$18,$70 ; TT Ambush -db $74,$18,$68, $f8,$10,$f0 ; TT BK Corner -WestEdgeInfo: -db $78,$30,$60 ; TT Attic -db $40,$20,$30 ; DP North Hall -db $40,$20,$30 ; DP Arrow Pot -db $84,$18,$78, $68,$10,$60 ; HC South -db $a0,$a0,$50 ; DP East Wing -db $58,$50,$30, $98,$50,$70 ; TT BK Corner -db $58,$50,$30 ; TT Compass -EastEdgeInfo: -db $78,$30,$60 ; TT Attic -db $40,$20,$30 ; DP Sandworm -db $40,$20,$30 ; DP North Hall -db $68,$10,$60, $84,$18,$78 ; HC Guards -db $a0,$a0,$50 ; DP Main Lobby -db $58,$50,$30, $98,$50,$70 ; TT Ambush -db $58,$50,$30 ; TT Nook -MultDivInfo: ; (1, 2, 3, 4, 5, 6, 10, 20) -db $01, $02, $03, $04, $05, $06, $0a, $14 -; indices: 0-7 - -; In-room stairs in North/South pairs. From left to right: -; PoD, IP right side, IP Freezor chest and GT -org $27C700 -InroomStairsTable: -dw $0003,$0003, $0003,$0003, $0003,$0003, $0003,$0003 - -org $27C720 -InroomStairsRoom: -db $0B,$1B, $3F,$1F, $7E,$5E, $96,$3D -InroomStairsX: -dw $0190, $0160, $0040, $0178 -InroomStairsY: -dw $0058, $0148, $0198, $0190 - - -org $27E000 -CutoffRooms: -; TT Alcove, Mire Bridge Left & Right, Mire Bent Bridge, Mire Hub -; Pod Falling & Harmless, SW Star Pits, TR Lava Escape & TR Dual Pipes, Bob's Room & GT Big Chest -dw $00bc, $00a2, $00a3, $00c2, $001a, $0049, $0014, $008c -; Ice Many Pots, Swamp Waterfall, GT Gauntlet 3, Eastern Push Block, Eastern Courtyard, Eastern Map Valley -; Eastern Cannonball, HC East Hall -dw $009f, $0066, $005d, $00a8, $00a9, $00aa, $00b9, $0052 -; HC West Hall, TR Dash Bridge, TR Hub, Pod Arena, GT Petting Zoo, Ice Spike Cross -dw $0050, $00c5, $00c6, $0009, $0003, $002a, $007d, $005e -; Sewer Drop, Mire Cross, GT Crystal Circles -dw $0011, $00b2, $003d -dw $ffff - -; dungeon tables -; HC HC EP DP AT SP PD MM SW IP TH TT TR GT -org $27f000 -CompassBossIndicator: -dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000 -TotalKeys: ;27f020 -db $04, $04, $02, $04, $04, $06, $06, $06, $05, $06, $01, $03, $06, $08, $00, $00 -ChestKeys: ;27f030 -db $01, $01, $00, $01, $02, $01, $06, $03, $03, $02, $01, $01, $04, $04, $00, $00 -BigKeyStatus: ;27f040 (status 2 indicate BnC guard) -dw $0002, $0002, $0001, $0001, $0000, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0001, $0000, $0000 -DungeonReminderTable: ;27f060 -dw $2D50, $2D50, $2D51, $2D52, $2D54, $2D56, $2D55, $2D5A, $2D57, $2D59, $2D53, $2D58, $2D5B, $2D5C, $0000, $0000 -TotalLocationsLow: ;27f080 -db $08, $08, $06, $06, $02, $00, $04, $08, $08, $08, $06, $08, $02, $07, $00, $00 -TotalLocationsHigh: ;27f090 -db $00, $00, $00, $00, $00, $01, $01, $00, $00, $00, $00, $00, $01, $02, $00, $00 -org $27f0a0 -TotalLocations: -db $08, $08, $06, $06, $02, $0a, $0e, $08, $08, $08, $06, $08, $0c, $1b, $00, $00 -; no more room here - -; Vert 0,6,0 Horz 2,0,8 -org $27f0b0 -CoordIndex: ; Horizontal 1st -db 2, 0 ; Coordinate Index $20-$23 -OppCoordIndex: -db 0, 2 ; Swapped coordinate Index $20-$23 (minor optimization) -CameraIndex: ; Horizontal 1st -db 0, 6 ; Camera Index $e2-$ea -CamQuadIndex: ; Horizontal 1st -db 8, 0 ; Camera quadrants $600-$60f -ShiftQuadIndex: -db 2, 1 ; see ShiftQuad func (relates to $a9,$aa) -CamBoundIndex: ; Horizontal 1st -db 0, 4 ; Camera Bounds $0618-$61f -OppCamBoundIndex: ; Horizontal 1st -db 4, 0 ; Camera Bounds $0618-$61f -CamBoundBaseLine: ; X camera stuff is 1st column todo Y camera needs more testing -dw $007f, $0077 ; Left/Top camera bounds when at edge or layout frozen -dw $0007, $000b ; Left/Top camera bounds when not frozen + appropriate low byte $22/$20 (preadj. by #$78/#$6c) -dw $00ff, $010b ; Right/Bot camera bounds when not frozen + appropriate low byte $20/$22 -dw $017f, $0187 ; Right/Bot camera bound when at edge or layout frozen -;27f0ce next free byte - -org $27f0f0 -RemoveRainDoorsRoom: -dw $0060, $0062, $ffff ; ffff indicates end of list -RainDoorMatch: ; org $27f0f6 and f8 for now -dw $0081, $0061 ; not xba'd -BlockSanctuaryDoorInRain: ;27f0fa -dw $0000 - - -org $27f100 -TilesetTable: -; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler -db $13,$04,$04,$06,$0d,$ff,$08,$05,$06,$07,$07,$07,$0e,$0e,$0b,$ff -db $13,$04,$04,$0d,$0d,$0d,$08,$05,$06,$07,$07,$07,$0e,$0e,$0b,$0b -db $04,$04,$04,$0d,$0d,$ff,$08,$05,$08,$09,$07,$07,$06,$ff,$0b,$06 -db $04,$05,$04,$12,$08,$08,$08,$08,$08,$09,$07,$07,$06,$0e,$0b,$0b -db $04,$04,$04,$12,$0a,$0a,$08,$ff,$ff,$09,$07,$07,$0e,$0e,$0b,$0b -db $04,$04,$04,$12,$08,$01,$09,$09,$09,$09,$07,$0e,$0e,$0e,$0b,$0b -db $04,$04,$04,$12,$0a,$0a,$08,$09,$09,$ff,$07,$0e,$0e,$0e,$0b,$ff -db $04,$04,$04,$12,$12,$12,$08,$05,$ff,$ff,$ff,$0e,$0e,$0e,$0b,$0b -db $04,$04,$04,$12,$12,$12,$ff,$05,$ff,$05,$ff,$0e,$0e,$0e,$0b,$ff -db $0c,$0c,$0c,$0c,$ff,$0e,$0e,$0c,$0c,$05,$ff,$0e,$0e,$0e,$0b,$0b -db $0c,$0c,$0c,$0c,$0d,$0e,$0e,$05,$05,$05,$05,$0a,$0a,$ff,$0b,$0b -db $04,$0c,$0c,$0c,$0d,$0d,$0d,$0d,$05,$05,$05,$0a,$0a,$ff,$0b,$0b -db $04,$0c,$0c,$0c,$0d,$0d,$0d,$0d,$05,$05,$ff,$0a,$0a,$ff,$0b,$ff -db $04,$0c,$0c,$ff,$ff,$0d,$0d,$ff,$05,$05,$05,$0a,$0a,$ff,$0b,$06 -db $04,$06,$06,$06,$06,$06,$06,$06,$06,$ff,$06,$06,$ff,$06,$06,$06 -db $06,$06,$03,$03,$03,$03,$ff,$ff,$06,$06,$06,$06,$ff,$06,$06,$06 - -;27f200 -PaletteTable: -db $21,$00,$00,$07,$00,$08,$00,$00,$07,$00,$00,$00,$00,$00,$00,$21 -db $21,$00,$00,$00,$00,$00,$00,$00,$07,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$0e,$00,$00,$07,$00,$00,$07 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$07,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$13 -db $00,$00,$00,$00,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -; 0 1 2 3 4 5 6 7 8 9 a b c d e f --Offset Ruler -db $00,$00,$00,$00,$00,$00,$00,$06,$00,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 -db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$14,$20 -db $00,$07,$20,$20,$07,$07,$07,$07,$07,$20,$20,$07,$20,$20,$20,$20 -db $07,$07,$02,$02,$02,$02,$07,$07,$07,$20,$20,$07,$20,$20,$20,$07 - -;27f300 -DungeonTilesets: -db $04,$04,$05,$12,$04,$08,$07,$0C,$09,$0B,$05,$0A,$0D,$0E,$06,$06 - -; -;org $27ff00 - -org $27fff0 -LinksHouseDarkWorld: -dw $ffff -SanctuaryDarkWorld: -dw $ffff -OldManDarkWorld: -dw $ffff \ No newline at end of file diff --git a/asm/dr_lobby.asm b/asm/dr_lobby.asm deleted file mode 100644 index 15ee435c..00000000 --- a/asm/dr_lobby.asm +++ /dev/null @@ -1,10 +0,0 @@ -CheckDarkWorldSpawn: - STA $A0 : STA $048E ; what we wrote over - LDA.l DRFlags : AND #$0200 : BEQ + ; skip if the flag isn't set - LDA.l $7EF357 : AND #$00FF : BNE + ; moon pearl? - LDA.l LinksHouseDarkWorld : CMP $A0 : BEQ ++ - LDA.l SanctuaryDarkWorld : CMP $A0 : BEQ ++ - LDA.l OldManDarkWorld : CMP $A0 : BNE + - ++ SEP #$30 : LDA #$17 : STA $5D - INC $02E0 : LDA.b #$40 : STA !DARK_WORLD : REP #$30 -+ RTL diff --git a/asm/drhooks.asm b/asm/drhooks.asm deleted file mode 100644 index e8c48b90..00000000 --- a/asm/drhooks.asm +++ /dev/null @@ -1,221 +0,0 @@ -org $02b5c4 ; -- moving right routine 135c4 -jsl WarpRight -org $02b665 ; -- moving left routine -jsl WarpLeft -org $02b713 ; -- moving down routine -jsl WarpDown -org $02b7b4 ; -- moving up routine -jsl WarpUp -org $02bd80 -jsl AdjustTransition -nop - -;turn off linking doors -- see .notRoomLinkDoor label in Bank02.asm -org $02b5a8 ; <- 135a8 - Bank02.asm : 8368 (LDA $7EC004 : STA $A0) -jsl CheckLinkDoorR -bcc NotLinkDoor1 -org $02b5b6 -NotLinkDoor1: -org $02b649 ; <- 135a8 - Bank02.asm : 8482 (LDA $7EC004 : STA $A0) -jsl CheckLinkDoorL -bcc NotLinkDoor2 -org $02b657 -NotLinkDoor2: - - -; Staircase routine -org $01c3d4 ; <- c3d4 - Bank01.asm : 9762-4 (Dungeon_DetectStaircase-> STA $A0 : LDA $063D, X) -jsl RecordStairType : nop -org $02a1e7 ;(PC: 121e7) -jsl SpiralWarp - -org $0291b3 ; <- Bank02.asm : 3303 (LDA $0462 : AND.b #$04) -jsl SpiralPriorityHack : nop -org $0290f9 ; <- Bank02.asm : 3188 (LDA $0462 : AND.b #$04) -jsl SpiralPriorityHack : nop - -org $029369 ; <- 11369 - Bank02.asm : 3610 (STX $0464 : STY $012E) -jsl StraightStairsAdj : nop #2 -org $029383 ; <- 11384 - Bank02.asm : 3629 (.walkingDownStaircase-> ADD $20 : STA $20) -jsl StraightStairsFix : nop -org $0293aa ; <- 113aa - Bank02.asm : 3653 (ADD $20 : STA $20) -jsl StraightStairsFix : nop -org $0293d1 ; <- 113d1 - Bank02.asm : 3683 (ADD $20 : STA $20 BRANCH_IOTA) -jsl StraightStairsFix : nop -org $029396 ; <- 11396 - Bank02.asm : 3641 (LDA $01C322, X) -jsl StraightStairLayerFix -org $02c06d ; <- Bank02.asm : 9874 (LDX $0418, CMP.b #$02) -jsl DoorToStraight : nop -org $02c092 ; STA $0020, Y : LDX #$00 -jsl DoorToInroom : nop -org $02c0f8 ; CMP $02C034, X -jsl DoorToInroomEnd -org $02941a ; <- Bank02.asm : 3748 module 7.12.11 (LDA $0464 : BNE BRANCH_$11513 : INC $B0 : RTS) -jsl StraightStairsTrapDoor : rts -org $028b54 ; <- Bank02.asm : 2200 (JSL UseImplicitRegIndexedLocalJumpTable) -jsl InroomStairsTrapDoor - -org $0289a0 ; JSL $0091C4 -jsl QuadrantLoadOrderBeforeScroll -org $02bd9c ; JSL $0091C4 -jsl QuadrantLoadOrderAfterScroll - - -; Graphics fix -org $02895d ; Bank 02 line 1812 (JSL Dungeon_LoadRoom : JSL Dungeon_InitStarTileChr : JSL $00D6F9 : INC $B0) -Splicer: -jsl GfxFixer -lda $b1 : beq .done -rts -nop #5 -.done - -org $01b618 ; Bank01.asm : 7963 Dungeon_LoadHeader (REP #$20 : INY : LDA [$0D], Y) -nop : jsl OverridePaletteHeader - -org $02817e ; Bank02.asm : 414 (LDA $02811E, X) -jsl FixAnimatedTiles - -org $0aef43 ; UnderworldMap_RecoverGFX -jsl FixCloseDungeonMap - -org $028a06 ; Bank02.asm : 1941 Dungeon_ResetTorchBackgroundAndPlayer -JSL FixWallmasterLamp - -org $00d377 ;Bank 00 line 3185 -DecompDungAnimatedTiles: -org $00fda4 ;Bank 00 line 8882 -Dungeon_InitStarTileCh: -org $00d6ae ;(PC: 56ae) -LoadTransAuxGfx: -org $00d739 ; -LoadTransAuxGfx_Alt: -org $00df5a ;(PC: 5f5a) -PrepTransAuxGfx: -org $0ffd65 ;(PC: 07fd65) -Dungeon_LoadCustomTileAttr: -org $01feb0 -Dungeon_ApproachFixedColor: -;org $01fec1 -;Dungeon_ApproachFixedColor_variable: -;org $a0f972 ; Rando version -;LoadRoomHook: -org $1bee74 ;(PC: 0dee74) -Palette_DungBgMain: -org $1bec77 -Palette_SpriteAux3: -org $1becc5 -Palette_SpriteAux2: -org $1bece4 -Palette_SpriteAux1: - - -org $0DFA53 -jsl.l LampCheckOverride -org $028046 ; <- 10046 - Bank02.asm : 217 (JSL EnableForceBlank) (Start of Module_LoadFile) -jsl.l OnFileLoadOverride -org $07A93F ; < 3A93F - Bank07.asm 6548 (LDA $8A : AND.b #$40 - Mirror checks) -jsl.l MirrorCheckOverride - -org $05ef47 -Sprite_HeartContainer_Override: ;sprite_heart_upgrades.asm : 96-100 (LDA $040C : CMP.b #$1A : BNE .not_in_ganons_tower) -jsl GtBossHeartCheckOverride : bcs .not_in_ganons_tower -nop : stz $0dd0, X : rts -.not_in_ganons_tower - - -org $07a955 ; <- Bank07.asm : around 6564 (JP is a bit different) (STZ $05FC : STZ $05FD) -jsl BlockEraseFix -nop #2 - -org $02A0A8 -Mirror_SaveRoomData: -org $07A95B ; < bank_07.asm ; #_07A95B: JSL Mirror_SaveRoomData -jsl EGFixOnMirror - -org $02b82a -jsl FixShopCode - -org $1ddeea ; <- Bank1D.asm : 286 (JSL Sprite_LoadProperties) -jsl VitreousKeyReset - -org $1ed024 ; f5024 sprite_guruguru_bar.asm : 27 (LDA $040C : CMP.b #$12 : INY #2 -jsl GuruguruFix : bra .next -nop #3 -.next - -org $028fc9 -nop #2 : jsl BlindAtticFix - -org $028409 -jsl SuctionOverworldFix - -org $0ded04 ; <- rando's hooks.asm line 2192 - 6ED04 - equipment.asm : 1963 (REP #$30) -jsl DrHudDungeonItemsAdditions -;org $098638 ; rando's hooks.asm line 2192 -;jsl CountChestKeys -org $06D192 ; rando's hooks.asm line 457 -jsl CountAbsorbedKeys -; rando's hooks.asm line 1020 -;org $05FC7E ; <- 2FC7E - sprite_dash_item.asm : 118 (LDA $7EF36F : INC A : STA $7EF36F) -;jsl CountBonkItem - -org $019dbd ; <- Bank01.asm : 4465 of Object_Draw8xN (LDA $9B52, Y : STA $7E2000, X) -jsl CutoffEntranceRug : bra .nextTile : nop -.nextTile - -;maybe set 02e2 to 0 - -org $0799de ; <- Bank07.asm : 4088 (LDA.b #$15 : STA $5D) -JSL StoreTempBunnyState -; -org $08c450 ; <- ancilla_receive_item.asm : 146-148 (STY $5D : STZ $02D8) -JSL RetrieveBunnyState : NOP - -org $02d9ce ; <- Bank02.asm : Dungeon_LoadEntrance 10829 (STA $A0 : STA $048E) -JSL CheckDarkWorldSpawn : NOP - -org $01891e ; <- Bank 01.asm : 991 Dungeon_LoadType2Object (LDA $00 : XBA : AND.w #$00FF) -JSL RainPrevention : BCC + : RTS : NOP : + - -org $1edabf ; <- sprite_energy_ball.asm : 86-7 Sprite_EnergyBall (LDA.b #$10 : LDX.b #$00) -JSL StandardAgaDmg - - -org $09a681 ; < - similar to talalong.asm : 1157 (JSL Main_ShowTextMessage) -JSL BlindsAtticHint : NOP #2 -org $1cfd69 -Main_ShowTextMessage: - -; Conditionally disable UW music changes in Door Rando -org $028ADB ; <- Bank02.asm:2088-2095 (LDX.b #$14 : LDA $A0 ...) -JSL.l Underworld_DoorDown_Entry : CPX #$FF -BEQ + : db $80, $1C ; BRA $028B04 -NOP #6 : + - -org $02C3F2 ; <- Bank02.asm:10521 Unused call -Underworld_DoorDown_Call: -org $02C3F3 -dw $8AD9 ; address of Bank02.asm:2085 - -; These two, if enabled together, have implications for vanilla BK doors in IP/Hera/Mire -; IPBJ is common enough to consider not doing this. Mire is not a concern for vanilla - maybe glitched modes -; Hera BK door back can be seen with Pot clipping - likely useful for no logic seeds - -;Kill big key (1e) check for south doors -;org $1aa90 -;DontCheck: -;bra .done -;nop #3 -;.done - -;Enable south facing bk graphic -;org $4e24 -;dw $2ac8 - -org $01b714 ; PC: b714 -OpenableDoors: -jsl CheckIfDoorsOpen -bcs .normal -rts -.normal diff --git a/asm/edges.asm b/asm/edges.asm deleted file mode 100644 index 58852b12..00000000 --- a/asm/edges.asm +++ /dev/null @@ -1,299 +0,0 @@ -HorzEdge: - cpy #$ff : beq + - jsr DetectWestEdge : ldy #$02 : bra ++ - + jsr DetectEastEdge - ++ cmp #$ff : beq + - sta $00 : asl : !add $00 : tax - cpy #$ff : beq ++ - jsr LoadWestData : bra .main - ++ jsr LoadEastData - .main - jsr LoadEdgeRoomHorz - sec : rts - + clc : rts - -VertEdge: - cpy #$ff : beq + - jsr DetectNorthEdge : bra ++ - + jsr DetectSouthEdge - ++ cmp #$ff : beq + - sta $00 : asl : !add $00 : tax - cpy #$ff : beq ++ - jsr LoadNorthData : bra .main - ++ jsr LoadSouthData - .main - jsr LoadEdgeRoomVert - sec : rts - + clc : rts - -LoadEdgeRoomHorz: - lda $03 : sta $a0 - sty $06 - and.b #$0f : asl a : !sub $23 : !add $06 : sta $02 - ldy #$00 : jsr ShiftVariablesMainDir - - lda $04 : and #$80 : bne .edge - lda $04 : sta $01 ; load up flags in $01 - jsr PrepScrollToNormal - bra .scroll - - .edge - lda $04 : and #$10 : beq + - lda #$01 - + sta $ee ; layer stuff - - jsr MathHorz - - .scroll - jsr ScrollY - rts - -LoadEdgeRoomVert: - lda $03 : sta $a0 - sty $06 - and.b #$f0 : lsr #3 : !sub $21 : !add $06 : sta $02 - - lda $04 : and #$80 : bne .edge - lda $04 : sta $01 ; load up flags in $01 - and #$03 : cmp #$03 : beq .inroom - ldy #$01 : jsr ShiftVariablesMainDir - jsr PrepScrollToNormal - bra .scroll - - .inroom - jsr ScrollToInroomStairs - rts - - .edge - ldy #$01 : jsr ShiftVariablesMainDir - lda $04 : and #$10 : beq + - lda #$01 - + sta $ee ; layer stuff - - jsr MathVert - lda $03 - - .scroll - jsr ScrollX - rts - - -MathHorz: - jsr MathStart : lda $20 - jsr MathMid : and #$0040 - jsr MathEnd - rts - -MathVert: - jsr MathStart : lda $22 - jsr MathMid : and #$0020 - jsr MathEnd - rts - -MathStart: - rep #$30 - lda $08 : and #$00ff : sta $00 - rts - -MathMid: - and #$01ff : !sub $00 : and #$00ff : sta $00 - ; nothing should be bigger than $a0 at this point - - lda $05 : and #$00f0 : lsr #4 : tax - lda MultDivInfo, x : and #$00ff : tay - lda $00 : jsr MultiplyByY : sta $02 - - lda $07 : and #$00ff : jsr MultiplyByY : tax - - lda $05 : and #$000f : tay - lda MultDivInfo, y : and #$00ff : tay - lda $02 : jsr DivideByY : sta $00 - lda $0c : and #$00ff : sta $02 - lda $04 - rts - -MathEnd: - beq + - lda #$0100 - + !add $02 : !add $00 - sta $04 - sep #$30 - rts - -; don't need midpoint of edge Link is leaving (formerly in $06 - used by dir indicator) -; don't need width of edge Link is going to (currently in $0b) -LoadNorthData: - lda NorthOpenEdge, x : sta $03 : inx ; target room - lda NorthEdgeInfo, x : sta $07 ; needed for maths - (divide by 2 anyway) - lda NorthOpenEdge, x : sta $04 : inx ; bit field - lda NorthEdgeInfo, x : sta $08 ; needed for maths - lda NorthOpenEdge, x : sta $05 ; ratio - lda $04 : jsr LoadSouthMidpoint : inx ; needed now, and for nrml transition - lda SouthEdgeInfo, x : sta $0b : inx ; probably not needed todo: remove - lda SouthEdgeInfo, x : sta $0c ; needed for maths - rts - -LoadSouthMidpoint: - and #$0f : sta $00 : asl : !add $00 : tax - lda SouthEdgeInfo, x : sta $0a ; needed now, and for nrml transition - rts - -LoadSouthData: - lda SouthOpenEdge, x : sta $03 : inx - lda SouthEdgeInfo, x : sta $07 - lda SouthOpenEdge, x : sta $04 : inx - lda SouthEdgeInfo, x : sta $08 - lda SouthOpenEdge, x : sta $05 - lda $04 : jsr LoadNorthMidpoint : inx - lda NorthEdgeInfo, x : sta $0b : inx - lda NorthEdgeInfo, x : sta $0c - rts - -LoadNorthMidpoint: - and #$0f : sta $00 : asl : !add $00 : tax - lda NorthEdgeInfo, x : sta $0a ; needed now, and for nrml transition - rts - -LoadWestData: - lda WestOpenEdge, x : sta $03 : inx - lda WestEdgeInfo, x : sta $07 - lda WestOpenEdge, x : sta $04 : inx - lda WestEdgeInfo, x : sta $08 - lda WestOpenEdge, x : sta $05 - lda $04 : jsr LoadEastMidpoint : inx - lda EastEdgeInfo, x : sta $0b : inx - lda EastEdgeInfo, x : sta $0c - rts - -LoadEastMidpoint: - and #$0f : sta $00 : asl : !add $00 : tax - lda EastEdgeInfo, x : sta $0a ; needed now, and for nrml transition - rts - -LoadEastData: - lda EastOpenEdge, x : sta $03 : inx - lda EastEdgeInfo, x : sta $07 - lda EastOpenEdge, x : sta $04 : inx - lda EastEdgeInfo, x : sta $08 - lda EastOpenEdge, x : sta $05 - lda $04 : jsr LoadWestMidpoint : inx - lda WestEdgeInfo, x : sta $0b : inx - lda WestEdgeInfo, x : sta $0c - - -LoadWestMidpoint: - and #$0f : sta $00 : asl : !add $00 : tax - lda WestEdgeInfo, x : sta $0a ; needed now, and for nrml transition - rts - - -DetectNorthEdge: - ldx #$ff - lda $a2 - cmp #$82 : bne + - lda $22 : cmp #$50 : bcs ++ - ldx #$01 : bra .end - ++ ldx #$00 : bra .end - + cmp #$83 : bne + - ldx #$02 : bra .end - + cmp #$84 : bne + - lda $a9 : beq ++ - lda $22 : cmp #$78 : bcs +++ - ldx #$04 : bra .end - +++ ldx #$05 : bra .end - ++ lda $22 : cmp #$78 : bcs ++ - ldx #$03 : bra .end - ++ ldx #$04 : bra .end - + cmp #$85 : bne + - ldx #$06 : bra .end - + cmp #$db : bne + - lda $a9 : beq ++ - lda $22 : beq ++ - ldx #$08 : bra .end - ++ ldx #$07 : bra .end - + cmp #$dc : bne .end - lda $a9 : bne ++ - lda $22 : cmp #$b0 : bcs ++ - ldx #$09 : bra .end - ++ ldx #$0a - .end txa : rts - -DetectSouthEdge: - ldx #$ff - lda $a2 - cmp #$72 : bne + - lda $22 : cmp #$50 : bcs ++ - ldx #$01 : bra .end - ++ ldx #$00 : bra .end - + cmp #$73 : bne + - ldx #$02 : bra .end - + cmp #$74 : bne + - lda $a9 : beq ++ - lda $22 : cmp #$78 : bcs +++ - ldx #$04 : bra .end - +++ ldx #$05 : bra .end - ++ lda $22 : cmp #$78 : bcs ++ - ldx #$03 : bra .end - ++ ldx #$04 : bra .end - + cmp #$75 : bne + - ldx #$06 : bra .end - + cmp #$cb : bne + - lda $a9 : beq ++ - lda $22 : beq ++ - ldx #$08 : bra .end - ++ ldx #$07 : bra .end - + cmp #$cc : bne .end - lda $a9 : bne ++ - lda $22 : cmp #$b0 : bcs ++ - ldx #$09 : bra .end - ++ ldx #$0a - .end txa : rts - -DetectWestEdge: - ldx #$ff - lda $a2 - cmp #$65 : bne + - ldx #$00 : bra .end - + cmp #$74 : bne + - ldx #$01 : bra .end - + cmp #$75 : bne + - ldx #$02 : bra .end - + cmp #$82 : bne + - lda $aa : beq ++ - ldx #$03 : bra .end - ++ ldx #$04 : bra .end - + cmp #$85 : bne + - ldx #$05 : bra .end - + cmp #$cc : bne + - lda $aa : beq ++ - ldx #$06 : bra .end - ++ ldx #$07 : bra .end - + cmp #$dc : bne .end - ldx #$08 - .end txa : rts - -DetectEastEdge: - ldx #$ff - lda $a2 - cmp #$64 : bne + - ldx #$00 : bra .end - + cmp #$73 : bne + - ldx #$01 : bra .end - + cmp #$74 : bne + - ldx #$02 : bra .end - + cmp #$81 : bne + - lda $aa : beq ++ - ldx #$04 : bra .end - ++ ldx #$03 : bra .end - + cmp #$84 : bne + - ldx #$05 : bra .end - + cmp #$cb : bne + - lda $aa : beq ++ - ldx #$06 : bra .end - ++ ldx #$07 : bra .end - + cmp #$db : bne .end - ldx #$08 - .end txa : rts - - - diff --git a/asm/gfx.asm b/asm/gfx.asm deleted file mode 100644 index 94cb8848..00000000 --- a/asm/gfx.asm +++ /dev/null @@ -1,95 +0,0 @@ -GfxFixer: -{ - lda.l DRMode : bne + - jsl LoadRoomHook ;this is the code we overwrote - jsl Dungeon_InitStarTileCh - jsl LoadTransAuxGfx_Alt - inc $b0 - rtl - + lda $b1 : bne .stage2 - jsl LoadRoomHook ; this is the rando version - let's only call this guy once - may fix star tiles and slower loads - jsl Dungeon_InitStarTileCh - jsl LoadTransAuxGfx - jsl Dungeon_LoadCustomTileAttr - jsl PrepTransAuxGfx - lda.l DRMode : cmp #$02 : bne + ; only do this in crossed mode - ldx $a0 : lda.l TilesetTable, x - cmp $0aa1 : beq + ; already eq no need to decomp - sta $0aa1 - tax : lda $02802e, x : tay - jsl DecompDungAnimatedTiles - + - lda #$09 : sta $17 : sta $0710 - jsl Palette_SpriteAux3 - jsl Palette_SpriteAux2 - jsl Palette_SpriteAux1 - jsl Palette_DungBgMain - jsr CgramAuxToMain - inc $b1 - rtl - .stage2 - lda #$0a : sta $17 : sta $0710 - stz $b1 : inc $b0 - rtl -} - -FixAnimatedTiles: - LDA.L DRMode : CMP #$02 : BNE + - LDA $040C : CMP.b #$FF : BEQ + - PHX - LDX $A0 : LDA.l TilesetTable, x - CMP $0AA1 : beq ++ - TAX : PLA : BRA + - ++ - PLX - + LDA $02802E, X ; what we wrote over - RTL - -FixCloseDungeonMap: - LDA.l DRMode : CMP #$02 : BNE .vanilla - LDA $040C : BMI .vanilla - LSR : TAX - LDA.l DungeonTilesets,x - RTL - .vanilla - LDA $7EC20E - RTL - -FixWallmasterLamp: -ORA $0458 -STY $1C : STA $1D : RTL ; what we wrote over - - -CgramAuxToMain: ; ripped this from bank02 because it ended with rts -{ - rep #$20 - ldx.b #$00 - - .loop - lda $7EC300, X : sta $7EC500, x - lda $7EC340, x : sta $7EC540, x - lda $7EC380, x : sta $7EC580, x - lda $7EC3C0, x : sta $7EC5C0, x - lda $7EC400, x : sta $7EC600, x - lda $7EC440, x : sta $7EC640, x - lda $7EC480, x : sta $7EC680, x - lda $7EC4C0, x : sta $7EC6C0, x - - inx #2 : cpx.b #$40 : bne .loop - sep #$20 - - ; tell NMI to upload new CGRAM data - inc $15 - rts -} - -OverridePaletteHeader: - lda.l DRMode : cmp #$02 : bne + - lda.l DRFlags : and #$20 : bne + - cpx #$01c2 : !bge + - rep #$20 - txa : lsr : tax - lda.l PaletteTable, x - iny : rtl - + rep #$20 : iny : lda [$0D], Y ; what we wrote over -rtl \ No newline at end of file diff --git a/asm/hudadditions.asm b/asm/hudadditions.asm deleted file mode 100644 index 575e189f..00000000 --- a/asm/hudadditions.asm +++ /dev/null @@ -1,291 +0,0 @@ -DrHudOverride: -{ - jsl.l NewDrawHud - jsr HudAdditions - rtl -} - -HudAdditions: -{ - LDA.l DRFlags : AND #$0008 : BNE + : JMP .end_item_count : + - LDA.l $7EF423 : PHA : CMP #1000 : !BLT + - JSL HexToDec4Digit_fast - LDX.b $04 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS ; draw 1000's digit - BRA .skip - + JSL HexToDec_fast - .skip - LDA #$207F : STA !GOAL_DRAW_ADDRESS+2 : STA !GOAL_DRAW_ADDRESS+4 - PLA : PHA : CMP.w #100 : !BLT + - LDX.b $05 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+2 ; draw 100's digit - + PLA : CMP.w #10 : !BLT + - LDX.b $06 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+4 ; draw 10's digit - + LDX.b $07 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+6 ; draw 1's digit - LDA.w #$2830 : STA !GOAL_DRAW_ADDRESS+8 ; draw slash - LDA.l DRFlags : AND #$0100 : BNE + - LDA.l $7EF33E : CMP #1000 : !BLT .three_digit_goal - JSL HexToDec4Digit_fast - LDX.b $04 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+10 ; draw 1000's digit - LDX.b $05 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+12 ; draw 100's digit - LDX.b $06 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+14 ; draw 10's digit - LDX.b $07 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+16 ; draw 1's digit - BRA .end_item_count - .three_digit_goal - JSL HexToDec_fast - LDX.b $05 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+10 ; draw 100's digit - LDX.b $06 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+12 ; draw 10's digit - LDX.b $07 : TXA : ORA.w #$2490 : STA !GOAL_DRAW_ADDRESS+14 ; draw 1's digit - BRA .end_item_count - + LDA.w #$2405 : STA !GOAL_DRAW_ADDRESS+10 : STA !GOAL_DRAW_ADDRESS+12 - STA !GOAL_DRAW_ADDRESS+14 : STA !GOAL_DRAW_ADDRESS+16 - .end_item_count - - LDX $1B : BNE + : RTS : + ; Skip if outdoors - ldx $040c : cpx #$ff : bne + : rts : + ; Skip if not in dungeon - lda.l DRMode : bne + : rts : + ; Skip if not door rando - phb : phk : plb - lda $7ef364 : and.l $0098c0, x : beq + - lda.w CompassBossIndicator, x : and #$00ff : cmp $a0 : bne + - lda $1a : and #$0010 : beq + - lda #$345e : sta $7ec790 : bra .next - + lda #$207f : sta $7ec790 - .next lda.w DRMode : and #$0002 : bne + : plb : rts : + - lda $7ef36d : and #$00ff : beq + - lda.w DungeonReminderTable, x : bra .reminder - + lda #$207f - .reminder sta $7ec702 - + lda.w DRFlags : and #$0004 : beq .restore - lda $7ef368 : and.l $0098c0, x : beq .restore - txa : lsr : tax - - lda.l GenericKeys : and #$00ff : bne + - lda $7ef4e0, x : jsr ConvertToDisplay : sta $7ec7a2 - lda #$2830 : sta $7ec7a4 - + - lda.w ChestKeys, x : jsr ConvertToDisplay : sta $7ec7a6 - ; todo 4b0 no longer in use - - .restore - plb : rts -} - -;column distance for BK/Smalls -HudOffsets: -; none hc east desert aga swamp pod mire skull ice hera tt tr gt -dw $fffe, $0000, $0006, $0008, $0002, $0010, $000e, $0018, $0012, $0016, $000a, $0014, $001a, $001e - -; offset from 1644 -RowOffsets: -dw $0000, $0000, $0040, $0080, $0000, $0080, $0040, $0080, $00c0, $0040, $00c0, $0000, $00c0, $0000 - -ColumnOffsets: -dw $0000, $0000, $0000, $0000, $000a, $000a, $000a, $0014, $000a, $0014, $0000, $0014, $0014, $001e - - -DrHudDungeonItemsAdditions: -{ - jsl DrawHUDDungeonItems - lda.l HUDDungeonItems : and #$ff : bne + : rtl : + - lda.l DRMode : cmp #$02 : beq + : rtl : + - - phx : phy : php - rep #$30 - - lda.w #$24f5 : sta $1606 : sta $1610 : sta $161a : sta $1624 - sta $1644 : sta $164a : sta $1652 : sta $1662 : sta $1684 : sta $16c4 - ldx #$0000 - - sta $1704, x : sta $170e, x : sta $1718, x - inx #2 : cpx #$0008 : !blt - - - lda !HUD_FLAG : and.w #$0020 : beq + : JMP ++ : + - lda HUDDungeonItems : and.w #$0007 : bne + : JMP ++ : + - ; bk symbols - lda.w #$2811 : sta $1606 : sta $1610 : sta $161a : sta $1624 - ; sm symbols - lda.w #$2810 : sta $160a : sta $1614 : sta $161e : sta $16e4 - ; blank out stuff - lda.w #$24f5 : sta $1724 - - ldx #$0002 - - lda #$0000 : !addl RowOffsets,x : !addl ColumnOffsets, x : tay - lda.l DungeonReminderTable, x : sta $1644, y : iny #2 - lda.w #$24f5 : sta $1644, y - lda $7ef368 : and.l $0098c0, x : beq + ; must have map - jsr BkStatus : sta $1644, y : bra .smallKey ; big key status - + lda $7ef366 : and.l $0098c0, x : beq .smallKey - lda.w #$2826 : sta $1644, y - .smallKey - + iny #2 - cpx #$001a : bne + - tya : !add #$003c : tay - + stx $00 - txa : lsr : tax - lda.w #$24f5 : sta $1644, y - lda.l GenericKeys : and #$00FF : bne + - lda.l $7ef37c, x : and #$00FF : beq + - jsr ConvertToDisplay2 : sta $1644, y - + iny #2 : lda.w #$24f5 : sta $1644, y - phx : ldx $00 - lda $7ef368 : and.l $0098c0, x : beq + ; must have map - plx : sep #$30 : lda.l ChestKeys, x : sta $02 - lda.l GenericKeys : bne +++ - lda $02 : !sub $7ef4e0, x : sta $02 - +++ lda $02 - rep #$30 - jsr ConvertToDisplay2 : sta $1644, y ; small key totals - bra .skipStack - + plx - .skipStack iny #2 - cpx #$000d : beq + - lda.w #$24f5 : sta $1644, y - + - ldx $00 - + inx #2 : cpx #$001b : bcs ++ : JMP - - ++ - lda !HUD_FLAG : and.w #$0020 : bne + : JMP ++ : + - lda HUDDungeonItems : and.w #$000c : bne + : JMP ++ : + - ; map symbols (do I want these) ; note compass symbol is 2c20 - lda.w #$2821 : sta $1606 : sta $1610 : sta $161a : sta $1624 - ; blank out a couple thing from old hud - lda.w #$24f5 : sta $16e4 : sta $1724 - sta $160a : sta $1614 : sta $161e ; blank out sm key indicators - ldx #$0002 - - lda #$0000 ; start of hud area - !addl RowOffsets, x : !addl ColumnOffsets, x : tay - lda.l DungeonReminderTable, x : sta $1644, y - iny #2 - lda.w #$24f5 : sta $1644, y ; blank out map spot - lda $7ef368 : and.l $0098c0, x : beq + ; must have map - JSR MapIndicatorShort : STA $1644, Y - + iny #2 - cpx #$001a : bne + - tya : !add #$003c : tay - + lda $7ef364 : and.l $0098c0, x : beq + ; must have compass - phx ; total chest counts - txa : lsr : tax - sep #$30 - lda.l TotalLocations, x : !sub $7EF4BF, x : JSR HudHexToDec2DigitCopy - rep #$30 - lda $06 : jsr ConvertToDisplay2 : sta $1644, y : iny #2 - lda $07 : jsr ConvertToDisplay2 : sta $1644, y - plx - bra .skipBlanks - + lda.w #$24f5 : sta $1644, y : iny #2 : sta $1644, y - .skipBlanks iny #2 - cpx #$001a : beq + - lda.w #$24f5 : sta $1644, y ; blank out spot - + inx #2 : cpx #$001b : !bge ++ : JMP - - ++ - plp : ply : plx : rtl -} - -MapIndicatorLong: - PHX - LDA.l OldHudToNewHudTable, X : TAX - JSR MapIndicator - PLX -RTL - -MapIndicatorShort: - PHX - TXA : LSR : TAX - JSR MapIndicator - PLX -RTS - -OldHudToNewHudTable: - dw 1, 2, 3, 10, 4, 6, 5, 8, 11, 9, 7, 12, 13 - -IndicatorCharacters: - ; check 1 2 3 4 5 6 7 G B R - dw $2426, $2817, $2818, $2819, $281A, $281B, $281C, $281D, $2590, $258B, $259B - -MapIndicator: - LDA.l CrystalPendantFlags_3, X : AND #$00FF - PHX - ASL : TAX : LDA.l IndicatorCharacters, X - PLX -RTS - -BkStatus: - lda $7ef366 : and.l $0098c0, x : bne +++ ; has the bk already - lda.l BigKeyStatus, x : bne ++ - lda #$2827 : rts ; 0/O for no BK - ++ cmp #$0002 : bne + - lda #$2420 : rts ; symbol for BnC - + lda #$24f5 : rts ; black otherwise - +++ lda #$2826 : rts ; check mark - -ConvertToDisplay: - and.w #$00ff : cmp #$000a : !blt + - !add #$2553 : rts - + !add #$2490 : rts - -ConvertToDisplay2: - and.w #$00ff : beq ++ - cmp #$000a : !blt + - !add #$2553 : rts ; todo: use 2580 with 258A as "A" for non transparent digits - + !add #$2816 : rts - ++ lda #$2827 : rts ; 0/O for 0 or placeholder digit ;2483 - -CountAbsorbedKeys: - jsl IncrementSmallKeysNoPrimary : phx - lda $040c : cmp #$ff : beq + - lsr : tax - lda $7ef4b0, x : inc : sta $7ef4b0, x - + plx : rtl - -;================================================================================ -; 16-bit A, 8-bit X -; in: A(b) - Byte to Convert -; out: $04 - $07 (high - low) -;================================================================================ -HudHexToDec4DigitCopy: - LDY.b #$90 - - - CMP.w #1000 : !BLT + - INY - SBC.w #1000 : BRA - - + - STY $04 : LDY #$90 ; Store 1000s digit & reset Y - - - CMP.w #100 : !BLT + - INY - SBC.w #100 : BRA - - + - STY $05 : LDY #$90 ; Store 100s digit & reset Y - - - CMP.w #10 : !BLT + - INY - SBC.w #10 : BRA - - + - STY $06 : LDY #$90 ; Store 10s digit & reset Y - CMP.w #1 : !BLT + - - - INY - DEC : BNE - - + - STY $07 ; Store 1s digit -RTS - -;================================================================================ -; 8-bit registers -; in: A(b) - Byte to Convert -; out: $06 - $07 (high - low) -;================================================================================ -HudHexToDec2DigitCopy: ; modified - PHY - LDY.b #$00 - - - CMP.b #10 : !BLT + - INY - SBC.b #10 : BRA - - + - STY $06 : LDY #$00 ; Store 10s digit and reset Y - CMP.b #1 : !BLT + - - - INY - DEC : BNE - - + - STY $07 ; Store 1s digit - PLY -RTS \ No newline at end of file diff --git a/asm/keydoors.asm b/asm/keydoors.asm deleted file mode 100644 index 1ec10c39..00000000 --- a/asm/keydoors.asm +++ /dev/null @@ -1,42 +0,0 @@ -; code to un-pair or re-pair doors - -; doorlist is loaded into 19A0 but no terminator -; new room is in A0 -; for "each" door do the following: (each could mean the first four doors?) -; in lookup table, grab room and corresponding position -; find the info at 7ef000, x where x is twice the paired room -; check the corresponding bit (there are only 4) -; set the bit in 068C - -; Note the carry bit is used to indicate if we should aborted (set) or not -CheckIfDoorsOpen: { - jsr TrapDoorFixer ; see normal.asm - ; note we are 16bit mode right now - lda.l DRMode : beq + - lda $040c : cmp #$00ff : bne .gtg - + lda $a0 : dec : tax : and #$000f ; hijacked code - sec : rtl ; set carry to indicate normal behavior - - .gtg - phb : phk : plb - stx $00 : ldy #$0000 - .nextDoor - lda $a0 : asl : tax - lda.w KeyDoorOffset, x : beq .skipDoor - asl : sty $05 : !add $05 : tax - lda.w PairedDoorTable, x : beq .skipDoor - sta $02 : and #$00ff : asl a : tax - lda $02 : and #$ff00 : sta $03 - lda $7ef000, x : and #$f000 : and $03 : beq .skipDoor - tyx : lda $068c : ora $0098c0,x : sta $068c - .skipDoor - iny #2 : cpy $00 : bne .nextDoor - plb : clc : rtl -} - -; outstanding issues -; how to indicate opening for other (non-first four doors?) -; Bank01 Door Register stores the 4 bits in 068c to 400 (depending on type) -; Key collision and others depend on F0-F3 attribute not sure if extendable to other numbers -; Dungeon_ProcessTorchAndDoorInteractives.isOpenableDoor is the likely culprit for collision problems -; Saving open status to other unused rooms is tricky -- Bank 2 13947 (line 8888) \ No newline at end of file diff --git a/asm/math.asm b/asm/math.asm deleted file mode 100644 index 03cd46a3..00000000 --- a/asm/math.asm +++ /dev/null @@ -1,66 +0,0 @@ -;divide by 2 example -; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10--Offset Ruler -;v 00 01 01 02 02 03 03 04 04 04 05 05 06 06 07 07 08 - -;divide by 3 example -; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 -;00 00 01 01 01 02 02 02 03 03 03 04 04 04 05 05 05 06 06 06 07 07 07 08 08 - -MultiplyByY: -.loop cpy #$0001 : beq .done -cpy #$0003 : bne ++ - jsr MultiBy3 : bra .done -++ cpy #$0005 : bne ++ - jsr MultiBy5 : bra .done -++ asl : sta $00 : tya : lsr : tay : lda $00 : bra .loop -.done rts - -;Divisor in Y. Width of division is in X for rounding toward middle -DivideByY: -.loop -cpy #$0000 : beq .done -cpy #$0001 : beq .done -cpy #$0003 : bne ++ - jsr DivideBy3 : bra .done -++ cpy #$0005 : bne ++ - jsr DivideBy5 : bra .done -++ jsr DivideBy2 : sta $00 -tya : lsr : tay -txa : lsr : tax -lda $00 : bra .loop -.done rts - -MultiBy3: -sta $00 : asl : !add $00 -rts - -MultiBy5: -sta $00 : asl #2 : !add $00 -rts - -;width of divison in x: rounds toward X/2 -DivideBy2: -sta $00 -lsr : bcc .done -sta $02 : txa : lsr : cmp $00 : !blt + - lda $02 : inc : bra .done -+ lda $02 -.done rts - -DivideBy3: -sta $00 -ldx #$0000 -lda #$0002 -.loop cmp $00 : !bge .store - inx : !add #$0003 : bra .loop -.store txa -rts - -DivideBy5: -sta $00 -ldx #$0000 -lda #$0003 -.loop cmp $00 : !bge .store - inx : !add #$0005 : bra .loop -.store txa -rts \ No newline at end of file diff --git a/asm/normal.asm b/asm/normal.asm deleted file mode 100644 index 13323d88..00000000 --- a/asm/normal.asm +++ /dev/null @@ -1,419 +0,0 @@ -WarpLeft: - lda.l DRMode : beq .end - lda $040c : cmp.b #$ff : beq .end - lda $20 : ldx $aa - jsr CalcIndex - !add #$06 : ldy #$01 ; offsets in A, Y - jsr LoadRoomHorz -.end - jsr Cleanup - rtl - -WarpRight: - lda.l DRMode : beq .end - lda $040c : cmp.b #$ff : beq .end - lda $20 : ldx $aa - jsr CalcIndex - !add #$12 : ldy #$ff ; offsets in A, Y - jsr LoadRoomHorz -.end - jsr Cleanup - rtl - -WarpUp: - lda.l DRMode : beq .end - lda $040c : cmp.b #$ff : beq .end - lda $22 : ldx $a9 - jsr CalcIndex - ldy #$02 ; offsets in A, Y - jsr LoadRoomVert -.end - jsr Cleanup - rtl - -; Checks if $a0 is equal to . If it is, opens its stonewall if it's there -macro StonewallCheck(Room) - lda $a0 : cmp.b # : bne ?end - lda.l *2+$7ef000 : ora #$80 : sta.l *2+$7ef000 - ?end -endmacro - -WarpDown: - lda.l DRMode : beq .end - lda $040c : cmp.b #$ff : beq .end - lda $22 : ldx $a9 - jsr CalcIndex - !add #$0c : ldy #$ff ; offsets in A, Y - jsr LoadRoomVert - %StonewallCheck($43) -.end - jsr Cleanup - rtl - -; carry set = use link door like normal -; carry clear = we are in dr mode, never use linking doors -CheckLinkDoorR: - lda.l DRMode : bne + - lda $7ec004 : sta $a0 ; what we wrote over - sec : rtl - + clc : rtl - -CheckLinkDoorL: - lda.l DRMode : bne + - lda $7ec003 : sta $a0 ; what we wrote over - sec : rtl - + clc : rtl - -TrapDoorFixer: - lda $fe : and #$0038 : beq .end - xba : asl #2 : sta $00 - stz $0468 : lda $068c : ora $00 : sta $068c - .end - stz $fe ; clear our fe here because we don't need it anymore - rts - -Cleanup: - lda.l DRFlags : and #$10 : beq + - stz $047a - + inc $11 - lda $ef - rts - -;A needs be to the low coordinate, x needs to be either 0 for left,upper or non-zero for right,down -; This sets A (00,02,04) and stores half that at $04 for later use, (src door) -CalcIndex: ; A->low byte of Link's Coord, X-> Link's quadrant, DoorOffset x 2 -> A, DoorOffset -> $04 (vert/horz agnostic) - cpx.b #00 : bne .largeDoor - cmp.b #$d0 : bcc .smallDoor - lda #$01 : bra .done ; Middle Door - .smallDoor lda #$00 : bra .done - .largeDoor lda #$02 - .done - sta $04 - asl - rts - -; Y is an adjustment for main direction of travel -; A is a door table row offset -LoadRoomHorz: -{ - phb : phk : plb - sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack - lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00-$01 - lda $00 : cmp #$03 : bne .gtg - jsr HorzEdge : pla : bcs .end - sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine) - - .gtg ;Good to Go! - pla ; Throw away normal room (don't fill up the stack) - lda $a0 : and.b #$0F : asl a : !sub $23 : !add $06 : sta $02 - ldy #$00 : jsr ShiftVariablesMainDir - - lda $01 : and #$80 : beq .normal - ldy $06 : cpy #$ff : beq + - lda $01 : jsr LoadEastMidpoint : bra ++ - + lda $01 : jsr LoadWestMidpoint - ++ jsr PrepScrollToEdge : bra .scroll - - .normal - jsr PrepScrollToNormal - .scroll - lda $01 : and #$40 : pha - jsr ScrollY - pla : beq .end - ldy #$06 : jsr ApplyScroll - .end - plb ; restore db register - rts -} - -; Y is an adjustment for main direction of travel (stored at $06) -; A is a door table row offset (stored a $07) -LoadRoomVert: -{ - phb : phk : plb - sty $06 : sta $07 : lda $a0 : pha ; Store normal room on stack - lda $07 : jsr LookupNewRoom ; New room is in A, Room Data is in $00-$01 - lda $00 : cmp #$03 : bne .gtg - jsr VertEdge : pla : bcs .end - sta $a0 : bra .end ; Restore normal room, abort (straight staircases and open edges can get in this routine) - .gtg ;Good to Go! - pla ; Throw away normal room (don't fill up the stack) - lda $a0 : and.b #$F0 : lsr #3 : !sub $21 : !add $06 : sta $02 - - lda $01 : and #$80 : beq .notEdge - ldy #$01 : jsr ShiftVariablesMainDir - ldy $06 : cpy #$ff : beq + - lda $01 : jsr LoadSouthMidpoint : bra ++ - + lda $01 : jsr LoadNorthMidpoint - ++ jsr PrepScrollToEdge : bra .scroll - - .notEdge - lda $01 : and #$03 : cmp #$03 : bne .normal - jsr ScrollToInroomStairs - stz $046d - bra .end - .normal - ldy #$01 : jsr ShiftVariablesMainDir - jsr PrepScrollToNormal - .scroll - lda $01 : and #$40 : sta $046d - jsr ScrollX - .end - plb ; restore db register - rts -} - -LookupNewRoom: ; expects data offset to be in A -{ - rep #$30 : and #$00FF ;sanitize A reg (who knows what is in the high byte) - sta $00 ; offset in 00 - lda $a2 : tax ; probably okay loading $a3 in the high byte - lda.w DoorOffset,x : and #$00FF ;we only want the low byte - asl #3 : sta $02 : !add $02 : !add $02 ;multiply by 24 (data size) - !add $00 ; should now have the offset of the address I want to load - tax : lda.w DoorTable,x : sta $00 - and #$00FF : sta $a0 ; assign new room - sep #$30 - rts -} - -; INPUTS-- Y: Direction Index , $02: Shift Value -; Sets high bytes of various registers -ShiftVariablesMainDir: -{ - lda.w CoordIndex,y : tax - lda $21,x : !add $02 : sta $21,x ; coordinate update - lda.w CameraIndex,y : tax - lda $e3,x : !add $02 : sta $e3,x ; scroll register high byte - lda.w CamQuadIndex,y : tax - lda $0605,x : !add $02 : sta $0605,x ; high bytes of these guys - lda $0607,x : !add $02 : sta $0607,x - lda $0601,x : !add $02 : sta $0601,x - lda $0603,x : !add $02 : sta $0603,x - rts -} - -; Normal Flags should be in $01 -ScrollToInroomStairs: -{ - jsr PrepScrollToInroomStairs - ldy #$01 : jsr ShiftVariablesMainDir - jsr ScrollX - ldy #$00 : jsr ApplyScroll - lda $a0 : and #$0f : cmp #$0f : bne + - stz $e0 : stz $e2 ; special case camera fix - lda #$1f : sta $e1 : sta $e3 - + - rts -} - -; Direction should be in $06, Shift Value (see above) in $02 and other info in $01 -; Sets $02, $04, $05, $ee, $045e, $045f and things related to Y coordinate -PrepScrollToInroomStairs: -{ - lda $01 : and #$30 : lsr #3 : tay - lda.w InroomStairsX,y : sta $04 - lda.w InroomStairsX+1,y : sta $05 - lda $06 : cmp #$ff : beq .south - lda.w InroomStairsY+1,y : bne + - inc $045f ; flag indicating special screen transition - dec $02 ; shift variables further - stz $aa - lda $a8 : and #%11111101 : sta $a8 - stz $0613 ; North scroll target - inc $0603 : inc $0607 - dec $0619 : dec $061b - + - lda.w InroomStairsY,y : !add #$20 : sta $20 - !sub #$38 : sta $045e - lda $01 : and #$40 : beq + - lda $20 : !add #$20 : sta $20 - stz $045f - + - dec $21 - %StonewallCheck($1b) - bra ++ - .south - lda.w InroomStairsY+1,y : beq + - inc $045f ; flag indicating special screen transition - inc $02 ; shift variables further - lda #$02 : sta $aa - lda $a8 : ora #%00000010 : sta $a8 - inc $0611 ; South scroll target - dec $0603 : dec $0607 - inc $0619 : inc $061b - + - lda.w InroomStairsY,y : !sub #$20 : sta $20 - !add #$38 : sta $045e - lda $01 : and #$40 : beq + - lda $20 : !sub #$20 : sta $20 - stz $045f - + - inc $21 - ++ - lda $01 : and #$04 : lsr #2 : sta $ee : bne + - stz $0476 - + rts -} - -; Target pixel should be in A, other info in $01 -; Sets $04 $05 and $ee -PrepScrollToEdge: -{ - sta $04 : lda $01 : and #$20 : beq + - lda #01 - + sta $05 - lda $01 : and #$10 : beq + - lda #01 - + sta $ee : bne + - stz $0476 - + rts -} - -; Normal Flags should be in $01 -; Sets $04 $05 and $ee, and $fe -PrepScrollToNormal: -{ - lda $01 : sta $fe : and #$04 : lsr #2 : sta $ee ; trap door and layer - bne + - stz $0476 - + stz $05 : lda #$78 : sta $04 - lda $01 : and #$03 : beq .end - cmp #$02 : !bge + - lda #$f8 : sta $04 : bra .end - + inc $05 - .end rts -} - -StraightStairsAdj: -{ - stx $0464 : sty $012e ; what we wrote over - lda.l DRMode : beq + - lda $045e : bne .toInroom - lda $046d : beq .noScroll - sta $22 - ldy #$00 : jsr ApplyScroll - stz $046d - .noScroll - jsr GetTileAttribute : tax - lda $11 : cmp #$12 : beq .goingNorth - lda $a2 : cmp #$51 : bne ++ - rep #$20 : lda #$0018 : !add $20 : sta $20 : sep #$20 ; special fix for throne room - jsr GetTileAttribute : tax - ++ lda.l StepAdjustmentDown, X : bra .end -; lda $ee : beq .end -; rep #$20 : lda #$ffe0 : !add $20 : sta $20 : sep #$20 - .goingNorth - cpx #$00 : bne ++ - lda $a0 : cmp #$51 : bne ++ - lda #$36 : bra .end ; special fix for throne room - ++ ldy $ee : cpy #$00 : beq ++ - inx - ++ lda.l StepAdjustmentUp, X - .end - pha : lda $0462 : and #$04 : bne ++ - pla : !add #$f6 : pha - ++ pla : !add $0464 : sta $0464 - + rtl - .toInroom - lda #$32 : sta $0464 : stz $045e - rtl -} - -GetTileAttribute: -{ - phk : pea.w .jslrtsreturn-1 - pea.w $02802c - jml $02c11d ; mucks with x/y sets a to Tile Attribute, I think - .jslrtsreturn - rts -} - -; 0 open edge -; 1 nrm door high -; 2 straight str -; 3 nrm door low -; 4 trap door high -; 5 trap door low (none of these exist on North direction) -StepAdjustmentUp: ; really North Stairs -db $00, $f6, $1a, $18, $16, $38 -StepAdjustmentDown: ; really South Stairs -db $d0, $f6, $10, $1a, $f0, $00 - -StraightStairsFix: -{ - pha - lda.l DRMode : bne + - pla : !add $20 : sta $20 : rtl ;what we wrote over - + pla : rtl -} - -StraightStairLayerFix: -{ - lda.l DRMode : beq + - lda $ee : rtl - + lda $01c322, x : rtl ; what we wrote over -} - -DoorToStraight: -{ - pha - lda.l DRMode : beq .skip - pla : bne .end - pha - lda $a0 : cmp #$51 : bne .skip - lda #$04 : sta $4e - .skip pla - .end ldx $0418 : cmp #$02 ;what we wrote over - rtl -} - -DoorToInroom: -{ - ldx $045e : bne .end - sta $0020, y ; what we wrote over - .end - ldx #$00 ; what we wrote over - rtl -} - -DoorToInroomEnd: -{ - ldy $045e : beq .vanilla - cmp $045e : bne .return - stz $045e ; clear - .return - rtl - .vanilla - cmp $02c034, x ; what we wrote over - rtl -} - -StraightStairsTrapDoor: -{ - lda $0464 : bne + - ; reset function - .reset phk : pea.w .jslrtsreturn-1 - pea.w $02802c - jml $028c73 ; $10D71 .reset label of Bank02 - .jslrtsreturn - lda $0468 : bne ++ - lda $a0 : cmp.b #$ac : bne .animateTraps - lda $0403 : and.b #$20 : bne .animateTraps - lda $0403 : and.b #$10 : beq ++ - .animateTraps - lda #$05 : sta $11 - inc $0468 : stz $068e : stz $0690 - ++ JSL Underworld_DoorDown_Call : rtl - + JML Dungeon_ApproachFixedColor ; what we wrote over -} - -InroomStairsTrapDoor: -{ - lda $0200 : cmp #$05 : beq .reset - lda $b0 : jml $008781 ; what we wrote over (essentially) - .reset - pla : pla : pla - jsl StraightStairsTrapDoor_reset - jml $028b15 ; just some RTS in bank 02 -} \ No newline at end of file diff --git a/asm/overrides.asm b/asm/overrides.asm deleted file mode 100644 index c822de5f..00000000 --- a/asm/overrides.asm +++ /dev/null @@ -1,154 +0,0 @@ -;================================================================================ -; Lamp Mantle & Light Cone Fix -;-------------------------------------------------------------------------------- -; Output: 0 for darkness, 1 for lamp cone -;-------------------------------------------------------------------------------- -LampCheckOverride: - LDA $7F50C4 : CMP.b #$01 : BNE + : RTL : + - CMP.b #$FF : BNE + : INC : RTL : + - - LDA $7EF34A : BNE .done ; skip if we already have lantern - - LDA $7EF3CA : BNE + - .lightWorld - LDA $040C : CMP.b #$04 : !BGE ++ ; check if we're in HC - LDA LampConeSewers : BRA .done - ++ - LDA LampConeLightWorld : BRA .done - + - .darkWorld - LDA LampConeDarkWorld - .done - ;BNE + : STZ $1D : + ; remember to turn cone off after a torch -RTL - -GtBossHeartCheckOverride: - lda $a0 : cmp #$1c : beq ++ - cmp #$6c : beq ++ - cmp #$4d : bne + - ++ lda.l DRFlags : and #$01 : bne ++ ;skip if flag on - lda $403 : ora #$80 : sta $403 - ++ clc -rtl - + sec -rtl - -OnFileLoadOverride: - jsl OnFileLoad ; what I wrote over - + lda.l DRFlags : and #$02 : beq + ; Mirror Scroll - lda $7ef353 : bne + - lda #$01 : sta $7ef353 -+ rtl - -MirrorCheckOverride: - lda.l DRFlags : and #$02 : beq ++ - lda $7ef353 : cmp #$01 : beq + - ++ lda $8A : and #$40 ; what I wrote over - rtl - + lda.l DRScroll : rtl - -EGFixOnMirror: - lda.l DRFlags : and #$10 : beq + - stz $047a - + jsl Mirror_SaveRoomData - rtl - -BlockEraseFix: - lda $7ef353 : and #$02 : beq + - stz $05fc : stz $05fd - + rtl - -FixShopCode: - cpx #$300 : !bge + - sta $7ef000, x - + rtl - -VitreousKeyReset: - lda.l DRMode : beq + - stz $0cba, x - + JML $0db818 ;restore old code - -GuruguruFix: - lda $a0 : cmp #$df : !bge + - and #$0f : cmp #$0e : !blt + - iny #2 - + rtl - -BlindAtticFix: - lda.l DRMode : beq + - lda #$01 : rtl - + lda $7EF3CC : cmp.b #$06 - rtl - -SuctionOverworldFix: - stz $50 : stz $5e - lda.l DRMode : beq + - stz $49 - + rtl - -!CutoffTable = "$27E000" - -CutoffEntranceRug: - PHA : PHX - LDA.l DRMode : BEQ .norm - LDA $04 : cmp #$000A : BEQ + ; only affect A & C objects - cmp #$000C : BNE .norm - + LDX #$0000 : LDA !CutoffTable, x - - CMP.W $A0 : BEQ .check - INX #2 : LDA !CutoffTable, x : CMP.w #$FFFF : BNE - - .norm PLX : PLA : LDA $9B52, y : STA $7E2000, x ; what we wrote over -RTL - .check - LDA $0c : CMP #$0004 : !BGE .skip - LDA $0e : CMP #$0008 : !BGE .skip - CMP.l #$0004 : !BLT .skip - BRA .norm -.skip PLX : PLA : RTL - -StoreTempBunnyState: - LDA $5D : CMP #$1C : BNE + - STA $5F - + LDA #$15 : STA $5D ; what we wrote over -RTL - -RetrieveBunnyState: - STY $5D : STZ $02D8 ; what we wrote over - LDA $5F : BEQ + - STA $5D -+ RTL - -RainPrevention: - LDA $00 : XBA : AND #$00FF : STA.b $0A ; what we wrote over - PHA - LDA $7EF3C5 : AND #$00FF : CMP #$0002 : !BGE .done ; only in rain states (0 or 1) - LDA.l $7EF3C6 : AND #$0004 : BNE .done ; zelda's been rescued - LDA.l BlockSanctuaryDoorInRain : BEQ .done ;flagged - LDA $A0 : CMP #$0012 : BNE + ;we're in the sanctuary - LDA.l $7EF3CC : AND #$00FF : CMP #$0001 : BEQ .done ; zelda is following - LDA $00 : AND #$00FF : CMP #$00A1 : BNE .done ; position is a1 - PLA : LDA #$0008 : RTL - + LDA.l BlockCastleDoorsInRain : AND #$00FF : BEQ .done ;flagged - LDX #$FFFE - - INX #2 : LDA.l RemoveRainDoorsRoom, X : CMP #$FFFF : BEQ .done - CMP $A0 : BNE - - SEP #$20 : LDA.l RainDoorMatch, X : CMP $00 : BNE .continue - REP #$20 : PLA : SEC : RTL - .continue - REP #$20 : BRA - - .done PLA : CLC : RTL - -; A should be how much dmg to do to Aga when leaving this function -StandardAgaDmg: - LDX.b #$00 ; part of what we wrote over - LDA.l $7EF3C6 : AND #$04 : BEQ + ; zelda's not been rescued - LDA.b #$10 ; hurt him! - + RTL ; A is zero if the AND results in zero and then Agahnim's invincible! - -; note: this skips both maiden dialog triggers if the hole is open -BlindsAtticHint: - REP #$20 - CMP.w #$0122 : BNE + - LDA $7EF0CA : AND.w #$0100 : BEQ + - SEP #$20 : RTL ; skip the dialog box if the hole is already open - + SEP #$20 : JML Main_ShowTextMessage - diff --git a/asm/owrando.asm b/asm/owrando.asm deleted file mode 100644 index 3c0c022c..00000000 --- a/asm/owrando.asm +++ /dev/null @@ -1,1821 +0,0 @@ -org $aa8000 ;150000 -db $4f, $52 ;OR -OWMode: -dw 0 -OWFlags: -dw 0 -OWReserved: -dw 0 -org $aa8010 -OWVersionInfo: -dw $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000 - -;Hooks -org $82a929 -OWDetectTransitionReturn: - -org $82a939 -OverworldHandleTransitions_SpecialTrigger: -JSL OWDetectEdgeTransition -BCS OWDetectTransitionReturn - -org $82a999 -jsl OWEdgeTransition : nop #4 ;LDA $02A4E3,X : ORA $7EF3CA - -org $82aa07 -JSL OWMarkVisited : NOP - -org $84e8ae -JSL OWDetectSpecialTransition -RTL : NOP - -org $82e809 -JSL OWSpecialExit - -org $82bfe8 -JSL OWAdjustExitPosition - -org $82c1a9 -JSL OWEndScrollTransition - -org $84E881 -Overworld_LoadSpecialOverworld_RoomId: -org $84E8B4 -Overworld_LoadSpecialOverworld: - -org $84E96A -JSL OWSpecialReturnTriggerClear - -org $82A9DA -JSL OWSkipPalettes -BCC OverworldHandleTransitions_change_palettes : NOP #4 - -org $87982A -Link_ResetSwimmingState: - - -; mirror hooks -org $8283DC ; override world check when spawning mirror portal sprite in Crossed OWR -jsl OWLightWorldOrCrossed -org $85AF75 -Sprite_6C_MirrorPortal: -jsl OWMirrorSpriteDisable ; LDA $7EF3CA -org $85AF88 -jsl OWMirrorSpriteSkipDraw : NOP ; LDA.w $0FC6 : CMP.b #$03 -org $85AFDF -Sprite_6C_MirrorPortal_missing_mirror: -org $8ABFB6 -jsl OWMirrorSpriteOnMap : NOP ; LDA.w $008A : CMP.b #$40 - -; whirlpool shuffle cross world change -org $82b3bd -jsl OWWhirlpoolUpdate ;JSL $02EA6C -org $82B44E -jsl OWWhirlpoolEnd ; STZ.b $11 : STZ.b $B0 - -; flute menu cancel -org $8ab7af ;LDA $F2 : ORA $F0 : AND #$C0 -jml OWFluteCancel2 : nop -org $8ab90d ;JSL $02E99D -jsl OWFluteCancel -org $8ab816 -JSL OWMapFluteCancelIcon - -; allows Frog sprite to spawn in LW and also allows his friend to spawn in their house -org $868a76 ; < 30a76 - sprite_prep.asm:785 (LDA $7EF3CA : AND.w #$40) -lda.b IndoorsFlag : eor.b #1 : nop #2 - -; allows Frog to be accepted at Blacksmith -org $86b3ee ; < 333ee - sprite_smithy_bros.asm:347 (LDA $7EF3CC : CMP.b #$08 : BEQ .no_returning_smithy_tagalong) -jsl OWSmithAccept : nop #2 -db #$b0 ; BCS to replace BEQ - -; load Stumpy per screen's original world, not current world flag -org $86907f ; < 3107f - sprite_prep.asm:2170 (LDA $7EF3CA) -lda.b OverworldIndex : and.b #$40 - -; override Link speed with Old Man following -org $89a32e ; < 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) -;org $89c957 ; <- 4c957 -;dw #$cb5f ; matches value on Central Bonk Rocks screen - -; override world check when viewing overworld (incl. title screen portion) -org $8aba6c ; < ? - Bank0a.asm:474 () -jsl OWMapWorldCheck16 : nop - -; Mixed Overworld Map -org $8ABA99 -WorldMap_LoadDarkWorldMap: -LDA.b GameMode : CMP.b #$14 ; attract module -BEQ .vanilla_light - LDA.l OWMode+1 : AND.b #!FLAG_OW_MIXED : BNE .mixed - LDA.b OverworldIndex : AND.b #$40 - BEQ .vanilla_light - .mixed - PHB : PHK : PLB - JSL LoadMapDarkOrMixed - PLB -.vanilla_light ; $0ABAB5 - -;(replacing -> LDA $8A : AND.b #$40) -org $80d8c4 ; < ? - Bank00.asm:4068 () -jsl OWWorldCheck -org $82aa36 ; < ? - Bank02.asm:6559 () -jsl OWWorldCheck -org $82aeca ; < ? - Bank02.asm:7257 () -jsl OWWorldCheck16 : nop -org $82b349 ; < ? - Bank02.asm:7902 () -jsl OWWorldCheck -org $82c40a ; < ? - Bank02.asm:10547 () -jsl OWWorldCheck -org $85afd9 ; < ? - sprite_warp_vortex.asm:60 () -jsl OWWorldCheck -org $87a3f0 ; < ? - Bank07.asm:5772 () ; flute activation/use -jsl OWWorldCheck -org $87a967 ; < ? - Bank07.asm:6578 () -jsl OWWorldCheck -org $87a9a1 ; < ? - Bank07.asm:6622 () -jsl OWWorldCheck -org $87a9ed ; < ? - Bank07.asm:6677 () -jsl OWWorldCheck -org $87aa34 ; < ? - Bank07.asm:6718 () -jsl OWWorldCheck -org $88d408 ; < ? - ancilla_morph_poof.asm:48 () -jsl OWWorldCheck -org $8bfeab ; < ? - Bank0b.asm:36 () -jsl OWWorldCheck16 : nop -org $8cffb6 ; < ? - ?.asm ? () -jsl OWWorldCheck16 : nop -org $8cffe8 ; < ? - ?.asm ? () -jsl OWWorldCheck16 : nop -org $9beca2 ; < ? - palettes.asm:556 () -jsl OWWorldCheck16 : nop -org $9bed95 ; < ? - palettes.asm:748 () -jsl OWWorldCheck16 : nop - -org $82B16C ; LDA $8A : AND #$3F : ORA 7EF3CA -JSL OWApplyWorld : BRA + : NOP #2 : + - -org $89C3C4 -jsl OWBonkDropPrepSprite : nop #2 -org $89C801 -jsl OWBonkDropPrepSprite : nop #2 -org $86D052 -jsl OWBonkDropSparkle -org $86AD49 -jsl OWBonkDropsOverworld : nop -org $9EDE6A -jsl OWBonkDropSparkle : BNE GoldBee_Dormant_exit -jsl OWBonkDropsUnderworld : bra + -GoldBee_SpawnSelf_SetProperties: -phb : lda.b #$1E : pha : plb ; switch to bank 1E - jsr GoldBee_SpawnSelf+12 -plb : rtl -nop #2 -+ - -;Code -org $aa8800 -OWTransitionDirection: -dw 3, 2, 1, 0 ; $02 after $02A932 -OWEdgeDataOffset: -dw OWSouthEdges, OWEastEdges, OWSouthEdges -OWCoordIndex: ; Horizontal 1st -db 2, 2, 0, 0 ; Coordinate Index $20-$23 -OWOppCoordIndex: ; Horizontal 1st -db 0, 0, 2, 2 ; Coordinate Index $20-$23 -OWBGIndex: ; Horizontal 1st -db 0, 0, 6, 6 ; BG Scroll Index $e0-$eb -OWOppBGIndex: ; Horizontal 1st -db 6, 6, 0, 0 ; BG Scroll Index $e0-$eb -OWCameraIndex: ; Horizontal 1st -db 4, 4, 0, 0 ; Camera Index $0618-$61f -OWOppCameraIndex: ; Horizontal 1st -db 0, 0, 4, 4 ; Camera Index $0618-$61f -OWOppSlotOffset: ; Amount to offset OW Slot -db 8, -8, 1, -1 ; OW Slot x2 $700 -OWOppDirectionOffset: ; Amount to offset coord calc -db $10, $f0, $02, $fe -OWCameraRangeIndex: -db 2, 2, 0, 0 ; For OWCameraRange -OWCameraRange: -dw $011E, $0100 ; Length of the range the camera can move on small screens -OWAutoWalk: -db $04, $08, $01, $02 - -DivideByTwoPreserveSign: -{ - asl : php : ror : plp : ror : rtl -} - -OWWorldCheck: -{ - phx - ldx.b OverworldIndex : lda.l OWTileWorldAssoc,x - plx : and.b #$ff : rtl -} -OWWorldCheck16: -{ - phx - ldx.b OverworldIndex : lda.l OWTileWorldAssoc,x - plx : and.w #$00ff : rtl -} -OWMapWorldCheck16: -{ - lda.b GameMode : cmp.w #$0014 : beq .return ; attract module, return with Z flag cleared - jsl OWWorldCheck16 - .return - rtl -} -OWApplyWorld: -{ - LDX.b OverworldIndex - - .fromScreen - LDA.l OWTileWorldAssoc,X : CMP.l CurrentWorld : BEQ .keepWorld ; if dest screen mismatches the current world - TXA : EOR.b #$40 : RTL - - .keepWorld - TXA : RTL -} - -OWWhirlpoolUpdate: -{ - jsl FindPartnerWhirlpoolExit ; what we wrote over - ldx.b OverworldIndex : ldy.b #$03 : jsr OWWorldTerrainUpdate - rtl -} - -OWWhirlpoolEnd: -{ - STZ.b SubSubModule ; what we wrote over - LDA.w RandoOverworldForceTrans : BEQ .normal - LDA.b #$3C : STA.w SFX2 ; play error sound before forced transition - RTL - .normal - STZ.b GameSubMode ; end whirlpool transition - RTL -} - -OWDestroyItemSprites: -{ - PHX : LDX.b #$0F - .nextSprite - LDA.w SpriteTypeTable,X - CMP.b #$D8 : BCC .continue - CMP.b #$EC : BCS .continue - .killSprite ; need to kill sprites from D8 to EB on screen transition - STZ.w SpriteAITable,X - .continue - DEX : BPL .nextSprite - PLX : RTL -} - -OWMirrorSpriteOnMap: -{ - JSL OWWorldCheck - CMP.b #$40 ; part of what we wrote over - RTL -} -OWMirrorSpriteDisable: -{ - LDA.b GameMode : CMP.b #$0F : BNE + ; avoid rare freeze during mirror superbunny - PLA : PLA : PLA : JML Sprite_6C_MirrorPortal_missing_mirror - + - - lda.l OWMode+1 : and.b #!FLAG_OW_CROSSED : beq .vanilla - lda.l InvertedMode : beq + - lda.b #$40 - + rtl - - .vanilla - lda.l CurrentWorld ; what we wrote over - rtl -} -OWMirrorSpriteSkipDraw: -{ - lda.l OWMode+1 : and.b #!FLAG_OW_CROSSED : beq .vanilla - lda.l InvertedMode : beq + - lda.l CurrentWorld : eor.b #$40 - bra ++ - + lda.l CurrentWorld : ++ beq .vanilla - stz.w SpriteMovement,x ; disables collision - sec : rtl - - .vanilla - LDA.w GfxChrHalfSlotVerify : CMP.b #$03 ; what we wrote over - RTL -} -OWLightWorldOrCrossed: -{ - lda.l OWMode+1 : and.b #!FLAG_OW_CROSSED : beq ++ - lda.l InvertedMode : beq + - lda.b #$40 - + rtl - ++ jsl OWWorldCheck : rtl -} - -OWFluteCancel: -{ - lda.l OWFlags+1 : and.b #$01 : bne + - jsl FluteMenu_LoadTransport : rtl - + lda.w RandoOverworldTargetEdge : bne + - jsl FluteMenu_LoadTransport - + stz.w RandoOverworldTargetEdge : rtl -} -OWFluteCancel2: -{ - lda.b Joy1B_All : ora.b Joy1A_All : and.b #$c0 : bne + - jml FluteMenu_HandleSelection_NoSelection - + inc.w SubModuleInterface - lda.l OWFlags+1 : and.b #$01 : beq + - lda.b Joy1B_All : cmp.b #$40 : bne + - lda.b #$01 : sta.w RandoOverworldTargetEdge - + rtl -} -OWMapFluteCancelIcon: -{ - STA.b Scrap0B : LDX.b #$10 ; what we wrote over - LDA.l OWFlags+1 : AND.b #$01 : BEQ .return - LDA.b GameSubMode : CMP.b #$0A : BNE .return - LDA.b FrameCounter : AND.b #$10 : BNE .return - LDA.b #$7E : STA.b Scrap0D - LDA.b #$34 : STA.b Scrap0C - STZ.b Scrap0B - LDA.b Scrap0E : CLC : ADC.b #$04 : STA.b Scrap0E - LDA.b Scrap0F : CLC : ADC.b #$04 : STA.b Scrap0F - .return - RTL -} -OWSmithAccept: -{ - lda.l FollowerIndicator : cmp.b #$07 : beq + - cmp.b #$08 : beq + - clc : rtl - + sec : rtl -} -OWOldManSpeed: -{ - lda.b IndoorsFlag : beq .outdoors - lda.b RoomIndex : and.b #$fe : cmp.b #$f0 : beq .vanilla ; if in cave where you find Old Man - bra .normalspeed - .outdoors - lda.b OverworldIndex : cmp.b #$03 : beq .vanilla ; if on WDM screen - - .normalspeed - lda.b LinkSpeed : cmp.b #$0c : rtl - stz.b LinkSpeed : rtl - - .vanilla - lda.b #$0c : sta.b LinkSpeed ; what we wrote over - rtl -} -OWMarkVisited: -{ - LDX.b OverworldIndex : STZ.w $0412 ; what we wrote over - LDA.b GameMode : CMP.b #$14 : BCS .return - LDA.l OverworldEventDataWRAM,X - ORA.b #$80 : STA.l OverworldEventDataWRAM,X - - .return - RTL -} - -LoadMapDarkOrMixed: -{ - CMP.b #!FLAG_OW_MIXED : REP #$30 : BEQ .mixed - LDX.w #$03FE ; draw vanilla Dark World (what we wrote over) - .copy_next - LDA.w WorldMap_DarkWorldTilemap,X : STA.w GFXStripes,X - DEX : DEX : BPL .copy_next - BRL .end - .mixed - LDX.b OverworldIndex - LDA.l OWTileWorldAssoc,X - STA.b Scrap00 - LDY.w #$139C - LDX.w #$003F - .next_screen - PHX - LDA.l OWTileWorldAssoc,X - EOR.b Scrap00 - AND.w #$0040 - BEQ .light - TYX : BRA .copy_screen - .light - TXA : AND.w #$0024 : LSR : TAX - TYA : SEC : SBC.l LWQuadrantOffsets,X - TYX : TAY - .copy_screen ; more efficient to have X on the right side - LDA.w $C739+$00,Y : STA.b $00,X - LDA.w $C739+$02,Y : STA.b $02,X - LDA.w $C739+$20,Y : STA.b $20,X - LDA.w $C739+$22,Y : STA.b $22,X - LDA.w $C739+$40,Y : STA.b $40,X - LDA.w $C739+$42,Y : STA.b $42,X - LDA.w $C739+$60,Y : STA.b $60,X - LDA.w $C739+$62,Y : STA.b $62,X - TXY : PLX - DEY : DEY : DEY : DEY ; move one screen left - TXA : AND.w #$0007 : BNE .same_row - TYA : SEC : SBC.w #$0060 : TAY ; move one screen row up - .same_row - DEX - BPL .next_screen - .end - SEP #$30 - LDA.b #$15 : STA.b NMIINCR ; what we wrote over - RTL - - LWQuadrantOffsets: - dw $1000-$0210 ; top left - dw $0C00-$01F0 ; top right - dw 0,0,0,0,0,0 - dw $0800+$01F0 ; bottom left - dw $0400+$0210 ; bottom right -} - -OWBonkDropPrepSprite: -{ - LDA.b IndoorsFlag : BEQ + - LDA.w $0FB5 ; what we wrote over - PHA - BRA .continue - + - STZ.w SpriteLayer,X : STZ.w SpriteAux,X ; what we wrote over - PHA - - .continue - LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BEQ .return - + LDA.w SpriteTypeTable,X : CMP.b #$D9 : BNE + - LDA.b #$03 : STA.w SpriteLayer,X - BRA .prep - + CMP.b #$B2 : BEQ .prep - PLA : RTL - - .prep - STZ.w SprRedrawFlag,X - PHB : PHK : PLB : PHY - TXY : JSR OWBonkDropLookup : BCC .done - ; found match ; X = rec + 1 - INX : LDA.w OWBonkPrizeData,X : PHA - JSR OWBonkDropCollected : PLA : BCC .done - TYX : LDA.b #$01 : STA.w SprRedrawFlag,X - .done - TYX : PLY : PLB - - .return - PLA : RTL -} - -OWBonkDropSparkle: -{ - LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BEQ .nosparkle - LDA.w $0E90,X : BEQ .nosparkle - LDA.w SprRedrawFlag,X : BNE .nosparkle - LDA.b GameMode : CMP.b #$0E : BEQ .nosparkle - LDA.b LinkState : CMP.b #$08 : BCC + : CMP.b #$0A+1 : BCS + : BRA .nosparkle : + ; skip if we're mid-medallion - JSL Sprite_SpawnSparkleGarnish - ; move sparkle down 1 tile - PHX : TYX : PLY - LDA.l $7FF81E,X : CLC : ADC.b #$10 : STA.l $7FF81E,X - LDA.l $7FF85A,X : ADC.b #$00 : STA.l $7FF85A,X - PHY : TXY : PLX - - .nosparkle - LDA.w SpriteTypeTable,X : CMP.b #$D9 : BEQ .greenrupee - CMP.b #$B2 : BEQ .goodbee - RTL - - .goodbee - LDA.w $0E90,X ; what we wrote over - RTL - - .greenrupee - JSL Sprite_DrawRippleIfInWater ; what we wrote over - RTL -} - -OWBonkDropsUnderworld: -{ - LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BNE .shuffled - .vanilla ; what we wrote over - STZ.w SpriteAITable,X - LDA.l BottleContentsOne : ORA.l BottleContentsTwo - ORA.l BottleContentsThree : ORA.l BottleContentsFour - RTL - - .shuffled - LDA.w SpriteAITable,X : BNE + - BRA .return+1 - + PHY : TXY - JSL OWBonkDrops - - .return - PLY - LDA.b #$08 ; makes original good bee not spawn - RTL -} - -OWBonkDropsOverworld: -{ - LDA.l OWFlags+1 : AND.b #!FLAG_OW_BONKDROP : BNE .shuffled - BRA .vanilla - - .shuffled - LDA.w SpriteAITable,Y : BNE + - BRA .vanilla - + LDA.w SpriteTypeTable,Y : CMP.b #$D9 : BEQ + - BRA .vanilla+3 - + - LDA.b #$00 : STA.w SpriteLayer,Y ; restore proper layer - JSL OWBonkDrops - - .vanilla - LDA.w SpriteTypeTable,Y : CMP.b #$D8 ; what we wrote over - RTL -} - -OWBonkDrops: -{ - PHB : PHK : PLB - LDA.b IndoorsFlag : BEQ + - LDX.b #((UWBonkPrizeData-OWBonkPrizeData)+1) - BRA .found_match - + - JSR OWBonkDropLookup : BCS .found_match - JMP .return+2 - - .found_match - INX : LDA.w OWBonkPrizeData,X : PHX : PHA ; S = FlagBitmask, X (row + 2) - JSR OWBonkDropCollected : PHA : BCS .load_item_and_mw ; S = Collected, FlagBitmask, X (row + 2) - LDA.b #$1B : STA.w SFX3 ; JSL Sound_SetSfx3PanLong ; seems that when you bonk, there is a pending bonk sfx, so we clear that out and replace with reveal secret sfx - ; JSLSpriteSFX_QueueSFX3WithPan - - .load_item_and_mw - LDA.b 3,S : TAX : INX : LDA.w OWBonkPrizeData,X - PHA : INX : LDA.w OWBonkPrizeData,X : BEQ + - ; multiworld item - DEX : PLA ; A = item id; X = row + 3 - JMP .spawn_item - + DEX : PLA ; A = item id; X = row + 3 - - .determine_type ; A = item id; X = row + 3; S = Collected, FlagBitmask, X (row + 2) - CMP.b #$D0 : BNE + - LDA.b #$79 : JMP .sprite_transform ; transform to bees - + CMP.b #$42 : BNE + - JSL Sprite_TransmuteToBomb ; transform a heart to bomb, vanilla behavior - JMP .mark_collected - + CMP.b #$34 : BNE + - LDA.b #$D9 : JMP .sprite_transform ; transform to single rupee - + CMP.b #$35 : BNE + - LDA.b #$DA : JMP .sprite_transform ; transform to blue rupee - + CMP.b #$36 : BNE + - LDA.b #$DB : BRA .sprite_transform ; transform to red rupee - + CMP.b #$27 : BNE + - LDA.b #$DC : BRA .sprite_transform ; transform to 1 bomb - + CMP.b #$28 : BNE + - LDA.b #$DD : BRA .sprite_transform ; transform to 4 bombs - + CMP.b #$31 : BNE + - LDA.b #$DE : BRA .sprite_transform ; transform to 8 bombs - + CMP.b #$45 : BNE + - LDA.b #$DF : BRA .sprite_transform ; transform to small magic - + CMP.b #$D4 : BNE + - LDA.b #$E0 : BRA .sprite_transform ; transform to big magic - + CMP.b #$D6 : BNE + - LDA.b #$79 : JSL OWBonkSpritePrep - JSL GoldBee_SpawnSelf_SetProperties ; transform to good bee - BRA .mark_collected - + CMP.b #$44 : BNE + - LDA.b #$E2 : BRA .sprite_transform ; transform to 10 arrows - + CMP.b #$D1 : BNE + - LDA.b #$AC : BRA .sprite_transform ; transform to apples - + CMP.b #$D2 : BNE + - LDA.b #$E3 : BRA .sprite_transform ; transform to fairy - + CMP.b #$D3 : BNE .spawn_item - INX : INX : LDA.w OWBonkPrizeData,X ; X = row + 5 - CLC : ADC.b #$08 : PHA - LDA.w SpritePosYLow,Y : SEC : SBC.b 1,S : STA.w SpritePosYLow,Y - LDA.w SpritePosYHigh,Y : SBC.b #$00 : STA.w SpritePosYHigh,Y : PLX - LDA.b #$0B ; BRA .sprite_transform ; transform to chicken - - .sprite_transform - JSL OWBonkSpritePrep - - .mark_collected ; S = Collected, FlagBitmask, X (row + 2) - PLA : BNE + ; S = FlagBitmask, X (row + 2) - TYX : JSL Sprite_IsOnscreen : BCC + - LDA.b IndoorsFlag : BEQ ++ - LDA.l RoomDataWRAM[$0120].high : ORA.b 1,S : STA.l RoomDataWRAM[$0120].high - LDA.w $0400 : ORA.b 1,S : STA.w $0400 - BRA .increment_collection - ++ - LDX.b OverworldIndex : LDA.l OverworldEventDataWRAM,X : ORA.b 1,S : STA.l OverworldEventDataWRAM,X - - .increment_collection - REP #$20 - LDA.l TotalItemCounter : INC : STA.l TotalItemCounter - INC.w UpdateHUDFlag - SEP #$20 - + BRA .return - - ; spawn itemget item - .spawn_item ; A = item id ; Y = bonk sprite slot ; S = Collected, FlagBitmask, X (row + 2) - PLX : BEQ + : LDA.b #$00 : STA.w SpriteAITable,Y : BRA .return ; S = FlagBitmask, X (row + 2) - + PHA - - LDA.b #$EB - JSL Sprite_SpawnDynamically+15 ; +15 to skip finding a new slot, use existing sprite - - PLA : STA.w SprSourceItemId, Y - PHX : TYX : PLY - JSL RequestStandingItemVRAMSlot - PHY : TXY : PLX - - ; affects the rate the item moves in the Y/X direction - LDA.b #$00 : STA.w SpriteVelocityY,Y - LDA.b #$0A : STA.w SpriteVelocityX,Y - - LDA.b #$1A : STA.w SpriteVelocityZ,Y ; amount of force (gives height to the arch) - LDA.b #$FF : STA.w EnemyStunTimer,Y ; stun timer - LDA.b #$30 : STA.w SpriteTimerE,Y ; aux delay timer 4 ?? dunno what that means - - LDA.b #$00 : STA.w SpriteLayer,Y ; layer the sprite is on - - LDA.b IndoorsFlag : BEQ + - ; sets the tile type that is underneath the sprite, water - TYX : LDA.b #$09 : STA.l $7FF9C2,X ; TODO: Figure out how to get the game to set this - + - - ; sets bitmask flag, uses free RAM - PLA : STA.w SpriteSpawnStep,Y ; S = X (row + 2) - - ; sets MW player - PLX : INX : INX - LDA.w OWBonkPrizeData,X : STA.w SprItemMWPlayer,Y - ; determines the initial spawn point of item - INX - LDA.w SpritePosYLow,Y : SEC : SBC.w OWBonkPrizeData,X : STA.w SpritePosYLow,Y - LDA.w SpritePosYHigh,Y : SBC.b #$00 : STA.w SpritePosYHigh,Y - - BRA .return+2 - - .return - PLA : PLA : PLB - RTL -} - -; Y = sprite slot; returns X = row + 1 -OWBonkDropLookup: -{ - ; loop thru rando bonk table to find match - LDA.b OverworldIndex - LDX.b #((UWBonkPrizeData-OWBonkPrizeData)-sizeof(OWBonkPrizeTable)) ; 41 bonk items, 6 bytes each - - CMP.w OWBonkPrizeData,X : BNE + - INX - LDA.w SpritePosXLow,Y : LSR A : LSR A : LSR A : LSR A - EOR.w SpritePosYLow,Y : CMP.w OWBonkPrizeData,X : BNE ++ ; X = row + 1 - SEC : RTS - ++ DEX : LDA.b OverworldIndex - + CPX.b #$00 : BNE + - CLC : RTS - + DEX : DEX : DEX : DEX : DEX : DEX : BRA - -} - -; S = FlagBitmask ; returns SEC if collected -OWBonkDropCollected: -{ - ; check if collected - CLC - LDA.b IndoorsFlag : BEQ + - LDA.l RoomDataWRAM[$0120].high : AND.b 3,S : BEQ .return ; S = Collected, FlagBitmask, X (row + 2) - SEC : RTS - + - LDX.b OverworldIndex : LDA.l OverworldEventDataWRAM,X : AND.b 3,S : BEQ .return ; S = Collected, FlagBitmask, X (row + 2) - SEC : RTS - - .return - RTS -} - -; A = SprItemReceipt, Y = Sprite Slot Index, X = free/overwritten -OWBonkSpritePrep: -{ - STA.w SpriteTypeTable,Y - TYX : JSL SpritePrep_LoadProperties - BEQ + - ; these are sprite properties that make it fall out of the tree to the east - LDA.b #$30 : STA.w SpriteVelocityZ,Y ; amount of force (related to speed) - LDA.b #$10 : STA.w SpriteVelocityX,Y ; eastward rate of speed - LDA.b #$FF : STA.w EnemyStunTimer,Y ; expiration timer - + RTL -} - -org $aa9000 -OWDetectEdgeTransition: -{ - JSL OWDestroyItemSprites - STZ.w RandoOverworldWalkDist - LDA.l OWMode : ORA.l OWMode+1 : BEQ .vanilla - JSR OWShuffle - LDA.w RandoOverworldTargetEdge : BMI .special - .vanilla - REP #$31 : LDX.b Scrap02 : LDA.b OverworldMap16Buffer ; what we wrote over - RTL - .special - REP #$30 - AND.w #$0003 : TAY : ASL : TAX - LDA.w #$007F : STA.w RandoOverworldTargetEdge - JSR OWLoadSpecialArea - SEC - RTL -} -OWDetectSpecialTransition: -{ - STZ.w RandoOverworldWalkDist - LDA.l OWMode : BEQ .normal - TXA : AND.w #$0002 : LSR - STA.w RandoOverworldTerrain - LDA.l OWSpecialDestIndex,X : BIT.w #$0080 : BEQ .switch_to_edge - AND.w #$0003 : TAY : ASL : TAX - .normal - JSR OWLoadSpecialArea - .return - RTL - - .switch_to_edge - STA.w RandoOverworldTargetEdge - LDA.l OWEdgeDataOffset,X : STA.w RandoOverworldEdgeAddr - PLA : SEP #$30 : PLA ; delete 3 bytes from stack - JSL Link_CheckForEdgeScreenTransition : BCS .return ; Link_CheckForEdgeScreenTransition - LDA.l Overworld_CheckForSpecialOverworldTrigger_Direction,X : STA.b Scrap00 : CMP.b #$08 : BNE .hobo - LSR : STA.b LinkPosY : STZ.b BG2V ; move Link and camera to edge - LDA.b #$06 : STA.b Scrap02 - STZ.w TransitionDirection - BRA .continue - .hobo - STA.b Scrap02 : STA.w TransitionDirection - ASL : STA.b LinkPosX : STZ.b BG2H ; move Link and camera to edge - LDA.b #$0A : STA.b LinkPosX+1 : STA.b BG2H+1 - .continue - STZ.b Scrap03 - ; copied from DeleteCertainAncillaeStopDashing at $028A0E - JSL Ancilla_TerminateSelectInteractives - LDA.w LinkDashing : BEQ .not_dashing - STZ.b LinkJumping : STZ.b LinkIncapacitatedTimer - LDA.b #$FF : STA.b LinkRecoilZ : STA.b $C7 - STZ.b $3D : STZ.b LinkSpeed : STZ.w $032B : STZ.w LinkDashing : STZ.b LinkState - .not_dashing - PLA : REP #$31 : PLA ; delete 3 bytes from stack - LDX.b Scrap02 - LDA.b OverworldMap16Buffer - JML OverworldHandleTransitions_SpecialTrigger+6 -} -OWEdgeTransition: -{ - LDA.l OWMode : ORA.l OWMode+1 : BEQ .unshuffled - LDY.w RandoOverworldTargetEdge : STZ.w RandoOverworldTargetEdge - CPY.b #$7F : BEQ .unshuffled - REP #$10 - LDX.w RandoOverworldEdgeAddr - PHB : PHK : PLB - JSR OWNewDestination - PLB - SEP #$30 - RTL - - .unshuffled - LDA.l Overworld_ActualScreenID,X : ORA.l CurrentWorld ; what we wrote over - TAX : LDA.l OWMode+1 : AND.b #!FLAG_OW_MIXED : BEQ .vanilla - JML OWApplyWorld_fromScreen - - .vanilla - TXA : RTL -} -OWSpecialExit: -{ - LDA.l OWMode : ORA.l OWMode+1 : BEQ .vanilla - PHY - LDY.b #$00 - LDA.w TransitionDirection : LSR : BNE + - LDY.w RandoOverworldTerrain : BRA ++ - + - LDA.w RandoOverworldTerrain : BNE ++ - LDY.b #$02 - ++ - JSR OWWorldTerrainUpdate - PLY - .vanilla - LDA.l $7EFD40,X ; what we wrote over - RTL -} -OWShuffle: -{ - ;determine direction of edge transition - phx : lsr.w OverworldSlotPosition - tyx : lda.l OWTransitionDirection,X : sta.w TransitionDirection - - .setOWID - ;look up transitions in current area in table OWEdgeOffsets - ;offset is (8bytes * OW Slot ID) + (2bytes * direction) - asl : rep #$20 : and.w #$00ff : pha : sep #$20 ;2 bytes per direction - - ldx.b OverworldIndex : lda.l OWTileWorldAssoc,X : eor.l CurrentWorld : beq + - ; fake world, will treat this OW area as opposite world - txa : eor.b #$40 : tax - + txa : and.b #$40 : !ADD.w OverworldSlotPosition : rep #$30 : and.w #$00ff : asl #3 - - adc.b 1,S : tax - asl.w OverworldSlotPosition : pla - ;x = offset to edgeoffsets table - - sep #$20 : lda.l OWEdgeOffsets,x : and.b #$ff : beq .noTransition : pha ;get number of transitions - ;s1 = number of transitions left to check - - inx : lda.l OWEdgeOffsets,x ;record id of first transition in table - ;multiply ^ by 16, 16bytes per record - sta.w CPUMULTA : lda.b #16 : sta.w CPUMULTB ;wait 8 cycles - pla ;a = number of trans - rep #$20 - and.w #$00ff - ldx.w CPUPRODUCT ;x = offset to first record - - .nextTransition - pha - jsr OWSearchTransition_entry : bcs .newDestination - txa : !ADD.w #$0010 : tax - pla : dec : bne .nextTransition : bra .noTransition - - .newDestination - pla : sep #$30 : plx : rts - - .noTransition - sep #$30 : plx - lda.b #$7f : sta.w RandoOverworldTargetEdge - - .return - rts -} -OWSearchTransition: -{ - .exitloop ; moved here because of branch distance - clc : rts - - .entry - ;A-16 XY-16 - lda.w TransitionDirection : bne + ;north - lda.l OWNorthEdges,x : dec - cmp.b LinkPosX : !BGE .exitloop - lda.l OWNorthEdges+2,x : cmp.b LinkPosX : !BLT .exitloop - ;MATCH - lda.l OWNorthEdges+14,x : tay ;y = record id of dest - lda.l OWNorthEdges+12,x ;a = current terrain - ldx.w #OWSouthEdges ;x = address of table - bra .matchfound - + dec : bne + ;south - lda.l OWSouthEdges,x : dec - cmp.b LinkPosX : !BGE .exitloop - lda.l OWSouthEdges+2,x : cmp.b LinkPosX : !BLT .exitloop - ;MATCH - lda.l OWSouthEdges+14,x : tay ;y = record id of dest - lda.l OWSouthEdges+12,x ;a = current terrain - ldx.w #OWNorthEdges ;x = address of table - bra .matchfound - + dec : bne + ; west - lda.l OWWestEdges,x : dec - cmp.b LinkPosY : !BGE .exitloop - lda.l OWWestEdges+2,x : cmp.b LinkPosY : !BLT .exitloop - ;MATCH - lda.l OWWestEdges+14,x : tay ;y = record id of dest - lda.l OWWestEdges+12,x ;a = current terrain - ldx.w #OWEastEdges ;x = address of table - bra .matchfound - + lda.l OWEastEdges,x : dec ;east - cmp.b LinkPosY : !BGE .exitloop - lda.l OWEastEdges+2,x : cmp.b LinkPosY : !BLT .exitloop - ;MATCH - lda.l OWEastEdges+14,x : tay ;y = record id of dest - lda.l OWEastEdges+12,x ;a = current terrain - ldx.w #OWWestEdges ;x = address of table - - .matchfound - stx.w RandoOverworldEdgeAddr : sty.w RandoOverworldTargetEdge : sta.w RandoOverworldTerrain : sec : rts - plx : pla : pea.w $0001 : phx - sec : rts -} -OWNewDestination: -{ - tya : sta.w CPUMULTA : lda.b #16 : sta.w CPUMULTB ;wait 8 cycles - rep #$20 : txa : nop : !ADD.w CPUPRODUCT : tax ;a = offset to dest record - lda.w $0008,x : sta.b Scrap04 ;save dest OW slot/ID - ldy.b LinkPosY : lda.w TransitionDirection : dec #2 : bpl + : ldy.b LinkPosX : + sty.b Scrap06 - - ;;22 e0 e2 61c 61e - X - ;;20 e6 e8 618 61a - Y - ;keep current position if within incoming gap - lda.w $0000,x : and.w #$01ff : pha : lda.w $0002,x : and.w #$01ff : pha - LDA.l OWMode : AND.w #$0007 : BEQ .noLayoutShuffle ;temporary fix until VRAM issues are solved - lda.w $0006,x : sta.b Scrap06 ;set coord - lda.w $000a,x : sta.b OverworldMap16Buffer ;VRAM - tya : and.w #$01ff : cmp.b 3,s : !BLT .adjustMainAxis - dec : cmp.b 1,s : !BGE .adjustMainAxis - inc : pha : lda.b Scrap06 : and.w #$fe00 : !ADD.b 1,s : sta.b Scrap06 : pla - - ; adjust and set other VRAM addresses - lda.w $0006,x : pha : lda.b Scrap06 : !SUB 1,s - jsl DivideByTwoPreserveSign : jsl DivideByTwoPreserveSign : jsl DivideByTwoPreserveSign : jsl DivideByTwoPreserveSign : pha ; number of tiles - lda.w TransitionDirection : dec #2 : bmi + - pla : pea.w $0000 : bra ++ ;pla : asl #7 : pha : bra ++ ; y-axis shifts VRAM by increments of 0x80 (disabled for now) - + pla : asl : pha ; x-axis shifts VRAM by increments of 0x02 - ++ lda.b OverworldMap16Buffer : !ADD.b 1,s : sta.b OverworldMap16Buffer : pla : pla - - .adjustMainAxis - LDA.b OverworldMap16Buffer : SEC : SBC.w #$0400 : AND.w #$0F00 : ASL : XBA : STA.b OverworldTilemapIndexY ; vram - LDA.b OverworldMap16Buffer : SEC : SBC.w #$0010 : AND.w #$003E : LSR : STA.b OverworldTilemapIndexX - - .noLayoutShuffle - LDA.w $000F,X : AND.w #$00FF : STA.w RandoOverworldWalkDist ; position to walk to after transition (if non-zero) - - LDY.w #$0000 - LDA.w $000C,X : AND.w #$0001 : BEQ + ; check if going to water transition - LDA.w RandoOverworldTerrain : AND.w #$0001 : BNE ++ ; check if coming from water transition - INY : BRA ++ - + - LDA.w RandoOverworldTerrain : BEQ ++ ; check if coming from water transition - LDY.w #$0002 - ++ - STY.b Scrap08 - - pla : pla : sep #$10 : ldy.w TransitionDirection - ldx.w OWCoordIndex,y : lda.b LinkPosY,x : and.w #$fe00 : pha - lda.b LinkPosY,x : and.w #$01ff : pha ;s1 = relative cur, s3 = ow cur - lda.b Scrap06 : and.w #$fe00 : !SUB.b 3,s : pha ;set coord, s1 = ow diff, s3 = relative cur, s5 = ow cur - lda.b Scrap06 : and.w #$01ff : !SUB.b 3,s : pha ;s1 = rel diff, s3 = ow diff, s5 = relative cur, s7 = ow cur - lda.b Scrap06 : sta.b LinkPosY,x : and.w #$fe00 : sta.b Scrap06 ;set coord - ldx.w OWBGIndex,y : lda.b BG2H,x : !ADD.b 1,s : adc.b 3,s : sta.b BG2H,x - ldx.w OWCameraIndex,y : lda.w CameraScrollN,x : !ADD.b 1,s : adc.b 3,s : sta.w CameraScrollN,x - ldx.w OWCameraIndex,y : lda.w CameraScrollS,x : !ADD.b 1,s : adc.b 3,s : sta.w CameraScrollS,x - pla : jsl DivideByTwoPreserveSign : pha - ldx.w OWBGIndex,y : lda.b BG1H,x : !ADD.b 1,s : sta.b BG1H,x : pla - ldx.w OWBGIndex,y : lda.b BG1H,x : !ADD.b 1,s : sta.b BG1H,x : pla - pla : pla - - ;fix camera unlock - lda.b BG2H,x : !SUB.b Scrap06 : bpl + - pha : lda.b Scrap06 : sta.b BG2H,x - ldx.w OWCameraIndex,y : lda.w CameraScrollN,x : !SUB.b 1,s : sta.w CameraScrollN,x - lda.w CameraScrollS,x : !SUB.b 1,s : sta.w CameraScrollS,x : pla - bra .adjustOppositeAxis - + lda.b Scrap06 : ldx.w OWCameraRangeIndex,y : !ADD.w OWCameraRange,x : sta.b Scrap06 - ldx.w OWBGIndex,y : !SUB.b BG2H,x : bcs .adjustOppositeAxis - pha : lda.b Scrap06 : sta.b BG2H,x - ldx.w OWCameraIndex,y : lda.w CameraScrollN,x : !ADD.b 1,s : sta.w CameraScrollN,x - lda.w CameraScrollS,x : !ADD.b 1,s : sta.w CameraScrollS,x : pla - - .adjustOppositeAxis - ;opposite coord stuff - rep #$30 : lda.w OWOppDirectionOffset,y : and.w #$00ff : bit.w #$0080 : beq + - ora.w #$ff00 ;extend 8-bit negative to 16-bit negative - + pha : cpy.w #$0002 : lda.w OverworldSlotPosition : !BGE + - and.w #$00f0 : pha : lda.b Scrap04 : asl : and.w #$0070 : !SUB.b 1,s : tax : pla : txa - !ADD.b 1,s : tax : pla : txa : asl : asl : asl : asl : asl : pha : bra ++ - + and.w #$000f : pha : lda.b Scrap04 : asl : and.w #$000f : !SUB.b 1,s : !ADD.b 3,s - sep #$10 : tax : phx : ldx.b #$0 : phx : rep #$10 : pla : plx : plx : pha - - ++ sep #$10 : ldx.w OWOppCoordIndex,y : lda.b LinkPosY,x : !ADD.b 1,s : sta.b LinkPosY,x ;set coord - ldx.w OWOppBGIndex,y : lda.b BG2H,x : !ADD.b 1,s : sta.b BG2H,x - ldx.w OWOppCameraIndex,y : lda.w CameraScrollN,x : !ADD.b 1,s : sta.w CameraScrollN,x - ldx.w OWOppCameraIndex,y : lda.w CameraScrollS,x : !ADD.b 1,s : sta.w CameraScrollS,x - ldx.w OWOppBGIndex,y : lda.b BG1H,x : !ADD.b 1,s : sta.b BG1H,x - lda.w TransitionDirection : asl : tax : lda.w CameraTargetN,x : !ADD.b 1,s : sta.w CameraTargetN,x : pla - - sep #$30 : lda.b Scrap04 : and.b #$3f : !ADD.w OWOppSlotOffset,y : asl : sta.w OverworldSlotPosition - - ; crossed OW shuffle and terrain - ldx.b Scrap05 : ldy.b Scrap08 : jsr OWWorldTerrainUpdate - - ldx.b OverworldIndex : lda.b Scrap05 : sta.b OverworldIndex : stx.b Scrap05 ; $05 is prev screen id, $8a is dest screen - - jsr OWGfxUpdate - - lda.b OverworldIndex - rep #$30 : rts -} -OWLoadSpecialArea: -{ - LDA.l Overworld_LoadSpecialOverworld_RoomId,X : STA.b RoomIndex - JSL Overworld_LoadSpecialOverworld ; sets M and X flags - TYX - LDY.b #$00 - CPX.b #$01 : BNE + ; check if going to water transition - LDA.w RandoOverworldTerrain : BNE ++ ; check if coming from water transition - INY : BRA ++ - + - LDA.w RandoOverworldTerrain : BEQ ++ ; check if coming from water transition - LDY.b #$02 - ++ - LDA.l OWSpecialDestSlot,X : TAX - JSR OWWorldTerrainUpdate - .return - RTS -} -OWWorldTerrainUpdate: ; x = owid of destination screen, y = 1 for land to water, 2 for water to land, 3 for whirlpools and 0 else -{ - LDA.l OWMode+1 : AND.b #!FLAG_OW_CROSSED : BEQ .not_crossed - LDA.l OWTileWorldAssoc,x : CMP.l CurrentWorld : BNE .crossed - .not_crossed - JMP .normal - .crossed - sta.l CurrentWorld ; change world - - ; moving mirror portal off screen when in DW - cmp.b #0 : beq + : lda.b #1 - + cmp.l InvertedMode : bne + - lda.w MirrorPortalPosXH : and.b #$0f : sta.w MirrorPortalPosXH : bra .playSfx ; bring portal back into position - + lda.w MirrorPortalPosXH : ora.b #$40 : sta.w MirrorPortalPosXH ; move portal off screen - - .playSfx - lda.b #$38 : sta.w SFX3 ; play sfx - #$3b is an alternative - - ; toggle bunny mode - lda.l MoonPearlEquipment : beq + : jmp .nobunny - + lda.l InvertedMode : bne .inverted - lda.l CurrentWorld : bra + - .inverted lda.l CurrentWorld : eor.b #$40 - + and.b #$40 : beq .nobunny - LDA.w RandoOverworldForceTrans : BEQ + ; check if forced transition - CPY.b #$03 : BEQ ++ - LDA.b #$17 : STA.b LinkState - LDA.b #$01 : STA.w BunnyFlag : STA.b BunnyFlagDP - LDA.w RandoOverworldForceTrans : JSR OWLoadGearPalettes : BRA .end_forced_edge - ++ JSR OWLoadGearPalettes : BRA .end_forced_whirlpool - + - CPY.b #$01 : BEQ .auto ; check if going from land to water - CPY.b #$02 : BEQ .to_bunny_reset_swim ; bunny state if swimming to land - LDA.b LinkState : CMP.b #$04 : BNE .to_bunny ; check if swimming - .auto - PHX - LDA.b #$01 - LDX.b LinkState : CPX.b #$04 : BNE + - INC - + - STA.w RandoOverworldForceTrans - CPY.b #$03 : BEQ .whirlpool - LDA.b #$01 : STA.w LinkDeepWater - LDX.w TransitionDirection - LDA.l OWAutoWalk,X : STA.b ForceMove - STZ.b LinkState - PLX - BRA .to_pseudo_bunny - .whirlpool - PLX : JMP OWLoadGearPalettes - .to_bunny_reset_swim - LDA.b LinkState : CMP.b #$04 : BNE .to_bunny ; check if swimming - JSL Link_ResetSwimmingState - STZ.w LinkDeepWater - .to_bunny - LDA.b #$17 : STA.b LinkState - .to_pseudo_bunny - LDA.b #$01 : STA.w BunnyFlag : STA.b BunnyFlagDP - JMP OWLoadGearPalettes - - .nobunny - lda.b LinkState : cmp.b #$17 : bne + ; retain current state unless bunny - stz.b LinkState - + stz.w BunnyFlag : stz.b BunnyFlagDP - - .normal - LDA.w RandoOverworldForceTrans : BEQ .not_forced ; check if forced transition - CPY.b #$03 : BEQ .end_forced_whirlpool - .end_forced_edge - STZ.b ForceMove : STZ.w LinkDeepWater - .end_forced_whirlpool - STZ.w RandoOverworldForceTrans - CMP.b #$02 : BNE + - DEC : STA.w LinkDeepWater : STZ.w LinkSwimDirection - LDA.b #$04 : BRA .set_state - + - CMP.b #$03 : BNE ++ - LDA.b #$17 - .set_state - STA.b LinkState - ++ - RTS - .not_forced - CPY.b #$02 : BNE + ; check if going from water to land - LDA.b LinkState : CMP.b #$04 : BNE .return ; check if swimming - JSL Link_ResetSwimmingState - STZ.w LinkDeepWater - STZ.b LinkState - + - CPY.b #$01 : BNE .return ; check if going from land to water - LDA.b LinkState : CMP.b #$04 : BEQ .return ; check if swimming - LDA.b #$01 : STA.w LinkDeepWater - LDA.l FlippersEquipment : BEQ .no_flippers ; check if flippers obtained - LDA.b LinkState : CMP.b #$17 : BEQ .no_flippers ; check if bunny - LDA.b #$04 : STA.b LinkState : STZ.w LinkSwimDirection : RTS - .no_flippers - PHX - INC : STA.w RandoOverworldForceTrans - LDX.w TransitionDirection - LDA.l OWAutoWalk,X : STA.b ForceMove - PLX - LDA.b LinkState : CMP.b #$17 : BNE .return ; check if bunny - LDA.b #$03 : STA.w RandoOverworldForceTrans - STZ.b LinkState - .return - RTS -} -OWGfxUpdate: -{ - REP #$20 : LDA.l OWMode : AND.w #$0207 : BEQ .is_only_mixed : SEP #$20 - ;;;;PLA : AND.b #$3F : BEQ .leaving_woods - LDA.b OverworldIndex : AND.b #$3F : BEQ .entering_woods - ;LDA.b Scrap05 : JSL OWSkipPalettes : BCS .skip_palettes - LDA.b OverworldIndex : JSR OWDetermineScreensPaletteSet - CPX.w $0AB3 : BEQ .skip_palettes ; check if next screen's palette is different - LDA.b Scrap00 : PHA - JSL OverworldLoadScreensPaletteSet_long ; loading correct OW palette - PLA : STA.b Scrap00 - .leaving_woods - .entering_woods - .is_only_mixed - .skip_palettes - SEP #$20 -} -OWLoadGearPalettes: -{ - PHX : PHY : LDA.b Scrap00 : PHA - LDA.w BunnyFlag : BEQ + - JSL LoadGearPalettes_bunny - BRA .return - + - JSL LoadGearPalettes_link - .return - PLA : STA.b Scrap00 : PLY : PLX - RTS -} -OWDetermineScreensPaletteSet: ; A = OWID to check -{ - LDX.b #$02 - PHA : AND.b #$3F - CMP.b #$03 : BEQ .death_mountain - CMP.b #$05 : BEQ .death_mountain - CMP.b #$07 : BEQ .death_mountain - LDX.b #$00 - .death_mountain - PLA : PHX : TAX : LDA.l OWTileWorldAssoc,X : BEQ + - PLX : INX : RTS - + PLX : RTS -} -OWSkipPalettes: -{ - STA.b Scrap05 ; A = previous screen, also stored in $05 - ; only skip mosaic if OWR Layout or Crossed - PHP : REP #$20 : LDA.l OWMode : AND.w #$0207 : BEQ .vanilla : PLP - ; checks to see if going to from any DM screens - ;LDA.b Scrap05 : JSR OWDetermineScreensPaletteSet : TXA : AND.b #$FE : STA.b Scrap04 - ;LDA.b OverworldIndex : JSR OWDetermineScreensPaletteSet : TXA : AND.b #$FE - ;CMP.b Scrap04 : BNE .skip_palettes - BRA .vanilla+1 - - .vanilla - PLP - LDA.b Scrap05 : AND.b #$3F : BEQ .skip_palettes ; what we - LDA.b OverworldIndex : AND.b #$BF : BNE .change_palettes ; wrote over, kinda - .skip_palettes - SEC : RTL ; mosaic transition occurs - .change_palettes - CLC : RTL -} -OWAdjustExitPosition: -{ - LDA.w RandoOverworldWalkDist : CMP.b #$60 : BEQ .stone_bridge - CMP.b #$B0 : BNE .normal - LDA.b #$80 : STA.b LinkPosY : STZ.b LinkPosY+1 - BRA .normal - .stone_bridge - LDA.b #$A0 : STA.b BG2H - LDA.b #$3D : STA.w CameraScrollW - LDA.b #$3B : STA.w CameraScrollE - INC.b LinkPosX+1 : INC.w CameraScrollW+1 : INC.w CameraScrollE+1 - .normal - LDA.w RandoOverworldForceTrans : BEQ + - LDA.b #$3C : STA.w SFX2 ; play error sound before forced transition - + - INC.b GameSubMode : STZ.b SubSubModule ; what we wrote over - RTL -} -OWEndScrollTransition: -{ - LDY.w RandoOverworldWalkDist : BEQ .normal - CMP.w RandoOverworldWalkDist - RTL - .normal - CMP.l Overworld_FinalizeEntryOntoScreen_Data,X ; what we wrote over - RTL -} -OWSpecialReturnTriggerClear: -{ - STZ.b SubSubModule : STZ.b RoomIndex ; what we wrote over - STZ.w RandoOverworldTargetEdge - RTL -} - -;Data -org $aaa000 -OWEdgeOffsets: -;2 bytes per each direction per each OW Slot, order is NSWE per value at $0418 -;AABB, A = offset to the transition table, B = number of transitions -dw $0000, $0000, $0000, $0000 ;OW Slot 00, OWID 0x00 Lost Woods -dw $0000, $0000, $0000, $0001 ;OW Slot 01, OWID 0x00 -dw $0000, $0001, $0001, $0000 ;OW Slot 02, OWID 0x02 Lumberjack -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $0101 -dw $0000, $0000, $0101, $0000 -dw $0000, $0000, $0000, $0201 -dw $0000, $0000, $0201, $0000 - -dw $0000, $0102, $0000, $0000 -dw $0000, $0301, $0000, $0000 -dw $0101, $0401, $0000, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $0301 -dw $0000, $0000, $0301, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0501, $0000, $0000 ;Zora - -dw $0302, $0602, $0000, $0000 -dw $0501, $0801, $0000, $0402 -dw $0601, $0902, $0402, $0602 -dw $0000, $0000, $0602, $0801 -dw $0000, $0000, $0801, $0901 -dw $0000, $0b03, $0901, $0a03 -dw $0000, $0000, $0a03, $0d02 -dw $0701, $0000, $0d02, $0000 - -dw $0802, $0000, $0000, $0000 ;OW Slot 18, OWID 0x18 Kakariko -dw $0a01, $0000, $0000, $0000 -dw $0b02, $0000, $0000, $0f01 -dw $0000, $0000, $0f01, $0000 -dw $0000, $0000, $0000, $0000 -dw $0d03, $0e01, $0000, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $0000 - -dw $0000, $0000, $0000, $0000 -dw $0000, $0f01, $0000, $1001 -dw $0000, $0000, $1001, $0000 -dw $0000, $1001, $0000, $0000 -dw $0000, $1101, $0000, $1101 -dw $1001, $1201, $1101, $0000 -dw $0000, $1301, $0000, $0000 -dw $0000, $1401, $0000, $0000 - -dw $0000, $0000, $0000, $1201 -dw $1101, $0000, $1201, $1301 -dw $0000, $1502, $1301, $0000 -dw $1201, $1701, $0000, $1403 -dw $1301, $1801, $1403, $1701 ;Links -dw $1401, $1901, $1801, $1802 ;Hobo -dw $1501, $1a02, $1902, $0000 -dw $1601, $0000, $0000, $0000 - -dw $0000, $0000, $0000, $0000 ;OW Slot 30, OWID 0x30 Desert -dw $0000, $0000, $0000, $0000 -dw $1702, $0000, $0000, $1a01 -dw $1901, $1c01, $1b01, $1b03 -dw $1a01, $1d01, $1c03, $0000 -dw $1b01, $0000, $0000, $0000 -dw $1c02, $0000, $0000, $0000 -dw $0000, $1e02, $0000, $0000 - -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $1e02 -dw $0000, $0000, $1f02, $2002 -dw $1e01, $0000, $2102, $2201 -dw $1f01, $0000, $2301, $2301 -dw $0000, $0000, $2401, $0000 -dw $0000, $0000, $0000, $2402 -dw $2002, $0000, $2502, $0000 - -dw $0000, $0000, $0000, $0000 ;OW Slot 40, OWID 0x40 Skull Woods -dw $0000, $0000, $0000, $2601 -dw $0000, $2001, $2701, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $2701 -dw $0000, $0000, $2801, $0000 -dw $0000, $0000, $0000, $2801 -dw $0000, $0000, $2901, $0000 - -dw $0000, $2102, $0000, $0000 -dw $0000, $2301, $0000, $0000 -dw $2201, $2401, $0000, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $2901 -dw $0000, $0000, $2a01, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $2501, $0000, $0000 - -dw $2302, $2602, $0000, $0000 -dw $2501, $2801, $0000, $2a02 -dw $2601, $2902, $2b02, $2c02 -dw $0000, $0000, $2d02, $2e01 -dw $0000, $0000, $2f01, $2f01 -dw $0000, $2b03, $3001, $3003 -dw $0000, $0000, $3103, $3302 -dw $2701, $0000, $3402, $0000 - -dw $2802, $0000, $0000, $0000 ;OW Slot 58, OWID 0x58 Village of Outcasts -dw $2a01, $0000, $0000, $0000 -dw $2b02, $0000, $0000, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $0000 -dw $2d03, $2e01, $0000, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $0000 - -dw $0000, $0000, $0000, $0000 -dw $0000, $2f01, $0000, $3501 -dw $0000, $0000, $3601, $0000 -dw $0000, $3001, $0000, $0000 -dw $0000, $3101, $0000, $3601 -dw $3001, $3201, $3701, $0000 -dw $0000, $3301, $0000, $0000 -dw $0000, $3401, $0000, $0000 - -dw $0000, $0000, $0000, $3702 -dw $3101, $0000, $3802, $3901 -dw $0000, $3502, $3a01, $0000 -dw $3201, $3701, $0000, $3a03 -dw $3301, $3801, $3b03, $3d01 -dw $3401, $3901, $3e01, $3e02 -dw $3501, $3a02, $3f02, $0000 -dw $3601, $0000, $0000, $0000 - -dw $0000, $0000, $0000, $0000 ;OW Slot 70, OWID 0x70 Mire -dw $0000, $0000, $0000, $0000 -dw $3702, $0000, $0000, $4001 -dw $3901, $3c01, $4101, $4103 -dw $3a01, $3d01, $4203, $0000 -dw $3b01, $0000, $0000, $0000 -dw $3c02, $0000, $0000, $0000 -dw $0000, $3e02, $0000, $0000 - -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $0000 -dw $0000, $0000, $0000, $4402 -dw $3e01, $0000, $4502, $4601 -dw $3f01, $0000, $4701, $4701 -dw $0000, $0000, $4801, $0000 -dw $0000, $0000, $0000, $4802 -dw $4002, $0000, $4902, $0000 - -dw $0000, $4001, $0000, $0000 -dw $0000, $0000, $0000, $4a01 -dw $0000, $4101, $0000, $0000 - -OWSpecialDestSlot: -db $80, $80, $81 - -org $aaa800 ;PC 152800 -OWNorthEdges: -; Min Max Width Mid OW Slot/OWID VRAM Terrain Dest Index -dw $00a0, $00a0, $0000, $00a0, $0000, $0000, $0000, $B040 ;Lost Woods (exit only) -dw $0458, $0540, $00e8, $04cc, $0a0a, $0000, $0000, $0000 -dw $0f38, $0f60, $0028, $0f4c, $0f0f, $0000, $0000, $2041 ;Waterfall (exit only) -dw $0058, $0058, $0000, $0058, $1010, $0000, $0000, $0001 -dw $0178, $0178, $0000, $0178, $1010, $0000, $0000, $0002 -dw $0388, $0388, $0000, $0388, $1111, $0000, $0000, $0003 -dw $0480, $05b0, $0130, $0518, $1212, $0000, $0000, $0004 -dw $0f70, $0f90, $0020, $0f80, $1717, $0000, $0000, $0005 -dw $0078, $0098, $0020, $0088, $1818, $0000, $0000, $0006 ;Kakariko -dw $0138, $0158, $0020, $0148, $1818, $0000, $0000, $0007 -dw $02e8, $0348, $0060, $0318, $1819, $0000, $0000, $0008 -dw $0478, $04d0, $0058, $04a4, $1a1a, $0000, $0000, $0009 -dw $0510, $0538, $0028, $0524, $1a1a, $0000, $0000, $000a -dw $0a48, $0af0, $00a8, $0a9c, $1d1d, $0000, $0000, $000b -dw $0b28, $0b38, $0010, $0b30, $1d1d, $0000, $0001, $000c -dw $0b70, $0ba0, $0030, $0b88, $1d1d, $0000, $0000, $000d -dw $0a40, $0b10, $00d0, $0aa8, $2525, $0000, $0000, $000e -dw $0350, $0390, $0040, $0370, $2929, $0000, $0000, $000f -dw $0670, $06a8, $0038, $068c, $2b2b, $0000, $0000, $0010 -dw $0898, $09b0, $0118, $0924, $2c2c, $0000, $0000, $0011 ;Links House -dw $0a40, $0ba0, $0160, $0af0, $2d2d, $0000, $0000, $0012 -dw $0c70, $0c90, $0020, $0c80, $2e2e, $0000, $0000, $0013 -dw $0f70, $0f80, $0010, $0f78, $2f2f, $0000, $0000, $0014 -dw $0430, $0468, $0038, $044c, $3232, $0000, $0000, $0015 -dw $04d8, $04f8, $0020, $04e8, $3232, $0000, $0000, $0016 -dw $0688, $06b0, $0028, $069c, $3333, $0000, $0000, $0017 -dw $08d0, $08f0, $0020, $08e0, $3434, $0000, $0000, $0018 -dw $0a80, $0b40, $00c0, $0ae0, $3535, $0000, $0000, $0019 -dw $0d38, $0d58, $0020, $0d48, $3536, $0000, $0001, $001a -dw $0d90, $0da0, $0010, $0d98, $3536, $0000, $0000, $001b -dw $06a0, $07b0, $0110, $0728, $3b3b, $0000, $0000, $001c -dw $0830, $09b0, $0180, $08f0, $3c3c, $0000, $0000, $001d -dw $0e78, $0e88, $0010, $0e80, $3f3f, $0000, $0001, $001e -dw $0ee0, $0fc0, $00e0, $0f50, $3f3f, $0000, $0000, $001f -dw $0458, $0540, $00e8, $04cc, $4a4a, $0000, $0000, $0020 -dw $0058, $0058, $0000, $0058, $5050, $0000, $0000, $0021 -dw $0178, $0178, $0000, $0178, $5050, $0000, $0000, $0022 -dw $0388, $0388, $0000, $0388, $5151, $0000, $0000, $0023 -dw $0480, $05b0, $0130, $0518, $5252, $0000, $0000, $0024 -dw $0f70, $0f90, $0020, $0f80, $5757, $0000, $0000, $0025 -dw $0078, $0098, $0020, $0088, $5858, $0000, $0000, $0026 ;Village of Outcasts -dw $0138, $0158, $0020, $0148, $5858, $0000, $0000, $0027 -dw $02e8, $0348, $0060, $0318, $5859, $0000, $0000, $0028 -dw $0478, $04d0, $0058, $04a4, $5a5a, $0000, $0000, $0029 -dw $0510, $0538, $0028, $0524, $5a5a, $0000, $0000, $002a -dw $0a48, $0af0, $00a8, $0a9c, $5d5d, $0000, $0000, $002b -dw $0b28, $0b38, $0010, $0b30, $5d5d, $0000, $0001, $002c -dw $0b70, $0ba0, $0030, $0b88, $5d5d, $0000, $0000, $002d -dw $0a40, $0b10, $00d0, $0aa8, $6565, $0000, $0000, $002e -dw $0350, $0390, $0040, $0370, $6969, $0000, $0000, $002f -dw $0670, $06a8, $0038, $068c, $6b6b, $0000, $0000, $0030 -dw $0898, $09b0, $0118, $0924, $6c6c, $0000, $0000, $0031 -dw $0a40, $0ba0, $0160, $0af0, $6d6d, $0000, $0000, $0032 -dw $0c70, $0c90, $0020, $0c80, $6e6e, $0000, $0000, $0033 -dw $0f70, $0f80, $0010, $0f78, $6f6f, $0000, $0000, $0034 -dw $0430, $0468, $0038, $044c, $7272, $0000, $0000, $0035 -dw $04d8, $04f8, $0020, $04e8, $7272, $0000, $0000, $0036 -dw $0688, $06b0, $0028, $069c, $7373, $0000, $0000, $0037 -dw $08d0, $08f0, $0020, $08e0, $7474, $0000, $0000, $0038 -dw $0a80, $0b40, $00c0, $0ae0, $7575, $0000, $0000, $0039 -dw $0d38, $0d58, $0020, $0d48, $7576, $0000, $0001, $003a -dw $0d90, $0da0, $0010, $0d98, $7576, $0000, $0000, $003b -dw $06a0, $07b0, $0110, $0728, $7b7b, $0000, $0000, $003c -dw $0830, $09b0, $0180, $08f0, $7c7c, $0000, $0000, $003d -dw $0e78, $0e88, $0010, $0e80, $7f7f, $0000, $0001, $003e -dw $0ee0, $0fc0, $00e0, $0f50, $7f7f, $0000, $0000, $003f -OWSouthEdges: -dw $0458, $0540, $00e8, $04cc, $0202, $0000, $0000, $0001 -dw $0058, $0058, $0000, $0058, $0008, $0000, $0000, $0003 -dw $0178, $0178, $0000, $0178, $0008, $0000, $0000, $0004 -dw $0388, $0388, $0000, $0388, $0009, $0000, $0000, $0005 -dw $0480, $05b0, $0130, $0518, $0a0a, $0000, $0000, $0006 -dw $0f70, $0f90, $0020, $0f80, $0f0f, $0000, $0000, $0007 -dw $0078, $0098, $0020, $0088, $1010, $0000, $0000, $0008 -dw $0138, $0158, $0020, $0148, $1010, $0000, $0000, $0009 -dw $02e8, $0348, $0060, $0318, $1111, $0000, $0000, $000a -dw $0478, $04d0, $0058, $04a4, $1212, $0000, $0000, $000b -dw $0510, $0538, $0028, $0524, $1212, $0000, $0000, $000c -dw $0a48, $0af0, $00a8, $0a9c, $1515, $0000, $0000, $000d -dw $0b28, $0b38, $0010, $0b30, $1515, $0000, $0001, $000e -dw $0b70, $0ba0, $0030, $0b88, $1515, $0000, $0000, $000f -dw $0a40, $0b10, $00d0, $0aa8, $1d1d, $0000, $0000, $0010 -dw $0350, $0390, $0040, $0370, $1821, $0000, $0000, $0011 -dw $0670, $06a8, $0038, $068c, $1b23, $0000, $0000, $0012 -dw $0898, $09b0, $0118, $0924, $1b24, $0000, $0000, $0013 -dw $0a40, $0ba0, $0160, $0af0, $2525, $0000, $0000, $0014 -dw $0c70, $0c90, $0020, $0c80, $1e26, $0000, $0000, $0015 -dw $0f70, $0f80, $0010, $0f78, $1e27, $0000, $0000, $0016 -dw $0430, $0468, $0038, $044c, $2a2a, $0000, $0000, $0017 -dw $04d8, $04f8, $0020, $04e8, $2a2a, $0000, $0000, $0018 -dw $0688, $06b0, $0028, $069c, $2b2b, $0000, $0000, $0019 -dw $08d0, $08f0, $0020, $08e0, $2c2c, $0000, $0000, $001a -dw $0a80, $0b40, $00c0, $0ae0, $2d2d, $0000, $0000, $001b -dw $0d38, $0d58, $0020, $0d48, $2e2e, $0000, $0001, $001c -dw $0d90, $0da0, $0010, $0d98, $2e2e, $0000, $0000, $001d -dw $06a0, $07b0, $0110, $0728, $3333, $0000, $0000, $001e -dw $0830, $09b0, $0180, $08f0, $3434, $0000, $0000, $001f -dw $0e78, $0e88, $0010, $0e80, $3737, $0000, $0001, $0020 -dw $0ee0, $0fc0, $00e0, $0f50, $3737, $0000, $0000, $0021 -dw $0458, $0540, $00e8, $04cc, $4242, $0000, $0000, $0022 -dw $0058, $0058, $0000, $0058, $4048, $0000, $0000, $0023 -dw $0178, $0178, $0000, $0178, $4048, $0000, $0000, $0024 -dw $0388, $0388, $0000, $0388, $4049, $0000, $0000, $0025 -dw $0480, $05b0, $0130, $0518, $4a4a, $0000, $0000, $0026 -dw $0f70, $0f90, $0020, $0f80, $4f4f, $0000, $0000, $0027 -dw $0078, $0098, $0020, $0088, $5050, $0000, $0000, $0028 -dw $0138, $0158, $0020, $0148, $5050, $0000, $0000, $0029 -dw $02e8, $0348, $0060, $0318, $5151, $0000, $0000, $002a -dw $0478, $04d0, $0058, $04a4, $5252, $0000, $0000, $002b -dw $0510, $0538, $0028, $0524, $5252, $0000, $0000, $002c -dw $0a48, $0af0, $00a8, $0a9c, $5555, $0000, $0000, $002d -dw $0b28, $0b38, $0010, $0b30, $5555, $0000, $0001, $002e -dw $0b70, $0ba0, $0030, $0b88, $5555, $0000, $0000, $002f -dw $0a40, $0b10, $00d0, $0aa8, $5d5d, $0000, $0000, $0030 -dw $0350, $0390, $0040, $0370, $5861, $0000, $0000, $0031 -dw $0670, $06a8, $0038, $068c, $5b63, $0000, $0000, $0032 -dw $0898, $09b0, $0118, $0924, $5b64, $0000, $0000, $0033 -dw $0a40, $0ba0, $0160, $0af0, $6565, $0000, $0000, $0034 -dw $0c70, $0c90, $0020, $0c80, $5e66, $0000, $0000, $0035 -dw $0f70, $0f80, $0010, $0f78, $5e67, $0000, $0000, $0036 -dw $0430, $0468, $0038, $044c, $6a6a, $0000, $0000, $0037 -dw $04d8, $04f8, $0020, $04e8, $6a6a, $0000, $0000, $0038 -dw $0688, $06b0, $0028, $069c, $6b6b, $0000, $0000, $0039 -dw $08d0, $08f0, $0020, $08e0, $6c6c, $0000, $0000, $003a -dw $0a80, $0b40, $00c0, $0ae0, $6d6d, $0000, $0000, $003b -dw $0d38, $0d58, $0020, $0d48, $6e6e, $0000, $0001, $003c -dw $0d90, $0da0, $0010, $0d98, $6e6e, $0000, $0000, $003d -dw $06a0, $07b0, $0110, $0728, $7373, $0000, $0000, $003e -dw $0830, $09b0, $0180, $08f0, $7474, $0000, $0000, $003f -dw $0e78, $0e88, $0010, $0e80, $7777, $0000, $0001, $0040 -dw $0ee0, $0fc0, $00e0, $0f50, $7777, $0000, $0000, $0041 -dw $0080, $0080, $0000, $0080, $8080, $0000, $0000, $0000 ;Pedestal (unused) -dw $0288, $02c0, $0038, $02a4, $8189, $0000, $0000, $0002 ;Zora (unused) -OWWestEdges: -dw $0070, $00a0, $0030, $0088, $0202, $0000, $0000, $0000 -dw $0068, $0078, $0010, $0070, $0505, $0000, $0000, $0001 -dw $0068, $0088, $0020, $0078, $0707, $0000, $0000, $0002 -dw $0318, $0368, $0050, $0340, $050d, $0000, $0000, $0003 -dw $0450, $0488, $0038, $046c, $1212, $0000, $0000, $0004 -dw $0560, $05a0, $0040, $0580, $1212, $0000, $0000, $0005 -dw $0488, $0500, $0078, $04c4, $1313, $0000, $0000, $0006 -dw $0538, $05a8, $0070, $0570, $1313, $0000, $0000, $0007 -dw $0470, $05a8, $0138, $050c, $1414, $0000, $0000, $0008 -dw $0470, $0598, $0128, $0504, $1515, $0000, $0000, $0009 -dw $0480, $0488, $0008, $0484, $1616, $0000, $0001, $000a -dw $04b0, $0510, $0060, $04e0, $1616, $0000, $0000, $000b -dw $0560, $0588, $0028, $0574, $1616, $0000, $0000, $000c -dw $0450, $0458, $0008, $0454, $1717, $0000, $0001, $000d -dw $0480, $04a8, $0028, $0494, $1717, $0000, $0000, $000e -dw $0718, $0738, $0020, $0728, $1b1b, $0000, $0000, $000f -dw $0908, $0948, $0040, $0928, $2222, $0000, $0000, $0010 -dw $0878, $08a8, $0030, $0890, $2525, $0000, $0000, $0011 -dw $0bb8, $0bc8, $0010, $0bc0, $2929, $0000, $0000, $0012 -dw $0b60, $0ba0, $0040, $0b80, $2a2a, $0000, $0000, $0013 -dw $0ab0, $0ad0, $0020, $0ac0, $2c2c, $0000, $0000, $0014 -dw $0af0, $0b40, $0050, $0b18, $2c2c, $0000, $0000, $0015 -dw $0b78, $0ba0, $0028, $0b8c, $2c2c, $0000, $0000, $0016 -dw $0b10, $0b28, $0018, $0b1c, $2d2d, $0000, $0001, $604a ;Stone Bridge (exit only) -dw $0b68, $0b98, $0030, $0b80, $2d2d, $0000, $0000, $0017 -dw $0a68, $0ab8, $0050, $0a90, $2e2e, $0000, $0000, $0018 -dw $0b00, $0b78, $0078, $0b3c, $2e2e, $0000, $0001, $0019 -dw $0c50, $0db8, $0168, $0d04, $3333, $0000, $0000, $001a -dw $0c78, $0ce3, $006b, $0cad, $3434, $0000, $0000, $001b -dw $0ce4, $0d33, $004f, $0d0b, $3434, $0000, $0001, $001c -dw $0d34, $0db8, $0084, $0d76, $3434, $0000, $0000, $001d -dw $0ea8, $0f20, $0078, $0ee4, $3a3a, $0000, $0000, $001e -dw $0f78, $0fa8, $0030, $0f90, $3a3a, $0000, $0000, $001f -dw $0f18, $0f18, $0000, $0f18, $3b3b, $0000, $0000, $0020 -dw $0fc8, $0fc8, $0000, $0fc8, $3b3b, $0000, $0000, $0021 -dw $0e28, $0fb8, $0190, $0ef0, $3c3c, $0000, $0000, $0022 -dw $0f78, $0fb8, $0040, $0f98, $353d, $0000, $0000, $0023 -dw $0f20, $0f40, $0020, $0f30, $3f3f, $0000, $0001, $0024 -dw $0f70, $0fb8, $0048, $0f94, $3f3f, $0000, $0000, $0025 -dw $0070, $00a0, $0030, $0088, $4242, $0000, $0000, $0026 -dw $0068, $0078, $0010, $0070, $4545, $0000, $0000, $0027 -dw $0068, $0088, $0020, $0078, $4747, $0000, $0000, $0028 -dw $0318, $0368, $0050, $0340, $454d, $0000, $0000, $0029 -dw $0450, $0488, $0038, $046c, $5252, $0000, $0000, $002a -dw $0560, $05a0, $0040, $0580, $5252, $0000, $0000, $002b -dw $0488, $0500, $0078, $04c4, $5353, $0000, $0000, $002c -dw $0538, $05a8, $0070, $0570, $5353, $0000, $0000, $002d -dw $0470, $05a8, $0138, $050c, $5454, $0000, $0000, $002e -dw $0470, $0598, $0128, $0504, $5555, $0000, $0000, $002f -dw $0480, $0488, $0008, $0484, $5656, $0000, $0001, $0030 -dw $04b0, $0510, $0060, $04e0, $5656, $0000, $0000, $0031 -dw $0560, $0588, $0028, $0574, $5656, $0000, $0000, $0032 -dw $0450, $0458, $0008, $0454, $5757, $0000, $0001, $0033 -dw $0480, $04a8, $0028, $0494, $5757, $0000, $0000, $0034 -dw $0908, $0948, $0040, $0928, $6262, $0000, $0000, $0035 -dw $0878, $08a8, $0030, $0890, $6565, $0000, $0000, $0036 -dw $0b60, $0b68, $0008, $0b64, $6969, $0000, $0000, $0037 -dw $0bb8, $0bc8, $0010, $0bc0, $6969, $0000, $0000, $0038 -dw $0b60, $0ba0, $0040, $0b80, $6a6a, $0000, $0000, $0039 -dw $0ab0, $0ad0, $0020, $0ac0, $6c6c, $0000, $0000, $003a -dw $0af0, $0b40, $0050, $0b18, $6c6c, $0000, $0000, $003b -dw $0b78, $0ba0, $0028, $0b8c, $6c6c, $0000, $0000, $003c -dw $0b68, $0b98, $0030, $0b80, $6d6d, $0000, $0000, $003d -dw $0a68, $0ab8, $0050, $0a90, $6e6e, $0000, $0000, $003e -dw $0b00, $0b78, $0078, $0b3c, $6e6e, $0000, $0001, $003f -dw $0c50, $0db8, $0168, $0d04, $7373, $0000, $0000, $0040 -dw $0c78, $0ce3, $006b, $0cad, $7474, $0000, $0000, $0041 -dw $0ce4, $0d33, $004f, $0d0b, $7474, $0000, $0001, $0042 -dw $0d34, $0db8, $0084, $0d76, $7474, $0000, $0000, $0043 -dw $0f18, $0f18, $0000, $0f18, $7b7b, $0000, $0000, $0044 -dw $0fc8, $0fc8, $0000, $0fc8, $7b7b, $0000, $0000, $0045 -dw $0e28, $0fb8, $0190, $0ef0, $7c7c, $0000, $0000, $0046 -dw $0f78, $0fb8, $0040, $0f98, $757d, $0000, $0000, $0047 -dw $0f20, $0f40, $0020, $0f30, $7f7f, $0000, $0001, $0048 -dw $0f70, $0fb8, $0048, $0f94, $7f7f, $0000, $0000, $0049 -OWEastEdges: -dw $0070, $00a0, $0030, $0088, $0001, $0000, $0000, $0000 -dw $0068, $0078, $0010, $0070, $0304, $0000, $0000, $0001 -dw $0068, $0088, $0020, $0078, $0506, $0000, $0000, $0002 -dw $0318, $0368, $0050, $0340, $030c, $0000, $0000, $0003 -dw $0450, $0488, $0038, $046c, $1111, $0000, $0000, $0004 -dw $0560, $05a0, $0040, $0580, $1111, $0000, $0000, $0005 -dw $0488, $0500, $0078, $04c4, $1212, $0000, $0000, $0006 -dw $0538, $05a8, $0070, $0570, $1212, $0000, $0000, $0007 -dw $0470, $05a8, $0138, $050c, $1313, $0000, $0000, $0008 -dw $0470, $0598, $0128, $0504, $1414, $0000, $0000, $0009 -dw $0480, $0488, $0008, $0484, $1515, $0000, $0001, $000a -dw $04b0, $0510, $0060, $04e0, $1515, $0000, $0000, $000b -dw $0560, $0588, $0028, $0574, $1515, $0000, $0000, $000c -dw $0450, $0458, $0008, $0454, $1616, $0000, $0001, $000d -dw $0480, $04a8, $0028, $0494, $1616, $0000, $0000, $000e -dw $0718, $0738, $0020, $0728, $1a1a, $0000, $0000, $000f -dw $0908, $0948, $0040, $0928, $1821, $0000, $0000, $0010 -dw $0878, $08a8, $0030, $0890, $1b24, $0000, $0000, $0011 -dw $0bb8, $0bc8, $0010, $0bc0, $2828, $0000, $0000, $0012 ;Race Game -dw $0b60, $0ba0, $0040, $0b80, $2929, $0000, $0000, $0013 -dw $0ab0, $0ad0, $0020, $0ac0, $2b2b, $0000, $0000, $0014 -dw $0af0, $0b40, $0050, $0b18, $2b2b, $0000, $0000, $0015 -dw $0b78, $0ba0, $0028, $0b8c, $2b2b, $0000, $0000, $0016 -dw $0b68, $0b98, $0030, $0b80, $2c2c, $0000, $0000, $0018 -dw $0a68, $0ab8, $0050, $0a90, $2d2d, $0000, $0000, $0019 -dw $0b00, $0b78, $0078, $0b3c, $2d2d, $0000, $0001, $001a -dw $0c50, $0db8, $0168, $0d04, $3232, $0000, $0000, $001b -dw $0c78, $0ce3, $006b, $0cad, $3333, $0000, $0000, $001c -dw $0ce4, $0d33, $004f, $0d0b, $3333, $0000, $0001, $001d -dw $0d34, $0db8, $0084, $0d76, $3333, $0000, $0000, $001e -dw $0ea8, $0f20, $0078, $0ee4, $3039, $0000, $0000, $001f -dw $0f78, $0fa8, $0030, $0f90, $3039, $0000, $0000, $0020 -dw $0f18, $0f18, $0000, $0f18, $3a3a, $0000, $0000, $0021 -dw $0fc8, $0fc8, $0000, $0fc8, $3a3a, $0000, $0000, $0022 -dw $0e28, $0fb8, $0190, $0ef0, $3b3b, $0000, $0000, $0023 -dw $0f78, $0fb8, $0040, $0f98, $3c3c, $0000, $0000, $0024 -dw $0f20, $0f40, $0020, $0f30, $353e, $0000, $0001, $0025 -dw $0f70, $0fb8, $0048, $0f94, $353e, $0000, $0000, $0026 -dw $0070, $00a0, $0030, $0088, $4041, $0000, $0000, $0027 ;Skull Woods -dw $0068, $0078, $0010, $0070, $4344, $0000, $0000, $0028 -dw $0068, $0088, $0020, $0078, $4546, $0000, $0000, $0029 -dw $0318, $0368, $0050, $0340, $434c, $0000, $0000, $002a -dw $0450, $0488, $0038, $046c, $5151, $0000, $0000, $002b -dw $0560, $05a0, $0040, $0580, $5151, $0000, $0000, $002c -dw $0488, $0500, $0078, $04c4, $5252, $0000, $0000, $002d -dw $0538, $05a8, $0070, $0570, $5252, $0000, $0000, $002e -dw $0470, $05a8, $0138, $050c, $5353, $0000, $0000, $002f -dw $0470, $0598, $0128, $0504, $5454, $0000, $0000, $0030 -dw $0480, $0488, $0008, $0484, $5555, $0000, $0001, $0031 -dw $04b0, $0510, $0060, $04e0, $5555, $0000, $0000, $0032 -dw $0560, $0588, $0028, $0574, $5555, $0000, $0000, $0033 -dw $0450, $0458, $0008, $0454, $5656, $0000, $0001, $0034 -dw $0480, $04a8, $0028, $0494, $5656, $0000, $0000, $0035 -dw $0908, $0948, $0040, $0928, $5861, $0000, $0000, $0036 -dw $0878, $08a8, $0030, $0890, $5b64, $0000, $0000, $0037 -dw $0b60, $0b68, $0008, $0b64, $6868, $0000, $0000, $0038 ;Dig Game -dw $0bb8, $0bc8, $0010, $0bc0, $6868, $0000, $0000, $0039 -dw $0b60, $0ba0, $0040, $0b80, $6969, $0000, $0000, $003a -dw $0ab0, $0ad0, $0020, $0ac0, $6b6b, $0000, $0000, $003b -dw $0af0, $0b40, $0050, $0b18, $6b6b, $0000, $0000, $003c -dw $0b78, $0ba0, $0028, $0b8c, $6b6b, $0000, $0000, $003d -dw $0b68, $0b98, $0030, $0b80, $6c6c, $0000, $0000, $003e -dw $0a68, $0ab8, $0050, $0a90, $6d6d, $0000, $0000, $003f -dw $0b00, $0b78, $0078, $0b3c, $6d6d, $0000, $0001, $0040 -dw $0c50, $0db8, $0168, $0d04, $7272, $0000, $0000, $0041 -dw $0c78, $0ce3, $006b, $0cad, $7373, $0000, $0000, $0042 -dw $0ce4, $0d33, $004f, $0d0b, $7373, $0000, $0001, $0043 -dw $0d34, $0db8, $0084, $0d76, $7373, $0000, $0000, $0044 -dw $0f18, $0f18, $0000, $0f18, $7a7a, $0000, $0000, $0045 -dw $0fc8, $0fc8, $0000, $0fc8, $7a7a, $0000, $0000, $0046 -dw $0e28, $0fb8, $0190, $0ef0, $7b7b, $0000, $0000, $0047 -dw $0f78, $0fb8, $0040, $0f98, $7c7c, $0000, $0000, $0048 -dw $0f20, $0f40, $0020, $0f30, $757e, $0000, $0001, $0049 -dw $0f70, $0fb8, $0048, $0f94, $757e, $0000, $0000, $004a -dw $0058, $00c0, $0068, $008c, $8080, $0000, $0001, $0017 ;Hobo (unused) - -org $aab9a0 ;PC 1539a0 -OWSpecialDestIndex: -dw $0080, $0081, $0082 - -org $aab9b0 ;PC 1539b0 -OWTileWorldAssoc: -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $40, $40, $40, $40, $40, $40, $40, $40 -db $00, $00 - -org $aaba70 ;PC 153a70 -OWTileMapAlt: -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 - -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 -db 0, 0, 0, 0, 0, 0, 0, 0 - -db 0, 0 - -;================================================================================ -; Bonk Prize Data ($AABB00 - $AABBFB) -;-------------------------------------------------------------------------------- -; This table stores data relating to bonk locations for Bonk Drop Shuffle -; -; Example: We can use OWBonkPrizeTable[$09].loot to read what item is in the -; east tree on the Sanctuary screen -;-------------------------------------------------------------------------------- -; Search Criteria - The following two fields are used as a unique index -; .owid = OW screen ID -; .yx = Y & X coordinate data *see below* -; -; .flag = OW event flag bitmask -; .loot = Loot ID -; .mw_player = Multiworld player ID -; .vert_offset = Vertical offset, # of pixels the sprite moves up when activated -; -; .yx field is a combination of both the least significant digits of the Y and X -; coordinates of the static location of the sprite located in a bonk location. -; All sprites, when initialized, are aligned by a 16 pixel increment. -; The coordinate system in LTTP is handled by two bytes: -; (high) (low) -; - - - w w w w s s s s s s s s s -; w = world absolute coords, every screen is $200 pixels in each dimension -; s = local screen coords, coords relative to the bounds of the current screen -; Because of the 16 pixel alignment of sprites, the last four bits of the coords -; are unset. This leaves 5 bits remaining, we simply disregard the highest bit -; and then combine the Y and X coords together to be used as search criteria. -; This does open the possibility of a false positive match from 3 other coords -; on the same screen (15 on megatile screens) but there are no bonk sprites that -; have collision in this regard. -;-------------------------------------------------------------------------------- -struct OWBonkPrizeTable $AABB00 - .owid: skip 1 - .yx: skip 1 - .flag: skip 1 - .loot: skip 1 - .mw_player: skip 1 - .vert_offset: skip 1 -endstruct align 6 - -org $aabb00 ;PC 153b00 -OWBonkPrizeData: -; OWID YX Flag Item MW Offset -db $00, $59, $10, $b0, $00, $20 -db $05, $04, $10, $b2, $00, $00 -db $0a, $4e, $10, $b0, $00, $20 -db $0a, $a9, $08, $b1, $00, $20 -db $10, $c7, $10, $b1, $00, $20 -db $10, $f7, $08, $b4, $00, $20 -db $11, $08, $10, $27, $00, $00 -db $12, $a4, $10, $b2, $00, $20 -db $13, $c7, $10, $31, $00, $20 -db $13, $98, $08, $b1, $00, $20 -db $15, $a4, $10, $b1, $00, $20 -db $15, $fb, $08, $b2, $00, $20 -db $18, $a8, $10, $b2, $00, $20 -db $18, $36, $08, $35, $00, $20 -db $1a, $8a, $10, $42, $00, $20 -db $1a, $1d, $08, $b2, $00, $20 -;db $1a, $77, $04, $35, $00, $20 ; pre aga ONLY ; hijacked murahdahla bonk tree -db $1b, $46, $10, $b1, $00, $10 -db $1d, $6b, $10, $b1, $00, $20 -db $1e, $72, $10, $b2, $00, $20 -db $2a, $8f, $10, $36, $00, $20 -db $2a, $45, $08, $36, $00, $20 -db $2b, $d6, $10, $b2, $00, $20 -db $2e, $9c, $10, $b2, $00, $20 -db $2e, $b4, $08, $b0, $00, $20 -db $32, $29, $10, $42, $00, $20 -db $32, $9a, $08, $b2, $00, $20 -;db $34, $xx, $10, $xx, $00, $1c ; pre aga ONLY -db $42, $66, $10, $b2, $00, $20 -db $51, $08, $10, $b2, $00, $04 -db $51, $09, $08, $b2, $00, $04 -db $54, $b5, $10, $27, $00, $14 -db $54, $ef, $08, $b2, $00, $08 -db $54, $b9, $04, $36, $00, $00 -db $55, $aa, $10, $b0, $00, $20 -db $55, $fb, $08, $35, $00, $20 -db $56, $e4, $10, $b0, $00, $20 -db $5b, $a7, $10, $b2, $00, $20 -db $5e, $00, $10, $b2, $00, $20 -db $6e, $8c, $10, $35, $00, $10 -db $6e, $90, $08, $b0, $00, $10 -db $6e, $a4, $04, $b1, $00, $10 -db $74, $4e, $10, $b1, $00, $1c -UWBonkPrizeData: -db $ff, $00, $02, $b5, $00, $08 - -; temporary fix - murahdahla replaces one of the bonk tree prizes -; so we copy the sprite table here and update the pointer -; longterm solution should be to spawn in murahdahla separately -org $89AE2A -Overworld_Sprites_Screen1A_2: -db $08, $0F, $41 ; yx:{ 0x080, 0x0F0 } -db $0E, $0C, $41 ; yx:{ 0x0E0, 0x0C0 } -db $11, $0D, $E3 ; yx:{ 0x110, 0x0D0 } -db $18, $0A, $D8 ; yx:{ 0x180, 0x0A0 } -db $18, $0F, $45 ; yx:{ 0x180, 0x0F0 } -db $FF ; END -org $89CA55 -dw Overworld_Sprites_Screen1A_2&$FFFF \ No newline at end of file diff --git a/asm/scroll.asm b/asm/scroll.asm deleted file mode 100644 index 435b5c98..00000000 --- a/asm/scroll.asm +++ /dev/null @@ -1,222 +0,0 @@ -AdjustTransition: -{ - lda $ab : and #$01ff : beq .reset - phy : ldy #$06 ; operating on vertical registers during horizontal trans - cpx.b #$02 : bcs .horizontalScrolling - ldy #$00 ; operate on horizontal regs during vert trans - .horizontalScrolling - cmp #$0008 : bcs + - pha : lda $ab : and #$0200 : beq ++ - pla : bra .add - ++ pla : eor #$ffff : inc ; convert to negative - .add jsr AdjustCamAdd : ply : bra .reset - + lda $ab : and #$0200 : xba : tax - lda.l OffsetTable,x : jsr AdjustCamAdd - lda $ab : !sub #$0008 : sta $ab - ply : bra .done - .reset ; clear the $ab variable so to not disturb intra-tile doors - stz $ab - .done - lda $00 : and #$01fc - rtl -} - -AdjustCamAdd: - !add $00E2,y : pha - and #$01ff : cmp #$0111 : !blt + - cmp #$01f8 : !bge ++ - pla : and #$ff10 : pha : bra + - ++ pla : and #$ff00 : !add #$0100 : pha - + pla : sta $00E2,y : sta $00E0,y : rts - -; expects target quad in $05 (either 0 or 1) and target pixel in $04, target room should be in $a0 -; $06 is either $ff or $01/02 -; uses $00-$03 and $0e for calculation -; also set up $ac -ScrollY: ;change the Y offset variables - lda $a0 : and.b #$f0 : lsr #3 : sta $0603 : inc : sta $0607 - - lda $05 : bne + - lda $603 : sta $00 : stz $01 : bra ++ - + lda $607 : sta $00 : lda #$02 : sta $01 - ++ ; $01 now contains 0 or 2 and $00 contains the correct lat - - stz $0e - rep #$30 - lda $00 : pha - - lda $e8 : and #$01ff : sta $02 - lda $04 : jsr LimitYCamera : sta $00 - jsr CheckRoomLayoutY : bcc + - lda $00 : cmp #$0080 : !bge ++ - cmp #$0010 : !blt .cmpSrll - lda #$0010 : bra .cmpSrll - ++ cmp #$0100 : !bge .cmpSrll - lda #$0100 - .cmpSrll sta $00 - - ; figures out scroll amt - + lda $00 : cmp $02 : bne + - lda #$0000 : bra .next - + !blt + - !sub $02 : inc $0e : bra .next - + lda $02 : !sub $00 - - .next - sta $ab - jsr AdjustCameraBoundsY - - pla : sta $00 - sep #$30 - lda $04 : sta $20 - lda $00 : sta $21 : sta $0601 : sta $0605 - lda $01 : sta $aa - lda $0e : asl : ora $ac : sta $ac - lda $e9 : and #$01 : asl #2 : tax : lda $0603, x : sta $e9 - rts - -LimitYCamera: - cmp #$006c : !bge + - lda #$0000 : bra .end - + cmp #$017d : !blt + - lda #$0110 : bra .end - + !sub #$006c - .end rts - -CheckRoomLayoutY: - jsr LoadRoomLayout ;switches to 8-bit - cmp #$00 : beq .lock - cmp #$07 : beq .free - cmp #$01 : beq .free - cmp #$04 : !bge .lock - cmp #$02 : bne + - lda $06 : cmp #$ff : beq .lock - + cmp #$03 : bne .free - lda $06 : cmp #$ff : bne .lock - .free rep #$30 : clc : rts - .lock rep #$30 : sec : rts - -AdjustCameraBoundsY: - jsr CheckRoomLayoutY : bcc .free - - ; layouts that are camera locked (quads only) - lda $04 : and #$00ff : cmp #$007d : !blt + - lda #$0088 : bra ++ - + cmp #$006d : !bge + - lda #$0078 : bra ++ - + !add #$000b - - ; I think we no longer need the $02 variable - ++ sta $02 : lda $04 : and #$0100 : !add $02 : bra .setBounds - - ; layouts where the camera is free - .free lda $04 : cmp #$006c : !bge + - lda #$0077 : bra .setBounds - + cmp #$017c : !blt + - lda #$0187 : bra .setBounds - + !add #$000b - .setBounds sta $0618 : inc #2 : sta $061a - rts - -LoadRoomLayout: - lda $a0 : asl : !add $a0 : tax - lda $1f8001, x : sta $b8 - lda $1f8000, x : sta $b7 - sep #$30 - ldy #$01 : lda [$b7], y : and #$1c : lsr #2 - rts - -; expects target quad in $05 (either 0 or 1) and target pixel in $04, target room should be in $a0 -; uses $00-$03 and $0e for calculation -; also set up $ac -ScrollX: ;change the X offset variables - lda $a0 : and.b #$0f : asl : sta $060b : inc : sta $060f - - lda $05 : bne + - lda $60b : sta $00 : stz $01 : bra ++ - + lda $60f : sta $00 : lda #$01 : sta $01 - ++ ; $01 now contains 0 or 1 and $00 contains the correct long - - stz $0e ; pos/neg indicator - rep #$30 - lda $00 : pha - - lda $e2 : and #$01ff : sta $02 - lda $04 : jsr LimitXCamera : sta $00 - jsr CheckRoomLayoutX : bcc + - lda $00 : cmp #$0080 : !bge ++ - lda #$0000 : bra .cmpSrll - ++ lda #$0100 - .cmpSrll sta $00 - - ;figures out scroll amt - + lda $00 : cmp $02 : bne + - lda #$0000 : bra .next - + !blt + - !sub $02 : inc $0e : bra .next - + lda $02 : !sub $00 - - .next - sta $ab : lda $04 - - cmp #$0078 : !bge + - lda #$007f : bra ++ - + cmp #$0178 : !blt + - lda #$017f : bra ++ - + !add #$0007 - ++ sta $061c : inc #2 : sta $061e - - pla : sta $00 - sep #$30 - lda $04 : ldx $046d : bne .straight - sta $22 : bra + - .straight - sta $046d ; set X position later - + - lda $00 : sta $23 : sta $0609 : sta $060d - lda $01 : sta $a9 - lda $0e : asl : ora $ac : sta $ac - lda $e3 : and #$01 : asl #2 : tax : lda $060b, x : sta $e3 - - rts - -LimitXCamera: - cmp #$0079 : !bge + - lda #$0000 : bra .end - + cmp #$0178 : !blt + - lda #$0178 - + !sub #$0078 - .end rts - -CheckRoomLayoutX: - jsr LoadRoomLayout ;switches to 8-bit - cmp #$04 : !blt .lock - cmp #$05 : bne + - lda $06 : cmp #$ff : beq .lock - + cmp #$06 : bne .free - lda $06 : cmp #$ff : bne .lock - .free rep #$30 : clc : rts - .lock rep #$30 : sec : rts - -ApplyScroll: - rep #$30 - lda $ab : and #$01ff : sta $00 - lda $ab : and #$0200 : beq + - lda $00e2, y : !add $00 : bra .end - + lda $00e2, y : !sub $00 - .end - sta $00e2, y - sta $00e0, y - stz $ab : sep #$30 : rts - -QuadrantLoadOrderBeforeScroll: - lda $045f : beq .end - lda #$08 : sta $045c ; start with opposite quadrant row - .end - JML $0091c4 ; what we overwrote - -QuadrantLoadOrderAfterScroll: - lda $045f : beq .end - stz $045c : stz $045f ; draw other row and clear flag - .end - JML $0091c4 ; what we overwrote \ No newline at end of file diff --git a/asm/spiral.asm b/asm/spiral.asm deleted file mode 100644 index e73b5e16..00000000 --- a/asm/spiral.asm +++ /dev/null @@ -1,332 +0,0 @@ -RecordStairType: { - pha - lda.l DRMode : beq .norm - lda $040c : cmp #$ff : beq .norm - lda $0e - cmp #$25 : bcc ++ ; don't record straight staircases - sta $045e - ++ pla : bra + - .norm pla : sta $a0 - + lda $063d, x - rtl -} - -SpiralWarp: { - lda.l DRMode : beq .abort ; abort if not DR - lda $040c : cmp.b #$ff : beq .abort ; abort if not in dungeon - lda $045e : cmp #$5e : beq .gtg ; abort if not spiral - intended room is in A! - cmp #$5f : beq .gtg - cmp #$26 : beq .inroom - .abort - stz $045e : lda $a2 : and #$0f : rtl ; clear,run hijacked code and get out - .inroom - jsr InroomStairsWarp - lda $a2 : and #$0f ; this is the code we are hijacking - rtl - - .gtg - phb : phk : plb : phx : phy ; push stuff - jsr LookupSpiralOffset - rep #$30 : and #$00FF : asl #2 : tax - lda.w SpiralTable, x : sta $00 - lda.w SpiralTable+2, x : sta $02 - sep #$30 - lda $00 : sta $a0 - ; shift quadrant if necessary - stz $07 ; this is a x quad adjuster for those blasted staircase on the edges - lda $01 : and #$01 : !sub $a9 - bne .xQuad - lda $0462 : and #$04 : bne .xqCont - inc $07 - .xqCont lda $22 : bne .skipXQuad ; this is an edge case - dec $23 : bra .skipXQuad ; need to -1 if $22 is 0 - .xQuad sta $06 : !add $a9 : sta $a9 - lda $0462 : and #$04 : bne .xCont - inc $07 ; up stairs are going to -1 the quad anyway during transition, need to add this back - .xCont ldy #$00 : jsr ShiftQuadSimple - - .skipXQuad - lda $aa : lsr : sta $06 : lda $01 : and #$02 : lsr : !sub $06 - beq .skipYQuad - sta $06 : asl : !add $aa : sta $aa - ldy #$01 : jsr ShiftQuadSimple - - .skipYQuad - lda $01 : and #$04 : lsr : sta $048a ;fix layer calc 0->0 2->1 - lda $01 : and #$08 : lsr #2 : sta $0492 ;fix from layer calc 0->0 2->1 - ; shift lower coordinates - lda $02 : sta $22 : bne .adjY : lda $23 : !add $07 : sta $23 - .adjY lda $03 : sta $20 : bne .upDownAdj : inc $21 - .upDownAdj ldx #$08 - lda $0462 : and #$04 : beq .upStairs - ldx #$fd - lda $01 : and #$80 : bne .set53 - ; if target is also down adjust by (6,-15) - lda #$06 : !add $20 : sta $20 : lda #$eb : !add $22 : sta $22 : bra .set53 - .upStairs - lda $01 : and #$80 : beq .set53 - ; if target is also up adjust by (-6, 14) - lda #$fa : !add $20 : sta $20 : lda #$14 : !add $22 : sta $22 - bne .set53 : inc $23 - .set53 - txa : !add $22 : sta $53 - - lda $01 : and #$10 : sta $07 ; zeroHzCam check - ldy #$00 : jsr SetCamera - lda $01 : and #$20 : sta $07 ; zeroVtCam check - ldy #$01 : jsr SetCamera - - jsr StairCleanup - ply : plx : plb ; pull the stuff we pushed - lda $a2 : and #$0f ; this is the code we are hijacking - rtl -} - -StairCleanup: { - stz $045e ; clear the staircase flag - - ; animated tiles fix - lda.l DRMode : cmp #$02 : bne + ; only do this in crossed mode - ldx $a0 : lda.l TilesetTable, x - cmp $0aa1 : beq + ; already eq no need to decomp - sta $0aa1 - tax : lda $02802e, x : tay - jsl DecompDungAnimatedTiles - + - stz $047a - rts -} - -;Sets the offset in A -LookupSpiralOffset: { - ;where link currently is in $a2: quad in a8 & #$03 - ;count doors - stz $00 : ldx #$00 : stz $01 - - .loop - lda $047e, x : cmp $00 : bcc .continue - sta $00 - .continue inx #2 - cpx #$08 : bcc .loop - - lda $00 : lsr - cmp #$01 : beq .done - - ; look up the quad - lda $a9 : ora $aa : and #$03 : beq .quad0 - cmp #$01 : beq .quad1 - cmp #$02 : beq .quad2 - bra .quad3 - .quad0 - inc $01 : lda $a2 - cmp #$0c : beq .q0diff ;gt ent - cmp #$70 : bne .done ;hc stairwell - .q0diff lda $22 : cmp #$00 : beq .secondDoor - cmp #$98 : bcc .done ;gt ent and hc stairwell - .secondDoor inc $01 : bra .done - .quad1 - lda $a2 - cmp #$1a : beq .q1diff ;pod compass - cmp #$26 : beq .q1diff ;swamp elbows - cmp #$6a : beq .q1diff ;pod dark basement - cmp #$76 : bne .done ;swamp drain - .q1diff lda $22 : cmp #$98 : bcc .done - inc $01 : bra .done - .quad2 - lda #$03 : sta $01 : lda $a2 - cmp #$5f : beq .iceu ;ice u room - cmp #$3f : bne .done ;hammer ice exception - stz $01 : bra .done - .iceu lda $22 : cmp #$78 : bcc .done - inc $01 : bra .done - .quad3 - lda $a2 : cmp #$40 : beq .done ; top of aga exception - lda #$02 : sta $01 ; always 2 - - .done - lda $a2 : tax : lda.w SpiralOffset,x - !add $01 ;add a thing (0 in easy case) - rts -} - -InroomStairsWarp: { - phb : phk : plb : phx : phy ; push stuff - ; find stairs by room and store index in X - lda $a0 : ldx #$07 - .loop - cmp.w InroomStairsRoom,x - beq .found - dex - bne .loop - .found - rep #$30 - txa : and #$00ff : asl : tay - lda.w InroomStairsTable,y : sta $00 - sep #$30 - sta $a0 - - ; set position and everything else based on target door type - txa : and #$01 : eor #$01 : sta $07 - ; should be the same as lda $0462 : and #$04 : lsr #2 : eor #$01 : sta $07 - lda $01 : and #$80 : beq .notEdge - lda $07 : sta $03 : beq + - lda $01 : jsr LoadSouthMidpoint : sta $22 : lda #$f4 - bra ++ - + - lda $01 : jsr LoadNorthMidpoint : sta $22 : dec $21 : lda #$f7 - ++ - sta $20 - lda $01 : and #$20 : beq + - lda #$01 - + - sta $02 - stz $07 - lda $01 : and #$10 : lsr #4 - JMP .layer - .notEdge - lda $01 : and #$03 : cmp #$03 : bne .normal - txa : and #$06 : sta $07 - lda $01 : and #$30 : lsr #3 : tay - lda.w InroomStairsX+1,y : sta $02 - lda.w InroomStairsY+1,y : sta $03 - cpy $07 : beq .vanillaTransition - lda.w InroomStairsX,y : sta $22 - lda.w InroomStairsY,y - ldy $07 : beq + - !add #$07 - + - sta $20 - inc $07 - bra ++ - .vanillaTransition - lda #$c0 : sta $07 ; leave camera - ++ - %StonewallCheck($1b) - lda $01 : and #$04 : lsr #2 - bra .layer - .normal - lda $01 : sta $fe ; trap door - lda $07 : sta $03 : beq + - ldy $a0 : cpy #$51 : beq .specialFix ; throne room - cpy #$02 : beq .specialFix ; sewers pull switch - cpy #$71 : beq .specialFix ; castle armory - lda #$e0 - bra ++ - .specialFix - lda #$c8 - bra ++ - + - %StonewallCheck($43) - lda #$1b - ++ - sta $20 - inc $07 : stz $02 : lda #$78 : sta $22 - lda $01 : and #$03 : beq ++ - cmp #$02 : !bge + - lda #$f8 : sta $22 : stz $07 : bra ++ - + inc $02 - ++ - lda $01 : and #$04 : lsr #2 - - .layer - sta $ee - bne + - stz $0476 - + - - lda $02 : !sub $a9 - beq .skipXQuad - sta $06 : !add $a9 : sta $a9 - ldy #$00 : jsr ShiftQuadSimple - .skipXQuad - lda $aa : lsr : sta $06 : lda $03 : !sub $06 - beq .skipYQuad - sta $06 : asl : !add $aa : sta $aa - ldy #$01 : jsr ShiftQuadSimple - .skipYQuad - - lda $07 : bmi .skipCamera - ldy #$00 : jsr SetCamera ; horizontal camera - ldy #$01 : sty $07 : jsr SetCamera ; vertical camera - lda $20 : cmp #$e0 : bcc + - lda $e8 : bne + - lda #$10 : sta $e8 ; adjust vertical camera at bottom - + - .skipCamera - - jsr StairCleanup - ply : plx : plb ; pull the stuff we pushed - rts -} - -ShiftQuadSimple: { - lda.w CoordIndex,y : tax - lda $20,x : beq .skip - lda $21,x : !add $06 : sta $21,x ; coordinate update - .skip - lda.w CamQuadIndex,y : tax - lda $0601,x : !add $06 : sta $0601,x - lda $0605,x : !add $06 : sta $0605,x ; high bytes of these guys - rts -} - -SetCamera: { - stz $04 - tyx : lda $a9,x : bne .nonZeroHalf - lda.w CamQuadIndex,y : tax : lda $607,x : pha - lda.w CameraIndex,y : tax : pla : cmp $e3, x : bne .noQuadAdj - dec $e3,x - - .noQuadAdj - lda $07 : bne .adj0 - lda.w CoordIndex,y : tax - lda $20,x : beq .oddQuad - cmp #$79 : bcc .adj0 - !sub #$78 : sta $04 - tya : asl : !add #$04 : tax : jsr AdjCamBounds : bra .done - .oddQuad - lda #$80 : sta $04 : bra .adj1 ; this is such a weird case - quad cross boundary - .adj0 - tya : asl : tax : jsr AdjCamBounds : bra .done - - .nonZeroHalf ;meaning either right half or bottom half - lda $07 : bne .setQuad - lda.w CoordIndex,y : tax - lda $20,x : cmp #$78 : bcs .setQuad - !add #$78 : sta $04 - lda.w CamQuadIndex,y : tax : lda $0603, x : pha - lda.w CameraIndex,y : tax : pla : sta $e3, x - .adj1 - tya : asl : !add #$08 : tax : jsr AdjCamBounds : bra .done - - .setQuad - lda.w CamQuadIndex,y : tax : lda $0607, x : pha - lda.w CameraIndex,y : tax : pla : sta $e3, x - tya : asl : !add #$0c : tax : jsr AdjCamBounds : bra .done - - .done - lda.w CameraIndex,y : tax - lda $04 : sta $e2, x - rts -} - -; input, expects X to be an appropriate offset into the CamBoundBaseLine table -; when $04 is 0 no coordinate are added -AdjCamBounds: { - rep #$20 : lda.w CamBoundBaseLine, x : sta $05 - lda $04 : and #$00ff : beq .common - lda.w CoordIndex,y : tax - lda $20, x : and #$00ff : !add $05 : sta $05 - .common - lda.w OppCamBoundIndex,y : tax - lda $05 : sta $0618, x - inc #2 : sta $061A, x : sep #$20 - rts -} - -SpiralPriorityHack: { - lda.l DRMode : beq + - lda #$01 : rtl ; always skip the priority code - until I figure out how to fix it - + lda $0462 : and #$04 ; what we wrote over - rtl -} \ No newline at end of file diff --git a/asm/testdata/horizontaltest.txt b/asm/testdata/horizontaltest.txt deleted file mode 100644 index 8d9a7e54..00000000 --- a/asm/testdata/horizontaltest.txt +++ /dev/null @@ -1,227 +0,0 @@ -org $27A000 -DoorTable: -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Ganon -dw $8000, $8000, $8000, $0450, $8000, $8000, $8000, $8000, $8000, $0452, $8000, $8000 ; HC Back Hall (x01) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $0112, $8000, $8000, $8000, $8000 ; Sewer Switches (x02) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x10 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x20 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;PoD Arena (x2a) -dw $8000, $8000, $8000, $8000, $8000, $0161, $8000, $8000, $8000, $8000, $8000, $8000 ;PoD Statue (x2b) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x30 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $0061 ; Swamp Main (x36) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x40 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $0061, $8000, $8000 ;HC West Hall (x50) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC Throne Room (x51) -dw $8000, $8000, $8000, $0401, $8000, $8000, $0462, $0162, $8000, $8000, $8000, $8000 ;HC East Hall (x52) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $0550, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $0061, $0561, $8000 ;HC West Lobby (x60) -dw $8000, $8000, $8000, $0236, $00a9, $8000, $8000, $8000, $8000, $8000, $062b, $8000 ;HC Main Lobby (x61) -dw $0452, $0152, $8000, $8000, $0561, $8000, $8000, $8000, $8000, $0203, $0203, $0203 ;HC East Lobby (x62) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;Desert Back (x63) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;TT Attic L (x64) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;TT Attic R (x65) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x66 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x67 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x68 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x69 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6a -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6b -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6c -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6d -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6e -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6f -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x70 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; HC Cellblock (x80) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Vitreous (x90) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Mire Pre-Vitreous (xa0) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Trinexx (xa4) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Eastern Compass (xa8) -dw $8000, $8000, $8000, $04a8, $00a8, $8000, $8000, $8000, $8000, $0161, $00aa, $8000 ; Eastern Courtyard (xa9) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Eastern Map (xaa) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xb0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xc0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xd0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xe0 diff --git a/asm/testdata/vanilla.txt b/asm/testdata/vanilla.txt deleted file mode 100644 index 8f3f4517..00000000 --- a/asm/testdata/vanilla.txt +++ /dev/null @@ -1,227 +0,0 @@ -org $27A000 -DoorTable: -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Ganon -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; HC Back Hall (x01) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Sewer Switches (x02) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x10 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x20 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;PoD Arena (x2a) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;PoD Statue (x2b) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x30 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Swamp Main (x36) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x40 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC West Hall (x50) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC Throne Room (x51) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC East Hall (x52) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC West Lobby (x60) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC Main Lobby (x61) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC East Lobby (x62) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;Desert Back (x63) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;TT Attic L (x64) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;TT Attic R (x65) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x66 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x67 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x68 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x69 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6a -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6b -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6c -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6d -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6e -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6f -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x70 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; HC Cellblock (x80) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Vitreous (x90) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Mire Pre-Vitreous (xa0) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Trinexx (xa4) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Eastern Compass (xa8) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Eastern Courtyard (xa9) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Eastern Map (xaa) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xb0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xc0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xd0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xe0 diff --git a/asm/testdata/verticaltest.txt b/asm/testdata/verticaltest.txt deleted file mode 100644 index 89c79232..00000000 --- a/asm/testdata/verticaltest.txt +++ /dev/null @@ -1,227 +0,0 @@ -org $27A000 -DoorTable: -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Ganon -dw $8000, $8000, $8000, $0450, $8000, $8000, $8000, $8000, $8000, $0452, $8000, $8000 ; HC Back Hall (x01) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $0112, $8000, $8000, $8000, $8000 ; Sewer Switches (x02) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x10 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x20 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;PoD Arena (x2a) -dw $8000, $8000, $8000, $8000, $8000, $0161, $8000, $8000, $8000, $8000, $8000, $8000 ;PoD Statue (x2b) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x30 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $0061 ; Swamp Main (x36) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; x40 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $0462, $0061, $8000, $8000 ;HC West Hall (x50) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;HC Throne Room (x51) -dw $8000, $8000, $8000, $0401, $8000, $8000, $0162, $0660, $8000, $8000, $8000, $8000 ;HC East Hall (x52) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $0152, $8000, $8000, $8000, $8000, $8000, $8000, $0061, $0561, $8000 ;HC West Lobby (x60) -dw $8000, $8000, $8000, $0236, $0160, $8000, $8000, $8000, $8000, $8000, $0162, $8000 ;HC Main Lobby (x61) -dw $0650, $0452, $8000, $8000, $0561, $8000, $8000, $8000, $8000, $0203, $0203, $0203 ;HC East Lobby (x62) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;Desert Back (x63) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;TT Attic L (x64) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;TT Attic R (x65) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x66 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x67 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x68 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x69 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6a -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6b -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6c -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6d -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6e -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x6f -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ;x70 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; HC Cellblock (x80) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Vitreous (x90) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Mire Pre-Vitreous (xa0) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Trinexx (xa4) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Eastern Compass (xa8) -dw $8000, $8000, $8000, $04a8, $00a8, $8000, $8000, $8000, $8000, $0161, $00aa, $8000 ; Eastern Courtyard (xa9) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; Eastern Map (xaa) -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xb0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xc0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xd0 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 -dw $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000, $8000 ; xe0 diff --git a/data/base2current.bps b/data/base2current.bps index 6c0e12f3..e6438813 100644 Binary files a/data/base2current.bps and b/data/base2current.bps differ diff --git a/data/itemgfx/Apples.gif b/data/itemgfx/Apples.gif new file mode 100644 index 00000000..53cb2725 Binary files /dev/null and b/data/itemgfx/Apples.gif differ diff --git a/data/itemgfx/Arrow Upgrade (+10).gif b/data/itemgfx/Arrow Upgrade (+10).gif new file mode 100644 index 00000000..8b9c158b Binary files /dev/null and b/data/itemgfx/Arrow Upgrade (+10).gif differ diff --git a/data/itemgfx/Arrow Upgrade (+5).gif b/data/itemgfx/Arrow Upgrade (+5).gif new file mode 100644 index 00000000..25d2c7fd Binary files /dev/null and b/data/itemgfx/Arrow Upgrade (+5).gif differ diff --git a/data/itemgfx/Arrow Upgrade (70).gif b/data/itemgfx/Arrow Upgrade (70).gif new file mode 100644 index 00000000..db7cff10 Binary files /dev/null and b/data/itemgfx/Arrow Upgrade (70).gif differ diff --git a/data/itemgfx/Arrow.gif b/data/itemgfx/Arrow.gif new file mode 100644 index 00000000..fb3656a4 Binary files /dev/null and b/data/itemgfx/Arrow.gif differ diff --git a/data/itemgfx/Arrows (10).gif b/data/itemgfx/Arrows (10).gif new file mode 100644 index 00000000..54f0962c Binary files /dev/null and b/data/itemgfx/Arrows (10).gif differ diff --git a/data/itemgfx/Bee Trap.gif b/data/itemgfx/Bee Trap.gif new file mode 100644 index 00000000..b1706373 Binary files /dev/null and b/data/itemgfx/Bee Trap.gif differ diff --git a/data/itemgfx/Big Key.gif b/data/itemgfx/Big Key.gif new file mode 100644 index 00000000..026b6ae5 Binary files /dev/null and b/data/itemgfx/Big Key.gif differ diff --git a/data/itemgfx/Blacksmith.gif b/data/itemgfx/Blacksmith.gif new file mode 100644 index 00000000..30b372d8 Binary files /dev/null and b/data/itemgfx/Blacksmith.gif differ diff --git a/data/itemgfx/Blue Clock.gif b/data/itemgfx/Blue Clock.gif new file mode 100644 index 00000000..b60111ca Binary files /dev/null and b/data/itemgfx/Blue Clock.gif differ diff --git a/data/itemgfx/Blue Maiden (Body).gif b/data/itemgfx/Blue Maiden (Body).gif new file mode 100644 index 00000000..d6567942 Binary files /dev/null and b/data/itemgfx/Blue Maiden (Body).gif differ diff --git a/data/itemgfx/Blue Mail.gif b/data/itemgfx/Blue Mail.gif new file mode 100644 index 00000000..f82bcad3 Binary files /dev/null and b/data/itemgfx/Blue Mail.gif differ diff --git a/data/itemgfx/Blue Pendant.gif b/data/itemgfx/Blue Pendant.gif new file mode 100644 index 00000000..acbecc1a Binary files /dev/null and b/data/itemgfx/Blue Pendant.gif differ diff --git a/data/itemgfx/Blue Potion (B).gif b/data/itemgfx/Blue Potion (B).gif new file mode 100644 index 00000000..31364657 Binary files /dev/null and b/data/itemgfx/Blue Potion (B).gif differ diff --git a/data/itemgfx/Blue Potion.gif b/data/itemgfx/Blue Potion.gif new file mode 100644 index 00000000..8cc533e8 Binary files /dev/null and b/data/itemgfx/Blue Potion.gif differ diff --git a/data/itemgfx/Blue Shield (Thin).gif b/data/itemgfx/Blue Shield (Thin).gif new file mode 100644 index 00000000..2c9f7770 Binary files /dev/null and b/data/itemgfx/Blue Shield (Thin).gif differ diff --git a/data/itemgfx/Blue Shield.gif b/data/itemgfx/Blue Shield.gif new file mode 100644 index 00000000..196c216e Binary files /dev/null and b/data/itemgfx/Blue Shield.gif differ diff --git a/data/itemgfx/Bomb Upgrade (+10).gif b/data/itemgfx/Bomb Upgrade (+10).gif new file mode 100644 index 00000000..65e0675e Binary files /dev/null and b/data/itemgfx/Bomb Upgrade (+10).gif differ diff --git a/data/itemgfx/Bomb Upgrade (+5).gif b/data/itemgfx/Bomb Upgrade (+5).gif new file mode 100644 index 00000000..5c943927 Binary files /dev/null and b/data/itemgfx/Bomb Upgrade (+5).gif differ diff --git a/data/itemgfx/Bomb Upgrade (50).gif b/data/itemgfx/Bomb Upgrade (50).gif new file mode 100644 index 00000000..7a5b9a38 Binary files /dev/null and b/data/itemgfx/Bomb Upgrade (50).gif differ diff --git a/data/itemgfx/Bomb.gif b/data/itemgfx/Bomb.gif new file mode 100644 index 00000000..7f578fe6 Binary files /dev/null and b/data/itemgfx/Bomb.gif differ diff --git a/data/itemgfx/Bombbag.gif b/data/itemgfx/Bombbag.gif new file mode 100644 index 00000000..2f6f234e Binary files /dev/null and b/data/itemgfx/Bombbag.gif differ diff --git a/data/itemgfx/Bombos.gif b/data/itemgfx/Bombos.gif new file mode 100644 index 00000000..f5757b08 Binary files /dev/null and b/data/itemgfx/Bombos.gif differ diff --git a/data/itemgfx/Bombs (10).gif b/data/itemgfx/Bombs (10).gif new file mode 100644 index 00000000..2510e18b Binary files /dev/null and b/data/itemgfx/Bombs (10).gif differ diff --git a/data/itemgfx/Bombs (3).gif b/data/itemgfx/Bombs (3).gif new file mode 100644 index 00000000..4ccaa4d3 Binary files /dev/null and b/data/itemgfx/Bombs (3).gif differ diff --git a/data/itemgfx/Book of Mudora.gif b/data/itemgfx/Book of Mudora.gif new file mode 100644 index 00000000..b198d5a4 Binary files /dev/null and b/data/itemgfx/Book of Mudora.gif differ diff --git a/data/itemgfx/Boomerang.gif b/data/itemgfx/Boomerang.gif new file mode 100644 index 00000000..fed694ba Binary files /dev/null and b/data/itemgfx/Boomerang.gif differ diff --git a/data/itemgfx/Bottle (Bee).gif b/data/itemgfx/Bottle (Bee).gif new file mode 100644 index 00000000..d16add0f Binary files /dev/null and b/data/itemgfx/Bottle (Bee).gif differ diff --git a/data/itemgfx/Bottle (Blue Potion).gif b/data/itemgfx/Bottle (Blue Potion).gif new file mode 100644 index 00000000..f9c1560b Binary files /dev/null and b/data/itemgfx/Bottle (Blue Potion).gif differ diff --git a/data/itemgfx/Bottle (Fairy).gif b/data/itemgfx/Bottle (Fairy).gif new file mode 100644 index 00000000..d691e96a Binary files /dev/null and b/data/itemgfx/Bottle (Fairy).gif differ diff --git a/data/itemgfx/Bottle (Green Potion).gif b/data/itemgfx/Bottle (Green Potion).gif new file mode 100644 index 00000000..bb443f2c Binary files /dev/null and b/data/itemgfx/Bottle (Green Potion).gif differ diff --git a/data/itemgfx/Bottle (Red Potion).gif b/data/itemgfx/Bottle (Red Potion).gif new file mode 100644 index 00000000..3613a148 Binary files /dev/null and b/data/itemgfx/Bottle (Red Potion).gif differ diff --git a/data/itemgfx/Bottle.gif b/data/itemgfx/Bottle.gif new file mode 100644 index 00000000..477de6cf Binary files /dev/null and b/data/itemgfx/Bottle.gif differ diff --git a/data/itemgfx/Bow.gif b/data/itemgfx/Bow.gif new file mode 100644 index 00000000..18ee3d6c Binary files /dev/null and b/data/itemgfx/Bow.gif differ diff --git a/data/itemgfx/Bug Net.gif b/data/itemgfx/Bug Net.gif new file mode 100644 index 00000000..2795115f Binary files /dev/null and b/data/itemgfx/Bug Net.gif differ diff --git a/data/itemgfx/Byrna.gif b/data/itemgfx/Byrna.gif new file mode 100644 index 00000000..439ad828 Binary files /dev/null and b/data/itemgfx/Byrna.gif differ diff --git a/data/itemgfx/Chest.gif b/data/itemgfx/Chest.gif new file mode 100644 index 00000000..68e07985 Binary files /dev/null and b/data/itemgfx/Chest.gif differ diff --git a/data/itemgfx/Chicken.gif b/data/itemgfx/Chicken.gif new file mode 100644 index 00000000..f959f8bb Binary files /dev/null and b/data/itemgfx/Chicken.gif differ diff --git a/data/itemgfx/Compass.gif b/data/itemgfx/Compass.gif new file mode 100644 index 00000000..6a88b996 Binary files /dev/null and b/data/itemgfx/Compass.gif differ diff --git a/data/itemgfx/Crystal.gif b/data/itemgfx/Crystal.gif new file mode 100644 index 00000000..8492f4c7 Binary files /dev/null and b/data/itemgfx/Crystal.gif differ diff --git a/data/itemgfx/Duck.gif b/data/itemgfx/Duck.gif new file mode 100644 index 00000000..df8edbf3 Binary files /dev/null and b/data/itemgfx/Duck.gif differ diff --git a/data/itemgfx/Egg.gif b/data/itemgfx/Egg.gif new file mode 100644 index 00000000..b848c53c Binary files /dev/null and b/data/itemgfx/Egg.gif differ diff --git a/data/itemgfx/Ether.gif b/data/itemgfx/Ether.gif new file mode 100644 index 00000000..cd3e7294 Binary files /dev/null and b/data/itemgfx/Ether.gif differ diff --git a/data/itemgfx/Fairy.gif b/data/itemgfx/Fairy.gif new file mode 100644 index 00000000..3f461512 Binary files /dev/null and b/data/itemgfx/Fairy.gif differ diff --git a/data/itemgfx/Fighter Sword (Thin).gif b/data/itemgfx/Fighter Sword (Thin).gif new file mode 100644 index 00000000..a34335f2 Binary files /dev/null and b/data/itemgfx/Fighter Sword (Thin).gif differ diff --git a/data/itemgfx/Fighter Sword.gif b/data/itemgfx/Fighter Sword.gif new file mode 100644 index 00000000..4f5f2046 Binary files /dev/null and b/data/itemgfx/Fighter Sword.gif differ diff --git a/data/itemgfx/Fire Rod.gif b/data/itemgfx/Fire Rod.gif new file mode 100644 index 00000000..fdde5d16 Binary files /dev/null and b/data/itemgfx/Fire Rod.gif differ diff --git a/data/itemgfx/Fire Shield.gif b/data/itemgfx/Fire Shield.gif new file mode 100644 index 00000000..b4a151c7 Binary files /dev/null and b/data/itemgfx/Fire Shield.gif differ diff --git a/data/itemgfx/Fire.gif b/data/itemgfx/Fire.gif new file mode 100644 index 00000000..69f8250a Binary files /dev/null and b/data/itemgfx/Fire.gif differ diff --git a/data/itemgfx/Flippers.gif b/data/itemgfx/Flippers.gif new file mode 100644 index 00000000..c1cc5814 Binary files /dev/null and b/data/itemgfx/Flippers.gif differ diff --git a/data/itemgfx/Frog.gif b/data/itemgfx/Frog.gif new file mode 100644 index 00000000..e3c00a4e Binary files /dev/null and b/data/itemgfx/Frog.gif differ diff --git a/data/itemgfx/Full Magic.gif b/data/itemgfx/Full Magic.gif new file mode 100644 index 00000000..ed594f88 Binary files /dev/null and b/data/itemgfx/Full Magic.gif differ diff --git a/data/itemgfx/Golden Sword (Thin).gif b/data/itemgfx/Golden Sword (Thin).gif new file mode 100644 index 00000000..69a61930 Binary files /dev/null and b/data/itemgfx/Golden Sword (Thin).gif differ diff --git a/data/itemgfx/Golden Sword.gif b/data/itemgfx/Golden Sword.gif new file mode 100644 index 00000000..54cd4a13 Binary files /dev/null and b/data/itemgfx/Golden Sword.gif differ diff --git a/data/itemgfx/Green Clock.gif b/data/itemgfx/Green Clock.gif new file mode 100644 index 00000000..9e5a666e Binary files /dev/null and b/data/itemgfx/Green Clock.gif differ diff --git a/data/itemgfx/Green Maiden (Body).gif b/data/itemgfx/Green Maiden (Body).gif new file mode 100644 index 00000000..6c9fad99 Binary files /dev/null and b/data/itemgfx/Green Maiden (Body).gif differ diff --git a/data/itemgfx/Green Mail.gif b/data/itemgfx/Green Mail.gif new file mode 100644 index 00000000..793ec1ad Binary files /dev/null and b/data/itemgfx/Green Mail.gif differ diff --git a/data/itemgfx/Green Pendant.gif b/data/itemgfx/Green Pendant.gif new file mode 100644 index 00000000..9db766fe Binary files /dev/null and b/data/itemgfx/Green Pendant.gif differ diff --git a/data/itemgfx/Green Potion (G).gif b/data/itemgfx/Green Potion (G).gif new file mode 100644 index 00000000..f812ca71 Binary files /dev/null and b/data/itemgfx/Green Potion (G).gif differ diff --git a/data/itemgfx/Green Potion.gif b/data/itemgfx/Green Potion.gif new file mode 100644 index 00000000..591fee95 Binary files /dev/null and b/data/itemgfx/Green Potion.gif differ diff --git a/data/itemgfx/Green Rupees (20).gif b/data/itemgfx/Green Rupees (20).gif new file mode 100644 index 00000000..6dd23918 Binary files /dev/null and b/data/itemgfx/Green Rupees (20).gif differ diff --git a/data/itemgfx/Half Magic.gif b/data/itemgfx/Half Magic.gif new file mode 100644 index 00000000..ae039e5b Binary files /dev/null and b/data/itemgfx/Half Magic.gif differ diff --git a/data/itemgfx/Hammer.gif b/data/itemgfx/Hammer.gif new file mode 100644 index 00000000..2e5f68f3 Binary files /dev/null and b/data/itemgfx/Hammer.gif differ diff --git a/data/itemgfx/Heart (Blue).gif b/data/itemgfx/Heart (Blue).gif new file mode 100644 index 00000000..ead09923 Binary files /dev/null and b/data/itemgfx/Heart (Blue).gif differ diff --git a/data/itemgfx/Heart (Green).gif b/data/itemgfx/Heart (Green).gif new file mode 100644 index 00000000..b9cdc4b0 Binary files /dev/null and b/data/itemgfx/Heart (Green).gif differ diff --git a/data/itemgfx/Heart Container (Blue).gif b/data/itemgfx/Heart Container (Blue).gif new file mode 100644 index 00000000..3fb54bfc Binary files /dev/null and b/data/itemgfx/Heart Container (Blue).gif differ diff --git a/data/itemgfx/Heart Container (Green).gif b/data/itemgfx/Heart Container (Green).gif new file mode 100644 index 00000000..bfa4ace8 Binary files /dev/null and b/data/itemgfx/Heart Container (Green).gif differ diff --git a/data/itemgfx/Heart Container.gif b/data/itemgfx/Heart Container.gif new file mode 100644 index 00000000..97bde533 Binary files /dev/null and b/data/itemgfx/Heart Container.gif differ diff --git a/data/itemgfx/Heart.gif b/data/itemgfx/Heart.gif new file mode 100644 index 00000000..dbe31169 Binary files /dev/null and b/data/itemgfx/Heart.gif differ diff --git a/data/itemgfx/Hookshot.gif b/data/itemgfx/Hookshot.gif new file mode 100644 index 00000000..c97f65f2 Binary files /dev/null and b/data/itemgfx/Hookshot.gif differ diff --git a/data/itemgfx/Ice Rod.gif b/data/itemgfx/Ice Rod.gif new file mode 100644 index 00000000..59d5fa3e Binary files /dev/null and b/data/itemgfx/Ice Rod.gif differ diff --git a/data/itemgfx/Kiki (Body).gif b/data/itemgfx/Kiki (Body).gif new file mode 100644 index 00000000..39305489 Binary files /dev/null and b/data/itemgfx/Kiki (Body).gif differ diff --git a/data/itemgfx/Kiki (Head).gif b/data/itemgfx/Kiki (Head).gif new file mode 100644 index 00000000..232f6c86 Binary files /dev/null and b/data/itemgfx/Kiki (Head).gif differ diff --git a/data/itemgfx/Lamp.gif b/data/itemgfx/Lamp.gif new file mode 100644 index 00000000..a48c95be Binary files /dev/null and b/data/itemgfx/Lamp.gif differ diff --git a/data/itemgfx/Locksmith (Body).gif b/data/itemgfx/Locksmith (Body).gif new file mode 100644 index 00000000..9dec6d2f Binary files /dev/null and b/data/itemgfx/Locksmith (Body).gif differ diff --git a/data/itemgfx/Locksmith (Head).gif b/data/itemgfx/Locksmith (Head).gif new file mode 100644 index 00000000..f9c373b6 Binary files /dev/null and b/data/itemgfx/Locksmith (Head).gif differ diff --git a/data/itemgfx/Lumberjack (Head).gif b/data/itemgfx/Lumberjack (Head).gif new file mode 100644 index 00000000..d607b9d8 Binary files /dev/null and b/data/itemgfx/Lumberjack (Head).gif differ diff --git a/data/itemgfx/Magic Cape.gif b/data/itemgfx/Magic Cape.gif new file mode 100644 index 00000000..4e9442ed Binary files /dev/null and b/data/itemgfx/Magic Cape.gif differ diff --git a/data/itemgfx/Magic Mirror.gif b/data/itemgfx/Magic Mirror.gif new file mode 100644 index 00000000..e71a088a Binary files /dev/null and b/data/itemgfx/Magic Mirror.gif differ diff --git a/data/itemgfx/Magic Powder.gif b/data/itemgfx/Magic Powder.gif new file mode 100644 index 00000000..d805b264 Binary files /dev/null and b/data/itemgfx/Magic Powder.gif differ diff --git a/data/itemgfx/Maiden (Head).gif b/data/itemgfx/Maiden (Head).gif new file mode 100644 index 00000000..a67b7851 Binary files /dev/null and b/data/itemgfx/Maiden (Head).gif differ diff --git a/data/itemgfx/Map.gif b/data/itemgfx/Map.gif new file mode 100644 index 00000000..c8b90b47 Binary files /dev/null and b/data/itemgfx/Map.gif differ diff --git a/data/itemgfx/Master Key.gif b/data/itemgfx/Master Key.gif new file mode 100644 index 00000000..5c4d950a Binary files /dev/null and b/data/itemgfx/Master Key.gif differ diff --git a/data/itemgfx/Master Sword (Thin).gif b/data/itemgfx/Master Sword (Thin).gif new file mode 100644 index 00000000..f5766313 Binary files /dev/null and b/data/itemgfx/Master Sword (Thin).gif differ diff --git a/data/itemgfx/Master Sword.gif b/data/itemgfx/Master Sword.gif new file mode 100644 index 00000000..a730f087 Binary files /dev/null and b/data/itemgfx/Master Sword.gif differ diff --git a/data/itemgfx/Mirror Shield.gif b/data/itemgfx/Mirror Shield.gif new file mode 100644 index 00000000..790fcac4 Binary files /dev/null and b/data/itemgfx/Mirror Shield.gif differ diff --git a/data/itemgfx/Moon Pearl.gif b/data/itemgfx/Moon Pearl.gif new file mode 100644 index 00000000..4622e154 Binary files /dev/null and b/data/itemgfx/Moon Pearl.gif differ diff --git a/data/itemgfx/Mushroom.gif b/data/itemgfx/Mushroom.gif new file mode 100644 index 00000000..b533aeb7 Binary files /dev/null and b/data/itemgfx/Mushroom.gif differ diff --git a/data/itemgfx/Ocarina.gif b/data/itemgfx/Ocarina.gif new file mode 100644 index 00000000..ff68f924 Binary files /dev/null and b/data/itemgfx/Ocarina.gif differ diff --git a/data/itemgfx/Old Man (Body).gif b/data/itemgfx/Old Man (Body).gif new file mode 100644 index 00000000..7de45046 Binary files /dev/null and b/data/itemgfx/Old Man (Body).gif differ diff --git a/data/itemgfx/Old Man (Head).gif b/data/itemgfx/Old Man (Head).gif new file mode 100644 index 00000000..ca34f42a Binary files /dev/null and b/data/itemgfx/Old Man (Head).gif differ diff --git a/data/itemgfx/Open Chest.gif b/data/itemgfx/Open Chest.gif new file mode 100644 index 00000000..5ad6c64a Binary files /dev/null and b/data/itemgfx/Open Chest.gif differ diff --git a/data/itemgfx/Pegasus Boots.gif b/data/itemgfx/Pegasus Boots.gif new file mode 100644 index 00000000..5c2503a2 Binary files /dev/null and b/data/itemgfx/Pegasus Boots.gif differ diff --git a/data/itemgfx/Piece of Heart.gif b/data/itemgfx/Piece of Heart.gif new file mode 100644 index 00000000..be6d378b Binary files /dev/null and b/data/itemgfx/Piece of Heart.gif differ diff --git a/data/itemgfx/Power Glove.gif b/data/itemgfx/Power Glove.gif new file mode 100644 index 00000000..81752b3d Binary files /dev/null and b/data/itemgfx/Power Glove.gif differ diff --git a/data/itemgfx/Power Star.gif b/data/itemgfx/Power Star.gif new file mode 100644 index 00000000..89b7b948 Binary files /dev/null and b/data/itemgfx/Power Star.gif differ diff --git a/data/itemgfx/Progressive Bow.gif b/data/itemgfx/Progressive Bow.gif new file mode 100644 index 00000000..b61c67f8 Binary files /dev/null and b/data/itemgfx/Progressive Bow.gif differ diff --git a/data/itemgfx/Pseudoboots.gif b/data/itemgfx/Pseudoboots.gif new file mode 100644 index 00000000..3d08f85b Binary files /dev/null and b/data/itemgfx/Pseudoboots.gif differ diff --git a/data/itemgfx/Pseudolamp.gif b/data/itemgfx/Pseudolamp.gif new file mode 100644 index 00000000..2eb31420 Binary files /dev/null and b/data/itemgfx/Pseudolamp.gif differ diff --git a/data/itemgfx/Purple Chest.gif b/data/itemgfx/Purple Chest.gif new file mode 100644 index 00000000..745f6419 Binary files /dev/null and b/data/itemgfx/Purple Chest.gif differ diff --git a/data/itemgfx/Quake.gif b/data/itemgfx/Quake.gif new file mode 100644 index 00000000..e86194db Binary files /dev/null and b/data/itemgfx/Quake.gif differ diff --git a/data/itemgfx/Quarter Magic.gif b/data/itemgfx/Quarter Magic.gif new file mode 100644 index 00000000..97841b1e Binary files /dev/null and b/data/itemgfx/Quarter Magic.gif differ diff --git a/data/itemgfx/Red Boomerang.gif b/data/itemgfx/Red Boomerang.gif new file mode 100644 index 00000000..052dfa99 Binary files /dev/null and b/data/itemgfx/Red Boomerang.gif differ diff --git a/data/itemgfx/Red Clock.gif b/data/itemgfx/Red Clock.gif new file mode 100644 index 00000000..9629dccc Binary files /dev/null and b/data/itemgfx/Red Clock.gif differ diff --git a/data/itemgfx/Red Crystal.gif b/data/itemgfx/Red Crystal.gif new file mode 100644 index 00000000..6d17df29 Binary files /dev/null and b/data/itemgfx/Red Crystal.gif differ diff --git a/data/itemgfx/Red Maiden (Body).gif b/data/itemgfx/Red Maiden (Body).gif new file mode 100644 index 00000000..625947d3 Binary files /dev/null and b/data/itemgfx/Red Maiden (Body).gif differ diff --git a/data/itemgfx/Red Mail.gif b/data/itemgfx/Red Mail.gif new file mode 100644 index 00000000..0cc9885f Binary files /dev/null and b/data/itemgfx/Red Mail.gif differ diff --git a/data/itemgfx/Red Pendant.gif b/data/itemgfx/Red Pendant.gif new file mode 100644 index 00000000..dcf55738 Binary files /dev/null and b/data/itemgfx/Red Pendant.gif differ diff --git a/data/itemgfx/Red Potion (R).gif b/data/itemgfx/Red Potion (R).gif new file mode 100644 index 00000000..a39f20cd Binary files /dev/null and b/data/itemgfx/Red Potion (R).gif differ diff --git a/data/itemgfx/Red Potion.gif b/data/itemgfx/Red Potion.gif new file mode 100644 index 00000000..1bf1960e Binary files /dev/null and b/data/itemgfx/Red Potion.gif differ diff --git a/data/itemgfx/Rupee (1).gif b/data/itemgfx/Rupee (1).gif new file mode 100644 index 00000000..a2d025fe Binary files /dev/null and b/data/itemgfx/Rupee (1).gif differ diff --git a/data/itemgfx/Rupee (20).gif b/data/itemgfx/Rupee (20).gif new file mode 100644 index 00000000..88f807ff Binary files /dev/null and b/data/itemgfx/Rupee (20).gif differ diff --git a/data/itemgfx/Rupee (5).gif b/data/itemgfx/Rupee (5).gif new file mode 100644 index 00000000..c2744645 Binary files /dev/null and b/data/itemgfx/Rupee (5).gif differ diff --git a/data/itemgfx/Rupees (100).gif b/data/itemgfx/Rupees (100).gif new file mode 100644 index 00000000..1caa75f5 Binary files /dev/null and b/data/itemgfx/Rupees (100).gif differ diff --git a/data/itemgfx/Rupees (300).gif b/data/itemgfx/Rupees (300).gif new file mode 100644 index 00000000..6163dd17 Binary files /dev/null and b/data/itemgfx/Rupees (300).gif differ diff --git a/data/itemgfx/Rupees (50).gif b/data/itemgfx/Rupees (50).gif new file mode 100644 index 00000000..df4789c9 Binary files /dev/null and b/data/itemgfx/Rupees (50).gif differ diff --git a/data/itemgfx/Shovel.gif b/data/itemgfx/Shovel.gif new file mode 100644 index 00000000..fc211be3 Binary files /dev/null and b/data/itemgfx/Shovel.gif differ diff --git a/data/itemgfx/Silver Arrows (Ag).gif b/data/itemgfx/Silver Arrows (Ag).gif new file mode 100644 index 00000000..78e77cd4 Binary files /dev/null and b/data/itemgfx/Silver Arrows (Ag).gif differ diff --git a/data/itemgfx/Silver Arrows.gif b/data/itemgfx/Silver Arrows.gif new file mode 100644 index 00000000..454d5c28 Binary files /dev/null and b/data/itemgfx/Silver Arrows.gif differ diff --git a/data/itemgfx/Small Key.gif b/data/itemgfx/Small Key.gif new file mode 100644 index 00000000..b2632bfa Binary files /dev/null and b/data/itemgfx/Small Key.gif differ diff --git a/data/itemgfx/Small Magic.gif b/data/itemgfx/Small Magic.gif new file mode 100644 index 00000000..99b4b69d Binary files /dev/null and b/data/itemgfx/Small Magic.gif differ diff --git a/data/itemgfx/Somaria.gif b/data/itemgfx/Somaria.gif new file mode 100644 index 00000000..79327b8a Binary files /dev/null and b/data/itemgfx/Somaria.gif differ diff --git a/data/itemgfx/Super Bomb.gif b/data/itemgfx/Super Bomb.gif new file mode 100644 index 00000000..42ae2056 Binary files /dev/null and b/data/itemgfx/Super Bomb.gif differ diff --git a/data/itemgfx/Sword and Shield.gif b/data/itemgfx/Sword and Shield.gif new file mode 100644 index 00000000..de135c5d Binary files /dev/null and b/data/itemgfx/Sword and Shield.gif differ diff --git a/data/itemgfx/Tempered Sword (Thin).gif b/data/itemgfx/Tempered Sword (Thin).gif new file mode 100644 index 00000000..a1391b7d Binary files /dev/null and b/data/itemgfx/Tempered Sword (Thin).gif differ diff --git a/data/itemgfx/Tempered Sword.gif b/data/itemgfx/Tempered Sword.gif new file mode 100644 index 00000000..7a47e2cf Binary files /dev/null and b/data/itemgfx/Tempered Sword.gif differ diff --git a/data/itemgfx/Titans Mitt.gif b/data/itemgfx/Titans Mitt.gif new file mode 100644 index 00000000..bfd90ffa Binary files /dev/null and b/data/itemgfx/Titans Mitt.gif differ diff --git a/data/itemgfx/Triforce.gif b/data/itemgfx/Triforce.gif new file mode 100644 index 00000000..33f4e3d5 Binary files /dev/null and b/data/itemgfx/Triforce.gif differ diff --git a/data/itemgfx/Warp Tile.gif b/data/itemgfx/Warp Tile.gif new file mode 100644 index 00000000..6ba33bb1 Binary files /dev/null and b/data/itemgfx/Warp Tile.gif differ diff --git a/data/itemgfx/Whirlpool.gif b/data/itemgfx/Whirlpool.gif new file mode 100644 index 00000000..26edb127 Binary files /dev/null and b/data/itemgfx/Whirlpool.gif differ diff --git a/data/itemgfx/Zelda (Body).gif b/data/itemgfx/Zelda (Body).gif new file mode 100644 index 00000000..5db7ac8c Binary files /dev/null and b/data/itemgfx/Zelda (Body).gif differ diff --git a/data/itemgfx/Zelda (Head).gif b/data/itemgfx/Zelda (Head).gif new file mode 100644 index 00000000..a5f5d80f Binary files /dev/null and b/data/itemgfx/Zelda (Head).gif differ diff --git a/docs/Customizer.md b/docs/Customizer.md index 0113a501..17c5c337 100644 --- a/docs/Customizer.md +++ b/docs/Customizer.md @@ -51,7 +51,9 @@ Start inventory is not supported here. It has a separate section. Some settings are intended to only be accessed using the customizer: * `aga_randomness` setting this to false, turns off blue balls and ganon warp randomness -* `money_balance` this is a percent (0-100). For numbers less than 100, both price balancing and money balancing will only attempt to ensure the player has access to only a percentage of the required funds. When 0, this should effectively disable money balancing. Grinding for rupees may be necessary whenever this is less than 100. +* `money_balance` this is a percent (0-100). For numbers less than 100, both price balancing and money balancing will only attempt to ensure the player has access to only a percentage of the required funds. When 0, this should effectively disable money balancing. Grinding for rupees may be necessary whenever this is less than 100. +* `free_lamp_cone` setting this to true will make all dark rooms have a light cone without lamp. The lamp will be placed without regard to dark room logic. +* `force_enemy` setting this to a specific enemy (like 'StalfosKnight' or 'Lynel', complete list in EnemyList.py) will attempt to make all enemies that type. Some enemies cannot be changed (like bosses). Known issues with gfx glitches occurring in the overworld, as they do not limit the enemy types as appropriate for the sprite sheet. ###### Not Yet Implemented @@ -70,6 +72,134 @@ Then each player can have the entire item pool defined. The name of item should Dungeon items amount can be increased (but not decreased as the minimum of each dungeon item is either pre-determined or calculated by door rando) if the type of dungeon item is not shuffled then it is attempted to be placed in the dungeon. Extra item beyond dungeon capacity not be confined to the dungeon. +### goals + +This must be defined by player. Each player number should be listed with the appropriate custom goals. This section has four primary subsections for each of the current supported events: + +* `gtentry` (Ganon's Tower entrance) +* `ganongoal` (Ganon vulnerability) +* `pedgoal` (Master Sword Pedestal activation) +* `murahgoal` (Murahdahla requirement, if given requirements, Murahdahla appears always and acts as an alternative way to beat the game) + +These four custom goals use the following identical structure to define them. These goals have four primary subsections: `cutscene_gfx`, `goaltext`, `requirements`, and `logic` + +#### cutscene_gfx + +This is where you can define custom GFX to be used for an event that has an animation (currently only the GT entry cutscene is supported). For convenience, there are a number of pre-defined names that can be used to indicate already known GFX values built into the ROM. There are too many to list, but a full list can be found in `item_gfx_table` in `Tables.py`. You can also use `Random` and it will take a random one from the aforementioned table. + +```yaml +goals: + 1: + gtentry: + cutscene_gfx: Mirror Shield +``` + +Alternatively, you may also supply a custom address and palette ID, respectively, if you are injecting your own personal custom GFX into the ROM. + +```yaml +goals: + 1: + gtentry: + cutscene_gfx: + - 0x8140 + - 0x04 +``` + +#### goaltext + +This is where you define the dialogue that will show in-game that informs the player what the goal is. This section is required if a goal event has any `requirements` defined. This value can contain `%d` as a numeric placeholder, where this value will be provided by the goal information provided in the `requirements` section (prioritizes the first goal defined). + +A new dialogue has been added for Master Sword Pedestal, if you attempt to receive the pedestal item but do not satisfy the condition for it, a dialogue will appear. + +#### requirements + +For the various events, you may define many conditions for the player to meet. All of the conditions you specify must pass to activate the event. There are several built-in conditions that can be used and the logic will be automatically added for consideration. However, when `CustomGoal` goals are used, there is no automatic logic that gets applied for this; for this, you must supply additional logic information to be used during generation. For more information on this, see the `logic` subsection. Keep in mind, through this level of customization, it is possible to create unbeatable games, and it will be possible to require things that the game doesn't provide a way to see the current progress for, and none of the options here change any HUD or UI elements to expose that information. It will be important to be careful when making these definitions and to use all provided tools and information to minimize these risks. These are the current supported conditions: + +* `Pendants` (Default: 3) +* `Crystals` (Default: 7) +* `PendantBosses` (Default: 3) +* `CrystalBosses` (Default: 7) +* `PrizeBosses` (Default: 10) +* `Agahnim1Defeated` +* `Agahnim2Defeated` +* `TriforcePieces` (Default: set elsewhere) +* `CollectionRate` (Default: Max) +* `CustomGoal` (Needs additional `logic` defined when applicable) + +These condition sections use a default target value unless a `target` is specified to override the default. + +In addition, we have provided a `CustomGoal` to allow for very advanced control over custom requirements; this however requires some knowledge of either the rando assembly code, the LTTP disassembly source, or autotracker memory addresses. `CustomGoal` uses a few additional required and optional subsections: + +* `address`: An address from memory that the game should read to compare (Only addresses from banks 0x7E and 0x7F are valid) +* `target`: A value to use to compare to the value found at the address (Hexadecimal values can be used) +* `size`: Optional, default is 1 byte will be read from memory (`16bit` or `2 bytes` are valid keywords to specify 2 bytes should be read and compared) +* `comparison`: This is to specify the method of comparison that should take place + +##### comparison + +* `minimum` or `at least`: Checks if a value is met or exceeded. This will likely be the most common comparison method. +* `equals`: Checks if a value exactly matches +* `any flag`: Checks against a bitfield value to see if any flag bits are set. (ie. a target of 0x40 only checks the one flag) +* `flags match`: Checks against a bitfield value to see if all flag bits are set. (ie. a target of 0x70 checks if all 3 bits are set) +* `count bits`: Counts the number of bits are set and compares that to the target + +#### logic + +Logic is automatically calculated for all of the basic out-of-the-box conditions, so nothing additional is required for specification for these. But for `CustomGoal`, this `logic` subsection is here to allow mode sculptors to provide this custom logic. This section is handled by three subsections: `item`, `access`, and `ability` + +##### item + +This is simply a list of items that are to be logically required to unlock the event. If multiple of the an item are needed, use an `=` followed by the amount required (ie. `- Triforce Piece=30`). For better support of Door Rando, dungeon items can be specified with a region name instead of a dungeon name; this way if you want to require a specific Big Key that opens a specific big chest in some room, this is possible to achieve (ie. `- Big Key (PoD Big Chest Balcony)`) + +##### access + +This is a list of regions that are logically required to be able to access before unlocking an event. Region names are internally named and not exposed on spoiler logs, but can be found by browsing `Regions.py` + +##### ability + +This is a list of abilities that the player logically requires. These are built-in logical patterns to make it easy to bundle larger nuanced requirements into one single definition. Some abilities take in an optional or required parameter, specified within `(` and `)` following the ability keyword. Here are the allowed keywords: + +* `FarmBombs`: Link has access to repeatedly acquire bombs +* `CanUseBombs`: Link has the ability to use bombs +* `FarmRupees`: Link has access to repeatedly acquire rupees +* `NoBunny()`: Link is required to not be a bunny in the specified region +* `MagicExtension()`: Link has a magic meter with a higher capacity (parameter is optional, a value of 8 represents one normal full magic bar, default value if left blank is 16, which is equivalent to half magic or one bottle with access to a green potion) +* `CanStun`: Link has the ability to stun enemies +* `CanKill()`: Link has the ability to kill most enemy types (parameter is optional, higher number tends to favor weapons that don't consume ammo, default value is 6 enemies) +* `CanShootArrows`: Link has ability to fire arrows at enemies +* `CanBonkDrop`: Link is able to retrieve Bonk Drops from trees and rocks +* `CanLift`: Link is able to lift basic rocks +* `CanFlute`: Link has ability to use flute (includes access to flute activation) +* `HasFire`: Link has a fire source +* `CanMelt`: Link can melt ice with Firerod or Bombos +* `HasMMMedallion`: Link has the medallion required for unlocking Misery Mire entrance +* `HasTRMedallion`: Link has the medallion required for unlocking Turtle Rock entrance + +#### (example) + +This entire section is very advanced and can be used to make very powerful customizations to the game. To make the overall definition more clear, we provide an example that makes use of a lot of the controls in place: Ganon requiring both 5 crystals AND requiring opening the GT Big Chest + +```yaml +goals: + 1: + ganongoal: + goaltext: You’ll need %d crystals and to open the Big Chest in Ganon’s Tower + requirements: + - Crystals: + target: 5 + - Custom: + address: 0x7ef118 + target: 0x80 + comparison: flags match + logic: + item: + - Big Key (GT Big Chest) + access: + - GT Big Chest + ability: + - NoBunny(GT Big Chest) +``` + ### placements This must be defined by player. Each player number should be listed with the appropriate placement list. @@ -348,27 +478,3 @@ prices: Dark Death Mountain Shop - Right: 300 Dark Lake Hylia Shop - Left: 200 ``` - -### gt_entry - -This must be defined by player. This is where you are able to customize aspects of GT entry - -#### cutscene_gfx - -This is where you can define custom GFX to be used in the GT entry cutscene. For convenience, there are a number of pre-defined names that can be used to indicate already known GFX values built into the ROM. There are too many to list, but a full list can be found in `item_gfx_table` in `Tables.py`. You can also use `Random` and it will take a random one from the aforementioned table. - -``` -gt_entry: - 1: - cutscene_gfx: Mirror Shield -``` - -Alternatively, you may also supply a custom address and palette ID, respectively, if you are injecting your own personal custom GFX into the ROM. - -``` -gt_entry: - 1: - cutscene_gfx: - - 0x8140 - - 0x04 -``` diff --git a/presets/world/owr_vanilla.yaml b/presets/world/owr_vanilla.yaml index d26bb8fa..9c86cc79 100644 --- a/presets/world/owr_vanilla.yaml +++ b/presets/world/owr_vanilla.yaml @@ -1,14 +1,36 @@ ow-edges: 1: two-way: + Lost Woods NW: Master Sword Meadow SC + Lost Woods SW*: Lost Woods Pass NW* + Lost Woods SC*: Lost Woods Pass NE* + Lost Woods SE*: Kakariko Fortune NE* + Lost Woods EN*: Lumberjack WN* + Skull Woods SW*: Skull Woods Pass NW* + Skull Woods SC*: Skull Woods Pass NE* + Skull Woods SE*: Dark Fortune NE* + Skull Woods EN*: Dark Lumberjack WN* Lumberjack SW*: Mountain Pass NW* Dark Lumberjack SW*: Bumper Cave NW* + West Death Mountain EN*: East Death Mountain WN* + West Death Mountain ES*: East Death Mountain WS* + West Dark Death Mountain EN*: East Dark Death Mountain WN* + West Dark Death Mountain ES*: East Dark Death Mountain WS* + East Death Mountain EN*: Death Mountain TR Pegs WN* + East Dark Death Mountain EN*: Turtle Rock WN* Mountain Pass SE*: Kakariko Pond NE* Bumper Cave SE*: Outcast Pond NE* + Zora Waterfall NE: Zoras Domain SW Zora Waterfall SE*: Zora Approach NE* Catfish SE*: Catfish Approach NE* + Lost Woods Pass SW*: Kakariko NW* + Lost Woods Pass SE*: Kakariko NC* + Skull Woods Pass SW*: Village of Outcasts NW* + Skull Woods Pass SE*: Village of Outcasts NC* + Kakariko Fortune SC*: Kakariko NE* Kakariko Fortune EN*: Kakariko Pond WN* Kakariko Fortune ES*: Kakariko Pond WS* + Dark Fortune SC*: Village of Outcasts NE* Dark Fortune EN*: Outcast Pond WN* Dark Fortune ES*: Outcast Pond WS* Kakariko Pond EN*: Sanctuary WN* @@ -39,8 +61,25 @@ ow-edges: Potion Shop EC*: Zora Approach WC* Dark Witch EN*: Catfish Approach WN* Dark Witch EC*: Catfish Approach WC* + Zora Approach NE*: Zora Waterfall SE* + Catfish Approach NE*: Catfish SE* + Kakariko SE*: Kakariko Suburb NE* + Kakariko ES*: Blacksmith WS* + Village of Outcasts SE*: Frog NE* + Village of Outcasts ES*: Hammer Pegs WS* + Forgotten Forest ES: Hyrule Castle WN + Hyrule Castle SW*: Central Bonk Rocks NW* + Hyrule Castle SE*: Links House NE* + Hyrule Castle ES*: Sand Dunes WN* + Pyramid SW*: Dark Bonk Rocks NW* + Pyramid SE*: Big Bomb Shop NE* + Pyramid ES*: Dark Dunes WN* Wooden Bridge SW*: Sand Dunes NW* Broken Bridge SW*: Dark Dunes NW* + Eastern Palace SW*: Tree Line NW* + Eastern Palace SE*: Eastern Nook NE* + Palace of Darkness SW*: Dark Tree Line NW* + Palace of Darkness SE*: Palace of Darkness Nook NE* Sand Dunes SC*: Stone Bridge NC* Dark Dunes SC*: Hammer Bridge NC* Maze Race ES*: Kakariko Suburb WS* @@ -65,10 +104,18 @@ ow-edges: Big Bomb Shop SC*: Hype Cave NC* Big Bomb Shop ES*: Hammer Bridge WS* Stone Bridge WC: Hobo EC + Stone Bridge SC*: Lake Hylia NW* Stone Bridge EN*: Tree Line WN* Stone Bridge EC*: Tree Line WC* + Hammer Bridge SC*: Ice Lake NW* Hammer Bridge EN*: Dark Tree Line WN* Hammer Bridge EC*: Dark Tree Line WC* + Tree Line SC*: Lake Hylia NC* + Tree Line SE*: Lake Hylia NE* + Dark Tree Line SC*: Ice Lake NC* + Dark Tree Line SE*: Ice Lake NE* + Desert EC: Desert Pass WC + Desert ES: Desert Pass WS Flute Boy Approach EC*: C Whirlpool WC* Stumpy Approach EC*: Dark C Whirlpool WC* C Whirlpool EN*: Statues WN* @@ -81,6 +128,10 @@ ow-edges: Dark C Whirlpool SC*: Swamp NC* Statues SC*: South Pass NC* Hype Cave SC*: Dark South Pass NC* + Lake Hylia EC*: Octoballoon WC* + Lake Hylia ES*: Octoballoon WS* + Ice Lake EC*: Bomber Corner WC* + Ice Lake ES*: Bomber Corner WS* Ice Cave SW*: Octoballoon NW* Ice Cave SE*: Octoballoon NE* Shopping Mall SW*: Bomber Corner NW* @@ -91,96 +142,8 @@ ow-edges: Swamp Nook ES*: Swamp WS* Dam EC*: South Pass WC* Swamp EC*: Dark South Pass WC* - Lumberjack SW*: Mountain Pass NW* - Dark Lumberjack SW*: Bumper Cave NW* - Mountain Pass SE*: Kakariko Pond NE* - Bumper Cave SE*: Outcast Pond NE* - Zora Waterfall SE*: Zora Approach NE* - Catfish SE*: Catfish Approach NE* - Kakariko Fortune EN*: Kakariko Pond WN* - Kakariko Fortune ES*: Kakariko Pond WS* - Dark Fortune EN*: Outcast Pond WN* - Dark Fortune ES*: Outcast Pond WS* - Kakariko Pond EN*: Sanctuary WN* - Kakariko Pond ES*: Sanctuary WS* - Kakariko Pond SW*: Forgotten Forest NW* - Kakariko Pond SE*: Forgotten Forest NE* - Outcast Pond EN*: Dark Chapel WN* - Outcast Pond ES*: Dark Chapel WS* - Outcast Pond SW*: Shield Shop NW* - Outcast Pond SE*: Shield Shop NE* - Sanctuary EC*: Graveyard WC* - Dark Chapel EC*: Dark Graveyard WC* - Graveyard EC*: River Bend WC* - Dark Graveyard EC*: Qirn Jump WC* - River Bend EN*: Potion Shop WN* - River Bend EC*: Potion Shop WC* - River Bend ES*: Potion Shop WS* - River Bend SW*: Wooden Bridge NW* - River Bend SC*: Wooden Bridge NC* - River Bend SE*: Wooden Bridge NE* - Qirn Jump EN*: Dark Witch WN* - Qirn Jump EC*: Dark Witch WC* - Qirn Jump ES*: Dark Witch WS* - Qirn Jump SW*: Broken Bridge NW* - Qirn Jump SC*: Broken Bridge NC* - Qirn Jump SE*: Broken Bridge NE* - Potion Shop EN*: Zora Approach WN* - Potion Shop EC*: Zora Approach WC* - Dark Witch EN*: Catfish Approach WN* - Dark Witch EC*: Catfish Approach WC* - Wooden Bridge SW*: Sand Dunes NW* - Broken Bridge SW*: Dark Dunes NW* - Sand Dunes SC*: Stone Bridge NC* - Dark Dunes SC*: Hammer Bridge NC* - Maze Race ES*: Kakariko Suburb WS* - Dig Game EC: Frog WC - Dig Game ES*: Frog WS* - Kakariko Suburb ES*: Flute Boy WS* - Frog ES*: Stumpy WS* - Flute Boy SW*: Flute Boy Approach NW* - Flute Boy SC*: Flute Boy Approach NC* - Stumpy SW*: Stumpy Approach NW* - Stumpy SC*: Stumpy Approach NC* - Central Bonk Rocks EN*: Links House WN* - Central Bonk Rocks EC*: Links House WC* - Central Bonk Rocks ES*: Links House WS* - Central Bonk Rocks SW*: C Whirlpool NW* - Dark Bonk Rocks EN*: Big Bomb Shop WN* - Dark Bonk Rocks EC*: Big Bomb Shop WC* - Dark Bonk Rocks ES*: Big Bomb Shop WS* - Dark Bonk Rocks SW*: Dark C Whirlpool NW* - Links House SC*: Statues NC* - Links House ES*: Stone Bridge WS* - Big Bomb Shop SC*: Hype Cave NC* - Big Bomb Shop ES*: Hammer Bridge WS* - Stone Bridge WC: Hobo EC - Stone Bridge EN*: Tree Line WN* - Stone Bridge EC*: Tree Line WC* - Hammer Bridge EN*: Dark Tree Line WN* - Hammer Bridge EC*: Dark Tree Line WC* - Flute Boy Approach EC*: C Whirlpool WC* - Stumpy Approach EC*: Dark C Whirlpool WC* - C Whirlpool EN*: Statues WN* - C Whirlpool EC*: Statues WC* - C Whirlpool ES*: Statues WS* - C Whirlpool SC*: Dam NC* - Dark C Whirlpool EN*: Hype Cave WN* - Dark C Whirlpool EC*: Hype Cave WC* - Dark C Whirlpool ES*: Hype Cave WS* - Dark C Whirlpool SC*: Swamp NC* - Statues SC*: South Pass NC* - Hype Cave SC*: Dark South Pass NC* - Ice Cave SW*: Octoballoon NW* - Ice Cave SE*: Octoballoon NE* - Shopping Mall SW*: Bomber Corner NW* - Shopping Mall SE*: Bomber Corner NE* - Desert Pass EC*: Dam WC* - Desert Pass ES*: Dam WS* - Swamp Nook EC*: Swamp WC* - Swamp Nook ES*: Swamp WS* - Dam EC*: South Pass WC* - Swamp EC*: Dark South Pass WC* + South Pass ES*: Lake Hylia WS* + Dark South Pass ES*: Ice Lake WS* ow-whirlpools: 1: two-way: diff --git a/resources/app/cli/args.json b/resources/app/cli/args.json index 26a2c49d..e792268d 100644 --- a/resources/app/cli/args.json +++ b/resources/app/cli/args.json @@ -522,6 +522,7 @@ ] }, "sprite": {}, + "triforce_gfx": {}, "create_rom": { "action": "store_false", "type": "bool" @@ -688,5 +689,6 @@ }, "outputname": {}, "notes": {}, - "code": {} + "code": {}, + "rom_header" : {} } diff --git a/resources/app/gui/lang/en.json b/resources/app/gui/lang/en.json index 8632601f..0ad57757 100644 --- a/resources/app/gui/lang/en.json +++ b/resources/app/gui/lang/en.json @@ -42,6 +42,8 @@ "adjust.sprite": "Sprite:", "adjust.sprite.unchanged": "(unchanged)", + "adjust.triforcegfx": "Triforce Piece:", + "adjust.triforcegfx.unchanged": "(unchanged)", "adjust.rom": "Rom to adjust: ", "adjust.rom.romfiles": "Rom Files", @@ -259,7 +261,8 @@ "randomizer.gameoptions.sprite": "Sprite:", "randomizer.gameoptions.sprite.unchanged": "(unchanged)", - + "randomizer.gameoptions.triforcegfx": "Triforce Piece:", + "randomizer.gameoptions.triforcegfx.unchanged": "(unchanged)", "randomizer.generation.bps": "Create BPS Patches", "randomizer.generation.spoiler": "Create Spoiler Log", diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index 0b421fca..7a3f3712 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -208,6 +208,7 @@ class CustomSettings(object): # rom adjust stuff args.sprite[p] = get_setting(settings['sprite'], args.sprite[p]) + args.triforce_gfx[p] = get_setting(settings['triforce_gfx'], args.triforce_gfx[p]) args.disablemusic[p] = get_setting(settings['disablemusic'], args.disablemusic[p]) args.quickswap[p] = get_setting(settings['quickswap'], args.quickswap[p]) args.reduce_flashing[p] = get_setting(settings['reduce_flashing'], args.reduce_flashing[p]) @@ -221,6 +222,14 @@ class CustomSettings(object): args.shuffle_songinstruments[p] = get_setting(settings['shuffle_songinstruments'], args.shuffle_songinstruments[p]) args.msu_resume[p] = get_setting(settings['msu_resume'], args.msu_resume[p]) + def has_setting(self, player, setting): + if 'settings' in self.file_source and player in self.file_source['settings']: + return setting in self.file_source['settings'][player] + return False + + def get_setting(self, player, setting): + return self.file_source['settings'][player][setting] + def get_item_pool(self): if 'item_pool' in self.file_source: return self.file_source['item_pool'] @@ -299,9 +308,9 @@ class CustomSettings(object): return self.file_source['enemies'] return None - def get_gtentry(self): - if 'gt_entry' in self.file_source: - return self.file_source['gt_entry'] + def get_goals(self): + if 'goals' in self.file_source: + return self.file_source['goals'] return None @@ -577,9 +586,13 @@ class CustomSettings(object): def load_yaml(path): - if os.path.exists(Path(path)): - with open(path, "r", encoding="utf-8") as f: - return yaml.load(f, Loader=yaml.SafeLoader) - elif urllib.parse.urlparse(path).scheme in ['http', 'https']: - return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) + try: + if os.path.exists(Path(path)): + with open(path, "r", encoding="utf-8") as f: + return yaml.load(f, Loader=yaml.SafeLoader) + elif urllib.parse.urlparse(path).scheme in ['http', 'https']: + return yaml.load(urllib.request.urlopen(path), Loader=yaml.FullLoader) + except yaml.YAMLError as e: + error_msg = f"Error parsing YAML file '{path}':\n{str(e)}" + raise ValueError(error_msg) from e diff --git a/source/classes/ItemGfxSelector.py b/source/classes/ItemGfxSelector.py new file mode 100644 index 00000000..ee5d528d --- /dev/null +++ b/source/classes/ItemGfxSelector.py @@ -0,0 +1,130 @@ +from tkinter import Button, Canvas, Label, LabelFrame, Frame, PhotoImage, Scrollbar, Toplevel, LEFT, BOTTOM, X, RIGHT, TOP +import os +from GuiUtils import ToolTips, set_icon +from Utils import local_path + + +class ItemGfxSelector(object): + def __init__(self, parent, callback, valid_items=None, adjuster=False): + self.parent = parent + self.window = Toplevel(parent) + self.window.geometry("800x650") + self.callback = callback + self.valid_items = valid_items if valid_items else [] + self.adjuster = adjuster + + self.window.wm_title("Select Triforce Piece Graphics") + self.window['padx'] = 5 + self.window['pady'] = 5 + + def open_itemgfx_dir(_evt): + from Utils import open_file + itemgfx_dir = local_path(os.path.join("data", "itemgfx")) + if not os.path.isdir(itemgfx_dir): + os.makedirs(itemgfx_dir) + open_file(itemgfx_dir) + + frametitle = Frame(self.window) + title_text = Label(frametitle, text="Item Graphics") + title_text.pack(side=LEFT) + local_title_link = Label(frametitle, text="(open folder)", fg="blue", cursor="hand2") + local_title_link.pack(side=LEFT) + local_title_link.bind("", open_itemgfx_dir) + + self.icon_section(frametitle) + + frame = Frame(self.window) + frame.pack(side=BOTTOM, fill=X, pady=5) + + button = Button(frame, text="Default (Triforce)", command=self.use_default) + button.pack(side=LEFT, padx=(0, 5)) + + if adjuster: + button = Button(frame, text="Current triforce from rom", command=self.use_default_unchanged) + button.pack(side=LEFT, padx=(0, 5)) + + set_icon(self.window) + self.window.focus() + + def icon_section(self, frame_label): + frame = LabelFrame(self.window, labelwidget=frame_label, padx=5, pady=5) + canvas = Canvas(frame, borderwidth=0, width=780) + y_scrollbar = Scrollbar(frame, orient="vertical", command=canvas.yview) + y_scrollbar.pack(side="right", fill="y") + content_frame = Frame(canvas) + canvas.pack(side="left", fill="both", expand=True) + canvas.create_window((4, 4), window=content_frame, anchor="nw") + canvas.configure(yscrollcommand=y_scrollbar.set) + + def onFrameConfigure(canvas): + """Reset the scroll region to encompass the inner frame""" + canvas.configure(scrollregion=canvas.bbox("all")) + + content_frame.bind("", lambda event, canvas=canvas: onFrameConfigure(canvas)) + frame.pack(side=TOP, fill="both", expand=True) + + itemgfx_dir = local_path(os.path.join("data", "itemgfx")) + + if not os.path.exists(itemgfx_dir): + label = Label(content_frame, text='No item graphics found in data/itemgfx folder.') + label.pack() + return + + # Get all GIF files (converted from PNG) + gif_files = [] + for file in os.listdir(itemgfx_dir): + if file.lower().endswith('.gif'): + item_name = os.path.splitext(file)[0] + # Only include if it's in the valid_items list + if item_name in self.valid_items: + gif_files.append((file, item_name)) + + # Sort by name + gif_files.sort(key=lambda x: str.lower(x[1])) + + if len(gif_files) == 0: + label = Label(content_frame, text='No valid item graphics found. Items must match names from Tables.py.') + label.pack() + return + + # Calculate how many columns can fit (assuming ~40px per icon with padding) + max_columns = 18 + + i = 0 + for filename, item_name in gif_files: + filepath = os.path.join(itemgfx_dir, filename) + image = self.get_image_for_item(filepath) + if image is None: + continue + + button = Button(content_frame, image=image, command=lambda name=item_name: self.select_item(name)) + ToolTips.register(button, item_name) + button.image = image + button.grid(row=i // max_columns, column=i % max_columns, padx=2, pady=2) + i += 1 + + if i == 0: + label = Label(content_frame, text='No valid item graphics could be loaded.') + label.pack() + + def get_image_for_item(self, filepath): + """Load and prepare an item graphic for display""" + try: + # Load GIF with native Tkinter PhotoImage (no PIL required) + photo = PhotoImage(file=filepath) + return photo + except Exception as e: + print(f"Error loading image {filepath}: {e}") + return None + + def use_default(self): + self.callback("Triforce") + self.window.destroy() + + def use_default_unchanged(self): + self.callback(None) + self.window.destroy() + + def select_item(self, item_name): + self.callback(item_name) + self.window.destroy() diff --git a/source/dungeon/DungeonStitcher.py b/source/dungeon/DungeonStitcher.py index 29a2c32f..d7ce3c4f 100644 --- a/source/dungeon/DungeonStitcher.py +++ b/source/dungeon/DungeonStitcher.py @@ -333,13 +333,13 @@ def determine_paths_for_dungeon(world, player, all_regions, name): if portal.destination: paths.append(portal.door.entrance.parent_region.name) if world.mode[player] == 'standard' and name == 'Hyrule Castle Dungeon': - paths.append('Hyrule Dungeon Cellblock') - paths.append(('Hyrule Dungeon Cellblock', 'Hyrule Castle Throne Room')) + paths.append(world.default_zelda_region[player]) + paths.append((world.default_zelda_region[player], 'Hyrule Castle Throne Room')) entrance = next(x for x in world.dungeon_portals[player] if x.name == 'Hyrule Castle South') # todo: in non-er, we can use the other portals too - paths.append(('Hyrule Dungeon Cellblock', entrance.door.entrance.parent_region.name)) + paths.append((world.default_zelda_region[player], entrance.door.entrance.parent_region.name)) paths.append(('Hyrule Castle Throne Room', [entrance.door.entrance.parent_region.name, - 'Hyrule Dungeon Cellblock'])) + world.default_zelda_region[player]])) if world.doorShuffle[player] in ['basic'] and name == 'Thieves Town': paths.append('Thieves Attic Window') elif 'Thieves Attic Window' in all_r_names: diff --git a/source/enemizer/Enemizer.py b/source/enemizer/Enemizer.py index 492966d8..796d1211 100644 --- a/source/enemizer/Enemizer.py +++ b/source/enemizer/Enemizer.py @@ -1,4 +1,5 @@ import RaceRandom as random +from collections import defaultdict from Utils import snes_to_pc from source.dungeon.EnemyList import SpriteType, EnemySprite, sprite_translation @@ -446,13 +447,16 @@ def randomize_enemies(world, player): set_mimics(data_tables) elif world.enemy_shuffle[player] != 'none': data_tables = world.data_tables[player] - custom_ow, custom_uw = {}, {} - enemy_map = world.customizer.get_enemies() if world.customizer else None - if enemy_map and player in enemy_map: - if 'Underworld' in enemy_map[player]: - custom_uw = enemy_map[player]['Underworld'] - if 'Overworld' in enemy_map[player]: - custom_ow = enemy_map[player]['Overworld'] + if world.force_enemy[player]: + custom_ow = {area_id: {i: world.force_enemy[player] for i, s in enumerate(sprite_list)} for area_id, sprite_list in world.data_tables[player].ow_enemy_table.items()} + custom_uw = {room_id: {i: world.force_enemy[player] for i, s in enumerate(sprite_list)} for room_id, sprite_list in world.data_tables[player].uw_enemy_table.room_map.items()} + else: + enemy_map = world.customizer.get_enemies() if world.customizer else None + if enemy_map and player in enemy_map: + if 'Underworld' in enemy_map[player]: + custom_uw = enemy_map[player]['Underworld'] + if 'Overworld' in enemy_map[player]: + custom_ow = enemy_map[player]['Overworld'] randomize_underworld_sprite_sheets(data_tables.sprite_sheets, data_tables, custom_uw) randomize_underworld_rooms(data_tables, world, player, custom_uw) randomize_overworld_sprite_sheets(data_tables.sprite_sheets, data_tables, custom_ow) @@ -525,6 +529,21 @@ def randomize_enemies(world, player): green_mail, blue_mail, red_mail = original_table[idx] del original_table[idx] world.data_tables[player].enemy_damage[i] = [green_mail, blue_mail, red_mail] + # determine default zelda follower location + if world.mode[player] == 'standard' and world.doorShuffle[player] == 'crossed' and world.shuffle_followers[player]: + def random_zelda(): + world.default_zelda_region[player] = random.choice(['Hyrule Dungeon Cellblock', 'Thieves Blind\'s Cell']) + if world.customizer: + placements = world.customizer.get_placements() + if placements and player in placements and 'Zelda Herself' in placements[player].values(): + location = [l for (l, item) in placements[player].items() if item == 'Zelda Herself'][0] + if location == 'Suspicious Maiden': + world.default_zelda_region[player] = 'Thieves Blind\'s Cell' + else: + random_zelda() + else: + random_zelda() + def write_enemy_shuffle_settings(world, player, rom): diff --git a/source/enemizer/SpriteSheets.py b/source/enemizer/SpriteSheets.py index 0d1302fe..f558eb7d 100644 --- a/source/enemizer/SpriteSheets.py +++ b/source/enemizer/SpriteSheets.py @@ -363,7 +363,7 @@ def init_sprite_requirements(): SpriteRequirement(EnemySprite.TrinexxFireHead).exalt().sub_group(0, 0x40).sub_group(3, 0x3f), SpriteRequirement(EnemySprite.TrinexxIceHead).exalt().sub_group(0, 0x40).sub_group(3, 0x3f), SpriteRequirement(EnemySprite.Blind).exalt().sub_group(1, 0x2c).sub_group(2, 0x3b), - SpriteRequirement(EnemySprite.Swamola).no_drop().sub_group(3, 0x19), + SpriteRequirement(EnemySprite.Swamola).skip().no_drop().sub_group(3, 0x19), SpriteRequirement(EnemySprite.Lynel).sub_group(3, 0x14), SpriteRequirement(EnemySprite.BunnyBeam).no_drop().ow_skip(), SpriteRequirement(EnemySprite.FloppingFish).uw_skip().immune(), @@ -683,9 +683,11 @@ def setup_custom_enemy_sheets(custom_enemies, sheets, data_tables, sheet_range, if key not in requirements: continue req = requirements[key] - if isinstance(req, dict): + if isinstance(req, dict) and room_id in req: req = req[room_id] - if req.static or not req.can_randomize: + else: + req = None + if req and (req.static or not req.can_randomize): try: combine_req(sub_groups_choices, req) except IncompatibleEnemyException: diff --git a/source/enemizer/enemy_deny.yaml b/source/enemizer/enemy_deny.yaml index 3bc8fc3b..56aca46d 100644 --- a/source/enemizer/enemy_deny.yaml +++ b/source/enemizer/enemy_deny.yaml @@ -84,7 +84,7 @@ UwGeneralDeny: - [ 0x0039, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 1" - [0x0039, 5, ["RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "Bumper", "AntiFairyCircle"]] #"Skull Woods - Play Pen - Hardhat Beetle" - [ 0x0039, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "FirebarCW", "FirebarCCW" ] ] #"Skull Woods - Play Pen - Spike Trap 2" - - [0x003a, 1, ["RollerVerticalUp"]] + - [0x003a, 1, ["RollerVerticalUp", "RollerVerticalDown"]] - [ 0x003b, 1, [ "Bumper", "AntiFairyCircle" ]] - [ 0x003b, 4, ["RollerVerticalUp", "RollerVerticalDown"]] - [ 0x003c, 0, ["BigSpike"]] @@ -339,7 +339,11 @@ UwGeneralDeny: - [ 0x00c2, 5, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots - [ 0x00c5, 6, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Turtle Rock - Catwalk - Mini Helmasaur" - [ 0x00c5, 7, [ "Statue" ] ] #"Turtle Rock - Catwalk - Laser Eye (Left) 4" + - [0x00c6, 2, ["Bumper", "AntiFairyCircle"]] + - [0x00c6, 3, ["Bumper", "AntiFairyCircle"]] + - [0x00c6, 4, ["Bumper", "AntiFairyCircle"]] - [0x00c6, 5, ["Bumper", "AntiFairyCircle"]] + - [0x00c6, 6, ["Bumper", "AntiFairyCircle"]] - [ 0x00cb, 0, [ "Wizzrobe", "Statue" ] ] # Wizzrobes can't spawn on pots - [ 0x00cb, 3, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 1" - [ 0x00cb, 5, [ "RollerVerticalUp", "RollerVerticalDown", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Grand Room NW - Zol 2" @@ -397,6 +401,7 @@ UwGeneralDeny: - [ 0x00e4, 2, [ "RollerHorizontalLeft", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home - Keese 3" - [ 0x00e5, 4, [ "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home Circle - Keese 5" - [ 0x00e5, 5, [ "RollerVerticalDown", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Old Man Home Circle - Keese 6" + - [0x00e6, 0, ["Statue"]] # Death Mountain Descent Cave Left - Keese 1 - Statue blocking pot access - [ 0x00e7, 0, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Death Mountain Descent Cave Right - Keese 1" - [ 0x00e7, 1, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Death Mountain Descent Cave Right - Keese 2" - [ 0x00e7, 2, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Death Mountain Descent Cave Right - Keese 3" @@ -441,7 +446,7 @@ OwGeneralDeny: - [0x05, 10, ["Bumper", "AntiFairyCircle"]] # Blocks path - [0x05, 11, ["Bumper", "AntiFairyCircle"]] # Blocks path to portal - [0x07, 3, ["Bumper", "AntiFairyCircle", "RollerHorizontalRight", "RollerHorizontalLeft"]] # Blocks path to ladder - - [0x07, 4, ["RollerHorizontalLeft"]] # Blocks path to ladder + - [0x07, 4, ["Bumper", "AntiFairyCircle", "RollerHorizontalLeft"]] # Blocks path to ladder - [0x1e, 3, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle"]] # forbid a beamos here - [0x35, 8, ["RollerVerticalUp", "RollerVerticalDown"]] # blocks the dock - [0x37, 5, ["RollerVerticalUp"]] # combines with a roller above to make the way impassable @@ -450,7 +455,7 @@ OwGeneralDeny: - [0x40, 13, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]] - [0x40, 14, ["Beamos", "Bumper", "BigSpike", "AntiFairyCircle", "Thief"]] - [0x40, 16, ["RollerVerticalUp", "RollerVerticalDown"]] # Ropa near back hole is really large as a roller - - [0x55, 6, ["BigSpike"]] + - [0x55, 6, ["BigSpike", "Bumper", "AntiFairyCircle"]] - [0x57, 5, ["RollerVerticalUp", "RollerVerticalDown"]] - [0x5b, 0, ["AntiFairyCircle", "Bumper"]] # ropa on pyramid - [0x5e, 0, ["Gibo"]] # kiki eating Gibo @@ -480,6 +485,7 @@ OwGeneralDeny: - [0x77, 1, ["Bumper", "AntiFairyCircle"]] # soft-lock potential near ladder - [0x7f, 1, ["Bumper", "AntiFairyCircle"]] # soft-lock potential near ladder UwEnemyDrop: + - [0x0015, 8, ["Zoro"]] # layer issues - [0x0085, 9, ["Babasu"]] # ran off the edge and didn't return - [0x00cb, 3, ["Zoro"]] # layer issues - [0x00cb, 5, ["Zoro"]] # layer issues diff --git a/source/gui/adjust/overview.py b/source/gui/adjust/overview.py index a26bd750..2d062c8a 100644 --- a/source/gui/adjust/overview.py +++ b/source/gui/adjust/overview.py @@ -2,6 +2,7 @@ from tkinter import ttk, filedialog, messagebox, StringVar, Button, Entry, Frame from AdjusterMain import adjust, patch from argparse import Namespace from source.classes.SpriteSelector import SpriteSelector +from source.classes.ItemGfxSelector import ItemGfxSelector import source.gui.widgets as widgets import json import logging @@ -71,6 +72,30 @@ def adjust_page(top, parent, settings): spriteSelectButton2.pack(side=LEFT) spriteDialogFrame2.pack(anchor=E) + # Triforce Piece GFX Selection + self.triforceGfxNameVar = StringVar() + self.triforceGfxNameVar.set('(unchanged)') + triforceGfxDialogFrame = Frame(self.frames["leftAdjustFrame"]) + triforceGfxLabel = Label(triforceGfxDialogFrame, text='Triforce Piece:') + triforceGfxEntry = Label(triforceGfxDialogFrame, textvariable=self.triforceGfxNameVar) + self.triforce_gfx = None + + def set_triforce_gfx(item_name): + self.triforce_gfx = item_name + self.triforceGfxNameVar.set(item_name if item_name else '(unchanged)') + + def TriforceGfxSelectAdjuster(): + from Tables import item_gfx_table + valid_items = list(item_gfx_table.keys()) + ItemGfxSelector(parent, set_triforce_gfx, valid_items=valid_items, adjuster=True) + + triforceGfxSelectButton = Button(triforceGfxDialogFrame, text='...', command=TriforceGfxSelectAdjuster) + + triforceGfxLabel.pack(side=LEFT) + triforceGfxEntry.pack(side=LEFT) + triforceGfxSelectButton.pack(side=LEFT) + triforceGfxDialogFrame.pack(anchor=E) + # Path to game file to Adjust # This one's more-complicated, build it and stuff it adjustRomFrame = Frame(self.frames["bottomAdjustFrame"]) @@ -117,6 +142,7 @@ def adjust_page(top, parent, settings): guiargs.rom = self.romVar2.get() guiargs.baserom = top.pages["randomizer"].pages["generation"].widgets["rom"].storageVar.get() guiargs.sprite = self.sprite + guiargs.triforce_gfx = self.triforce_gfx guiargs.outputpath = os.path.dirname(guiargs.rom) try: adjust(args=guiargs) @@ -171,6 +197,7 @@ def adjust_page(top, parent, settings): guiargs.patch = self.patchVar.get() guiargs.baserom = top.pages["randomizer"].pages["generation"].widgets["rom"].storageVar.get() guiargs.sprite = self.sprite + guiargs.triforce_gfx = self.triforce_gfx guiargs.outputpath = os.path.dirname(guiargs.patch) try: patch(args=guiargs) diff --git a/source/gui/bottom.py b/source/gui/bottom.py index 7faf3402..35b6c516 100644 --- a/source/gui/bottom.py +++ b/source/gui/bottom.py @@ -77,32 +77,37 @@ def bottom_frame(self, parent, args=None): argsDump['sprite'] = argsDump['sprite'].name save_settings(parent, argsDump, "last.json") - guiargs = create_guiargs(parent) - # get default values for missing parameters - cliargs = ['--multi', str(guiargs.multi)] - if hasattr(guiargs, 'customizer'): - cliargs.extend(['--customizer', str(guiargs.customizer)]) - for k,v in vars(parse_cli(cliargs)).items(): - if k not in vars(guiargs): - setattr(guiargs, k, v) - elif type(v) is dict: # use same settings for every player - players = guiargs.multi if len(v) == 0 else len(v) - setattr(guiargs, k, {player: getattr(guiargs, k) for player in range(1, players + 1)}) - argsDump = vars(guiargs) - - needEnemizer = False - falsey = ["none", "default", False, 0] - for enemizerOption in ["shuffleenemies", "enemy_damage", "shufflebosses", "enemy_health"]: - if enemizerOption in argsDump: - if isinstance(argsDump[enemizerOption], dict): - for playerID,playerSetting in argsDump[enemizerOption].items(): - if not playerSetting in falsey: - needEnemizer = True - elif not argsDump[enemizerOption] in falsey: - needEnemizer = True - seeds = [] - try: + guiargs = create_guiargs(parent) + # get default values for missing parameters + cliargs = ['--multi', str(guiargs.multi)] + if hasattr(guiargs, 'customizer'): + cliargs.extend(['--customizer', str(guiargs.customizer)]) + + for k,v in vars(parse_cli(cliargs)).items(): + if k not in vars(guiargs): + setattr(guiargs, k, v) + elif type(v) is dict: # use same settings for every player + players = guiargs.multi if len(v) == 0 else len(v) + setattr(guiargs, k, {player: getattr(guiargs, k) for player in range(1, players + 1)}) + if guiargs.multi == 1 and guiargs.names.endswith("=="): + # allow settings code thru player names entry + guiargs.code[1] = guiargs.names + guiargs.names = "" + argsDump = vars(guiargs) + + needEnemizer = False + falsey = ["none", "default", False, 0] + for enemizerOption in ["shuffleenemies", "enemy_damage", "shufflebosses", "enemy_health"]: + if enemizerOption in argsDump: + if isinstance(argsDump[enemizerOption], dict): + for playerID,playerSetting in argsDump[enemizerOption].items(): + if not playerSetting in falsey: + needEnemizer = True + elif not argsDump[enemizerOption] in falsey: + needEnemizer = True + seeds = [] + if guiargs.count is not None and guiargs.seed: seed = guiargs.seed for _ in range(guiargs.count): @@ -340,6 +345,9 @@ def create_guiargs(parent): guiargs.sprite = parent.pages["randomizer"].pages["gameoptions"].widgets["sprite"]["spriteObject"] guiargs.randomSprite = parent.randomSprite.get() + # Get Triforce Piece GFX Selection + guiargs.triforce_gfx = parent.pages["randomizer"].pages["gameoptions"].widgets["triforce_gfx"]["selectedItem"] + # Get output path guiargs.outputpath = parent.settings["outputpath"] diff --git a/source/gui/loadcliargs.py b/source/gui/loadcliargs.py index 9230fe59..6ca7ad60 100644 --- a/source/gui/loadcliargs.py +++ b/source/gui/loadcliargs.py @@ -197,6 +197,13 @@ def loadcliargs(gui, args, settings=None): spriteNameVar=gui.pages["adjust"].content.spriteNameVar2, randomSpriteVar=gui.randomSprite) + # Figure out Triforce GFX Selection + if "triforce_gfx" in args and args["triforce_gfx"] is not None: + gui.pages["randomizer"].pages["gameoptions"].widgets["triforce_gfx"]["selectedItem"] = args["triforce_gfx"] + gui.pages["randomizer"].pages["gameoptions"].widgets["triforce_gfx"]["itemNameVar"].set(args["triforce_gfx"]) + gui.pages["adjust"].content.triforce_gfx = args["triforce_gfx"] + gui.pages["adjust"].content.triforceGfxNameVar.set(args["triforce_gfx"]) + # Load args/settings for Adjust tab def loadadjustargs(gui, settings): options = { diff --git a/source/gui/randomize/gameoptions.py b/source/gui/randomize/gameoptions.py index ac9bdc22..5f3dfddf 100644 --- a/source/gui/randomize/gameoptions.py +++ b/source/gui/randomize/gameoptions.py @@ -1,6 +1,7 @@ from tkinter import ttk, StringVar, Button, Entry, Frame, Label, NE, NW, E, W, LEFT, RIGHT from functools import partial import source.classes.SpriteSelector as spriteSelector +import source.classes.ItemGfxSelector as itemGfxSelector import source.gui.widgets as widgets import json import os @@ -66,6 +67,34 @@ def gameoptions_page(top, parent): spriteSelectButton.pack(side=LEFT) spriteDialogFrame.pack(anchor=E) + ## Triforce Piece graphics selection + triforcegfxDialogFrame = Frame(self.frames["leftRomOptionsFrame"]) + triforceGfxLabel = Label(triforcegfxDialogFrame, text='Triforce Piece:') + + self.widgets["triforce_gfx"] = {} + self.widgets["triforce_gfx"]["selectedItem"] = None + self.widgets["triforce_gfx"]["itemNameVar"] = StringVar() + self.widgets["triforce_gfx"]["itemNameVar"].set('Triforce') + + triforceGfxEntry = Label(triforcegfxDialogFrame, textvariable=self.widgets["triforce_gfx"]["itemNameVar"]) + + def triforce_gfx_setter(item_name): + self.widgets["triforce_gfx"]["selectedItem"] = item_name + self.widgets["triforce_gfx"]["itemNameVar"].set(item_name) + + def triforce_gfx_select(): + # Import Tables to get valid item names + from Tables import item_gfx_table + valid_items = list(item_gfx_table.keys()) + itemGfxSelector.ItemGfxSelector(parent, triforce_gfx_setter, valid_items=valid_items) + + triforceGfxSelectButton = Button(triforcegfxDialogFrame, text='...', command=triforce_gfx_select) + + triforceGfxLabel.pack(side=LEFT) + triforceGfxEntry.pack(side=LEFT) + triforceGfxSelectButton.pack(side=LEFT) + triforcegfxDialogFrame.pack(anchor=E) + return self diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index c190c428..8ef10110 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -403,6 +403,7 @@ def do_old_man_cave_exit(entrances, exits, avail, cross_world): else: region_name = 'West Dark Death Mountain (Top)' om_cave_options = list(get_accessible_entrances(region_name, avail, [], cross_world, True, True, True, True)) + om_cave_options = [e for e in om_cave_options if e in avail.entrances] if avail.swapped: om_cave_options = [e for e in om_cave_options if e not in Forbidden_Swap_Entrances] assert len(om_cave_options), 'No available entrances left to place Old Man Cave' @@ -643,7 +644,6 @@ def do_dark_sanc(entrances, exits, avail): entrances.remove(choice) exits.remove('Dark Sanctuary Hint') connect_entrance(choice, 'Dark Sanctuary Hint', avail) - ext.connect(avail.world.get_entrance(choice, avail.player).parent_region) if not avail.coupled: avail.decoupled_entrances.remove(choice) if avail.swapped and choice != 'Dark Sanctuary Hint': @@ -651,8 +651,7 @@ def do_dark_sanc(entrances, exits, avail): entrances.remove(swap_ent) exits.remove(swap_ext) elif not ext.connected_region: - # default to output to vanilla area, assume vanilla connection - ext.connect(avail.world.get_region('Dark Chapel Area', avail.player)) + raise Exception('Dark Sanctuary Hint was placed earlier but its exit not properly connected') def do_links_house(entrances, exits, avail, cross_world): @@ -722,8 +721,6 @@ def do_links_house(entrances, exits, avail, cross_world): connect_two_way(links_house, lh_exit, avail) else: connect_entrance(links_house, lh_exit, avail) - ext = avail.world.get_entrance('Big Bomb Shop Exit', avail.player) - ext.connect(avail.world.get_entrance(links_house, avail.player).parent_region) entrances.remove(links_house) exits.remove(lh_exit) if not avail.coupled: @@ -867,7 +864,7 @@ def get_accessible_entrances(start_region, avail, assumed_inventory=[], cross_wo for p in range(1, avail.world.players + 1): avail.world.key_logic[p] = {} - base_world = copy_world_premature(avail.world, avail.player) + base_world = copy_world_premature(avail.world, avail.player, create_flute_exits=True) base_world.override_bomb_check = True connect_simple(base_world, 'Links House S&Q', start_region, avail.player) @@ -1907,6 +1904,12 @@ def connect_entrance(entrancename, exit_name, avail): avail.entrances.remove(entrancename) if avail.coupled: avail.exits.remove(exit_name) + if exit_name == 'Big Bomb Shop' and avail.world.is_bombshop_start(avail.player): + ext = avail.world.get_entrance('Big Bomb Shop Exit', avail.player) + ext.connect(avail.world.get_entrance(entrancename, avail.player).parent_region) + if exit_name == 'Dark Sanctuary Hint' and avail.world.is_dark_chapel_start(avail.player): + ext = avail.world.get_entrance('Dark Sanctuary Hint Exit', avail.player) + ext.connect(avail.world.get_entrance(entrancename, avail.player).parent_region) world.spoiler.set_entrance(entrance.name, exit.name if exit is not None else region.name, 'entrance', player) logging.getLogger('').debug(f'Connected (entr) {entrance.name} to {exit.name if exit is not None else region.name}') diff --git a/source/tools/MysteryUtils.py b/source/tools/MysteryUtils.py index c7d811e3..ac130d8b 100644 --- a/source/tools/MysteryUtils.py +++ b/source/tools/MysteryUtils.py @@ -261,6 +261,7 @@ def roll_settings(weights): if 'rom' in weights: romweights = weights['rom'] ret.sprite = get_choice('sprite', romweights) + ret.triforce_gfx = get_choice('triforce_gfx', romweights) ret.disablemusic = get_choice_bool('disablemusic', romweights) ret.quickswap = get_choice_bool('quickswap', romweights) ret.reduce_flashing = get_choice_bool('reduce_flashing', romweights)