diff --git a/worlds/jakanddaxter/GameID.py b/worlds/jakanddaxter/GameID.py index e4ebb030f8..a025f2752a 100644 --- a/worlds/jakanddaxter/GameID.py +++ b/worlds/jakanddaxter/GameID.py @@ -9,5 +9,5 @@ game_name = "Jak and Daxter: The Precursor Legacy" # ID numbers shared across items. See respective # Locations files for explanations. cell_offset = 0 -fly_offset = 1048576 # 2^20 +fly_offset = 128 # 2^7 orb_offset = 2097152 # 2^21 diff --git a/worlds/jakanddaxter/Regions.py b/worlds/jakanddaxter/Regions.py index 787ad59214..8fb62c9eda 100644 --- a/worlds/jakanddaxter/Regions.py +++ b/worlds/jakanddaxter/Regions.py @@ -32,6 +32,8 @@ class JakAndDaxterSubLevel(int, Enum): FORBIDDEN_JUNGLE_PLANT_ROOM = auto() SENTINEL_BEACH_CANNON_TOWER = auto() PRECURSOR_BASIN_BLUE_RINGS = auto() + LOST_PRECURSOR_CITY_SUNKEN_ROOM = auto() + LOST_PRECURSOR_CITY_HELIX_ROOM = auto() BOGGY_SWAMP_FLUT_FLUT = auto() MOUNTAIN_PASS_RACE = auto() MOUNTAIN_PASS_SHORTCUT = auto() @@ -67,6 +69,8 @@ subLevel_table: typing.Dict[JakAndDaxterSubLevel, str] = { 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", @@ -133,8 +137,17 @@ def create_regions(multiworld: MultiWorld, options: JakAndDaxterOptions, player: create_cell_locations(sub_region_pbbr, {k: CellLocations.locPB_cellTable[k] for k in {59}}) region_lpc = create_region(player, multiworld, level_table[JakAndDaxterLevel.LOST_PRECURSOR_CITY]) - create_cell_locations(region_lpc, CellLocations.locLPC_cellTable) - create_fly_locations(region_lpc, ScoutLocations.locLPC_scoutTable) + 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}}) + + 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_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}}) 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}}) diff --git a/worlds/jakanddaxter/Rules.py b/worlds/jakanddaxter/Rules.py index deeef7c92d..58585bba18 100644 --- a/worlds/jakanddaxter/Rules.py +++ b/worlds/jakanddaxter/Rules.py @@ -12,10 +12,13 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) 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 - pb_purple_rings = game_id + cell_offset + 58 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 @@ -48,6 +51,11 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterSubLevel.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, + lambda state: state.has(item_table[fj_plant_boss], player)) + connect_regions(multiworld, player, JakAndDaxterLevel.SANDOVER_VILLAGE, JakAndDaxterLevel.SENTINEL_BEACH) @@ -85,6 +93,24 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterLevel.ROCK_VILLAGE, JakAndDaxterLevel.LOST_PRECURSOR_CITY) + connect_region_to_sub(multiworld, player, + JakAndDaxterLevel.LOST_PRECURSOR_CITY, + JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM) + + connect_subregions(multiworld, player, + JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_SUNKEN_ROOM, + JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM) + + connect_sub_to_region(multiworld, player, + JakAndDaxterSubLevel.LOST_PRECURSOR_CITY_HELIX_ROOM, + JakAndDaxterLevel.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, + lambda state: state.has(item_table[lpc_sunken], player)) + connect_regions(multiworld, player, JakAndDaxterLevel.ROCK_VILLAGE, JakAndDaxterLevel.BOGGY_SWAMP) @@ -109,10 +135,10 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterSubLevel.MOUNTAIN_PASS_SHORTCUT, lambda state: state.has(item_table[sm_yellow_switch], player)) - connect_regions(multiworld, player, - JakAndDaxterLevel.MOUNTAIN_PASS, - JakAndDaxterLevel.VOLCANIC_CRATER, - lambda state: state.has(item_table[mp_end], player)) + connect_sub_to_region(multiworld, player, + JakAndDaxterSubLevel.MOUNTAIN_PASS_RACE, + JakAndDaxterLevel.VOLCANIC_CRATER, + lambda state: state.has(item_table[mp_end], player)) connect_regions(multiworld, player, JakAndDaxterLevel.VOLCANIC_CRATER, @@ -185,6 +211,13 @@ def connect_region_to_sub(multiworld: MultiWorld, player: int, source: JakAndDax source_region.connect(target_region, rule=rule) +def connect_sub_to_region(multiworld: MultiWorld, player: int, source: JakAndDaxterSubLevel, target: JakAndDaxterLevel, + 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): source_region = multiworld.get_region(subLevel_table[source], player) diff --git a/worlds/jakanddaxter/locs/ScoutLocations.py b/worlds/jakanddaxter/locs/ScoutLocations.py index 1f86416d28..1672aadbd7 100644 --- a/worlds/jakanddaxter/locs/ScoutLocations.py +++ b/worlds/jakanddaxter/locs/ScoutLocations.py @@ -10,8 +10,8 @@ # 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 1,048,576 (2^20) for this purpose, because scout flies -# don't use more than 19 bits to describe themselves. +# from their power cells. We use 128 (2^7) for this purpose, because scout flies +# never use the 8th lowest bit to describe themselves. # TODO - The ID's you see below correspond directly to that fly's 32-bit ID in the game.