133 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			133 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								import typing
							 | 
						||
| 
								 | 
							
								from Options import OptionError
							 | 
						||
| 
								 | 
							
								from .items import item_table
							 | 
						||
| 
								 | 
							
								from .options import EnableOrbsanity, CompletionCondition
							 | 
						||
| 
								 | 
							
								from .rules import can_reach_orbs_global
							 | 
						||
| 
								 | 
							
								from .locs import cell_locations as cells, scout_locations as scouts
							 | 
						||
| 
								 | 
							
								from .regs import (geyser_rock_regions as geyser_rock,
							 | 
						||
| 
								 | 
							
								                   sandover_village_regions as sandover_village,
							 | 
						||
| 
								 | 
							
								                   forbidden_jungle_regions as forbidden_jungle,
							 | 
						||
| 
								 | 
							
								                   sentinel_beach_regions as sentinel_beach,
							 | 
						||
| 
								 | 
							
								                   misty_island_regions as misty_island,
							 | 
						||
| 
								 | 
							
								                   fire_canyon_regions as fire_canyon,
							 | 
						||
| 
								 | 
							
								                   rock_village_regions as rock_village,
							 | 
						||
| 
								 | 
							
								                   precursor_basin_regions as precursor_basin,
							 | 
						||
| 
								 | 
							
								                   lost_precursor_city_regions as lost_precursor_city,
							 | 
						||
| 
								 | 
							
								                   boggy_swamp_regions as boggy_swamp,
							 | 
						||
| 
								 | 
							
								                   mountain_pass_regions as mountain_pass,
							 | 
						||
| 
								 | 
							
								                   volcanic_crater_regions as volcanic_crater,
							 | 
						||
| 
								 | 
							
								                   spider_cave_regions as spider_cave,
							 | 
						||
| 
								 | 
							
								                   snowy_mountain_regions as snowy_mountain,
							 | 
						||
| 
								 | 
							
								                   lava_tube_regions as lava_tube,
							 | 
						||
| 
								 | 
							
								                   gol_and_maias_citadel_regions as gol_and_maias_citadel)
							 | 
						||
| 
								 | 
							
								from .regs.region_base import JakAndDaxterRegion
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if typing.TYPE_CHECKING:
							 | 
						||
| 
								 | 
							
								    from . import JakAndDaxterWorld
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								            amount = world.orb_bundle_size * (bundle_index + 1)
							 | 
						||
| 
								 | 
							
								            orbs.add_orb_locations(16,
							 | 
						||
| 
								 | 
							
								                                   bundle_index,
							 | 
						||
| 
								 | 
							
								                                   access_rule=lambda state, orb_amount=amount:
							 | 
						||
| 
								 | 
							
								                                   can_reach_orbs_global(state, player, world, orb_amount))
							 | 
						||
| 
								 | 
							
								        multiworld.regions.append(orbs)
							 | 
						||
| 
								 | 
							
								        menu.connect(orbs)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # Build all regions. Include their intra-connecting Rules, their Locations, and their Location access rules.
							 | 
						||
| 
								 | 
							
								    gr = geyser_rock.build_regions("Geyser Rock", world)
							 | 
						||
| 
								 | 
							
								    sv = sandover_village.build_regions("Sandover Village", world)
							 | 
						||
| 
								 | 
							
								    fj, fjp = forbidden_jungle.build_regions("Forbidden Jungle", world)
							 | 
						||
| 
								 | 
							
								    sb = sentinel_beach.build_regions("Sentinel Beach", world)
							 | 
						||
| 
								 | 
							
								    mi = misty_island.build_regions("Misty Island", world)
							 | 
						||
| 
								 | 
							
								    fc = fire_canyon.build_regions("Fire Canyon", world)
							 | 
						||
| 
								 | 
							
								    rv, rvp, rvc = rock_village.build_regions("Rock Village", world)
							 | 
						||
| 
								 | 
							
								    pb = precursor_basin.build_regions("Precursor Basin", world)
							 | 
						||
| 
								 | 
							
								    lpc = lost_precursor_city.build_regions("Lost Precursor City", world)
							 | 
						||
| 
								 | 
							
								    bs = boggy_swamp.build_regions("Boggy Swamp", world)
							 | 
						||
| 
								 | 
							
								    mp, mpr = mountain_pass.build_regions("Mountain Pass", world)
							 | 
						||
| 
								 | 
							
								    vc = volcanic_crater.build_regions("Volcanic Crater", world)
							 | 
						||
| 
								 | 
							
								    sc = spider_cave.build_regions("Spider Cave", world)
							 | 
						||
| 
								 | 
							
								    sm = snowy_mountain.build_regions("Snowy Mountain", world)
							 | 
						||
| 
								 | 
							
								    lt = lava_tube.build_regions("Lava Tube", world)
							 | 
						||
| 
								 | 
							
								    gmc, fb, fd = gol_and_maias_citadel.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}).")
							 |