Third round of Treble code reviews.

This commit is contained in:
massimilianodelliubaldini
2025-04-06 13:47:47 -04:00
parent 960f73cb8b
commit c677f6dfe7
19 changed files with 191 additions and 177 deletions

View File

@@ -63,22 +63,22 @@ def create_regions(world: JakAndDaxterWorld):
menu.connect(orbs)
# Build all regions. Include their intra-connecting Rules, their Locations, and their Location access rules.
[gr] = GeyserRock.build_regions("Geyser Rock", world)
[sv] = SandoverVillage.build_regions("Sandover Village", world)
[fj, fjp] = ForbiddenJungle.build_regions("Forbidden Jungle", world)
[sb] = SentinelBeach.build_regions("Sentinel Beach", world)
[mi] = MistyIsland.build_regions("Misty Island", world)
[fc] = FireCanyon.build_regions("Fire Canyon", world)
[rv, rvp, rvc] = RockVillage.build_regions("Rock Village", world)
[pb] = PrecursorBasin.build_regions("Precursor Basin", world)
[lpc] = LostPrecursorCity.build_regions("Lost Precursor City", world)
[bs] = BoggySwamp.build_regions("Boggy Swamp", world)
[mp, mpr] = MountainPass.build_regions("Mountain Pass", world)
[vc] = VolcanicCrater.build_regions("Volcanic Crater", world)
[sc] = SpiderCave.build_regions("Spider Cave", world)
[sm] = SnowyMountain.build_regions("Snowy Mountain", world)
[lt] = LavaTube.build_regions("Lava Tube", world)
[gmc, fb, fd] = GolAndMaiasCitadel.build_regions("Gol and Maia's Citadel", world)
gr = GeyserRock.build_regions("Geyser Rock", world)
sv = SandoverVillage.build_regions("Sandover Village", world)
fj, fjp = ForbiddenJungle.build_regions("Forbidden Jungle", world)
sb = SentinelBeach.build_regions("Sentinel Beach", world)
mi = MistyIsland.build_regions("Misty Island", world)
fc = FireCanyon.build_regions("Fire Canyon", world)
rv, rvp, rvc = RockVillage.build_regions("Rock Village", world)
pb = PrecursorBasin.build_regions("Precursor Basin", world)
lpc = LostPrecursorCity.build_regions("Lost Precursor City", world)
bs = BoggySwamp.build_regions("Boggy Swamp", world)
mp, mpr = MountainPass.build_regions("Mountain Pass", world)
vc = VolcanicCrater.build_regions("Volcanic Crater", world)
sc = SpiderCave.build_regions("Spider Cave", world)
sm = SnowyMountain.build_regions("Snowy Mountain", world)
lt = LavaTube.build_regions("Lava Tube", world)
gmc, fb, fd = GolAndMaiasCitadel.build_regions("Gol and Maia's Citadel", world)
# Configurable counts of cells for connector levels.
fc_count = options.fire_canyon_cell_count.value

View File

