From ee8feaed550e12bee525949d0645bc815ba1f899 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 26 Jan 2020 14:15:43 +1100 Subject: [PATCH 01/11] Fix skull woods exit: - Remove from list of unreachable exits (Moth may be in a different section) - Fix vanilla check to account for multiworld --- BaseClasses.py | 2 +- Rom.py | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 65c07066..7035b2ac 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -83,7 +83,7 @@ class World(object): set_player_attr('ganonstower_vanilla', True) set_player_attr('sewer_light_cone', self.mode[player] == 'standard') set_player_attr('fix_trock_doors', self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted') - set_player_attr('fix_skullwoods_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) + set_player_attr('fix_skullwoods_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple'] or self.doorShuffle[player] not in ['vanilla']) set_player_attr('fix_palaceofdarkness_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) set_player_attr('fix_trock_exit', self.shuffle[player] not in ['vanilla', 'simple', 'restricted', 'dungeonssimple']) set_player_attr('can_access_trock_eyebridge', None) diff --git a/Rom.py b/Rom.py index 8de2d0ec..60bbee3f 100644 --- a/Rom.py +++ b/Rom.py @@ -557,7 +557,7 @@ def patch_rom(world, rom, player, team, enemized): # todo fix screen scrolling if world.shuffle[player] not in ['insanity', 'insanity_legacy', 'madness_legacy'] and \ - exit.name in ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Skull Woods Final Section Exit', 'Ice Palace Exit', 'Misery Mire Exit', + exit.name in ['Eastern Palace Exit', 'Tower of Hera Exit', 'Thieves Town Exit', 'Ice Palace Exit', 'Misery Mire Exit', 'Palace of Darkness Exit', 'Swamp Palace Exit', 'Ganons Tower Exit', 'Desert Palace Exit (North)', 'Agahnims Tower Exit', 'Spiral Cave Exit (Top)', 'Superbunny Cave Exit (Bottom)', 'Turtle Rock Ledge Exit (East)']: # For exits that connot be reached from another, no need to apply offset fixes. @@ -608,16 +608,10 @@ def patch_rom(world, rom, player, team, enemized): for paired_door in world.paired_doors[player]: rom.write_bytes(paired_door.address_a(world, player), paired_door.rom_data_a(world, player)) rom.write_bytes(paired_door.address_b(world, player), paired_door.rom_data_b(world, player)) - if world.fix_skullwoods_exit and world.shuffle in ['vanilla', 'simple', 'restricted', 'dungeonssimple']: - connect = world.get_entrance('Skull Woods Final Section', player).connected_region - exit_name = None - for ext in connect.exits: - if ext.connected_region.name == 'Skull Woods Forest (West)': - exit_name = ext.name - break - if exit_name is not None and exit_name == 'Skull Woods Final Section Exit': - rom.write_int16(0x15DB5 + 2 * exit_ids['Skull Woods Final Section Exit'][1], 0x00F8) - # todo: fix other exits if ER enabled and similar situation happens + + # fix skull woods exit, if not fixed during exit patching + if world.fix_skullwoods_exit[player] and world.shuffle[player] == 'vanilla': + write_int16(rom, 0x15DB5 + 2 * exit_ids['Skull Woods Final Section Exit'][1], 0x00F8) write_custom_shops(rom, world, player) From a370b34aca573ac78ffa0c2adbb992fa85e4a680 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 26 Jan 2020 15:29:14 +1100 Subject: [PATCH 02/11] Turn off vanilla TR key logic checks when TR can be entered from back - will need to be based on which entrances are available and how the inaccessible entrances link --- KeyDoorShuffle.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index 8e89ec26..e27e8af8 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -1146,20 +1146,22 @@ def val_mire(key_logic, world, player): def val_turtle(key_logic, world, player): - val_rule(key_logic.door_rules['TR Hub NW'], 1) - val_rule(key_logic.door_rules['TR Pokey 1 NW'], 2) - val_rule(key_logic.door_rules['TR Chain Chomps Down Stairs'], 3) - val_rule(key_logic.door_rules['TR Pokey 2 ES'], 6, True, 'Turtle Rock - Big Key Chest', 4, {'Turtle Rock - Big Key Chest'}) - val_rule(key_logic.door_rules['TR Crystaroller Down Stairs'], 5) - val_rule(key_logic.door_rules['TR Dash Bridge WS'], 6) - assert world.get_location('Turtle Rock - Eye Bridge - Bottom Right', player) in key_logic.bk_restricted - assert world.get_location('Turtle Rock - Eye Bridge - Top Left', player) in key_logic.bk_restricted - assert world.get_location('Turtle Rock - Eye Bridge - Top Right', player) in key_logic.bk_restricted - assert world.get_location('Turtle Rock - Eye Bridge - Bottom Left', player) in key_logic.bk_restricted - assert world.get_location('Turtle Rock - Boss', player) in key_logic.bk_restricted - assert world.get_location('Turtle Rock - Crystaroller Room', player) in key_logic.bk_restricted - assert world.get_location('Turtle Rock - Big Chest', player) in key_logic.bk_restricted - assert len(key_logic.bk_restricted) == 7 + # todo: check vanilla key logic when TR back doors are accessible + if world.shuffle[player] == 'vanilla' and world.mode[player] != 'inverted': + val_rule(key_logic.door_rules['TR Hub NW'], 1) + val_rule(key_logic.door_rules['TR Pokey 1 NW'], 2) + val_rule(key_logic.door_rules['TR Chain Chomps Down Stairs'], 3) + val_rule(key_logic.door_rules['TR Pokey 2 ES'], 6, True, 'Turtle Rock - Big Key Chest', 4, {'Turtle Rock - Big Key Chest'}) + val_rule(key_logic.door_rules['TR Crystaroller Down Stairs'], 5) + val_rule(key_logic.door_rules['TR Dash Bridge WS'], 6) + assert world.get_location('Turtle Rock - Eye Bridge - Bottom Right', player) in key_logic.bk_restricted + assert world.get_location('Turtle Rock - Eye Bridge - Top Left', player) in key_logic.bk_restricted + assert world.get_location('Turtle Rock - Eye Bridge - Top Right', player) in key_logic.bk_restricted + assert world.get_location('Turtle Rock - Eye Bridge - Bottom Left', player) in key_logic.bk_restricted + assert world.get_location('Turtle Rock - Boss', player) in key_logic.bk_restricted + assert world.get_location('Turtle Rock - Crystaroller Room', player) in key_logic.bk_restricted + assert world.get_location('Turtle Rock - Big Chest', player) in key_logic.bk_restricted + assert len(key_logic.bk_restricted) == 7 def val_ganons(key_logic, world, player): From 3150e0f16173fe27e04a3ece11158e7f47f9b4bb Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 26 Jan 2020 18:16:00 +1100 Subject: [PATCH 03/11] No-Logic fix - don't try to spread crystal access if the current state is nothing --- BaseClasses.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 7035b2ac..358227f5 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -450,17 +450,17 @@ class CollectionState(object): blocked.add(entrance.parent_region) if color_type: ccr[candidate] = color_type - for ext in candidate.exits: - connect = ext.connected_region - if connect in rrp and connect in ccr: - door = self.world.check_for_door(ext.name, player) - if door is not None and not door.blocked: - if ext.can_reach(self): - new_color = ccr[connect] | (ccr[candidate] & (door.crystal or CrystalBarrier.Either)) - if new_color != ccr[connect]: - self.spread_crystal_access(candidate, new_color, rrp, ccr, player) - else: - blocked.add(candidate) + for ext in candidate.exits: + connect = ext.connected_region + if connect in rrp and connect in ccr: + door = self.world.check_for_door(ext.name, player) + if door is not None and not door.blocked: + if ext.can_reach(self): + new_color = ccr[connect] | (ccr[candidate] & (door.crystal or CrystalBarrier.Either)) + if new_color != ccr[connect]: + self.spread_crystal_access(candidate, new_color, rrp, ccr, player) + else: + blocked.add(candidate) new_regions = len(rrp) > reachable_regions_count reachable_regions_count = len(rrp) From ba6c73861a2e08b1391b1da9f6d4d060c17d09d1 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Sun, 26 Jan 2020 21:46:18 +1100 Subject: [PATCH 04/11] Remove comments in yaml files. Throw a meaningful error if the door-shuffle setting is invalid. --- DoorShuffle.py | 3 +++ Mystery.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/DoorShuffle.py b/DoorShuffle.py index ac81c5e9..c6d17863 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -55,6 +55,9 @@ def link_doors(world, player): cross_dungeon(world, player) elif world.doorShuffle[player] == 'experimental': experiment(world, player) + else: + logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player]) + raise Exception('Invalid door shuffle setting: %s' % world.doorShuffle[player]) if world.doorShuffle[player] != 'vanilla': create_door_spoiler(world, player) diff --git a/Mystery.py b/Mystery.py index 7bc43f37..9937b5ad 100644 --- a/Mystery.py +++ b/Mystery.py @@ -3,6 +3,7 @@ import logging import random import urllib.request import urllib.parse +import re from DungeonRandomizer import parse_arguments from Main import main as DRMain @@ -14,6 +15,7 @@ def parse_yaml(txt): ret = {} indents = {len(txt) - len(txt.lstrip(' ')): ret} for line in txt.splitlines(): + line = re.sub(r'#.*', '', line) if not line: continue name, val = line.split(':', 1) From c619e3018b3c085bac58bdd4c1f53eff4fcae041 Mon Sep 17 00:00:00 2001 From: aerinon Date: Mon, 27 Jan 2020 09:17:29 -0700 Subject: [PATCH 05/11] Key math fix Turn off vanilla validation if ER is on --- DoorShuffle.py | 3 ++- KeyDoorShuffle.py | 3 ++- Main.py | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index c6d17863..ce0665e2 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -149,7 +149,8 @@ def vanilla_key_logic(world, player): analyze_dungeon(key_layout, world, player) world.key_logic[player][builder.name] = key_layout.key_logic last_key = None - validate_vanilla_key_logic(world, player) + if world.shuffle[player] == 'vanilla': + validate_vanilla_key_logic(world, player) # some useful functions diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index e27e8af8..794bbf57 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -864,7 +864,8 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa def cnt_avail_small_locations(free_locations, key_only, state, world, player): if not world.keyshuffle[player] and not world.retro[player]: - avail_chest_keys = min(free_locations - state.used_locations + state.used_smalls, state.key_locations - key_only) + bk_adj = 1 if state.big_key_opened and not state.big_key_special else 0 + avail_chest_keys = min(free_locations - bk_adj, state.key_locations - key_only) return max(0, avail_chest_keys + key_only - state.used_smalls) return state.key_locations - state.used_smalls diff --git a/Main.py b/Main.py index daabef6c..1bff50e5 100644 --- a/Main.py +++ b/Main.py @@ -23,7 +23,8 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute from ItemList import generate_itempool, difficulties, fill_prizes from Utils import output_path, parse_player_names -__version__ = '0.0.7-pre' +__version__ = '0.0.8-pre' + def main(args, seed=None): if args.outputpath: From 1a2c83be4c93de3b394561010b613a65db598250 Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Tue, 28 Jan 2020 20:28:53 +1100 Subject: [PATCH 06/11] Update insanity shuffle hole targets (and legacy shuffles). Update hole target addresses. --- EntranceShuffle.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 3cdc9054..f00f02c6 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -550,7 +550,7 @@ def link_entrances(world, player): ('North Fairy Cave Exit', 'North Fairy Cave'), ('Lost Woods Hideout Exit', 'Lost Woods Hideout (top)'), ('Lumberjack Tree Exit', 'Lumberjack Tree (top)'), - (('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Woods Second Section (Drop)')] + (('Skull Woods Second Section Exit (East)', 'Skull Woods Second Section Exit (West)'), 'Skull Back Drop')] if world.mode[player] == 'standard': # cannot move uncle cave @@ -587,7 +587,7 @@ def link_entrances(world, player): else: sw_hole_pool = dw_hole_entrances mandatory_dark_world.append('Skull Woods First Section Exit') - for target in ['Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)']: + for target in ['Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle']: connect_entrance(world, sw_hole_pool.pop(), target, player) # sanctuary has to be in light world @@ -786,8 +786,8 @@ def link_entrances(world, player): hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] - hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section (Drop)', - 'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)'] + hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Back Drop', + 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle'] # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) @@ -924,8 +924,8 @@ def link_entrances(world, player): hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] - hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section (Drop)', - 'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)'] + hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Back Drop', + 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle'] if world.mode[player] == 'standard': # cannot move uncle cave @@ -1627,8 +1627,8 @@ def link_inverted_entrances(world, player): hole_entrances = ['Kakariko Well Drop', 'Bat Cave Drop', 'North Fairy Cave Drop', 'Lost Woods Hideout Drop', 'Lumberjack Tree Tree', 'Sanctuary Grave', 'Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods Second Section Hole'] - hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Woods Second Section (Drop)', - 'Skull Woods First Section (Left)', 'Skull Woods First Section (Right)', 'Skull Woods First Section (Top)'] + hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Back Drop', + 'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle'] # tavern back door cannot be shuffled yet connect_doors(world, ['Tavern North'], ['Tavern'], player) @@ -3780,8 +3780,8 @@ exit_ids = {'Links House Exit': (0x01, 0x00), 'Lost Woods Hideout (top)': 0x7A, 'Lumberjack Tree (top)': 0x7F, 'Sewer Drop': 0x81, - 'Skull Woods Second Section (Drop)': 0x79, - 'Skull Woods First Section (Left)': 0x77, - 'Skull Woods First Section (Right)': 0x78, - 'Skull Woods First Section (Top)': 0x76, + 'Skull Back Drop': 0x79, + 'Skull Left Drop': 0x77, + 'Skull Pinball': 0x78, + 'Skull Pot Circle': 0x76, 'Pyramid': 0x7B} From 710ed9b011b55883da0cd171f3d9cc4dff9fb94b Mon Sep 17 00:00:00 2001 From: compiling <8335770+compiling@users.noreply.github.com> Date: Wed, 29 Jan 2020 18:52:54 +1100 Subject: [PATCH 07/11] Require Hammer for Thieves' Town - Big Chest --- Rules.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Rules.py b/Rules.py index a29ec51d..b42646ec 100644 --- a/Rules.py +++ b/Rules.py @@ -224,6 +224,7 @@ def global_rules(world, player): forbid_item(world.get_location('Thieves\' Town - Blind\'s Cell', player), 'Big Key (Thieves Town)', player) for location in ['Suspicious Maiden', 'Thieves\' Town - Blind\'s Cell']: set_rule(world.get_location(location, player), lambda state: state.has('Big Key (Thieves Town)', player)) + set_rule(world.get_location('Thieves\' Town - Big Chest'), lambda state: state.has('Hammer', player)) set_rule(world.get_location('Revealing Light', player), lambda state: state.has('Shining Light', player) and state.has('Maiden Rescued', player)) set_rule(world.get_location('Thieves\' Town - Boss', player), lambda state: state.has('Maiden Unmasked', player) and world.get_location('Thieves\' Town - Boss', player).parent_region.dungeon.boss.can_defeat(state)) set_rule(world.get_location('Thieves\' Town - Prize', player), lambda state: state.has('Maiden Unmasked', player) and world.get_location('Thieves\' Town - Prize', player).parent_region.dungeon.boss.can_defeat(state)) From aac0d0486d839eb7be9774bd369159b6d399100e Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 29 Jan 2020 06:26:49 -0700 Subject: [PATCH 08/11] Ball n Chain compass fix --- DoorShuffle.py | 29 +++++++++++++++-------------- Rom.py | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/DoorShuffle.py b/DoorShuffle.py index ac81c5e9..c604fd26 100644 --- a/DoorShuffle.py +++ b/DoorShuffle.py @@ -2023,18 +2023,19 @@ default_one_way_connections = [ ] # For crossed -compass_data = { # offset from 0x122e17, sram storage, write offset from compass_w_addr, 0 = jmp or # of nops - 'Hyrule Castle': (0x1, 0xc0, 0x16, 0), - 'Eastern Palace': (0x1C, 0xc1, 0x28, 0), - 'Desert Palace': (0x35, 0xc2, 0x4a, 0), - 'Agahnims Tower': (0x51, 0xc3, 0x5c, 0), - 'Swamp Palace': (0x6A, 0xc4, 0x7e, 0), - 'Palace of Darkness': (0x83, 0xc5, 0xa4, 0), - 'Misery Mire': (0x9C, 0xc6, 0xca, 0), - 'Skull Woods': (0xB5, 0xc7, 0xf0, 0), - 'Ice Palace': (0xD0, 0xc8, 0x102, 0), - 'Tower of Hera': (0xEB, 0xc9, 0x114, 0), - 'Thieves Town': (0x106, 0xca, 0x138, 0), - 'Turtle Rock': (0x11F, 0xcb, 0x15e, 0), - 'Ganons Tower': (0x13A, 0xcc, 0x170, 2) +# offset from 0x122e17, sram storage, write offset from compass_w_addr, 0 = jmp or # of nops, dungeon_id +compass_data = { + 'Hyrule Castle': (0x1, 0xc0, 0x16, 0, 0x02), + 'Eastern Palace': (0x1C, 0xc1, 0x28, 0, 0x04), + 'Desert Palace': (0x35, 0xc2, 0x4a, 0, 0x06), + 'Agahnims Tower': (0x51, 0xc3, 0x5c, 0, 0x08), + 'Swamp Palace': (0x6A, 0xc4, 0x7e, 0, 0x0a), + 'Palace of Darkness': (0x83, 0xc5, 0xa4, 0, 0x0c), + 'Misery Mire': (0x9C, 0xc6, 0xca, 0, 0x0e), + 'Skull Woods': (0xB5, 0xc7, 0xf0, 0, 0x10), + 'Ice Palace': (0xD0, 0xc8, 0x102, 0, 0x12), + 'Tower of Hera': (0xEB, 0xc9, 0x114, 0, 0x14), + 'Thieves Town': (0x106, 0xca, 0x138, 0, 0x16), + 'Turtle Rock': (0x11F, 0xcb, 0x15e, 0, 0x18), + 'Ganons Tower': (0x13A, 0xcc, 0x170, 2, 0x1a) } diff --git a/Rom.py b/Rom.py index 8de2d0ec..43551f6f 100644 --- a/Rom.py +++ b/Rom.py @@ -2102,8 +2102,19 @@ def compass_code_good(rom): def update_compasses(rom, world, player): layouts = world.dungeon_layouts[player] + # cmp XX : bne escape + # cpy 32 : bne escape + # brl .itemCounts + # c9 02 d0 eastern + # nop #2 + new_code = [0x07, 0xC0, 0x32, 0xD0, 0x03, 0x82, 0xB9, 0x01, 0xC9, 0x02, 0xD0, 0x10, 0xEA, 0xEA] + rom.write_bytes(compass_w_addr + 8, new_code) + # 05 06 07 08 + # C9 00 D0 02 80 04 C9 02 D0 15 C0 32 D0 03 82 B3 01 + # C9 XX D0 07 C0 32 D0 03 82 B9 01 C9 02 D0 10 EA EA + for name, builder in layouts.items(): - digit_offset, sram_byte, write_offset, jmp_nop_flag = compass_data[name] + digit_offset, sram_byte, write_offset, jmp_nop_flag, dungeon_id = compass_data[name] digit1 = builder.location_cnt // 10 digit2 = builder.location_cnt % 10 rom.write_byte(compass_r_addr+digit_offset, 0x90+digit1) @@ -2128,6 +2139,8 @@ def update_compasses(rom, world, player): else: for i in range(0, jmp_nop_flag): rom.write_byte(write_address+9+i, 0xea) # nop + if builder.bk_provided: + rom.write_byte(compass_w_addr+6, dungeon_id) InconvenientDungeonEntrances = {'Turtle Rock': 'Turtle Rock Main', From 4d717c7e4bffde09c29f181cefc08a5c97437f0b Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 29 Jan 2020 12:35:59 -0700 Subject: [PATCH 09/11] Default values for quickswap/disablemusic Possible fix for Aga Kill room for enemizer Hammer required for TT Big Chest --- DungeonRandomizer.py | 4 ++-- RoomData.py | 2 ++ Rules.py | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/DungeonRandomizer.py b/DungeonRandomizer.py index 68858c9e..d04d6fb5 100755 --- a/DungeonRandomizer.py +++ b/DungeonRandomizer.py @@ -218,8 +218,8 @@ def parse_arguments(argv, no_defaults=False): Select the rate at which the menu opens and closes. (default: %(default)s) ''') - parser.add_argument('--quickswap', help='Enable quick item swapping with L and R.', action='store_true') - parser.add_argument('--disablemusic', help='Disables game music.', action='store_true') + parser.add_argument('--quickswap', default=defval(False), help='Enable quick item swapping with L and R.', action='store_true') + parser.add_argument('--disablemusic', default=defval(False), help='Disables game music.', action='store_true') parser.add_argument('--mapshuffle', default=defval(False), help='Maps are no longer restricted to their dungeons, but can be anywhere', action='store_true') parser.add_argument('--compassshuffle', default=defval(False), help='Compasses are no longer restricted to their dungeons, but can be anywhere', action='store_true') parser.add_argument('--keyshuffle', default=defval(False), help='Small Keys are no longer restricted to their dungeons, but can be anywhere', action='store_true') diff --git a/RoomData.py b/RoomData.py index add738e6..e80fb087 100644 --- a/RoomData.py +++ b/RoomData.py @@ -239,6 +239,8 @@ def create_rooms(world, player): world.get_room(0x61, player).swap(5, 6) # puts the Incognito Entrance at the end, so it can be deleted world.get_room(0x62, player).swap(1, 4) # puts the exit at pos 1 - enables pos 3 world.get_room(0x77, player).swap(0, 1) # fixes Hera Lobby Key Stairs - entrance now at pos 0 + if world.enemy_shuffle[player] != 'none': + world.get_room(0xc0, player).change(0, DoorKind.Normal) # fix this kill room if enemizer is on class Room(object): diff --git a/Rules.py b/Rules.py index a29ec51d..23c6d2c6 100644 --- a/Rules.py +++ b/Rules.py @@ -217,6 +217,7 @@ def global_rules(world, player): set_defeat_dungeon_boss_rule(world.get_location('Skull Woods - Prize', player)) # blind can't have the small key? - not necessarily true anymore - but likely still + set_rule(world.get_location('Thieves\' Town - Big Chest', player), lambda state: state.has('Hammer', player)) for entrance in ['Thieves Basement Block Path', 'Thieves Blocked Entry Path', 'Thieves Conveyor Block Path', 'Thieves Conveyor Bridge Block Path']: set_rule(world.get_entrance(entrance, player), lambda state: state.can_lift_rocks(player)) for location in ['Thieves\' Town - Blind\'s Cell', 'Thieves\' Town - Boss']: From b53297194659e8b2d4685bcd3624af5c8ae86d7a Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 29 Jan 2020 12:39:22 -0700 Subject: [PATCH 10/11] Bump to 0.0.9 --- Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Main.py b/Main.py index 1bff50e5..d673d1d8 100644 --- a/Main.py +++ b/Main.py @@ -23,7 +23,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute from ItemList import generate_itempool, difficulties, fill_prizes from Utils import output_path, parse_player_names -__version__ = '0.0.8-pre' +__version__ = '0.0.9-pre' def main(args, seed=None): From 79d2151f86adbf1466c0c6880ac52a1c93be77b5 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 29 Jan 2020 12:46:17 -0700 Subject: [PATCH 11/11] Bump to 0.0.9 --- Rules.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Rules.py b/Rules.py index 123c0d28..c3367c72 100644 --- a/Rules.py +++ b/Rules.py @@ -131,12 +131,12 @@ def global_rules(world, player): set_rule(world.get_location('Spike Cave', player), lambda state: - state.has('Hammer', player) and state.can_lift_rocks(player) and - ((state.has('Cape', player) and state.can_extend_magic(player, 16, True)) or - (state.has('Cane of Byrna', player) and - (state.can_extend_magic(player, 12, True) or - (state.world.can_take_damage and (state.has_Boots(player) or state.has_hearts(player, 4)))))) - ) + state.has('Hammer', player) and state.can_lift_rocks(player) and + ((state.has('Cape', player) and state.can_extend_magic(player, 16, True)) or + (state.has('Cane of Byrna', player) and + (state.can_extend_magic(player, 12, True) or + (state.world.can_take_damage and (state.has_Boots(player) or state.has_hearts(player, 4)))))) + ) set_rule(world.get_location('Hookshot Cave - Top Right', player), lambda state: state.has('Hookshot', player)) set_rule(world.get_location('Hookshot Cave - Top Left', player), lambda state: state.has('Hookshot', player)) @@ -225,7 +225,6 @@ def global_rules(world, player): forbid_item(world.get_location('Thieves\' Town - Blind\'s Cell', player), 'Big Key (Thieves Town)', player) for location in ['Suspicious Maiden', 'Thieves\' Town - Blind\'s Cell']: set_rule(world.get_location(location, player), lambda state: state.has('Big Key (Thieves Town)', player)) - set_rule(world.get_location('Thieves\' Town - Big Chest'), lambda state: state.has('Hammer', player)) set_rule(world.get_location('Revealing Light', player), lambda state: state.has('Shining Light', player) and state.has('Maiden Rescued', player)) set_rule(world.get_location('Thieves\' Town - Boss', player), lambda state: state.has('Maiden Unmasked', player) and world.get_location('Thieves\' Town - Boss', player).parent_region.dungeon.boss.can_defeat(state)) set_rule(world.get_location('Thieves\' Town - Prize', player), lambda state: state.has('Maiden Unmasked', player) and world.get_location('Thieves\' Town - Prize', player).parent_region.dungeon.boss.can_defeat(state)) @@ -365,7 +364,7 @@ def global_rules(world, player): add_rule(world.get_location('Sunken Treasure', player), lambda state: state.has('Open Floodgate', player)) set_rule(world.get_location('Ganon', player), lambda state: state.has_beam_sword(player) and state.has_fire_source(player) and state.has_crystals(world.crystals_needed_for_ganon[player], player) - and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times + and (state.has('Tempered Sword', player) or state.has('Golden Sword', player) or (state.has('Silver Arrows', player) and state.can_shoot_arrows(player)) or state.has('Lamp', player) or state.can_extend_magic(player, 12))) # need to light torch a sufficient amount of times set_rule(world.get_entrance('Ganon Drop', player), lambda state: state.has_beam_sword(player)) # need to damage ganon to get tiles to drop