Skip to content

Commit aa13ba6

Browse files
NewSoupViExempt-Medic
authored andcommitted
The Witness: Local Laser Shuffle + Option Presets (ArchipelagoMW#2590)
Co-authored-by: Exempt-Medic <[email protected]>
1 parent d872061 commit aa13ba6

File tree

3 files changed

+131
-9
lines changed

3 files changed

+131
-9
lines changed

worlds/witness/Options.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ class ShuffleSymbols(DefaultOnToggle):
2828
display_name = "Shuffle Symbols"
2929

3030

31-
class ShuffleLasers(Toggle):
31+
class ShuffleLasers(Choice):
3232
"""If on, the 11 lasers are turned into items and will activate on their own upon receiving them.
3333
Note: There is a visual bug that can occur with the Desert Laser. It does not affect gameplay - The Laser can still
3434
be redirected as normal, for both applications of redirection."""
3535
display_name = "Shuffle Lasers"
36+
option_off = 0
37+
option_local = 1
38+
option_anywhere = 2
3639

3740

3841
class ShuffleDoors(Choice):

worlds/witness/__init__.py

+26-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from BaseClasses import Region, Location, MultiWorld, Item, Entrance, Tutorial, CollectionState
88
from Options import PerGameCommonOptions, Toggle
9+
from .presets import witness_option_presets
910
from .hints import get_always_hint_locations, get_always_hint_items, get_priority_hint_locations, \
1011
get_priority_hint_items, make_hints, generate_joke_hints
1112
from worlds.AutoWorld import World, WebWorld
@@ -31,6 +32,8 @@ class WitnessWebWorld(WebWorld):
3132
["NewSoupVi", "Jarno"]
3233
)]
3334

35+
options_presets = witness_option_presets
36+
3437

