Files
Archipelago/worlds/jakanddaxter/Regions.py
massimilianodelliubaldini 4e4a59dd9a Create OptionGroups.
2024-09-17 16:57:46 -04:00

131 lines
6.9 KiB
Python

import typing
from Options import OptionError
from . import JakAndDaxterWorld
from .Items import item_table
from .Options import EnableOrbsanity, CompletionCondition
from .Rules import can_reach_orbs_global
from .locs import CellLocations as Cells, ScoutLocations as Scouts
from .regs import (GeyserRockRegions as GeyserRock,
SandoverVillageRegions as SandoverVillage,
ForbiddenJungleRegions as ForbiddenJungle,
SentinelBeachRegions as SentinelBeach,
MistyIslandRegions as MistyIsland,
FireCanyonRegions as FireCanyon,
RockVillageRegions as RockVillage,
PrecursorBasinRegions as PrecursorBasin,
LostPrecursorCityRegions as LostPrecursorCity,
BoggySwampRegions as BoggySwamp,
MountainPassRegions as MountainPass,
VolcanicCraterRegions as VolcanicCrater,
SpiderCaveRegions as SpiderCave,
SnowyMountainRegions as SnowyMountain,
LavaTubeRegions as LavaTube,
GolAndMaiasCitadelRegions as GolAndMaiasCitadel)
from .regs.RegionBase import JakAndDaxterRegion
def create_regions(world: JakAndDaxterWorld):
multiworld = world.multiworld
options = world.options
player = world.player
# Always start with Menu.
menu = JakAndDaxterRegion("Menu", player, multiworld)
multiworld.regions.append(menu)
# Build the special "Free 7 Scout Flies" Region. This is a virtual region always accessible to Menu.
# The Locations within are automatically checked when you receive the 7th scout fly for the corresponding cell.
free7 = JakAndDaxterRegion("'Free 7 Scout Flies' Power Cells", player, multiworld)
free7.add_cell_locations(Cells.loc7SF_cellTable.keys())
for scout_fly_cell in free7.locations:
# Translate from Cell AP ID to Scout AP ID using game ID as an intermediary.
scout_fly_id = Scouts.to_ap_id(Cells.to_game_id(typing.cast(int, scout_fly_cell.address)))
scout_fly_cell.access_rule = lambda state, flies=scout_fly_id: state.has(item_table[flies], player, 7)
multiworld.regions.append(free7)
menu.connect(free7)
# If Global Orbsanity is enabled, build the special Orbsanity Region. This is a virtual region always
# accessible to Menu. The Locations within are automatically checked when you collect enough orbs.
if options.enable_orbsanity == EnableOrbsanity.option_global:
orbs = JakAndDaxterRegion("Orbsanity", player, multiworld)
bundle_count = 2000 // world.orb_bundle_size
for bundle_index in range(bundle_count):
# Unlike Per-Level Orbsanity, Global Orbsanity Locations always have a level_index of 16.
orbs.add_orb_locations(16,
bundle_index,
access_rule=lambda state, bundle=bundle_index:
can_reach_orbs_global(state, player, world, bundle))
multiworld.regions.append(orbs)
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)
# Configurable counts of cells for connector levels.
fc_count = options.fire_canyon_cell_count.value
mp_count = options.mountain_pass_cell_count.value
lt_count = options.lava_tube_cell_count.value
# Define the interconnecting rules.
menu.connect(gr)
gr.connect(sv) # Geyser Rock modified to let you leave at any time.
sv.connect(fj)
sv.connect(sb)
sv.connect(mi, rule=lambda state: state.has("Fisherman's Boat", player))
sv.connect(fc, rule=lambda state: state.has("Power Cell", player, fc_count)) # Normally 20.
fc.connect(rv)
rv.connect(pb)
rv.connect(lpc)
rvp.connect(bs) # rv->rvp/rvc connections defined internally by RockVillageRegions.
rvc.connect(mp, rule=lambda state: state.has("Power Cell", player, mp_count)) # Normally 45.
mpr.connect(vc) # mp->mpr connection defined internally by MountainPassRegions.
vc.connect(sc)
vc.connect(sm, rule=lambda state: state.has("Snowy Mountain Gondola", player))
vc.connect(lt, rule=lambda state: state.has("Power Cell", player, lt_count)) # Normally 72.
lt.connect(gmc) # gmc->fb connection defined internally by GolAndMaiasCitadelRegions.
# Set the completion condition.
if options.jak_completion_condition == CompletionCondition.option_cross_fire_canyon:
multiworld.completion_condition[player] = lambda state: state.can_reach(rv, "Region", player)
elif options.jak_completion_condition == CompletionCondition.option_cross_mountain_pass:
multiworld.completion_condition[player] = lambda state: state.can_reach(vc, "Region", player)
elif options.jak_completion_condition == CompletionCondition.option_cross_lava_tube:
multiworld.completion_condition[player] = lambda state: state.can_reach(gmc, "Region", player)
elif options.jak_completion_condition == CompletionCondition.option_defeat_dark_eco_plant:
multiworld.completion_condition[player] = lambda state: state.can_reach(fjp, "Region", player)
elif options.jak_completion_condition == CompletionCondition.option_defeat_klaww:
multiworld.completion_condition[player] = lambda state: state.can_reach(mp, "Region", player)
elif options.jak_completion_condition == CompletionCondition.option_defeat_gol_and_maia:
multiworld.completion_condition[player] = lambda state: state.can_reach(fb, "Region", player)
elif options.jak_completion_condition == CompletionCondition.option_open_100_cell_door:
multiworld.completion_condition[player] = lambda state: state.can_reach(fd, "Region", player)
else:
raise OptionError(f"{world.player_name}: Unknown completion goal ID "
f"({options.jak_completion_condition.value}).")