diff --git a/worlds/jakanddaxter/JakAndDaxterOptions.py b/worlds/jakanddaxter/JakAndDaxterOptions.py index b1af9f788f..cc4178723e 100644 --- a/worlds/jakanddaxter/JakAndDaxterOptions.py +++ b/worlds/jakanddaxter/JakAndDaxterOptions.py @@ -51,7 +51,8 @@ class GlobalOrbsanityBundleSize(Choice): option_500_orbs = 500 option_1000_orbs = 1000 option_2000_orbs = 2000 - friendly_minimum = 5 + multiplayer_minimum = 5 + multiplayer_maximum = 400 default = 20 @@ -65,7 +66,7 @@ class PerLevelOrbsanityBundleSize(Choice): option_10_orbs = 10 option_25_orbs = 25 option_50_orbs = 50 - friendly_minimum = 5 + multiplayer_minimum = 5 default = 25 @@ -74,7 +75,8 @@ class FireCanyonCellCount(Range): display_name = "Fire Canyon Cell Count" range_start = 0 range_end = 100 - friendly_maximum = 30 + multiplayer_maximum = 30 + singleplayer_maximum = 34 default = 20 @@ -83,7 +85,8 @@ class MountainPassCellCount(Range): display_name = "Mountain Pass Cell Count" range_start = 0 range_end = 100 - friendly_maximum = 60 + multiplayer_maximum = 60 + singleplayer_maximum = 63 default = 45 @@ -92,7 +95,8 @@ class LavaTubeCellCount(Range): display_name = "Lava Tube Cell Count" range_start = 0 range_end = 100 - friendly_maximum = 90 + multiplayer_maximum = 90 + singleplayer_maximum = 99 default = 72 @@ -105,7 +109,7 @@ class CitizenOrbTradeAmount(Range): display_name = "Citizen Orb Trade Amount" range_start = 0 range_end = 222 - friendly_maximum = 120 + multiplayer_maximum = 120 default = 90 @@ -118,7 +122,7 @@ class OracleOrbTradeAmount(Range): display_name = "Oracle Orb Trade Amount" range_start = 0 range_end = 333 - friendly_maximum = 150 + multiplayer_maximum = 150 default = 120 diff --git a/worlds/jakanddaxter/Regions.py b/worlds/jakanddaxter/Regions.py index a8940e0c9a..6ddcf9f4cb 100644 --- a/worlds/jakanddaxter/Regions.py +++ b/worlds/jakanddaxter/Regions.py @@ -126,5 +126,5 @@ def create_regions(world: JakAndDaxterWorld): multiworld.completion_condition[player] = lambda state: state.can_reach(fd, "Region", player) else: - raise OptionError(f"Unknown completion goal ID ({options.jak_completion_condition.value}).") - + raise OptionError(f"{world.player_name}: Unknown completion goal ID " + f"({options.jak_completion_condition.value}).") diff --git a/worlds/jakanddaxter/Rules.py b/worlds/jakanddaxter/Rules.py index 4acff95145..0e3e4b8412 100644 --- a/worlds/jakanddaxter/Rules.py +++ b/worlds/jakanddaxter/Rules.py @@ -122,62 +122,94 @@ def can_fight(state: CollectionState, player: int) -> bool: return state.has_any({"Jump Dive", "Jump Kick", "Punch", "Kick"}, player) -def enforce_multiplayer_limits(options: JakAndDaxterOptions): +def enforce_multiplayer_limits(world: JakAndDaxterWorld): + options = world.options friendly_message = "" if (options.enable_orbsanity == EnableOrbsanity.option_global - and options.global_orbsanity_bundle_size.value < GlobalOrbsanityBundleSize.friendly_minimum): + and (options.global_orbsanity_bundle_size.value < GlobalOrbsanityBundleSize.multiplayer_minimum + or options.global_orbsanity_bundle_size.value > GlobalOrbsanityBundleSize.multiplayer_maximum)): friendly_message += (f" " f"{options.global_orbsanity_bundle_size.display_name} must be no less than " - f"{GlobalOrbsanityBundleSize.friendly_minimum} (currently " + f"{GlobalOrbsanityBundleSize.multiplayer_minimum} and no greater than" + f"{GlobalOrbsanityBundleSize.multiplayer_maximum} (currently " f"{options.global_orbsanity_bundle_size.value}).\n") if (options.enable_orbsanity == EnableOrbsanity.option_per_level - and options.level_orbsanity_bundle_size.value < PerLevelOrbsanityBundleSize.friendly_minimum): + and options.level_orbsanity_bundle_size.value < PerLevelOrbsanityBundleSize.multiplayer_minimum): friendly_message += (f" " f"{options.level_orbsanity_bundle_size.display_name} must be no less than " - f"{PerLevelOrbsanityBundleSize.friendly_minimum} (currently " + f"{PerLevelOrbsanityBundleSize.multiplayer_minimum} (currently " f"{options.level_orbsanity_bundle_size.value}).\n") - if options.fire_canyon_cell_count.value > FireCanyonCellCount.friendly_maximum: + if options.fire_canyon_cell_count.value > FireCanyonCellCount.multiplayer_maximum: friendly_message += (f" " f"{options.fire_canyon_cell_count.display_name} must be no greater than " - f"{FireCanyonCellCount.friendly_maximum} (currently " + f"{FireCanyonCellCount.multiplayer_maximum} (currently " f"{options.fire_canyon_cell_count.value}).\n") - if options.mountain_pass_cell_count.value > MountainPassCellCount.friendly_maximum: + if options.mountain_pass_cell_count.value > MountainPassCellCount.multiplayer_maximum: friendly_message += (f" " f"{options.mountain_pass_cell_count.display_name} must be no greater than " - f"{MountainPassCellCount.friendly_maximum} (currently " + f"{MountainPassCellCount.multiplayer_maximum} (currently " f"{options.mountain_pass_cell_count.value}).\n") - if options.lava_tube_cell_count.value > LavaTubeCellCount.friendly_maximum: + if options.lava_tube_cell_count.value > LavaTubeCellCount.multiplayer_maximum: friendly_message += (f" " f"{options.lava_tube_cell_count.display_name} must be no greater than " - f"{LavaTubeCellCount.friendly_maximum} (currently " + f"{LavaTubeCellCount.multiplayer_maximum} (currently " f"{options.lava_tube_cell_count.value}).\n") - if options.citizen_orb_trade_amount.value > CitizenOrbTradeAmount.friendly_maximum: + if options.citizen_orb_trade_amount.value > CitizenOrbTradeAmount.multiplayer_maximum: friendly_message += (f" " f"{options.citizen_orb_trade_amount.display_name} must be no greater than " - f"{CitizenOrbTradeAmount.friendly_maximum} (currently " + f"{CitizenOrbTradeAmount.multiplayer_maximum} (currently " f"{options.citizen_orb_trade_amount.value}).\n") - if options.oracle_orb_trade_amount.value > OracleOrbTradeAmount.friendly_maximum: + if options.oracle_orb_trade_amount.value > OracleOrbTradeAmount.multiplayer_maximum: friendly_message += (f" " f"{options.oracle_orb_trade_amount.display_name} must be no greater than " - f"{OracleOrbTradeAmount.friendly_maximum} (currently " + f"{OracleOrbTradeAmount.multiplayer_maximum} (currently " f"{options.oracle_orb_trade_amount.value}).\n") if friendly_message != "": - raise OptionError(f"Please adjust the following Options for a multiplayer game.\n" + raise OptionError(f"{world.player_name}: Please adjust the following Options for a multiplayer game.\n" f"{friendly_message}") +def enforce_singleplayer_limits(world: JakAndDaxterWorld): + options = world.options + friendly_message = "" + + if options.fire_canyon_cell_count.value > FireCanyonCellCount.singleplayer_maximum: + friendly_message += (f" " + f"{options.fire_canyon_cell_count.display_name} must be no greater than " + f"{FireCanyonCellCount.singleplayer_maximum} (currently " + f"{options.fire_canyon_cell_count.value}).\n") + + if options.mountain_pass_cell_count.value > MountainPassCellCount.singleplayer_maximum: + friendly_message += (f" " + f"{options.mountain_pass_cell_count.display_name} must be no greater than " + f"{MountainPassCellCount.singleplayer_maximum} (currently " + f"{options.mountain_pass_cell_count.value}).\n") + + if options.lava_tube_cell_count.value > LavaTubeCellCount.singleplayer_maximum: + friendly_message += (f" " + f"{options.lava_tube_cell_count.display_name} must be no greater than " + f"{LavaTubeCellCount.singleplayer_maximum} (currently " + f"{options.lava_tube_cell_count.value}).\n") + + if friendly_message != "": + raise OptionError(f"The options you have chosen may result in seed generation failures." + f"Please adjust the following Options for a singleplayer game.\n" + f"{friendly_message} " + f"Or set 'enforce_friendly_options' in host.yaml to false. (Use at your own risk!)") + + def verify_orb_trade_amounts(world: JakAndDaxterWorld): if world.total_trade_orbs > 2000: - raise OptionError(f"Required number of orbs for all trades ({world.total_trade_orbs}) " - f"is more than all the orbs in the game (2000). " - f"Reduce the value of either {world.options.citizen_orb_trade_amount.display_name} " + raise OptionError(f"{world.player_name}: Required number of orbs for all trades ({world.total_trade_orbs}) " + f"is more than all the orbs in the game (2000). Reduce the value of either " + f"{world.options.citizen_orb_trade_amount.display_name} " f"or {world.options.oracle_orb_trade_amount.display_name}.") diff --git a/worlds/jakanddaxter/__init__.py b/worlds/jakanddaxter/__init__.py index 1983a276f3..483484b15c 100644 --- a/worlds/jakanddaxter/__init__.py +++ b/worlds/jakanddaxter/__init__.py @@ -130,12 +130,16 @@ class JakAndDaxterWorld(World): # For the fairness of other players in a multiworld game, enforce some friendly limitations on our options, # so we don't cause chaos during seed generation. These friendly limits should **guarantee** a successful gen. enforce_friendly_options = Utils.get_settings()["jakanddaxter_options"]["enforce_friendly_options"] - if self.multiworld.players > 1 and enforce_friendly_options: - from .Rules import enforce_multiplayer_limits - enforce_multiplayer_limits(self.options) + if enforce_friendly_options: + if self.multiworld.players > 1: + from .Rules import enforce_multiplayer_limits + enforce_multiplayer_limits(self) + else: + from .Rules import enforce_singleplayer_limits + enforce_singleplayer_limits(self) # Verify that we didn't overload the trade amounts with more orbs than exist in the world. - # This is easy to do by accident even in a single-player world. + # This is easy to do by accident even in a singleplayer world. self.total_trade_orbs = (9 * self.options.citizen_orb_trade_amount) + (6 * self.options.oracle_orb_trade_amount) from .Rules import verify_orb_trade_amounts verify_orb_trade_amounts(self) diff --git a/worlds/jakanddaxter/locs/OrbCacheLocations.py b/worlds/jakanddaxter/locs/OrbCacheLocations.py index 5c0fb200a4..984d8e7c28 100644 --- a/worlds/jakanddaxter/locs/OrbCacheLocations.py +++ b/worlds/jakanddaxter/locs/OrbCacheLocations.py @@ -46,7 +46,7 @@ loc_orbCacheTable = { 23348: "Orb Cache in Snowy Fort (1)", 23349: "Orb Cache in Snowy Fort (2)", 23350: "Orb Cache in Snowy Fort (3)", - # 24038: "Orb Cache at End of Blast Furnace", # TODO - IDK, we didn't need all of the orb caches for move rando. - # 24039: "Orb Cache at End of Launch Pad Room", + # 24038: "Orb Cache at End of Blast Furnace", # TODO - We didn't need all of the orb caches for move rando. + # 24039: "Orb Cache at End of Launch Pad Room", # In future, could add/fill these with filler items? # 24040: "Orb Cache at Start of Launch Pad Room", }