From d5e69b28f294ff148e7b197a8de617d6d364c524 Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 14 Apr 2023 15:23:38 -0600 Subject: [PATCH 1/5] Fix for Non-ER Inverted Experimental (Aga and GT weren't logically swapped) Fix for customizer setting crystals to 0 for either GT/Ganon --- Main.py | 2 +- RELEASENOTES.md | 3 +++ source/classes/CustomSettings.py | 5 +++-- source/overworld/EntranceShuffle2.py | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Main.py b/Main.py index 62d519ed..107b0694 100644 --- a/Main.py +++ b/Main.py @@ -34,7 +34,7 @@ from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings -version_number = '1.2.0.16' +version_number = '1.2.0.17' version_branch = '-u' __version__ = f'{version_number}{version_branch}' diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a84d0551..4f622e60 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -109,6 +109,9 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes +* 1.2.0.17u + * Fix for Non-ER Inverted Experimental (Aga and GT weren't logically swapped) + * Fix for customizer setting crystals to 0 for either GT/Ganon * 1.2.0.16u * Fix for partial key logic on vanilla Mire * Fix for Kholdstare Shell collision when at Lanmo 2 diff --git a/source/classes/CustomSettings.py b/source/classes/CustomSettings.py index ba5bd705..deb9f4d2 100644 --- a/source/classes/CustomSettings.py +++ b/source/classes/CustomSettings.py @@ -2,6 +2,7 @@ import os import urllib.request import urllib.parse import yaml +from typing import Any from yaml.representer import Representer from collections import defaultdict from pathlib import Path @@ -46,8 +47,8 @@ class CustomSettings(object): return meta['players'] def adjust_args(self, args): - def get_setting(value, default): - if value: + def get_setting(value: Any, default): + if value or value == 0: if isinstance(value, dict): return random.choices(list(value.keys()), list(value.values()), k=1)[0] else: diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 572f3bb3..61f0a80d 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -56,6 +56,8 @@ def link_entrances_new(world, player): one_way_map.update(drop_map) one_way_map.update(single_entrance_map) if avail_pool.inverted: + default_map['Ganons Tower'] = 'Agahnims Tower Exit' + default_map['Agahnims Tower'] = 'Ganons Tower Exit' default_map['Old Man Cave (West)'] = 'Bumper Cave Exit (Bottom)' default_map['Death Mountain Return Cave (West)'] = 'Bumper Cave Exit (Top)' default_map['Bumper Cave (Bottom)'] = 'Old Man Cave Exit (West)' @@ -64,8 +66,6 @@ def link_entrances_new(world, player): default_map['Old Man Cave (East)'] = 'Death Mountain Return Cave Exit (West)' one_way_map['Bumper Cave (Top)'] = 'Dark Death Mountain Healer Fairy' del default_map['Bumper Cave (Top)'] - del one_way_map['Big Bomb Shop'] - one_way_map['Inverted Big Bomb Shop'] = 'Inverted Big Bomb Shop' avail_pool.default_map = default_map avail_pool.one_way_map = one_way_map From 0ab54def8b9ac8908b3627df92c01a69d1dcfe09 Mon Sep 17 00:00:00 2001 From: aerinon Date: Thu, 8 Jun 2023 10:25:05 -0600 Subject: [PATCH 2/5] Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead. --- Fill.py | 6 +++++- RELEASENOTES.md | 1 + source/item/FillUtil.py | 12 +----------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Fill.py b/Fill.py index 9acf7d45..f6582a16 100644 --- a/Fill.py +++ b/Fill.py @@ -279,6 +279,10 @@ def recovery_placement(item_to_place, locations, world, state, base_state, itemp if spot_to_fill: return spot_to_fill return None + # explicitly fail these cases + elif world.algorithm in ['dungeon_only', 'major_only']: + raise FillError(f'Rare placement for {world.algorithm} detected. {item_to_place} unable to be placed.' + f' Try a different seed') else: other_locations = [x for x in locations if x not in attempted] for location in other_locations: @@ -419,7 +423,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None else: max_trash = gt_count scaled_trash = math.floor(max_trash * scale_factor) - if world.goal[player] in ['triforcehunt', 'trinity', 'ganonhunt']: + if world.goal[player] in ['triforcehunt', 'trinity', 'ganonhunt'] or world.algorithm == 'dungeon_only': gftower_trash_count = random.randint(scaled_trash, max_trash) else: gftower_trash_count = random.randint(0, scaled_trash) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4f622e60..33b0a50e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -110,6 +110,7 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes * 1.2.0.17u + * Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead * Fix for Non-ER Inverted Experimental (Aga and GT weren't logically swapped) * Fix for customizer setting crystals to 0 for either GT/Ganon * 1.2.0.16u diff --git a/source/item/FillUtil.py b/source/item/FillUtil.py index 58558263..6a055584 100644 --- a/source/item/FillUtil.py +++ b/source/item/FillUtil.py @@ -151,9 +151,6 @@ def create_item_pool_config(world): config.item_pool[player] = determine_major_items(world, player) config.location_groups[0].locations = set(groups.locations) config.reserved_locations[player].update(groups.locations) - backup = (mode_grouping['Heart Pieces'] + mode_grouping['Dungeon Trash'] + mode_grouping['Shops'] - + mode_grouping['Overworld Trash'] + mode_grouping['GT Trash'] + mode_grouping['RetroShops']) - config.location_groups[1].locations = set(backup) elif world.algorithm == 'dungeon_only': config.location_groups = [ LocationGroup('Dungeons'), @@ -171,9 +168,6 @@ def create_item_pool_config(world): for player in range(1, world.players + 1): config.item_pool[player] = determine_major_items(world, player) config.location_groups[0].locations = set(dungeon_set) - backup = (mode_grouping['Heart Pieces'] + mode_grouping['Overworld Major'] - + mode_grouping['Overworld Trash'] + mode_grouping['Shops'] + mode_grouping['RetroShops']) - config.location_groups[1].locations = set(backup) def district_item_pool_config(world): @@ -419,11 +413,7 @@ def filter_locations(item_to_place, locations, world, vanilla_skip=False, potion if item_to_place.name in config.item_pool[item_to_place.player]: restricted = config.location_groups[0].locations filtered = [l for l in locations if l.name in restricted] - if len(filtered) == 0: - restricted = config.location_groups[1].locations - filtered = [l for l in locations if l.name in restricted] - # bias toward certain location in overflow? (thinking about this for major_bias) - return filtered if len(filtered) > 0 else locations + return filtered if world.algorithm == 'district': config = world.item_pool_config if ((isinstance(item_to_place,str) and item_to_place == 'Placeholder') From 8955e8b26fce4ead88c8fa5da936bc83b82ea929 Mon Sep 17 00:00:00 2001 From: Cody Bailey Date: Wed, 14 Jun 2023 15:31:49 -0400 Subject: [PATCH 3/5] Fix JSON metadata --- BaseClasses.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BaseClasses.py b/BaseClasses.py index a7170779..af1436eb 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -2499,6 +2499,7 @@ class Spoiler(object): 'pseudoboots': self.world.pseudoboots, 'triforcegoal': self.world.treasure_hunt_count, 'triforcepool': self.world.treasure_hunt_total, + 'race': self.world.settings.world_rep['meta']['race'], 'code': {p: Settings.make_code(self.world, p) for p in range(1, self.world.players + 1)} } @@ -2601,6 +2602,7 @@ class Spoiler(object): self.set_lobby(portal.name, portal.door.name, player) def to_json(self): + self.parse_meta() self.parse_data() out = OrderedDict() out['Entrances'] = list(self.entrances.values()) From 5da0836d9f14edae5a30b1eea6b27179331be95b Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 16 Jun 2023 09:15:06 -0600 Subject: [PATCH 4/5] Fixed logic with mirror in west dark world --- EntranceShuffle.py | 2 ++ OverworldShuffle.py | 2 +- Regions.py | 3 ++- Rules.py | 2 ++ source/overworld/EntranceShuffle2.py | 2 ++ 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/EntranceShuffle.py b/EntranceShuffle.py index 2e5162e4..3a44b677 100644 --- a/EntranceShuffle.py +++ b/EntranceShuffle.py @@ -2169,6 +2169,8 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('West Dark World Gap', 'West Dark World'), ('Broken Bridge Pass (Top)', 'East Dark World'), ('Broken Bridge Pass (Bottom)', 'Northeast Dark World'), + ('Dark Graveyard Bush (South)', 'Dark Graveyard North'), + ('Dark Graveyard Bush (North)', 'West Dark World'), ('Peg Area Rocks (Left)', 'Hammer Peg Area'), ('Peg Area Rocks (Right)', 'West Dark World'), ('Village of Outcasts Heavy Rock', 'West Dark World'), diff --git a/OverworldShuffle.py b/OverworldShuffle.py index 099d5a9c..3793f272 100644 --- a/OverworldShuffle.py +++ b/OverworldShuffle.py @@ -48,7 +48,7 @@ mirror_connections = { 'East Dark Death Mountain (Bushes)': ['Fairy Ascension Plateau'], 'East Dark Death Mountain (Bottom)': ['East Death Mountain (Bottom)'], - 'West Dark World': ['Graveyard Ledge', 'Kings Grave Area'], + 'Dark Graveyard North': ['Graveyard Ledge', 'Kings Grave Area'], 'Bumper Cave Ledge': ['Death Mountain Return Ledge'], 'Bumper Cave Entrance': ['Death Mountain Entrance'], diff --git a/Regions.py b/Regions.py index 7b0e2535..7546e012 100644 --- a/Regions.py +++ b/Regions.py @@ -85,7 +85,8 @@ def create_regions(world, player): create_dw_region(player, 'West Dark World', ['Frog'], ['Dark Lumberjack Shop', 'Fortune Teller (Dark)', 'Dark Sanctuary Hint', 'Chest Game', 'Thieves Town', 'C-Shaped House', 'Brewery', 'Red Shield Shop', 'Skull Woods Forest', 'Bumper Cave Entrance Rock', 'West Dark World Water Drop', 'Grassy Lawn Pegs (Bottom)', 'Peg Area Rocks (Left)', 'Village of Outcasts Drop', - 'West Dark World Teleporter', 'WDW Flute']), + 'West Dark World Teleporter', 'WDW Flute', 'Dark Graveyard Bush (South)']), + create_dw_region(player, 'Dark Graveyard North', None, ['Dark Graveyard Bush (North)']), create_dw_region(player, 'Skull Woods Forest', None, ['Skull Woods First Section Hole (East)', 'Skull Woods First Section Hole (West)', 'Skull Woods First Section Hole (North)', 'Skull Woods First Section Door', 'Skull Woods Second Section Door (East)']), create_dw_region(player, 'Skull Woods Forest (West)', None, ['Skull Woods Second Section Hole', 'Skull Woods Second Section Door (West)', 'Skull Woods Final Section'], 'a deep, dark forest'), diff --git a/Rules.py b/Rules.py index fc608ec2..80392396 100644 --- a/Rules.py +++ b/Rules.py @@ -965,6 +965,8 @@ def ow_bunny_rules(world, player): add_bunny_rule(world.get_entrance('East Dark Death Mountain Bushes', player), player) add_bunny_rule(world.get_entrance('Bumper Cave Entrance Rock', player), player) + add_bunny_rule(world.get_entrance('Dark Graveyard Bush (South)', player), player) + add_bunny_rule(world.get_entrance('Dark Graveyard Bush (North)', player), player) add_bunny_rule(world.get_entrance('Dark Witch Rock (North)', player), player) add_bunny_rule(world.get_entrance('Dark Witch Rock (South)', player), player) add_bunny_rule(world.get_entrance('Grassy Lawn Pegs (Bottom)', player), player) diff --git a/source/overworld/EntranceShuffle2.py b/source/overworld/EntranceShuffle2.py index 61f0a80d..6afc7b9e 100644 --- a/source/overworld/EntranceShuffle2.py +++ b/source/overworld/EntranceShuffle2.py @@ -1962,6 +1962,8 @@ mandatory_connections = [('Links House S&Q', 'Links House'), ('Grassy Lawn Pegs (Top)', 'West Dark World'), ('Grassy Lawn Pegs (Bottom)', 'Dark Grassy Lawn'), ('West Dark World Gap', 'West Dark World'), + ('Dark Graveyard Bush (South)', 'Dark Graveyard North'), + ('Dark Graveyard Bush (North)', 'West Dark World'), ('Broken Bridge Pass (Top)', 'East Dark World'), ('Broken Bridge Pass (Bottom)', 'Northeast Dark World'), ('Peg Area Rocks (Left)', 'Hammer Peg Area'), From 8afdbaca25724942f0d22d0ad9c886341bdce04c Mon Sep 17 00:00:00 2001 From: aerinon Date: Fri, 16 Jun 2023 09:22:08 -0600 Subject: [PATCH 5/5] Update release notes --- RELEASENOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 33b0a50e..e3d09589 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -110,6 +110,7 @@ These are now independent of retro mode and have three options: None, Random, an # Bug Fixes and Notes * 1.2.0.17u + * Fixed logic bug that allowed Pearl to be behind Graveyard Cave or King's Tomb entrances with only Mirror and West Dark World access (cross world shuffles only) * Removed backup locations for Dungeon Only and Major Only algorithms. If item cannot be placed in the appropriate location, the seed will fail to generate instead * Fix for Non-ER Inverted Experimental (Aga and GT weren't logically swapped) * Fix for customizer setting crystals to 0 for either GT/Ganon