| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | from typing import Dict, Union | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | from BaseClasses import MultiWorld | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | from Options import Toggle, DefaultOnToggle, Option, Range, Choice | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # class HardMode(Toggle): | 
					
						
							|  |  |  | #    "Play the randomizer in hardmode" | 
					
						
							|  |  |  | #    display_name = "Hard Mode" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  | class DisableNonRandomizedPuzzles(Toggle): | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |     """Disables puzzles that cannot be randomized.
 | 
					
						
							|  |  |  |     This includes many puzzles that heavily involve the environment, such as Shadows, Monastery or Orchard. | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |     The lasers for those areas will be activated as you solve optional puzzles throughout the island."""
 | 
					
						
							|  |  |  |     display_name = "Disable non randomized puzzles" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | class EarlySecretArea(Toggle): | 
					
						
							| 
									
										
										
										
											2022-09-18 04:20:59 +02:00
										 |  |  |     """Opens the Mountainside shortcut to the Caves from the start.
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  |     (Otherwise known as "UTM", "Caves" or the "Challenge Area")"""
 | 
					
						
							| 
									
										
										
										
											2022-09-18 04:20:59 +02:00
										 |  |  |     display_name = "Early Caves" | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ShuffleSymbols(DefaultOnToggle): | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |     """You will need to unlock puzzle symbols as items to be able to solve the panels that contain those symbols.
 | 
					
						
							|  |  |  |     If you turn this off, there will be no progression items in the game unless you turn on door shuffle."""
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  |     display_name = "Shuffle Symbols" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  | class ShuffleLasers(Toggle): | 
					
						
							|  |  |  |     """If on, the 11 lasers are turned into items and will activate on their own upon receiving them.
 | 
					
						
							|  |  |  |     Note: There is a visual bug that can occur with the Desert Laser. It does not affect gameplay - The Laser can still | 
					
						
							|  |  |  |     be redirected as normal, for both applications of redirection."""
 | 
					
						
							|  |  |  |     display_name = "Shuffle Lasers" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ShuffleDoors(Choice): | 
					
						
							|  |  |  |     """If on, opening doors will require their respective "keys".
 | 
					
						
							|  |  |  |     If set to "panels", those keys will unlock the panels on doors. | 
					
						
							| 
									
										
										
										
											2022-07-23 12:42:14 +02:00
										 |  |  |     In "doors_simple" and "doors_complex", the doors will magically open by themselves upon receiving the key. | 
					
						
							|  |  |  |     The last option, "max", is a combination of "doors_complex" and "panels"."""
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  |     display_name = "Shuffle Doors" | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |     option_none = 0 | 
					
						
							|  |  |  |     option_panels = 1 | 
					
						
							|  |  |  |     option_doors_simple = 2 | 
					
						
							|  |  |  |     option_doors_complex = 3 | 
					
						
							|  |  |  |     option_max = 4 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | class ShuffleDiscardedPanels(Toggle): | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |     """Add Discarded Panels into the location pool.
 | 
					
						
							|  |  |  |     Solving certain Discarded Panels may still be necessary to beat the game, even if this is off."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |     display_name = "Shuffle Discarded Panels" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ShuffleVaultBoxes(Toggle): | 
					
						
							|  |  |  |     """Vault Boxes will have items on them.""" | 
					
						
							|  |  |  |     display_name = "Shuffle Vault Boxes" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  | class ShuffleEnvironmentalPuzzles(Choice): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Add Environmental/Obelisk Puzzles into the location pool. | 
					
						
							|  |  |  |     In "individual", every Environmental Puzzle sends an item. | 
					
						
							|  |  |  |     In "obelisk_sides", completing every puzzle on one side of an Obelisk sends an item. | 
					
						
							| 
									
										
										
										
											2023-02-03 19:38:54 +01:00
										 |  |  |     Note: In Obelisk Sides, any EPs excluded through another setting will be counted as pre-completed on their Obelisk. | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Shuffle Environmental Puzzles" | 
					
						
							|  |  |  |     option_off = 0 | 
					
						
							|  |  |  |     option_individual = 1 | 
					
						
							|  |  |  |     option_obelisk_sides = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ShuffleDog(Toggle): | 
					
						
							|  |  |  |     """Add petting the Town dog into the location pool.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     display_name = "Pet the Dog" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class EnvironmentalPuzzlesDifficulty(Choice): | 
					
						
							| 
									
										
										
										
											2023-02-03 19:38:54 +01:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     When "Shuffle Environmental Puzzles" is on, this setting governs which EPs are eligible for the location pool. | 
					
						
							|  |  |  |     On "eclipse", every EP in the game is eligible, including the 1-hour-long "Theater Eclipse EP". | 
					
						
							|  |  |  |     On "tedious", Theater Eclipse EP is excluded from the location pool. | 
					
						
							|  |  |  |     On "normal", several other difficult or long EPs are excluded as well. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  |     display_name = "Environmental Puzzles Difficulty" | 
					
						
							|  |  |  |     option_normal = 0 | 
					
						
							|  |  |  |     option_tedious = 1 | 
					
						
							|  |  |  |     option_eclipse = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  | class ShufflePostgame(Toggle): | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |     """Adds locations into the pool that are guaranteed to become accessible after or at the same time as your goal.
 | 
					
						
							| 
									
										
										
										
											2023-01-24 03:36:27 +01:00
										 |  |  |     Use this if you don't play with release on victory. IMPORTANT NOTE: The possibility of your second | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |     "Progressive Dots" showing up in the Caves is ignored, they will still be considered "postgame" in base settings."""
 | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |     display_name = "Shuffle Postgame" | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | class VictoryCondition(Choice): | 
					
						
							|  |  |  |     """Change the victory condition from the original game's ending (elevator) to beating the Challenge
 | 
					
						
							|  |  |  |     or solving the mountaintop box, either using the short solution | 
					
						
							|  |  |  |     (7 lasers or whatever you've changed it to) or the long solution (11 lasers or whatever you've changed it to)."""
 | 
					
						
							|  |  |  |     display_name = "Victory Condition" | 
					
						
							|  |  |  |     option_elevator = 0 | 
					
						
							|  |  |  |     option_challenge = 1 | 
					
						
							|  |  |  |     option_mountain_box_short = 2 | 
					
						
							|  |  |  |     option_mountain_box_long = 3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  | class PuzzleRandomization(Choice): | 
					
						
							|  |  |  |     """Puzzles in this randomizer are randomly generated. This setting changes the difficulty/types of puzzles.""" | 
					
						
							|  |  |  |     display_name = "Puzzle Randomization" | 
					
						
							|  |  |  |     option_sigma_normal = 0 | 
					
						
							|  |  |  |     option_sigma_expert = 1 | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  |     option_none = 2 | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | class MountainLasers(Range): | 
					
						
							|  |  |  |     """Sets the amount of beams required to enter the final area.""" | 
					
						
							|  |  |  |     display_name = "Required Lasers for Mountain Entry" | 
					
						
							|  |  |  |     range_start = 1 | 
					
						
							|  |  |  |     range_end = 7 | 
					
						
							|  |  |  |     default = 7 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChallengeLasers(Range): | 
					
						
							| 
									
										
										
										
											2022-09-18 04:20:59 +02:00
										 |  |  |     """Sets the amount of beams required to enter the Caves through the Mountain Bottom Floor Discard.""" | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  |     display_name = "Required Lasers for Challenge" | 
					
						
							|  |  |  |     range_start = 1 | 
					
						
							|  |  |  |     range_end = 11 | 
					
						
							|  |  |  |     default = 11 | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-09 07:20:28 +02:00
										 |  |  | class TrapPercentage(Range): | 
					
						
							|  |  |  |     """Replaces junk items with traps, at the specified rate.""" | 
					
						
							|  |  |  |     display_name = "Trap Percentage" | 
					
						
							|  |  |  |     range_start = 0 | 
					
						
							|  |  |  |     range_end = 100 | 
					
						
							|  |  |  |     default = 20 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | class PuzzleSkipAmount(Range): | 
					
						
							|  |  |  |     """Adds this number of Puzzle Skips into the pool, if there is room. Puzzle Skips let you skip one panel.
 | 
					
						
							|  |  |  |     Works on most panels in the game - The only big exception is The Challenge."""
 | 
					
						
							|  |  |  |     display_name = "Puzzle Skips" | 
					
						
							|  |  |  |     range_start = 0 | 
					
						
							| 
									
										
										
										
											2022-10-20 05:05:36 +02:00
										 |  |  |     range_end = 30 | 
					
						
							|  |  |  |     default = 10 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  | class HintAmount(Range): | 
					
						
							|  |  |  |     """Adds hints to Audio Logs. Hints will have the same number of duplicates, as many as will fit. Remaining Audio
 | 
					
						
							|  |  |  |     Logs will have junk hints."""
 | 
					
						
							|  |  |  |     display_name = "Hints on Audio Logs" | 
					
						
							|  |  |  |     range_start = 0 | 
					
						
							|  |  |  |     range_end = 49 | 
					
						
							|  |  |  |     default = 10 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 07:58:00 +01:00
										 |  |  | class DeathLink(Toggle): | 
					
						
							|  |  |  |     """If on: Whenever you fail a puzzle (with some exceptions), everyone who is also on Death Link dies.
 | 
					
						
							|  |  |  |     The effect of a "death" in The Witness is a Power Surge."""
 | 
					
						
							|  |  |  |     display_name = "Death Link" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | the_witness_options: Dict[str, type] = { | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |     "puzzle_randomization": PuzzleRandomization, | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |     "shuffle_symbols": ShuffleSymbols, | 
					
						
							|  |  |  |     "shuffle_doors": ShuffleDoors, | 
					
						
							|  |  |  |     "shuffle_lasers": ShuffleLasers, | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |     "disable_non_randomized_puzzles": DisableNonRandomizedPuzzles, | 
					
						
							|  |  |  |     "shuffle_discarded_panels": ShuffleDiscardedPanels, | 
					
						
							|  |  |  |     "shuffle_vault_boxes": ShuffleVaultBoxes, | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  |     "shuffle_EPs": ShuffleEnvironmentalPuzzles, | 
					
						
							|  |  |  |     "EP_difficulty": EnvironmentalPuzzlesDifficulty, | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |     "shuffle_postgame": ShufflePostgame, | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  |     "victory_condition": VictoryCondition, | 
					
						
							|  |  |  |     "mountain_lasers": MountainLasers, | 
					
						
							|  |  |  |     "challenge_lasers": ChallengeLasers, | 
					
						
							| 
									
										
										
										
											2022-07-23 12:42:14 +02:00
										 |  |  |     "early_secret_area": EarlySecretArea, | 
					
						
							|  |  |  |     "trap_percentage": TrapPercentage, | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  |     "puzzle_skip_amount": PuzzleSkipAmount, | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |     "hint_amount": HintAmount, | 
					
						
							| 
									
										
										
										
											2023-03-10 07:58:00 +01:00
										 |  |  |     "death_link": DeathLink, | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def is_option_enabled(world: MultiWorld, player: int, name: str) -> bool: | 
					
						
							|  |  |  |     return get_option_value(world, player, name) > 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  | def get_option_value(world: MultiWorld, player: int, name: str) -> Union[bool, int]: | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |     option = getattr(world, name, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if option is None: | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 03:04:45 +02:00
										 |  |  |     if issubclass(the_witness_options[name], Toggle) or issubclass(the_witness_options[name], DefaultOnToggle): | 
					
						
							|  |  |  |         return bool(option[player].value) | 
					
						
							|  |  |  |     return option[player].value |