From 9fbfa337d7ec393d09306869de701baa3a787c82 Mon Sep 17 00:00:00 2001 From: Catobat <69204835+Catobat@users.noreply.github.com> Date: Sat, 29 May 2021 16:52:22 +0200 Subject: [PATCH 1/5] Fix missing "[player]"s --- PotShuffle.py | 2 +- Rom.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PotShuffle.py b/PotShuffle.py index 0f4ca4d8..e8e6d3ce 100644 --- a/PotShuffle.py +++ b/PotShuffle.py @@ -295,7 +295,7 @@ def shuffle_pots(world, player): elif old_pot.item == PotItem.Switch: available_pots = (pot for pot in new_pots if (pot.room == old_pot.room or pot.room in movable_switch_rooms[old_pot.room]) and not (pot.flags & PotFlags.NoSwitch)) elif old_pot.item == PotItem.Key: - if world.doorShuffle[player] == 'vanilla' and not world.retro[player] and not world.keydropshuffle[player] and world.logic != 'nologic': + if world.doorShuffle[player] == 'vanilla' and not world.retro[player] and not world.keydropshuffle[player] and world.logic[player] != 'nologic': available_pots = (pot for pot in new_pots if pot.room not in invalid_key_rooms) else: available_pots = new_pots diff --git a/Rom.py b/Rom.py index 3dab4c8e..9d18f5a4 100644 --- a/Rom.py +++ b/Rom.py @@ -970,7 +970,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): #Work around for json patch ordering issues - write bow limit separately so that it is replaced in the patch rom.write_bytes(0x180098, [difficulty.progressive_bow_limit, overflow_replacement]) - if difficulty.progressive_bow_limit < 2 and world.swords == 'swordless': + if difficulty.progressive_bow_limit < 2 and world.swords[player] == 'swordless': rom.write_bytes(0x180098, [2, overflow_replacement]) # set up game internal RNG seed From 4243494b66a4cf48cbdc84232fe48ee0bc9a96a2 Mon Sep 17 00:00:00 2001 From: Catobat <69204835+Catobat@users.noreply.github.com> Date: Sat, 29 May 2021 16:57:34 +0200 Subject: [PATCH 2/5] Write Pot Shuffle setting to spoiler --- BaseClasses.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BaseClasses.py b/BaseClasses.py index 411e9438..ba685ac2 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2032,6 +2032,7 @@ class Spoiler(object): 'enemy_shuffle': self.world.enemy_shuffle, 'enemy_health': self.world.enemy_health, 'enemy_damage': self.world.enemy_damage, + 'potshuffle': self.world.potshuffle, 'players': self.world.players, 'teams': self.world.teams, 'experimental': self.world.experimental, @@ -2104,6 +2105,7 @@ class Spoiler(object): outfile.write('Enemy shuffle: %s\n' % self.metadata['enemy_shuffle'][player]) outfile.write('Enemy health: %s\n' % self.metadata['enemy_health'][player]) outfile.write('Enemy damage: %s\n' % self.metadata['enemy_damage'][player]) + outfile.write('Pot shuffle: %s\n' % ('Yes' if self.metadata['potshuffle'][player] else 'No')) outfile.write('Hints: %s\n' % ('Yes' if self.metadata['hints'][player] else 'No')) outfile.write('Experimental: %s\n' % ('Yes' if self.metadata['experimental'][player] else 'No')) outfile.write('Key Drops shuffled: %s\n' % ('Yes' if self.metadata['keydropshuffle'][player] else 'No')) From b071191e9bf2740905a011b29af924d5d8facd48 Mon Sep 17 00:00:00 2001 From: Catobat <69204835+Catobat@users.noreply.github.com> Date: Sat, 29 May 2021 17:02:29 +0200 Subject: [PATCH 3/5] Remove unreachable code --- Rom.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Rom.py b/Rom.py index 9d18f5a4..128eeeac 100644 --- a/Rom.py +++ b/Rom.py @@ -1314,9 +1314,6 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): if item.name != 'Piece of Heart' or equip[0x36B] == 0: equip[0x36C] = min(equip[0x36C] + 0x08, 0xA0) equip[0x36D] = min(equip[0x36D] + 0x08, 0xA0) - elif item.name == 'Pegasus Boots': - rom.write_byte(0x183015, 0x01) - ability_flags |= 0b00000100 else: raise RuntimeError(f'Unsupported item in starting equipment: {item.name}') From 87c4c0811aa3464d85809a3f5dc15a4b829fe9be Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 1 Jun 2021 09:33:15 -0600 Subject: [PATCH 4/5] Inverted fix for insanity --- EntranceShuffle.py | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index b32fec84..e78b35b8 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -1673,20 +1673,18 @@ def link_inverted_entrances(world, player): elif world.shuffle[player] == 'insanity': # beware ye who enter here - entrances = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + Inverted_Old_Man_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Entrance (South)'] entrances_must_exits = Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit doors = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Secret Entrance Stairs'] + Inverted_Old_Man_Entrances +\ Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] +\ Inverted_LW_Single_Cave_Doors + Inverted_DW_Single_Cave_Doors + ['Desert Palace Entrance (West)', 'Desert Palace Entrance (North)'] + exit_pool = list(doors) # randomize which desert ledge door is a must-exit if random.randint(0, 1) == 0: entrances_must_exits.append('Desert Palace Entrance (North)') - entrances.append('Desert Palace Entrance (West)') else: entrances_must_exits.append('Desert Palace Entrance (West)') - entrances.append('Desert Palace Entrance (North)') # TODO: there are other possible entrances we could support here by way of exiting from a connector, # and rentering to find bomb shop. However appended list here is all those that we currently have @@ -1716,7 +1714,6 @@ def link_inverted_entrances(world, player): hole_entrances.append('Hyrule Castle Secret Entrance Drop') hole_targets.append('Hyrule Castle Secret Entrance') - entrances.append('Hyrule Castle Secret Entrance Stairs') caves.append('Hyrule Castle Secret Entrance Exit') if not world.shuffle_ganon: @@ -1724,15 +1721,15 @@ def link_inverted_entrances(world, player): connect_two_way(world, 'Inverted Pyramid Entrance', 'Pyramid Exit', player) connect_entrance(world, 'Inverted Pyramid Hole', 'Pyramid', player) else: - entrances.append('Inverted Ganons Tower') caves.extend(['Inverted Ganons Tower Exit', 'Pyramid Exit']) hole_entrances.append('Inverted Pyramid Hole') hole_targets.append('Pyramid') doors.extend(['Inverted Ganons Tower', 'Inverted Pyramid Entrance']) + exit_pool.extend(['Inverted Ganons Tower', 'Inverted Pyramid Entrance']) random.shuffle(hole_entrances) random.shuffle(hole_targets) - random.shuffle(entrances) + random.shuffle(exit_pool) # fill up holes for hole in hole_entrances: @@ -1745,18 +1742,15 @@ def link_inverted_entrances(world, player): if not world.shufflelinks[player]: links_house = 'Inverted Links House' else: - links_house_doors = [i for i in entrances + entrances_must_exits if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] + links_house_doors = [i for i in doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors] links_house = random.choice(links_house_doors) connect_two_way(world, links_house, 'Inverted Links House Exit', player) - if links_house in entrances: - entrances.remove(links_house) - elif links_house in entrances_must_exits: - entrances_must_exits.remove(links_house) doors.remove(links_house) + exit_pool.remove(links_house) - sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in entrances] + sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in exit_pool] sanc_door = random.choice(sanc_doors) - entrances.remove(sanc_door) + exit_pool.remove(sanc_door) doors.remove(sanc_door) connect_entrance(world, sanc_door, 'Inverted Dark Sanctuary', player) world.get_entrance('Inverted Dark Sanctuary Exit', player).connect(world.get_entrance(sanc_door, player).parent_region) @@ -1778,7 +1772,7 @@ def link_inverted_entrances(world, player): cavelist.remove(candidate) return candidate - def connect_reachable_exit(entrance, caves, doors): + def connect_reachable_exit(entrance, caves, doors, exit_pool): cave = extract_reachable_exit(caves) exit = cave[-1] @@ -1786,18 +1780,19 @@ def link_inverted_entrances(world, player): connect_exit(world, exit, entrance, player) connect_entrance(world, doors.pop(), exit, player) # rest of cave now is forced to be in this world + exit_pool.remove(entrance) caves.append(cave) # connect mandatory exits for entrance in entrances_must_exits: - connect_reachable_exit(entrance, caves, doors) + connect_reachable_exit(entrance, caves, doors, exit_pool) # place old man, has limited options # exit has to come from specific set of doors, the entrance is free to move about - old_man_entrances = [entrance for entrance in old_man_entrances if entrance in entrances] + old_man_entrances = [entrance for entrance in old_man_entrances if entrance in exit_pool] random.shuffle(old_man_entrances) old_man_exit = old_man_entrances.pop() - entrances.remove(old_man_exit) + exit_pool.remove(old_man_exit) connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit, player) connect_entrance(world, doors.pop(), 'Old Man Cave Exit (East)', player) @@ -1809,6 +1804,7 @@ def link_inverted_entrances(world, player): blacksmith_hut = blacksmith_doors.pop() connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player) doors.remove(blacksmith_hut) + exit_pool.remove(blacksmith_hut) # place dam and pyramid fairy, have limited options bomb_shop_doors = [door for door in bomb_shop_doors if door in doors] @@ -1816,6 +1812,7 @@ def link_inverted_entrances(world, player): bomb_shop = bomb_shop_doors.pop() connect_entrance(world, bomb_shop, 'Inverted Big Bomb Shop', player) doors.remove(bomb_shop) + exit_pool.remove(bomb_shop) # handle remaining caves for cave in caves: @@ -1823,7 +1820,7 @@ def link_inverted_entrances(world, player): cave = (cave,) for exit in cave: - connect_exit(world, exit, entrances.pop(), player) + connect_exit(world, exit, exit_pool.pop(), player) connect_entrance(world, doors.pop(), exit, player) # place remaining doors From e0479922ccb11fe6eb3f76961b767489e0bafb24 Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 1 Jun 2021 14:52:23 -0600 Subject: [PATCH 5/5] Msu minor fix Bosses simple fix Boss shuffle mystery fix --- Bosses.py | 2 +- Main.py | 2 +- Mystery.py | 6 +++--- RELEASENOTES.md | 6 ++++++ Rom.py | 2 +- data/base2current.bps | Bin 133024 -> 133035 bytes 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Bosses.py b/Bosses.py index c1f311ef..ebf8b4dd 100644 --- a/Bosses.py +++ b/Bosses.py @@ -174,7 +174,7 @@ def place_bosses(world, player): boss_locations.remove(['Ice Palace', None]) placeable_bosses.remove('Kholdstare') - if world.boss_shuffle[player] == "basic": # vanilla bosses shuffled + if world.boss_shuffle[player] == "simple": # vanilla bosses shuffled bosses = placeable_bosses + ['Armos Knights', 'Lanmolas', 'Moldorm'] else: # all bosses present, the three duplicates chosen at random bosses = all_bosses + [random.choice(placeable_bosses) for _ in range(3)] diff --git a/Main.py b/Main.py index a64e317f..919ba67f 100644 --- a/Main.py +++ b/Main.py @@ -27,7 +27,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops from Utils import output_path, parse_player_names -__version__ = '0.4.0.4-u' +__version__ = '0.4.0.5-u' class EnemizerError(RuntimeError): diff --git a/Mystery.py b/Mystery.py index e9d438de..271e8194 100644 --- a/Mystery.py +++ b/Mystery.py @@ -187,9 +187,9 @@ def roll_settings(weights): ret.item_functionality = get_choice('item_functionality') - old_style_bosses = {'simple': 'basic', - 'full': 'normal', - 'random': 'chaos'} + old_style_bosses = {'basic': 'simple', + 'normal': 'full', + 'chaos': 'random'} boss_choice = get_choice('boss_shuffle') if boss_choice in old_style_bosses.keys(): boss_choice = old_style_bosses[boss_choice] diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 6bbab2ce..5f392a15 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -10,6 +10,12 @@ Thanks to qadan, cheuer, & compiling # Bug Fixes and Notes. +* 0.4.0.5 + * Insanity - less restrictions on exiting (all modes) + * Fix for simple bosses shuffle + * Fix for boss shuffle from Mystery.py + * Minor msu fade out bug (thanks codemann8) + * Other bug fixes (thanks Catobat) * 0.4.0.4 * Added --shufflelinks option * Moved spawning as a bunny indoors to experimental diff --git a/Rom.py b/Rom.py index 3dab4c8e..02310146 100644 --- a/Rom.py +++ b/Rom.py @@ -27,7 +27,7 @@ from EntranceShuffle import door_addresses, exit_ids JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '32b289d8294deba1603c75bb1321d3da' +RANDOMIZERBASEHASH = 'f8f1b851b091d50af2b87283ea79ed90' class JsonRom(object): diff --git a/data/base2current.bps b/data/base2current.bps index abda4b8c6894e42f2fc35fa6a2747920bfa7c6b9..97c703b32d372808a204f8aa3af275183f0d3004 100644 GIT binary patch delta 1486 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 TzwtRD0wtQ={^LL2G|T@3cS~B+