The Witness: v4 Content Update (#1338)
## New Features: - EP Shuffle (Individual or Obelisk Sides, with varying difficulty levels) - Ability to play without Puzzle Randomization (I.e. vanilla + AP layer) - Pet the Dog to get a Puzzle Skip :) (No, really.) ## Changes: - Starting inventory behavior improved (Consider starting items like doors and lasers logically even if they aren't part of the mode) - Audio Log hint system improved (On low hint counts, you will no longer get the same locations hinted every time, i.e. always hints are shuffled) ## Fixes: - Many fixes to symbol requirements - Fixes to "shuffle_postgame" (What checks are evaluated as "postgame" in specific modes) - Logically irrelevant doors are now "useful" instead of "progression"
This commit is contained in:
@@ -13,13 +13,6 @@ class StaticWitnessLocations:
|
||||
"""
|
||||
ID_START = 158000
|
||||
|
||||
TYPE_OFFSETS = {
|
||||
"General": 0,
|
||||
"Discard": 600,
|
||||
"Vault": 650,
|
||||
"Laser": 700,
|
||||
}
|
||||
|
||||
EXTRA_LOCATIONS = {
|
||||
"Tutorial Front Left",
|
||||
"Tutorial Back Left",
|
||||
@@ -143,7 +136,214 @@ class StaticWitnessLocations:
|
||||
"Theater Mountain Video",
|
||||
"Town RGB Room Left",
|
||||
"Town RGB Room Right",
|
||||
"Town Sound Room Right",
|
||||
"Swamp Purple Underwater",
|
||||
|
||||
"First Hallway EP",
|
||||
"Tutorial Cloud EP",
|
||||
"Tutorial Patio Flowers EP",
|
||||
"Tutorial Gate EP",
|
||||
"Outside Tutorial Garden EP",
|
||||
"Outside Tutorial Town Sewer EP",
|
||||
"Outside Tutorial Path EP",
|
||||
"Outside Tutorial Tractor EP",
|
||||
"Main Island Thundercloud EP",
|
||||
"Glass Factory Vase EP",
|
||||
"Symmetry Island Glass Factory Black Line Reflection EP",
|
||||
"Symmetry Island Glass Factory Black Line EP",
|
||||
"Desert Sand Snake EP",
|
||||
"Desert Facade Right EP",
|
||||
"Desert Facade Left EP",
|
||||
"Desert Stairs Left EP",
|
||||
"Desert Stairs Right EP",
|
||||
"Desert Broken Wall Straight EP",
|
||||
"Desert Broken Wall Bend EP",
|
||||
"Desert Shore EP",
|
||||
"Desert Island EP",
|
||||
"Desert Pond Room Near Reflection EP",
|
||||
"Desert Pond Room Far Reflection EP",
|
||||
"Desert Flood Room EP",
|
||||
"Desert Elevator EP",
|
||||
"Quarry Shore EP",
|
||||
"Quarry Entrance Pipe EP",
|
||||
"Quarry Sand Pile EP",
|
||||
"Quarry Rock Line EP",
|
||||
"Quarry Rock Line Reflection EP",
|
||||
"Quarry Railroad EP",
|
||||
"Quarry Mill Ramp EP",
|
||||
"Quarry Mill Lift EP",
|
||||
"Quarry Boathouse Moving Ramp EP",
|
||||
"Quarry Boathouse Hook EP",
|
||||
"Shadows Quarry Mill Rooftop Vent EP",
|
||||
"Treehouse Beach Rock Shadow EP",
|
||||
"Treehouse Beach Sand Shadow EP",
|
||||
"Treehouse Beach Both Orange Bridges EP",
|
||||
"Keep Red Flowers EP",
|
||||
"Keep Purple Flowers EP",
|
||||
"Shipwreck Circle Near EP",
|
||||
"Shipwreck Circle Left EP",
|
||||
"Shipwreck Circle Far EP",
|
||||
"Shipwreck Stern EP",
|
||||
"Shipwreck Rope Inner EP",
|
||||
"Shipwreck Rope Outer EP",
|
||||
"Shipwreck Couch EP",
|
||||
"Keep Pressure Plates 1 EP",
|
||||
"Keep Pressure Plates 2 EP",
|
||||
"Keep Pressure Plates 3 EP",
|
||||
"Keep Pressure Plates 4 Left Exit EP",
|
||||
"Keep Pressure Plates 4 Right Exit EP",
|
||||
"Keep Path EP",
|
||||
"Keep Hedges EP",
|
||||
"Monastery Facade Left Near EP",
|
||||
"Monastery Facade Left Far Short EP",
|
||||
"Monastery Facade Left Far Long EP",
|
||||
"Monastery Facade Right Near EP",
|
||||
"Monastery Facade Left Stairs EP",
|
||||
"Monastery Facade Right Stairs EP",
|
||||
"Monastery Grass Stairs EP",
|
||||
"Monastery Left Shutter EP",
|
||||
"Monastery Middle Shutter EP",
|
||||
"Monastery Right Shutter EP",
|
||||
"Town Windmill First Blade EP",
|
||||
"Town Windmill Second Blade EP",
|
||||
"Town Windmill Third Blade EP",
|
||||
"Town Tower Underside First EP",
|
||||
"Town Tower Underside Second EP",
|
||||
"Town Tower Underside Third EP",
|
||||
"Town Tower Underside Fourth EP",
|
||||
"Town RGB House Red EP",
|
||||
"Town RGB House Green EP",
|
||||
"Town Maze Bridge Underside EP",
|
||||
"Town Black Line Redirect EP",
|
||||
"Town Black Line Church EP",
|
||||
"Town Brown Bridge EP",
|
||||
"Town Black Line Tower EP",
|
||||
"Theater Eclipse EP",
|
||||
"Theater Window EP",
|
||||
"Theater Door EP",
|
||||
"Theater Church EP",
|
||||
"Jungle Long Arch Moss EP",
|
||||
"Jungle Straight Left Moss EP",
|
||||
"Jungle Pop-up Wall Moss EP",
|
||||
"Jungle Short Arch Moss EP",
|
||||
"Jungle Entrance EP",
|
||||
"Jungle Tree Halo EP",
|
||||
"Jungle Bamboo CCW EP",
|
||||
"Jungle Bamboo CW EP",
|
||||
"River Green Leaf Moss EP",
|
||||
"River Monastery Garden Left EP",
|
||||
"River Monastery Garden Right EP",
|
||||
"River Monastery Wall EP",
|
||||
"Bunker Tinted Door EP",
|
||||
"Bunker Green Room Flowers EP",
|
||||
"Swamp Purple Sand Middle EP",
|
||||
"Swamp Purple Sand Top EP",
|
||||
"Swamp Purple Sand Bottom EP",
|
||||
"Swamp Sliding Bridge Left EP",
|
||||
"Swamp Sliding Bridge Right EP",
|
||||
"Swamp Cyan Underwater Sliding Bridge EP",
|
||||
"Swamp Rotating Bridge CCW EP",
|
||||
"Swamp Rotating Bridge CW EP",
|
||||
"Swamp Boat EP",
|
||||
"Swamp Long Bridge Side EP",
|
||||
"Swamp Purple Underwater Right EP",
|
||||
"Swamp Purple Underwater Left EP",
|
||||
"Treehouse Buoy EP",
|
||||
"Treehouse Right Orange Bridge EP",
|
||||
"Treehouse Burned House Beach EP",
|
||||
"Mountainside Cloud Cycle EP",
|
||||
"Mountainside Bush EP",
|
||||
"Mountainside Apparent River EP",
|
||||
"Mountaintop River Shape EP",
|
||||
"Mountaintop Arch Black EP",
|
||||
"Mountaintop Arch White Right EP",
|
||||
"Mountaintop Arch White Left EP",
|
||||
"Mountain Bottom Floor Yellow Bridge EP",
|
||||
"Mountain Bottom Floor Blue Bridge EP",
|
||||
"Mountain Floor 2 Pink Bridge EP",
|
||||
"Caves Skylight EP",
|
||||
"Challenge Water EP",
|
||||
"Tunnels Theater Flowers EP",
|
||||
"Boat Desert EP",
|
||||
"Boat Shipwreck CCW Underside EP",
|
||||
"Boat Shipwreck Green EP",
|
||||
"Boat Shipwreck CW Underside EP",
|
||||
"Boat Bunker Yellow Line EP",
|
||||
"Boat Town Long Sewer EP",
|
||||
"Boat Tutorial EP",
|
||||
"Boat Tutorial Reflection EP",
|
||||
"Boat Tutorial Moss EP",
|
||||
"Boat Cargo Box EP",
|
||||
|
||||
"Desert Obelisk Side 1",
|
||||
"Desert Obelisk Side 2",
|
||||
"Desert Obelisk Side 3",
|
||||
"Desert Obelisk Side 4",
|
||||
"Desert Obelisk Side 5",
|
||||
"Monastery Obelisk Side 1",
|
||||
"Monastery Obelisk Side 2",
|
||||
"Monastery Obelisk Side 3",
|
||||
"Monastery Obelisk Side 4",
|
||||
"Monastery Obelisk Side 5",
|
||||
"Monastery Obelisk Side 6",
|
||||
"Treehouse Obelisk Side 1",
|
||||
"Treehouse Obelisk Side 2",
|
||||
"Treehouse Obelisk Side 3",
|
||||
"Treehouse Obelisk Side 4",
|
||||
"Treehouse Obelisk Side 5",
|
||||
"Treehouse Obelisk Side 6",
|
||||
"River Obelisk Side 1",
|
||||
"River Obelisk Side 2",
|
||||
"River Obelisk Side 3",
|
||||
"River Obelisk Side 4",
|
||||
"River Obelisk Side 5",
|
||||
"River Obelisk Side 6",
|
||||
"Quarry Obelisk Side 1",
|
||||
"Quarry Obelisk Side 2",
|
||||
"Quarry Obelisk Side 3",
|
||||
"Quarry Obelisk Side 4",
|
||||
"Town Obelisk Side 1",
|
||||
"Town Obelisk Side 2",
|
||||
"Town Obelisk Side 3",
|
||||
"Town Obelisk Side 4",
|
||||
"Town Obelisk Side 5",
|
||||
"Town Obelisk Side 6",
|
||||
}
|
||||
|
||||
OBELISK_SIDES = {
|
||||
"Desert Obelisk Side 1",
|
||||
"Desert Obelisk Side 2",
|
||||
"Desert Obelisk Side 3",
|
||||
"Desert Obelisk Side 4",
|
||||
"Desert Obelisk Side 5",
|
||||
"Monastery Obelisk Side 1",
|
||||
"Monastery Obelisk Side 2",
|
||||
"Monastery Obelisk Side 3",
|
||||
"Monastery Obelisk Side 4",
|
||||
"Monastery Obelisk Side 5",
|
||||
"Monastery Obelisk Side 6",
|
||||
"Treehouse Obelisk Side 1",
|
||||
"Treehouse Obelisk Side 2",
|
||||
"Treehouse Obelisk Side 3",
|
||||
"Treehouse Obelisk Side 4",
|
||||
"Treehouse Obelisk Side 5",
|
||||
"Treehouse Obelisk Side 6",
|
||||
"River Obelisk Side 1",
|
||||
"River Obelisk Side 2",
|
||||
"River Obelisk Side 3",
|
||||
"River Obelisk Side 4",
|
||||
"River Obelisk Side 5",
|
||||
"River Obelisk Side 6",
|
||||
"Quarry Obelisk Side 1",
|
||||
"Quarry Obelisk Side 2",
|
||||
"Quarry Obelisk Side 3",
|
||||
"Quarry Obelisk Side 4",
|
||||
"Town Obelisk Side 1",
|
||||
"Town Obelisk Side 2",
|
||||
"Town Obelisk Side 3",
|
||||
"Town Obelisk Side 4",
|
||||
"Town Obelisk Side 5",
|
||||
"Town Obelisk Side 6",
|
||||
}
|
||||
|
||||
CAVES_LOCATIONS = {
|
||||
@@ -170,8 +370,12 @@ class StaticWitnessLocations:
|
||||
"Caves Left Upstairs Left Row 5",
|
||||
|
||||
"Tunnels Vault Box",
|
||||
"Mountain Bottom Floor Discard",
|
||||
"Theater Challenge Video",
|
||||
|
||||
"Caves Skylight EP",
|
||||
"Challenge Water EP",
|
||||
"Tunnels Theater Flowers EP",
|
||||
"Tutorial Gate EP",
|
||||
}
|
||||
|
||||
MOUNTAIN_UNREACHABLE_FROM_BEHIND = {
|
||||
@@ -183,6 +387,10 @@ class StaticWitnessLocations:
|
||||
"Mountain Floor 1 Trash Pillar 2",
|
||||
"Mountain Floor 2 Near Row 5",
|
||||
"Mountain Floor 2 Far Row 6",
|
||||
|
||||
"Mountain Bottom Floor Yellow Bridge EP",
|
||||
"Mountain Bottom Floor Blue Bridge EP",
|
||||
"Mountain Floor 2 Pink Bridge EP",
|
||||
}
|
||||
|
||||
MOUNTAIN_REACHABLE_FROM_BEHIND = {
|
||||
@@ -213,10 +421,11 @@ class StaticWitnessLocations:
|
||||
def get_event_name(panel_hex):
|
||||
"""
|
||||
Returns the event name of any given panel.
|
||||
Currently this is always "Panelname Solved"
|
||||
"""
|
||||
|
||||
return StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]["checkName"] + " Solved"
|
||||
action = " Opened" if StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]["panelType"] == "Door" else " Solved"
|
||||
|
||||
return StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]["checkName"] + action
|
||||
|
||||
def __init__(self):
|
||||
all_loc_to_id = {
|
||||
@@ -286,11 +495,26 @@ class WitnessPlayerLocations:
|
||||
if is_option_enabled(world, player, "shuffle_vault_boxes"):
|
||||
self.PANEL_TYPES_TO_SHUFFLE.add("Vault")
|
||||
|
||||
if get_option_value(world, player, "shuffle_EPs") == 1:
|
||||
self.PANEL_TYPES_TO_SHUFFLE.add("EP")
|
||||
elif get_option_value(world, player, "shuffle_EPs") == 2:
|
||||
self.PANEL_TYPES_TO_SHUFFLE.add("Obelisk Side")
|
||||
|
||||
for obelisk_loc in StaticWitnessLocations.OBELISK_SIDES:
|
||||
obelisk_loc_hex = StaticWitnessLogic.CHECKS_BY_NAME[obelisk_loc]["checkHex"]
|
||||
if player_logic.REQUIREMENTS_BY_HEX[obelisk_loc_hex] == frozenset({frozenset()}):
|
||||
self.CHECK_LOCATIONS.discard(obelisk_loc)
|
||||
|
||||
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 -= {
|
||||
StaticWitnessLogic.CHECKS_BY_HEX[panel]["checkName"]
|
||||
for panel in player_logic.PRECOMPLETED_LOCATIONS
|
||||
}
|
||||
|
||||
self.CHECK_LOCATIONS.discard(StaticWitnessLogic.CHECKS_BY_HEX[player_logic.VICTORY_LOCATION]["checkName"])
|
||||
|
||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS - {
|
||||
@@ -301,8 +525,13 @@ class WitnessPlayerLocations:
|
||||
self.CHECK_PANELHEX_TO_ID = {
|
||||
StaticWitnessLogic.CHECKS_BY_NAME[ch]["checkHex"]: StaticWitnessLocations.ALL_LOCATIONS_TO_ID[ch]
|
||||
for ch in self.CHECK_LOCATIONS
|
||||
if StaticWitnessLogic.CHECKS_BY_NAME[ch]["panelType"] in self.PANEL_TYPES_TO_SHUFFLE
|
||||
}
|
||||
|
||||
dog_hex = StaticWitnessLogic.CHECKS_BY_NAME["Town Pet the Dog"]["checkHex"]
|
||||
dog_id = StaticWitnessLocations.ALL_LOCATIONS_TO_ID["Town Pet the Dog"]
|
||||
self.CHECK_PANELHEX_TO_ID[dog_hex] = dog_id
|
||||
|
||||
self.CHECK_PANELHEX_TO_ID = dict(
|
||||
sorted(self.CHECK_PANELHEX_TO_ID.items(), key=lambda item: item[1])
|
||||
)
|
||||
@@ -317,9 +546,9 @@ class WitnessPlayerLocations:
|
||||
}
|
||||
|
||||
check_dict = {
|
||||
location: StaticWitnessLocations.get_id(StaticWitnessLogic.CHECKS_BY_NAME[location]["checkHex"])
|
||||
for location in self.CHECK_LOCATIONS
|
||||
if StaticWitnessLogic.CHECKS_BY_NAME[location]["panelType"] in self.PANEL_TYPES_TO_SHUFFLE
|
||||
StaticWitnessLogic.CHECKS_BY_HEX[location]["checkName"]:
|
||||
StaticWitnessLocations.get_id(StaticWitnessLogic.CHECKS_BY_HEX[location]["checkHex"])
|
||||
for location in self.CHECK_PANELHEX_TO_ID
|
||||
}
|
||||
|
||||
self.CHECK_LOCATION_TABLE = {**self.EVENT_LOCATION_TABLE, **check_dict}
|
||||
|
||||
Reference in New Issue
Block a user