From df31d874da3f699bcdcb7aab4fff8abd1777f7f0 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 22 Apr 2024 22:33:17 -0400 Subject: [PATCH] Jak 1: Fixed a few things. Four maps to go. --- worlds/jakanddaxter/GameID.py | 2 +- worlds/jakanddaxter/Rules.py | 20 ++++++-- worlds/jakanddaxter/locs/CellLocations.py | 2 + worlds/jakanddaxter/locs/OrbLocations.py | 2 + worlds/jakanddaxter/locs/ScoutLocations.py | 58 +++++++++++----------- 5 files changed, 52 insertions(+), 32 deletions(-) diff --git a/worlds/jakanddaxter/GameID.py b/worlds/jakanddaxter/GameID.py index d3e7582660..37100eca4b 100644 --- a/worlds/jakanddaxter/GameID.py +++ b/worlds/jakanddaxter/GameID.py @@ -1,4 +1,4 @@ -# All Jak And Daxter IDs must be offset by this number. +# All Jak And Daxter Archipelago IDs must be offset by this number. jak1_id = 741000000 # The name of the game. diff --git a/worlds/jakanddaxter/Rules.py b/worlds/jakanddaxter/Rules.py index d0c778f9d9..0333fa6e56 100644 --- a/worlds/jakanddaxter/Rules.py +++ b/worlds/jakanddaxter/Rules.py @@ -1,10 +1,22 @@ -from BaseClasses import MultiWorld +from BaseClasses import MultiWorld, CollectionState from .Options import JakAndDaxterOptions from .Regions import Jak1Level, Jak1SubLevel, level_table, subLevel_table from .Locations import location_table as item_table from .locs import CellLocations as Cells, ScoutLocations as Scouts +# Helper function for a handful of special cases +# where we need "at least any N" number of a specific set of cells. +def has_count_of(cell_list: set, required_count: int, player: int, state: CollectionState) -> bool: + c: int = 0 + for k in cell_list: + if state.has(item_table[k], player): + c += 1 + if c >= required_count: + return True + return False + + 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. @@ -21,6 +33,7 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) lpc_helix = Cells.to_ap_id(50) mp_klaww = Cells.to_ap_id(86) mp_end = Cells.to_ap_id(87) + pre_sm_cells = {Cells.to_ap_id(k) for k in {**Cells.locVC_cellTable, **Cells.locSC_cellTable}} sm_yellow_switch = Cells.to_ap_id(60) sm_fort_gate = Cells.to_ap_id(63) lt_end = Cells.to_ap_id(89) @@ -35,7 +48,7 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) connect_regions(multiworld, player, Jak1Level.GEYSER_ROCK, Jak1Level.SANDOVER_VILLAGE, - lambda state: state.has_all({item_table[k] for k in gr_cells}, player)) + lambda state: has_count_of(gr_cells, 4, player, state)) connect_regions(multiworld, player, Jak1Level.SANDOVER_VILLAGE, @@ -146,7 +159,8 @@ def set_rules(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) connect_regions(multiworld, player, Jak1Level.VOLCANIC_CRATER, - Jak1Level.SNOWY_MOUNTAIN) + Jak1Level.SNOWY_MOUNTAIN, + lambda state: has_count_of(pre_sm_cells, 2, player, state)) connect_region_to_sub(multiworld, player, Jak1Level.SNOWY_MOUNTAIN, diff --git a/worlds/jakanddaxter/locs/CellLocations.py b/worlds/jakanddaxter/locs/CellLocations.py index 1bff477161..304810af80 100644 --- a/worlds/jakanddaxter/locs/CellLocations.py +++ b/worlds/jakanddaxter/locs/CellLocations.py @@ -11,10 +11,12 @@ from ..GameID import jak1_id # 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: + assert game_id < jak1_id, f"Attempted to convert {game_id} to an AP ID, but it already is one." return jak1_id + game_id def to_game_id(ap_id: int) -> int: + assert ap_id >= jak1_id, f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one." return ap_id - jak1_id diff --git a/worlds/jakanddaxter/locs/OrbLocations.py b/worlds/jakanddaxter/locs/OrbLocations.py index 6b913dc11c..4e586a65fb 100644 --- a/worlds/jakanddaxter/locs/OrbLocations.py +++ b/worlds/jakanddaxter/locs/OrbLocations.py @@ -25,10 +25,12 @@ 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: + assert game_id < jak1_id, f"Attempted to convert {game_id} to an AP ID, but it already is one." return jak1_id + orb_offset + game_id # Add the offsets and the orb Actor ID. def to_game_id(ap_id: int) -> int: + assert ap_id >= jak1_id, f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one." return ap_id - jak1_id - orb_offset # Reverse process, subtract the offsets. diff --git a/worlds/jakanddaxter/locs/ScoutLocations.py b/worlds/jakanddaxter/locs/ScoutLocations.py index 809df2d287..d2796f36d1 100644 --- a/worlds/jakanddaxter/locs/ScoutLocations.py +++ b/worlds/jakanddaxter/locs/ScoutLocations.py @@ -20,12 +20,14 @@ fly_offset = 1024 # 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: + assert game_id < jak1_id, f"Attempted to convert {game_id} to an AP ID, but it already is one." 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: + assert ap_id >= jak1_id, f"Attempted to convert {ap_id} to a Jak 1 ID, but it already is one." 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. @@ -129,46 +131,46 @@ locPB_scoutTable = { # Lost Precursor City locLPC_scoutTable = { - 157: "LPC: Scout Fly First Room", - 158: "LPC: Scout Fly Before Second Room", - 159: "LPC: Scout Fly Second Room, Near Orb Vent", - 160: "LPC: Scout Fly Second Room, On Path To Cell", - 161: "LPC: Scout Fly Second Room, Green Switch", - 162: "LPC: Scout Fly Second Room, Blue Switch", - 163: "LPC: Scout Fly Across Steam Vents" + 262193: "LPC: Scout Fly First Room", + 131121: "LPC: Scout Fly Before Second Room", + 393265: "LPC: Scout Fly Second Room, Near Orb Vent", + 196657: "LPC: Scout Fly Second Room, On Path To Cell", + 49: "LPC: Scout Fly Second Room, Green Pipe", # Sunken Pipe Game, special cases. See `got-buzzer?` + 65585: "LPC: Scout Fly Second Room, Blue Pipe", # Sunken Pipe Game, special cases. See `got-buzzer?` + 327729: "LPC: Scout Fly Across Steam Vents" } # Boggy Swamp locBS_scoutTable = { - 164: "BS: Scout Fly Near Entrance", - 165: "BS: Scout Fly Over First Jump Pad", - 166: "BS: Scout Fly Over Second Jump Pad", - 167: "BS: Scout Fly Across Black Swamp", - 168: "BS: Scout Fly Overlooking Flut Flut", - 169: "BS: Scout Fly On Flut Flut Platforms", - 170: "BS: Scout Fly In Field Of Boxes" + 43: "BS: Scout Fly Near Entrance", + 393259: "BS: Scout Fly Over First Jump Pad", + 65579: "BS: Scout Fly Over Second Jump Pad", + 262187: "BS: Scout Fly Across Black Swamp", + 327723: "BS: Scout Fly Overlooking Flut Flut", + 131115: "BS: Scout Fly On Flut Flut Platforms", + 196651: "BS: Scout Fly In Field Of Boxes" } # Mountain Pass locMP_scoutTable = { - 171: "MP: Scout Fly 1", - 172: "MP: Scout Fly 2", - 173: "MP: Scout Fly 3", - 174: "MP: Scout Fly 4", - 175: "MP: Scout Fly 5", - 176: "MP: Scout Fly 6", - 177: "MP: Scout Fly 7" + 88: "MP: Scout Fly 1", + 65624: "MP: Scout Fly 2", + 131160: "MP: Scout Fly 3", + 196696: "MP: Scout Fly 4", + 262232: "MP: Scout Fly 5", + 327768: "MP: Scout Fly 6", + 393304: "MP: Scout Fly 7" } # Volcanic Crater locVC_scoutTable = { - 178: "VC: Scout Fly In Miner's Cave", - 179: "VC: Scout Fly Near Oracle", - 180: "VC: Scout Fly Overlooking Minecarts", - 181: "VC: Scout Fly On First Minecart Path", - 182: "VC: Scout Fly At Minecart Junction", - 183: "VC: Scout Fly At Spider Cave Entrance", - 184: "VC: Scout Fly Under Mountain Pass Exit" + 262221: "VC: Scout Fly In Miner's Cave", + 393293: "VC: Scout Fly Near Oracle", + 196685: "VC: Scout Fly On Stone Platforms", + 131149: "VC: Scout Fly Near Lava Tube", + 77: "VC: Scout Fly At Minecart Junction", + 65613: "VC: Scout Fly Near Spider Cave", + 327757: "VC: Scout Fly Near Mountain Pass" } # Spider Cave