From cc70a6fa2647ff6f7be5f0b26bc45f4a39ac9698 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 30 Aug 2021 18:00:39 +0200 Subject: [PATCH] LttP: make shuffle names consistent --- BaseClasses.py | 2 +- Options.py | 12 ++++++------ playerSettings.yaml | 41 ++++++++++++++++++++++++---------------- worlds/alttp/Dungeons.py | 2 +- worlds/alttp/ItemPool.py | 8 ++++---- worlds/alttp/Options.py | 16 ++++++++-------- worlds/alttp/Rom.py | 34 ++++++++++++++++----------------- worlds/alttp/Rules.py | 10 +++++----- worlds/alttp/Shops.py | 8 ++++---- worlds/alttp/__init__.py | 6 +++--- 10 files changed, 74 insertions(+), 65 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index dff5617f..65b5d97f 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -569,7 +569,7 @@ class CollectionState(object): def has_key(self, item, player, count: int = 1): if self.world.logic[player] == 'nologic': return True - if self.world.smallkeyshuffle[player] == "universal": + if self.world.smallkey_shuffle[player] == "universal": return self.can_buy_unlimited('Small Key (Universal)', player) return self.prog_items[item, player] >= count diff --git a/Options.py b/Options.py index 4af038b3..620e8c7f 100644 --- a/Options.py +++ b/Options.py @@ -243,14 +243,14 @@ if __name__ == "__main__": from worlds.alttp.Options import Logic import argparse - mapshuffle = Toggle - compassshuffle = Toggle + map_shuffle = Toggle + compass_shuffle = Toggle keyshuffle = Toggle - bigkeyshuffle = Toggle + bigkey_shuffle = Toggle hints = Toggle test = argparse.Namespace() test.logic = Logic.from_text("no_logic") - test.mapshuffle = mapshuffle.from_text("ON") + test.map_shuffle = map_shuffle.from_text("ON") test.hints = hints.from_text('OFF') try: test.logic = Logic.from_text("overworld_glitches_typo") @@ -260,7 +260,7 @@ if __name__ == "__main__": test.logic_owg = Logic.from_text("owg") except KeyError as e: print(e) - if test.mapshuffle: - print("Mapshuffle is on") + if test.map_shuffle: + print("map_shuffle is on") print(f"Hints are {bool(test.hints)}") print(test) diff --git a/playerSettings.yaml b/playerSettings.yaml index f8f20149..2c39a529 100644 --- a/playerSettings.yaml +++ b/playerSettings.yaml @@ -279,22 +279,31 @@ A Link to the Past: on: 0 # prevents unshuffled compasses, maps and keys to be boss drops, they can still drop keysanity and other players' items off: 50 ### End of Logic Section ### - map_shuffle: # Shuffle dungeon maps into the world and other dungeons, including other players' worlds - on: 0 - off: 50 - compass_shuffle: # Shuffle compasses into the world and other dungeons, including other players' worlds - on: 0 - off: 50 - smallkey_shuffle: # Shuffle small keys into the world and other dungeons, including other players' worlds - on: 0 - universal: 0 # allows small keys to be used in any dungeon and adds shops to buy more - off: 50 - bigkey_shuffle: # Shuffle big keys into the world and other dungeons, including other players' worlds - on: 0 - off: 50 - local_keys: # Keep small keys and big keys local to your world - on: 0 - off: 50 + bigkey_shuffle: # Big Key Placement + original_dungeon: 50 + own_dungeons: 0 + own_world: 0 + any_world: 0 + different_world: 0 + smallkey_shuffle: # Small Key Placement + original_dungeon: 50 + own_dungeons: 0 + own_world: 0 + any_world: 0 + different_world: 0 + universal: 0 + compass_shuffle: # Compass Placement + original_dungeon: 50 + own_dungeons: 0 + own_world: 0 + any_world: 0 + different_world: 0 + map_shuffle: # Map Placement + original_dungeon: 50 + own_dungeons: 0 + own_world: 0 + any_world: 0 + different_world: 0 dungeon_items: # Alternative to the 4 shuffles and local_keys above this, does nothing until the respective 4 shuffles and local_keys above are deleted mc: 0 # Shuffle maps and compasses none: 50 # Shuffle none of the 4 diff --git a/worlds/alttp/Dungeons.py b/worlds/alttp/Dungeons.py index d3d79478..fee1cadb 100644 --- a/worlds/alttp/Dungeons.py +++ b/worlds/alttp/Dungeons.py @@ -8,7 +8,7 @@ from worlds.alttp.Regions import lookup_boss_drops def create_dungeons(world, player): def make_dungeon(name, default_boss, dungeon_regions, big_key, small_keys, dungeon_items): dungeon = Dungeon(name, dungeon_regions, big_key, - [] if world.smallkeyshuffle[player] == "universal" else small_keys, + [] if world.smallkey_shuffle[player] == "universal" else small_keys, dungeon_items, player) for item in dungeon.all_items: item.dungeon = dungeon diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index afa118bf..c0ea01cc 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -274,7 +274,7 @@ def generate_itempool(world): itempool.extend(['Rupees (300)'] * 34) itempool.extend(['Bombs (10)'] * 5) itempool.extend(['Arrows (10)'] * 7) - if world.smallkeyshuffle[player] == 'universal': + if world.smallkey_shuffle[player] == 'universal': itempool.extend(itemdiff.universal_keys) itempool.append('Small Key (Universal)') @@ -633,7 +633,7 @@ def get_pool_core(world, player: int): if retro: replace = {'Single Arrow', 'Arrows (10)', 'Arrow Upgrade (+5)', 'Arrow Upgrade (+10)'} pool = ['Rupees (5)' if item in replace else item for item in pool] - if world.smallkeyshuffle[player] == "universal": + if world.smallkey_shuffle[player] == "universal": pool.extend(diff.universal_keys) item_to_place = 'Small Key (Universal)' if goal != 'icerodhunt' else 'Nothing' if mode == 'standard': @@ -770,7 +770,7 @@ def make_custom_item_pool(world, player): itemtotal = itemtotal + 1 if mode == 'standard': - if world.smallkeyshuffle[player] == "universal": + if world.smallkey_shuffle[player] == "universal": key_location = world.random.choice( ['Secret Passage', 'Hyrule Castle - Boomerang Chest', 'Hyrule Castle - Map Chest', 'Hyrule Castle - Zelda\'s Chest', 'Sewers - Dark Cross']) @@ -793,7 +793,7 @@ def make_custom_item_pool(world, player): pool.extend(['Magic Mirror'] * customitemarray[22]) pool.extend(['Moon Pearl'] * customitemarray[28]) - if world.smallkeyshuffle == "universal": + if world.smallkey_shuffle == "universal": itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in Retro Mode if itemtotal < total_items_to_place: pool.extend(['Nothing'] * (total_items_to_place - itemtotal)) diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index 4ba111de..93225e05 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -43,26 +43,26 @@ class DungeonItem(Choice): return self.value in {0, 1} -class BigKeyShuffle(DungeonItem): +class bigkey_shuffle(DungeonItem): """Big Key Placement""" item_name_group = "Big Keys" displayname = "Big Key Shuffle" -class SmallKeyShuffle(DungeonItem): +class smallkey_shuffle(DungeonItem): """Small Key Placement""" option_universal = 5 item_name_group = "Small Keys" displayname = "Small Key Shuffle" -class CompassShuffle(DungeonItem): +class compass_shuffle(DungeonItem): """Compass Placement""" item_name_group = "Compasses" displayname = "Compass Shuffle" -class MapShuffle(DungeonItem): +class map_shuffle(DungeonItem): """Map Placement""" item_name_group = "Maps" displayname = "Map Shuffle" @@ -221,10 +221,10 @@ class TriforceHud(Choice): alttp_options: typing.Dict[str, type(Option)] = { "crystals_needed_for_gt": CrystalsTower, "crystals_needed_for_ganon": CrystalsGanon, - "bigkeyshuffle": BigKeyShuffle, - "smallkeyshuffle": SmallKeyShuffle, - "compassshuffle": CompassShuffle, - "mapshuffle": MapShuffle, + "bigkey_shuffle": bigkey_shuffle, + "smallkey_shuffle": smallkey_shuffle, + "compass_shuffle": compass_shuffle, + "map_shuffle": map_shuffle, "progressive": Progressive, "shop_item_slots": ShopItemSlots, "ow_palettes": OWPalette, diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index db363a86..949d243c 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -802,14 +802,14 @@ def patch_rom(world, rom, player, enemized): # patch music music_addresses = dungeon_music_addresses[location.name] - if world.mapshuffle[player]: + if world.map_shuffle[player]: music = local_random.choice([0x11, 0x16]) else: music = 0x11 if 'Pendant' in location.item.name else 0x16 for music_address in music_addresses: rom.write_byte(music_address, music) - if world.mapshuffle[player]: + if world.map_shuffle[player]: rom.write_byte(0x155C9, local_random.choice([0x11, 0x16])) # Randomize GT music too with map shuffle # patch entrance/exits/holes @@ -1491,18 +1491,18 @@ def patch_rom(world, rom, player, enemized): # block HC upstairs doors in rain state in standard mode rom.write_byte(0x18008A, 0x01 if world.mode[player] == "standard" and world.shuffle[player] != 'vanilla' else 0x00) - rom.write_byte(0x18016A, 0x10 | ((0x01 if world.smallkeyshuffle[player] else 0x00) - | (0x02 if world.compassshuffle[player] else 0x00) - | (0x04 if world.mapshuffle[player] else 0x00) - | (0x08 if world.bigkeyshuffle[player] else 0x00))) # free roaming item text boxes - rom.write_byte(0x18003B, 0x01 if world.mapshuffle[player] else 0x00) # maps showing crystals on overworld + rom.write_byte(0x18016A, 0x10 | ((0x01 if world.smallkey_shuffle[player] else 0x00) + | (0x02 if world.compass_shuffle[player] else 0x00) + | (0x04 if world.map_shuffle[player] else 0x00) + | (0x08 if world.bigkey_shuffle[player] else 0x00))) # free roaming item text boxes + rom.write_byte(0x18003B, 0x01 if world.map_shuffle[player] else 0x00) # maps showing crystals on overworld # compasses showing dungeon count if world.clock_mode[player] or not world.dungeon_counters[player]: rom.write_byte(0x18003C, 0x00) # Currently must be off if timer is on, because they use same HUD location elif world.dungeon_counters[player] is True: rom.write_byte(0x18003C, 0x02) # always on - elif world.compassshuffle[player] or world.dungeon_counters[player] == 'pickup': + elif world.compass_shuffle[player] or world.dungeon_counters[player] == 'pickup': rom.write_byte(0x18003C, 0x01) # show on pickup else: rom.write_byte(0x18003C, 0x00) @@ -1515,10 +1515,10 @@ def patch_rom(world, rom, player, enemized): # b - Big Key # a - Small Key # - rom.write_byte(0x180045, ((0x01 if world.smallkeyshuffle[player] is True else 0x00) - | (0x02 if world.bigkeyshuffle[player] else 0x00) - | (0x04 if world.mapshuffle[player] else 0x00) - | (0x08 if world.compassshuffle[player] else 0x00))) # free roaming items in menu + rom.write_byte(0x180045, ((0x01 if world.smallkey_shuffle[player] is True else 0x00) + | (0x02 if world.bigkey_shuffle[player] else 0x00) + | (0x04 if world.map_shuffle[player] else 0x00) + | (0x08 if world.compass_shuffle[player] else 0x00))) # free roaming items in menu # Map reveals reveal_bytes = { @@ -1544,11 +1544,11 @@ def patch_rom(world, rom, player, enemized): return 0x0000 rom.write_int16(0x18017A, - get_reveal_bytes('Green Pendant') if world.mapshuffle[player] else 0x0000) # Sahasrahla reveal - rom.write_int16(0x18017C, get_reveal_bytes('Crystal 5') | get_reveal_bytes('Crystal 6') if world.mapshuffle[ + get_reveal_bytes('Green Pendant') if world.map_shuffle[player] else 0x0000) # Sahasrahla reveal + rom.write_int16(0x18017C, get_reveal_bytes('Crystal 5') | get_reveal_bytes('Crystal 6') if world.map_shuffle[ player] else 0x0000) # Bomb Shop Reveal - rom.write_byte(0x180172, 0x01 if world.smallkeyshuffle[player] == "universal" else 0x00) # universal keys + rom.write_byte(0x180172, 0x01 if world.smallkey_shuffle[player] == "universal" else 0x00) # universal keys rom.write_byte(0x18637E, 0x01 if world.retro[player] else 0x00) # Skip quiver in item shops once bought rom.write_byte(0x180175, 0x01 if world.retro[player] else 0x00) # rupee bow rom.write_byte(0x180176, 0x0A if world.retro[player] else 0x00) # wood arrow cost @@ -2247,9 +2247,9 @@ def write_strings(rom, world, player): # Lastly we write hints to show where certain interesting items are. It is done the way it is to re-use the silver code and also to give one hint per each type of item regardless of how many exist. This supports many settings well. items_to_hint = RelevantItems.copy() - if world.smallkeyshuffle[player]: + if world.smallkey_shuffle[player]: items_to_hint.extend(SmallKeys) - if world.bigkeyshuffle[player]: + if world.bigkey_shuffle[player]: items_to_hint.extend(BigKeys) local_random.shuffle(items_to_hint) hint_count = 5 if world.shuffle[player] not in ['vanilla', 'dungeonssimple', 'dungeonsfull', 'dungeonscrossed'] else 8 diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 66c5f9a6..7defb55a 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -212,7 +212,7 @@ def global_rules(world, player): set_rule(world.get_entrance('Sewers Door', player), lambda state: state.has_key('Small Key (Hyrule Castle)', player) or ( - world.smallkeyshuffle[player] == "universal" and world.mode[ + world.smallkey_shuffle[player] == "universal" and world.mode[ player] == 'standard')) # standard universal small keys cannot access the shop set_rule(world.get_entrance('Sewers Back Door', player), lambda state: state.has_key('Small Key (Hyrule Castle)', player)) @@ -243,7 +243,7 @@ def global_rules(world, player): set_rule(world.get_location('Desert Palace - Boss', player), lambda state: state.has_key('Small Key (Desert Palace)', player) and state.has('Big Key (Desert Palace)', player) and state.has_fire_source(player) and state.world.get_location('Desert Palace - Boss', player).parent_region.dungeon.boss.can_defeat(state)) # logic patch to prevent placing a crystal in Desert that's required to reach the required keys - if not (world.smallkeyshuffle[player] and world.bigkeyshuffle[player]): + if not (world.smallkey_shuffle[player] and world.bigkey_shuffle[player]): add_rule(world.get_location('Desert Palace - Prize', player), lambda state: state.world.get_region('Desert Palace Main (Outer)', player).can_reach(state)) set_rule(world.get_entrance('Tower of Hera Small Key Door', player), lambda state: state.has_key('Small Key (Tower of Hera)', player) or item_name(state, 'Tower of Hera - Big Key Chest', player) == ('Small Key (Tower of Hera)', player)) @@ -260,7 +260,7 @@ def global_rules(world, player): if world.accessibility[player] != 'locations': set_always_allow(world.get_location('Swamp Palace - Big Chest', player), lambda state, item: item.name == 'Big Key (Swamp Palace)' and item.player == player) set_rule(world.get_entrance('Swamp Palace (North)', player), lambda state: state.has('Hookshot', player)) - if not world.smallkeyshuffle[player] and world.logic[player] != 'nologic': + if not world.smallkey_shuffle[player] and world.logic[player] != 'nologic': forbid_item(world.get_location('Swamp Palace - Entrance', player), 'Big Key (Swamp Palace)', player) set_rule(world.get_entrance('Thieves Town Big Key Door', player), lambda state: state.has('Big Key (Thieves Town)', player)) @@ -915,14 +915,14 @@ def set_trock_key_rules(world, player): return 4 # If TR is only accessible from the middle, the big key must be further restricted to prevent softlock potential - if not can_reach_front and not world.smallkeyshuffle[player]: + if not can_reach_front and not world.smallkey_shuffle[player]: # Must not go in the Big Key Chest - only 1 other chest available and 2+ keys required for all other chests forbid_item(world.get_location('Turtle Rock - Big Key Chest', player), 'Big Key (Turtle Rock)', player) if not can_reach_big_chest: # Must not go in the Chain Chomps chest - only 2 other chests available and 3+ keys required for all other chests forbid_item(world.get_location('Turtle Rock - Chain Chomps', player), 'Big Key (Turtle Rock)', player) if world.accessibility[player] == 'locations' and world.goal[player] != 'icerodhunt': - if world.bigkeyshuffle[player] and can_reach_big_chest: + if world.bigkey_shuffle[player] and can_reach_big_chest: # Must not go in the dungeon - all 3 available chests (Chomps, Big Chest, Crystaroller) must be keys to access laser bridge, and the big key is required first for location in ['Turtle Rock - Chain Chomps', 'Turtle Rock - Compass Chest', 'Turtle Rock - Roller Room - Left', 'Turtle Rock - Roller Room - Right']: diff --git a/worlds/alttp/Shops.py b/worlds/alttp/Shops.py index 359b3b75..c7e42626 100644 --- a/worlds/alttp/Shops.py +++ b/worlds/alttp/Shops.py @@ -271,7 +271,7 @@ def create_shops(world, player: int): # make sure that blue potion is available in inverted, special case locked = None; lock when done. player_shop_table["Dark Lake Hylia Shop"] = \ player_shop_table["Dark Lake Hylia Shop"]._replace(items=_inverted_hylia_shop_defaults, locked=None) - chance_100 = int(world.retro[player])*0.25+int(world.smallkeyshuffle[player] == "universal") * 0.5 + chance_100 = int(world.retro[player])*0.25+int(world.smallkey_shuffle[player] == "universal") * 0.5 for region_name, (room_id, type, shopkeeper, custom, locked, inventory, sram_offset) in player_shop_table.items(): region = world.get_region(region_name, player) shop: Shop = shop_class_mapping[type](region, room_id, shopkeeper, custom, locked, sram_offset) @@ -371,13 +371,13 @@ def set_up_shops(world, player: int): rss = world.get_region('Red Shield Shop', player).shop replacement_items = [['Red Potion', 150], ['Green Potion', 75], ['Blue Potion', 200], ['Bombs (10)', 50], ['Blue Shield', 50], ['Small Heart', 10]] # Can't just replace the single arrow with 10 arrows as retro doesn't need them. - if world.smallkeyshuffle[player] == "universal": + if world.smallkey_shuffle[player] == "universal": replacement_items.append(['Small Key (Universal)', 100]) replacement_item = world.random.choice(replacement_items) rss.add_inventory(2, 'Single Arrow', 80, 1, replacement_item[0], replacement_item[1]) rss.locked = True - if world.smallkeyshuffle[player] == "universal" or world.retro[player]: + if world.smallkey_shuffle[player] == "universal" or world.retro[player]: for shop in world.random.sample([s for s in world.shops if s.custom and not s.locked and s.type == ShopType.Shop and s.region.player == player], 5): @@ -385,7 +385,7 @@ def set_up_shops(world, player: int): slots = [0, 1, 2] world.random.shuffle(slots) slots = iter(slots) - if world.smallkeyshuffle[player] == "universal": + if world.smallkey_shuffle[player] == "universal": shop.add_inventory(next(slots), 'Small Key (Universal)', 100) if world.retro[player]: shop.push_inventory(next(slots), 'Single Arrow', 80) diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index cbb7fa1b..4320fd01 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -65,7 +65,7 @@ class ALTTPWorld(World): world.er_seeds[player] = seed elif world.shuffle[player] == "vanilla": world.er_seeds[player] = "vanilla" - for dungeon_item in ["smallkeyshuffle", "bigkeyshuffle", "compassshuffle", "mapshuffle"]: + for dungeon_item in ["smallkey_shuffle", "bigkey_shuffle", "compass_shuffle", "map_shuffle"]: option = getattr(world, dungeon_item)[player] if option == "own_world": world.local_items[player] |= self.item_name_groups[option.item_name_group] @@ -324,8 +324,8 @@ class ALTTPWorld(World): trash_counts = {} standard_keyshuffle_players = set() for player in world.get_game_players("A Link to the Past"): - if world.mode[player] == 'standard' and world.smallkeyshuffle[player] \ - and world.smallkeyshuffle[player] != "universal": + if world.mode[player] == 'standard' and world.smallkey_shuffle[player] \ + and world.smallkey_shuffle[player] != "universal": standard_keyshuffle_players.add(player) if not world.ganonstower_vanilla[player] or \ world.logic[player] in {'owglitches', 'hybridglitches', "nologic"}: