diff --git a/BaseClasses.py b/BaseClasses.py index d841da36..205aee99 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -67,7 +67,7 @@ class World(object): self.compassshuffle = {player: False for player in range(1, players + 1)} self.keyshuffle = {player: False for player in range(1, players + 1)} self.bigkeyshuffle = {player: False for player in range(1, players + 1)} - self.retro = retro + self.retro = retro.copy() self.custom = custom self.customitemarray = customitemarray self.can_take_damage = True @@ -379,7 +379,7 @@ class CollectionState(object): return self.prog_items.count((item, player)) >= count def has_key(self, item, player, count=1): - if self.world.retro: + if self.world.retro[player]: return self.can_buy_unlimited('Small Key (Universal)', player) if count == 1: return (item, player) in self.prog_items @@ -448,7 +448,7 @@ class CollectionState(object): ) def can_shoot_arrows(self, player): - if self.world.retro: + if self.world.retro[player]: #TODO: need to decide how we want to handle wooden arrows longer-term (a can-buy-a check, or via dynamic shop location) #FIXME: Should do something about hard+ ganon only silvers. For the moment, i believe they effective grant wooden, so we are safe return self.has('Bow', player) and (self.has('Silver Arrows', player) or self.can_buy_unlimited('Single Arrow', player)) @@ -1044,6 +1044,7 @@ class Spoiler(object): self.metadata = {'version': ERVersion, 'logic': self.world.logic, 'mode': self.world.mode, + 'retro': self.world.retro, 'weapons': self.world.swords, 'goal': self.world.goal, 'shuffle': self.world.shuffle, @@ -1083,6 +1084,7 @@ class Spoiler(object): outfile.write('ALttP Entrance Randomizer Version %s - Seed: %s\n\n' % (self.metadata['version'], self.world.seed)) outfile.write('Logic: %s\n' % self.metadata['logic']) outfile.write('Mode: %s\n' % self.metadata['mode']) + outfile.write('Retro: %s\n' % {k: 'Yes' if v else 'No' for k, v in self.metadata['retro'].items()}) outfile.write('Swords: %s\n' % self.metadata['weapons']) outfile.write('Goal: %s\n' % self.metadata['goal']) outfile.write('Difficulty: %s\n' % self.metadata['item_pool']) diff --git a/Dungeons.py b/Dungeons.py index 7237af00..9470d390 100644 --- a/Dungeons.py +++ b/Dungeons.py @@ -8,7 +8,7 @@ from Items import ItemFactory 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.retro else small_keys, dungeon_items, player) + dungeon = Dungeon(name, dungeon_regions, big_key, [] if world.retro[player] else small_keys, dungeon_items, player) dungeon.boss = BossFactory(default_boss, player) for region in dungeon.regions: world.get_region(region, player).dungeon = dungeon @@ -47,7 +47,7 @@ def fill_dungeons(world): for player in range(1, world.players + 1): pinball_room = world.get_location('Skull Woods - Pinball Room', player) - if world.retro: + if world.retro[player]: world.push_item(pinball_room, ItemFactory('Small Key (Universal)', player), False) else: world.push_item(pinball_room, ItemFactory('Small Key (Skull Woods)', player), False) @@ -126,7 +126,7 @@ def fill_dungeons_restrictive(world, shuffled_locations): for player in range(1, world.players + 1): pinball_room = world.get_location('Skull Woods - Pinball Room', player) - if world.retro: + if world.retro[player]: world.push_item(pinball_room, ItemFactory('Small Key (Universal)', player), False) else: world.push_item(pinball_room, ItemFactory('Small Key (Skull Woods)', player), False) diff --git a/EntranceRandomizer.py b/EntranceRandomizer.py index 3782a001..a423cae1 100755 --- a/EntranceRandomizer.py +++ b/EntranceRandomizer.py @@ -280,7 +280,8 @@ def parse_arguments(argv, no_defaults=False): for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', 'shuffle', 'crystals_ganon', 'crystals_gt', 'openpyramid', - 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle']: + 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', + 'retro']: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) diff --git a/ItemList.py b/ItemList.py index 69114363..991588b4 100644 --- a/ItemList.py +++ b/ItemList.py @@ -174,10 +174,10 @@ def generate_itempool(world, player): # set up item pool if world.custom: - (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro, world.customitemarray) + (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.customitemarray) world.rupoor_cost = min(world.customitemarray[69], 9999) else: - (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro) + (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player]) for item in precollected_items: world.push_precollected(ItemFactory(item, player)) @@ -242,7 +242,7 @@ def generate_itempool(world, player): place_bosses(world, player) set_up_shops(world, player) - if world.retro: + if world.retro[player]: set_up_take_anys(world, player) create_dynamic_shop_locations(world, player) @@ -355,13 +355,13 @@ def set_up_shops(world, player): for shop in world.shops: shop.active = True - if world.retro: + if world.retro[player]: rss = world.get_region('Red Shield Shop', player).shop rss.active = True rss.add_inventory(2, 'Single Arrow', 80) # Randomized changes to Shops - if world.retro: + if world.retro[player]: for shop in random.sample([s for s in world.shops if s.replaceable and s.region.player == player], 5): shop.active = True shop.add_inventory(0, 'Single Arrow', 80) diff --git a/Main.py b/Main.py index 1f45700f..876f6912 100644 --- a/Main.py +++ b/Main.py @@ -191,7 +191,7 @@ def main(args, seed=None): world.mode[player], world.goal[player], "" if world.timer in ['none', 'display'] else "-" + world.timer, world.shuffle[player], world.algorithm, mcsb_name, - "-retro" if world.retro else "", + "-retro" if world.retro[player] else "", "-prog_" + world.progressive if world.progressive in ['off', 'random'] else "", "-nohints" if not world.hints else "")) if not args.outputname else '' rom.write_to_file(output_path(f'{outfilebase}{outfilesuffix}.sfc')) diff --git a/Rom.py b/Rom.py index 12be1b7c..d49be486 100644 --- a/Rom.py +++ b/Rom.py @@ -743,7 +743,7 @@ def patch_rom(world, player, rom, enemized): prizes = [prize_replacements.get(prize, prize) for prize in prizes] dig_prizes = [prize_replacements.get(prize, prize) for prize in dig_prizes] - if world.retro: + if world.retro[player]: prize_replacements = {0xE1: 0xDA, #5 Arrows -> Blue Rupee 0xE2: 0xDB} #10 Arrows -> Red Rupee prizes = [prize_replacements.get(prize, prize) for prize in prizes] @@ -786,7 +786,7 @@ def patch_rom(world, player, rom, 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 else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode) + 0x58, 0x01, 0x36 if world.retro[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 @@ -1001,15 +1001,15 @@ def patch_rom(world, player, rom, enemized): write_int16(rom, 0x18017A, get_reveal_bytes('Green Pendant') if world.mapshuffle[player] else 0x0000) # Sahasrahla reveal write_int16(rom, 0x18017C, get_reveal_bytes('Crystal 5')|get_reveal_bytes('Crystal 6') if world.mapshuffle[player] else 0x0000) # Bomb Shop Reveal - rom.write_byte(0x180172, 0x01 if world.retro else 0x00) # universal keys - rom.write_byte(0x180175, 0x01 if world.retro else 0x00) # rupee bow - rom.write_byte(0x180176, 0x0A if world.retro else 0x00) # wood arrow cost - rom.write_byte(0x180178, 0x32 if world.retro else 0x00) # silver arrow cost - rom.write_byte(0x301FC, 0xDA if world.retro else 0xE1) # rupees replace arrows under pots - rom.write_byte(0x30052, 0xDB if world.retro else 0xE2) # replace arrows in fish prize from bottle merchant - rom.write_bytes(0xECB4E, [0xA9, 0x00, 0xEA, 0xEA] if world.retro else [0xAF, 0x77, 0xF3, 0x7E]) # Thief steals rupees instead of arrows - rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if world.retro else [0xAF, 0x77, 0xF3, 0x7E]) # Pikit steals rupees instead of arrows - rom.write_bytes(0xEDA5, [0x35, 0x41] if world.retro else [0x43, 0x44]) # Chest game gives rupees instead of arrows + rom.write_byte(0x180172, 0x01 if world.retro[player] else 0x00) # universal keys + 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, 0x7E]) # Thief steals rupees instead of arrows + rom.write_bytes(0xF0D96, [0xA9, 0x00, 0xEA, 0xEA] if world.retro[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 digging_game_rng = random.randint(1, 30) # set rng for digging game rom.write_byte(0x180020, digging_game_rng) rom.write_byte(0xEFD95, digging_game_rng)