@@ -1,5 +1,5 @@
import typing
from BaseClasses import MultiWorld, CollectionState
from BaseClasses import CollectionState
from Options import OptionError
from . import JakAndDaxterWorld
from .Options import (EnableOrbsanity,
@@ -13,7 +13,6 @@ from .Options import (EnableOrbsanity,
from .locs import CellLocations as Cells
from .Locations import location_table
from .Levels import level_table
from .regs.RegionBase import JakAndDaxterRegion
def set_orb_trade_rule(world: JakAndDaxterWorld):
@@ -22,13 +21,13 @@ def set_orb_trade_rule(world: JakAndDaxterWorld):
if options.enable_orbsanity == EnableOrbsanity.option_off:
world.can_trade = lambda state, required_orbs, required_previous_trade: (
can_trade_vanilla(state, player, required_orbs, required_previous_trade))
can_trade_vanilla(state, player, world, required_orbs, required_previous_trade))
else:
world.can_trade = lambda state, required_orbs, required_previous_trade: (
can_trade_orbsanity(state, player, required_orbs, required_previous_trade))
can_trade_orbsanity(state, player, world, required_orbs, required_previous_trade))
def recalculate_reachable_orbs(state: CollectionState, player: int) -> None:
def recalculate_reachable_orbs(state: CollectionState, player: int, world: JakAndDaxterWorld) -> None:
if not state.prog_items[player]["Reachable Orbs Fresh"]:
@@ -36,34 +35,33 @@ def recalculate_reachable_orbs(state: CollectionState, player: int) -> None:
# when a specific bundle of orbs in one level may unlock access to another.
for level in level_table:
state.prog_items[player][f"{level} Reachable Orbs".strip()] = (
count_reachable_orbs_level(state, player, state.multiworld, level))
count_reachable_orbs_level(state, world, level))
# Also recalculate the global count, still used even when Orbsanity is Off.
state.prog_items[player]["Reachable Orbs"] = count_reachable_orbs_global(state, player, state.multiworld)
state.prog_items[player]["Reachable Orbs"] = count_reachable_orbs_global(state, world)
state.prog_items[player]["Reachable Orbs Fresh"] = True
def count_reachable_orbs_global(state: CollectionState,
player: int,
multiworld: MultiWorld) -> int:
world: JakAndDaxterWorld) -> int:
accessible_orbs = 0
# Cast all regions upfront to access their unique attributes.
for region in typing.cast(typing.List[JakAndDaxterRegion], multiworld.get_regions(player)):
# Rely on short-circuiting to skip region.can_reach whenever possible.
if region.orb_count > 0 and region.can_reach(state):
accessible_orbs += region.orb_count
for level_name in world.level_to_regions:
for region in world.level_to_regions[level_name]:
# Rely on short-circuiting to skip region.can_reach whenever possible.
if region.orb_count > 0 and region.can_reach(state):
accessible_orbs += region.orb_count
return accessible_orbs
def count_reachable_orbs_level(state: CollectionState,
player: int,
multiworld: MultiWorld,
world: JakAndDaxterWorld,
level_name: str = "") -> int:
accessible_orbs = 0
# Cast all regions upfront to access their unique attributes.
for region in typing.cast(typing.List[JakAndDaxterRegion], multiworld.get_regions(player)):
for region in world.level_to_regions[level_name]:
# Rely on short-circuiting to skip region.can_reach whenever possible.
if region.level_name == level_name and region.orb_count > 0 and region.can_reach(state):
accessible_orbs += region.orb_count
@@ -75,7 +73,7 @@ def can_reach_orbs_global(state: CollectionState,
world: JakAndDaxterWorld,
bundle: int) -> bool:
recalculate_reachable_orbs(state, player)
recalculate_reachable_orbs(state, player, world)
return state.has("Reachable Orbs", player, world.orb_bundle_size * (bundle + 1))
@@ -85,16 +83,18 @@ def can_reach_orbs_level(state: CollectionState,
level_name: str,
bundle: int) -> bool:
recalculate_reachable_orbs(state, player)
recalculate_reachable_orbs(state, player, world)
return state.has(f"{level_name} Reachable Orbs", player, world.orb_bundle_size * (bundle + 1))
def can_trade_vanilla(state: CollectionState,
player: int,
world: JakAndDaxterWorld,
required_orbs: int,
required_previous_trade: typing.Optional[int] = None) -> bool:
recalculate_reachable_orbs(state, player) # With Orbsanity Off, Reachable Orbs are in fact Tradeable Orbs.
# With Orbsanity Off, Reachable Orbs are in fact Tradeable Orbs.
recalculate_reachable_orbs(state, player, world)
if required_previous_trade:
name_of_previous_trade = location_table[Cells.to_ap_id(required_previous_trade)]
return (state.has("Reachable Orbs", player, required_orbs)
@@ -104,10 +104,12 @@ def can_trade_vanilla(state: CollectionState,
def can_trade_orbsanity(state: CollectionState,
player: int,
world: JakAndDaxterWorld,
required_orbs: int,
required_previous_trade: typing.Optional[int] = None) -> bool:
recalculate_reachable_orbs(state, player) # Yes, even Orbsanity trades may unlock access to new Reachable Orbs.
# Yes, even Orbsanity trades may unlock access to new Reachable Orbs.
recalculate_reachable_orbs(state, player, world)
if required_previous_trade:
name_of_previous_trade = location_table[Cells.to_ap_id(required_previous_trade)]
return (state.has("Tradeable Orbs", player, required_orbs)

View File

@@ -225,9 +225,17 @@ class JakAndDaxterWorld(World):
power_cell_thresholds: list[int]
trap_weights: tuple[list[str], list[int]]
# Store a dictionary of levels to regions for faster access.
level_to_regions: dict[str, list[JakAndDaxterRegion]]
# Handles various options validation, rules enforcement, and caching of important information.
def generate_early(self) -> None:
# Initialize the level-region dictionary.
self.level_to_regions = {}
for level_name in level_table:
self.level_to_regions[level_name] = []
# Cache the power cell threshold values for quicker reference.
self.power_cell_thresholds = [
self.options.fire_canyon_cell_count.value,
@@ -307,6 +315,10 @@ class JakAndDaxterWorld(World):
from .Regions import create_regions
create_regions(self)
for level in self.level_to_regions:
for region in self.level_to_regions[level]:
self.multiworld.regions.append(region)
# from Utils import visualize_regions
# visualize_regions(self.multiworld.get_region("Menu", self.player), "jakanddaxter.puml")

View File

@@ -5,7 +5,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_fight, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -135,23 +135,23 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
fourth_tether.connect(last_tar_pit, rule=lambda state: can_jump_farther(state, player))
fourth_tether.connect(main_area) # Fall down.
multiworld.regions.append(main_area)
multiworld.regions.append(first_bats)
multiworld.regions.append(first_jump_pad)
multiworld.regions.append(first_tether)
multiworld.regions.append(first_tether_rat_colony)
multiworld.regions.append(second_jump_pad)
multiworld.regions.append(first_pole_course)
multiworld.regions.append(second_tether)
multiworld.regions.append(second_bats)
multiworld.regions.append(third_jump_pad)
multiworld.regions.append(fourth_jump_pad)
multiworld.regions.append(flut_flut_pad)
multiworld.regions.append(flut_flut_course)
multiworld.regions.append(farthy_snacks)
multiworld.regions.append(box_field)
multiworld.regions.append(last_tar_pit)
multiworld.regions.append(fourth_tether)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(first_bats)
world.level_to_regions[level_name].append(first_jump_pad)
world.level_to_regions[level_name].append(first_tether)
world.level_to_regions[level_name].append(first_tether_rat_colony)
world.level_to_regions[level_name].append(second_jump_pad)
world.level_to_regions[level_name].append(first_pole_course)
world.level_to_regions[level_name].append(second_tether)
world.level_to_regions[level_name].append(second_bats)
world.level_to_regions[level_name].append(third_jump_pad)
world.level_to_regions[level_name].append(fourth_jump_pad)
world.level_to_regions[level_name].append(flut_flut_pad)
world.level_to_regions[level_name].append(flut_flut_course)
world.level_to_regions[level_name].append(farthy_snacks)
world.level_to_regions[level_name].append(box_field)
world.level_to_regions[level_name].append(last_tar_pit)
world.level_to_regions[level_name].append(fourth_tether)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -167,4 +167,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -5,7 +5,7 @@ from ..Rules import can_reach_orbs_level
from ..locs import CellLocations as Cells, ScoutLocations as Scouts
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -16,7 +16,7 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
main_area.add_cell_locations(Cells.locFC_cellTable.keys())
main_area.add_fly_locations(Scouts.locFC_scoutTable.keys())
multiworld.regions.append(main_area)
world.level_to_regions[level_name].append(main_area)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -32,4 +32,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -4,7 +4,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_free_scout_flies, can_fight, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> tuple[JakAndDaxterRegion, ...]:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -75,13 +75,13 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
# Requires defeating the plant boss (combat).
temple_int_post_blue.connect(temple_exit, rule=lambda state: can_fight(state, player))
multiworld.regions.append(main_area)
multiworld.regions.append(lurker_machine)
multiworld.regions.append(river)
multiworld.regions.append(temple_exit)
multiworld.regions.append(temple_exterior)
multiworld.regions.append(temple_int_pre_blue)
multiworld.regions.append(temple_int_post_blue)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(lurker_machine)
world.level_to_regions[level_name].append(river)
world.level_to_regions[level_name].append(temple_exit)
world.level_to_regions[level_name].append(temple_exterior)
world.level_to_regions[level_name].append(temple_int_pre_blue)
world.level_to_regions[level_name].append(temple_int_post_blue)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -97,4 +97,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area, temple_int_post_blue]
return main_area, temple_int_post_blue

View File

@@ -5,7 +5,7 @@ from ..Rules import can_reach_orbs_level
from ..locs import ScoutLocations as Scouts
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -25,8 +25,8 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
cliff.connect(main_area) # Jump down or ride blue eco elevator.
multiworld.regions.append(main_area)
multiworld.regions.append(cliff)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(cliff)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -42,4 +42,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -6,7 +6,7 @@ from ..Rules import can_free_scout_flies, can_fight, can_reach_orbs_level
# God help me... here we go.
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> tuple[JakAndDaxterRegion | None, ...]:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -100,13 +100,13 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
final_boss.connect(rotating_tower) # Take elevator back down.
multiworld.regions.append(main_area)
multiworld.regions.append(robot_scaffolding)
multiworld.regions.append(jump_pad_room)
multiworld.regions.append(blast_furnace)
multiworld.regions.append(bunny_room)
multiworld.regions.append(rotating_tower)
multiworld.regions.append(final_boss)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(robot_scaffolding)
world.level_to_regions[level_name].append(jump_pad_room)
world.level_to_regions[level_name].append(blast_furnace)
world.level_to_regions[level_name].append(bunny_room)
world.level_to_regions[level_name].append(rotating_tower)
world.level_to_regions[level_name].append(final_boss)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -127,8 +127,8 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
final_door = JakAndDaxterRegion("Final Door", player, multiworld, level_name, 0)
final_boss.connect(final_door, rule=lambda state: state.has("Power Cell", player, 100))
multiworld.regions.append(final_door)
world.level_to_regions[level_name].append(final_door)
return [main_area, final_boss, final_door]
return main_area, final_boss, final_door
else:
return [main_area, final_boss, None]
return main_area, final_boss, None

View File

@@ -5,7 +5,7 @@ from ..Rules import can_reach_orbs_level
from ..locs import CellLocations as Cells, ScoutLocations as Scouts
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -16,7 +16,7 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
main_area.add_cell_locations(Cells.locLT_cellTable.keys())
main_area.add_fly_locations(Scouts.locLT_scoutTable.keys())
multiworld.regions.append(main_area)
world.level_to_regions[level_name].append(main_area)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -32,4 +32,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -4,7 +4,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_free_scout_flies, can_fight, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -121,19 +121,19 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
state.has("Double Jump", player) # Capsule is a convenient exit to the level.
or can_fight(state, player))
multiworld.regions.append(main_area)
multiworld.regions.append(first_room_upper)
multiworld.regions.append(first_room_lower)
multiworld.regions.append(first_room_orb_cache)
multiworld.regions.append(first_hallway)
multiworld.regions.append(second_room)
multiworld.regions.append(center_complex)
multiworld.regions.append(color_platforms)
multiworld.regions.append(quick_platforms)
multiworld.regions.append(first_slide)
multiworld.regions.append(capsule_room)
multiworld.regions.append(second_slide)
multiworld.regions.append(helix_room)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(first_room_upper)
world.level_to_regions[level_name].append(first_room_lower)
world.level_to_regions[level_name].append(first_room_orb_cache)
world.level_to_regions[level_name].append(first_hallway)
world.level_to_regions[level_name].append(second_room)
world.level_to_regions[level_name].append(center_complex)
world.level_to_regions[level_name].append(color_platforms)
world.level_to_regions[level_name].append(quick_platforms)
world.level_to_regions[level_name].append(first_slide)
world.level_to_regions[level_name].append(capsule_room)
world.level_to_regions[level_name].append(second_slide)
world.level_to_regions[level_name].append(helix_room)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -149,4 +149,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -4,7 +4,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_free_scout_flies, can_fight, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -98,18 +98,18 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
arena.connect(lower_approach) # Run.
arena.connect(far_side) # Run.
multiworld.regions.append(main_area)
multiworld.regions.append(muse_course)
multiworld.regions.append(zoomer)
multiworld.regions.append(ship)
multiworld.regions.append(far_side)
multiworld.regions.append(far_side_cliff)
multiworld.regions.append(far_side_cache)
multiworld.regions.append(barrel_course)
multiworld.regions.append(cannon)
multiworld.regions.append(upper_approach)
multiworld.regions.append(lower_approach)
multiworld.regions.append(arena)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(muse_course)
world.level_to_regions[level_name].append(zoomer)
world.level_to_regions[level_name].append(ship)
world.level_to_regions[level_name].append(far_side)
world.level_to_regions[level_name].append(far_side_cliff)
world.level_to_regions[level_name].append(far_side_cache)
world.level_to_regions[level_name].append(barrel_course)
world.level_to_regions[level_name].append(cannon)
world.level_to_regions[level_name].append(upper_approach)
world.level_to_regions[level_name].append(lower_approach)
world.level_to_regions[level_name].append(arena)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -125,4 +125,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -6,7 +6,7 @@ from ..locs import ScoutLocations as Scouts
from worlds.generic.Rules import add_rule
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> tuple[JakAndDaxterRegion, ...]:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -42,9 +42,9 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
shortcut.connect(race)
multiworld.regions.append(main_area)
multiworld.regions.append(race)
multiworld.regions.append(shortcut)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(race)
world.level_to_regions[level_name].append(shortcut)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -61,4 +61,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
main_area.connect(orbs)
# Return race required for inter-level connections.
return [main_area, race]
return main_area, race

View File

@@ -5,7 +5,7 @@ from ..Rules import can_reach_orbs_level
from ..locs import CellLocations as Cells, ScoutLocations as Scouts
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -16,7 +16,7 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
main_area.add_cell_locations(Cells.locPB_cellTable.keys())
main_area.add_fly_locations(Scouts.locPB_scoutTable.keys())
multiworld.regions.append(main_area)
world.level_to_regions[level_name].append(main_area)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -32,4 +32,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -4,7 +4,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_free_scout_flies, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> tuple[JakAndDaxterRegion, ...]:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -49,10 +49,10 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
klaww_cliff.connect(pontoon_bridge) # Just jump back down.
multiworld.regions.append(main_area)
multiworld.regions.append(orb_cache)
multiworld.regions.append(pontoon_bridge)
multiworld.regions.append(klaww_cliff)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(orb_cache)
world.level_to_regions[level_name].append(pontoon_bridge)
world.level_to_regions[level_name].append(klaww_cliff)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -69,4 +69,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
main_area.connect(orbs)
# Return klaww_cliff required for inter-level connections.
return [main_area, pontoon_bridge, klaww_cliff]
return main_area, pontoon_bridge, klaww_cliff

View File

@@ -4,7 +4,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_free_scout_flies, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -58,10 +58,10 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
yakow_cliff.connect(main_area)
oracle_platforms.connect(main_area)
multiworld.regions.append(main_area)
multiworld.regions.append(orb_cache_cliff)
multiworld.regions.append(yakow_cliff)
multiworld.regions.append(oracle_platforms)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(orb_cache_cliff)
world.level_to_regions[level_name].append(yakow_cliff)
world.level_to_regions[level_name].append(oracle_platforms)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -77,4 +77,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -5,7 +5,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_free_scout_flies, can_fight, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -80,13 +80,13 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
blue_ridge.connect(main_area)
cannon_tower.connect(main_area)
multiworld.regions.append(main_area)
multiworld.regions.append(pelican)
multiworld.regions.append(flut_flut_egg)
multiworld.regions.append(eco_harvesters)
multiworld.regions.append(green_ridge)
multiworld.regions.append(blue_ridge)
multiworld.regions.append(cannon_tower)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(pelican)
world.level_to_regions[level_name].append(flut_flut_egg)
world.level_to_regions[level_name].append(eco_harvesters)
world.level_to_regions[level_name].append(green_ridge)
world.level_to_regions[level_name].append(blue_ridge)
world.level_to_regions[level_name].append(cannon_tower)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -102,4 +102,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -6,7 +6,7 @@ from ..Rules import can_free_scout_flies, can_fight, can_reach_orbs_level
# God help me... here we go.
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -166,22 +166,22 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
bunny_cave_end.connect(fort_exterior)
# I really hope that is everything.
multiworld.regions.append(main_area)
multiworld.regions.append(glacier_lurkers)
multiworld.regions.append(blockers)
multiworld.regions.append(snowball_canyon)
multiworld.regions.append(frozen_box_cave)
multiworld.regions.append(frozen_box_cave_crates)
multiworld.regions.append(ice_skating_rink)
multiworld.regions.append(flut_flut_course)
multiworld.regions.append(fort_exterior)
multiworld.regions.append(bunny_cave_start)
multiworld.regions.append(bunny_cave_end)
multiworld.regions.append(switch_cave)
multiworld.regions.append(fort_interior)
multiworld.regions.append(fort_interior_caches)
multiworld.regions.append(fort_interior_base)
multiworld.regions.append(fort_interior_course_end)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(glacier_lurkers)
world.level_to_regions[level_name].append(blockers)
world.level_to_regions[level_name].append(snowball_canyon)
world.level_to_regions[level_name].append(frozen_box_cave)
world.level_to_regions[level_name].append(frozen_box_cave_crates)
world.level_to_regions[level_name].append(ice_skating_rink)
world.level_to_regions[level_name].append(flut_flut_course)
world.level_to_regions[level_name].append(fort_exterior)
world.level_to_regions[level_name].append(bunny_cave_start)
world.level_to_regions[level_name].append(bunny_cave_end)
world.level_to_regions[level_name].append(switch_cave)
world.level_to_regions[level_name].append(fort_interior)
world.level_to_regions[level_name].append(fort_interior_caches)
world.level_to_regions[level_name].append(fort_interior_base)
world.level_to_regions[level_name].append(fort_interior_course_end)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -197,4 +197,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -4,7 +4,7 @@ from .. import JakAndDaxterWorld
from ..Rules import can_free_scout_flies, can_fight, can_reach_orbs_level
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -95,17 +95,17 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
# Requires yellow eco switch.
spider_tunnel.connect(spider_tunnel_crates, rule=lambda state: state.has("Yellow Eco Switch", player))
multiworld.regions.append(main_area)
multiworld.regions.append(dark_crystals)
multiworld.regions.append(dark_cave)
multiworld.regions.append(robot_cave)
multiworld.regions.append(scaffolding_level_zero)
multiworld.regions.append(scaffolding_level_one)
multiworld.regions.append(scaffolding_level_two)
multiworld.regions.append(scaffolding_level_three)
multiworld.regions.append(pole_course)
multiworld.regions.append(spider_tunnel)
multiworld.regions.append(spider_tunnel_crates)
world.level_to_regions[level_name].append(main_area)
world.level_to_regions[level_name].append(dark_crystals)
world.level_to_regions[level_name].append(dark_cave)
world.level_to_regions[level_name].append(robot_cave)
world.level_to_regions[level_name].append(scaffolding_level_zero)
world.level_to_regions[level_name].append(scaffolding_level_one)
world.level_to_regions[level_name].append(scaffolding_level_two)
world.level_to_regions[level_name].append(scaffolding_level_three)
world.level_to_regions[level_name].append(pole_course)
world.level_to_regions[level_name].append(spider_tunnel)
world.level_to_regions[level_name].append(spider_tunnel_crates)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -121,4 +121,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area

View File

@@ -5,7 +5,7 @@ from ..Rules import can_free_scout_flies, can_reach_orbs_level
from ..locs import ScoutLocations as Scouts
def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxterRegion]:
def build_regions(level_name: str, world: JakAndDaxterWorld) -> JakAndDaxterRegion:
multiworld = world.multiworld
options = world.options
player = world.player
@@ -30,7 +30,7 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
# Approach the gondola to get this check.
main_area.add_special_locations([105])
multiworld.regions.append(main_area)
world.level_to_regions[level_name].append(main_area)
# If Per-Level Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Main Area. The Locations within are automatically checked when you collect enough orbs.
@@ -46,4 +46,4 @@ def build_regions(level_name: str, world: JakAndDaxterWorld) -> list[JakAndDaxte
multiworld.regions.append(orbs)
main_area.connect(orbs)
return [main_area]
return main_area