diff --git a/worlds/jakanddaxter/Client.py b/worlds/jakanddaxter/Client.py index d1a43179cc..b2faacd6a1 100644 --- a/worlds/jakanddaxter/Client.py +++ b/worlds/jakanddaxter/Client.py @@ -10,7 +10,7 @@ import colorama import asyncio from asyncio import Task -from typing import Set, Awaitable, Optional, List +from typing import Set, Awaitable, Optional import pymem from pymem.exception import ProcessNotFound @@ -219,11 +219,11 @@ class JakAndDaxterContext(CommonContext): self.repl.received_deathlink = True super().on_deathlink(data) - async def ap_inform_location_check(self, location_ids: List[int]): + async def ap_inform_location_check(self, location_ids: list[int]): message = [{"cmd": "LocationChecks", "locations": location_ids}] await self.send_msgs(message) - def on_location_check(self, location_ids: List[int]): + def on_location_check(self, location_ids: list[int]): create_task_log_exception(self.ap_inform_location_check(location_ids)) async def ap_inform_finished_game(self): diff --git a/worlds/jakanddaxter/Items.py b/worlds/jakanddaxter/Items.py index 00d6cb9809..d759c7a482 100644 --- a/worlds/jakanddaxter/Items.py +++ b/worlds/jakanddaxter/Items.py @@ -68,18 +68,18 @@ orb_item_table = { # respective Location ID. Like scout flies, this is necessary for game<->archipelago communication. # TODO - These numbers of checks may be inaccurate post-region refactor. special_item_table = { - 5: "Fisherman's Boat", # Unlocks 14 checks in Misty Island - 4: "Jungle Elevator", # Unlocks 2 checks in Forbidden Jungle - 2: "Blue Eco Switch", # Unlocks 1 check in Jungle and 1 in Beach - 17: "Flut Flut", # Unlocks 2 checks in Swamp and 2 in Snowy - 33: "Warrior's Pontoons", # Unlocks 14 checks in Swamp and everything post-Rock Village - 105: "Snowy Mountain Gondola", # Unlocks 15 checks in Snowy Mountain - 60: "Yellow Eco Switch", # Unlocks 1 check in Pass and 1 in Snowy - 63: "Snowy Fort Gate", # Unlocks 3 checks in Snowy Mountain - 71: "Freed The Blue Sage", # 1 of 3 unlocks for the final staircase and 2 checks in Citadel - 72: "Freed The Red Sage", # 1 of 3 unlocks for the final staircase and 2 checks in Citadel - 73: "Freed The Yellow Sage", # 1 of 3 unlocks for the final staircase and 2 checks in Citadel - 70: "Freed The Green Sage", # Unlocks the final elevator + 5: "Fisherman's Boat", # Unlocks Misty Island + 4: "Jungle Elevator", # Unlocks the Forbidden Jungle Temple + 2: "Blue Eco Switch", # Unlocks Blue Eco Vents + 17: "Flut Flut", # Unlocks Flut Flut sections in Boggy Swamp and Snowy Mountain + 33: "Warrior's Pontoons", # Unlocks Boggy Swamp and everything post-Rock Village + 105: "Snowy Mountain Gondola", # Unlocks Snowy Mountain + 60: "Yellow Eco Switch", # Unlocks Yellow Eco Vents + 63: "Snowy Fort Gate", # Unlocks the Snowy Mountain Fort + 71: "Freed The Blue Sage", # 1 of 3 unlocks for the final staircase in Citadel + 72: "Freed The Red Sage", # 1 of 3 unlocks for the final staircase in Citadel + 73: "Freed The Yellow Sage", # 1 of 3 unlocks for the final staircase in Citadel + 70: "Freed The Green Sage", # Unlocks the final boss elevator in Citadel } # These are the move items for move randomizer. Notice that their Item ID equals some of the Orb Cache Location ID's. @@ -96,7 +96,7 @@ move_item_table = { 23348: "Punch", 23349: "Punch Uppercut", 23350: "Kick", - # 24038: "Orb Cache at End of Blast Furnace", # TODO - IDK, we didn't need all of the orb caches for move rando. + # 24038: "Orb Cache at End of Blast Furnace", # Hold onto these ID's for future use. # 24039: "Orb Cache at End of Launch Pad Room", # 24040: "Orb Cache at Start of Launch Pad Room", } diff --git a/worlds/jakanddaxter/Options.py b/worlds/jakanddaxter/Options.py index 0073f32492..664b619c0d 100644 --- a/worlds/jakanddaxter/Options.py +++ b/worlds/jakanddaxter/Options.py @@ -11,7 +11,8 @@ class EnableMoveRandomizer(Toggle): class EnableOrbsanity(Choice): - """Include bundles of Precursor Orbs as checks. Every time you collect the chosen number of orbs, you will trigger another check. + """Include bundles of Precursor Orbs as checks. Every time you collect the chosen number of orbs, you will trigger + another check. "Per Level" means bundles are for each level in the game. "Global" means bundles carry over level to level. @@ -128,7 +129,7 @@ class RequirePunchForKlaww(DefaultOnToggle): # 222 is the absolute maximum because there are 9 citizen trades and 2000 orbs to trade (2000/9 = 222). class CitizenOrbTradeAmount(Range): - """Set the number of orbs you need to trade to ordinary citizens for a power cell (Mayor, Uncle, etc.). + """The number of orbs you need to trade to citizens for a power cell (Mayor, Uncle, etc.). Along with Oracle Orb Trade Amount, this setting cannot exceed the total number of orbs in the game (2000). The equation to determine the total number of trade orbs is (9 * Citizen Trades) + (6 * Oracle Trades). @@ -143,7 +144,7 @@ class CitizenOrbTradeAmount(Range): # 333 is the absolute maximum because there are 6 oracle trades and 2000 orbs to trade (2000/6 = 333). class OracleOrbTradeAmount(Range): - """Set the number of orbs you need to trade to the Oracles for a power cell. + """The number of orbs you need to trade to the Oracles for a power cell. Along with Citizen Orb Trade Amount, this setting cannot exceed the total number of orbs in the game (2000). The equation to determine the total number of trade orbs is (9 * Citizen Trades) + (6 * Oracle Trades). diff --git a/worlds/jakanddaxter/__init__.py b/worlds/jakanddaxter/__init__.py index 7d952714d6..2548c8caa5 100644 --- a/worlds/jakanddaxter/__init__.py +++ b/worlds/jakanddaxter/__init__.py @@ -1,4 +1,4 @@ -from typing import Dict, Any, ClassVar, Tuple, Callable, Optional, Union, List +from typing import Any, ClassVar, Callable, Optional, Union from math import ceil import Utils import settings @@ -114,7 +114,7 @@ class JakAndDaxterWorld(World): """ # ID, name, version game = jak1_name - required_client_version = (0, 4, 6) + required_client_version = (0, 6, 0) # Options settings: ClassVar[JakAndDaxterSettings] @@ -199,7 +199,7 @@ class JakAndDaxterWorld(World): orb_bundle_item_name: str = "" orb_bundle_size: int = 0 total_trade_orbs: int = 0 - power_cell_thresholds: List[int] = [] + power_cell_thresholds: list[int] = [] # Handles various options validation, rules enforcement, and caching of important information. def generate_early(self) -> None: @@ -212,7 +212,6 @@ class JakAndDaxterWorld(World): self.power_cell_thresholds.append(100) # The 100 Power Cell Door. # Order the thresholds ascending and set the options values to the new order. - # TODO - How does this affect region access rules and other things? try: if self.options.enable_ordered_cell_counts: self.power_cell_thresholds.sort() @@ -265,8 +264,8 @@ class JakAndDaxterWorld(World): # Helper function to reuse some nasty if/else trees. This outputs a list of pairs of item count and classification. # For instance, not all 101 power cells need to be marked progression if you only need 72 to beat the game. So we # will have 72 Progression Power Cells, and 29 Filler Power Cells. - def item_type_helper(self, item) -> List[Tuple[int, ItemClass]]: - counts_and_classes: List[Tuple[int, ItemClass]] = [] + def item_type_helper(self, item) -> list[tuple[int, ItemClass]]: + counts_and_classes: list[tuple[int, ItemClass]] = [] # Make 101 Power Cells. We only want AP's Progression Fill routine to handle the amount of cells we need # to reach the furthest possible region. Even for early completion goals, all areas in the game must be @@ -412,7 +411,7 @@ class JakAndDaxterWorld(World): state.prog_items[self.player]["Reachable Orbs Fresh"] = False return change - def fill_slot_data(self) -> Dict[str, Any]: + def fill_slot_data(self) -> dict[str, Any]: return self.options.as_dict("enable_move_randomizer", "enable_orbsanity", "global_orbsanity_bundle_size", diff --git a/worlds/jakanddaxter/client/MemoryReader.py b/worlds/jakanddaxter/client/MemoryReader.py index de675c4efa..c9af179fa6 100644 --- a/worlds/jakanddaxter/client/MemoryReader.py +++ b/worlds/jakanddaxter/client/MemoryReader.py @@ -1,7 +1,7 @@ import logging import random import struct -from typing import ByteString, List, Callable, Optional +from typing import ByteString, Callable, Optional import json import pymem from pymem import pattern @@ -163,7 +163,7 @@ class JakAndDaxterMemoryReader: # The memory reader just needs the game running. gk_process: pymem.process = None - location_outbox: List[int] = [] + location_outbox: list[int] = [] outbox_index: int = 0 finished_game: bool = False @@ -327,7 +327,7 @@ class JakAndDaxterMemoryReader: await self.verify_memory_version() self.log_info(logger, msg) - def read_memory(self) -> List[int]: + def read_memory(self) -> list[int]: try: # Need to grab these first and convert to floats, see below. citizen_orb_amount = self.read_goal_address(citizen_orb_amount_offset, sizeof_float) diff --git a/worlds/jakanddaxter/client/ReplClient.py b/worlds/jakanddaxter/client/ReplClient.py index f811c883db..1c0f37f5b8 100644 --- a/worlds/jakanddaxter/client/ReplClient.py +++ b/worlds/jakanddaxter/client/ReplClient.py @@ -6,7 +6,7 @@ import struct import random from dataclasses import dataclass from queue import Queue -from typing import Dict, Optional, Callable +from typing import Optional, Callable import pymem from pymem.exception import ProcessNotFound, ProcessError @@ -52,7 +52,7 @@ class JakAndDaxterReplClient: gk_process: pymem.process = None goalc_process: pymem.process = None - item_inbox: Dict[int, NetworkItem] = {} + item_inbox: dict[int, NetworkItem] = {} inbox_index = 0 json_message_queue: Queue[JsonMessageData] = queue.Queue() diff --git a/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md b/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md index f9bd239915..1f551c9749 100644 --- a/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md +++ b/worlds/jakanddaxter/docs/en_Jak and Daxter The Precursor Legacy.md @@ -133,15 +133,13 @@ This will show you a list of all the moves in the game. - Light blue items indicate you possess that move, as well as its prerequisites. ## What does Orbsanity do? -If you enable Orbsanity, Precursor Orbs will be turned into ordered lists of progressive checks. Every time you collect -a "bundle" of the correct number of orbs, you will trigger the next release in the list. Likewise, these bundles of orbs -will be added to the item pool to be randomized. There are several options to change the difficulty of this challenge. +If you enable Orbsanity, bundles of Precursor Orbs will be turned into checks. Every time you collect the chosen number +of orbs, i.e. a "bundle," you will trigger another check. Likewise, the orbs will be added to the random item pool. +There are several options to change the difficulty of this challenge. -- "Per Level" Orbsanity means the lists of orb checks are generated and populated for each level in the game. - - (Geyser Rock, Sandover Village, etc.) -- "Global" Orbsanity means there is only one list of checks for the entire game. - - It does not matter where you pick up the orbs, they all count toward the same list. -- The options with "Bundle Size" in the name indicate how many orbs are in a "bundle." This adds a number of Items +- "Per Level" Orbsanity means the bundles are for each level in the game. (Geyser Rock, Sandover Village, etc.) +- "Global" Orbsanity means orbs collected from any level count toward the next bundle. +- The options with "Bundle Size" in the name indicate how many orbs are in a bundle. This adds a number of Items and Locations to the pool inversely proportional to the size of the bundle. - For example, if your bundle size is 20 orbs, you will add 100 items to the pool. If your bundle size is 250 orbs, you will add 8 items to the pool.