The Witness 0.3.4 features (#780)

New options:

Shuffle Doors: Many doors in the game will open on their own upon receiving an item ("key").
Variant - Shuffle Door/Control Panels: Many panels in the game that open doors or control devices in the world will be off until receiving their respective item ("key").
Shuffle Lasers: Lasers no longer activate by solving the laser panel, instead you will get an item that activates the laser.
Shuffle Symbols: Now that there is something else to shuffle (doors / door panels), you can turn off Symbol Rando.
Shuffle Postgame (replaces "Shuffle Hard"): The randomizer will now determine by your settings which panels are in the "postgame" - Meaning they can only be accessed after you can complete your win condition anyway.
This commit is contained in:
NewSoupVi
2022-07-17 12:56:22 +02:00
committed by GitHub
parent 472e114fb9
commit bd4850b2b5
21 changed files with 2058 additions and 994 deletions

View File

@@ -2,7 +2,7 @@
Defines constants for different types of locations in the game
"""
from .Options import is_option_enabled
from .Options import is_option_enabled, get_option_value
from .player_logic import StaticWitnessLogic, WitnessPlayerLogic
@@ -42,7 +42,7 @@ class StaticWitnessLocations:
"Symmetry Island Colored Dots 6",
"Symmetry Island Fading Lines 7",
"Symmetry Island Scenery Outlines 5",
"Symmetry Island Laser",
"Symmetry Island Laser Panel",
"Orchard Apple Tree 5",
@@ -52,7 +52,7 @@ class StaticWitnessLocations:
"Desert Artificial Light Reflection 3",
"Desert Pond Reflection 5",
"Desert Flood Reflection 6",
"Desert Laser",
"Desert Laser Panel",
"Quarry Mill Eraser and Dots 6",
"Quarry Mill Eraser and Squares 8",
@@ -63,34 +63,34 @@ class StaticWitnessLocations:
"Quarry Boathouse Stars & Eraser & Shapers 2",
"Quarry Boathouse Stars & Eraser & Shapers 5",
"Quarry Discard",
"Quarry Laser",
"Quarry Laser Panel",
"Shadows Lower Avoid 8",
"Shadows Environmental Avoid 8",
"Shadows Follow 5",
"Shadows Laser",
"Shadows Laser Panel",
"Keep Hedge Maze 4",
"Keep Pressure Plates 4",
"Keep Discard",
"Keep Laser Hedges",
"Keep Laser Pressure Plates",
"Keep Laser Panel Hedges",
"Keep Laser Panel Pressure Plates",
"Shipwreck Vault Box",
"Shipwreck Discard",
"Monastery Rhombic Avoid 3",
"Monastery Branch Follow 2",
"Monastery Laser",
"Monastery Laser Panel",
"Town Cargo Box Discard",
"Town Hexagonal Reflection",
"Town Square Avoid",
"Town Church Lattice",
"Town Rooftop Discard",
"Town Symmetry Squares 5 + Dots",
"Town Full Dot Grid Shapers 5",
"Town Shapers & Dots & Eraser",
"Town Laser",
"Town Laser Panel",
"Theater Discard",
@@ -98,7 +98,7 @@ class StaticWitnessLocations:
"Jungle Waves 3",
"Jungle Waves 7",
"Jungle Popup Wall 6",
"Jungle Laser",
"Jungle Laser Panel",
"River Vault Box",
@@ -106,7 +106,7 @@ class StaticWitnessLocations:
"Bunker Drawn Squares 9",
"Bunker Drawn Squares through Tinted Glass 3",
"Bunker Drop-Down Door Squares 2",
"Bunker Laser",
"Bunker Laser Panel",
"Swamp Seperatable Shapers 6",
"Swamp Combinable Shapers 8",
@@ -117,7 +117,7 @@ class StaticWitnessLocations:
"Swamp Red Underwater Negative Shapers 4",
"Swamp More Rotated Shapers 4",
"Swamp Blue Underwater Negative Shapers 5",
"Swamp Laser",
"Swamp Laser Panel",
"Treehouse Yellow Bridge 9",
"Treehouse First Purple Bridge 5",
@@ -125,21 +125,12 @@ class StaticWitnessLocations:
"Treehouse Green Bridge 7",
"Treehouse Green Bridge Discard",
"Treehouse Left Orange Bridge 15",
"Treehouse Burned House Discard",
"Treehouse Burnt House Discard",
"Treehouse Right Orange Bridge 12",
"Treehouse Laser",
"Treehouse Laser Panel",
"Mountaintop Discard",
"Mountaintop Vault Box",
"Inside Mountain Obscured Vision 5",
"Inside Mountain Moving Background 7",
"Inside Mountain Physically Obstructed 3",
"Inside Mountain Angled Inside Trash 2",
"Inside Mountain Color Cycle 5",
"Inside Mountain Same Solution 6",
"Inside Mountain Elevator Discard",
"Inside Mountain Giant Puzzle",
}
UNCOMMON_LOCATIONS = {
@@ -156,35 +147,53 @@ class StaticWitnessLocations:
"Swamp Underwater Back Optional",
}
HARD_LOCATIONS = {
"Inside Mountain Secret Area Dot Grid Triangles 4",
"Inside Mountain Secret Area Symmetry Triangles",
"Inside Mountain Secret Area Stars & Squares and Triangles 2",
"Inside Mountain Secret Area Shapers and Triangles 2",
"Inside Mountain Secret Area Symmetry Shapers",
"Inside Mountain Secret Area Broken and Negative Shapers",
"Inside Mountain Secret Area Broken Shapers",
CAVES_LOCATIONS = {
"Inside Mountain Caves Dot Grid Triangles 4",
"Inside Mountain Caves Symmetry Triangles",
"Inside Mountain Caves Stars & Squares and Triangles 2",
"Inside Mountain Caves Shapers and Triangles 2",
"Inside Mountain Caves Symmetry Shapers",
"Inside Mountain Caves Broken and Negative Shapers",
"Inside Mountain Caves Broken Shapers",
"Inside Mountain Secret Area Rainbow Squares",
"Inside Mountain Secret Area Squares & Stars and Colored Eraser",
"Inside Mountain Secret Area Rotated Broken Shapers",
"Inside Mountain Secret Area Stars and Squares",
"Inside Mountain Secret Area Lone Pillar",
"Inside Mountain Secret Area Wooden Beam Shapers",
"Inside Mountain Secret Area Wooden Beam Squares and Shapers",
"Inside Mountain Secret Area Wooden Beam Stars and Squares",
"Inside Mountain Secret Area Wooden Beam Shapers and Stars",
"Inside Mountain Secret Area Upstairs Invisible Dots 8",
"Inside Mountain Secret Area Upstairs Invisible Dot Symmetry 3",
"Inside Mountain Secret Area Upstairs Dot Grid Negative Shapers",
"Inside Mountain Secret Area Upstairs Dot Grid Rotated Shapers",
"Inside Mountain Caves Rainbow Squares",
"Inside Mountain Caves Squares & Stars and Colored Eraser",
"Inside Mountain Caves Rotated Broken Shapers",
"Inside Mountain Caves Stars and Squares",
"Inside Mountain Caves Lone Pillar",
"Inside Mountain Caves Wooden Beam Shapers",
"Inside Mountain Caves Wooden Beam Squares and Shapers",
"Inside Mountain Caves Wooden Beam Stars and Squares",
"Inside Mountain Caves Wooden Beam Shapers and Stars",
"Inside Mountain Caves Upstairs Invisible Dots 8",
"Inside Mountain Caves Upstairs Invisible Dot Symmetry 3",
"Inside Mountain Caves Upstairs Dot Grid Negative Shapers",
"Inside Mountain Caves Upstairs Dot Grid Rotated Shapers",
"Challenge Vault Box",
"Theater Walkway Vault Box",
"Inside Mountain Bottom Layer Discard",
"Theater Challenge Video",
}
MOUNTAIN_UNREACHABLE_FROM_BEHIND = {
"Mountaintop Trap Door Triple Exit",
"Inside Mountain Obscured Vision 5",
"Inside Mountain Moving Background 7",
"Inside Mountain Physically Obstructed 3",
"Inside Mountain Angled Inside Trash 2",
"Inside Mountain Color Cycle 5",
"Inside Mountain Same Solution 6",
}
MOUNTAIN_REACHABLE_FROM_BEHIND = {
"Inside Mountain Elevator Discard",
"Inside Mountain Giant Puzzle",
"Inside Mountain Final Room Left Pillar 4",
"Inside Mountain Final Room Right Pillar 4",
}
ALL_LOCATIONS_TO_ID = dict()
@staticmethod
@@ -193,12 +202,7 @@ class StaticWitnessLocations:
Calculates the location ID for any given location
"""
panel_offset = StaticWitnessLogic.CHECKS_BY_HEX[chex]["idOffset"]
type_offset = StaticWitnessLocations.TYPE_OFFSETS[
StaticWitnessLogic.CHECKS_BY_HEX[chex]["panelType"]
]
return StaticWitnessLocations.ID_START + panel_offset + type_offset
return StaticWitnessLogic.CHECKS_BY_HEX[chex]["id"]
@staticmethod
def get_event_name(panel_hex):
@@ -213,6 +217,7 @@ class StaticWitnessLocations:
all_loc_to_id = {
panel_obj["checkName"]: self.get_id(chex)
for chex, panel_obj in StaticWitnessLogic.CHECKS_BY_HEX.items()
if panel_obj["id"]
}
all_loc_to_id = dict(
@@ -229,12 +234,34 @@ class WitnessPlayerLocations:
"""
def __init__(self, world, player, player_logic: WitnessPlayerLogic):
"""Defines locations AFTER logic changes due to options"""
self.PANEL_TYPES_TO_SHUFFLE = {"General", "Laser"}
self.CHECK_LOCATIONS = (
StaticWitnessLocations.GENERAL_LOCATIONS
)
"""Defines locations AFTER logic changes due to options"""
doors = get_option_value(world, player, "shuffle_doors")
earlyutm = is_option_enabled(world, player, "early_secret_area")
victory = get_option_value(world, player, "victory_condition")
lasers = get_option_value(world, player, "challenge_lasers")
laser_shuffle = get_option_value(world, player, "shuffle_lasers")
postgame = set()
postgame = postgame | StaticWitnessLocations.CAVES_LOCATIONS
postgame = postgame | StaticWitnessLocations.MOUNTAIN_REACHABLE_FROM_BEHIND
postgame = postgame | StaticWitnessLocations.MOUNTAIN_UNREACHABLE_FROM_BEHIND
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | postgame
if earlyutm or doors >= 2 or (victory == 1 and (lasers <= 11 or laser_shuffle)):
postgame -= StaticWitnessLocations.CAVES_LOCATIONS
if doors >= 2:
postgame -= StaticWitnessLocations.MOUNTAIN_REACHABLE_FROM_BEHIND
if victory != 2:
postgame -= StaticWitnessLocations.MOUNTAIN_UNREACHABLE_FROM_BEHIND
if is_option_enabled(world, player, "shuffle_discarded_panels"):
self.PANEL_TYPES_TO_SHUFFLE.add("Discard")
@@ -245,18 +272,11 @@ class WitnessPlayerLocations:
if is_option_enabled(world, player, "shuffle_uncommon"):
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.UNCOMMON_LOCATIONS
if is_option_enabled(world, player, "shuffle_hard"):
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.HARD_LOCATIONS
if is_option_enabled(world, player, "shuffle_symbols") and is_option_enabled(world, player, "shuffle_doors"):
if is_option_enabled(world, player, "disable_non_randomized_puzzles"):
# This particular combination of logic settings leads to logic so restrictive that generation can fail
# Hence, we add some extra sphere 0 locations
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.EXTRA_LOCATIONS
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | player_logic.ADDED_CHECKS
if not is_option_enabled(world, player, "shuffle_postgame"):
self.CHECK_LOCATIONS -= postgame
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS - {
StaticWitnessLogic.CHECKS_BY_HEX[check_hex]["checkName"]
for check_hex in player_logic.COMPLETELY_DISABLED_CHECKS
@@ -272,7 +292,7 @@ class WitnessPlayerLocations:
)
event_locations = {
p for p in player_logic.NECESSARY_EVENT_PANELS
p for p in player_logic.EVENT_PANELS
}
self.EVENT_LOCATION_TABLE = {