Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion archipelago.json
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
30 changes: 18 additions & 12 deletions archipelago/FillSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -363,18 +365,22 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None
settings_dict["no_consumable_upgrades"] = options.remove_bait_potions.value


def apply_blocker_settings(settings_dict: dict, options) -> None:
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)


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.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
Expand Down Expand Up @@ -866,7 +872,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)
Expand Down
26 changes: 2 additions & 24 deletions archipelago/Logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1491,33 +1491,11 @@ 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."""
Expand Down
40 changes: 38 additions & 2 deletions archipelago/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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))

Expand Down Expand Up @@ -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,
Expand All @@ -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."""
Expand Down
4 changes: 2 additions & 2 deletions archipelago/client/emu_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand All @@ -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),
}
Expand Down
Loading