mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-25 09:23:20 -07:00
Jak 1: Add more scout fly ID's, refactor game/AP ID translation for easier reading and code reuse.
This commit is contained in:
@@ -1,13 +1,5 @@
|
||||
# All Jak And Daxter IDs must be offset by this number.
|
||||
game_id = 746800000
|
||||
jak1_id = 741000000
|
||||
|
||||
# The name of the game.
|
||||
game_name = "Jak and Daxter: The Precursor Legacy"
|
||||
|
||||
# What follows are offsets for each Location/Item type,
|
||||
# necessary for Archipelago to avoid collision between
|
||||
# ID numbers shared across items. See respective
|
||||
# Locations files for explanations.
|
||||
cell_offset = 0
|
||||
fly_offset = 128 # 2^7
|
||||
orb_offset = 2097152 # 2^21
|
||||
jak1_name = "Jak and Daxter: The Precursor Legacy"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from BaseClasses import Item
|
||||
from .GameID import game_name
|
||||
from .GameID import jak1_name
|
||||
|
||||
|
||||
class JakAndDaxterItem(Item):
|
||||
game: str = game_name
|
||||
game: str = jak1_name
|
||||
|
||||
|
||||
@@ -1,78 +1,46 @@
|
||||
from BaseClasses import Location
|
||||
from .GameID import game_id, game_name, cell_offset, fly_offset
|
||||
from .locs import CellLocations, ScoutLocations
|
||||
from .GameID import jak1_name
|
||||
from .locs import CellLocations as Cells, ScoutLocations as Scouts
|
||||
|
||||
|
||||
class JakAndDaxterLocation(Location):
|
||||
game: str = game_name
|
||||
game: str = jak1_name
|
||||
|
||||
|
||||
# All Locations
|
||||
# Because all items in Jak And Daxter are unique and do not regenerate, we can use this same table as our item table.
|
||||
# Each Item ID == its corresponding Location ID. And then we only have to do this ugly math once.
|
||||
# Each Item ID == its corresponding Location ID. While we're here, do all the ID conversions needed.
|
||||
location_table = {
|
||||
**{game_id + cell_offset + k: CellLocations.locGR_cellTable[k]
|
||||
for k in CellLocations.locGR_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locSV_cellTable[k]
|
||||
for k in CellLocations.locSV_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locFJ_cellTable[k]
|
||||
for k in CellLocations.locFJ_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locSB_cellTable[k]
|
||||
for k in CellLocations.locSB_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locMI_cellTable[k]
|
||||
for k in CellLocations.locMI_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locFC_cellTable[k]
|
||||
for k in CellLocations.locFC_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locRV_cellTable[k]
|
||||
for k in CellLocations.locRV_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locPB_cellTable[k]
|
||||
for k in CellLocations.locPB_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locLPC_cellTable[k]
|
||||
for k in CellLocations.locLPC_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locBS_cellTable[k]
|
||||
for k in CellLocations.locBS_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locMP_cellTable[k]
|
||||
for k in CellLocations.locMP_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locVC_cellTable[k]
|
||||
for k in CellLocations.locVC_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locSC_cellTable[k]
|
||||
for k in CellLocations.locSC_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locSM_cellTable[k]
|
||||
for k in CellLocations.locSM_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locLT_cellTable[k]
|
||||
for k in CellLocations.locLT_cellTable},
|
||||
**{game_id + cell_offset + k: CellLocations.locGMC_cellTable[k]
|
||||
for k in CellLocations.locGMC_cellTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locGR_scoutTable[k]
|
||||
for k in ScoutLocations.locGR_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locSV_scoutTable[k]
|
||||
for k in ScoutLocations.locSV_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locFJ_scoutTable[k]
|
||||
for k in ScoutLocations.locFJ_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locSB_scoutTable[k]
|
||||
for k in ScoutLocations.locSB_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locMI_scoutTable[k]
|
||||
for k in ScoutLocations.locMI_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locFC_scoutTable[k]
|
||||
for k in ScoutLocations.locFC_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locRV_scoutTable[k]
|
||||
for k in ScoutLocations.locRV_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locPB_scoutTable[k]
|
||||
for k in ScoutLocations.locPB_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locLPC_scoutTable[k]
|
||||
for k in ScoutLocations.locLPC_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locBS_scoutTable[k]
|
||||
for k in ScoutLocations.locBS_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locMP_scoutTable[k]
|
||||
for k in ScoutLocations.locMP_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locVC_scoutTable[k]
|
||||
for k in ScoutLocations.locVC_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locSC_scoutTable[k]
|
||||
for k in ScoutLocations.locSC_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locSM_scoutTable[k]
|
||||
for k in ScoutLocations.locSM_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locLT_scoutTable[k]
|
||||
for k in ScoutLocations.locLT_scoutTable},
|
||||
**{game_id + fly_offset + k: ScoutLocations.locGMC_scoutTable[k]
|
||||
for k in ScoutLocations.locGMC_scoutTable}
|
||||
**{Cells.to_ap_id(k): Cells.locGR_cellTable[k] for k in Cells.locGR_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locSV_cellTable[k] for k in Cells.locSV_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locFJ_cellTable[k] for k in Cells.locFJ_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locSB_cellTable[k] for k in Cells.locSB_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locMI_cellTable[k] for k in Cells.locMI_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locFC_cellTable[k] for k in Cells.locFC_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locRV_cellTable[k] for k in Cells.locRV_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locPB_cellTable[k] for k in Cells.locPB_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locLPC_cellTable[k] for k in Cells.locLPC_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locBS_cellTable[k] for k in Cells.locBS_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locMP_cellTable[k] for k in Cells.locMP_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locVC_cellTable[k] for k in Cells.locVC_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locSC_cellTable[k] for k in Cells.locSC_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locSM_cellTable[k] for k in Cells.locSM_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locLT_cellTable[k] for k in Cells.locLT_cellTable},
|
||||
**{Cells.to_ap_id(k): Cells.locGMC_cellTable[k] for k in Cells.locGMC_cellTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locGR_scoutTable[k] for k in Scouts.locGR_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locSV_scoutTable[k] for k in Scouts.locSV_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locFJ_scoutTable[k] for k in Scouts.locFJ_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locSB_scoutTable[k] for k in Scouts.locSB_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locMI_scoutTable[k] for k in Scouts.locMI_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locFC_scoutTable[k] for k in Scouts.locFC_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locRV_scoutTable[k] for k in Scouts.locRV_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locPB_scoutTable[k] for k in Scouts.locPB_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locLPC_scoutTable[k] for k in Scouts.locLPC_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locBS_scoutTable[k] for k in Scouts.locBS_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locMP_scoutTable[k] for k in Scouts.locMP_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locVC_scoutTable[k] for k in Scouts.locVC_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locSC_scoutTable[k] for k in Scouts.locSC_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locSM_scoutTable[k] for k in Scouts.locSM_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locLT_scoutTable[k] for k in Scouts.locLT_scoutTable},
|
||||
**{Scouts.to_ap_id(k): Scouts.locGMC_scoutTable[k] for k in Scouts.locGMC_scoutTable}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import typing
|
||||
from enum import Enum, auto
|
||||
from BaseClasses import MultiWorld, Region
|
||||
from .GameID import game_id, game_name, cell_offset, fly_offset
|
||||
from .GameID import jak1_name
|
||||
from .Options import JakAndDaxterOptions
|
||||
from .Locations import JakAndDaxterLocation, location_table
|
||||
from .locs import CellLocations, ScoutLocations
|
||||
from .locs import CellLocations as Cells, ScoutLocations as Scouts
|
||||
|
||||
|
||||
class JakAndDaxterLevel(int, Enum):
|
||||
class Jak1Level(int, Enum):
|
||||
GEYSER_ROCK = auto()
|
||||
SANDOVER_VILLAGE = auto()
|
||||
FORBIDDEN_JUNGLE = auto()
|
||||
@@ -26,7 +26,7 @@ class JakAndDaxterLevel(int, Enum):
|
||||
GOL_AND_MAIAS_CITADEL = auto()
|
||||
|
||||
|
||||
class JakAndDaxterSubLevel(int, Enum):
|
||||
class Jak1SubLevel(int, Enum):
|
||||
MAIN_AREA = auto()
|
||||
FORBIDDEN_JUNGLE_SWITCH_ROOM = auto()
|
||||
FORBIDDEN_JUNGLE_PLANT_ROOM = auto()
|
||||
@@ -44,165 +44,161 @@ class JakAndDaxterSubLevel(int, Enum):
|
||||
GOL_AND_MAIAS_CITADEL_FINAL_BOSS = auto()
|
||||
|
||||
|
||||
level_table: typing.Dict[JakAndDaxterLevel, str] = {
|
||||
JakAndDaxterLevel.GEYSER_ROCK: "Geyser Rock",
|
||||
JakAndDaxterLevel.SANDOVER_VILLAGE: "Sandover Village",
|
||||
JakAndDaxterLevel.FORBIDDEN_JUNGLE: "Forbidden Jungle",
|
||||
JakAndDaxterLevel.SENTINEL_BEACH: "Sentinel Beach",
|
||||
JakAndDaxterLevel.MISTY_ISLAND: "Misty Island",
|
||||
JakAndDaxterLevel.FIRE_CANYON: "Fire Canyon",
|
||||
JakAndDaxterLevel.ROCK_VILLAGE: "Rock Village",
|
||||
JakAndDaxterLevel.PRECURSOR_BASIN: "Precursor Basin",
|
||||
JakAndDaxterLevel.LOST_PRECURSOR_CITY: "Lost Precursor City",
|
||||
JakAndDaxterLevel.BOGGY_SWAMP: "Boggy Swamp",
|
||||
JakAndDaxterLevel.MOUNTAIN_PASS: "Mountain Pass",
|
||||
JakAndDaxterLevel.VOLCANIC_CRATER: "Volcanic Crater",
|
||||
JakAndDaxterLevel.SPIDER_CAVE: "Spider Cave",
|
||||
JakAndDaxterLevel.SNOWY_MOUNTAIN: "Snowy Mountain",
|
||||
JakAndDaxterLevel.LAVA_TUBE: "Lava Tube",
|
||||
JakAndDaxterLevel.GOL_AND_MAIAS_CITADEL: "Gol and Maia's Citadel"
|
||||
level_table: typing.Dict[Jak1Level, str] = {
|
||||
Jak1Level.GEYSER_ROCK: "Geyser Rock",
|
||||
Jak1Level.SANDOVER_VILLAGE: "Sandover Village",
|
||||
Jak1Level.FORBIDDEN_JUNGLE: "Forbidden Jungle",
|
||||
Jak1Level.SENTINEL_BEACH: "Sentinel Beach",
|
||||
Jak1Level.MISTY_ISLAND: "Misty Island",
|
||||
Jak1Level.FIRE_CANYON: "Fire Canyon",
|
||||
Jak1Level.ROCK_VILLAGE: "Rock Village",
|
||||
Jak1Level.PRECURSOR_BASIN: "Precursor Basin",
|
||||
Jak1Level.LOST_PRECURSOR_CITY: "Lost Precursor City",
|
||||
Jak1Level.BOGGY_SWAMP: "Boggy Swamp",
|
||||
Jak1Level.MOUNTAIN_PASS: "Mountain Pass",
|
||||
Jak1Level.VOLCANIC_CRATER: "Volcanic Crater",
|
||||
Jak1Level.SPIDER_CAVE: "Spider Cave",
|
||||
Jak1Level.SNOWY_MOUNTAIN: "Snowy Mountain",
|
||||
Jak1Level.LAVA_TUBE: "Lava Tube",
|
||||
Jak1Level.GOL_AND_MAIAS_CITADEL: "Gol and Maia's Citadel"
|
||||
}
|
||||
|
||||
subLevel_table: typing.Dict[JakAndDaxterSubLevel, str] = {
|
||||
JakAndDaxterSubLevel.MAIN_AREA: "Main Area",
|
||||
JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM: "Forbidden Jungle Switch Room",
|
||||
JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM: "Forbidden Jungle Plant Room",
|
||||
JakAndDaxterSubLevel.SENTINEL_BEACH_CANNON_TOWER: "Sentinel Beach Cannon Tower",
|
||||
JakAndDaxterSubLevel.PRECURSOR_BASIN_BLUE_RINGS: "Precursor Basin Blue Rings",
|
||||
JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM: "Lost Precursor City Sunken Room",
|
||||
JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM: "Lost Precursor City Helix Room",
|
||||
JakAndDaxterSubLevel.BOGGY_SWAMP_FLUT_FLUT: "Boggy Swamp Flut Flut",
|
||||
JakAndDaxterSubLevel.MOUNTAIN_PASS_RACE: "Mountain Pass Race",
|
||||
JakAndDaxterSubLevel.MOUNTAIN_PASS_SHORTCUT: "Mountain Pass Shortcut",
|
||||
JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FLUT_FLUT: "Snowy Mountain Flut Flut",
|
||||
JakAndDaxterSubLevel.SNOWY_MOUNTAIN_LURKER_FORT: "Snowy Mountain Lurker Fort",
|
||||
JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FROZEN_BOX: "Snowy Mountain Frozen Box",
|
||||
JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER: "Gol and Maia's Citadel Rotating Tower",
|
||||
JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS: "Gol and Maia's Citadel Final Boss"
|
||||
subLevel_table: typing.Dict[Jak1SubLevel, str] = {
|
||||
Jak1SubLevel.MAIN_AREA: "Main Area",
|
||||
Jak1SubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM: "Forbidden Jungle Switch Room",
|
||||
Jak1SubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM: "Forbidden Jungle Plant Room",
|
||||
Jak1SubLevel.SENTINEL_BEACH_CANNON_TOWER: "Sentinel Beach Cannon Tower",
|
||||
Jak1SubLevel.PRECURSOR_BASIN_BLUE_RINGS: "Precursor Basin Blue Rings",
|
||||
Jak1SubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM: "Lost Precursor City Sunken Room",
|
||||
Jak1SubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM: "Lost Precursor City Helix Room",
|
||||
Jak1SubLevel.BOGGY_SWAMP_FLUT_FLUT: "Boggy Swamp Flut Flut",
|
||||
Jak1SubLevel.MOUNTAIN_PASS_RACE: "Mountain Pass Race",
|
||||
Jak1SubLevel.MOUNTAIN_PASS_SHORTCUT: "Mountain Pass Shortcut",
|
||||
Jak1SubLevel.SNOWY_MOUNTAIN_FLUT_FLUT: "Snowy Mountain Flut Flut",
|
||||
Jak1SubLevel.SNOWY_MOUNTAIN_LURKER_FORT: "Snowy Mountain Lurker Fort",
|
||||
Jak1SubLevel.SNOWY_MOUNTAIN_FROZEN_BOX: "Snowy Mountain Frozen Box",
|
||||
Jak1SubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER: "Gol and Maia's Citadel Rotating Tower",
|
||||
Jak1SubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS: "Gol and Maia's Citadel Final Boss"
|
||||
}
|
||||
|
||||
|
||||
class JakAndDaxterRegion(Region):
|
||||
game: str = game_name
|
||||
game: str = jak1_name
|
||||
|
||||
|
||||
# Use the original ID's for each item to tell the Region which Locations are available in it.
|
||||
# You do NOT need to add the item offsets, that will be handled by create_*_locations.
|
||||
# Use the original game ID's for each item to tell the Region which Locations are available in it.
|
||||
# You do NOT need to add the item offsets or game ID, that will be handled by create_*_locations.
|
||||
def create_regions(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int):
|
||||
create_region(player, multiworld, "Menu")
|
||||
|
||||
region_gr = create_region(player, multiworld, level_table[JakAndDaxterLevel.GEYSER_ROCK])
|
||||
create_cell_locations(region_gr, CellLocations.locGR_cellTable)
|
||||
create_fly_locations(region_gr, ScoutLocations.locGR_scoutTable)
|
||||
region_gr = create_region(player, multiworld, level_table[Jak1Level.GEYSER_ROCK])
|
||||
create_cell_locations(region_gr, Cells.locGR_cellTable)
|
||||
create_fly_locations(region_gr, Scouts.locGR_scoutTable)
|
||||
|
||||
region_sv = create_region(player, multiworld, level_table[JakAndDaxterLevel.SANDOVER_VILLAGE])
|
||||
create_cell_locations(region_sv, CellLocations.locSV_cellTable)
|
||||
create_fly_locations(region_sv, ScoutLocations.locSV_scoutTable)
|
||||
region_sv = create_region(player, multiworld, level_table[Jak1Level.SANDOVER_VILLAGE])
|
||||
create_cell_locations(region_sv, Cells.locSV_cellTable)
|
||||
create_fly_locations(region_sv, Scouts.locSV_scoutTable)
|
||||
|
||||
region_fj = create_region(player, multiworld, level_table[JakAndDaxterLevel.FORBIDDEN_JUNGLE])
|
||||
create_cell_locations(region_fj, {k: CellLocations.locFJ_cellTable[k] for k in {3, 4, 5, 8, 9, 7}})
|
||||
create_fly_locations(region_fj, ScoutLocations.locFJ_scoutTable)
|
||||
region_fj = create_region(player, multiworld, level_table[Jak1Level.FORBIDDEN_JUNGLE])
|
||||
create_cell_locations(region_fj, {k: Cells.locFJ_cellTable[k] for k in {3, 4, 5, 8, 9, 7}})
|
||||
create_fly_locations(region_fj, Scouts.locFJ_scoutTable)
|
||||
|
||||
sub_region_fjsr = create_subregion(region_fj, subLevel_table[JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM])
|
||||
create_cell_locations(sub_region_fjsr, {k: CellLocations.locFJ_cellTable[k] for k in {2}})
|
||||
sub_region_fjsr = create_subregion(region_fj, subLevel_table[Jak1SubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM])
|
||||
create_cell_locations(sub_region_fjsr, {k: Cells.locFJ_cellTable[k] for k in {2}})
|
||||
|
||||
sub_region_fjpr = create_subregion(sub_region_fjsr, subLevel_table[JakAndDaxterSubLevel
|
||||
.FORBIDDEN_JUNGLE_PLANT_ROOM])
|
||||
create_cell_locations(sub_region_fjpr, {k: CellLocations.locFJ_cellTable[k] for k in {6}})
|
||||
sub_region_fjpr = create_subregion(sub_region_fjsr, subLevel_table[Jak1SubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM])
|
||||
create_cell_locations(sub_region_fjpr, {k: Cells.locFJ_cellTable[k] for k in {6}})
|
||||
|
||||
region_sb = create_region(player, multiworld, level_table[JakAndDaxterLevel.SENTINEL_BEACH])
|
||||
create_cell_locations(region_sb, {k: CellLocations.locSB_cellTable[k] for k in {15, 17, 16, 18, 21, 22, 20}})
|
||||
create_fly_locations(region_sb, ScoutLocations.locSB_scoutTable)
|
||||
region_sb = create_region(player, multiworld, level_table[Jak1Level.SENTINEL_BEACH])
|
||||
create_cell_locations(region_sb, {k: Cells.locSB_cellTable[k] for k in {15, 17, 16, 18, 21, 22, 20}})
|
||||
create_fly_locations(region_sb, Scouts.locSB_scoutTable)
|
||||
|
||||
sub_region_sbct = create_subregion(region_sb, subLevel_table[JakAndDaxterSubLevel.SENTINEL_BEACH_CANNON_TOWER])
|
||||
create_cell_locations(sub_region_sbct, {k: CellLocations.locSB_cellTable[k] for k in {19}})
|
||||
sub_region_sbct = create_subregion(region_sb, subLevel_table[Jak1SubLevel.SENTINEL_BEACH_CANNON_TOWER])
|
||||
create_cell_locations(sub_region_sbct, {k: Cells.locSB_cellTable[k] for k in {19}})
|
||||
|
||||
region_mi = create_region(player, multiworld, level_table[JakAndDaxterLevel.MISTY_ISLAND])
|
||||
create_cell_locations(region_mi, CellLocations.locMI_cellTable)
|
||||
create_fly_locations(region_mi, ScoutLocations.locMI_scoutTable)
|
||||
region_mi = create_region(player, multiworld, level_table[Jak1Level.MISTY_ISLAND])
|
||||
create_cell_locations(region_mi, Cells.locMI_cellTable)
|
||||
create_fly_locations(region_mi, Scouts.locMI_scoutTable)
|
||||
|
||||
region_fc = create_region(player, multiworld, level_table[JakAndDaxterLevel.FIRE_CANYON])
|
||||
create_cell_locations(region_fc, CellLocations.locFC_cellTable)
|
||||
create_fly_locations(region_fc, ScoutLocations.locFC_scoutTable)
|
||||
region_fc = create_region(player, multiworld, level_table[Jak1Level.FIRE_CANYON])
|
||||
create_cell_locations(region_fc, Cells.locFC_cellTable)
|
||||
create_fly_locations(region_fc, Scouts.locFC_scoutTable)
|
||||
|
||||
region_rv = create_region(player, multiworld, level_table[JakAndDaxterLevel.ROCK_VILLAGE])
|
||||
create_cell_locations(region_rv, CellLocations.locRV_cellTable)
|
||||
create_fly_locations(region_rv, ScoutLocations.locRV_scoutTable)
|
||||
region_rv = create_region(player, multiworld, level_table[Jak1Level.ROCK_VILLAGE])
|
||||
create_cell_locations(region_rv, Cells.locRV_cellTable)
|
||||
create_fly_locations(region_rv, Scouts.locRV_scoutTable)
|
||||
|
||||
region_pb = create_region(player, multiworld, level_table[JakAndDaxterLevel.PRECURSOR_BASIN])
|
||||
create_cell_locations(region_pb, {k: CellLocations.locPB_cellTable[k] for k in {54, 53, 52, 56, 55, 58, 57}})
|
||||
create_fly_locations(region_pb, ScoutLocations.locPB_scoutTable)
|
||||
region_pb = create_region(player, multiworld, level_table[Jak1Level.PRECURSOR_BASIN])
|
||||
create_cell_locations(region_pb, {k: Cells.locPB_cellTable[k] for k in {54, 53, 52, 56, 55, 58, 57}})
|
||||
create_fly_locations(region_pb, Scouts.locPB_scoutTable)
|
||||
|
||||
sub_region_pbbr = create_subregion(region_pb, subLevel_table[JakAndDaxterSubLevel.PRECURSOR_BASIN_BLUE_RINGS])
|
||||
create_cell_locations(sub_region_pbbr, {k: CellLocations.locPB_cellTable[k] for k in {59}})
|
||||
sub_region_pbbr = create_subregion(region_pb, subLevel_table[Jak1SubLevel.PRECURSOR_BASIN_BLUE_RINGS])
|
||||
create_cell_locations(sub_region_pbbr, {k: Cells.locPB_cellTable[k] for k in {59}})
|
||||
|
||||
region_lpc = create_region(player, multiworld, level_table[JakAndDaxterLevel.LOST_PRECURSOR_CITY])
|
||||
create_cell_locations(region_lpc, {k: CellLocations.locLPC_cellTable[k] for k in {45, 48, 44, 51}})
|
||||
create_fly_locations(region_lpc, {k: ScoutLocations.locLPC_scoutTable[k] for k in {157, 158, 159, 160, 161, 162}})
|
||||
region_lpc = create_region(player, multiworld, level_table[Jak1Level.LOST_PRECURSOR_CITY])
|
||||
create_cell_locations(region_lpc, {k: Cells.locLPC_cellTable[k] for k in {45, 48, 44, 51}})
|
||||
create_fly_locations(region_lpc, {k: Scouts.locLPC_scoutTable[k] for k in {157, 158, 159, 160, 161, 162}})
|
||||
|
||||
sub_region_lpcsr = create_subregion(region_lpc, subLevel_table[JakAndDaxterSubLevel
|
||||
.LOST_PRECURSOR_CITY_SUNKEN_ROOM])
|
||||
create_cell_locations(sub_region_lpcsr, {k: CellLocations.locLPC_cellTable[k] for k in {47, 49}})
|
||||
create_fly_locations(region_lpc, {k: ScoutLocations.locLPC_scoutTable[k] for k in {163}})
|
||||
sub_region_lpcsr = create_subregion(region_lpc, subLevel_table[Jak1SubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM])
|
||||
create_cell_locations(sub_region_lpcsr, {k: Cells.locLPC_cellTable[k] for k in {47, 49}})
|
||||
create_fly_locations(region_lpc, {k: Scouts.locLPC_scoutTable[k] for k in {163}})
|
||||
|
||||
sub_region_lpchr = create_subregion(region_lpc, subLevel_table[JakAndDaxterSubLevel
|
||||
.LOST_PRECURSOR_CITY_HELIX_ROOM])
|
||||
create_cell_locations(sub_region_lpchr, {k: CellLocations.locLPC_cellTable[k] for k in {46, 50}})
|
||||
sub_region_lpchr = create_subregion(region_lpc, subLevel_table[Jak1SubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM])
|
||||
create_cell_locations(sub_region_lpchr, {k: Cells.locLPC_cellTable[k] for k in {46, 50}})
|
||||
|
||||
region_bs = create_region(player, multiworld, level_table[JakAndDaxterLevel.BOGGY_SWAMP])
|
||||
create_cell_locations(region_bs, {k: CellLocations.locBS_cellTable[k] for k in {36, 38, 39, 40, 41, 42}})
|
||||
create_fly_locations(region_bs, {k: ScoutLocations.locBS_scoutTable[k] for k in {164, 165, 166, 167, 170}})
|
||||
region_bs = create_region(player, multiworld, level_table[Jak1Level.BOGGY_SWAMP])
|
||||
create_cell_locations(region_bs, {k: Cells.locBS_cellTable[k] for k in {36, 38, 39, 40, 41, 42}})
|
||||
create_fly_locations(region_bs, {k: Scouts.locBS_scoutTable[k] for k in {164, 165, 166, 167, 170}})
|
||||
|
||||
sub_region_bsff = create_subregion(region_bs, subLevel_table[JakAndDaxterSubLevel.BOGGY_SWAMP_FLUT_FLUT])
|
||||
create_cell_locations(sub_region_bsff, {k: CellLocations.locBS_cellTable[k] for k in {43, 37}})
|
||||
create_fly_locations(sub_region_bsff, {k: ScoutLocations.locBS_scoutTable[k] for k in {168, 169}})
|
||||
sub_region_bsff = create_subregion(region_bs, subLevel_table[Jak1SubLevel.BOGGY_SWAMP_FLUT_FLUT])
|
||||
create_cell_locations(sub_region_bsff, {k: Cells.locBS_cellTable[k] for k in {43, 37}})
|
||||
create_fly_locations(sub_region_bsff, {k: Scouts.locBS_scoutTable[k] for k in {168, 169}})
|
||||
|
||||
region_mp = create_region(player, multiworld, level_table[JakAndDaxterLevel.MOUNTAIN_PASS])
|
||||
create_cell_locations(region_mp, {k: CellLocations.locMP_cellTable[k] for k in {86}})
|
||||
region_mp = create_region(player, multiworld, level_table[Jak1Level.MOUNTAIN_PASS])
|
||||
create_cell_locations(region_mp, {k: Cells.locMP_cellTable[k] for k in {86}})
|
||||
|
||||
sub_region_mpr = create_subregion(region_mp, subLevel_table[JakAndDaxterSubLevel.MOUNTAIN_PASS_RACE])
|
||||
create_cell_locations(sub_region_mpr, {k: CellLocations.locMP_cellTable[k] for k in {87, 88}})
|
||||
create_fly_locations(sub_region_mpr, ScoutLocations.locMP_scoutTable)
|
||||
sub_region_mpr = create_subregion(region_mp, subLevel_table[Jak1SubLevel.MOUNTAIN_PASS_RACE])
|
||||
create_cell_locations(sub_region_mpr, {k: Cells.locMP_cellTable[k] for k in {87, 88}})
|
||||
create_fly_locations(sub_region_mpr, Scouts.locMP_scoutTable)
|
||||
|
||||
sub_region_mps = create_subregion(sub_region_mpr, subLevel_table[JakAndDaxterSubLevel.MOUNTAIN_PASS_SHORTCUT])
|
||||
create_cell_locations(sub_region_mps, {k: CellLocations.locMP_cellTable[k] for k in {110}})
|
||||
sub_region_mps = create_subregion(sub_region_mpr, subLevel_table[Jak1SubLevel.MOUNTAIN_PASS_SHORTCUT])
|
||||
create_cell_locations(sub_region_mps, {k: Cells.locMP_cellTable[k] for k in {110}})
|
||||
|
||||
region_vc = create_region(player, multiworld, level_table[JakAndDaxterLevel.VOLCANIC_CRATER])
|
||||
create_cell_locations(region_vc, CellLocations.locVC_cellTable)
|
||||
create_fly_locations(region_vc, ScoutLocations.locVC_scoutTable)
|
||||
region_vc = create_region(player, multiworld, level_table[Jak1Level.VOLCANIC_CRATER])
|
||||
create_cell_locations(region_vc, Cells.locVC_cellTable)
|
||||
create_fly_locations(region_vc, Scouts.locVC_scoutTable)
|
||||
|
||||
region_sc = create_region(player, multiworld, level_table[JakAndDaxterLevel.SPIDER_CAVE])
|
||||
create_cell_locations(region_sc, CellLocations.locSC_cellTable)
|
||||
create_fly_locations(region_sc, ScoutLocations.locSC_scoutTable)
|
||||
region_sc = create_region(player, multiworld, level_table[Jak1Level.SPIDER_CAVE])
|
||||
create_cell_locations(region_sc, Cells.locSC_cellTable)
|
||||
create_fly_locations(region_sc, Scouts.locSC_scoutTable)
|
||||
|
||||
region_sm = create_region(player, multiworld, level_table[JakAndDaxterLevel.SNOWY_MOUNTAIN])
|
||||
create_cell_locations(region_sm, {k: CellLocations.locSM_cellTable[k] for k in {60, 61, 66, 64}})
|
||||
create_fly_locations(region_sm, {k: ScoutLocations.locSM_scoutTable[k] for k in {192, 193, 194, 195, 196}})
|
||||
region_sm = create_region(player, multiworld, level_table[Jak1Level.SNOWY_MOUNTAIN])
|
||||
create_cell_locations(region_sm, {k: Cells.locSM_cellTable[k] for k in {60, 61, 66, 64}})
|
||||
create_fly_locations(region_sm, {k: Scouts.locSM_scoutTable[k] for k in {192, 193, 194, 195, 196}})
|
||||
|
||||
sub_region_smfb = create_subregion(region_sm, subLevel_table[JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FROZEN_BOX])
|
||||
create_cell_locations(sub_region_smfb, {k: CellLocations.locSM_cellTable[k] for k in {67}})
|
||||
sub_region_smfb = create_subregion(region_sm, subLevel_table[Jak1SubLevel.SNOWY_MOUNTAIN_FROZEN_BOX])
|
||||
create_cell_locations(sub_region_smfb, {k: Cells.locSM_cellTable[k] for k in {67}})
|
||||
|
||||
sub_region_smff = create_subregion(region_sm, subLevel_table[JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FLUT_FLUT])
|
||||
create_cell_locations(sub_region_smff, {k: CellLocations.locSM_cellTable[k] for k in {63}})
|
||||
sub_region_smff = create_subregion(region_sm, subLevel_table[Jak1SubLevel.SNOWY_MOUNTAIN_FLUT_FLUT])
|
||||
create_cell_locations(sub_region_smff, {k: Cells.locSM_cellTable[k] for k in {63}})
|
||||
|
||||
sub_region_smlf = create_subregion(region_sm, subLevel_table[JakAndDaxterSubLevel.SNOWY_MOUNTAIN_LURKER_FORT])
|
||||
create_cell_locations(sub_region_smlf, {k: CellLocations.locSM_cellTable[k] for k in {62, 65}})
|
||||
create_fly_locations(sub_region_smlf, {k: ScoutLocations.locSM_scoutTable[k] for k in {197, 198}})
|
||||
sub_region_smlf = create_subregion(region_sm, subLevel_table[Jak1SubLevel.SNOWY_MOUNTAIN_LURKER_FORT])
|
||||
create_cell_locations(sub_region_smlf, {k: Cells.locSM_cellTable[k] for k in {62, 65}})
|
||||
create_fly_locations(sub_region_smlf, {k: Scouts.locSM_scoutTable[k] for k in {197, 198}})
|
||||
|
||||
region_lt = create_region(player, multiworld, level_table[JakAndDaxterLevel.LAVA_TUBE])
|
||||
create_cell_locations(region_lt, CellLocations.locLT_cellTable)
|
||||
create_fly_locations(region_lt, ScoutLocations.locLT_scoutTable)
|
||||
region_lt = create_region(player, multiworld, level_table[Jak1Level.LAVA_TUBE])
|
||||
create_cell_locations(region_lt, Cells.locLT_cellTable)
|
||||
create_fly_locations(region_lt, Scouts.locLT_scoutTable)
|
||||
|
||||
region_gmc = create_region(player, multiworld, level_table[JakAndDaxterLevel.GOL_AND_MAIAS_CITADEL])
|
||||
create_cell_locations(region_gmc, {k: CellLocations.locGMC_cellTable[k] for k in {71, 72, 73}})
|
||||
create_fly_locations(region_gmc, {k: ScoutLocations.locGMC_scoutTable[k] for k in {206, 207, 208, 209, 210, 211}})
|
||||
region_gmc = create_region(player, multiworld, level_table[Jak1Level.GOL_AND_MAIAS_CITADEL])
|
||||
create_cell_locations(region_gmc, {k: Cells.locGMC_cellTable[k] for k in {71, 72, 73}})
|
||||
create_fly_locations(region_gmc, {k: Scouts.locGMC_scoutTable[k] for k in {206, 207, 208, 209, 210, 211}})
|
||||
|
||||
sub_region_gmcrt = create_subregion(region_gmc, subLevel_table[JakAndDaxterSubLevel
|
||||
.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER])
|
||||
create_cell_locations(sub_region_gmcrt, {k: CellLocations.locGMC_cellTable[k] for k in {70, 91}})
|
||||
create_fly_locations(sub_region_gmcrt, {k: ScoutLocations.locGMC_scoutTable[k] for k in {212}})
|
||||
sub_region_gmcrt = create_subregion(region_gmc, subLevel_table[Jak1SubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER])
|
||||
create_cell_locations(sub_region_gmcrt, {k: Cells.locGMC_cellTable[k] for k in {70, 91}})
|
||||
create_fly_locations(sub_region_gmcrt, {k: Scouts.locGMC_scoutTable[k] for k in {212}})
|
||||
|
||||
create_subregion(sub_region_gmcrt, subLevel_table[JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS])
|
||||
create_subregion(sub_region_gmcrt, subLevel_table[Jak1SubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS])
|
||||
|
||||
|
||||
def create_region(player: int, multiworld: MultiWorld, name: str) -> JakAndDaxterRegion:
|
||||
@@ -219,13 +215,13 @@ def create_subregion(parent: Region, name: str) -> JakAndDaxterRegion:
|
||||
|
||||
def create_cell_locations(region: Region, locations: typing.Dict[int, str]):
|
||||
region.locations += [JakAndDaxterLocation(region.player,
|
||||
location_table[game_id + cell_offset + loc],
|
||||
game_id + cell_offset + loc,
|
||||
location_table[Cells.to_ap_id(loc)],
|
||||
Cells.to_ap_id(loc),
|
||||
region) for loc in locations]
|
||||
|
||||
|
||||
def create_fly_locations(region: Region, locations: typing.Dict[int, str]):
|
||||
region.locations += [JakAndDaxterLocation(region.player,
|
||||
location_table[game_id + fly_offset + loc],
|
||||
game_id + fly_offset + loc,
|
||||
location_table[Scouts.to_ap_id(loc)],
|
||||
Scouts.to_ap_id(loc),
|
||||
region) for loc in locations]
|
||||
|
||||
@@ -1,225 +1,221 @@
|
||||
from BaseClasses import MultiWorld
|
||||
from .GameID import game_id, cell_offset, fly_offset
|
||||
from .Options import JakAndDaxterOptions
|
||||
from .Regions import JakAndDaxterLevel, JakAndDaxterSubLevel, level_table, subLevel_table
|
||||
from .Regions import Jak1Level, Jak1SubLevel, level_table, subLevel_table
|
||||
from .Locations import location_table as item_table
|
||||
from .locs.CellLocations import locGR_cellTable
|
||||
from .locs import CellLocations as Cells, ScoutLocations as Scouts
|
||||
|
||||
|
||||
def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int):
|
||||
# Setting up some useful variables here because the offset numbers can get confusing
|
||||
# for access rules. Feel free to add more variables here to keep the code more readable.
|
||||
gr_cells = {game_id + cell_offset + k for k in locGR_cellTable}
|
||||
fj_temple_top = game_id + cell_offset + 4
|
||||
fj_blue_switch = game_id + cell_offset + 2
|
||||
fj_plant_boss = game_id + cell_offset + 6
|
||||
fj_fisherman = game_id + cell_offset + 5
|
||||
sb_flut_flut = game_id + cell_offset + 17
|
||||
fc_end = game_id + cell_offset + 69
|
||||
pb_purple_rings = game_id + cell_offset + 58
|
||||
lpc_sunken = game_id + cell_offset + 47
|
||||
lpc_helix = game_id + cell_offset + 50
|
||||
mp_klaww = game_id + cell_offset + 86
|
||||
mp_end = game_id + cell_offset + 87
|
||||
sm_yellow_switch = game_id + cell_offset + 60
|
||||
sm_fort_gate = game_id + cell_offset + 63
|
||||
lt_end = game_id + cell_offset + 89
|
||||
gmc_blue_sage = game_id + cell_offset + 71
|
||||
gmc_red_sage = game_id + cell_offset + 72
|
||||
gmc_yellow_sage = game_id + cell_offset + 73
|
||||
gmc_green_sage = game_id + cell_offset + 70
|
||||
# You DO need to convert the game ID's to AP ID's here.
|
||||
gr_cells = {Cells.to_ap_id(k) for k in Cells.locGR_cellTable}
|
||||
fj_temple_top = Cells.to_ap_id(4)
|
||||
fj_blue_switch = Cells.to_ap_id(2)
|
||||
fj_plant_boss = Cells.to_ap_id(6)
|
||||
fj_fisherman = Cells.to_ap_id(5)
|
||||
sb_flut_flut = Cells.to_ap_id(17)
|
||||
fc_end = Cells.to_ap_id(69)
|
||||
pb_purple_rings = Cells.to_ap_id(58)
|
||||
lpc_sunken = Cells.to_ap_id(47)
|
||||
lpc_helix = Cells.to_ap_id(50)
|
||||
mp_klaww = Cells.to_ap_id(86)
|
||||
mp_end = Cells.to_ap_id(87)
|
||||
sm_yellow_switch = Cells.to_ap_id(60)
|
||||
sm_fort_gate = Cells.to_ap_id(63)
|
||||
lt_end = Cells.to_ap_id(89)
|
||||
gmc_blue_sage = Cells.to_ap_id(71)
|
||||
gmc_red_sage = Cells.to_ap_id(72)
|
||||
gmc_yellow_sage = Cells.to_ap_id(73)
|
||||
gmc_green_sage = Cells.to_ap_id(70)
|
||||
|
||||
# Start connecting regions and set their access rules.
|
||||
connect_start(multiworld, player, JakAndDaxterLevel.GEYSER_ROCK)
|
||||
connect_start(multiworld, player, Jak1Level.GEYSER_ROCK)
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.GEYSER_ROCK,
|
||||
JakAndDaxterLevel.SANDOVER_VILLAGE,
|
||||
Jak1Level.GEYSER_ROCK,
|
||||
Jak1Level.SANDOVER_VILLAGE,
|
||||
lambda state: state.has_all({item_table[k] for k in gr_cells}, player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.SANDOVER_VILLAGE,
|
||||
JakAndDaxterLevel.FORBIDDEN_JUNGLE)
|
||||
Jak1Level.SANDOVER_VILLAGE,
|
||||
Jak1Level.FORBIDDEN_JUNGLE)
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.FORBIDDEN_JUNGLE,
|
||||
JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM,
|
||||
Jak1Level.FORBIDDEN_JUNGLE,
|
||||
Jak1SubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM,
|
||||
lambda state: state.has(item_table[fj_temple_top], player))
|
||||
|
||||
connect_subregions(multiworld, player,
|
||||
JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM,
|
||||
JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM,
|
||||
Jak1SubLevel.FORBIDDEN_JUNGLE_SWITCH_ROOM,
|
||||
Jak1SubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM,
|
||||
lambda state: state.has(item_table[fj_blue_switch], player))
|
||||
|
||||
connect_sub_to_region(multiworld, player,
|
||||
JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM,
|
||||
JakAndDaxterLevel.FORBIDDEN_JUNGLE,
|
||||
Jak1SubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM,
|
||||
Jak1Level.FORBIDDEN_JUNGLE,
|
||||
lambda state: state.has(item_table[fj_plant_boss], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.SANDOVER_VILLAGE,
|
||||
JakAndDaxterLevel.SENTINEL_BEACH)
|
||||
Jak1Level.SANDOVER_VILLAGE,
|
||||
Jak1Level.SENTINEL_BEACH)
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.SENTINEL_BEACH,
|
||||
JakAndDaxterSubLevel.SENTINEL_BEACH_CANNON_TOWER,
|
||||
Jak1Level.SENTINEL_BEACH,
|
||||
Jak1SubLevel.SENTINEL_BEACH_CANNON_TOWER,
|
||||
lambda state: state.has(item_table[fj_blue_switch], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.SANDOVER_VILLAGE,
|
||||
JakAndDaxterLevel.MISTY_ISLAND,
|
||||
Jak1Level.SANDOVER_VILLAGE,
|
||||
Jak1Level.MISTY_ISLAND,
|
||||
lambda state: state.has(item_table[fj_fisherman], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.SANDOVER_VILLAGE,
|
||||
JakAndDaxterLevel.FIRE_CANYON,
|
||||
Jak1Level.SANDOVER_VILLAGE,
|
||||
Jak1Level.FIRE_CANYON,
|
||||
lambda state: state.count_group("Power Cell", player) >= 20)
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.FIRE_CANYON,
|
||||
JakAndDaxterLevel.ROCK_VILLAGE,
|
||||
Jak1Level.FIRE_CANYON,
|
||||
Jak1Level.ROCK_VILLAGE,
|
||||
lambda state: state.has(item_table[fc_end], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.ROCK_VILLAGE,
|
||||
JakAndDaxterLevel.PRECURSOR_BASIN)
|
||||
Jak1Level.ROCK_VILLAGE,
|
||||
Jak1Level.PRECURSOR_BASIN)
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.PRECURSOR_BASIN,
|
||||
JakAndDaxterSubLevel.PRECURSOR_BASIN_BLUE_RINGS,
|
||||
Jak1Level.PRECURSOR_BASIN,
|
||||
Jak1SubLevel.PRECURSOR_BASIN_BLUE_RINGS,
|
||||
lambda state: state.has(item_table[pb_purple_rings], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.ROCK_VILLAGE,
|
||||
JakAndDaxterLevel.LOST_PRECURSOR_CITY)
|
||||
Jak1Level.ROCK_VILLAGE,
|
||||
Jak1Level.LOST_PRECURSOR_CITY)
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.LOST_PRECURSOR_CITY,
|
||||
JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM)
|
||||
Jak1Level.LOST_PRECURSOR_CITY,
|
||||
Jak1SubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM)
|
||||
|
||||
connect_subregions(multiworld, player,
|
||||
JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM,
|
||||
JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM)
|
||||
Jak1SubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM,
|
||||
Jak1SubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM)
|
||||
|
||||
connect_sub_to_region(multiworld, player,
|
||||
JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM,
|
||||
JakAndDaxterLevel.LOST_PRECURSOR_CITY,
|
||||
Jak1SubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM,
|
||||
Jak1Level.LOST_PRECURSOR_CITY,
|
||||
lambda state: state.has(item_table[lpc_helix], player))
|
||||
|
||||
connect_sub_to_region(multiworld, player,
|
||||
JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM,
|
||||
JakAndDaxterLevel.ROCK_VILLAGE,
|
||||
Jak1SubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM,
|
||||
Jak1Level.ROCK_VILLAGE,
|
||||
lambda state: state.has(item_table[lpc_sunken], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.ROCK_VILLAGE,
|
||||
JakAndDaxterLevel.BOGGY_SWAMP)
|
||||
Jak1Level.ROCK_VILLAGE,
|
||||
Jak1Level.BOGGY_SWAMP)
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.BOGGY_SWAMP,
|
||||
JakAndDaxterSubLevel.BOGGY_SWAMP_FLUT_FLUT,
|
||||
Jak1Level.BOGGY_SWAMP,
|
||||
Jak1SubLevel.BOGGY_SWAMP_FLUT_FLUT,
|
||||
lambda state: state.has(item_table[sb_flut_flut], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.ROCK_VILLAGE,
|
||||
JakAndDaxterLevel.MOUNTAIN_PASS,
|
||||
Jak1Level.ROCK_VILLAGE,
|
||||
Jak1Level.MOUNTAIN_PASS,
|
||||
lambda state: state.count_group("Power Cell", player) >= 45)
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.MOUNTAIN_PASS,
|
||||
JakAndDaxterSubLevel.MOUNTAIN_PASS_RACE,
|
||||
Jak1Level.MOUNTAIN_PASS,
|
||||
Jak1SubLevel.MOUNTAIN_PASS_RACE,
|
||||
lambda state: state.has(item_table[mp_klaww], player))
|
||||
|
||||
connect_subregions(multiworld, player,
|
||||
JakAndDaxterSubLevel.MOUNTAIN_PASS_RACE,
|
||||
JakAndDaxterSubLevel.MOUNTAIN_PASS_SHORTCUT,
|
||||
Jak1SubLevel.MOUNTAIN_PASS_RACE,
|
||||
Jak1SubLevel.MOUNTAIN_PASS_SHORTCUT,
|
||||
lambda state: state.has(item_table[sm_yellow_switch], player))
|
||||
|
||||
connect_sub_to_region(multiworld, player,
|
||||
JakAndDaxterSubLevel.MOUNTAIN_PASS_RACE,
|
||||
JakAndDaxterLevel.VOLCANIC_CRATER,
|
||||
Jak1SubLevel.MOUNTAIN_PASS_RACE,
|
||||
Jak1Level.VOLCANIC_CRATER,
|
||||
lambda state: state.has(item_table[mp_end], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.VOLCANIC_CRATER,
|
||||
JakAndDaxterLevel.SPIDER_CAVE)
|
||||
Jak1Level.VOLCANIC_CRATER,
|
||||
Jak1Level.SPIDER_CAVE)
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.VOLCANIC_CRATER,
|
||||
JakAndDaxterLevel.SNOWY_MOUNTAIN)
|
||||
Jak1Level.VOLCANIC_CRATER,
|
||||
Jak1Level.SNOWY_MOUNTAIN)
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.SNOWY_MOUNTAIN,
|
||||
JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FROZEN_BOX,
|
||||
Jak1Level.SNOWY_MOUNTAIN,
|
||||
Jak1SubLevel.SNOWY_MOUNTAIN_FROZEN_BOX,
|
||||
lambda state: state.has(item_table[sm_yellow_switch], player))
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.SNOWY_MOUNTAIN,
|
||||
JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FLUT_FLUT,
|
||||
Jak1Level.SNOWY_MOUNTAIN,
|
||||
Jak1SubLevel.SNOWY_MOUNTAIN_FLUT_FLUT,
|
||||
lambda state: state.has(item_table[sb_flut_flut], player))
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.SNOWY_MOUNTAIN,
|
||||
JakAndDaxterSubLevel.SNOWY_MOUNTAIN_LURKER_FORT,
|
||||
Jak1Level.SNOWY_MOUNTAIN,
|
||||
Jak1SubLevel.SNOWY_MOUNTAIN_LURKER_FORT,
|
||||
lambda state: state.has(item_table[sm_fort_gate], player))
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.VOLCANIC_CRATER,
|
||||
JakAndDaxterLevel.LAVA_TUBE,
|
||||
Jak1Level.VOLCANIC_CRATER,
|
||||
Jak1Level.LAVA_TUBE,
|
||||
lambda state: state.count_group("Power Cell", player) >= 72)
|
||||
|
||||
connect_regions(multiworld, player,
|
||||
JakAndDaxterLevel.LAVA_TUBE,
|
||||
JakAndDaxterLevel.GOL_AND_MAIAS_CITADEL,
|
||||
Jak1Level.LAVA_TUBE,
|
||||
Jak1Level.GOL_AND_MAIAS_CITADEL,
|
||||
lambda state: state.has(item_table[lt_end], player))
|
||||
|
||||
connect_region_to_sub(multiworld, player,
|
||||
JakAndDaxterLevel.GOL_AND_MAIAS_CITADEL,
|
||||
JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER,
|
||||
Jak1Level.GOL_AND_MAIAS_CITADEL,
|
||||
Jak1SubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER,
|
||||
lambda state: state.has(item_table[gmc_blue_sage], player)
|
||||
and state.has(item_table[gmc_red_sage], player)
|
||||
and state.has(item_table[gmc_yellow_sage], player))
|
||||
|
||||
connect_subregions(multiworld, player,
|
||||
JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER,
|
||||
JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS,
|
||||
Jak1SubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER,
|
||||
Jak1SubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS,
|
||||
lambda state: state.has(item_table[gmc_green_sage], player))
|
||||
|
||||
multiworld.completion_condition[player] = lambda state: state.can_reach(
|
||||
multiworld.get_region(subLevel_table[JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS], player),
|
||||
multiworld.get_region(subLevel_table[Jak1SubLevel.GOL_AND_MAIAS_CITADEL_FINAL_BOSS], player),
|
||||
"Region",
|
||||
player)
|
||||
|
||||
|
||||
def connect_start(multiworld: MultiWorld, player: int, target: JakAndDaxterLevel):
|
||||
def connect_start(multiworld: MultiWorld, player: int, target: Jak1Level):
|
||||
menu_region = multiworld.get_region("Menu", player)
|
||||
start_region = multiworld.get_region(level_table[target], player)
|
||||
menu_region.connect(start_region)
|
||||
|
||||
|
||||
def connect_regions(multiworld: MultiWorld, player: int, source: JakAndDaxterLevel, target: JakAndDaxterLevel,
|
||||
rule=None):
|
||||
def connect_regions(multiworld: MultiWorld, player: int, source: Jak1Level, target: Jak1Level, rule=None):
|
||||
source_region = multiworld.get_region(level_table[source], player)
|
||||
target_region = multiworld.get_region(level_table[target], player)
|
||||
source_region.connect(target_region, rule=rule)
|
||||
|
||||
|
||||
def connect_region_to_sub(multiworld: MultiWorld, player: int, source: JakAndDaxterLevel, target: JakAndDaxterSubLevel,
|
||||
rule=None):
|
||||
def connect_region_to_sub(multiworld: MultiWorld, player: int, source: Jak1Level, target: Jak1SubLevel, rule=None):
|
||||
source_region = multiworld.get_region(level_table[source], player)
|
||||
target_region = multiworld.get_region(subLevel_table[target], player)
|
||||
source_region.connect(target_region, rule=rule)
|
||||
|
||||
|
||||
def connect_sub_to_region(multiworld: MultiWorld, player: int, source: JakAndDaxterSubLevel, target: JakAndDaxterLevel,
|
||||
rule=None):
|
||||
def connect_sub_to_region(multiworld: MultiWorld, player: int, source: Jak1SubLevel, target: Jak1Level, rule=None):
|
||||
source_region = multiworld.get_region(subLevel_table[source], player)
|
||||
target_region = multiworld.get_region(level_table[target], player)
|
||||
source_region.connect(target_region, rule=rule)
|
||||
|
||||
|
||||
def connect_subregions(multiworld: MultiWorld, player: int, source: JakAndDaxterSubLevel, target: JakAndDaxterSubLevel,
|
||||
rule=None):
|
||||
def connect_subregions(multiworld: MultiWorld, player: int, source: Jak1SubLevel, target: Jak1SubLevel, rule=None):
|
||||
source_region = multiworld.get_region(subLevel_table[source], player)
|
||||
target_region = multiworld.get_region(subLevel_table[target], player)
|
||||
source_region.connect(target_region, rule=rule)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
from BaseClasses import Item, ItemClassification
|
||||
from .Locations import JakAndDaxterLocation, location_table as item_table
|
||||
from .GameID import jak1_id, jak1_name
|
||||
from .Options import JakAndDaxterOptions
|
||||
from .Regions import JakAndDaxterLevel, JakAndDaxterSubLevel, JakAndDaxterRegion, level_table, subLevel_table, \
|
||||
create_regions
|
||||
from .Rules import set_rules
|
||||
from .Items import JakAndDaxterItem
|
||||
from .GameID import game_id, game_name, cell_offset, fly_offset, orb_offset
|
||||
from .Locations import JakAndDaxterLocation, location_table as item_table
|
||||
from .locs import CellLocations as Cells, ScoutLocations as Scouts, OrbLocations as Orbs
|
||||
from .Regions import create_regions
|
||||
from .Rules import set_rules
|
||||
from ..AutoWorld import World
|
||||
|
||||
|
||||
class JakAndDaxterWorld(World):
|
||||
game: str = game_name
|
||||
game: str = jak1_name
|
||||
data_version = 1
|
||||
required_client_version = (0, 4, 5)
|
||||
|
||||
@@ -18,13 +18,14 @@ class JakAndDaxterWorld(World):
|
||||
options: JakAndDaxterOptions
|
||||
|
||||
# Stored as {ID: Name} pairs, these must now be swapped to {Name: ID} pairs.
|
||||
# Remember, the game ID and various offsets for each item type have already been calculated.
|
||||
item_name_to_id = {item_table[k]: k for k in item_table}
|
||||
location_name_to_id = {item_table[k]: k for k in item_table}
|
||||
item_name_groups = {
|
||||
"Power Cell": {item_table[k]: k
|
||||
for k in item_table if k in range(game_id + cell_offset, game_id + fly_offset)},
|
||||
"Scout Fly": {item_table[k]: k
|
||||
for k in item_table if k in range(game_id + fly_offset, game_id + orb_offset)},
|
||||
"Power Cell": {item_table[k]: k for k in item_table
|
||||
if k in range(jak1_id, jak1_id + Scouts.fly_offset)},
|
||||
"Scout Fly": {item_table[k]: k for k in item_table
|
||||
if k in range(jak1_id + Scouts.fly_offset, jak1_id + Orbs.orb_offset)},
|
||||
"Precursor Orb": {} # TODO
|
||||
}
|
||||
|
||||
@@ -39,13 +40,13 @@ class JakAndDaxterWorld(World):
|
||||
|
||||
def create_item(self, name: str) -> Item:
|
||||
item_id = self.item_name_to_id[name]
|
||||
if item_id in range(game_id + cell_offset, game_id + fly_offset):
|
||||
if item_id in range(jak1_id, jak1_id + Scouts.fly_offset):
|
||||
# Power Cell
|
||||
classification = ItemClassification.progression_skip_balancing
|
||||
elif item_id in range(game_id + fly_offset, game_id + orb_offset):
|
||||
elif item_id in range(jak1_id + Scouts.fly_offset, jak1_id + Orbs.orb_offset):
|
||||
# Scout Fly
|
||||
classification = ItemClassification.progression_skip_balancing
|
||||
elif item_id > game_id + orb_offset:
|
||||
elif item_id > jak1_id + Orbs.orb_offset:
|
||||
# Precursor Orb
|
||||
classification = ItemClassification.filler # TODO
|
||||
else:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from ..GameID import jak1_id
|
||||
|
||||
# Power Cells are given ID's between 0 and 116 by the game.
|
||||
|
||||
# The game tracks all game-tasks as integers.
|
||||
@@ -5,6 +7,17 @@
|
||||
# necessarily ordered, nor are they the first 101 in the task list.
|
||||
# The remaining ones are cutscenes and other events.
|
||||
|
||||
|
||||
# These helper functions do all the math required to get information about each
|
||||
# power cell and translate its ID between AP and OpenGOAL.
|
||||
def to_ap_id(game_id: int) -> int:
|
||||
return jak1_id + game_id
|
||||
|
||||
|
||||
def to_game_id(ap_id: int) -> int:
|
||||
return ap_id - jak1_id
|
||||
|
||||
|
||||
# The ID's you see below correspond directly to that cell's game-task ID.
|
||||
|
||||
# Geyser Rock
|
||||
|
||||
@@ -1,7 +1,38 @@
|
||||
# Precursor Orbs start at ??? and end at ???
|
||||
from ..GameID import jak1_id
|
||||
|
||||
# Given that Scout Flies are being offset by 2^20 to avoid collisions with power cells,
|
||||
# I'm tentatively setting the Orb offset to 2^21, or 2,097,152.
|
||||
# Precursor Orbs are not necessarily given ID's by the game.
|
||||
|
||||
# Of the 2000 orbs (or "money") you can pick up, only 1233 are standalone ones you find in the overworld.
|
||||
# We can identify them by Actor ID's, which run from 549 to 24433. Other actors reside in this range,
|
||||
# so like Power Cells these are not ordered, nor contiguous, nor exclusively orbs.
|
||||
|
||||
# In fact, other ID's in this range belong to actors that spawn orbs when they are activated or when they die,
|
||||
# like steel crates, orb caches, Spider Cave gnawers, or jumping on the Plant Boss's head.
|
||||
|
||||
# These orbs that spawn from parent actors DON'T have an Actor ID themselves - the parent object keeps
|
||||
# track of how many of its orbs have been picked up. If you pick up only some of its orbs, it
|
||||
# will respawn when you leave the area, and only drop the remaining number of orbs when activated/killed.
|
||||
# Once all the orbs are picked up, the actor will permanently "retire" and never spawn again.
|
||||
# The maximum number of orbs that any actor can spawn is 30 (the orb caches in citadel). Covering
|
||||
# these ID-less orbs may need to be a future enhancement. TODO ^^
|
||||
|
||||
# Standalone orbs need 15 bits to identify themselves by Actor ID,
|
||||
# so we can use 2^15 to offset them from scout flies, just like we offset
|
||||
# scout flies from power cells by 2^10.
|
||||
orb_offset = 32768
|
||||
|
||||
|
||||
# These helper functions do all the math required to get information about each
|
||||
# precursor orb and translate its ID between AP and OpenGOAL.
|
||||
def to_ap_id(game_id: int) -> int:
|
||||
return jak1_id + orb_offset + game_id # Add the offsets and the orb Actor ID.
|
||||
|
||||
|
||||
def to_game_id(ap_id: int) -> int:
|
||||
return ap_id - jak1_id - orb_offset # Reverse process, subtract the offsets.
|
||||
|
||||
|
||||
# The ID's you see below correspond directly to that orb's Actor ID in the game.
|
||||
|
||||
# Geyser Rock
|
||||
locGR_orbTable = {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from ..GameID import jak1_id
|
||||
|
||||
# Scout Flies are given ID's between 0 and 393311 by the game, explanation below.
|
||||
|
||||
# Each fly is given a unique 32-bit number broken into two 16-bit numbers.
|
||||
# Each fly (or "buzzer") is given a unique 32-bit number broken into two 16-bit numbers.
|
||||
# The lower 16 bits are the game-task ID of the power cell the fly corresponds to.
|
||||
# The higher 16 bits are the index of the fly itself, from 000 (0) to 110 (6).
|
||||
|
||||
@@ -10,10 +12,32 @@
|
||||
|
||||
# Because flies are indexed from 0, each 0th fly's full ID == the power cell's ID.
|
||||
# So we need to offset all of their ID's in order for Archipelago to separate them
|
||||
# from their power cells. We use 128 (2^7) for this purpose, because scout flies
|
||||
# never use the 8th lowest bit to describe themselves.
|
||||
# from their power cells. We can use 1024 (2^10) for this purpose, because scout flies
|
||||
# only ever need 10 bits to identify themselves (3 for the index, 7 for the cell ID).
|
||||
fly_offset = 1024
|
||||
|
||||
# TODO - The ID's you see below correspond directly to that fly's 32-bit ID in the game.
|
||||
|
||||
# These helper functions do all the math required to get information about each
|
||||
# scout fly and translate its ID between AP and OpenGOAL.
|
||||
def to_ap_id(game_id: int) -> int:
|
||||
cell_id = get_cell_id(game_id) # This is AP/OpenGOAL agnostic, works on either ID.
|
||||
buzzer_index = (game_id - cell_id) >> 9 # Subtract the cell ID, bit shift the index down 9 places.
|
||||
return jak1_id + fly_offset + buzzer_index + cell_id # Add the offsets, the bit-shifted index, and the cell ID.
|
||||
|
||||
|
||||
def to_game_id(ap_id: int) -> int:
|
||||
cell_id = get_cell_id(ap_id) # This is AP/OpenGOAL agnostic, works on either ID.
|
||||
buzzer_index = ap_id - jak1_id - fly_offset - cell_id # Reverse process, subtract the offsets and the cell ID.
|
||||
return (buzzer_index << 9) + cell_id # Bit shift the index up 9 places, re-add the cell ID.
|
||||
|
||||
|
||||
def get_cell_id(buzzer_id: int) -> int:
|
||||
return buzzer_id & 0b1111111 # Get the power cell ID from the lowest 7 bits.
|
||||
|
||||
|
||||
# The ID's you see below correspond directly to that fly's 32-bit ID in the game.
|
||||
# I used the decompiled entity JSON's and Jak's X/Y coordinates in Debug Mode
|
||||
# to determine which box ID is which location.
|
||||
|
||||
# Geyser Rock
|
||||
locGR_scoutTable = {
|
||||
@@ -61,46 +85,46 @@ locSB_scoutTable = {
|
||||
|
||||
# Misty Island
|
||||
locMI_scoutTable = {
|
||||
129: "MI: Scout Fly Overlooking Entrance",
|
||||
130: "MI: Scout Fly On Ledge Path, First",
|
||||
131: "MI: Scout Fly On Ledge Path, Second",
|
||||
132: "MI: Scout Fly Overlooking Shipyard",
|
||||
133: "MI: Scout Fly On Ship",
|
||||
134: "MI: Scout Fly On Barrel Ramps",
|
||||
135: "MI: Scout Fly On Zoomer Ramps"
|
||||
327708: "MI: Scout Fly Overlooking Entrance",
|
||||
65564: "MI: Scout Fly On Ledge Near Arena Entrance",
|
||||
262172: "MI: Scout Fly Near Arena Door",
|
||||
28: "MI: Scout Fly On Ledge Near Arena Exit",
|
||||
131100: "MI: Scout Fly On Ship",
|
||||
196636: "MI: Scout Fly On Barrel Ramps",
|
||||
393244: "MI: Scout Fly On Zoomer Ramps"
|
||||
}
|
||||
|
||||
# Fire Canyon
|
||||
locFC_scoutTable = {
|
||||
136: "FC: Scout Fly 1",
|
||||
137: "FC: Scout Fly 2",
|
||||
138: "FC: Scout Fly 3",
|
||||
139: "FC: Scout Fly 4",
|
||||
140: "FC: Scout Fly 5",
|
||||
141: "FC: Scout Fly 6",
|
||||
142: "FC: Scout Fly 7"
|
||||
393284: "FC: Scout Fly 1",
|
||||
68: "FC: Scout Fly 2",
|
||||
65604: "FC: Scout Fly 3",
|
||||
196676: "FC: Scout Fly 4",
|
||||
131140: "FC: Scout Fly 5",
|
||||
262212: "FC: Scout Fly 6",
|
||||
327748: "FC: Scout Fly 7"
|
||||
}
|
||||
|
||||
# Rock Village
|
||||
locRV_scoutTable = {
|
||||
143: "RV: Scout Fly Behind Sage's Hut",
|
||||
144: "RV: Scout Fly On Path To Village",
|
||||
145: "RV: Scout Fly Behind Geologist",
|
||||
146: "RV: Scout Fly Behind Fiery Boulder",
|
||||
147: "RV: Scout Fly On Dock",
|
||||
148: "RV: Scout Fly At Pontoon Bridge",
|
||||
149: "RV: Scout Fly At Boggy Swamp Entrance"
|
||||
76: "RV: Scout Fly Behind Sage's Hut",
|
||||
131148: "RV: Scout Fly Near Waterfall",
|
||||
196684: "RV: Scout Fly Behind Geologist",
|
||||
262220: "RV: Scout Fly Behind Fiery Boulder",
|
||||
65612: "RV: Scout Fly On Dock",
|
||||
327756: "RV: Scout Fly At Pontoon Bridge",
|
||||
393292: "RV: Scout Fly At Boggy Swamp Entrance"
|
||||
}
|
||||
|
||||
# Precursor Basin
|
||||
locPB_scoutTable = {
|
||||
150: "PB: Scout Fly Overlooking Entrance",
|
||||
151: "PB: Scout Fly Near Mole Hole",
|
||||
152: "PB: Scout Fly At Purple Ring Start",
|
||||
153: "PB: Scout Fly Overlooking Dark Eco Plant",
|
||||
154: "PB: Scout Fly At Green Ring Start",
|
||||
155: "PB: Scout Fly Before Big Jump",
|
||||
156: "PB: Scout Fly Near Dark Eco Plant"
|
||||
196665: "PB: Scout Fly Overlooking Entrance",
|
||||
393273: "PB: Scout Fly Near Mole Hole",
|
||||
131129: "PB: Scout Fly At Purple Ring Start",
|
||||
65593: "PB: Scout Fly Near Dark Eco Plant, Above",
|
||||
57: "PB: Scout Fly At Blue Ring Start",
|
||||
262201: "PB: Scout Fly Before Big Jump",
|
||||
327737: "PB: Scout Fly Near Dark Eco Plant, Below"
|
||||
}
|
||||
|
||||
# Lost Precursor City
|
||||
|
||||
Reference in New Issue
Block a user