Added singleplayer limits, player names to enforcement rules.

This commit is contained in:
massimilianodelliubaldini
2024-08-29 10:00:36 -04:00
parent 3eadf54bf3
commit 30f5d84ab3
5 changed files with 74 additions and 34 deletions

View File

@@ -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

View File

@@ -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}).")

View File

@@ -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}.")

View File

@@ -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)

View File

@@ -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",
}