diff --git a/worlds/jakanddaxter/GameID.py b/worlds/jakanddaxter/GameID.py new file mode 100644 index 0000000000..f88a02a30a --- /dev/null +++ b/worlds/jakanddaxter/GameID.py @@ -0,0 +1 @@ +game_id = 74680000 # All IDs will be offset by this number. \ No newline at end of file diff --git a/worlds/jakanddaxter/Items.py b/worlds/jakanddaxter/Items.py index d1bac68258..d50810b77e 100644 --- a/worlds/jakanddaxter/Items.py +++ b/worlds/jakanddaxter/Items.py @@ -14,7 +14,7 @@ generic_item_table = { # Items Only Found Once special_item_table = { 2213: "Fisherman's Boat", - 2214: "Sculptor's Muse", + # 2214: "Sculptor's Muse", # Unused? 2215: "Flut Flut", 2216: "Blue Eco Switch", 2217: "Gladiator's Pontoons", diff --git a/worlds/jakanddaxter/Locations.py b/worlds/jakanddaxter/Locations.py index d74473951a..ee21ce079e 100644 --- a/worlds/jakanddaxter/Locations.py +++ b/worlds/jakanddaxter/Locations.py @@ -1,26 +1,27 @@ import typing from BaseClasses import Location -from .locs import CellLocations +from .locs import CellLocations, SpecialLocations class JakAndDaxterLocation(Location): game: str = "Jak and Daxter: The Precursor Legacy" # All Locations location_table = { - **CellLocations.locGR_cellTable, \ - **CellLocations.locSV_cellTable, \ - **CellLocations.locFJ_cellTable, \ - **CellLocations.locSB_cellTable, \ - **CellLocations.locMI_cellTable, \ - **CellLocations.locFC_cellTable, \ - **CellLocations.locRV_cellTable, \ - **CellLocations.locPB_cellTable, \ - **CellLocations.locLPC_cellTable, \ - **CellLocations.locBS_cellTable, \ - **CellLocations.locMP_cellTable, \ - **CellLocations.locVC_cellTable, \ - **CellLocations.locSC_cellTable, \ - **CellLocations.locSM_cellTable, \ - **CellLocations.locLT_cellTable, \ - **CellLocations.locGMC_cellTable + **CellLocations.locGR_cellTable, + **CellLocations.locSV_cellTable, + **CellLocations.locFJ_cellTable, + **CellLocations.locSB_cellTable, + **CellLocations.locMI_cellTable, + **CellLocations.locFC_cellTable, + **CellLocations.locRV_cellTable, + **CellLocations.locPB_cellTable, + **CellLocations.locLPC_cellTable, + **CellLocations.locBS_cellTable, + **CellLocations.locMP_cellTable, + **CellLocations.locVC_cellTable, + **CellLocations.locSC_cellTable, + **CellLocations.locSM_cellTable, + **CellLocations.locLT_cellTable, + **CellLocations.locGMC_cellTable, + **SpecialLocations.loc_specialTable } diff --git a/worlds/jakanddaxter/Regions.py b/worlds/jakanddaxter/Regions.py index 6f29e08172..dda46d1b18 100644 --- a/worlds/jakanddaxter/Regions.py +++ b/worlds/jakanddaxter/Regions.py @@ -3,7 +3,7 @@ from enum import Enum from BaseClasses import MultiWorld, Region, Entrance, Location from .Options import JakAndDaxterOptions from .Locations import JakAndDaxterLocation, location_table -from .locs import CellLocations +from .locs import CellLocations, SpecialLocations class JakAndDaxterLevel(int, Enum): GEYSER_ROCK = 0 @@ -76,13 +76,19 @@ def create_regions(multiworld: MultiWorld, options: JakAndDaxterOptions, player: create_locations(regionSV, CellLocations.locSV_cellTable) regionFJ = create_region(player, multiworld, level_table[JakAndDaxterLevel.FORBIDDEN_JUNGLE]) - create_locations(regionFJ, {k: CellLocations.locFJ_cellTable[k] for k in {10, 11, 12, 14, 15, 16, 17}}) + create_locations(regionFJ, { + **{k: CellLocations.locFJ_cellTable[k] for k in {10, 11, 12, 14, 15, 16, 17}}, + **{k: SpecialLocations.loc_specialTable[k] for k in {2213, 2216}} + }) subRegionFJPR = create_subregion(regionFJ, subLevel_table[JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM]) create_locations(subRegionFJPR, {k: CellLocations.locFJ_cellTable[k] for k in {13}}) regionSB = create_region(player, multiworld, level_table[JakAndDaxterLevel.SENTINEL_BEACH]) - create_locations(regionSB, {k: CellLocations.locSB_cellTable[k] for k in {18, 19, 20, 21, 23, 24, 25}}) + create_locations(regionSB, { + **{k: CellLocations.locSB_cellTable[k] for k in {18, 19, 20, 21, 23, 24, 25}}, + **{k: SpecialLocations.loc_specialTable[k] for k in {2215}} + }) subRegionSBCT = create_subregion(regionSB, subLevel_table[JakAndDaxterSubLevel.SENTINEL_BEACH_CANNON_TOWER]) create_locations(subRegionSBCT, {k: CellLocations.locSB_cellTable[k] for k in {22}}) @@ -94,7 +100,10 @@ def create_regions(multiworld: MultiWorld, options: JakAndDaxterOptions, player: create_locations(regionFC, CellLocations.locFC_cellTable) regionRV = create_region(player, multiworld, level_table[JakAndDaxterLevel.ROCK_VILLAGE]) - create_locations(regionRV, CellLocations.locRV_cellTable) + create_locations(regionRV, { + **CellLocations.locRV_cellTable, + **{k: SpecialLocations.loc_specialTable[k] for k in {2217}} + }) regionPB = create_region(player, multiworld, level_table[JakAndDaxterLevel.PRECURSOR_BASIN]) create_locations(regionPB, CellLocations.locPB_cellTable) @@ -121,10 +130,16 @@ def create_regions(multiworld: MultiWorld, options: JakAndDaxterOptions, player: create_locations(regionSC, CellLocations.locSC_cellTable) regionSM = create_region(player, multiworld, level_table[JakAndDaxterLevel.SNOWY_MOUNTAIN]) - create_locations(regionSM, {k: CellLocations.locSM_cellTable[k] for k in {86, 87, 88, 89, 92}}) + create_locations(regionSM, { + **{k: CellLocations.locSM_cellTable[k] for k in {86, 87, 88, 89, 92}}, + **{k: SpecialLocations.loc_specialTable[k] for k in {2218}} + }) subRegionSMFF = create_subregion(regionSM, subLevel_table[JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FLUT_FLUT]) - create_locations(subRegionSMFF, {k: CellLocations.locSM_cellTable[k] for k in {90}}) + create_locations(subRegionSMFF, { + **{k: CellLocations.locSM_cellTable[k] for k in {90}}, + **{k: SpecialLocations.loc_specialTable[k] for k in {2219}} + }) subRegionSMLF = create_subregion(regionSM, subLevel_table[JakAndDaxterSubLevel.SNOWY_MOUNTAIN_LURKER_FORT]) create_locations(subRegionSMLF, {k: CellLocations.locSM_cellTable[k] for k in {91, 93}}) @@ -147,16 +162,8 @@ def create_region(player: int, multiworld: MultiWorld, name: str) -> JakAndDaxte def create_subregion(parent: Region, name: str) -> JakAndDaxterRegion: region = JakAndDaxterRegion(name, parent.player, parent.multiworld) - connection = Entrance(parent.player, name, parent) - connection.connect(region) - parent.entrances.append(connection) - - # connection = Entrance(parent.player, parent.name + " " + subLevel_table[JakAndDaxterSubLevel.MAIN_AREA], parent) - # connection.connect(parent) - # region.entrances.append(connection) - parent.multiworld.regions.append(region) return region def create_locations(region: Region, locs: typing.Dict[int, str]): - region.locations += [JakAndDaxterLocation(region.player, loc, location_table[loc], region) for loc in locs] + region.locations += [JakAndDaxterLocation(region.player, location_table[loc], loc, region) for loc in locs] diff --git a/worlds/jakanddaxter/Rules.py b/worlds/jakanddaxter/Rules.py index 069e6e6e5f..be9c16cd61 100644 --- a/worlds/jakanddaxter/Rules.py +++ b/worlds/jakanddaxter/Rules.py @@ -20,7 +20,8 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterLevel.SANDOVER_VILLAGE, JakAndDaxterLevel.FORBIDDEN_JUNGLE) - assign_subregion_access_rule(multiworld, player, + connect_subregions(multiworld, player, + JakAndDaxterLevel.FORBIDDEN_JUNGLE, JakAndDaxterSubLevel.FORBIDDEN_JUNGLE_PLANT_ROOM, lambda state: state.has(item_table[2216], player)) @@ -28,7 +29,8 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterLevel.SANDOVER_VILLAGE, JakAndDaxterLevel.SENTINEL_BEACH) - assign_subregion_access_rule(multiworld, player, + connect_subregions(multiworld, player, + JakAndDaxterLevel.SENTINEL_BEACH, JakAndDaxterSubLevel.SENTINEL_BEACH_CANNON_TOWER, lambda state: state.has(item_table[2216], player)) @@ -59,7 +61,8 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterLevel.BOGGY_SWAMP, lambda state: state.has(item_table[2217], player)) - assign_subregion_access_rule(multiworld, player, + connect_subregions(multiworld, player, + JakAndDaxterLevel.BOGGY_SWAMP, JakAndDaxterSubLevel.BOGGY_SWAMP_FLUT_FLUT, lambda state: state.has(item_table[2215], player)) @@ -68,7 +71,8 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterLevel.MOUNTAIN_PASS, lambda state: state.has(item_table[2217], player) and state.has(item_table[0], player, 45)) - assign_subregion_access_rule(multiworld, player, + connect_subregions(multiworld, player, + JakAndDaxterLevel.MOUNTAIN_PASS, JakAndDaxterSubLevel.MOUNTAIN_PASS_SHORTCUT, lambda state: state.has(item_table[2218], player)) @@ -84,11 +88,13 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterLevel.VOLCANIC_CRATER, JakAndDaxterLevel.SNOWY_MOUNTAIN) - assign_subregion_access_rule(multiworld, player, + connect_subregions(multiworld, player, + JakAndDaxterLevel.SNOWY_MOUNTAIN, JakAndDaxterSubLevel.SNOWY_MOUNTAIN_FLUT_FLUT, lambda state: state.has(item_table[2215], player)) - assign_subregion_access_rule(multiworld, player, + connect_subregions(multiworld, player, + JakAndDaxterLevel.SNOWY_MOUNTAIN, JakAndDaxterSubLevel.SNOWY_MOUNTAIN_LURKER_FORT, lambda state: state.has(item_table[2219], player)) @@ -101,15 +107,22 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) JakAndDaxterLevel.LAVA_TUBE, JakAndDaxterLevel.GOL_AND_MAIAS_CITADEL) - assign_subregion_access_rule(multiworld, player, + connect_subregions(multiworld, player, + JakAndDaxterLevel.GOL_AND_MAIAS_CITADEL, JakAndDaxterSubLevel.GOL_AND_MAIAS_CITADEL_ROTATING_TOWER, - lambda state: state.has(item_table[96], player) and state.has(item_table[97], player) and state.has(item_table[98], player)) + # lambda state: state.has(item_table[96], player) and state.has(item_table[97], player) and state.has(item_table[98], player)) + lambda state: state.has(item_table[0], player, 75)) def connect_regions(multiworld: MultiWorld, player: int, source: int, target: int, rule = None): sourceRegion = multiworld.get_region(level_table[source], player) targetRegion = multiworld.get_region(level_table[target], player) sourceRegion.connect(targetRegion, rule = rule) +def connect_subregions(multiworld: MultiWorld, player: int, source: int, target: int, rule = None): + sourceRegion = multiworld.get_region(level_table[source], player) + targetRegion = multiworld.get_region(subLevel_table[target], player) + sourceRegion.connect(targetRegion, rule = rule) + def assign_subregion_access_rule(multiworld: MultiWorld, player: int, target: int, rule = None): targetEntrance = multiworld.get_entrance(subLevel_table[target], player) targetEntrance.access_rule = rule diff --git a/worlds/jakanddaxter/__init__.py b/worlds/jakanddaxter/__init__.py index 7ff173e4f4..ecbcbd2fa0 100644 --- a/worlds/jakanddaxter/__init__.py +++ b/worlds/jakanddaxter/__init__.py @@ -5,35 +5,33 @@ 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, item_table, generic_item_table, special_item_table +from .GameID import game_id from ..AutoWorld import World from Utils import visualize_regions - class JakAndDaxterWorld(World): game: str = "Jak and Daxter: The Precursor Legacy" - game_id = 74680000 # All IDs will be offset by this number. # Stored as {ID: Name} pairs, these must now be swapped to {Name: ID} pairs. - item_name_to_id = {item_table[k]: 74680000 + k for k in item_table} - location_name_to_id = {location_table[k]: 74680000 + k for k in location_table} + item_name_to_id = {item_table[k]: game_id + k for k in item_table} + location_name_to_id = {location_table[k]: game_id + k for k in location_table} options_dataclass = JakAndDaxterOptions + options: JakAndDaxterOptions def create_regions(self): create_regions(self.multiworld, self.options, self.player) def set_rules(self): set_rules(self.multiworld, self.options, self.player) - visualize_regions(self.multiworld.get_region("Menu", self.player), "my_world.puml") - def create_item(self, name: str) -> Item: - item_id = self.item_name_to_id[name] - if name == "Power Cell": + def create_item(self, name: str, item_id: int) -> Item: + if "Power Cell" in name: classification = ItemClassification.progression_skip_balancing - elif name == "Scout Fly": + elif "Scout Fly" in name: classification = ItemClassification.progression_skip_balancing - elif name == "Precursor Orb": + elif "Precursor Orb" in name: classification = ItemClassification.filler # TODO else: classification = ItemClassification.progression @@ -42,6 +40,6 @@ class JakAndDaxterWorld(World): return item def create_items(self): - self.multiworld.itempool += [self.create_item(item_table[0]) for k in range(0, 100)] - self.multiworld.itempool += [self.create_item(item_table[101]) for k in range(101, 212)] - self.multiworld.itempool += [self.create_item(item_table[k]) for k in special_item_table] + self.multiworld.itempool += [self.create_item("Power Cell", game_id + k) for k in range(0, 101)] + # self.multiworld.itempool += [self.create_item(item_table[101]) for k in range(101, 212)] + self.multiworld.itempool += [self.create_item(item_table[k], game_id + k) for k in special_item_table] diff --git a/worlds/jakanddaxter/locs/SpecialLocations.py b/worlds/jakanddaxter/locs/SpecialLocations.py new file mode 100644 index 0000000000..de7c891db3 --- /dev/null +++ b/worlds/jakanddaxter/locs/SpecialLocations.py @@ -0,0 +1,11 @@ +# Special Locations start at ID 2213 and end at ID 2219. + +loc_specialTable = { + 2213: "Fisherman's Boat", + # 2214: "Sculptor's Muse", # Unused? + 2215: "Flut Flut", + 2216: "Blue Eco Switch", + 2217: "Gladiator's Pontoons", + 2218: "Yellow Eco Switch", + 2219: "Lurker Fort Gate" +} \ No newline at end of file