mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-24 19:03:26 -07:00
Added singleplayer limits, player names to enforcement rules.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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}).")
|
||||
|
||||
@@ -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}.")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user