3538
class WitnessWorld(World):
3639
"""
@@ -102,14 +105,29 @@ def generate_early(self):
102105

103106
self.log_ids_to_hints = dict()
104107

105-
if not (self.options.shuffle_symbols or self.options.shuffle_doors or self.options.shuffle_lasers):
106-
if self.multiworld.players == 1:
107-
warning(f"{self.multiworld.get_player_name(self.player)}'s Witness world doesn't have any progression"
108-
f" items. Please turn on Symbol Shuffle, Door Shuffle or Laser Shuffle if that doesn't"
109-
f" seem right.")
110-
else:
111-
raise Exception(f"{self.multiworld.get_player_name(self.player)}'s Witness world doesn't have any"
112-
f" progression items. Please turn on Symbol Shuffle, Door Shuffle or Laser Shuffle.")
108+
interacts_with_multiworld = (
109+
self.options.shuffle_symbols or
110+
self.options.shuffle_doors or
111+
self.options.shuffle_lasers == "anywhere"
112+
)
113+
114+
has_progression = (
115+
interacts_with_multiworld
116+
or self.options.shuffle_lasers == "local"
117+
or self.options.shuffle_boat
118+
or self.options.early_caves == "add_to_pool"
119+
)
120+
121+
if not has_progression and self.multiworld.players == 1:
122+
warning(f"{self.multiworld.get_player_name(self.player)}'s Witness world doesn't have any progression"
123+
f" items. Please turn on Symbol Shuffle, Door Shuffle or Laser Shuffle if that doesn't seem right.")
124+
elif not interacts_with_multiworld and self.multiworld.players > 1:
125+
raise Exception(f"{self.multiworld.get_player_name(self.player)}'s Witness world doesn't have enough"
126+
f" progression items that can be placed in other players' worlds. Please turn on Symbol"
127+
f" Shuffle, Door Shuffle or non-local Laser Shuffle.")
128+
129+
if self.options.shuffle_lasers == "local":
130+
self.options.local_items.value |= self.item_name_groups["Lasers"]
113131

114132
def create_regions(self):
115133
self.regio.create_regions(self, self.player_logic)

worlds/witness/presets.py

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from typing import Any, Dict
2+
3+
from .options import *
4+
5+
witness_option_presets: Dict[str, Dict[str, Any]] = {
6+
# Great for short syncs & scratching that "speedrun with light routing elements" itch.
7+
"Short & Dense": {
8+
"progression_balancing": 30,
9+
10+
"puzzle_randomization": PuzzleRandomization.option_sigma_normal,
11+
12+
"shuffle_symbols": False,
13+
"shuffle_doors": ShuffleDoors.option_panels,
14+
"door_groupings": DoorGroupings.option_off,
15+
"shuffle_boat": True,
16+
"shuffle_lasers": ShuffleLasers.option_local,
17+
18+
"disable_non_randomized_puzzles": True,
19+
"shuffle_discarded_panels": False,
20+
"shuffle_vault_boxes": False,
21+
"shuffle_EPs": ShuffleEnvironmentalPuzzles.option_off,
22+
"EP_difficulty": EnvironmentalPuzzlesDifficulty.option_normal,
23+
"shuffle_postgame": False,
24+
25+
"victory_condition": VictoryCondition.option_mountain_box_short,
26+
"mountain_lasers": 7,
27+
"challenge_lasers": 11,
28+
29+
"early_caves": EarlyCaves.option_off,
30+
"elevators_come_to_you": False,
31+
32+
"trap_percentage": TrapPercentage.default,
33+
"puzzle_skip_amount": PuzzleSkipAmount.default,
34+
"hint_amount": HintAmount.default,
35+
"death_link": DeathLink.default,
36+
},
37+
38+
# For relative beginners who want to move to the next step.
39+
"Advanced, But Chill": {
40+
"progression_balancing": 30,
41+
42+
"puzzle_randomization": PuzzleRandomization.option_sigma_normal,
43+
44+
"shuffle_symbols": True,
45+
"shuffle_doors": ShuffleDoors.option_doors,
46+
"door_groupings": DoorGroupings.option_regional,
47+
"shuffle_boat": True,
48+
"shuffle_lasers": ShuffleLasers.option_off,
49+
50+
"disable_non_randomized_puzzles": False,
51+
"shuffle_discarded_panels": True,
52+
"shuffle_vault_boxes": True,
53+
"shuffle_EPs": ShuffleEnvironmentalPuzzles.option_obelisk_sides,
54+
"EP_difficulty": EnvironmentalPuzzlesDifficulty.option_normal,
55+
"shuffle_postgame": False,
56+
57+
"victory_condition": VictoryCondition.option_mountain_box_long,
58+
"mountain_lasers": 6,
59+
"challenge_lasers": 9,
60+
61+
"early_caves": EarlyCaves.option_off,
62+
"elevators_come_to_you": False,
63+
64+
"trap_percentage": TrapPercentage.default,
65+
"puzzle_skip_amount": 15,
66+
"hint_amount": HintAmount.default,
67+
"death_link": DeathLink.default,
68+
},
69+
70+
# Allsanity but without the BS (no expert, no tedious EPs).
71+
"Nice Allsanity": {
72+
"progression_balancing": 50,
73+
74+
"puzzle_randomization": PuzzleRandomization.option_sigma_normal,
75+
76+
"shuffle_symbols": True,
77+
"shuffle_doors": ShuffleDoors.option_mixed,
78+
"door_groupings": DoorGroupings.option_off,
79+
"shuffle_boat": True,
80+
"shuffle_lasers": ShuffleLasers.option_anywhere,
81+
82+
"disable_non_randomized_puzzles": False,
83+
"shuffle_discarded_panels": True,
84+
"shuffle_vault_boxes": True,
85+
"shuffle_EPs": ShuffleEnvironmentalPuzzles.option_individual,
86+
"EP_difficulty": EnvironmentalPuzzlesDifficulty.option_normal,
87+
"shuffle_postgame": False,
88+
89+
"victory_condition": VictoryCondition.option_challenge,
90+
"mountain_lasers": 6,
91+
"challenge_lasers": 9,
92+
93+
"early_caves": EarlyCaves.option_off,
94+
"elevators_come_to_you": True,
95+
96+
"trap_percentage": TrapPercentage.default,
97+
"puzzle_skip_amount": 15,
98+
"hint_amount": HintAmount.default,
99+
"death_link": DeathLink.default,
100+
},
101+
}

0 commit comments

Comments
 (0)