From 9233bedb5697af1c9419bad3ed2b2a113ea9c159 Mon Sep 17 00:00:00 2001 From: GreenestBeen Date: Sat, 16 May 2026 21:12:32 -0700 Subject: [PATCH 1/7] ravioli ravioli fix me the buggioli --- archipelago/FillSettings.py | 27 ++++++++++++++----------- archipelago/Logic.py | 27 ++----------------------- archipelago/Options.py | 40 +++++++++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/archipelago/FillSettings.py b/archipelago/FillSettings.py index 1e6f5e94e..6e253860f 100644 --- a/archipelago/FillSettings.py +++ b/archipelago/FillSettings.py @@ -362,19 +362,22 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None settings_dict["galleon_water"] = GalleonWaterSetting.vanilla settings_dict["no_consumable_upgrades"] = options.remove_bait_potions.value +def generate_blocker(option_value: String, random: Random): + """Calculate bounds of wincon value.""" + upper_bound = 201 if option_value == "random" else int(option_value.split("-")[1])) + 1 + lower_bound = 0 if option_value == "random" else int(option_value.split("-")[0]) + return random.randrange(lower_bound, upper_bound) -def apply_blocker_settings(settings_dict: dict, options) -> None: + +def apply_blocker_settings(settings_dict: dict, options, random_obj) -> None: """Apply level blocker settings.""" - blocker_options = [ - options.level_blockers.value.get("level_1", 0), - options.level_blockers.value.get("level_2", 0), - options.level_blockers.value.get("level_3", 0), - options.level_blockers.value.get("level_4", 0), - options.level_blockers.value.get("level_5", 0), - options.level_blockers.value.get("level_6", 0), - options.level_blockers.value.get("level_7", 0), - options.level_blockers.value.get("level_8", 64), - ] + blocker_options = [0,0,0,0,0,0,0,0] + for blocker, amount in options.level_blockers.values: + blocker_number = int(blocker.removeprefix("level_")) - 1 + if amount == "random" or len(amount.split("-")) == 2: + blocker_options[blocker_number] = generate_blocker(amount, random_obj) + else: + blocker_options[blocker_number] = int(amount) # Blocker settings - prioritize chaos blockers, then randomization setting settings_dict["maximize_helm_blocker"] = options.maximize_level8_blocker.value @@ -866,7 +869,7 @@ def fillsettings(options, multiworld, random_obj): # Apply all setting categories apply_archipelago_settings(settings_dict, options, multiworld) - apply_blocker_settings(settings_dict, options) + apply_blocker_settings(settings_dict, options, random_obj) apply_item_randomization_settings(settings_dict, options) apply_hard_mode_settings(settings_dict, options) apply_kong_settings(settings_dict, options) diff --git a/archipelago/Logic.py b/archipelago/Logic.py index d585df6da..94368a5d2 100644 --- a/archipelago/Logic.py +++ b/archipelago/Logic.py @@ -1491,33 +1491,10 @@ def CoinDoorOpened(self): def CanFreeDiddy(self): """Check if the cage locking Diddy's vanilla location can be opened.""" - return self.spoiler.LocationList[Locations.DiddyKong].item == Items.NoItem or self.hasMoveSwitchsanity(Switches.JapesFreeKong) + return self.hasMoveSwitchsanity(Switches.JapesFreeKong) def CanOpenJapesGates(self): - """Check if we can pick up the item inside Diddy's cage, thus opening the gates in Japes.""" - caged_item_id = self.spoiler.LocationList[Locations.JapesDonkeyFreeDiddy].item - # If it's NoItem, then the gates are already open - if caged_item_id == Items.NoItem: - return True - # If we can't free Diddy, then we can't access the item so we can't reach the item - if not self.CanFreeDiddy(): - return False - # If we are the right kong, then we can always get the item - if self.IsKong(self.settings.diddy_freeing_kong): - return True - # If we aren't the right kong, we need free trade to be on - elif self.settings.free_trade_items: - # During the fill we can't assume this item is accessible quite yet - this could cause errors with placing items in the back of Japes - if caged_item_id is None: - return False - # If it's not a blueprint, free trade gets us the item - if ItemList[caged_item_id].type != Types.Blueprint: - return True - # But if it is a blueprint, we need to check blueprint access (which checks blueprint free trade) - else: - return self.BlueprintAccess(ItemList[caged_item_id]) - # If we failed to hit a successful condition, we failed to reach the caged item - return False + return self.CanFreeDiddy() def CanFreeTiny(self): """Check if kong at Tiny location can be freed.""" diff --git a/archipelago/Options.py b/archipelago/Options.py index 96493f854..716259c1c 100644 --- a/archipelago/Options.py +++ b/archipelago/Options.py @@ -115,7 +115,6 @@ def verify(self, world: type[World], player_name: str, plando_options: PlandoOpt accumulated_errors = [] for key, value in self.value.items(): - print(f"Checking {key}: {value}") max = self.max_values_dict[key] if isinstance(value, numbers.Integral): value = int(value) @@ -140,7 +139,6 @@ def verify(self, world: type[World], player_name: str, plando_options: PlandoOpt accumulated_errors.append(f"{key}: Upper edge of range {bound} is higher than maximum allowed value {max}") elif bound < self.min: accumulated_errors.append(f"{key}: Lower edge of range {bound} is lower than minimum allowed value {self.min}") - print("\n".join(accumulated_errors)) if accumulated_errors: raise OptionError("Found errors with option goal_quantity:\n" + "\n".join(accumulated_errors)) @@ -629,6 +627,7 @@ class LevelBlockers(OptionDict): min = 0 max = 201 + allowed_keys = ["level_1", "level_2", "level_3", "level_4", "level_5", "level_6", "level_7", "level_8"] default = { "level_1": 0, "level_2": 0, @@ -640,6 +639,43 @@ class LevelBlockers(OptionDict): "level_8": 64, } + def verify(self, world: type[World], player_name: str, plando_options: PlandoOptions) -> None: + """Verify B. Lockers""" + super(LevelBlockers, self).verify(world, player_name, plando_options) + + for key in self.value.keys(): + if key not in self.allowed_keys: + raise OptionError(f"{key} is not a valid key for level_blockers.") + + accumulated_errors = [] + + for key, value in self.value.items(): + if isinstance(value, numbers.Integral): + value = int(value) + if value > self.max: + accumulated_errors.append(f"{key}: {value} is higher than maximum allowed value {self.max}") + elif value < self.min: + accumulated_errors.append(f"{key}: {value} is lower than minimum allowed value {self.min}") + else: + if value == "random": + continue + split = value.split("-") + if len(split) != 2: + accumulated_errors.append(f'{key}: {value} is not an integer or range, nor is it "random".') + else: + for bound in split: + try: + bound = int(bound) + except (ValueError, TypeError): + accumulated_errors.append(f'{key}: {value} is not an integer or range, nor is it "random".') + continue + if bound > self.max: + accumulated_errors.append(f"{key}: Upper edge of range {bound} is higher than maximum allowed value {self.max}") + elif bound < self.min: + accumulated_errors.append(f"{key}: Lower edge of range {bound} is lower than minimum allowed value {self.min}") + if accumulated_errors: + raise OptionError("Found errors with option level_blockers:\n" + "\n".join(accumulated_errors)) + class BouldersInPool(Toggle): """Determines if throwing boulders/barrels spawn a check.""" From 60b078fc02d016b619f92e5683aecf65be15eb12 Mon Sep 17 00:00:00 2001 From: GreenestBeen Date: Sat, 16 May 2026 21:20:47 -0700 Subject: [PATCH 2/7] docstring --- archipelago/Logic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/archipelago/Logic.py b/archipelago/Logic.py index 94368a5d2..92790a41a 100644 --- a/archipelago/Logic.py +++ b/archipelago/Logic.py @@ -1494,6 +1494,7 @@ def CanFreeDiddy(self): return self.hasMoveSwitchsanity(Switches.JapesFreeKong) def CanOpenJapesGates(self): + """Check if we can pick up the item inside Diddy's cage, thus opening the gates in Japes.""" return self.CanFreeDiddy() def CanFreeTiny(self): From d60e3d77299b09744936244f49a57813b7ec3d24 Mon Sep 17 00:00:00 2001 From: GreenestBeen Date: Sun, 17 May 2026 19:09:02 -0700 Subject: [PATCH 3/7] fixing it up --- archipelago/FillSettings.py | 15 +++++++++------ archipelago/client/emu_loader.py | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/archipelago/FillSettings.py b/archipelago/FillSettings.py index 6e253860f..24b59b269 100644 --- a/archipelago/FillSettings.py +++ b/archipelago/FillSettings.py @@ -4,6 +4,8 @@ that was previously in the generate_early method. """ +from random import Random + from randomizer.Settings import Settings from randomizer.Enums.Settings import ( ActivateAllBananaports, @@ -362,9 +364,9 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None settings_dict["galleon_water"] = GalleonWaterSetting.vanilla settings_dict["no_consumable_upgrades"] = options.remove_bait_potions.value -def generate_blocker(option_value: String, random: Random): +def generate_blocker(option_value: str, random: Random): """Calculate bounds of wincon value.""" - upper_bound = 201 if option_value == "random" else int(option_value.split("-")[1])) + 1 + upper_bound = 201 if option_value == "random" else int(option_value.split("-")[1]) + 1 lower_bound = 0 if option_value == "random" else int(option_value.split("-")[0]) return random.randrange(lower_bound, upper_bound) @@ -372,12 +374,13 @@ def generate_blocker(option_value: String, random: Random): def apply_blocker_settings(settings_dict: dict, options, random_obj) -> None: """Apply level blocker settings.""" blocker_options = [0,0,0,0,0,0,0,0] - for blocker, amount in options.level_blockers.values: + for blocker, amount in options.level_blockers.value.items(): blocker_number = int(blocker.removeprefix("level_")) - 1 - if amount == "random" or len(amount.split("-")) == 2: - blocker_options[blocker_number] = generate_blocker(amount, random_obj) - else: + try: blocker_options[blocker_number] = int(amount) + except (TypeError, ValueError): + blocker_options[blocker_number] = generate_blocker(amount, random_obj) + # Blocker settings - prioritize chaos blockers, then randomization setting settings_dict["maximize_helm_blocker"] = options.maximize_level8_blocker.value diff --git a/archipelago/client/emu_loader.py b/archipelago/client/emu_loader.py index b1b0b6998..2fc56f4b7 100644 --- a/archipelago/client/emu_loader.py +++ b/archipelago/client/emu_loader.py @@ -786,7 +786,7 @@ def validate_rom(self) -> bool: EMULATOR_CONFIGS = { - Emulators.Project64_v4: EmulatorInfo(Emulators.Project64_v4, "Project64 4.0", "project64", False, None, False, 0xFDD00000, 0xFE1FFFFF), + Emulators.Project64_v4: EmulatorInfo(Emulators.Project64_v4, "Project64 4.0", "project64", False, None, False, 0xFDD00000, 0xFE1FFFFF, scan_memory_for_signature=True), Emulators.BizHawk: EmulatorInfo(Emulators.BizHawk, "Bizhawk", "emuhawk", True, "mupen64plus.dll", False, 0x5A000, 0x5658DF, linux_dll_name="libmupen64plus.so"), Emulators.RMG: EmulatorInfo(Emulators.RMG, "Rosalie's Mupen GUI", "rmg", True, "mupen64plus.dll", True, 0x29C15D8, 0x2FC15D8, extra_offset=0x80000000, linux_dll_name="libmupen64plus.so"), Emulators.Simple64: EmulatorInfo(Emulators.Simple64, "simple64", "simple64-gui", True, "libmupen64plus.dll", True, 0x1380000, 0x29C95D8, linux_dll_name="libmupen64plus.so"), @@ -799,7 +799,7 @@ def validate_rom(self) -> bool: Emulators.RetroArch: EmulatorInfo( Emulators.RetroArch, "RetroArch", "retroarch", True, "mupen64plus_next_libretro.dll", True, 0, 0xFFFFFF, range_step=4, linux_dll_name="mupen64plus_next_libretro.so" ), - Emulators.Project64: EmulatorInfo(Emulators.Project64, "Project64", "project64", False, None, False, 0xDFD00000, 0xE01FFFFF), + Emulators.Project64: EmulatorInfo(Emulators.Project64, "Project64", "project64", False, None, False, 0xDFD00000, 0xE01FFFFF, scan_memory_for_signature=True), Emulators.Gopher64: EmulatorInfo(Emulators.Gopher64, "Gopher64", "gopher64", False, None, False, 0, 0, scan_memory_for_signature=True), Emulators.Ares: EmulatorInfo(Emulators.Ares, "ares", "ares", False, None, False, 0, 0, scan_memory_for_signature=True, signature_alignment=0x1000), } From 59fc3511c595429471edb16fe198a4f0114a7654 Mon Sep 17 00:00:00 2001 From: GreenestBeen Date: Sun, 17 May 2026 20:31:48 -0700 Subject: [PATCH 4/7] ver bump --- archipelago.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archipelago.json b/archipelago.json index 390569551..754d957a5 100644 --- a/archipelago.json +++ b/archipelago.json @@ -1,6 +1,6 @@ { "minimum_ap_version": "0.6.5", - "world_version": "1.5.5", + "world_version": "1.5.6", "authors": ["2dos", "AlmostSeagull", "Ballaam", "Green Bean", "Killklli", "Lrauq", "PoryGone", "Umed"], "version": 7, "compatible_version": 7, From 213a02532f63a00cab7b8b617b5abb32b310147d Mon Sep 17 00:00:00 2001 From: GreenestBeen Date: Sun, 17 May 2026 21:09:18 -0700 Subject: [PATCH 5/7] respect blocker max --- archipelago/FillSettings.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/archipelago/FillSettings.py b/archipelago/FillSettings.py index 24b59b269..de48bc72c 100644 --- a/archipelago/FillSettings.py +++ b/archipelago/FillSettings.py @@ -364,9 +364,9 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None settings_dict["galleon_water"] = GalleonWaterSetting.vanilla settings_dict["no_consumable_upgrades"] = options.remove_bait_potions.value -def generate_blocker(option_value: str, random: Random): - """Calculate bounds of wincon value.""" - upper_bound = 201 if option_value == "random" else int(option_value.split("-")[1]) + 1 +def generate_blocker(option_value: str, blocker_max: int, random: Random): + """Randomize a B. Locker value, either within a range or up to the maximum.""" + upper_bound = blocker_max if option_value == "random" else int(option_value.split("-")[1]) + 1 lower_bound = 0 if option_value == "random" else int(option_value.split("-")[0]) return random.randrange(lower_bound, upper_bound) @@ -379,7 +379,7 @@ def apply_blocker_settings(settings_dict: dict, options, random_obj) -> None: try: blocker_options[blocker_number] = int(amount) except (TypeError, ValueError): - blocker_options[blocker_number] = generate_blocker(amount, random_obj) + blocker_options[blocker_number] = generate_blocker(amount, options.blocker_max.value, random_obj) # Blocker settings - prioritize chaos blockers, then randomization setting From f45d17746c42ccc12897edfb80323bded7eba3f9 Mon Sep 17 00:00:00 2001 From: GreenestBeen Date: Sun, 17 May 2026 21:14:18 -0700 Subject: [PATCH 6/7] lint --- archipelago/FillSettings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archipelago/FillSettings.py b/archipelago/FillSettings.py index de48bc72c..148a7a024 100644 --- a/archipelago/FillSettings.py +++ b/archipelago/FillSettings.py @@ -364,6 +364,7 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None settings_dict["galleon_water"] = GalleonWaterSetting.vanilla settings_dict["no_consumable_upgrades"] = options.remove_bait_potions.value + def generate_blocker(option_value: str, blocker_max: int, random: Random): """Randomize a B. Locker value, either within a range or up to the maximum.""" upper_bound = blocker_max if option_value == "random" else int(option_value.split("-")[1]) + 1 @@ -373,14 +374,13 @@ def generate_blocker(option_value: str, blocker_max: int, random: Random): def apply_blocker_settings(settings_dict: dict, options, random_obj) -> None: """Apply level blocker settings.""" - blocker_options = [0,0,0,0,0,0,0,0] + blocker_options = [0, 0, 0, 0, 0, 0, 0, 0] for blocker, amount in options.level_blockers.value.items(): blocker_number = int(blocker.removeprefix("level_")) - 1 try: blocker_options[blocker_number] = int(amount) except (TypeError, ValueError): blocker_options[blocker_number] = generate_blocker(amount, options.blocker_max.value, random_obj) - # Blocker settings - prioritize chaos blockers, then randomization setting settings_dict["maximize_helm_blocker"] = options.maximize_level8_blocker.value From ef535c6bb0558a36d6456ba92fd9a330b7512a0d Mon Sep 17 00:00:00 2001 From: GreenestBeen Date: Mon, 18 May 2026 18:55:10 -0700 Subject: [PATCH 7/7] fine, I will end my doc with a period. --- archipelago/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archipelago/Options.py b/archipelago/Options.py index 716259c1c..0355625d2 100644 --- a/archipelago/Options.py +++ b/archipelago/Options.py @@ -640,7 +640,7 @@ class LevelBlockers(OptionDict): } def verify(self, world: type[World], player_name: str, plando_options: PlandoOptions) -> None: - """Verify B. Lockers""" + """Verify B. Lockers.""" super(LevelBlockers, self).verify(world, player_name, plando_options) for key in self.value.keys():