From d0a98949f5f4c3588b0529da6ab0d903603cc292 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 1 Jun 2022 17:29:21 +0200 Subject: [PATCH] LttP: split Retro into Retro Bows and Retro Caves (#588) --- BaseClasses.py | 2 +- Main.py | 4 ++-- worlds/alttp/ItemPool.py | 8 ++++---- worlds/alttp/Options.py | 16 +++++++++++----- worlds/alttp/Rom.py | 34 +++++++++++++++++----------------- worlds/alttp/Shops.py | 14 +++++++------- worlds/alttp/__init__.py | 2 +- 7 files changed, 43 insertions(+), 37 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 6cd0db6b..c5627a10 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -790,7 +790,7 @@ class CollectionState(): or (self.has('Bombs (10)', player) and enemies < 6)) def can_shoot_arrows(self, player: int) -> bool: - if self.world.retro[player]: + if self.world.retro_bow[player]: return (self.has('Bow', player) or self.has('Silver Bow', player)) and self.can_buy('Single Arrow', player) return self.has('Bow', player) or self.has('Silver Bow', player) diff --git a/Main.py b/Main.py index 04ac2124..0d937851 100644 --- a/Main.py +++ b/Main.py @@ -265,7 +265,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No # collect ER hint info er_hint_data = {player: {} for player in world.get_game_players("A Link to the Past") if - world.shuffle[player] != "vanilla" or world.retro[player]} + world.shuffle[player] != "vanilla" or world.retro_caves[player]} for region in world.regions: if region.player in er_hint_data and region.locations: @@ -305,7 +305,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No takeanyregions = ["Old Man Sword Cave", "Take-Any #1", "Take-Any #2", "Take-Any #3", "Take-Any #4"] for index, take_any in enumerate(takeanyregions): for region in [world.get_region(take_any, player) for player in - world.get_game_players("A Link to the Past") if world.retro[player]]: + world.get_game_players("A Link to the Past") if world.retro_caves[player]]: item = world.create_item( region.shop.inventory[(0 if take_any == "Old Man Sword Cave" else 1)]['item'], region.player) diff --git a/worlds/alttp/ItemPool.py b/worlds/alttp/ItemPool.py index ccb739e9..3c7ca4d2 100644 --- a/worlds/alttp/ItemPool.py +++ b/worlds/alttp/ItemPool.py @@ -440,7 +440,7 @@ def generate_itempool(world): world.itempool += progressionitems + nonprogressionitems - if world.retro[player]: + if world.retro_caves[player]: set_up_take_anys(world, player) # depends on world.itempool to be set @@ -531,7 +531,7 @@ def get_pool_core(world, player: int): goal = world.goal[player] mode = world.mode[player] swordless = world.swordless[player] - retro = world.retro[player] + retro_bow = world.retro_bow[player] logic = world.logic[player] pool = [] @@ -647,7 +647,7 @@ def get_pool_core(world, player: int): place_item('Master Sword Pedestal', 'Triforce') pool.remove("Rupees (20)") - if retro: + if retro_bow: 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.smallkey_shuffle[player] == smallkey_shuffle.option_universal: @@ -812,7 +812,7 @@ def make_custom_item_pool(world, player): pool.extend(['Moon Pearl'] * customitemarray[28]) if world.smallkey_shuffle[player] == smallkey_shuffle.option_universal: - itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in Retro Mode + itemtotal = itemtotal - 28 # Corrects for small keys not being in item pool in universal mode if itemtotal < total_items_to_place: pool.extend(['Nothing'] * (total_items_to_place - itemtotal)) logging.warning(f"Pool was filled up with {total_items_to_place - itemtotal} Nothing's for player {player}") diff --git a/worlds/alttp/Options.py b/worlds/alttp/Options.py index 6d741b76..51ff1c8e 100644 --- a/worlds/alttp/Options.py +++ b/worlds/alttp/Options.py @@ -147,10 +147,15 @@ class Swordless(Toggle): display_name = "Swordless" -class Retro(Toggle): - """Zelda-1 like mode. You have to purchase a quiver to shoot arrows using rupees - and there are randomly placed take-any caves that contain one Sword and choices of Heart Container/Blue Potion.""" - display_name = "Retro" +class RetroBow(Toggle): + """Zelda-1 like mode. You have to purchase a quiver to shoot arrows using rupees.""" + display_name = "Retro Bow" + + +class RetroCaves(Toggle): + """Zelda-1 like mode. There are randomly placed take-any caves that contain one Sword and + choices of Heart Container/Blue Potion.""" + display_name = "Retro Caves" class RestrictBossItem(Toggle): @@ -330,7 +335,8 @@ alttp_options: typing.Dict[str, type(Option)] = { "map_shuffle": map_shuffle, "progressive": Progressive, "swordless": Swordless, - "retro": Retro, + "retro_bow": RetroBow, + "retro_caves": RetroCaves, "hints": Hints, "scams": Scams, "restrict_dungeon_item_on_boss": RestrictBossItem, diff --git a/worlds/alttp/Rom.py b/worlds/alttp/Rom.py index c4e1cd64..a88d879b 100644 --- a/worlds/alttp/Rom.py +++ b/worlds/alttp/Rom.py @@ -873,7 +873,7 @@ def patch_rom(world, rom, player, enemized): return 0x53 + int(num), 0x79 + int(num) credits_total = 216 - if world.retro[player]: # Old man cave and Take any caves will count towards collection rate. + if world.retro_caves[player]: # Old man cave and Take any caves will count towards collection rate. credits_total += 5 if world.shop_item_slots[player]: # Potion shop only counts towards collection rate if included in the shuffle. credits_total += 30 if 'w' in world.shop_shuffle[player] else 27 @@ -1037,7 +1037,7 @@ def patch_rom(world, rom, player, enemized): prize_replacements[0xE0] = 0xDF # Fairy -> heart prize_replacements[0xE3] = 0xD8 # Big magic -> small magic - if world.retro[player]: + if world.retro_bow[player]: prize_replacements[0xE1] = 0xDA # 5 Arrows -> Blue Rupee prize_replacements[0xE2] = 0xDB # 10 Arrows -> Red Rupee @@ -1130,7 +1130,7 @@ def patch_rom(world, rom, player, enemized): 0x12, 0x01, 0x35, 0xFF, # lamp -> 5 rupees 0x51, 0x06, 0x52, 0xFF, # 6 +5 bomb upgrades -> +10 bomb upgrade 0x53, 0x06, 0x54, 0xFF, # 6 +5 arrow upgrades -> +10 arrow upgrade - 0x58, 0x01, 0x36 if world.retro[player] else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode) + 0x58, 0x01, 0x36 if world.retro_bow[player] else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode) 0x3E, difficulty.boss_heart_container_limit, 0x47, 0xff, # boss heart -> green 20 0x17, difficulty.heart_piece_limit, 0x47, 0xff, # piece of heart -> green 20 0xFF, 0xFF, 0xFF, 0xFF, # end of table sentinel @@ -1270,12 +1270,12 @@ def patch_rom(world, rom, player, enemized): if startingstate.has('Silver Bow', player): equip[0x340] = 1 equip[0x38E] |= 0x60 - if not world.retro[player]: + if not world.retro_bow[player]: equip[0x38E] |= 0x80 elif startingstate.has('Bow', player): equip[0x340] = 1 equip[0x38E] |= 0x20 # progressive flag to get the correct hint in all cases - if not world.retro[player]: + if not world.retro_bow[player]: equip[0x38E] |= 0x80 if startingstate.has('Silver Arrows', player): equip[0x38E] |= 0x40 @@ -1413,7 +1413,7 @@ def patch_rom(world, rom, player, enemized): elif item.name in bombs: equip[0x343] += bombs[item.name] elif item.name in arrows: - if world.retro[player]: + if world.retro_bow[player]: equip[0x38E] |= 0x80 equip[0x377] = 1 else: @@ -1547,18 +1547,18 @@ def patch_rom(world, rom, player, enemized): rom.write_byte(0x180172, 0x01 if world.smallkey_shuffle[ player] == smallkey_shuffle.option_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 - rom.write_byte(0x180178, 0x32 if world.retro[player] else 0x00) # silver arrow cost - rom.write_byte(0x301FC, 0xDA if world.retro[player] else 0xE1) # rupees replace arrows under pots - rom.write_byte(0x30052, 0xDB if world.retro[player] else 0xE2) # replace arrows in fish prize from bottle merchant - rom.write_bytes(0xECB4E, [0xA9, 0x00, 0xEA, 0xEA] if world.retro[player] else [0xAF, 0x77, 0xF3, + rom.write_byte(0x18637E, 0x01 if world.retro_bow[player] else 0x00) # Skip quiver in item shops once bought + rom.write_byte(0x180175, 0x01 if world.retro_bow[player] else 0x00) # rupee bow + rom.write_byte(0x180176, 0x0A if world.retro_bow[player] else 0x00) # wood arrow cost + rom.write_byte(0x180178, 0x32 if world.retro_bow[player] else 0x00) # silver arrow cost + rom.write_byte(0x301FC, 0xDA if world.retro_bow[player] else 0xE1) # rupees replace arrows under pots + rom.write_byte(0x30052, 0xDB if world.retro_bow[player] else 0xE2) # replace arrows in fish prize from bottle merchant + rom.write_bytes(0xECB4E, [0xA9, 0x00, 0xEA, 0xEA] if world.retro_bow[player] else [0xAF, 0x77, 0xF3, 0x7E]) # Thief steals rupees instead of arrows - rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if world.retro[player] else [0xAF, 0x77, 0xF3, + rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if world.retro_bow[player] else [0xAF, 0x77, 0xF3, 0x7E]) # Pikit steals rupees instead of arrows rom.write_bytes(0xEDA5, - [0x35, 0x41] if world.retro[player] else [0x43, 0x44]) # Chest game gives rupees instead of arrows + [0x35, 0x41] if world.retro_bow[player] else [0x43, 0x44]) # Chest game gives rupees instead of arrows digging_game_rng = local_random.randint(1, 30) # set rng for digging game rom.write_byte(0x180020, digging_game_rng) rom.write_byte(0xEFD95, digging_game_rng) @@ -1727,7 +1727,7 @@ def write_custom_shops(rom, world, player): item_code = get_nonnative_item_sprite(item['item']) else: item_code = ItemFactory(item['item'], player).code - if item['item'] == 'Single Arrow' and item['player'] == 0 and world.retro[player]: + if item['item'] == 'Single Arrow' and item['player'] == 0 and world.retro_bow[player]: rom.write_byte(0x186500 + shop.sram_offset + slot, arrow_mask) item_data = [shop_id, item_code] + price_data + \ @@ -1740,7 +1740,7 @@ def write_custom_shops(rom, world, player): items_data.extend([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) rom.write_bytes(0x184900, items_data) - if world.retro[player]: + if world.retro_bow[player]: retro_shop_slots.append(0xFF) rom.write_bytes(0x186540, retro_shop_slots) diff --git a/worlds/alttp/Shops.py b/worlds/alttp/Shops.py index 73714abc..54af2017 100644 --- a/worlds/alttp/Shops.py +++ b/worlds/alttp/Shops.py @@ -287,7 +287,7 @@ def create_shops(world, player: int): if 'g' in option or 'f' in option: default_shop_table = [i for l in [shop_generation_types[x] for x in ['arrows', 'bombs', 'potions', 'shields', 'bottle'] if - not world.retro[player] or x != 'arrows'] for i in l] + not world.retro_bow[player] or x != 'arrows'] for i in l] new_basic_shop = world.random.sample(default_shop_table, k=3) new_dark_shop = world.random.sample(default_shop_table, k=3) for name, shop in player_shop_table.items(): @@ -305,7 +305,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( + chance_100 = int(world.retro_bow[player]) * 0.25 + int( world.smallkey_shuffle[player] == smallkey_shuffle.option_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) @@ -402,7 +402,7 @@ shop_generation_types = { def set_up_shops(world, player: int): # TODO: move hard+ mode changes for shields here, utilizing the new shops - if world.retro[player]: + if world.retro_bow[player]: 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', @@ -413,7 +413,7 @@ def set_up_shops(world, player: int): rss.add_inventory(2, 'Single Arrow', 80, 1, replacement_item[0], replacement_item[1]) rss.locked = True - if world.smallkey_shuffle[player] == smallkey_shuffle.option_universal or world.retro[player]: + if world.smallkey_shuffle[player] == smallkey_shuffle.option_universal or world.retro_bow[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): @@ -423,7 +423,7 @@ def set_up_shops(world, player: int): slots = iter(slots) if world.smallkey_shuffle[player] == smallkey_shuffle.option_universal: shop.add_inventory(next(slots), 'Small Key (Universal)', 100) - if world.retro[player]: + if world.retro_bow[player]: shop.push_inventory(next(slots), 'Single Arrow', 80) @@ -436,7 +436,7 @@ def shuffle_shops(world, items, player: int): new_items = ["Bomb Upgrade (+5)"] * 6 new_items.append("Bomb Upgrade (+5)" if progressive else "Bomb Upgrade (+10)") - if not world.retro[player]: + if not world.retro_bow[player]: new_items += ["Arrow Upgrade (+5)"] * 6 new_items.append("Arrow Upgrade (+5)" if progressive else "Arrow Upgrade (+10)") @@ -578,7 +578,7 @@ def price_to_funny_price(world, item: dict, player: int): if world.smallkey_shuffle[player] == smallkey_shuffle.option_universal \ and not "Small Key (Universal)" == item['replacement']: price_types.append(ShopPriceType.Keys) - if not world.retro[player]: + if not world.retro_bow[player]: price_types.append(ShopPriceType.Arrows) world.random.shuffle(price_types) for p_type in price_types: diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index b782a15d..cdeb9e39 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -154,7 +154,7 @@ class ALTTPWorld(World): self.er_seed = "vanilla" elif seed.startswith("group-") or world.is_race: self.er_seed = get_same_seed(world, ( - shuffle, seed, world.retro[player], world.mode[player], world.logic[player])) + shuffle, seed, world.retro_caves[player], world.mode[player], world.logic[player])) else: # not a race or group seed, use set seed as is. self.er_seed = seed elif world.shuffle[player] == "vanilla":