From 17b484580e343c2285b10561a267d45f93a24a14 Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:15:01 -0400 Subject: [PATCH] Make orb trade amounts configurable, make orbsanity defaults more reasonable. --- worlds/jakanddaxter/Client.py | 2 + worlds/jakanddaxter/JakAndDaxterOptions.py | 38 +++++++++++++--- worlds/jakanddaxter/Regions.py | 26 +++++++++++ worlds/jakanddaxter/__init__.py | 2 + worlds/jakanddaxter/client/MemoryReader.py | 28 ++++++++---- worlds/jakanddaxter/client/ReplClient.py | 9 ++-- .../en_Jak and Daxter The Precursor Legacy.md | 44 ++++++++++--------- worlds/jakanddaxter/regs/RegionBase.py | 2 +- .../jakanddaxter/regs/RockVillageRegions.py | 12 ++--- .../regs/SandoverVillageRegions.py | 10 +++-- .../regs/VolcanicCraterRegions.py | 14 +++--- 11 files changed, 132 insertions(+), 55 deletions(-) diff --git a/worlds/jakanddaxter/Client.py b/worlds/jakanddaxter/Client.py index 23cf1a4cbd..ef69fddef3 100644 --- a/worlds/jakanddaxter/Client.py +++ b/worlds/jakanddaxter/Client.py @@ -130,6 +130,8 @@ class JakAndDaxterContext(CommonContext): slot_data["fire_canyon_cell_count"], slot_data["mountain_pass_cell_count"], slot_data["lava_tube_cell_count"], + slot_data["citizen_orb_trade_amount"], + slot_data["oracle_orb_trade_amount"], goal_id)) # Because Orbsanity and the orb traders in the game are intrinsically linked, we need the server diff --git a/worlds/jakanddaxter/JakAndDaxterOptions.py b/worlds/jakanddaxter/JakAndDaxterOptions.py index 57f6c1ca74..12b7ebc1f7 100644 --- a/worlds/jakanddaxter/JakAndDaxterOptions.py +++ b/worlds/jakanddaxter/JakAndDaxterOptions.py @@ -3,8 +3,8 @@ from Options import PerGameCommonOptions, StartInventoryPool, Toggle, Choice, Ra class EnableMoveRandomizer(Toggle): - """Enable to include movement options as items in the randomizer. Jak is only able to run, swim, and single jump - until you find his other moves. + """Enable to include movement options as items in the randomizer. Until you find his other moves, Jak is limited to + running, swimming, single-jumping, and shooting yellow eco through his goggles. This adds 11 items to the pool.""" display_name = "Enable Move Randomizer" @@ -51,7 +51,7 @@ class GlobalOrbsanityBundleSize(Choice): option_500_orbs = 500 option_1000_orbs = 1000 option_2000_orbs = 2000 - default = 1 + default = 20 class PerLevelOrbsanityBundleSize(Choice): @@ -64,11 +64,11 @@ class PerLevelOrbsanityBundleSize(Choice): option_10_orbs = 10 option_25_orbs = 25 option_50_orbs = 50 - default = 1 + default = 25 class FireCanyonCellCount(Range): - """Set the number of orbs you need to cross Fire Canyon.""" + """Set the number of power cells you need to cross Fire Canyon.""" display_name = "Fire Canyon Cell Count" range_start = 0 range_end = 100 @@ -76,7 +76,7 @@ class FireCanyonCellCount(Range): class MountainPassCellCount(Range): - """Set the number of orbs you need to reach Klaww and cross Mountain Pass.""" + """Set the number of power cells you need to reach Klaww and cross Mountain Pass.""" display_name = "Mountain Pass Cell Count" range_start = 0 range_end = 100 @@ -84,13 +84,35 @@ class MountainPassCellCount(Range): class LavaTubeCellCount(Range): - """Set the number of orbs you need to cross Lava Tube.""" + """Set the number of power cells you need to cross Lava Tube.""" display_name = "Lava Tube Cell Count" range_start = 0 range_end = 100 default = 72 +# 222 is the 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.). + + Along with Oracle Orb Trade Amount, this setting cannot exceed the total number of orbs in the game (2000).""" + display_name = "Citizen Orb Trade Amount" + range_start = 0 + range_end = 222 + default = 90 + + +# 333 is the 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. + + Along with Citizen Orb Trade Amount, this setting cannot exceed the total number of orbs in the game (2000).""" + display_name = "Oracle Orb Trade Amount" + range_start = 0 + range_end = 333 + default = 120 + + class CompletionCondition(Choice): """Set the goal for completing the game.""" display_name = "Completion Condition" @@ -113,5 +135,7 @@ class JakAndDaxterOptions(PerGameCommonOptions): fire_canyon_cell_count: FireCanyonCellCount mountain_pass_cell_count: MountainPassCellCount lava_tube_cell_count: LavaTubeCellCount + citizen_orb_trade_amount: CitizenOrbTradeAmount + oracle_orb_trade_amount: OracleOrbTradeAmount jak_completion_condition: CompletionCondition start_inventory_from_pool: StartInventoryPool diff --git a/worlds/jakanddaxter/Regions.py b/worlds/jakanddaxter/Regions.py index 6d016bad2c..24e7dbccf8 100644 --- a/worlds/jakanddaxter/Regions.py +++ b/worlds/jakanddaxter/Regions.py @@ -133,6 +133,9 @@ def create_regions(multiworld: MultiWorld, options: JakAndDaxterOptions, player: # the connector levels. E.g. if you set Fire Canyon count to 99, we may not have 99 Locations in hub 1. verify_connector_level_accessibility(multiworld, options, player) + # Also verify that we didn't overload the trade amounts with more orbs than exist in the world. + verify_orbs_for_trades(multiworld, options, player) + def verify_connector_level_accessibility(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int): @@ -182,3 +185,26 @@ def verify_connector_level_accessibility(multiworld: MultiWorld, options: JakAnd for item in required_items: state.collect(JakAndDaxterItem(required_items[item], ItemClassification.progression, item, player)) + + +def verify_orbs_for_trades(multiworld: MultiWorld, options: JakAndDaxterOptions, player: int): + + citizen_trade_orbs = 9 * options.citizen_orb_trade_amount + if citizen_trade_orbs > 2000: + raise OptionError(f"Settings conflict with {options.citizen_orb_trade_amount.display_name}: " + f"required number of orbs to trade with citizens ({citizen_trade_orbs}) " + f"is more than all the orbs in the game (2000).") + + oracle_trade_orbs = 6 * options.oracle_orb_trade_amount + if oracle_trade_orbs > 2000: + raise OptionError(f"Settings conflict with {options.oracle_orb_trade_amount.display_name}: " + f"required number of orbs to trade with oracles ({oracle_trade_orbs}) " + f"is more than all the orbs in the game (2000).") + + total_trade_orbs = (9 * options.citizen_orb_trade_amount) + (6 * options.oracle_orb_trade_amount) + if total_trade_orbs > 2000: + raise OptionError(f"Settings conflict with Orb Trade Amounts: " + f"required number of orbs for all trades ({total_trade_orbs}) " + f"is more than all the orbs in the game (2000). " + f"Reduce the value of either {options.citizen_orb_trade_amount.display_name} " + f"or {options.oracle_orb_trade_amount.display_name}.") diff --git a/worlds/jakanddaxter/__init__.py b/worlds/jakanddaxter/__init__.py index 7d3339472c..bbd2f3118e 100644 --- a/worlds/jakanddaxter/__init__.py +++ b/worlds/jakanddaxter/__init__.py @@ -200,4 +200,6 @@ class JakAndDaxterWorld(World): "fire_canyon_cell_count", "mountain_pass_cell_count", "lava_tube_cell_count", + "citizen_orb_trade_amount", + "oracle_orb_trade_amount", "jak_completion_condition") diff --git a/worlds/jakanddaxter/client/MemoryReader.py b/worlds/jakanddaxter/client/MemoryReader.py index 049fe1eb7c..e9f3bfe182 100644 --- a/worlds/jakanddaxter/client/MemoryReader.py +++ b/worlds/jakanddaxter/client/MemoryReader.py @@ -1,4 +1,5 @@ import random +import struct from typing import ByteString, List, Callable import json import pymem @@ -76,6 +77,8 @@ collected_bundle_offset = offsets.define(sizeof_uint32, 17) fire_canyon_unlock_offset = offsets.define(sizeof_float) mountain_pass_unlock_offset = offsets.define(sizeof_float) lava_tube_unlock_offset = offsets.define(sizeof_float) +citizen_orb_amount_offset = offsets.define(sizeof_float) +oracle_orb_amount_offset = offsets.define(sizeof_float) completion_goal_offset = offsets.define(sizeof_uint8) completed_offset = offsets.define(sizeof_uint8) @@ -89,6 +92,11 @@ my_item_finder_offset = offsets.define(sizeof_uint8, 32) end_marker_offset = offsets.define(sizeof_uint8, 4) +# Can't believe this is easier to do in GOAL than Python but that's how it be sometimes. +def as_float(value: int) -> int: + return int(struct.unpack('f', value.to_bytes(sizeof_float, "little"))[0]) + + # "Jak" to be replaced by player name in the Client. def autopsy(died: int) -> str: assert died > 0, f"Tried to find Jak's cause of death, but he's still alive!" @@ -239,10 +247,11 @@ class JakAndDaxterMemoryReader: def read_memory(self) -> List[int]: try: - next_cell_index = self.read_goal_address(0, sizeof_uint64) - next_buzzer_index = self.read_goal_address(next_buzzer_index_offset, sizeof_uint64) - next_special_index = self.read_goal_address(next_special_index_offset, sizeof_uint64) + # Need to grab these first and convert to floats, see below. + citizen_orb_amount = self.read_goal_address(citizen_orb_amount_offset, sizeof_float) + oracle_orb_amount = self.read_goal_address(oracle_orb_amount_offset, sizeof_float) + next_cell_index = self.read_goal_address(next_cell_index_offset, sizeof_uint64) for k in range(0, next_cell_index): next_cell = self.read_goal_address(cells_checked_offset + (k * sizeof_uint32), sizeof_uint32) cell_ap_id = Cells.to_ap_id(next_cell) @@ -253,13 +262,16 @@ class JakAndDaxterMemoryReader: # If orbsanity is ON and next_cell is one of the traders or oracles, then run a callback # to add their amount to the DataStorage value holding our current orb trade total. if next_cell in {11, 12, 31, 32, 33, 96, 97, 98, 99}: - self.orbs_paid += 90 - logger.debug("Traded 90 orbs!") + citizen_orb_amount = as_float(citizen_orb_amount) + self.orbs_paid += citizen_orb_amount + logger.debug(f"Traded {citizen_orb_amount} orbs!") if next_cell in {13, 14, 34, 35, 100, 101}: - self.orbs_paid += 120 - logger.debug("Traded 120 orbs!") + oracle_orb_amount = as_float(oracle_orb_amount) + self.orbs_paid += oracle_orb_amount + logger.debug(f"Traded {oracle_orb_amount} orbs!") + next_buzzer_index = self.read_goal_address(next_buzzer_index_offset, sizeof_uint64) for k in range(0, next_buzzer_index): next_buzzer = self.read_goal_address(buzzers_checked_offset + (k * sizeof_uint32), sizeof_uint32) buzzer_ap_id = Flies.to_ap_id(next_buzzer) @@ -267,6 +279,7 @@ class JakAndDaxterMemoryReader: self.location_outbox.append(buzzer_ap_id) logger.debug("Checked scout fly: " + str(next_buzzer)) + next_special_index = self.read_goal_address(next_special_index_offset, sizeof_uint64) for k in range(0, next_special_index): next_special = self.read_goal_address(specials_checked_offset + (k * sizeof_uint32), sizeof_uint32) special_ap_id = Specials.to_ap_id(next_special) @@ -284,7 +297,6 @@ class JakAndDaxterMemoryReader: self.deathlink_enabled = bool(deathlink_flag) next_cache_index = self.read_goal_address(next_orb_cache_index_offset, sizeof_uint64) - for k in range(0, next_cache_index): next_cache = self.read_goal_address(orb_caches_checked_offset + (k * sizeof_uint32), sizeof_uint32) cache_ap_id = Caches.to_ap_id(next_cache) diff --git a/worlds/jakanddaxter/client/ReplClient.py b/worlds/jakanddaxter/client/ReplClient.py index 09b488d174..eb551fe83a 100644 --- a/worlds/jakanddaxter/client/ReplClient.py +++ b/worlds/jakanddaxter/client/ReplClient.py @@ -356,15 +356,18 @@ class JakAndDaxterReplClient: async def setup_options(self, os_option: int, os_bundle: int, fc_count: int, mp_count: int, - lt_count: int, goal_id: int) -> bool: + lt_count: int, ct_amount: int, + ot_amount: int, goal_id: int) -> bool: ok = await self.send_form(f"(ap-setup-options! " f"(the uint {os_option}) (the uint {os_bundle}) " f"(the float {fc_count}) (the float {mp_count}) " - f"(the float {lt_count}) (the uint {goal_id}))") + f"(the float {lt_count}) (the float {ct_amount}) " + f"(the float {ot_amount}) (the uint {goal_id}))") message = (f"Setting options: \n" f" Orbsanity Option {os_option}, Orbsanity Bundle {os_bundle}, \n" f" FC Cell Count {fc_count}, MP Cell Count {mp_count}, \n" - f" LT Cell Count {lt_count}, Completion GOAL {goal_id}... ") + f" LT Cell Count {lt_count}, Citizen Orb Amt {ct_amount}, \n" + f" Oracle Orb Amt {ot_amount}, Completion GOAL {goal_id}... ") if ok: logger.debug(message + "Success!") else: 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 19597bda31..d26e380427 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 @@ -7,9 +7,9 @@ all the options you need to configure and export a config file. At this time, there are several caveats and restrictions: - Power Cells and Scout Flies are **always** randomized. -- Precursor Orbs are **never** randomized. -- **All** of the traders in the game become in-logic checks **if and only if** you have enough Orbs (1530) to pay them all at once. - - This is to prevent hard locks, where an item required for progression is locked behind a trade you can't afford. +- **All** the traders in the game become in-logic checks **if and only if** you have enough Orbs to pay all of them at once. + - This is to prevent hard locks, where an item required for progression is locked behind a trade you can't afford because you spent the orbs elsewhere. + - By default, that total is 1530. ## What does randomization do to this game? The game now contains the following Location checks: @@ -56,10 +56,14 @@ This will show you a list of all the special items in the game, ones not normall Gray items indicate you do not possess that item, light blue items indicate you possess that item. ## What is the goal of the game once randomized? -To complete the game, you must defeat the Gol and Maia and stop them from opening the Dark Eco silo. +By default, to complete the game you must defeat the Gol and Maia and stop them from opening the Dark Eco silo. In order +to reach them, you will need at least 72 Power Cells to cross the Lava Tube, as well as the four special items for +freeing the Red, Blue, Yellow, and Green Sages. -In order to reach them, you will need at least 72 Power Cells to cross the Lava Tube. In addition, -you will need the four special items that free the Red, Blue, Yellow, and Green Sages. +Alternatively, you can choose from a handful of other completion conditions like defeating a particular boss, crossing +a particular connector level, or opening the 100 Power Cell door after defeating the final boss. You can also customize +the thresholds for connector levels and orb trades. These options allow you to tailor the expected length and difficulty +of your run as you see fit. ## What happens when I pick up or receive a power cell? When you pick up a power cell, Jak and Daxter will perform their victory animation. Your power cell count will @@ -85,23 +89,23 @@ scout fly. So in short: - When you _pick up_ your 7th fly, the normal rules apply. - When you _receive_ your 7th fly, 2 things will happen in quick succession. - - First, you will receive that scout fly, as normal. - - Second, you will immediately complete the "Free 7 Scout Flies" check, which will send out another item. + - First, you will receive that scout fly, as normal. + - Second, you will immediately complete the "Free 7 Scout Flies" check, which will send out another item. ## What does Deathlink do? If you enable Deathlink, all the other players in your Multiworld who also have it enabled will be linked on death. That means when Jak dies in your game, the players in your Deathlink group also die. Likewise, if any of the other -players die, Jak will also die in a random fashion. +players die, Jak will also die in a random, possibly spectacular fashion. -You can turn off Deathlink at any time in the game by opening the game's menu, navigate to `Options`, +You can turn off Deathlink at any time in the game by opening the game's menu and navigating to `Options`, then `Archipelago Options`, then `Deathlink`. ## What does Move Randomizer do? If you enable Move Randomizer, most of Jak's movement set will be added to the randomized item pool, and you will need to receive the move in order to use it (i.e. you must find it, or another player must send it to you). Some moves have prerequisite moves that you must also have in order to use them (e.g. Crouch Jump is dependent on Crouch). Jak will only -be able to run, swim (including underwater), and perform single jumps. Note that Flut Flut will have access to her full -movement set at all times. +be able to run, swim (including underwater), perform single jumps, and shoot yellow eco from his goggles ("firing from +the hip" requires Punch). Note that Flut Flut and the Zoomer will have access to their full movement sets at all times. You can turn off Move Rando at any time in the game by opening the game's menu, navigate to `Options`, then `Archipelago Options`, then `Move Randomizer`. This will give you access to the full movement set again. @@ -134,9 +138,9 @@ a "bundle" of the correct number of orbs, you will trigger the next release in t will be added to the item pool to be randomized. 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.) + - (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. + - 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 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, @@ -161,20 +165,18 @@ to the nearest sage's hut to continue your journey. Depending on the nature of the bug, there are a couple of different options. * If you found a logical error in the randomizer, please create a new Issue -[here.](https://github.com/ArchipelaGOAL/Archipelago/issues) - * Use this page if: +[here.](https://github.com/ArchipelaGOAL/Archipelago/issues) Use this page if: * An item required for progression is unreachable. * The randomizer did not respect one of the Options you chose. * You see a mistake, typo, etc. on this webpage. * You see an error or stack trace appear on the text client. - * Please upload your config file and spoiler log file in the Issue, so we can troubleshoot the problem. * If you encountered an error in OpenGOAL, please create a new Issue -[here.](https://github.com/ArchipelaGOAL/ArchipelaGOAL/issues) - * Use this page if: - * You encounter a crash, freeze, reset, etc in the game. +[here.](https://github.com/ArchipelaGOAL/ArchipelaGOAL/issues) Use this page if: + * You encounter a crash, freeze, reset, etc. in the game. * You fail to send Items you find in the game to the Archipelago server. * You fail to receive Items the server sends to you. * Your game disconnects from the server and cannot reconnect. * You go looking for a game item that has already disappeared before you could reach it. - * Please upload any log files that may have been generated. \ No newline at end of file + +* Please upload your config file, spoiler log file, and any other generated logs in the Issue, so we can troubleshoot the problem. \ No newline at end of file diff --git a/worlds/jakanddaxter/regs/RegionBase.py b/worlds/jakanddaxter/regs/RegionBase.py index 42534e462a..6629991bc8 100644 --- a/worlds/jakanddaxter/regs/RegionBase.py +++ b/worlds/jakanddaxter/regs/RegionBase.py @@ -14,7 +14,7 @@ class JakAndDaxterRegion(Region): """ Holds region information such as name, level name, number of orbs available, etc. We especially need orb counts to be tracked because we need to know when you can - afford the 90-orb and 120-orb payments for more checks. + afford the Citizen and Oracle orb payments for more checks. """ game: str = jak1_name level_name: str diff --git a/worlds/jakanddaxter/regs/RockVillageRegions.py b/worlds/jakanddaxter/regs/RockVillageRegions.py index f59e63101a..353a9ba412 100644 --- a/worlds/jakanddaxter/regs/RockVillageRegions.py +++ b/worlds/jakanddaxter/regs/RockVillageRegions.py @@ -7,18 +7,20 @@ from ..Rules import can_free_scout_flies, can_trade, can_reach_orbs def build_regions(level_name: str, multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) -> List[JakAndDaxterRegion]: + total_trade_orbs = (9 * options.citizen_orb_trade_amount) + (6 * options.oracle_orb_trade_amount) + # This includes most of the area surrounding LPC as well, for orb_count purposes. You can swim and single jump. main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 23) main_area.add_cell_locations([31], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) main_area.add_cell_locations([32], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) main_area.add_cell_locations([33], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) main_area.add_cell_locations([34], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) main_area.add_cell_locations([35], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530, 34)) + can_trade(state, player, multiworld, options, total_trade_orbs, 34)) # These 2 scout fly boxes can be broken by running with nearby blue eco. main_area.add_fly_locations([196684, 262220]) diff --git a/worlds/jakanddaxter/regs/SandoverVillageRegions.py b/worlds/jakanddaxter/regs/SandoverVillageRegions.py index f4ee264a74..c05321fb4c 100644 --- a/worlds/jakanddaxter/regs/SandoverVillageRegions.py +++ b/worlds/jakanddaxter/regs/SandoverVillageRegions.py @@ -7,14 +7,16 @@ from ..Rules import can_free_scout_flies, can_trade, can_reach_orbs def build_regions(level_name: str, multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) -> List[JakAndDaxterRegion]: + total_trade_orbs = (9 * options.citizen_orb_trade_amount) + (6 * options.oracle_orb_trade_amount) + main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 26) # Yakows requires no combat. main_area.add_cell_locations([10]) main_area.add_cell_locations([11], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) main_area.add_cell_locations([12], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) # These 4 scout fly boxes can be broken by running with all the blue eco from Sentinel Beach. main_area.add_fly_locations([262219, 327755, 131147, 65611]) @@ -33,9 +35,9 @@ def build_regions(level_name: str, multiworld: MultiWorld, options: JakAndDaxter oracle_platforms = JakAndDaxterRegion("Oracle Platforms", player, multiworld, level_name, 6) oracle_platforms.add_cell_locations([13], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) oracle_platforms.add_cell_locations([14], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530, 13)) + can_trade(state, player, multiworld, options, total_trade_orbs, 13)) oracle_platforms.add_fly_locations([393291], access_rule=lambda state: can_free_scout_flies(state, player)) diff --git a/worlds/jakanddaxter/regs/VolcanicCraterRegions.py b/worlds/jakanddaxter/regs/VolcanicCraterRegions.py index 875f1c2cbc..e25b6de3ec 100644 --- a/worlds/jakanddaxter/regs/VolcanicCraterRegions.py +++ b/worlds/jakanddaxter/regs/VolcanicCraterRegions.py @@ -8,20 +8,22 @@ from ..locs import CellLocations as Cells, ScoutLocations as Scouts def build_regions(level_name: str, multiworld: MultiWorld, options: JakAndDaxterOptions, player: int) -> List[JakAndDaxterRegion]: + total_trade_orbs = (9 * options.citizen_orb_trade_amount) + (6 * options.oracle_orb_trade_amount) + # No area is inaccessible in VC even with only running and jumping. main_area = JakAndDaxterRegion("Main Area", player, multiworld, level_name, 50) main_area.add_cell_locations([96], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) main_area.add_cell_locations([97], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530, 96)) + can_trade(state, player, multiworld, options, total_trade_orbs, 96)) main_area.add_cell_locations([98], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530, 97)) + can_trade(state, player, multiworld, options, total_trade_orbs, 97)) main_area.add_cell_locations([99], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530, 98)) + can_trade(state, player, multiworld, options, total_trade_orbs, 98)) main_area.add_cell_locations([100], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530)) + can_trade(state, player, multiworld, options, total_trade_orbs)) main_area.add_cell_locations([101], access_rule=lambda state: - can_trade(state, player, multiworld, options, 1530, 100)) + can_trade(state, player, multiworld, options, total_trade_orbs, 100)) # Hidden Power Cell: you can carry yellow eco from Spider Cave just by running and jumping # and using your Goggles to shoot the box (you do not need Punch to shoot from FP mode).