diff --git a/worlds/witness/Options.py b/worlds/witness/Options.py index b7364b5e70ea..4c4b4f76267f 100644 --- a/worlds/witness/Options.py +++ b/worlds/witness/Options.py @@ -1,23 +1,25 @@ -from typing import Dict, Union -from BaseClasses import MultiWorld -from Options import Toggle, DefaultOnToggle, Range, Choice +from dataclasses import dataclass +from Options import Toggle, DefaultOnToggle, Range, Choice, PerGameCommonOptions -# class HardMode(Toggle): -# "Play the randomizer in hardmode" -# display_name = "Hard Mode" - class DisableNonRandomizedPuzzles(Toggle): """Disables puzzles that cannot be randomized. This includes many puzzles that heavily involve the environment, such as Shadows, Monastery or Orchard. - The lasers for those areas will be activated as you solve optional puzzles throughout the island.""" + The lasers for those areas will activate as you solve optional puzzles, such as Discarded Panels. + Additionally, the panels activating Monastery Laser and Jungle Popup Wall will be on from the start.""" display_name = "Disable non randomized puzzles" -class EarlySecretArea(Toggle): - """Opens the Mountainside shortcut to the Caves from the start. - (Otherwise known as "UTM", "Caves" or the "Challenge Area")""" +class EarlyCaves(Choice): + """Adds an item that opens the Caves Shortcuts to Swamp and Mountain, + allowing early access to the Caves even if you are not playing a remote Door Shuffle mode. + You can either add this item to the pool to be found on one of your randomized checks, + or you can outright start with it and have immediate access to the Caves. + If you choose "add_to_pool" and you are already playing a remote Door Shuffle mode, this setting will do nothing.""" display_name = "Early Caves" + option_off = 0 + option_add_to_pool = 1 + option_starting_inventory = 2 class ShuffleSymbols(DefaultOnToggle): @@ -34,27 +36,41 @@ class ShuffleLasers(Toggle): class ShuffleDoors(Choice): - """If on, opening doors will require their respective "keys". - If set to "panels", those keys will unlock the panels on doors. - 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".""" + """If on, opening doors, moving bridges etc. will require a "key". + If set to "panels", the panel on the door will be locked until receiving its corresponding key. + If set to "doors", the door will open immediately upon receiving its key. Door panels are added as location checks. + "Mixed" includes all doors from "doors", and all control panels (bridges, elevators etc.) from "panels".""" display_name = "Shuffle Doors" - option_none = 0 + option_off = 0 option_panels = 1 - option_doors_simple = 2 - option_doors_complex = 3 - option_max = 4 + option_doors = 2 + option_mixed = 3 + + +class DoorGroupings(Choice): + """If set to "none", there will be one key for every door, resulting in up to 120 keys being added to the item pool. + If set to "regional", all doors in the same general region will open at once with a single key, + reducing the amount of door items and complexity.""" + display_name = "Door Groupings" + option_off = 0 + option_regional = 1 + + +class ShuffleBoat(DefaultOnToggle): + """If set, adds a "Boat" item to the item pool. Before receiving this item, you will not be able to use the boat.""" + display_name = "Shuffle Boat" class ShuffleDiscardedPanels(Toggle): """Add Discarded Panels into the location pool. - Solving certain Discarded Panels may still be necessary to beat the game, even if this is off.""" + Solving certain Discarded Panels may still be necessary to beat the game, even if this is off - The main example + of this being the alternate activation triggers in disable_non_randomized.""" display_name = "Shuffle Discarded Panels" class ShuffleVaultBoxes(Toggle): - """Vault Boxes will have items on them.""" + """Add Vault Boxes to the location pool.""" display_name = "Shuffle Vault Boxes" @@ -132,6 +148,12 @@ class ChallengeLasers(Range): default = 11 +class ElevatorsComeToYou(Toggle): + """If true, the Quarry Elevator, Bunker Elevator and Swamp Long Bridge will "come to you" if you approach them. + This does actually affect logic as it allows unintended backwards / early access into these areas.""" + display_name = "All Bridges & Elevators come to you" + + class TrapPercentage(Range): """Replaces junk items with traps, at the specified rate.""" display_name = "Trap Percentage" @@ -150,8 +172,8 @@ class PuzzleSkipAmount(Range): 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.""" + """Adds hints to Audio Logs. If set to a low amount, up to 2 additional duplicates of each hint will be added. + Remaining Audio Logs will have junk hints.""" display_name = "Hints on Audio Logs" range_start = 0 range_end = 49 @@ -164,38 +186,26 @@ class DeathLink(Toggle): display_name = "Death Link" -the_witness_options: Dict[str, type] = { - "puzzle_randomization": PuzzleRandomization, - "shuffle_symbols": ShuffleSymbols, - "shuffle_doors": ShuffleDoors, - "shuffle_lasers": ShuffleLasers, - "disable_non_randomized_puzzles": DisableNonRandomizedPuzzles, - "shuffle_discarded_panels": ShuffleDiscardedPanels, - "shuffle_vault_boxes": ShuffleVaultBoxes, - "shuffle_EPs": ShuffleEnvironmentalPuzzles, - "EP_difficulty": EnvironmentalPuzzlesDifficulty, - "shuffle_postgame": ShufflePostgame, - "victory_condition": VictoryCondition, - "mountain_lasers": MountainLasers, - "challenge_lasers": ChallengeLasers, - "early_secret_area": EarlySecretArea, - "trap_percentage": TrapPercentage, - "puzzle_skip_amount": PuzzleSkipAmount, - "hint_amount": HintAmount, - "death_link": DeathLink, -} - - -def is_option_enabled(world: MultiWorld, player: int, name: str) -> bool: - return get_option_value(world, player, name) > 0 - - -def get_option_value(world: MultiWorld, player: int, name: str) -> Union[bool, int]: - option = getattr(world, name, None) - - if option is None: - return 0 - - if issubclass(the_witness_options[name], Toggle) or issubclass(the_witness_options[name], DefaultOnToggle): - return bool(option[player].value) - return option[player].value +@dataclass +class TheWitnessOptions(PerGameCommonOptions): + puzzle_randomization: PuzzleRandomization + shuffle_symbols: ShuffleSymbols + shuffle_doors: ShuffleDoors + door_groupings: DoorGroupings + shuffle_boat: ShuffleBoat + shuffle_lasers: ShuffleLasers + disable_non_randomized_puzzles: DisableNonRandomizedPuzzles + shuffle_discarded_panels: ShuffleDiscardedPanels + shuffle_vault_boxes: ShuffleVaultBoxes + shuffle_EPs: ShuffleEnvironmentalPuzzles + EP_difficulty: EnvironmentalPuzzlesDifficulty + shuffle_postgame: ShufflePostgame + victory_condition: VictoryCondition + mountain_lasers: MountainLasers + challenge_lasers: ChallengeLasers + early_caves: EarlyCaves + elevators_come_to_you: ElevatorsComeToYou + trap_percentage: TrapPercentage + puzzle_skip_amount: PuzzleSkipAmount + hint_amount: HintAmount + death_link: DeathLink diff --git a/worlds/witness/WitnessItems.txt b/worlds/witness/WitnessItems.txt index 71ffe276a60e..750d6bd4ebec 100644 --- a/worlds/witness/WitnessItems.txt +++ b/worlds/witness/WitnessItems.txt @@ -37,22 +37,42 @@ Jokes: Doors: 1100 - Glass Factory Entry (Panel) - 0x01A54 +1101 - Tutorial Outpost Entry (Panel) - 0x0A171 +1102 - Tutorial Outpost Exit (Panel) - 0x04CA4 1105 - Symmetry Island Lower (Panel) - 0x000B0 1107 - Symmetry Island Upper (Panel) - 0x1C349 1110 - Desert Light Room Entry (Panel) - 0x0C339 1111 - Desert Flood Controls (Panel) - 0x1C2DF,0x1831E,0x1C260,0x1831C,0x1C2F3,0x1831D,0x1C2B1,0x1831B +1112 - Desert Light Control (Panel) - 0x09FAA +1113 - Desert Flood Room Entry (Panel) - 0x0A249 +1115 - Quarry Elevator Control (Panel) - 0x17CC4 +1117 - Quarry Entry 1 (Panel) - 0x09E57 +1118 - Quarry Entry 2 (Panel) - 0x17C09 1119 - Quarry Stoneworks Entry (Panel) - 0x01E5A,0x01E59 1120 - Quarry Stoneworks Ramp Controls (Panel) - 0x03678,0x03676 1122 - Quarry Stoneworks Lift Controls (Panel) - 0x03679,0x03675 1125 - Quarry Boathouse Ramp Height Control (Panel) - 0x03852 1127 - Quarry Boathouse Ramp Horizontal Control (Panel) - 0x03858 +1129 - Quarry Boathouse Hook Control (Panel) - 0x275FA 1131 - Shadows Door Timer (Panel) - 0x334DB,0x334DC +1140 - Keep Hedge Maze 1 (Panel) - 0x00139 +1142 - Keep Hedge Maze 2 (Panel) - 0x019DC +1144 - Keep Hedge Maze 3 (Panel) - 0x019E7 +1146 - Keep Hedge Maze 4 (Panel) - 0x01A0F 1150 - Monastery Entry Left (Panel) - 0x00B10 1151 - Monastery Entry Right (Panel) - 0x00C92 -1162 - Town Tinted Glass Door (Panel) - 0x28998 +1156 - Monastery Shutters Control (Panel) - 0x09D9B +1162 - Town RGB House Entry (Panel) - 0x28998 1163 - Town Church Entry (Panel) - 0x28A0D -1166 - Town Maze Panel (Drop-Down Staircase) (Panel) - 0x28A79 -1169 - Windmill Entry (Panel) - 0x17F5F +1164 - Town RGB Control (Panel) - 0x334D8 +1166 - Town Maze Stairs (Panel) - 0x28A79 +1167 - Town Maze Rooftop Bridge (Panel) - 0x2896A +1169 - Town Windmill Entry (Panel) - 0x17F5F +1172 - Town Cargo Box Entry (Panel) - 0x0A0C8 +1182 - Windmill Turn Control (Panel) - 0x17D02 +1184 - Theater Entry (Panel) - 0x17F89 +1185 - Theater Video Input (Panel) - 0x00815 +1189 - Theater Exit (Panel) - 0x0A168,0x33AB2 1200 - Treehouse First & Second Doors (Panel) - 0x0288C,0x02886 1202 - Treehouse Third Door (Panel) - 0x0A182 1205 - Treehouse Laser House Door Timer (Panel) - 0x2700B,0x17CBC @@ -61,10 +81,24 @@ Doors: 1180 - Bunker Entry (Panel) - 0x17C2E 1183 - Bunker Tinted Glass Door (Panel) - 0x0A099 1186 - Bunker Elevator Control (Panel) - 0x0A079 +1188 - Bunker Drop-Down Door Controls (Panel) - 0x34BC5,0x34BC6 1190 - Swamp Entry (Panel) - 0x0056E 1192 - Swamp Sliding Bridge (Panel) - 0x00609,0x18488 +1194 - Swamp Platform Shortcut (Panel) - 0x17C0D 1195 - Swamp Rotating Bridge (Panel) - 0x181F5 -1197 - Swamp Maze Control (Panel) - 0x17C0A,0x17E07 +1196 - Swamp Long Bridge (Panel) - 0x17E2B +1197 - Swamp Maze Controls (Panel) - 0x17C0A,0x17E07 +1220 - Mountain Floor 1 Light Bridge (Panel) - 0x09E39 +1225 - Mountain Floor 2 Light Bridge Near (Panel) - 0x09E86 +1230 - Mountain Floor 2 Light Bridge Far (Panel) - 0x09ED8 +1235 - Mountain Floor 2 Elevator Control (Panel) - 0x09EEB +1240 - Caves Entry (Panel) - 0x00FF8 +1242 - Caves Elevator Controls (Panel) - 0x335AB,0x335AC,0x3369D +1245 - Challenge Entry (Panel) - 0x0A16E +1250 - Tunnels Entry (Panel) - 0x039B4 +1255 - Tunnels Town Shortcut (Panel) - 0x09E85 + + 1310 - Boat - 0x17CDF,0x17CC8,0x17CA6,0x09DB8,0x17C95,0x0A054 1400 - Caves Mountain Shortcut (Door) - 0x2D73F @@ -82,6 +116,7 @@ Doors: 1624 - Desert Pond Room Entry (Door) - 0x0C2C3 1627 - Desert Flood Room Entry (Door) - 0x0A24B 1630 - Desert Elevator Room Entry (Door) - 0x0C316 +1631 - Desert Elevator (Door) - 0x01317 1633 - Quarry Entry 1 (Door) - 0x09D6F 1636 - Quarry Entry 2 (Door) - 0x17C07 1639 - Quarry Stoneworks Entry (Door) - 0x02010 @@ -109,13 +144,13 @@ Doors: 1699 - Keep Pressure Plates 4 Exit (Door) - 0x01D40 1702 - Keep Shadows Shortcut (Door) - 0x09E3D 1705 - Keep Tower Shortcut (Door) - 0x04F8F -1708 - Monastery Shortcut (Door) - 0x0364E +1708 - Monastery Laser Shortcut (Door) - 0x0364E 1711 - Monastery Entry Inner (Door) - 0x0C128 1714 - Monastery Entry Outer (Door) - 0x0C153 1717 - Monastery Garden Entry (Door) - 0x03750 1718 - Town Cargo Box Entry (Door) - 0x0A0C9 1720 - Town Wooden Roof Stairs (Door) - 0x034F5 -1723 - Town Tinted Glass Door - 0x28A61 +1723 - Town RGB House Entry (Door) - 0x28A61 1726 - Town Church Entry (Door) - 0x03BB0 1729 - Town Maze Stairs (Door) - 0x28AA2 1732 - Town Windmill Entry (Door) - 0x1845B @@ -129,7 +164,7 @@ Doors: 1756 - Theater Exit Right (Door) - 0x3CCDF 1759 - Jungle Bamboo Laser Shortcut (Door) - 0x3873B 1760 - Jungle Popup Wall (Door) - 0x1475B -1762 - River Monastery Shortcut (Door) - 0x0CF2A +1762 - River Monastery Garden Shortcut (Door) - 0x0CF2A 1765 - Bunker Entry (Door) - 0x0C2A4 1768 - Bunker Tinted Glass Door - 0x17C79 1771 - Bunker UV Room Entry (Door) - 0x0C2A3 @@ -166,36 +201,66 @@ Doors: 1870 - Tunnels Town Shortcut (Door) - 0x09E87 1903 - Outside Tutorial Outpost Doors - 0x03BA2,0x0A170,0x04CA3 +1904 - Glass Factory Doors - 0x0D7ED,0x01A29 1906 - Symmetry Island Doors - 0x17F3E,0x18269 1909 - Orchard Gates - 0x03313,0x03307 -1912 - Desert Doors - 0x09FEE,0x0C2C3,0x0A24B,0x0C316 -1915 - Quarry Main Entry - 0x09D6F,0x17C07 -1918 - Quarry Stoneworks Shortcuts - 0x17CE8,0x0368A,0x275FF -1921 - Quarry Boathouse Barriers - 0x17C50,0x3865F -1924 - Shadows Laser Room Door - 0x194B2,0x19665 -1927 - Shadows Barriers - 0x19865,0x0A2DF,0x1855B,0x19ADE +1912 - Desert Doors & Elevator - 0x09FEE,0x0C2C3,0x0A24B,0x0C316,0x01317 +1915 - Quarry Entry Doors - 0x09D6F,0x17C07 +1918 - Quarry Stoneworks Doors - 0x02010,0x275FF,0x17CE8,0x0368A +1921 - Quarry Boathouse Doors - 0x17C50,0x3865F,0x2769B,0x27163 +1924 - Shadows Laser Room Doors - 0x194B2,0x19665 +1927 - Shadows Lower Doors - 0x19865,0x0A2DF,0x1855B,0x19ADE,0x19B24 1930 - Keep Hedge Maze Doors - 0x01954,0x018CE,0x019D8,0x019B5,0x019E6,0x0199A,0x01A0E 1933 - Keep Pressure Plates Doors - 0x01BEC,0x01BEA,0x01CD5,0x01D40 1936 - Keep Shortcuts - 0x09E3D,0x04F8F -1939 - Monastery Entry - 0x0C128,0x0C153 -1942 - Monastery Shortcuts - 0x0364E,0x03750 -1945 - Town Doors - 0x0A0C9,0x034F5,0x28A61,0x03BB0,0x28AA2,0x1845B,0x2897B +1939 - Monastery Entry Doors - 0x0C128,0x0C153 +1942 - Monastery Shortcuts - 0x0364E,0x03750,0x0CF2A +1945 - Town Doors - 0x0A0C9,0x034F5,0x28A61,0x03BB0,0x28AA2,0x2897B 1948 - Town Tower Doors - 0x27798,0x27799,0x2779A,0x2779C -1951 - Theater Exit - 0x0A16D,0x3CCDF -1954 - Jungle & River Shortcuts - 0x3873B,0x0CF2A +1951 - Windmill & Theater Doors - 0x0A16D,0x3CCDF,0x1845B,0x17F88 +1954 - Jungle Doors - 0x3873B,0x1475B 1957 - Bunker Doors - 0x0C2A4,0x17C79,0x0C2A3,0x0A08D -1960 - Swamp Doors - 0x00C1C,0x184B7,0x38AE6,0x18507 +1960 - Swamp Doors - 0x00C1C,0x184B7,0x18507 +1961 - Swamp Shortcuts - 0x38AE6,0x2D880 1963 - Swamp Water Pumps - 0x04B7F,0x183F2,0x305D5,0x18482,0x0A1D6 1966 - Treehouse Entry Doors - 0x0C309,0x0C310,0x0A181 -1975 - Mountain Floor 2 Stairs & Doors - 0x09FFB,0x09EDD,0x09E07 -1978 - Mountain Bottom Floor Doors to Caves - 0x17F33,0x2D77D -1981 - Caves Doors to Challenge - 0x019A5,0x0A19A -1984 - Caves Exits to Main Island - 0x2D859,0x2D73F -1987 - Tunnels Doors - 0x27739,0x27263,0x09E87 +1969 - Treehouse Upper Doors - 0x0C323,0x0C32D +1975 - Mountain Floor 1 & 2 Doors - 0x09E54,0x09FFB,0x09EDD,0x09E07 +1978 - Mountain Bottom Floor Doors - 0x0C141,0x17F33,0x09F89 +1981 - Caves Doors - 0x019A5,0x0A19A,0x2D77D +1984 - Caves Shortcuts - 0x2D859,0x2D73F +1987 - Tunnels Doors - 0x27739,0x27263,0x09E87,0x0348A + +2000 - Desert Control Panels - 0x09FAA,0x1C2DF,0x1831E,0x1C260,0x1831C,0x1C2F3,0x1831D,0x1C2B1,0x1831B +2005 - Quarry Stoneworks Control Panels - 0x03678,0x03676,0x03679,0x03675 +2010 - Quarry Boathouse Control Panels - 0x03852,0x03858,0x275FA +2015 - Town Control Panels - 0x2896A,0x334D8 +2020 - Windmill & Theater Control Panels - 0x17D02,0x00815 +2025 - Bunker Control Panels - 0x34BC5,0x34BC6,0x0A079 +2030 - Swamp Control Panels - 0x00609,0x18488,0x181F5,0x17E2B,0x17C0A,0x17E07 +2035 - Mountain & Caves Control Panels - 0x09ED8,0x09E86,0x09E39,0x09EEB,0x335AB,0x335AC,0x3369D + +2100 - Symmetry Island Panels - 0x1C349,0x000B0 +2101 - Tutorial Outpost Panels - 0x0A171,0x04CA4 +2105 - Desert Panels - 0x09FAA,0x1C2DF,0x1831E,0x1C260,0x1831C,0x1C2F3,0x1831D,0x1C2B1,0x1831B,0x0C339,0x0A249 +2110 - Quarry Outside Panels - 0x17C09,0x09E57,0x17CC4 +2115 - Quarry Stoneworks Panels - 0x01E5A,0x01E59,0x03678,0x03676,0x03679,0x03675 +2120 - Quarry Boathouse Panels - 0x03852,0x03858,0x275FA +2122 - Keep Hedge Maze Panels - 0x00139,0x019DC,0x019E7,0x01A0F +2125 - Monastery Panels - 0x09D9B,0x00C92,0x00B10 +2130 - Town Church & RGB House Panels - 0x28998,0x28A0D,0x334D8 +2135 - Town Maze Panels - 0x2896A,0x28A79 +2140 - Windmill & Theater Panels - 0x17D02,0x00815,0x17F5F,0x17F89,0x0A168,0x33AB2 +2145 - Treehouse Panels - 0x0A182,0x0288C,0x02886,0x2700B,0x17CBC,0x037FF +2150 - Bunker Panels - 0x34BC5,0x34BC6,0x0A079,0x0A099,0x17C2E +2155 - Swamp Panels - 0x00609,0x18488,0x181F5,0x17E2B,0x17C0A,0x17E07,0x17C0D,0x0056E +2160 - Mountain Panels - 0x09ED8,0x09E86,0x09E39,0x09EEB +2165 - Caves Panels - 0x3369D,0x00FF8,0x0A16E,0x335AB,0x335AC +2170 - Tunnels Panels - 0x09E85,0x039B4 Lasers: 1500 - Symmetry Laser - 0x00509 -1501 - Desert Laser - 0x012FB,0x01317 +1501 - Desert Laser - 0x012FB 1502 - Quarry Laser - 0x01539 1503 - Shadows Laser - 0x181B3 1504 - Keep Laser - 0x014BB diff --git a/worlds/witness/WitnessLogic.txt b/worlds/witness/WitnessLogic.txt index dffdc1a701d0..acfbe8c14eb0 100644 --- a/worlds/witness/WitnessLogic.txt +++ b/worlds/witness/WitnessLogic.txt @@ -1,3 +1,5 @@ +Menu (Menu) - Entry - True: + Entry (Entry): First Hallway (First Hallway) - Entry - True - First Hallway Room - 0x00064: @@ -21,9 +23,9 @@ Tutorial (Tutorial) - Outside Tutorial - 0x03629: 159513 - 0x33600 (Patio Flowers EP) - 0x0C373 - True 159517 - 0x3352F (Gate EP) - 0x03505 - True -Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2: -158650 - 0x033D4 (Vault) - True - Dots & Black/White Squares -158651 - 0x03481 (Vault Box) - 0x033D4 - True +Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2 - Outside Tutorial Vault - 0x033D0: +158650 - 0x033D4 (Vault Panel) - True - Dots & Black/White Squares +Door - 0x033D0 (Vault Door) - 0x033D4 158013 - 0x0005D (Shed Row 1) - True - Dots 158014 - 0x0005E (Shed Row 2) - 0x0005D - Dots 158015 - 0x0005F (Shed Row 3) - 0x0005E - Dots @@ -44,6 +46,9 @@ Door - 0x03BA2 (Outpost Path) - 0x0A3B5 159516 - 0x334A3 (Path EP) - True - True 159500 - 0x035C7 (Tractor EP) - True - True +Outside Tutorial Vault (Outside Tutorial): +158651 - 0x03481 (Vault Box) - True - True + Outside Tutorial Path To Outpost (Outside Tutorial) - Outside Tutorial Outpost - 0x0A170: 158011 - 0x0A171 (Outpost Entry Panel) - True - Dots & Full Dots Door - 0x0A170 (Outpost Entry) - 0x0A171 @@ -54,6 +59,7 @@ Door - 0x04CA3 (Outpost Exit) - 0x04CA4 158600 - 0x17CFB (Discard) - True - Triangles Main Island (Main Island) - Outside Tutorial - True: +159801 - 0xFFD00 (Reached Independently) - True - True 159550 - 0x28B91 (Thundercloud EP) - 0x09F98 & 0x012FB - True Outside Glass Factory (Glass Factory) - Main Island - True - Inside Glass Factory - 0x01A29: @@ -76,7 +82,7 @@ Inside Glass Factory (Glass Factory) - Inside Glass Factory Behind Back Wall - 0 158038 - 0x0343A (Melting 3) - 0x00082 - Symmetry Door - 0x0D7ED (Back Wall) - 0x0005C -Inside Glass Factory Behind Back Wall (Glass Factory) - Boat - 0x17CC8: +Inside Glass Factory Behind Back Wall (Glass Factory) - The Ocean - 0x17CC8: 158039 - 0x17CC8 (Boat Spawn) - 0x17CA6 | 0x17CDF | 0x09DB8 | 0x17C95 - Boat Outside Symmetry Island (Symmetry Island) - Main Island - True - Symmetry Island Lower - 0x17F3E: @@ -112,12 +118,12 @@ Door - 0x18269 (Upper) - 0x1C349 159000 - 0x0332B (Glass Factory Black Line Reflection EP) - True - True Symmetry Island Upper (Symmetry Island): -158065 - 0x00A52 (Yellow 1) - True - Symmetry & Colored Dots -158066 - 0x00A57 (Yellow 2) - 0x00A52 - Symmetry & Colored Dots -158067 - 0x00A5B (Yellow 3) - 0x00A57 - Symmetry & Colored Dots -158068 - 0x00A61 (Blue 1) - 0x00A52 - Symmetry & Colored Dots -158069 - 0x00A64 (Blue 2) - 0x00A61 & 0x00A52 - Symmetry & Colored Dots -158070 - 0x00A68 (Blue 3) - 0x00A64 & 0x00A57 - Symmetry & Colored Dots +158065 - 0x00A52 (Laser Yellow 1) - True - Symmetry & Colored Dots +158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Symmetry & Colored Dots +158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Symmetry & Colored Dots +158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Symmetry & Colored Dots +158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Symmetry & Colored Dots +158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Symmetry & Colored Dots 158700 - 0x0360D (Laser Panel) - 0x00A68 - True Laser - 0x00509 (Laser) - 0x0360D 159001 - 0x03367 (Glass Factory Black Line EP) - True - True @@ -135,9 +141,9 @@ Door - 0x03313 (Second Gate) - 0x032FF Orchard End (Orchard): -Desert Outside (Desert) - Main Island - True - Desert Floodlight Room - 0x09FEE: -158652 - 0x0CC7B (Vault) - True - Dots & Shapers & Rotated Shapers & Negative Shapers & Full Dots -158653 - 0x0339E (Vault Box) - 0x0CC7B - True +Desert Outside (Desert) - Main Island - True - Desert Floodlight Room - 0x09FEE - Desert Vault - 0x03444: +158652 - 0x0CC7B (Vault Panel) - True - Dots & Shapers & Rotated Shapers & Negative Shapers & Full Dots +Door - 0x03444 (Vault Door) - 0x0CC7B 158602 - 0x17CE7 (Discard) - True - Triangles 158076 - 0x00698 (Surface 1) - True - True 158077 - 0x0048F (Surface 2) - 0x00698 - True @@ -163,6 +169,9 @@ Laser - 0x012FB (Laser) - 0x03608 159040 - 0x334B9 (Shore EP) - True - True 159041 - 0x334BC (Island EP) - True - True +Desert Vault (Desert): +158653 - 0x0339E (Vault Box) - True - True + Desert Floodlight Room (Desert) - Desert Pond Room - 0x0C2C3: 158087 - 0x09FAA (Light Control) - True - True 158088 - 0x00422 (Light Room 1) - 0x09FAA - True @@ -199,18 +208,19 @@ Desert Water Levels Room (Desert) - Desert Elevator Room - 0x0C316: Door - 0x0C316 (Elevator Room Entry) - 0x18076 159034 - 0x337F8 (Flood Room EP) - 0x1C2DF - True -Desert Elevator Room (Desert) - Desert Lowest Level Inbetween Shortcuts - 0x012FB: +Desert Elevator Room (Desert) - Desert Lowest Level Inbetween Shortcuts - 0x01317: 158111 - 0x17C31 (Final Transparent) - True - True 158113 - 0x012D7 (Final Hexagonal) - 0x17C31 & 0x0A015 - True 158114 - 0x0A015 (Final Hexagonal Control) - 0x17C31 - True 158115 - 0x0A15C (Final Bent 1) - True - True 158116 - 0x09FFF (Final Bent 2) - 0x0A15C - True 158117 - 0x0A15F (Final Bent 3) - 0x09FFF - True -159035 - 0x037BB (Elevator EP) - 0x012FB - True +159035 - 0x037BB (Elevator EP) - 0x01317 - True +Door - 0x01317 (Elevator) - 0x03608 Desert Lowest Level Inbetween Shortcuts (Desert): -Outside Quarry (Quarry) - Main Island - True - Quarry Between Entrys - 0x09D6F - Quarry Elevator - TrueOneWay: +Outside Quarry (Quarry) - Main Island - True - Quarry Between Entrys - 0x09D6F - Quarry Elevator - 0xFFD00 & 0xFFD01: 158118 - 0x09E57 (Entry 1 Panel) - True - Black/White Squares 158603 - 0x17CF0 (Discard) - True - Triangles 158702 - 0x03612 (Laser Panel) - 0x0A3D0 & 0x0367C - Eraser & Shapers @@ -222,7 +232,7 @@ Door - 0x09D6F (Entry 1) - 0x09E57 159420 - 0x289CF (Rock Line EP) - True - True 159421 - 0x289D1 (Rock Line Reflection EP) - True - True -Quarry Elevator (Quarry): +Quarry Elevator (Quarry) - Outside Quarry - 0x17CC4 - Quarry - 0x17CC4: 158120 - 0x17CC4 (Elevator Control) - 0x0367C - Dots & Eraser 159403 - 0x17CB9 (Railroad EP) - 0x17CC4 - True @@ -230,28 +240,31 @@ Quarry Between Entrys (Quarry) - Quarry - 0x17C07: 158119 - 0x17C09 (Entry 2 Panel) - True - Shapers Door - 0x17C07 (Entry 2) - 0x17C09 -Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010 - Quarry Elevator - 0x17CC4: +Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010: +159802 - 0xFFD01 (Inside Reached Independently) - True - True 158121 - 0x01E5A (Stoneworks Entry Left Panel) - True - Black/White Squares 158122 - 0x01E59 (Stoneworks Entry Right Panel) - True - Dots Door - 0x02010 (Stoneworks Entry) - 0x01E59 & 0x01E5A -Quarry Stoneworks Ground Floor (Quarry Stoneworks) - Quarry - 0x275FF - Quarry Stoneworks Middle Floor - 0x03678 - Outside Quarry - 0x17CE8: +Quarry Stoneworks Ground Floor (Quarry Stoneworks) - Quarry - 0x275FF - Quarry Stoneworks Middle Floor - 0x03678 - Outside Quarry - 0x17CE8 - Quarry Stoneworks Lift - TrueOneWay: 158123 - 0x275ED (Side Exit Panel) - True - True Door - 0x275FF (Side Exit) - 0x275ED 158124 - 0x03678 (Lower Ramp Control) - True - Dots & Eraser 158145 - 0x17CAC (Roof Exit Panel) - True - True Door - 0x17CE8 (Roof Exit) - 0x17CAC -Quarry Stoneworks Middle Floor (Quarry Stoneworks) - Quarry Stoneworks Ground Floor - 0x03675 - Quarry Stoneworks Upper Floor - 0x03679: +Quarry Stoneworks Middle Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - TrueOneWay: 158125 - 0x00E0C (Lower Row 1) - True - Dots & Eraser 158126 - 0x01489 (Lower Row 2) - 0x00E0C - Dots & Eraser 158127 - 0x0148A (Lower Row 3) - 0x01489 - Dots & Eraser 158128 - 0x014D9 (Lower Row 4) - 0x0148A - Dots & Eraser 158129 - 0x014E7 (Lower Row 5) - 0x014D9 - Dots & Eraser 158130 - 0x014E8 (Lower Row 6) - 0x014E7 - Dots & Eraser + +Quarry Stoneworks Lift (Quarry Stoneworks) - Quarry Stoneworks Middle Floor - 0x03679 - Quarry Stoneworks Ground Floor - 0x03679 - Quarry Stoneworks Upper Floor - 0x03679: 158131 - 0x03679 (Lower Lift Control) - 0x014E8 - Dots & Eraser -Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Middle Floor - 0x03676 & 0x03679 - Quarry Stoneworks Ground Floor - 0x0368A: +Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - 0x03675 - Quarry Stoneworks Ground Floor - 0x0368A: 158132 - 0x03676 (Upper Ramp Control) - True - Dots & Eraser 158133 - 0x03675 (Upper Lift Control) - True - Dots & Eraser 158134 - 0x00557 (Upper Row 1) - True - Colored Squares & Eraser @@ -262,7 +275,7 @@ Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Middle Flo 158139 - 0x3C12D (Upper Row 6) - 0x0146C - Colored Squares & Eraser 158140 - 0x03686 (Upper Row 7) - 0x3C12D - Colored Squares & Eraser 158141 - 0x014E9 (Upper Row 8) - 0x03686 - Colored Squares & Eraser -158142 - 0x03677 (Stair Control) - True - Colored Squares & Eraser +158142 - 0x03677 (Stairs Panel) - True - Colored Squares & Eraser Door - 0x0368A (Stairs) - 0x03677 158143 - 0x3C125 (Control Room Left) - 0x014E9 - Black/White Squares & Dots & Eraser 158144 - 0x0367C (Control Room Right) - 0x014E9 - Colored Squares & Dots & Eraser @@ -277,7 +290,7 @@ Quarry Boathouse (Quarry Boathouse) - Quarry - True - Quarry Boathouse Upper Fro Door - 0x2769B (Dock) - 0x17CA6 Door - 0x27163 (Dock Invis Barrier) - 0x17CA6 -Quarry Boathouse Behind Staircase (Quarry Boathouse) - Boat - 0x17CA6: +Quarry Boathouse Behind Staircase (Quarry Boathouse) - The Ocean - 0x17CA6: Quarry Boathouse Upper Front (Quarry Boathouse) - Quarry Boathouse Upper Middle - 0x17C50: 158149 - 0x021B3 (Front Row 1) - True - Shapers & Eraser @@ -309,9 +322,9 @@ Door - 0x3865F (Second Barrier) - 0x38663 158169 - 0x0A3D0 (Back Second Row 3) - 0x0A3CC - Stars & Eraser & Shapers 159401 - 0x005F6 (Hook EP) - 0x275FA & 0x03852 & 0x3865F - True -Shadows (Shadows) - Main Island - True - Shadows Ledge - 0x19B24 - Shadows Laser Room - 0x194B2 & 0x19665: +Shadows (Shadows) - Main Island - True - Shadows Ledge - 0x19B24 - Shadows Laser Room - 0x194B2 | 0x19665: 158170 - 0x334DB (Door Timer Outside) - True - True -Door - 0x19B24 (Timed Door) - 0x334DB +Door - 0x19B24 (Timed Door) - 0x334DB | 0x334DC 158171 - 0x0AC74 (Intro 6) - 0x0A8DC - True 158172 - 0x0AC7A (Intro 7) - 0x0AC74 - True 158173 - 0x0A8E0 (Intro 8) - 0x0AC7A - True @@ -336,7 +349,7 @@ Shadows Ledge (Shadows) - Shadows - 0x1855B - Quarry - 0x19865 & 0x0A2DF: 158187 - 0x334DC (Door Timer Inside) - True - True 158188 - 0x198B5 (Intro 1) - True - True 158189 - 0x198BD (Intro 2) - 0x198B5 - True -158190 - 0x198BF (Intro 3) - 0x198BD & 0x334DC & 0x19B24 - True +158190 - 0x198BF (Intro 3) - 0x198BD & 0x19B24 - True Door - 0x19865 (Quarry Barrier) - 0x198BF Door - 0x0A2DF (Quarry Barrier 2) - 0x198BF 158191 - 0x19771 (Intro 4) - 0x198BF - True @@ -345,7 +358,7 @@ Door - 0x1855B (Ledge Barrier) - 0x0A8DC Door - 0x19ADE (Ledge Barrier 2) - 0x0A8DC Shadows Laser Room (Shadows): -158703 - 0x19650 (Laser Panel) - True - True +158703 - 0x19650 (Laser Panel) - 0x194B2 & 0x19665 - True Laser - 0x181B3 (Laser) - 0x19650 Treehouse Beach (Treehouse Beach) - Main Island - True: @@ -395,9 +408,9 @@ Door - 0x01D40 (Pressure Plates 4 Exit) - 0x01D3F 158205 - 0x09E49 (Shadows Shortcut Panel) - True - True Door - 0x09E3D (Shadows Shortcut) - 0x09E49 -Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True: -158654 - 0x00AFB (Vault) - True - Symmetry & Sound Dots & Colored Dots -158655 - 0x03535 (Vault Box) - 0x00AFB - True +Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True - Shipwreck Vault - 0x17BB4: +158654 - 0x00AFB (Vault Panel) - True - Symmetry & Sound Dots & Colored Dots +Door - 0x17BB4 (Vault Door) - 0x00AFB 158605 - 0x17D28 (Discard) - True - Triangles 159220 - 0x03B22 (Circle Far EP) - True - True 159221 - 0x03B23 (Circle Left EP) - True - True @@ -407,6 +420,9 @@ Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True: 159226 - 0x28ABE (Rope Outer EP) - True - True 159230 - 0x3388F (Couch EP) - 0x17CDF | 0x0A054 - True +Shipwreck Vault (Shipwreck): +158655 - 0x03535 (Vault Box) - True - True + Keep Tower (Keep) - Keep - 0x04F8F: 158206 - 0x0361B (Tower Shortcut Panel) - True - True Door - 0x04F8F (Tower Shortcut) - 0x0361B @@ -422,8 +438,8 @@ Laser - 0x014BB (Laser) - 0x0360E | 0x03317 159251 - 0x3348F (Hedges EP) - True - True Outside Monastery (Monastery) - Main Island - True - Inside Monastery - 0x0C128 & 0x0C153 - Monastery Garden - 0x03750: -158207 - 0x03713 (Shortcut Panel) - True - True -Door - 0x0364E (Shortcut) - 0x03713 +158207 - 0x03713 (Laser Shortcut Panel) - True - True +Door - 0x0364E (Laser Shortcut) - 0x03713 158208 - 0x00B10 (Entry Left) - True - True 158209 - 0x00C92 (Entry Right) - True - True Door - 0x0C128 (Entry Inner) - 0x00B10 @@ -454,7 +470,7 @@ Inside Monastery (Monastery): Monastery Garden (Monastery): -Town (Town) - Main Island - True - Boat - 0x0A054 - Town Maze Rooftop - 0x28AA2 - Town Church - True - Town Wooden Rooftop - 0x034F5 - RGB House - 0x28A61 - Windmill Interior - 0x1845B - Town Inside Cargo Box - 0x0A0C9: +Town (Town) - Main Island - True - The Ocean - 0x0A054 - Town Maze Rooftop - 0x28AA2 - Town Church - True - Town Wooden Rooftop - 0x034F5 - RGB House - 0x28A61 - Windmill Interior - 0x1845B - Town Inside Cargo Box - 0x0A0C9: 158218 - 0x0A054 (Boat Spawn) - 0x17CA6 | 0x17CDF | 0x09DB8 | 0x17C95 - Boat 158219 - 0x0A0C8 (Cargo Box Entry Panel) - True - Black/White Squares & Shapers Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 @@ -469,11 +485,11 @@ Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Dots & Full Dots 158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Dots & Full Dots Door - 0x034F5 (Wooden Roof Stairs) - 0x28AC1 -158225 - 0x28998 (Tinted Glass Door Panel) - True - Stars & Rotated Shapers -Door - 0x28A61 (Tinted Glass Door) - 0x28998 +158225 - 0x28998 (RGB House Entry Panel) - True - Stars & Rotated Shapers +Door - 0x28A61 (RGB House Entry) - 0x28998 158226 - 0x28A0D (Church Entry Panel) - 0x28A61 - Stars Door - 0x03BB0 (Church Entry) - 0x28A0D -158228 - 0x28A79 (Maze Stair Control) - True - True +158228 - 0x28A79 (Maze Panel) - True - True Door - 0x28AA2 (Maze Stairs) - 0x28A79 158241 - 0x17F5F (Windmill Entry Panel) - True - Dots Door - 0x1845B (Windmill Entry) - 0x17F5F @@ -557,7 +573,7 @@ Door - 0x3CCDF (Exit Right) - 0x33AB2 159556 - 0x33A2A (Door EP) - 0x03553 - True 159558 - 0x33B06 (Church EP) - 0x0354E - True -Jungle (Jungle) - Main Island - True - Outside Jungle River - 0x3873B - Boat - 0x17CDF: +Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF: 158251 - 0x17CDF (Shore Boat Spawn) - True - Boat 158609 - 0x17F9B (Discard) - True - Triangles 158252 - 0x002C4 (First Row 1) - True - True @@ -588,18 +604,21 @@ Door - 0x3873B (Laser Shortcut) - 0x337FA 159350 - 0x035CB (Bamboo CCW EP) - True - True 159351 - 0x035CF (Bamboo CW EP) - True - True -Outside Jungle River (River) - Main Island - True - Monastery Garden - 0x0CF2A: -158267 - 0x17CAA (Monastery Shortcut Panel) - True - True -Door - 0x0CF2A (Monastery Shortcut) - 0x17CAA -158663 - 0x15ADD (Vault) - True - Black/White Squares & Dots -158664 - 0x03702 (Vault Box) - 0x15ADD - True +Outside Jungle River (River) - Main Island - True - Monastery Garden - 0x0CF2A - River Vault - 0x15287: +158267 - 0x17CAA (Monastery Garden Shortcut Panel) - True - True +Door - 0x0CF2A (Monastery Garden Shortcut) - 0x17CAA +158663 - 0x15ADD (Vault Panel) - True - Black/White Squares & Dots +Door - 0x15287 (Vault Door) - 0x15ADD 159110 - 0x03AC5 (Green Leaf Moss EP) - True - True 159120 - 0x03BE2 (Monastery Garden Left EP) - 0x03750 - True 159121 - 0x03BE3 (Monastery Garden Right EP) - True - True 159122 - 0x0A409 (Monastery Wall EP) - True - True +River Vault (River): +158664 - 0x03702 (Vault Box) - True - True + Outside Bunker (Bunker) - Main Island - True - Bunker - 0x0C2A4: -158268 - 0x17C2E (Entry Panel) - True - Black/White Squares & Colored Squares +158268 - 0x17C2E (Entry Panel) - True - Black/White Squares Door - 0x0C2A4 (Entry) - 0x17C2E Bunker (Bunker) - Bunker Glass Room - 0x17C79: @@ -616,9 +635,9 @@ Bunker (Bunker) - Bunker Glass Room - 0x17C79: Door - 0x17C79 (Tinted Glass Door) - 0x0A099 Bunker Glass Room (Bunker) - Bunker Ultraviolet Room - 0x0C2A3: -158279 - 0x0A010 (Glass Room 1) - True - Colored Squares -158280 - 0x0A01B (Glass Room 2) - 0x0A010 - Colored Squares & Black/White Squares -158281 - 0x0A01F (Glass Room 3) - 0x0A01B - Colored Squares & Black/White Squares +158279 - 0x0A010 (Glass Room 1) - 0x17C79 - Colored Squares +158280 - 0x0A01B (Glass Room 2) - 0x17C79 & 0x0A010 - Colored Squares & Black/White Squares +158281 - 0x0A01F (Glass Room 3) - 0x17C79 & 0x0A01B - Colored Squares & Black/White Squares Door - 0x0C2A3 (UV Room Entry) - 0x0A01F Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: @@ -631,7 +650,7 @@ Door - 0x0A08D (Elevator Room Entry) - 0x17E67 Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay: 159311 - 0x035F5 (Tinted Door EP) - 0x17C79 - True -Bunker Elevator (Bunker) - Bunker Laser Platform - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: +Bunker Elevator (Bunker) - Bunker Elevator Section - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: 158286 - 0x0A079 (Elevator Control) - True - Colored Squares & Black/White Squares Bunker Green Room (Bunker) - Bunker Elevator - TrueOneWay: @@ -676,7 +695,7 @@ Swamp Near Platform (Swamp) - Swamp Cyan Underwater - 0x04B7F - Swamp Near Boat 158316 - 0x00990 (Platform Row 4) - 0x0098F - Shapers Door - 0x184B7 (Between Bridges First Door) - 0x00990 158317 - 0x17C0D (Platform Shortcut Left Panel) - True - Shapers -158318 - 0x17C0E (Platform Shortcut Right Panel) - True - Shapers +158318 - 0x17C0E (Platform Shortcut Right Panel) - 0x17C0D - Shapers Door - 0x38AE6 (Platform Shortcut Door) - 0x17C0E Door - 0x04B7F (Cyan Water Pump) - 0x00006 @@ -715,18 +734,21 @@ Swamp Rotating Bridge (Swamp) - Swamp Between Bridges Far - 0x181F5 - Swamp Near 159331 - 0x016B2 (Rotating Bridge CCW EP) - 0x181F5 - True 159334 - 0x036CE (Rotating Bridge CW EP) - 0x181F5 - True -Swamp Near Boat (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Blue Underwater - 0x18482: +Swamp Near Boat (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Blue Underwater - 0x18482 - Swamp Long Bridge - 0xFFD00 & 0xFFD02 - The Ocean - 0x09DB8: +158903 - 0xFFD02 (Beyond Rotating Bridge Reached Independently) - True - True 158328 - 0x09DB8 (Boat Spawn) - True - Boat 158329 - 0x003B2 (Beyond Rotating Bridge 1) - 0x0000A - Rotated Shapers 158330 - 0x00A1E (Beyond Rotating Bridge 2) - 0x003B2 - Rotated Shapers 158331 - 0x00C2E (Beyond Rotating Bridge 3) - 0x00A1E - Rotated Shapers 158332 - 0x00E3A (Beyond Rotating Bridge 4) - 0x00C2E - Rotated Shapers -158339 - 0x17E2B (Long Bridge Control) - True - Rotated Shapers & Shapers Door - 0x18482 (Blue Water Pump) - 0x00E3A 159332 - 0x3365F (Boat EP) - 0x09DB8 - True 159333 - 0x03731 (Long Bridge Side EP) - 0x17E2B - True -Swamp Purple Area (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Purple Underwater - 0x0A1D6: +Swamp Long Bridge (Swamp) - Swamp Near Boat - 0x17E2B - Outside Swamp - 0x17E2B: +158339 - 0x17E2B (Long Bridge Control) - True - Rotated Shapers & Shapers + +Swamp Purple Area (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Purple Underwater - 0x0A1D6 - Swamp Near Boat - TrueOneWay: Door - 0x0A1D6 (Purple Water Pump) - 0x00E3A Swamp Purple Underwater (Swamp): @@ -752,7 +774,7 @@ Laser - 0x00BF6 (Laser) - 0x03615 158342 - 0x17C02 (Laser Shortcut Right Panel) - 0x17C05 - Shapers & Negative Shapers & Rotated Shapers Door - 0x2D880 (Laser Shortcut) - 0x17C02 -Treehouse Entry Area (Treehouse) - Treehouse Between Doors - 0x0C309: +Treehouse Entry Area (Treehouse) - Treehouse Between Doors - 0x0C309 - The Ocean - 0x17C95: 158343 - 0x17C95 (Boat Spawn) - True - Boat 158344 - 0x0288C (First Door Panel) - True - Stars Door - 0x0C309 (First Door) - 0x0288C @@ -778,7 +800,7 @@ Treehouse After Yellow Bridge (Treehouse) - Treehouse Junction - 0x0A181: Door - 0x0A181 (Third Door) - 0x0A182 Treehouse Junction (Treehouse) - Treehouse Right Orange Bridge - True - Treehouse First Purple Bridge - True - Treehouse Green Bridge - True: -158356 - 0x2700B (Laser House Door Timer Outside Control) - True - True +158356 - 0x2700B (Laser House Door Timer Outside) - True - True Treehouse First Purple Bridge (Treehouse) - Treehouse Second Purple Bridge - 0x17D6C: 158357 - 0x17DC8 (First Purple Bridge 1) - True - Stars & Dots @@ -802,7 +824,7 @@ Treehouse Right Orange Bridge (Treehouse) - Treehouse Bridge Platform - 0x17DA2: 158402 - 0x17DA2 (Right Orange Bridge 12) - 0x17DB1 - Stars Treehouse Bridge Platform (Treehouse) - Main Island - 0x0C32D: -158404 - 0x037FF (Bridge Control) - True - Stars +158404 - 0x037FF (Drawbridge Panel) - True - Stars Door - 0x0C32D (Drawbridge) - 0x037FF Treehouse Second Purple Bridge (Treehouse) - Treehouse Left Orange Bridge - 0x17DC6: @@ -847,7 +869,7 @@ Treehouse Green Bridge Left House (Treehouse): 159211 - 0x220A7 (Right Orange Bridge EP) - 0x17DA2 - True Treehouse Laser Room Front Platform (Treehouse) - Treehouse Laser Room - 0x0C323: -Door - 0x0C323 (Laser House Entry) - 0x17DA2 & 0x2700B & 0x17DDB +Door - 0x0C323 (Laser House Entry) - 0x17DA2 & 0x2700B & 0x17DDB | 0x17CBC Treehouse Laser Room Back Platform (Treehouse): 158611 - 0x17FA0 (Laser Discard) - True - Triangles @@ -860,19 +882,22 @@ Treehouse Laser Room (Treehouse): 158403 - 0x17CBC (Laser House Door Timer Inside) - True - True Laser - 0x028A4 (Laser) - 0x03613 -Mountainside (Mountainside) - Main Island - True - Mountaintop - True: +Mountainside (Mountainside) - Main Island - True - Mountaintop - True - Mountainside Vault - 0x00085: 158612 - 0x17C42 (Discard) - True - Triangles -158665 - 0x002A6 (Vault) - True - Symmetry & Colored Dots & Black/White Squares & Dots -158666 - 0x03542 (Vault Box) - 0x002A6 - True +158665 - 0x002A6 (Vault Panel) - True - Symmetry & Colored Dots & Black/White Squares & Dots +Door - 0x00085 (Vault Door) - 0x002A6 159301 - 0x335AE (Cloud Cycle EP) - True - True 159325 - 0x33505 (Bush EP) - True - True 159335 - 0x03C07 (Apparent River EP) - True - True +Mountainside Vault (Mountainside): +158666 - 0x03542 (Vault Box) - True - True + Mountaintop (Mountaintop) - Mountain Top Layer - 0x17C34: 158405 - 0x0042D (River Shape) - True - True 158406 - 0x09F7F (Box Short) - 7 Lasers - True -158407 - 0x17C34 (Trap Door Triple Exit) - 0x09F7F - Stars & Black/White Squares & Stars + Same Colored Symbol -158800 - 0xFFF00 (Box Long) - 7 Lasers & 11 Lasers & 0x17C34 - True +158407 - 0x17C34 (Mountain Entry Panel) - 0x09F7F - Stars & Black/White Squares & Stars + Same Colored Symbol +158800 - 0xFFF00 (Box Long) - 11 Lasers & 0x17C34 - True 159300 - 0x001A3 (River Shape EP) - True - True 159320 - 0x3370E (Arch Black EP) - True - True 159324 - 0x336C8 (Arch White Right EP) - True - True @@ -881,7 +906,7 @@ Mountaintop (Mountaintop) - Mountain Top Layer - 0x17C34: Mountain Top Layer (Mountain Floor 1) - Mountain Top Layer Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Black/White Squares & Colored Squares & Eraser -Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: +Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Top Layer At Door - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Dots 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Dots @@ -899,6 +924,8 @@ Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: 158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Dots 158424 - 0x09EAD (Trash Pillar 1) - True - Black/White Squares & Shapers 158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Black/White Squares & Shapers + +Mountain Top Layer At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near - 0x09FFB - Mountain Floor 2 Blue Bridge - 0x09E86 - Mountain Pink Bridge EP - TrueOneWay: @@ -917,7 +944,7 @@ Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86 Mountain Floor 2 Light Bridge Room Near (Mountain Floor 2): 158431 - 0x09E86 (Light Bridge Controller Near) - True - Stars & Stars + Same Colored Symbol & Rotated Shapers & Eraser -Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay: +Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay - Mountain Floor 2 - 0x09ED8: 158432 - 0x09FCC (Far Row 1) - True - Dots 158433 - 0x09FCE (Far Row 2) - 0x09FCC - Black/White Squares 158434 - 0x09FCF (Far Row 3) - 0x09FCE - Stars @@ -935,29 +962,27 @@ Mountain Floor 2 Elevator Room (Mountain Floor 2) - Mountain Floor 2 Elevator - Mountain Floor 2 Elevator (Mountain Floor 2) - Mountain Floor 2 Elevator Room - 0x09EEB - Mountain Third Layer - 0x09EEB: 158439 - 0x09EEB (Elevator Control Panel) - True - Dots -Mountain Third Layer (Mountain Bottom Floor) - Mountain Floor 2 Elevator - TrueOneWay - Mountain Bottom Floor - 0x09F89: +Mountain Third Layer (Mountain Bottom Floor) - Mountain Floor 2 Elevator - TrueOneWay - Mountain Bottom Floor - 0x09F89 - Mountain Pink Bridge EP - TrueOneWay: 158440 - 0x09FC1 (Giant Puzzle Bottom Left) - True - Shapers & Eraser 158441 - 0x09F8E (Giant Puzzle Bottom Right) - True - Shapers & Eraser 158442 - 0x09F01 (Giant Puzzle Top Right) - True - Rotated Shapers 158443 - 0x09EFF (Giant Puzzle Top Left) - True - Shapers & Eraser 158444 - 0x09FDA (Giant Puzzle) - 0x09FC1 & 0x09F8E & 0x09F01 & 0x09EFF - Shapers & Symmetry +159313 - 0x09D5D (Yellow Bridge EP) - 0x09E86 & 0x09ED8 - True +159314 - 0x09D5E (Blue Bridge EP) - 0x09E86 & 0x09ED8 - True Door - 0x09F89 (Exit) - 0x09FDA -Mountain Bottom Floor (Mountain Bottom Floor) - Mountain Bottom Floor Rock - 0x17FA2 - Final Room - 0x0C141 - Mountain Pink Bridge EP - TrueOneWay: +Mountain Bottom Floor (Mountain Bottom Floor) - Mountain Path to Caves - 0x17F33 - Final Room - 0x0C141: 158614 - 0x17FA2 (Discard) - 0xFFF00 - Triangles 158445 - 0x01983 (Final Room Entry Left) - True - Shapers & Stars 158446 - 0x01987 (Final Room Entry Right) - True - Colored Squares & Dots Door - 0x0C141 (Final Room Entry) - 0x01983 & 0x01987 -159313 - 0x09D5D (Yellow Bridge EP) - 0x09E86 & 0x09ED8 - True -159314 - 0x09D5E (Blue Bridge EP) - 0x09E86 & 0x09ED8 - True +Door - 0x17F33 (Rock Open) - 0x17FA2 | 0x334E1 Mountain Pink Bridge EP (Mountain Floor 2): 159312 - 0x09D63 (Pink Bridge EP) - 0x09E39 - True -Mountain Bottom Floor Rock (Mountain Bottom Floor) - Mountain Bottom Floor - 0x17F33 - Mountain Path to Caves - 0x17F33: -Door - 0x17F33 (Rock Open) - True - True - -Mountain Path to Caves (Mountain Bottom Floor) - Mountain Bottom Floor Rock - 0x334E1 - Caves - 0x2D77D: +Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D: 158447 - 0x00FF8 (Caves Entry Panel) - True - Triangles & Black/White Squares Door - 0x2D77D (Caves Entry) - 0x00FF8 158448 - 0x334E1 (Rock Control) - True - True @@ -1021,7 +1046,7 @@ Path to Challenge (Caves) - Challenge - 0x0A19A: 158477 - 0x0A16E (Challenge Entry Panel) - True - Stars & Shapers & Stars + Same Colored Symbol Door - 0x0A19A (Challenge Entry) - 0x0A16E -Challenge (Challenge) - Tunnels - 0x0348A: +Challenge (Challenge) - Tunnels - 0x0348A - Challenge Vault - 0x04D75: 158499 - 0x0A332 (Start Timer) - 11 Lasers - True 158500 - 0x0088E (Small Basic) - 0x0A332 - True 158501 - 0x00BAF (Big Basic) - 0x0088E - True @@ -1041,11 +1066,14 @@ Challenge (Challenge) - Tunnels - 0x0348A: 158515 - 0x034EC (Maze Hidden 2) - 0x00C68 | 0x00C59 | 0x00C22 - Triangles 158516 - 0x1C31A (Dots Pillar) - 0x034F4 & 0x034EC - Dots & Symmetry 158517 - 0x1C319 (Squares Pillar) - 0x034F4 & 0x034EC - Black/White Squares & Symmetry -158667 - 0x0356B (Vault Box) - 0x1C31A & 0x1C319 - True +Door - 0x04D75 (Vault Door) - 0x1C31A & 0x1C319 158518 - 0x039B4 (Tunnels Entry Panel) - True - Triangles Door - 0x0348A (Tunnels Entry) - 0x039B4 159530 - 0x28B30 (Water EP) - True - True +Challenge Vault (Challenge): +158667 - 0x0356B (Vault Box) - 0x1C31A & 0x1C319 - True + Tunnels (Tunnels) - Windmill Interior - 0x27739 - Desert Lowest Level Inbetween Shortcuts - 0x27263 - Town - 0x09E87: 158668 - 0x2FAF6 (Vault Box) - True - True 158519 - 0x27732 (Theater Shortcut Panel) - True - True @@ -1075,7 +1103,7 @@ Elevator (Mountain Final Room): 158535 - 0x3D9A8 (Back Wall Right) - 0x3D9A6 | 0x3D9A7 - True 158536 - 0x3D9A9 (Elevator Start) - 0x3D9AA & 7 Lasers | 0x3D9A8 & 7 Lasers - True -Boat (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Treehouse Entry Area - TrueOneWay - Quarry Boathouse Behind Staircase - TrueOneWay - Inside Glass Factory Behind Back Wall - TrueOneWay: +The Ocean (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Treehouse Entry Area - TrueOneWay - Quarry Boathouse Behind Staircase - TrueOneWay - Inside Glass Factory Behind Back Wall - TrueOneWay: 159042 - 0x22106 (Desert EP) - True - True 159223 - 0x03B25 (Shipwreck CCW Underside EP) - True - True 159231 - 0x28B29 (Shipwreck Green EP) - True - True @@ -1093,34 +1121,38 @@ Obelisks (EPs) - Entry - True: 159702 - 0xFFE02 (Desert Obelisk Side 3) - 0x3351D - True 159703 - 0xFFE03 (Desert Obelisk Side 4) - 0x0053C & 0x00771 & 0x335C8 & 0x335C9 & 0x337F8 & 0x037BB & 0x220E4 & 0x220E5 - True 159704 - 0xFFE04 (Desert Obelisk Side 5) - 0x334B9 & 0x334BC & 0x22106 & 0x0A14C & 0x0A14D - True +159709 - 0x00359 (Desert Obelisk) - True - True 159710 - 0xFFE10 (Monastery Obelisk Side 1) - 0x03ABC & 0x03ABE & 0x03AC0 & 0x03AC4 - True 159711 - 0xFFE11 (Monastery Obelisk Side 2) - 0x03AC5 - True 159712 - 0xFFE12 (Monastery Obelisk Side 3) - 0x03BE2 & 0x03BE3 & 0x0A409 - True 159713 - 0xFFE13 (Monastery Obelisk Side 4) - 0x006E5 & 0x006E6 & 0x006E7 & 0x034A7 & 0x034AD & 0x034AF & 0x03DAB & 0x03DAC & 0x03DAD - True 159714 - 0xFFE14 (Monastery Obelisk Side 5) - 0x03E01 - True 159715 - 0xFFE15 (Monastery Obelisk Side 6) - 0x289F4 & 0x289F5 - True +159719 - 0x00263 (Monastery Obelisk) - True - True 159720 - 0xFFE20 (Treehouse Obelisk Side 1) - 0x0053D & 0x0053E & 0x00769 - True 159721 - 0xFFE21 (Treehouse Obelisk Side 2) - 0x33721 & 0x220A7 & 0x220BD - True 159722 - 0xFFE22 (Treehouse Obelisk Side 3) - 0x03B22 & 0x03B23 & 0x03B24 & 0x03B25 & 0x03A79 & 0x28ABD & 0x28ABE - True 159723 - 0xFFE23 (Treehouse Obelisk Side 4) - 0x3388F & 0x28B29 & 0x28B2A - True 159724 - 0xFFE24 (Treehouse Obelisk Side 5) - 0x018B6 & 0x033BE & 0x033BF & 0x033DD & 0x033E5 - True 159725 - 0xFFE25 (Treehouse Obelisk Side 6) - 0x28AE9 & 0x3348F - True +159729 - 0x00097 (Treehouse Obelisk) - True - True 159730 - 0xFFE30 (River Obelisk Side 1) - 0x001A3 & 0x335AE - True 159731 - 0xFFE31 (River Obelisk Side 2) - 0x000D3 & 0x035F5 & 0x09D5D & 0x09D5E & 0x09D63 - True 159732 - 0xFFE32 (River Obelisk Side 3) - 0x3370E & 0x035DE & 0x03601 & 0x03603 & 0x03D0D & 0x3369A & 0x336C8 & 0x33505 - True 159733 - 0xFFE33 (River Obelisk Side 4) - 0x03A9E & 0x016B2 & 0x3365F & 0x03731 & 0x036CE & 0x03C07 & 0x03A93 - True 159734 - 0xFFE34 (River Obelisk Side 5) - 0x03AA6 & 0x3397C & 0x0105D & 0x0A304 - True 159735 - 0xFFE35 (River Obelisk Side 6) - 0x035CB & 0x035CF - True +159739 - 0x00367 (River Obelisk) - True - True 159740 - 0xFFE40 (Quarry Obelisk Side 1) - 0x28A7B & 0x005F6 & 0x00859 & 0x17CB9 & 0x28A4A - True 159741 - 0xFFE41 (Quarry Obelisk Side 2) - 0x334B6 & 0x00614 & 0x0069D & 0x28A4C - True 159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 - True 159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x33692 - True 159744 - 0xFFE44 (Quarry Obelisk Side 5) - 0x03E77 & 0x03E7C - True +159749 - 0x22073 (Quarry Obelisk) - True - True 159750 - 0xFFE50 (Town Obelisk Side 1) - 0x035C7 - True 159751 - 0xFFE51 (Town Obelisk Side 2) - 0x01848 & 0x03D06 & 0x33530 & 0x33600 & 0x28A2F & 0x28A37 & 0x334A3 & 0x3352F - True 159752 - 0xFFE52 (Town Obelisk Side 3) - 0x33857 & 0x33879 & 0x03C19 - True 159753 - 0xFFE53 (Town Obelisk Side 4) - 0x28B30 & 0x035C9 - True 159754 - 0xFFE54 (Town Obelisk Side 5) - 0x03335 & 0x03412 & 0x038A6 & 0x038AA & 0x03E3F & 0x03E40 & 0x28B8E - True 159755 - 0xFFE55 (Town Obelisk Side 6) - 0x28B91 & 0x03BCE & 0x03BCF & 0x03BD1 & 0x339B6 & 0x33A20 & 0x33A29 & 0x33A2A & 0x33B06 - True - -Lasers (Lasers) - Entry - True: +159759 - 0x0A16C (Town Obelisk) - True - True diff --git a/worlds/witness/WitnessLogicExpert.txt b/worlds/witness/WitnessLogicExpert.txt index 581167cc450d..b1d9b8e30e40 100644 --- a/worlds/witness/WitnessLogicExpert.txt +++ b/worlds/witness/WitnessLogicExpert.txt @@ -1,3 +1,5 @@ +Menu (Menu) - Entry - True: + Entry (Entry): First Hallway (First Hallway) - Entry - True - First Hallway Room - 0x00064: @@ -21,9 +23,9 @@ Tutorial (Tutorial) - Outside Tutorial - True: 159513 - 0x33600 (Patio Flowers EP) - 0x0C373 - True 159517 - 0x3352F (Gate EP) - 0x03505 - True -Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2: -158650 - 0x033D4 (Vault) - True - Dots & Full Dots & Squares & Black/White Squares -158651 - 0x03481 (Vault Box) - 0x033D4 - True +Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2 - Outside Tutorial Vault - 0x033D0: +158650 - 0x033D4 (Vault Panel) - True - Dots & Full Dots & Squares & Black/White Squares +Door - 0x033D0 (Vault Door) - 0x033D4 158013 - 0x0005D (Shed Row 1) - True - Dots & Full Dots 158014 - 0x0005E (Shed Row 2) - 0x0005D - Dots & Full Dots 158015 - 0x0005F (Shed Row 3) - 0x0005E - Dots & Full Dots @@ -44,6 +46,9 @@ Door - 0x03BA2 (Outpost Path) - 0x0A3B5 159516 - 0x334A3 (Path EP) - True - True 159500 - 0x035C7 (Tractor EP) - True - True +Outside Tutorial Vault (Outside Tutorial): +158651 - 0x03481 (Vault Box) - True - True + Outside Tutorial Path To Outpost (Outside Tutorial) - Outside Tutorial Outpost - 0x0A170: 158011 - 0x0A171 (Outpost Entry Panel) - True - Dots & Full Dots & Triangles Door - 0x0A170 (Outpost Entry) - 0x0A171 @@ -54,6 +59,7 @@ Door - 0x04CA3 (Outpost Exit) - 0x04CA4 158600 - 0x17CFB (Discard) - True - Arrows Main Island (Main Island) - Outside Tutorial - True: +159801 - 0xFFD00 (Reached Independently) - True - True 159550 - 0x28B91 (Thundercloud EP) - 0x09F98 & 0x012FB - True Outside Glass Factory (Glass Factory) - Main Island - True - Inside Glass Factory - 0x01A29: @@ -76,7 +82,7 @@ Inside Glass Factory (Glass Factory) - Inside Glass Factory Behind Back Wall - 0 158038 - 0x0343A (Melting 3) - 0x00082 - Symmetry & Dots Door - 0x0D7ED (Back Wall) - 0x0005C -Inside Glass Factory Behind Back Wall (Glass Factory) - Boat - 0x17CC8: +Inside Glass Factory Behind Back Wall (Glass Factory) - The Ocean - 0x17CC8: 158039 - 0x17CC8 (Boat Spawn) - 0x17CA6 | 0x17CDF | 0x09DB8 | 0x17C95 - Boat Outside Symmetry Island (Symmetry Island) - Main Island - True - Symmetry Island Lower - 0x17F3E: @@ -112,12 +118,12 @@ Door - 0x18269 (Upper) - 0x1C349 159000 - 0x0332B (Glass Factory Black Line Reflection EP) - True - True Symmetry Island Upper (Symmetry Island): -158065 - 0x00A52 (Yellow 1) - True - Symmetry & Colored Dots -158066 - 0x00A57 (Yellow 2) - 0x00A52 - Symmetry & Colored Dots -158067 - 0x00A5B (Yellow 3) - 0x00A57 - Symmetry & Colored Dots -158068 - 0x00A61 (Blue 1) - 0x00A52 - Symmetry & Colored Dots -158069 - 0x00A64 (Blue 2) - 0x00A61 & 0x00A52 - Symmetry & Colored Dots -158070 - 0x00A68 (Blue 3) - 0x00A64 & 0x00A57 - Symmetry & Colored Dots +158065 - 0x00A52 (Laser Yellow 1) - True - Symmetry & Colored Dots +158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Symmetry & Colored Dots +158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Symmetry & Colored Dots +158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Symmetry & Colored Dots +158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Symmetry & Colored Dots +158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Symmetry & Colored Dots 158700 - 0x0360D (Laser Panel) - 0x00A68 - True Laser - 0x00509 (Laser) - 0x0360D 159001 - 0x03367 (Glass Factory Black Line EP) - True - True @@ -135,9 +141,9 @@ Door - 0x03313 (Second Gate) - 0x032FF Orchard End (Orchard): -Desert Outside (Desert) - Main Island - True - Desert Floodlight Room - 0x09FEE: -158652 - 0x0CC7B (Vault) - True - Dots & Full Dots & Stars & Stars + Same Colored Symbol & Eraser & Triangles & Shapers & Negative Shapers & Colored Squares -158653 - 0x0339E (Vault Box) - 0x0CC7B - True +Desert Outside (Desert) - Main Island - True - Desert Floodlight Room - 0x09FEE - Desert Vault - 0x03444: +158652 - 0x0CC7B (Vault Panel) - True - Dots & Full Dots & Stars & Stars + Same Colored Symbol & Eraser & Triangles & Shapers & Negative Shapers & Colored Squares +Door - 0x03444 (Vault Door) - 0x0CC7B 158602 - 0x17CE7 (Discard) - True - Arrows 158076 - 0x00698 (Surface 1) - True - True 158077 - 0x0048F (Surface 2) - 0x00698 - True @@ -163,6 +169,9 @@ Laser - 0x012FB (Laser) - 0x03608 159040 - 0x334B9 (Shore EP) - True - True 159041 - 0x334BC (Island EP) - True - True +Desert Vault (Desert): +158653 - 0x0339E (Vault Box) - True - True + Desert Floodlight Room (Desert) - Desert Pond Room - 0x0C2C3: 158087 - 0x09FAA (Light Control) - True - True 158088 - 0x00422 (Light Room 1) - 0x09FAA - True @@ -199,18 +208,19 @@ Desert Water Levels Room (Desert) - Desert Elevator Room - 0x0C316: Door - 0x0C316 (Elevator Room Entry) - 0x18076 159034 - 0x337F8 (Flood Room EP) - 0x1C2DF - True -Desert Elevator Room (Desert) - Desert Lowest Level Inbetween Shortcuts - 0x012FB: +Desert Elevator Room (Desert) - Desert Lowest Level Inbetween Shortcuts - 0x01317: 158111 - 0x17C31 (Final Transparent) - True - True 158113 - 0x012D7 (Final Hexagonal) - 0x17C31 & 0x0A015 - True 158114 - 0x0A015 (Final Hexagonal Control) - 0x17C31 - True 158115 - 0x0A15C (Final Bent 1) - True - True 158116 - 0x09FFF (Final Bent 2) - 0x0A15C - True 158117 - 0x0A15F (Final Bent 3) - 0x09FFF - True -159035 - 0x037BB (Elevator EP) - 0x012FB - True +159035 - 0x037BB (Elevator EP) - 0x01317 - True +Door - 0x01317 (Elevator) - 0x03608 Desert Lowest Level Inbetween Shortcuts (Desert): -Outside Quarry (Quarry) - Main Island - True - Quarry Between Entrys - 0x09D6F - Quarry Elevator - TrueOneWay: +Outside Quarry (Quarry) - Main Island - True - Quarry Between Entrys - 0x09D6F - Quarry Elevator - 0xFFD00 & 0xFFD01: 158118 - 0x09E57 (Entry 1 Panel) - True - Squares & Black/White Squares & Triangles 158603 - 0x17CF0 (Discard) - True - Arrows 158702 - 0x03612 (Laser Panel) - 0x0A3D0 & 0x0367C - Eraser & Triangles & Stars & Stars + Same Colored Symbol @@ -222,7 +232,7 @@ Door - 0x09D6F (Entry 1) - 0x09E57 159420 - 0x289CF (Rock Line EP) - True - True 159421 - 0x289D1 (Rock Line Reflection EP) - True - True -Quarry Elevator (Quarry): +Quarry Elevator (Quarry) - Outside Quarry - 0x17CC4 - Quarry - 0x17CC4: 158120 - 0x17CC4 (Elevator Control) - 0x0367C - Dots & Eraser 159403 - 0x17CB9 (Railroad EP) - 0x17CC4 - True @@ -230,28 +240,31 @@ Quarry Between Entrys (Quarry) - Quarry - 0x17C07: 158119 - 0x17C09 (Entry 2 Panel) - True - Shapers & Triangles Door - 0x17C07 (Entry 2) - 0x17C09 -Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010 - Quarry Elevator - 0x17CC4: +Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010: +159802 - 0xFFD01 (Inside Reached Independently) - True - True 158121 - 0x01E5A (Stoneworks Entry Left Panel) - True - Squares & Black/White Squares & Stars & Stars + Same Colored Symbol 158122 - 0x01E59 (Stoneworks Entry Right Panel) - True - Triangles Door - 0x02010 (Stoneworks Entry) - 0x01E59 & 0x01E5A -Quarry Stoneworks Ground Floor (Quarry Stoneworks) - Quarry - 0x275FF - Quarry Stoneworks Middle Floor - 0x03678 - Outside Quarry - 0x17CE8: +Quarry Stoneworks Ground Floor (Quarry Stoneworks) - Quarry - 0x275FF - Quarry Stoneworks Middle Floor - 0x03678 - Outside Quarry - 0x17CE8 - Quarry Stoneworks Lift - TrueOneWay: 158123 - 0x275ED (Side Exit Panel) - True - True Door - 0x275FF (Side Exit) - 0x275ED 158124 - 0x03678 (Lower Ramp Control) - True - Dots & Eraser 158145 - 0x17CAC (Roof Exit Panel) - True - True Door - 0x17CE8 (Roof Exit) - 0x17CAC -Quarry Stoneworks Middle Floor (Quarry Stoneworks) - Quarry Stoneworks Ground Floor - 0x03675 - Quarry Stoneworks Upper Floor - 0x03679: +Quarry Stoneworks Middle Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - TrueOneWay: 158125 - 0x00E0C (Lower Row 1) - True - Triangles & Eraser 158126 - 0x01489 (Lower Row 2) - 0x00E0C - Triangles & Eraser 158127 - 0x0148A (Lower Row 3) - 0x01489 - Triangles & Eraser 158128 - 0x014D9 (Lower Row 4) - 0x0148A - Triangles & Eraser 158129 - 0x014E7 (Lower Row 5) - 0x014D9 - Triangles & Eraser 158130 - 0x014E8 (Lower Row 6) - 0x014E7 - Triangles & Eraser + +Quarry Stoneworks Lift (Quarry Stoneworks) - Quarry Stoneworks Middle Floor - 0x03679 - Quarry Stoneworks Ground Floor - 0x03679 - Quarry Stoneworks Upper Floor - 0x03679: 158131 - 0x03679 (Lower Lift Control) - 0x014E8 - Dots & Eraser -Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Middle Floor - 0x03676 & 0x03679 - Quarry Stoneworks Ground Floor - 0x0368A: +Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - 0x03675 - Quarry Stoneworks Ground Floor - 0x0368A: 158132 - 0x03676 (Upper Ramp Control) - True - Dots & Eraser 158133 - 0x03675 (Upper Lift Control) - True - Dots & Eraser 158134 - 0x00557 (Upper Row 1) - True - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol @@ -262,7 +275,7 @@ Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Middle Flo 158139 - 0x3C12D (Upper Row 6) - 0x0146C - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol 158140 - 0x03686 (Upper Row 7) - 0x3C12D - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol 158141 - 0x014E9 (Upper Row 8) - 0x03686 - Squares & Colored Squares & Eraser & Stars & Stars + Same Colored Symbol -158142 - 0x03677 (Stair Control) - True - Squares & Colored Squares & Eraser +158142 - 0x03677 (Stairs Panel) - True - Squares & Colored Squares & Eraser Door - 0x0368A (Stairs) - 0x03677 158143 - 0x3C125 (Control Room Left) - 0x014E9 - Squares & Black/White Squares & Dots & Full Dots & Eraser 158144 - 0x0367C (Control Room Right) - 0x014E9 - Squares & Colored Squares & Triangles & Eraser & Stars & Stars + Same Colored Symbol @@ -277,7 +290,7 @@ Quarry Boathouse (Quarry Boathouse) - Quarry - True - Quarry Boathouse Upper Fro Door - 0x2769B (Dock) - 0x17CA6 Door - 0x27163 (Dock Invis Barrier) - 0x17CA6 -Quarry Boathouse Behind Staircase (Quarry Boathouse) - Boat - 0x17CA6: +Quarry Boathouse Behind Staircase (Quarry Boathouse) - The Ocean - 0x17CA6: Quarry Boathouse Upper Front (Quarry Boathouse) - Quarry Boathouse Upper Middle - 0x17C50: 158149 - 0x021B3 (Front Row 1) - True - Shapers & Eraser & Negative Shapers @@ -309,9 +322,9 @@ Door - 0x3865F (Second Barrier) - 0x38663 158169 - 0x0A3D0 (Back Second Row 3) - 0x0A3CC - Stars & Eraser & Shapers & Negative Shapers & Stars + Same Colored Symbol 159401 - 0x005F6 (Hook EP) - 0x275FA & 0x03852 & 0x3865F - True -Shadows (Shadows) - Main Island - True - Shadows Ledge - 0x19B24 - Shadows Laser Room - 0x194B2 & 0x19665: +Shadows (Shadows) - Main Island - True - Shadows Ledge - 0x19B24 - Shadows Laser Room - 0x194B2 | 0x19665: 158170 - 0x334DB (Door Timer Outside) - True - True -Door - 0x19B24 (Timed Door) - 0x334DB +Door - 0x19B24 (Timed Door) - 0x334DB | 0x334DC 158171 - 0x0AC74 (Intro 6) - 0x0A8DC - True 158172 - 0x0AC7A (Intro 7) - 0x0AC74 - True 158173 - 0x0A8E0 (Intro 8) - 0x0AC7A - True @@ -336,7 +349,7 @@ Shadows Ledge (Shadows) - Shadows - 0x1855B - Quarry - 0x19865 & 0x0A2DF: 158187 - 0x334DC (Door Timer Inside) - True - True 158188 - 0x198B5 (Intro 1) - True - True 158189 - 0x198BD (Intro 2) - 0x198B5 - True -158190 - 0x198BF (Intro 3) - 0x198BD & 0x334DC & 0x19B24 - True +158190 - 0x198BF (Intro 3) - 0x198BD & 0x19B24 - True Door - 0x19865 (Quarry Barrier) - 0x198BF Door - 0x0A2DF (Quarry Barrier 2) - 0x198BF 158191 - 0x19771 (Intro 4) - 0x198BF - True @@ -345,7 +358,7 @@ Door - 0x1855B (Ledge Barrier) - 0x0A8DC Door - 0x19ADE (Ledge Barrier 2) - 0x0A8DC Shadows Laser Room (Shadows): -158703 - 0x19650 (Laser Panel) - True - True +158703 - 0x19650 (Laser Panel) - 0x194B2 & 0x19665 - True Laser - 0x181B3 (Laser) - 0x19650 Treehouse Beach (Treehouse Beach) - Main Island - True: @@ -395,9 +408,9 @@ Door - 0x01D40 (Pressure Plates 4 Exit) - 0x01D3F 158205 - 0x09E49 (Shadows Shortcut Panel) - True - True Door - 0x09E3D (Shadows Shortcut) - 0x09E49 -Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True: -158654 - 0x00AFB (Vault) - True - Symmetry & Sound Dots & Colored Dots -158655 - 0x03535 (Vault Box) - 0x00AFB - True +Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True - Shipwreck Vault - 0x17BB4: +158654 - 0x00AFB (Vault Panel) - True - Symmetry & Sound Dots & Colored Dots +Door - 0x17BB4 (Vault Door) - 0x00AFB 158605 - 0x17D28 (Discard) - True - Arrows 159220 - 0x03B22 (Circle Far EP) - True - True 159221 - 0x03B23 (Circle Left EP) - True - True @@ -407,6 +420,9 @@ Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True: 159226 - 0x28ABE (Rope Outer EP) - True - True 159230 - 0x3388F (Couch EP) - 0x17CDF | 0x0A054 - True +Shipwreck Vault (Shipwreck): +158655 - 0x03535 (Vault Box) - True - True + Keep Tower (Keep) - Keep - 0x04F8F: 158206 - 0x0361B (Tower Shortcut Panel) - True - True Door - 0x04F8F (Tower Shortcut) - 0x0361B @@ -422,8 +438,8 @@ Laser - 0x014BB (Laser) - 0x0360E | 0x03317 159251 - 0x3348F (Hedges EP) - True - True Outside Monastery (Monastery) - Main Island - True - Inside Monastery - 0x0C128 & 0x0C153 - Monastery Garden - 0x03750: -158207 - 0x03713 (Shortcut Panel) - True - True -Door - 0x0364E (Shortcut) - 0x03713 +158207 - 0x03713 (Laser Shortcut Panel) - True - True +Door - 0x0364E (Laser Shortcut) - 0x03713 158208 - 0x00B10 (Entry Left) - True - True 158209 - 0x00C92 (Entry Right) - True - True Door - 0x0C128 (Entry Inner) - 0x00B10 @@ -454,7 +470,7 @@ Inside Monastery (Monastery): Monastery Garden (Monastery): -Town (Town) - Main Island - True - Boat - 0x0A054 - Town Maze Rooftop - 0x28AA2 - Town Church - True - Town Wooden Rooftop - 0x034F5 - RGB House - 0x28A61 - Windmill Interior - 0x1845B - Town Inside Cargo Box - 0x0A0C9: +Town (Town) - Main Island - True - The Ocean - 0x0A054 - Town Maze Rooftop - 0x28AA2 - Town Church - True - Town Wooden Rooftop - 0x034F5 - RGB House - 0x28A61 - Windmill Interior - 0x1845B - Town Inside Cargo Box - 0x0A0C9: 158218 - 0x0A054 (Boat Spawn) - 0x17CA6 | 0x17CDF | 0x09DB8 | 0x17C95 - Boat 158219 - 0x0A0C8 (Cargo Box Entry Panel) - True - Squares & Black/White Squares & Shapers & Triangles Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 @@ -469,11 +485,11 @@ Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Triangles & Dots & Full Dots 158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Triangles & Dots & Full Dots Door - 0x034F5 (Wooden Roof Stairs) - 0x28AC1 -158225 - 0x28998 (Tinted Glass Door Panel) - True - Stars & Rotated Shapers & Stars + Same Colored Symbol -Door - 0x28A61 (Tinted Glass Door) - 0x28A0D +158225 - 0x28998 (RGB House Entry Panel) - True - Stars & Rotated Shapers & Stars + Same Colored Symbol +Door - 0x28A61 (RGB House Entry) - 0x28A0D 158226 - 0x28A0D (Church Entry Panel) - 0x28998 - Stars Door - 0x03BB0 (Church Entry) - 0x03C08 -158228 - 0x28A79 (Maze Stair Control) - True - True +158228 - 0x28A79 (Maze Panel) - True - True Door - 0x28AA2 (Maze Stairs) - 0x28A79 158241 - 0x17F5F (Windmill Entry Panel) - True - Dots Door - 0x1845B (Windmill Entry) - 0x17F5F @@ -484,7 +500,7 @@ Door - 0x1845B (Windmill Entry) - 0x17F5F 159541 - 0x03412 (Tower Underside Fourth EP) - True - True 159542 - 0x038A6 (Tower Underside First EP) - True - True 159543 - 0x038AA (Tower Underside Second EP) - True - True -159545 - 0x03E40 (RGB House Green EP) - 0x334D8 & 0x03C0C & 0x03C08 - True +159545 - 0x03E40 (RGB House Green EP) - 0x334D8 - True 159546 - 0x28B8E (Maze Bridge Underside EP) - 0x2896A - True 159552 - 0x03BCF (Black Line Redirect EP) - True - True 159800 - 0xFFF80 (Pet the Dog) - True - True @@ -557,7 +573,7 @@ Door - 0x3CCDF (Exit Right) - 0x33AB2 159556 - 0x33A2A (Door EP) - 0x03553 - True 159558 - 0x33B06 (Church EP) - 0x0354E - True -Jungle (Jungle) - Main Island - True - Outside Jungle River - 0x3873B - Boat - 0x17CDF: +Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF: 158251 - 0x17CDF (Shore Boat Spawn) - True - Boat 158609 - 0x17F9B (Discard) - True - Arrows 158252 - 0x002C4 (First Row 1) - True - True @@ -588,18 +604,21 @@ Door - 0x3873B (Laser Shortcut) - 0x337FA 159350 - 0x035CB (Bamboo CCW EP) - True - True 159351 - 0x035CF (Bamboo CW EP) - True - True -Outside Jungle River (River) - Main Island - True - Monastery Garden - 0x0CF2A: -158267 - 0x17CAA (Monastery Shortcut Panel) - True - True -Door - 0x0CF2A (Monastery Shortcut) - 0x17CAA -158663 - 0x15ADD (Vault) - True - Black/White Squares & Dots -158664 - 0x03702 (Vault Box) - 0x15ADD - True +Outside Jungle River (River) - Main Island - True - Monastery Garden - 0x0CF2A - River Vault - 0x15287: +158267 - 0x17CAA (Monastery Garden Shortcut Panel) - True - True +Door - 0x0CF2A (Monastery Garden Shortcut) - 0x17CAA +158663 - 0x15ADD (Vault Panel) - True - Black/White Squares & Dots +Door - 0x15287 (Vault Door) - 0x15ADD 159110 - 0x03AC5 (Green Leaf Moss EP) - True - True 159120 - 0x03BE2 (Monastery Garden Left EP) - 0x03750 - True 159121 - 0x03BE3 (Monastery Garden Right EP) - True - True 159122 - 0x0A409 (Monastery Wall EP) - True - True +River Vault (River): +158664 - 0x03702 (Vault Box) - True - True + Outside Bunker (Bunker) - Main Island - True - Bunker - 0x0C2A4: -158268 - 0x17C2E (Entry Panel) - True - Squares & Black/White Squares & Colored Squares +158268 - 0x17C2E (Entry Panel) - True - Squares & Black/White Squares Door - 0x0C2A4 (Entry) - 0x17C2E Bunker (Bunker) - Bunker Glass Room - 0x17C79: @@ -616,9 +635,9 @@ Bunker (Bunker) - Bunker Glass Room - 0x17C79: Door - 0x17C79 (Tinted Glass Door) - 0x0A099 Bunker Glass Room (Bunker) - Bunker Ultraviolet Room - 0x0C2A3: -158279 - 0x0A010 (Glass Room 1) - True - Squares & Colored Squares -158280 - 0x0A01B (Glass Room 2) - 0x0A010 - Squares & Colored Squares & Black/White Squares -158281 - 0x0A01F (Glass Room 3) - 0x0A01B - Squares & Colored Squares & Black/White Squares +158279 - 0x0A010 (Glass Room 1) - 0x17C79 - Squares & Colored Squares +158280 - 0x0A01B (Glass Room 2) - 0x17C79 & 0x0A010 - Squares & Colored Squares & Black/White Squares +158281 - 0x0A01F (Glass Room 3) - 0x17C79 & 0x0A01B - Squares & Colored Squares & Black/White Squares Door - 0x0C2A3 (UV Room Entry) - 0x0A01F Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: @@ -631,7 +650,7 @@ Door - 0x0A08D (Elevator Room Entry) - 0x17E67 Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay: 159311 - 0x035F5 (Tinted Door EP) - 0x17C79 - True -Bunker Elevator (Bunker) - Bunker Laser Platform - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: +Bunker Elevator (Bunker) - Bunker Elevator Section - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: 158286 - 0x0A079 (Elevator Control) - True - Colored Squares & Black/White Squares Bunker Green Room (Bunker) - Bunker Elevator - TrueOneWay: @@ -676,7 +695,7 @@ Swamp Near Platform (Swamp) - Swamp Cyan Underwater - 0x04B7F - Swamp Near Boat 158316 - 0x00990 (Platform Row 4) - 0x0098F - Rotated Shapers Door - 0x184B7 (Between Bridges First Door) - 0x00990 158317 - 0x17C0D (Platform Shortcut Left Panel) - True - Rotated Shapers -158318 - 0x17C0E (Platform Shortcut Right Panel) - True - Rotated Shapers +158318 - 0x17C0E (Platform Shortcut Right Panel) - 0x17C0D - Rotated Shapers Door - 0x38AE6 (Platform Shortcut Door) - 0x17C0E Door - 0x04B7F (Cyan Water Pump) - 0x00006 @@ -715,18 +734,21 @@ Swamp Rotating Bridge (Swamp) - Swamp Between Bridges Far - 0x181F5 - Swamp Near 159331 - 0x016B2 (Rotating Bridge CCW EP) - 0x181F5 - True 159334 - 0x036CE (Rotating Bridge CW EP) - 0x181F5 - True -Swamp Near Boat (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Blue Underwater - 0x18482: +Swamp Near Boat (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Blue Underwater - 0x18482 - Swamp Long Bridge - 0xFFD00 & 0xFFD02 - The Ocean - 0x09DB8: +158903 - 0xFFD02 (Beyond Rotating Bridge Reached Independently) - True - True 158328 - 0x09DB8 (Boat Spawn) - True - Boat 158329 - 0x003B2 (Beyond Rotating Bridge 1) - 0x0000A - Shapers & Dots & Full Dots 158330 - 0x00A1E (Beyond Rotating Bridge 2) - 0x003B2 - Rotated Shapers & Shapers & Dots & Full Dots 158331 - 0x00C2E (Beyond Rotating Bridge 3) - 0x00A1E - Shapers & Dots & Full Dots 158332 - 0x00E3A (Beyond Rotating Bridge 4) - 0x00C2E - Shapers & Dots & Full Dots -158339 - 0x17E2B (Long Bridge Control) - True - Rotated Shapers & Shapers Door - 0x18482 (Blue Water Pump) - 0x00E3A 159332 - 0x3365F (Boat EP) - 0x09DB8 - True 159333 - 0x03731 (Long Bridge Side EP) - 0x17E2B - True -Swamp Purple Area (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Purple Underwater - 0x0A1D6: +Swamp Long Bridge (Swamp) - Swamp Near Boat - 0x17E2B - Outside Swamp - 0x17E2B: +158339 - 0x17E2B (Long Bridge Control) - True - Rotated Shapers & Shapers + +Swamp Purple Area (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Purple Underwater - 0x0A1D6 - Swamp Near Boat - TrueOneWay: Door - 0x0A1D6 (Purple Water Pump) - 0x00E3A Swamp Purple Underwater (Swamp): @@ -752,7 +774,7 @@ Laser - 0x00BF6 (Laser) - 0x03615 158342 - 0x17C02 (Laser Shortcut Right Panel) - 0x17C05 - Shapers & Negative Shapers & Stars & Stars + Same Colored Symbol Door - 0x2D880 (Laser Shortcut) - 0x17C02 -Treehouse Entry Area (Treehouse) - Treehouse Between Doors - 0x0C309: +Treehouse Entry Area (Treehouse) - Treehouse Between Doors - 0x0C309 - The Ocean - 0x17C95: 158343 - 0x17C95 (Boat Spawn) - True - Boat 158344 - 0x0288C (First Door Panel) - True - Stars & Stars + Same Colored Symbol & Triangles Door - 0x0C309 (First Door) - 0x0288C @@ -778,7 +800,7 @@ Treehouse After Yellow Bridge (Treehouse) - Treehouse Junction - 0x0A181: Door - 0x0A181 (Third Door) - 0x0A182 Treehouse Junction (Treehouse) - Treehouse Right Orange Bridge - True - Treehouse First Purple Bridge - True - Treehouse Green Bridge - True: -158356 - 0x2700B (Laser House Door Timer Outside Control) - True - True +158356 - 0x2700B (Laser House Door Timer Outside) - True - True Treehouse First Purple Bridge (Treehouse) - Treehouse Second Purple Bridge - 0x17D6C: 158357 - 0x17DC8 (First Purple Bridge 1) - True - Stars & Dots & Full Dots @@ -802,7 +824,7 @@ Treehouse Right Orange Bridge (Treehouse) - Treehouse Bridge Platform - 0x17DA2: 158402 - 0x17DA2 (Right Orange Bridge 12) - 0x17DB1 - Stars & Stars + Same Colored Symbol & Triangles Treehouse Bridge Platform (Treehouse) - Main Island - 0x0C32D: -158404 - 0x037FF (Bridge Control) - True - Stars +158404 - 0x037FF (Drawbridge Panel) - True - Stars Door - 0x0C32D (Drawbridge) - 0x037FF Treehouse Second Purple Bridge (Treehouse) - Treehouse Left Orange Bridge - 0x17DC6: @@ -847,7 +869,7 @@ Treehouse Green Bridge Left House (Treehouse): 159211 - 0x220A7 (Right Orange Bridge EP) - 0x17DA2 - True Treehouse Laser Room Front Platform (Treehouse) - Treehouse Laser Room - 0x0C323: -Door - 0x0C323 (Laser House Entry) - 0x17DA2 & 0x2700B & 0x17DEC +Door - 0x0C323 (Laser House Entry) - 0x17DA2 & 0x2700B & 0x17DEC | 0x17CBC Treehouse Laser Room Back Platform (Treehouse): 158611 - 0x17FA0 (Laser Discard) - True - Arrows @@ -860,19 +882,22 @@ Treehouse Laser Room (Treehouse): 158403 - 0x17CBC (Laser House Door Timer Inside) - True - True Laser - 0x028A4 (Laser) - 0x03613 -Mountainside (Mountainside) - Main Island - True - Mountaintop - True: +Mountainside (Mountainside) - Main Island - True - Mountaintop - True - Mountainside Vault - 0x00085: 158612 - 0x17C42 (Discard) - True - Arrows -158665 - 0x002A6 (Vault) - True - Symmetry & Colored Squares & Triangles & Stars & Stars + Same Colored Symbol -158666 - 0x03542 (Vault Box) - 0x002A6 - True +158665 - 0x002A6 (Vault Panel) - True - Symmetry & Colored Squares & Triangles & Stars & Stars + Same Colored Symbol +Door - 0x00085 (Vault Door) - 0x002A6 159301 - 0x335AE (Cloud Cycle EP) - True - True 159325 - 0x33505 (Bush EP) - True - True 159335 - 0x03C07 (Apparent River EP) - True - True +Mountainside Vault (Mountainside): +158666 - 0x03542 (Vault Box) - True - True + Mountaintop (Mountaintop) - Mountain Top Layer - 0x17C34: 158405 - 0x0042D (River Shape) - True - True 158406 - 0x09F7F (Box Short) - 7 Lasers - True -158407 - 0x17C34 (Trap Door Triple Exit) - 0x09F7F - Stars & Black/White Squares & Stars + Same Colored Symbol & Triangles -158800 - 0xFFF00 (Box Long) - 7 Lasers & 11 Lasers & 0x17C34 - True +158407 - 0x17C34 (Mountain Entry Panel) - 0x09F7F - Stars & Black/White Squares & Stars + Same Colored Symbol & Triangles +158800 - 0xFFF00 (Box Long) - 11 Lasers & 0x17C34 - True 159300 - 0x001A3 (River Shape EP) - True - True 159320 - 0x3370E (Arch Black EP) - True - True 159324 - 0x336C8 (Arch White Right EP) - True - True @@ -881,7 +906,7 @@ Mountaintop (Mountaintop) - Mountain Top Layer - 0x17C34: Mountain Top Layer (Mountain Floor 1) - Mountain Top Layer Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Eraser & Triangles -Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: +Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Top Layer At Door - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots & Stars & Stars + Same Colored Symbol 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Triangles 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers & Stars & Stars + Same Colored Symbol @@ -899,6 +924,8 @@ Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: 158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Stars & Shapers & Stars + Same Colored Symbol 158424 - 0x09EAD (Trash Pillar 1) - True - Rotated Shapers & Stars 158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Rotated Shapers & Triangles + +Mountain Top Layer At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near - 0x09FFB - Mountain Floor 2 Blue Bridge - 0x09E86 - Mountain Pink Bridge EP - TrueOneWay: @@ -917,7 +944,7 @@ Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86 Mountain Floor 2 Light Bridge Room Near (Mountain Floor 2): 158431 - 0x09E86 (Light Bridge Controller Near) - True - Shapers & Dots -Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay: +Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay - Mountain Floor 2 - 0x09ED8: 158432 - 0x09FCC (Far Row 1) - True - Triangles 158433 - 0x09FCE (Far Row 2) - 0x09FCC - Black/White Squares & Stars & Stars + Same Colored Symbol 158434 - 0x09FCF (Far Row 3) - 0x09FCE - Stars & Triangles & Stars + Same Colored Symbol @@ -935,29 +962,27 @@ Mountain Floor 2 Elevator Room (Mountain Floor 2) - Mountain Floor 2 Elevator - Mountain Floor 2 Elevator (Mountain Floor 2) - Mountain Floor 2 Elevator Room - 0x09EEB - Mountain Third Layer - 0x09EEB: 158439 - 0x09EEB (Elevator Control Panel) - True - Dots -Mountain Third Layer (Mountain Bottom Floor) - Mountain Floor 2 Elevator - TrueOneWay - Mountain Bottom Floor - 0x09F89: +Mountain Third Layer (Mountain Bottom Floor) - Mountain Floor 2 Elevator - TrueOneWay - Mountain Bottom Floor - 0x09F89 - Mountain Pink Bridge EP - TrueOneWay: 158440 - 0x09FC1 (Giant Puzzle Bottom Left) - True - Shapers & Eraser & Negative Shapers 158441 - 0x09F8E (Giant Puzzle Bottom Right) - True - Shapers & Eraser & Negative Shapers 158442 - 0x09F01 (Giant Puzzle Top Right) - True - Shapers & Eraser & Negative Shapers 158443 - 0x09EFF (Giant Puzzle Top Left) - True - Shapers & Eraser & Negative Shapers 158444 - 0x09FDA (Giant Puzzle) - 0x09FC1 & 0x09F8E & 0x09F01 & 0x09EFF - Shapers & Symmetry +159313 - 0x09D5D (Yellow Bridge EP) - 0x09E86 & 0x09ED8 - True +159314 - 0x09D5E (Blue Bridge EP) - 0x09E86 & 0x09ED8 - True Door - 0x09F89 (Exit) - 0x09FDA -Mountain Bottom Floor (Mountain Bottom Floor) - Mountain Bottom Floor Rock - 0x17FA2 - Final Room - 0x0C141 - Mountain Pink Bridge EP - TrueOneWay: +Mountain Bottom Floor (Mountain Bottom Floor) - Mountain Path to Caves - 0x17F33 - Final Room - 0x0C141: 158614 - 0x17FA2 (Discard) - 0xFFF00 - Arrows 158445 - 0x01983 (Final Room Entry Left) - True - Shapers & Stars 158446 - 0x01987 (Final Room Entry Right) - True - Squares & Colored Squares & Dots Door - 0x0C141 (Final Room Entry) - 0x01983 & 0x01987 -159313 - 0x09D5D (Yellow Bridge EP) - 0x09E86 & 0x09ED8 - True -159314 - 0x09D5E (Blue Bridge EP) - 0x09E86 & 0x09ED8 - True +Door - 0x17F33 (Rock Open) - 0x17FA2 | 0x334E1 Mountain Pink Bridge EP (Mountain Floor 2): 159312 - 0x09D63 (Pink Bridge EP) - 0x09E39 - True -Mountain Bottom Floor Rock (Mountain Bottom Floor) - Mountain Bottom Floor - 0x17F33 - Mountain Path to Caves - 0x17F33: -Door - 0x17F33 (Rock Open) - True - -Mountain Path to Caves (Mountain Bottom Floor) - Mountain Bottom Floor Rock - 0x334E1 - Caves - 0x2D77D: +Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D: 158447 - 0x00FF8 (Caves Entry Panel) - True - Arrows & Black/White Squares Door - 0x2D77D (Caves Entry) - 0x00FF8 158448 - 0x334E1 (Rock Control) - True - True @@ -1021,31 +1046,34 @@ Path to Challenge (Caves) - Challenge - 0x0A19A: 158477 - 0x0A16E (Challenge Entry Panel) - True - Stars & Arrows & Stars + Same Colored Symbol Door - 0x0A19A (Challenge Entry) - 0x0A16E -Challenge (Challenge) - Tunnels - 0x0348A: +Challenge (Challenge) - Tunnels - 0x0348A - Challenge Vault - 0x04D75: 158499 - 0x0A332 (Start Timer) - 11 Lasers - True 158500 - 0x0088E (Small Basic) - 0x0A332 - True 158501 - 0x00BAF (Big Basic) - 0x0088E - True -158502 - 0x00BF3 (Square) - 0x00BAF - Squares & Black/White Squares +158502 - 0x00BF3 (Square) - 0x00BAF - Black/White Squares 158503 - 0x00C09 (Maze Map) - 0x00BF3 - Dots 158504 - 0x00CDB (Stars and Dots) - 0x00C09 - Stars & Dots 158505 - 0x0051F (Symmetry) - 0x00CDB - Symmetry & Colored Dots & Dots 158506 - 0x00524 (Stars and Shapers) - 0x0051F - Stars & Shapers 158507 - 0x00CD4 (Big Basic 2) - 0x00524 - True -158508 - 0x00CB9 (Choice Squares Right) - 0x00CD4 - Squares & Black/White Squares -158509 - 0x00CA1 (Choice Squares Middle) - 0x00CD4 - Squares & Black/White Squares -158510 - 0x00C80 (Choice Squares Left) - 0x00CD4 - Squares & Black/White Squares -158511 - 0x00C68 (Choice Squares 2 Right) - 0x00CB9 | 0x00CA1 | 0x00C80 - Squares & Black/White Squares & Colored Squares -158512 - 0x00C59 (Choice Squares 2 Middle) - 0x00CB9 | 0x00CA1 | 0x00C80 - Squares & Black/White Squares & Colored Squares -158513 - 0x00C22 (Choice Squares 2 Left) - 0x00CB9 | 0x00CA1 | 0x00C80 - Squares & Black/White Squares & Colored Squares +158508 - 0x00CB9 (Choice Squares Right) - 0x00CD4 - Black/White Squares +158509 - 0x00CA1 (Choice Squares Middle) - 0x00CD4 - Black/White Squares +158510 - 0x00C80 (Choice Squares Left) - 0x00CD4 - Black/White Squares +158511 - 0x00C68 (Choice Squares 2 Right) - 0x00CB9 | 0x00CA1 | 0x00C80 - Black/White Squares & Colored Squares +158512 - 0x00C59 (Choice Squares 2 Middle) - 0x00CB9 | 0x00CA1 | 0x00C80 - Black/White Squares & Colored Squares +158513 - 0x00C22 (Choice Squares 2 Left) - 0x00CB9 | 0x00CA1 | 0x00C80 - Black/White Squares & Colored Squares 158514 - 0x034F4 (Maze Hidden 1) - 0x00C68 | 0x00C59 | 0x00C22 - Triangles 158515 - 0x034EC (Maze Hidden 2) - 0x00C68 | 0x00C59 | 0x00C22 - Triangles 158516 - 0x1C31A (Dots Pillar) - 0x034F4 & 0x034EC - Dots & Symmetry -158517 - 0x1C319 (Squares Pillar) - 0x034F4 & 0x034EC - Squares & Black/White Squares & Symmetry -158667 - 0x0356B (Vault Box) - 0x1C31A & 0x1C319 - True +158517 - 0x1C319 (Squares Pillar) - 0x034F4 & 0x034EC - Black/White Squares & Symmetry +Door - 0x04D75 (Vault Door) - 0x1C31A & 0x1C319 158518 - 0x039B4 (Tunnels Entry Panel) - True - Arrows Door - 0x0348A (Tunnels Entry) - 0x039B4 159530 - 0x28B30 (Water EP) - True - True +Challenge Vault (Challenge): +158667 - 0x0356B (Vault Box) - 0x1C31A & 0x1C319 - True + Tunnels (Tunnels) - Windmill Interior - 0x27739 - Desert Lowest Level Inbetween Shortcuts - 0x27263 - Town - 0x09E87: 158668 - 0x2FAF6 (Vault Box) - True - True 158519 - 0x27732 (Theater Shortcut Panel) - True - True @@ -1075,7 +1103,7 @@ Elevator (Mountain Final Room): 158535 - 0x3D9A8 (Back Wall Right) - 0x3D9A6 | 0x3D9A7 - True 158536 - 0x3D9A9 (Elevator Start) - 0x3D9AA & 7 Lasers | 0x3D9A8 & 7 Lasers - True -Boat (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Treehouse Entry Area - TrueOneWay - Quarry Boathouse Behind Staircase - TrueOneWay - Inside Glass Factory Behind Back Wall - TrueOneWay: +The Ocean (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Treehouse Entry Area - TrueOneWay - Quarry Boathouse Behind Staircase - TrueOneWay - Inside Glass Factory Behind Back Wall - TrueOneWay: 159042 - 0x22106 (Desert EP) - True - True 159223 - 0x03B25 (Shipwreck CCW Underside EP) - True - True 159231 - 0x28B29 (Shipwreck Green EP) - True - True @@ -1093,32 +1121,38 @@ Obelisks (EPs) - Entry - True: 159702 - 0xFFE02 (Desert Obelisk Side 3) - 0x3351D - True 159703 - 0xFFE03 (Desert Obelisk Side 4) - 0x0053C & 0x00771 & 0x335C8 & 0x335C9 & 0x337F8 & 0x037BB & 0x220E4 & 0x220E5 - True 159704 - 0xFFE04 (Desert Obelisk Side 5) - 0x334B9 & 0x334BC & 0x22106 & 0x0A14C & 0x0A14D - True +159709 - 0x00359 (Desert Obelisk) - True - True 159710 - 0xFFE10 (Monastery Obelisk Side 1) - 0x03ABC & 0x03ABE & 0x03AC0 & 0x03AC4 - True 159711 - 0xFFE11 (Monastery Obelisk Side 2) - 0x03AC5 - True 159712 - 0xFFE12 (Monastery Obelisk Side 3) - 0x03BE2 & 0x03BE3 & 0x0A409 - True 159713 - 0xFFE13 (Monastery Obelisk Side 4) - 0x006E5 & 0x006E6 & 0x006E7 & 0x034A7 & 0x034AD & 0x034AF & 0x03DAB & 0x03DAC & 0x03DAD - True 159714 - 0xFFE14 (Monastery Obelisk Side 5) - 0x03E01 - True 159715 - 0xFFE15 (Monastery Obelisk Side 6) - 0x289F4 & 0x289F5 - True +159719 - 0x00263 (Monastery Obelisk) - True - True 159720 - 0xFFE20 (Treehouse Obelisk Side 1) - 0x0053D & 0x0053E & 0x00769 - True 159721 - 0xFFE21 (Treehouse Obelisk Side 2) - 0x33721 & 0x220A7 & 0x220BD - True 159722 - 0xFFE22 (Treehouse Obelisk Side 3) - 0x03B22 & 0x03B23 & 0x03B24 & 0x03B25 & 0x03A79 & 0x28ABD & 0x28ABE - True 159723 - 0xFFE23 (Treehouse Obelisk Side 4) - 0x3388F & 0x28B29 & 0x28B2A - True 159724 - 0xFFE24 (Treehouse Obelisk Side 5) - 0x018B6 & 0x033BE & 0x033BF & 0x033DD & 0x033E5 - True 159725 - 0xFFE25 (Treehouse Obelisk Side 6) - 0x28AE9 & 0x3348F - True +159729 - 0x00097 (Treehouse Obelisk) - True - True 159730 - 0xFFE30 (River Obelisk Side 1) - 0x001A3 & 0x335AE - True 159731 - 0xFFE31 (River Obelisk Side 2) - 0x000D3 & 0x035F5 & 0x09D5D & 0x09D5E & 0x09D63 - True 159732 - 0xFFE32 (River Obelisk Side 3) - 0x3370E & 0x035DE & 0x03601 & 0x03603 & 0x03D0D & 0x3369A & 0x336C8 & 0x33505 - True 159733 - 0xFFE33 (River Obelisk Side 4) - 0x03A9E & 0x016B2 & 0x3365F & 0x03731 & 0x036CE & 0x03C07 & 0x03A93 - True 159734 - 0xFFE34 (River Obelisk Side 5) - 0x03AA6 & 0x3397C & 0x0105D & 0x0A304 - True 159735 - 0xFFE35 (River Obelisk Side 6) - 0x035CB & 0x035CF - True +159739 - 0x00367 (River Obelisk) - True - True 159740 - 0xFFE40 (Quarry Obelisk Side 1) - 0x28A7B & 0x005F6 & 0x00859 & 0x17CB9 & 0x28A4A - True 159741 - 0xFFE41 (Quarry Obelisk Side 2) - 0x334B6 & 0x00614 & 0x0069D & 0x28A4C - True 159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 - True 159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x33692 - True 159744 - 0xFFE44 (Quarry Obelisk Side 5) - 0x03E77 & 0x03E7C - True +159749 - 0x22073 (Quarry Obelisk) - True - True 159750 - 0xFFE50 (Town Obelisk Side 1) - 0x035C7 - True 159751 - 0xFFE51 (Town Obelisk Side 2) - 0x01848 & 0x03D06 & 0x33530 & 0x33600 & 0x28A2F & 0x28A37 & 0x334A3 & 0x3352F - True 159752 - 0xFFE52 (Town Obelisk Side 3) - 0x33857 & 0x33879 & 0x03C19 - True 159753 - 0xFFE53 (Town Obelisk Side 4) - 0x28B30 & 0x035C9 - True 159754 - 0xFFE54 (Town Obelisk Side 5) - 0x03335 & 0x03412 & 0x038A6 & 0x038AA & 0x03E3F & 0x03E40 & 0x28B8E - True 159755 - 0xFFE55 (Town Obelisk Side 6) - 0x28B91 & 0x03BCE & 0x03BCF & 0x03BD1 & 0x339B6 & 0x33A20 & 0x33A29 & 0x33A2A & 0x33B06 - True +159759 - 0x0A16C (Town Obelisk) - True - True diff --git a/worlds/witness/WitnessLogicVanilla.txt b/worlds/witness/WitnessLogicVanilla.txt index 84e73e68a53c..719eae6c4e56 100644 --- a/worlds/witness/WitnessLogicVanilla.txt +++ b/worlds/witness/WitnessLogicVanilla.txt @@ -1,3 +1,5 @@ +Menu (Menu) - Entry - True: + Entry (Entry): First Hallway (First Hallway) - Entry - True - First Hallway Room - 0x00064: @@ -21,9 +23,9 @@ Tutorial (Tutorial) - Outside Tutorial - 0x03629: 159513 - 0x33600 (Patio Flowers EP) - 0x0C373 - True 159517 - 0x3352F (Gate EP) - 0x03505 - True -Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2: -158650 - 0x033D4 (Vault) - True - Dots & Black/White Squares -158651 - 0x03481 (Vault Box) - 0x033D4 - True +Outside Tutorial (Outside Tutorial) - Outside Tutorial Path To Outpost - 0x03BA2 - Outside Tutorial Vault - 0x033D0: +158650 - 0x033D4 (Vault Panel) - True - Dots & Black/White Squares +Door - 0x033D0 (Vault Door) - 0x033D4 158013 - 0x0005D (Shed Row 1) - True - Dots 158014 - 0x0005E (Shed Row 2) - 0x0005D - Dots 158015 - 0x0005F (Shed Row 3) - 0x0005E - Dots @@ -44,6 +46,9 @@ Door - 0x03BA2 (Outpost Path) - 0x0A3B5 159516 - 0x334A3 (Path EP) - True - True 159500 - 0x035C7 (Tractor EP) - True - True +Outside Tutorial Vault (Outside Tutorial): +158651 - 0x03481 (Vault Box) - True - True + Outside Tutorial Path To Outpost (Outside Tutorial) - Outside Tutorial Outpost - 0x0A170: 158011 - 0x0A171 (Outpost Entry Panel) - True - Dots & Full Dots Door - 0x0A170 (Outpost Entry) - 0x0A171 @@ -54,6 +59,7 @@ Door - 0x04CA3 (Outpost Exit) - 0x04CA4 158600 - 0x17CFB (Discard) - True - Triangles Main Island (Main Island) - Outside Tutorial - True: +159801 - 0xFFD00 (Reached Independently) - True - True 159550 - 0x28B91 (Thundercloud EP) - 0x09F98 & 0x012FB - True Outside Glass Factory (Glass Factory) - Main Island - True - Inside Glass Factory - 0x01A29: @@ -76,7 +82,7 @@ Inside Glass Factory (Glass Factory) - Inside Glass Factory Behind Back Wall - 0 158038 - 0x0343A (Melting 3) - 0x00082 - Symmetry Door - 0x0D7ED (Back Wall) - 0x0005C -Inside Glass Factory Behind Back Wall (Glass Factory) - Boat - 0x17CC8: +Inside Glass Factory Behind Back Wall (Glass Factory) - The Ocean - 0x17CC8: 158039 - 0x17CC8 (Boat Spawn) - 0x17CA6 | 0x17CDF | 0x09DB8 | 0x17C95 - Boat Outside Symmetry Island (Symmetry Island) - Main Island - True - Symmetry Island Lower - 0x17F3E: @@ -112,12 +118,12 @@ Door - 0x18269 (Upper) - 0x1C349 159000 - 0x0332B (Glass Factory Black Line Reflection EP) - True - True Symmetry Island Upper (Symmetry Island): -158065 - 0x00A52 (Yellow 1) - True - Symmetry & Colored Dots -158066 - 0x00A57 (Yellow 2) - 0x00A52 - Symmetry & Colored Dots -158067 - 0x00A5B (Yellow 3) - 0x00A57 - Symmetry & Colored Dots -158068 - 0x00A61 (Blue 1) - 0x00A52 - Symmetry & Colored Dots -158069 - 0x00A64 (Blue 2) - 0x00A61 & 0x00A52 - Symmetry & Colored Dots -158070 - 0x00A68 (Blue 3) - 0x00A64 & 0x00A57 - Symmetry & Colored Dots +158065 - 0x00A52 (Laser Yellow 1) - True - Symmetry & Colored Dots +158066 - 0x00A57 (Laser Yellow 2) - 0x00A52 - Symmetry & Colored Dots +158067 - 0x00A5B (Laser Yellow 3) - 0x00A57 - Symmetry & Colored Dots +158068 - 0x00A61 (Laser Blue 1) - 0x00A52 - Symmetry & Colored Dots +158069 - 0x00A64 (Laser Blue 2) - 0x00A61 & 0x00A57 - Symmetry & Colored Dots +158070 - 0x00A68 (Laser Blue 3) - 0x00A64 & 0x00A5B - Symmetry & Colored Dots 158700 - 0x0360D (Laser Panel) - 0x00A68 - True Laser - 0x00509 (Laser) - 0x0360D 159001 - 0x03367 (Glass Factory Black Line EP) - True - True @@ -135,9 +141,9 @@ Door - 0x03313 (Second Gate) - 0x032FF Orchard End (Orchard): -Desert Outside (Desert) - Main Island - True - Desert Floodlight Room - 0x09FEE: -158652 - 0x0CC7B (Vault) - True - Dots & Shapers & Rotated Shapers & Negative Shapers & Full Dots -158653 - 0x0339E (Vault Box) - 0x0CC7B - True +Desert Outside (Desert) - Main Island - True - Desert Floodlight Room - 0x09FEE - Desert Vault - 0x03444: +158652 - 0x0CC7B (Vault Panel) - True - Dots & Shapers & Rotated Shapers & Negative Shapers & Full Dots +Door - 0x03444 (Vault Door) - 0x0CC7B 158602 - 0x17CE7 (Discard) - True - Triangles 158076 - 0x00698 (Surface 1) - True - True 158077 - 0x0048F (Surface 2) - 0x00698 - True @@ -163,6 +169,9 @@ Laser - 0x012FB (Laser) - 0x03608 159040 - 0x334B9 (Shore EP) - True - True 159041 - 0x334BC (Island EP) - True - True +Desert Vault (Desert): +158653 - 0x0339E (Vault Box) - True - True + Desert Floodlight Room (Desert) - Desert Pond Room - 0x0C2C3: 158087 - 0x09FAA (Light Control) - True - True 158088 - 0x00422 (Light Room 1) - 0x09FAA - True @@ -199,18 +208,19 @@ Desert Water Levels Room (Desert) - Desert Elevator Room - 0x0C316: Door - 0x0C316 (Elevator Room Entry) - 0x18076 159034 - 0x337F8 (Flood Room EP) - 0x1C2DF - True -Desert Elevator Room (Desert) - Desert Lowest Level Inbetween Shortcuts - 0x012FB: +Desert Elevator Room (Desert) - Desert Lowest Level Inbetween Shortcuts - 0x01317: 158111 - 0x17C31 (Final Transparent) - True - True 158113 - 0x012D7 (Final Hexagonal) - 0x17C31 & 0x0A015 - True 158114 - 0x0A015 (Final Hexagonal Control) - 0x17C31 - True 158115 - 0x0A15C (Final Bent 1) - True - True 158116 - 0x09FFF (Final Bent 2) - 0x0A15C - True 158117 - 0x0A15F (Final Bent 3) - 0x09FFF - True -159035 - 0x037BB (Elevator EP) - 0x012FB - True +159035 - 0x037BB (Elevator EP) - 0x01317 - True +Door - 0x01317 (Elevator) - 0x03608 Desert Lowest Level Inbetween Shortcuts (Desert): -Outside Quarry (Quarry) - Main Island - True - Quarry Between Entrys - 0x09D6F - Quarry Elevator - TrueOneWay: +Outside Quarry (Quarry) - Main Island - True - Quarry Between Entrys - 0x09D6F - Quarry Elevator - 0xFFD00 & 0xFFD01: 158118 - 0x09E57 (Entry 1 Panel) - True - Black/White Squares 158603 - 0x17CF0 (Discard) - True - Triangles 158702 - 0x03612 (Laser Panel) - 0x0A3D0 & 0x0367C - Eraser & Shapers @@ -222,7 +232,7 @@ Door - 0x09D6F (Entry 1) - 0x09E57 159420 - 0x289CF (Rock Line EP) - True - True 159421 - 0x289D1 (Rock Line Reflection EP) - True - True -Quarry Elevator (Quarry): +Quarry Elevator (Quarry) - Outside Quarry - 0x17CC4 - Quarry - 0x17CC4: 158120 - 0x17CC4 (Elevator Control) - 0x0367C - Dots & Eraser 159403 - 0x17CB9 (Railroad EP) - 0x17CC4 - True @@ -230,28 +240,31 @@ Quarry Between Entrys (Quarry) - Quarry - 0x17C07: 158119 - 0x17C09 (Entry 2 Panel) - True - Shapers Door - 0x17C07 (Entry 2) - 0x17C09 -Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010 - Quarry Elevator - 0x17CC4: +Quarry (Quarry) - Quarry Stoneworks Ground Floor - 0x02010: +159802 - 0xFFD01 (Inside Reached Independently) - True - True 158121 - 0x01E5A (Stoneworks Entry Left Panel) - True - Black/White Squares 158122 - 0x01E59 (Stoneworks Entry Right Panel) - True - Dots Door - 0x02010 (Stoneworks Entry) - 0x01E59 & 0x01E5A -Quarry Stoneworks Ground Floor (Quarry Stoneworks) - Quarry - 0x275FF - Quarry Stoneworks Middle Floor - 0x03678 - Outside Quarry - 0x17CE8: +Quarry Stoneworks Ground Floor (Quarry Stoneworks) - Quarry - 0x275FF - Quarry Stoneworks Middle Floor - 0x03678 - Outside Quarry - 0x17CE8 - Quarry Stoneworks Lift - TrueOneWay: 158123 - 0x275ED (Side Exit Panel) - True - True Door - 0x275FF (Side Exit) - 0x275ED 158124 - 0x03678 (Lower Ramp Control) - True - Dots & Eraser 158145 - 0x17CAC (Roof Exit Panel) - True - True Door - 0x17CE8 (Roof Exit) - 0x17CAC -Quarry Stoneworks Middle Floor (Quarry Stoneworks) - Quarry Stoneworks Ground Floor - 0x03675 - Quarry Stoneworks Upper Floor - 0x03679: +Quarry Stoneworks Middle Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - TrueOneWay: 158125 - 0x00E0C (Lower Row 1) - True - Dots & Eraser 158126 - 0x01489 (Lower Row 2) - 0x00E0C - Dots & Eraser 158127 - 0x0148A (Lower Row 3) - 0x01489 - Dots & Eraser 158128 - 0x014D9 (Lower Row 4) - 0x0148A - Dots & Eraser 158129 - 0x014E7 (Lower Row 5) - 0x014D9 - Dots 158130 - 0x014E8 (Lower Row 6) - 0x014E7 - Dots & Eraser + +Quarry Stoneworks Lift (Quarry Stoneworks) - Quarry Stoneworks Middle Floor - 0x03679 - Quarry Stoneworks Ground Floor - 0x03679 - Quarry Stoneworks Upper Floor - 0x03679: 158131 - 0x03679 (Lower Lift Control) - 0x014E8 - Dots & Eraser -Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Middle Floor - 0x03676 & 0x03679 - Quarry Stoneworks Ground Floor - 0x0368A: +Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Lift - 0x03675 - Quarry Stoneworks Ground Floor - 0x0368A: 158132 - 0x03676 (Upper Ramp Control) - True - Dots & Eraser 158133 - 0x03675 (Upper Lift Control) - True - Dots & Eraser 158134 - 0x00557 (Upper Row 1) - True - Colored Squares & Eraser @@ -262,7 +275,7 @@ Quarry Stoneworks Upper Floor (Quarry Stoneworks) - Quarry Stoneworks Middle Flo 158139 - 0x3C12D (Upper Row 6) - 0x0146C - Colored Squares & Eraser 158140 - 0x03686 (Upper Row 7) - 0x3C12D - Colored Squares & Eraser 158141 - 0x014E9 (Upper Row 8) - 0x03686 - Colored Squares & Eraser -158142 - 0x03677 (Stair Control) - True - Colored Squares & Eraser +158142 - 0x03677 (Stairs Panel) - True - Colored Squares & Eraser Door - 0x0368A (Stairs) - 0x03677 158143 - 0x3C125 (Control Room Left) - 0x014E9 - Black/White Squares & Dots & Eraser 158144 - 0x0367C (Control Room Right) - 0x014E9 - Colored Squares & Dots & Eraser @@ -277,7 +290,7 @@ Quarry Boathouse (Quarry Boathouse) - Quarry - True - Quarry Boathouse Upper Fro Door - 0x2769B (Dock) - 0x17CA6 Door - 0x27163 (Dock Invis Barrier) - 0x17CA6 -Quarry Boathouse Behind Staircase (Quarry Boathouse) - Boat - 0x17CA6: +Quarry Boathouse Behind Staircase (Quarry Boathouse) - The Ocean - 0x17CA6: Quarry Boathouse Upper Front (Quarry Boathouse) - Quarry Boathouse Upper Middle - 0x17C50: 158149 - 0x021B3 (Front Row 1) - True - Shapers & Eraser @@ -309,9 +322,9 @@ Door - 0x3865F (Second Barrier) - 0x38663 158169 - 0x0A3D0 (Back Second Row 3) - 0x0A3CC - Stars & Eraser & Shapers 159401 - 0x005F6 (Hook EP) - 0x275FA & 0x03852 & 0x3865F - True -Shadows (Shadows) - Main Island - True - Shadows Ledge - 0x19B24 - Shadows Laser Room - 0x194B2 & 0x19665: +Shadows (Shadows) - Main Island - True - Shadows Ledge - 0x19B24 - Shadows Laser Room - 0x194B2 | 0x19665: 158170 - 0x334DB (Door Timer Outside) - True - True -Door - 0x19B24 (Timed Door) - 0x334DB +Door - 0x19B24 (Timed Door) - 0x334DB | 0x334DC 158171 - 0x0AC74 (Intro 6) - 0x0A8DC - True 158172 - 0x0AC7A (Intro 7) - 0x0AC74 - True 158173 - 0x0A8E0 (Intro 8) - 0x0AC7A - True @@ -336,7 +349,7 @@ Shadows Ledge (Shadows) - Shadows - 0x1855B - Quarry - 0x19865 & 0x0A2DF: 158187 - 0x334DC (Door Timer Inside) - True - True 158188 - 0x198B5 (Intro 1) - True - True 158189 - 0x198BD (Intro 2) - 0x198B5 - True -158190 - 0x198BF (Intro 3) - 0x198BD & 0x334DC & 0x19B24 - True +158190 - 0x198BF (Intro 3) - 0x198BD & 0x19B24 - True Door - 0x19865 (Quarry Barrier) - 0x198BF Door - 0x0A2DF (Quarry Barrier 2) - 0x198BF 158191 - 0x19771 (Intro 4) - 0x198BF - True @@ -345,7 +358,7 @@ Door - 0x1855B (Ledge Barrier) - 0x0A8DC Door - 0x19ADE (Ledge Barrier 2) - 0x0A8DC Shadows Laser Room (Shadows): -158703 - 0x19650 (Laser Panel) - True - True +158703 - 0x19650 (Laser Panel) - 0x194B2 & 0x19665 - True Laser - 0x181B3 (Laser) - 0x19650 Treehouse Beach (Treehouse Beach) - Main Island - True: @@ -395,9 +408,9 @@ Door - 0x01D40 (Pressure Plates 4 Exit) - 0x01D3F 158205 - 0x09E49 (Shadows Shortcut Panel) - True - True Door - 0x09E3D (Shadows Shortcut) - 0x09E49 -Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True: -158654 - 0x00AFB (Vault) - True - Symmetry & Sound Dots & Colored Dots -158655 - 0x03535 (Vault Box) - 0x00AFB - True +Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True - Shipwreck Vault - 0x17BB4: +158654 - 0x00AFB (Vault Panel) - True - Symmetry & Sound Dots & Colored Dots +Door - 0x17BB4 (Vault Door) - 0x00AFB 158605 - 0x17D28 (Discard) - True - Triangles 159220 - 0x03B22 (Circle Far EP) - True - True 159221 - 0x03B23 (Circle Left EP) - True - True @@ -407,6 +420,9 @@ Shipwreck (Shipwreck) - Keep 3rd Pressure Plate - True: 159226 - 0x28ABE (Rope Outer EP) - True - True 159230 - 0x3388F (Couch EP) - 0x17CDF | 0x0A054 - True +Shipwreck Vault (Shipwreck): +158655 - 0x03535 (Vault Box) - True - True + Keep Tower (Keep) - Keep - 0x04F8F: 158206 - 0x0361B (Tower Shortcut Panel) - True - True Door - 0x04F8F (Tower Shortcut) - 0x0361B @@ -422,8 +438,8 @@ Laser - 0x014BB (Laser) - 0x0360E | 0x03317 159251 - 0x3348F (Hedges EP) - True - True Outside Monastery (Monastery) - Main Island - True - Inside Monastery - 0x0C128 & 0x0C153 - Monastery Garden - 0x03750: -158207 - 0x03713 (Shortcut Panel) - True - True -Door - 0x0364E (Shortcut) - 0x03713 +158207 - 0x03713 (Laser Shortcut Panel) - True - True +Door - 0x0364E (Laser Shortcut) - 0x03713 158208 - 0x00B10 (Entry Left) - True - True 158209 - 0x00C92 (Entry Right) - True - True Door - 0x0C128 (Entry Inner) - 0x00B10 @@ -454,7 +470,7 @@ Inside Monastery (Monastery): Monastery Garden (Monastery): -Town (Town) - Main Island - True - Boat - 0x0A054 - Town Maze Rooftop - 0x28AA2 - Town Church - True - Town Wooden Rooftop - 0x034F5 - RGB House - 0x28A61 - Windmill Interior - 0x1845B - Town Inside Cargo Box - 0x0A0C9: +Town (Town) - Main Island - True - The Ocean - 0x0A054 - Town Maze Rooftop - 0x28AA2 - Town Church - True - Town Wooden Rooftop - 0x034F5 - RGB House - 0x28A61 - Windmill Interior - 0x1845B - Town Inside Cargo Box - 0x0A0C9: 158218 - 0x0A054 (Boat Spawn) - 0x17CA6 | 0x17CDF | 0x09DB8 | 0x17C95 - Boat 158219 - 0x0A0C8 (Cargo Box Entry Panel) - True - Black/White Squares & Shapers Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 @@ -469,11 +485,11 @@ Door - 0x0A0C9 (Cargo Box Entry) - 0x0A0C8 158238 - 0x28AC0 (Wooden Roof Lower Row 4) - 0x28ABF - Rotated Shapers & Dots & Full Dots 158239 - 0x28AC1 (Wooden Roof Lower Row 5) - 0x28AC0 - Rotated Shapers & Dots & Full Dots Door - 0x034F5 (Wooden Roof Stairs) - 0x28AC1 -158225 - 0x28998 (Tinted Glass Door Panel) - True - Stars & Rotated Shapers -Door - 0x28A61 (Tinted Glass Door) - 0x28998 +158225 - 0x28998 (RGB House Entry Panel) - True - Stars & Rotated Shapers +Door - 0x28A61 (RGB House Entry) - 0x28998 158226 - 0x28A0D (Church Entry Panel) - 0x28A61 - Stars Door - 0x03BB0 (Church Entry) - 0x28A0D -158228 - 0x28A79 (Maze Stair Control) - True - True +158228 - 0x28A79 (Maze Panel) - True - True Door - 0x28AA2 (Maze Stairs) - 0x28A79 158241 - 0x17F5F (Windmill Entry Panel) - True - Dots Door - 0x1845B (Windmill Entry) - 0x17F5F @@ -557,7 +573,7 @@ Door - 0x3CCDF (Exit Right) - 0x33AB2 159556 - 0x33A2A (Door EP) - 0x03553 - True 159558 - 0x33B06 (Church EP) - 0x0354E - True -Jungle (Jungle) - Main Island - True - Outside Jungle River - 0x3873B - Boat - 0x17CDF: +Jungle (Jungle) - Main Island - True - The Ocean - 0x17CDF: 158251 - 0x17CDF (Shore Boat Spawn) - True - Boat 158609 - 0x17F9B (Discard) - True - Triangles 158252 - 0x002C4 (First Row 1) - True - True @@ -588,18 +604,21 @@ Door - 0x3873B (Laser Shortcut) - 0x337FA 159350 - 0x035CB (Bamboo CCW EP) - True - True 159351 - 0x035CF (Bamboo CW EP) - True - True -Outside Jungle River (River) - Main Island - True - Monastery Garden - 0x0CF2A: -158267 - 0x17CAA (Monastery Shortcut Panel) - True - True -Door - 0x0CF2A (Monastery Shortcut) - 0x17CAA -158663 - 0x15ADD (Vault) - True - Black/White Squares & Dots -158664 - 0x03702 (Vault Box) - 0x15ADD - True +Outside Jungle River (River) - Main Island - True - Monastery Garden - 0x0CF2A - River Vault - 0x15287: +158267 - 0x17CAA (Monastery Garden Shortcut Panel) - True - True +Door - 0x0CF2A (Monastery Garden Shortcut) - 0x17CAA +158663 - 0x15ADD (Vault Panel) - True - Black/White Squares & Dots +Door - 0x15287 (Vault Door) - 0x15ADD 159110 - 0x03AC5 (Green Leaf Moss EP) - True - True 159120 - 0x03BE2 (Monastery Garden Left EP) - 0x03750 - True 159121 - 0x03BE3 (Monastery Garden Right EP) - True - True 159122 - 0x0A409 (Monastery Wall EP) - True - True +River Vault (River): +158664 - 0x03702 (Vault Box) - True - True + Outside Bunker (Bunker) - Main Island - True - Bunker - 0x0C2A4: -158268 - 0x17C2E (Entry Panel) - True - Black/White Squares & Colored Squares +158268 - 0x17C2E (Entry Panel) - True - Black/White Squares Door - 0x0C2A4 (Entry) - 0x17C2E Bunker (Bunker) - Bunker Glass Room - 0x17C79: @@ -616,9 +635,9 @@ Bunker (Bunker) - Bunker Glass Room - 0x17C79: Door - 0x17C79 (Tinted Glass Door) - 0x0A099 Bunker Glass Room (Bunker) - Bunker Ultraviolet Room - 0x0C2A3: -158279 - 0x0A010 (Glass Room 1) - True - Colored Squares -158280 - 0x0A01B (Glass Room 2) - 0x0A010 - Colored Squares & Black/White Squares -158281 - 0x0A01F (Glass Room 3) - 0x0A01B - Colored Squares & Black/White Squares +158279 - 0x0A010 (Glass Room 1) - 0x17C79 - Colored Squares +158280 - 0x0A01B (Glass Room 2) - 0x17C79 & 0x0A010 - Colored Squares & Black/White Squares +158281 - 0x0A01F (Glass Room 3) - 0x17C79 & 0x0A01B - Colored Squares & Black/White Squares Door - 0x0C2A3 (UV Room Entry) - 0x0A01F Bunker Ultraviolet Room (Bunker) - Bunker Elevator Section - 0x0A08D: @@ -631,7 +650,7 @@ Door - 0x0A08D (Elevator Room Entry) - 0x17E67 Bunker Elevator Section (Bunker) - Bunker Elevator - TrueOneWay: 159311 - 0x035F5 (Tinted Door EP) - 0x17C79 - True -Bunker Elevator (Bunker) - Bunker Laser Platform - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: +Bunker Elevator (Bunker) - Bunker Elevator Section - 0x0A079 - Bunker Green Room - 0x0A079 - Bunker Laser Platform - 0x0A079 - Outside Bunker - 0x0A079: 158286 - 0x0A079 (Elevator Control) - True - Colored Squares & Black/White Squares Bunker Green Room (Bunker) - Bunker Elevator - TrueOneWay: @@ -676,7 +695,7 @@ Swamp Near Platform (Swamp) - Swamp Cyan Underwater - 0x04B7F - Swamp Near Boat 158316 - 0x00990 (Platform Row 4) - 0x0098F - Shapers Door - 0x184B7 (Between Bridges First Door) - 0x00990 158317 - 0x17C0D (Platform Shortcut Left Panel) - True - Shapers -158318 - 0x17C0E (Platform Shortcut Right Panel) - True - Shapers +158318 - 0x17C0E (Platform Shortcut Right Panel) - 0x17C0D - Shapers Door - 0x38AE6 (Platform Shortcut Door) - 0x17C0E Door - 0x04B7F (Cyan Water Pump) - 0x00006 @@ -715,18 +734,21 @@ Swamp Rotating Bridge (Swamp) - Swamp Between Bridges Far - 0x181F5 - Swamp Near 159331 - 0x016B2 (Rotating Bridge CCW EP) - 0x181F5 - True 159334 - 0x036CE (Rotating Bridge CW EP) - 0x181F5 - True -Swamp Near Boat (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Blue Underwater - 0x18482: +Swamp Near Boat (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Blue Underwater - 0x18482 - Swamp Long Bridge - 0xFFD00 & 0xFFD02 - The Ocean - 0x09DB8: +158903 - 0xFFD02 (Beyond Rotating Bridge Reached Independently) - True - True 158328 - 0x09DB8 (Boat Spawn) - True - Boat 158329 - 0x003B2 (Beyond Rotating Bridge 1) - 0x0000A - Rotated Shapers 158330 - 0x00A1E (Beyond Rotating Bridge 2) - 0x003B2 - Rotated Shapers 158331 - 0x00C2E (Beyond Rotating Bridge 3) - 0x00A1E - Rotated Shapers & Shapers 158332 - 0x00E3A (Beyond Rotating Bridge 4) - 0x00C2E - Rotated Shapers -158339 - 0x17E2B (Long Bridge Control) - True - Rotated Shapers & Shapers Door - 0x18482 (Blue Water Pump) - 0x00E3A 159332 - 0x3365F (Boat EP) - 0x09DB8 - True 159333 - 0x03731 (Long Bridge Side EP) - 0x17E2B - True -Swamp Purple Area (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Purple Underwater - 0x0A1D6: +Swamp Long Bridge (Swamp) - Swamp Near Boat - 0x17E2B - Outside Swamp - 0x17E2B: +158339 - 0x17E2B (Long Bridge Control) - True - Rotated Shapers & Shapers + +Swamp Purple Area (Swamp) - Swamp Rotating Bridge - TrueOneWay - Swamp Purple Underwater - 0x0A1D6 - Swamp Near Boat - TrueOneWay: Door - 0x0A1D6 (Purple Water Pump) - 0x00E3A Swamp Purple Underwater (Swamp): @@ -752,7 +774,7 @@ Laser - 0x00BF6 (Laser) - 0x03615 158342 - 0x17C02 (Laser Shortcut Right Panel) - 0x17C05 - Shapers & Negative Shapers & Rotated Shapers Door - 0x2D880 (Laser Shortcut) - 0x17C02 -Treehouse Entry Area (Treehouse) - Treehouse Between Doors - 0x0C309: +Treehouse Entry Area (Treehouse) - Treehouse Between Doors - 0x0C309 - The Ocean - 0x17C95: 158343 - 0x17C95 (Boat Spawn) - True - Boat 158344 - 0x0288C (First Door Panel) - True - Stars Door - 0x0C309 (First Door) - 0x0288C @@ -778,7 +800,7 @@ Treehouse After Yellow Bridge (Treehouse) - Treehouse Junction - 0x0A181: Door - 0x0A181 (Third Door) - 0x0A182 Treehouse Junction (Treehouse) - Treehouse Right Orange Bridge - True - Treehouse First Purple Bridge - True - Treehouse Green Bridge - True: -158356 - 0x2700B (Laser House Door Timer Outside Control) - True - True +158356 - 0x2700B (Laser House Door Timer Outside) - True - True Treehouse First Purple Bridge (Treehouse) - Treehouse Second Purple Bridge - 0x17D6C: 158357 - 0x17DC8 (First Purple Bridge 1) - True - Stars & Dots @@ -802,7 +824,7 @@ Treehouse Right Orange Bridge (Treehouse) - Treehouse Bridge Platform - 0x17DA2: 158402 - 0x17DA2 (Right Orange Bridge 12) - 0x17DB1 - Stars Treehouse Bridge Platform (Treehouse) - Main Island - 0x0C32D: -158404 - 0x037FF (Bridge Control) - True - Stars +158404 - 0x037FF (Drawbridge Panel) - True - Stars Door - 0x0C32D (Drawbridge) - 0x037FF Treehouse Second Purple Bridge (Treehouse) - Treehouse Left Orange Bridge - 0x17DC6: @@ -847,7 +869,7 @@ Treehouse Green Bridge Left House (Treehouse): 159211 - 0x220A7 (Right Orange Bridge EP) - 0x17DA2 - True Treehouse Laser Room Front Platform (Treehouse) - Treehouse Laser Room - 0x0C323: -Door - 0x0C323 (Laser House Entry) - 0x17DA2 & 0x2700B & 0x17DDB +Door - 0x0C323 (Laser House Entry) - 0x17DA2 & 0x2700B & 0x17DDB | 0x17CBC Treehouse Laser Room Back Platform (Treehouse): 158611 - 0x17FA0 (Laser Discard) - True - Triangles @@ -860,19 +882,22 @@ Treehouse Laser Room (Treehouse): 158403 - 0x17CBC (Laser House Door Timer Inside) - True - True Laser - 0x028A4 (Laser) - 0x03613 -Mountainside (Mountainside) - Main Island - True - Mountaintop - True: +Mountainside (Mountainside) - Main Island - True - Mountaintop - True - Mountainside Vault - 0x00085: 158612 - 0x17C42 (Discard) - True - Triangles -158665 - 0x002A6 (Vault) - True - Symmetry & Colored Dots & Black/White Squares -158666 - 0x03542 (Vault Box) - 0x002A6 - True +158665 - 0x002A6 (Vault Panel) - True - Symmetry & Colored Dots & Black/White Squares +Door - 0x00085 (Vault Door) - 0x002A6 159301 - 0x335AE (Cloud Cycle EP) - True - True 159325 - 0x33505 (Bush EP) - True - True 159335 - 0x03C07 (Apparent River EP) - True - True +Mountainside Vault (Mountainside): +158666 - 0x03542 (Vault Box) - True - True + Mountaintop (Mountaintop) - Mountain Top Layer - 0x17C34: 158405 - 0x0042D (River Shape) - True - True 158406 - 0x09F7F (Box Short) - 7 Lasers - True -158407 - 0x17C34 (Trap Door Triple Exit) - 0x09F7F - Black/White Squares -158800 - 0xFFF00 (Box Long) - 7 Lasers & 11 Lasers & 0x17C34 - True +158407 - 0x17C34 (Mountain Entry Panel) - 0x09F7F - Black/White Squares +158800 - 0xFFF00 (Box Long) - 11 Lasers & 0x17C34 - True 159300 - 0x001A3 (River Shape EP) - True - True 159320 - 0x3370E (Arch Black EP) - True - True 159324 - 0x336C8 (Arch White Right EP) - True - True @@ -881,7 +906,7 @@ Mountaintop (Mountaintop) - Mountain Top Layer - 0x17C34: Mountain Top Layer (Mountain Floor 1) - Mountain Top Layer Bridge - 0x09E39: 158408 - 0x09E39 (Light Bridge Controller) - True - Black/White Squares & Rotated Shapers -Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: +Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Top Layer At Door - TrueOneWay: 158409 - 0x09E7A (Right Row 1) - True - Black/White Squares & Dots 158410 - 0x09E71 (Right Row 2) - 0x09E7A - Black/White Squares & Dots 158411 - 0x09E72 (Right Row 3) - 0x09E71 - Black/White Squares & Shapers @@ -899,6 +924,8 @@ Mountain Top Layer Bridge (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: 158423 - 0x09F6E (Back Row 3) - 0x33AF7 - Symmetry & Dots 158424 - 0x09EAD (Trash Pillar 1) - True - Black/White Squares & Shapers 158425 - 0x09EAF (Trash Pillar 2) - 0x09EAD - Black/White Squares & Shapers + +Mountain Top Layer At Door (Mountain Floor 1) - Mountain Floor 2 - 0x09E54: Door - 0x09E54 (Exit) - 0x09EAF & 0x09F6E & 0x09E6B & 0x09E7B Mountain Floor 2 (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Near - 0x09FFB - Mountain Floor 2 Blue Bridge - 0x09E86 - Mountain Pink Bridge EP - TrueOneWay: @@ -917,7 +944,7 @@ Door - 0x09EDD (Elevator Room Entry) - 0x09ED8 & 0x09E86 Mountain Floor 2 Light Bridge Room Near (Mountain Floor 2): 158431 - 0x09E86 (Light Bridge Controller Near) - True - Stars & Black/White Squares -Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay: +Mountain Floor 2 Beyond Bridge (Mountain Floor 2) - Mountain Floor 2 Light Bridge Room Far - 0x09E07 - Mountain Pink Bridge EP - TrueOneWay - Mountain Floor 2 - 0x09ED8: 158432 - 0x09FCC (Far Row 1) - True - Dots 158433 - 0x09FCE (Far Row 2) - 0x09FCC - Black/White Squares 158434 - 0x09FCF (Far Row 3) - 0x09FCE - Shapers @@ -935,29 +962,27 @@ Mountain Floor 2 Elevator Room (Mountain Floor 2) - Mountain Floor 2 Elevator - Mountain Floor 2 Elevator (Mountain Floor 2) - Mountain Floor 2 Elevator Room - 0x09EEB - Mountain Third Layer - 0x09EEB: 158439 - 0x09EEB (Elevator Control Panel) - True - Dots -Mountain Third Layer (Mountain Bottom Floor) - Mountain Floor 2 Elevator - TrueOneWay - Mountain Bottom Floor - 0x09F89: +Mountain Third Layer (Mountain Bottom Floor) - Mountain Floor 2 Elevator - TrueOneWay - Mountain Bottom Floor - 0x09F89 - Mountain Pink Bridge EP - TrueOneWay: 158440 - 0x09FC1 (Giant Puzzle Bottom Left) - True - Shapers & Eraser 158441 - 0x09F8E (Giant Puzzle Bottom Right) - True - Rotated Shapers & Eraser 158442 - 0x09F01 (Giant Puzzle Top Right) - True - Shapers & Eraser 158443 - 0x09EFF (Giant Puzzle Top Left) - True - Shapers & Eraser 158444 - 0x09FDA (Giant Puzzle) - 0x09FC1 & 0x09F8E & 0x09F01 & 0x09EFF - Shapers & Symmetry +159313 - 0x09D5D (Yellow Bridge EP) - 0x09E86 & 0x09ED8 - True +159314 - 0x09D5E (Blue Bridge EP) - 0x09E86 & 0x09ED8 - True Door - 0x09F89 (Exit) - 0x09FDA -Mountain Bottom Floor (Mountain Bottom Floor) - Mountain Bottom Floor Rock - 0x17FA2 - Final Room - 0x0C141 - Mountain Pink Bridge EP - TrueOneWay: +Mountain Bottom Floor (Mountain Bottom Floor) - Mountain Path to Caves - 0x17F33 - Final Room - 0x0C141: 158614 - 0x17FA2 (Discard) - 0xFFF00 - Triangles 158445 - 0x01983 (Final Room Entry Left) - True - Shapers & Stars 158446 - 0x01987 (Final Room Entry Right) - True - Colored Squares & Dots Door - 0x0C141 (Final Room Entry) - 0x01983 & 0x01987 -159313 - 0x09D5D (Yellow Bridge EP) - 0x09E86 & 0x09ED8 - True -159314 - 0x09D5E (Blue Bridge EP) - 0x09E86 & 0x09ED8 - True +Door - 0x17F33 (Rock Open) - 0x17FA2 | 0x334E1 Mountain Pink Bridge EP (Mountain Floor 2): 159312 - 0x09D63 (Pink Bridge EP) - 0x09E39 - True -Mountain Bottom Floor Rock (Mountain Bottom Floor) - Mountain Bottom Floor - 0x17F33 - Mountain Path to Caves - 0x17F33: -Door - 0x17F33 (Rock Open) - True - True - -Mountain Path to Caves (Mountain Bottom Floor) - Mountain Bottom Floor Rock - 0x334E1 - Caves - 0x2D77D: +Mountain Path to Caves (Mountain Bottom Floor) - Caves - 0x2D77D: 158447 - 0x00FF8 (Caves Entry Panel) - True - Black/White Squares Door - 0x2D77D (Caves Entry) - 0x00FF8 158448 - 0x334E1 (Rock Control) - True - True @@ -1021,7 +1046,7 @@ Path to Challenge (Caves) - Challenge - 0x0A19A: 158477 - 0x0A16E (Challenge Entry Panel) - True - Stars & Shapers & Stars + Same Colored Symbol Door - 0x0A19A (Challenge Entry) - 0x0A16E -Challenge (Challenge) - Tunnels - 0x0348A: +Challenge (Challenge) - Tunnels - 0x0348A - Challenge Vault - 0x04D75: 158499 - 0x0A332 (Start Timer) - 11 Lasers - True 158500 - 0x0088E (Small Basic) - 0x0A332 - True 158501 - 0x00BAF (Big Basic) - 0x0088E - True @@ -1041,11 +1066,14 @@ Challenge (Challenge) - Tunnels - 0x0348A: 158515 - 0x034EC (Maze Hidden 2) - 0x00C68 | 0x00C59 | 0x00C22 - Triangles 158516 - 0x1C31A (Dots Pillar) - 0x034F4 & 0x034EC - Dots & Symmetry 158517 - 0x1C319 (Squares Pillar) - 0x034F4 & 0x034EC - Black/White Squares & Symmetry -158667 - 0x0356B (Vault Box) - 0x1C31A & 0x1C319 - True +Door - 0x04D75 (Vault Door) - 0x1C31A & 0x1C319 158518 - 0x039B4 (Tunnels Entry Panel) - True - Triangles Door - 0x0348A (Tunnels Entry) - 0x039B4 159530 - 0x28B30 (Water EP) - True - True +Challenge Vault (Challenge): +158667 - 0x0356B (Vault Box) - 0x1C31A & 0x1C319 - True + Tunnels (Tunnels) - Windmill Interior - 0x27739 - Desert Lowest Level Inbetween Shortcuts - 0x27263 - Town - 0x09E87: 158668 - 0x2FAF6 (Vault Box) - True - True 158519 - 0x27732 (Theater Shortcut Panel) - True - True @@ -1075,7 +1103,7 @@ Elevator (Mountain Final Room): 158535 - 0x3D9A8 (Back Wall Right) - 0x3D9A6 | 0x3D9A7 - True 158536 - 0x3D9A9 (Elevator Start) - 0x3D9AA & 7 Lasers | 0x3D9A8 & 7 Lasers - True -Boat (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Treehouse Entry Area - TrueOneWay - Quarry Boathouse Behind Staircase - TrueOneWay - Inside Glass Factory Behind Back Wall - TrueOneWay: +The Ocean (Boat) - Main Island - TrueOneWay - Swamp Near Boat - TrueOneWay - Treehouse Entry Area - TrueOneWay - Quarry Boathouse Behind Staircase - TrueOneWay - Inside Glass Factory Behind Back Wall - TrueOneWay: 159042 - 0x22106 (Desert EP) - True - True 159223 - 0x03B25 (Shipwreck CCW Underside EP) - True - True 159231 - 0x28B29 (Shipwreck Green EP) - True - True @@ -1093,32 +1121,38 @@ Obelisks (EPs) - Entry - True: 159702 - 0xFFE02 (Desert Obelisk Side 3) - 0x3351D - True 159703 - 0xFFE03 (Desert Obelisk Side 4) - 0x0053C & 0x00771 & 0x335C8 & 0x335C9 & 0x337F8 & 0x037BB & 0x220E4 & 0x220E5 - True 159704 - 0xFFE04 (Desert Obelisk Side 5) - 0x334B9 & 0x334BC & 0x22106 & 0x0A14C & 0x0A14D - True +159709 - 0x00359 (Desert Obelisk) - True - True 159710 - 0xFFE10 (Monastery Obelisk Side 1) - 0x03ABC & 0x03ABE & 0x03AC0 & 0x03AC4 - True 159711 - 0xFFE11 (Monastery Obelisk Side 2) - 0x03AC5 - True 159712 - 0xFFE12 (Monastery Obelisk Side 3) - 0x03BE2 & 0x03BE3 & 0x0A409 - True 159713 - 0xFFE13 (Monastery Obelisk Side 4) - 0x006E5 & 0x006E6 & 0x006E7 & 0x034A7 & 0x034AD & 0x034AF & 0x03DAB & 0x03DAC & 0x03DAD - True 159714 - 0xFFE14 (Monastery Obelisk Side 5) - 0x03E01 - True 159715 - 0xFFE15 (Monastery Obelisk Side 6) - 0x289F4 & 0x289F5 - True +159719 - 0x00263 (Monastery Obelisk) - True - True 159720 - 0xFFE20 (Treehouse Obelisk Side 1) - 0x0053D & 0x0053E & 0x00769 - True 159721 - 0xFFE21 (Treehouse Obelisk Side 2) - 0x33721 & 0x220A7 & 0x220BD - True 159722 - 0xFFE22 (Treehouse Obelisk Side 3) - 0x03B22 & 0x03B23 & 0x03B24 & 0x03B25 & 0x03A79 & 0x28ABD & 0x28ABE - True 159723 - 0xFFE23 (Treehouse Obelisk Side 4) - 0x3388F & 0x28B29 & 0x28B2A - True 159724 - 0xFFE24 (Treehouse Obelisk Side 5) - 0x018B6 & 0x033BE & 0x033BF & 0x033DD & 0x033E5 - True 159725 - 0xFFE25 (Treehouse Obelisk Side 6) - 0x28AE9 & 0x3348F - True +159729 - 0x00097 (Treehouse Obelisk) - True - True 159730 - 0xFFE30 (River Obelisk Side 1) - 0x001A3 & 0x335AE - True 159731 - 0xFFE31 (River Obelisk Side 2) - 0x000D3 & 0x035F5 & 0x09D5D & 0x09D5E & 0x09D63 - True 159732 - 0xFFE32 (River Obelisk Side 3) - 0x3370E & 0x035DE & 0x03601 & 0x03603 & 0x03D0D & 0x3369A & 0x336C8 & 0x33505 - True 159733 - 0xFFE33 (River Obelisk Side 4) - 0x03A9E & 0x016B2 & 0x3365F & 0x03731 & 0x036CE & 0x03C07 & 0x03A93 - True 159734 - 0xFFE34 (River Obelisk Side 5) - 0x03AA6 & 0x3397C & 0x0105D & 0x0A304 - True 159735 - 0xFFE35 (River Obelisk Side 6) - 0x035CB & 0x035CF - True +159739 - 0x00367 (River Obelisk) - True - True 159740 - 0xFFE40 (Quarry Obelisk Side 1) - 0x28A7B & 0x005F6 & 0x00859 & 0x17CB9 & 0x28A4A - True 159741 - 0xFFE41 (Quarry Obelisk Side 2) - 0x334B6 & 0x00614 & 0x0069D & 0x28A4C - True 159742 - 0xFFE42 (Quarry Obelisk Side 3) - 0x289CF & 0x289D1 - True 159743 - 0xFFE43 (Quarry Obelisk Side 4) - 0x33692 - True 159744 - 0xFFE44 (Quarry Obelisk Side 5) - 0x03E77 & 0x03E7C - True +159749 - 0x22073 (Quarry Obelisk) - True - True 159750 - 0xFFE50 (Town Obelisk Side 1) - 0x035C7 - True 159751 - 0xFFE51 (Town Obelisk Side 2) - 0x01848 & 0x03D06 & 0x33530 & 0x33600 & 0x28A2F & 0x28A37 & 0x334A3 & 0x3352F - True 159752 - 0xFFE52 (Town Obelisk Side 3) - 0x33857 & 0x33879 & 0x03C19 - True 159753 - 0xFFE53 (Town Obelisk Side 4) - 0x28B30 & 0x035C9 - True 159754 - 0xFFE54 (Town Obelisk Side 5) - 0x03335 & 0x03412 & 0x038A6 & 0x038AA & 0x03E3F & 0x03E40 & 0x28B8E - True 159755 - 0xFFE55 (Town Obelisk Side 6) - 0x28B91 & 0x03BCE & 0x03BCF & 0x03BD1 & 0x339B6 & 0x33A20 & 0x33A29 & 0x33A2A & 0x33B06 - True +159759 - 0x0A16C (Town Obelisk) - True - True diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index 28eaba6404b6..c2d2311c1537 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -1,9 +1,11 @@ """ Archipelago init file for The Witness """ +import dataclasses from typing import Dict, Optional -from BaseClasses import Region, Location, MultiWorld, Item, Entrance, Tutorial +from BaseClasses import Region, Location, MultiWorld, Item, Entrance, Tutorial, CollectionState +from Options import PerGameCommonOptions, Toggle from .hints import get_always_hint_locations, get_always_hint_items, get_priority_hint_locations, \ get_priority_hint_items, make_hints, generate_joke_hints from worlds.AutoWorld import World, WebWorld @@ -11,9 +13,9 @@ from .static_logic import StaticWitnessLogic from .locations import WitnessPlayerLocations, StaticWitnessLocations from .items import WitnessItem, StaticWitnessItems, WitnessPlayerItems, ItemData -from .rules import set_rules from .regions import WitnessRegions -from .Options import is_option_enabled, the_witness_options, get_option_value +from .rules import set_rules +from .Options import TheWitnessOptions from .utils import get_audio_logs from logging import warning, error @@ -38,13 +40,15 @@ class WitnessWorld(World): """ game = "The Witness" topology_present = False - data_version = 13 + data_version = 14 StaticWitnessLogic() StaticWitnessLocations() StaticWitnessItems() web = WitnessWebWorld() - option_definitions = the_witness_options + + options_dataclass = TheWitnessOptions + options: TheWitnessOptions item_name_to_id = { name: data.ap_code for name, data in StaticWitnessItems.item_data.items() @@ -52,7 +56,7 @@ class WitnessWorld(World): location_name_to_id = StaticWitnessLocations.ALL_LOCATIONS_TO_ID item_name_groups = StaticWitnessItems.item_groups - required_client_version = (0, 3, 9) + required_client_version = (0, 4, 4) def __init__(self, multiworld: "MultiWorld", player: int): super().__init__(multiworld, player) @@ -64,6 +68,9 @@ def __init__(self, multiworld: "MultiWorld", player: int): self.log_ids_to_hints = None + self.items_placed_early = [] + self.own_itempool = [] + def _get_slot_data(self): return { 'seed': self.random.randrange(0, 1000000), @@ -72,12 +79,11 @@ def _get_slot_data(self): 'item_id_to_door_hexes': StaticWitnessItems.get_item_to_door_mappings(), 'door_hexes_in_the_pool': self.items.get_door_ids_in_pool(), 'symbols_not_in_the_game': self.items.get_symbol_ids_not_in_pool(), - 'disabled_panels': list(self.player_logic.COMPLETELY_DISABLED_CHECKS), + 'disabled_entities': [int(h, 16) for h in self.player_logic.COMPLETELY_DISABLED_ENTITIES], 'log_ids_to_hints': self.log_ids_to_hints, 'progressive_item_lists': self.items.get_progressive_item_ids_in_pool(), 'obelisk_side_id_to_EPs': StaticWitnessLogic.OBELISK_SIDE_ID_TO_EP_HEXES, - 'precompleted_puzzles': [int(h, 16) for h in - self.player_logic.EXCLUDED_LOCATIONS | self.player_logic.PRECOMPLETED_LOCATIONS], + 'precompleted_puzzles': [int(h, 16) for h in self.player_logic.EXCLUDED_LOCATIONS], 'entity_to_name': StaticWitnessLogic.ENTITY_ID_TO_NAME, } @@ -85,36 +91,125 @@ def generate_early(self): disabled_locations = self.multiworld.exclude_locations[self.player].value self.player_logic = WitnessPlayerLogic( - self.multiworld, self.player, disabled_locations, self.multiworld.start_inventory[self.player].value + self, disabled_locations, self.multiworld.start_inventory[self.player].value ) - self.locat: WitnessPlayerLocations = WitnessPlayerLocations(self.multiworld, self.player, self.player_logic) - self.items: WitnessPlayerItems = WitnessPlayerItems(self.multiworld, self.player, self.player_logic, self.locat) - self.regio: WitnessRegions = WitnessRegions(self.locat) + self.locat: WitnessPlayerLocations = WitnessPlayerLocations(self, self.player_logic) + self.items: WitnessPlayerItems = WitnessPlayerItems( + self, self.player_logic, self.locat + ) + self.regio: WitnessRegions = WitnessRegions(self.locat, self) self.log_ids_to_hints = dict() - if not (is_option_enabled(self.multiworld, self.player, "shuffle_symbols") - or get_option_value(self.multiworld, self.player, "shuffle_doors") - or is_option_enabled(self.multiworld, self.player, "shuffle_lasers")): + if not (self.options.shuffle_symbols or self.options.shuffle_doors or self.options.shuffle_lasers): if self.multiworld.players == 1: - warning("This Witness world doesn't have any progression items. Please turn on Symbol Shuffle, Door" - " Shuffle or Laser Shuffle if that doesn't seem right.") + warning(f"{self.multiworld.get_player_name(self.player)}'s Witness world doesn't have any progression" + f" items. Please turn on Symbol Shuffle, Door Shuffle or Laser Shuffle if that doesn't" + f" seem right.") else: - raise Exception("This Witness world doesn't have any progression items. Please turn on Symbol Shuffle," - " Door Shuffle or Laser Shuffle.") + raise Exception(f"{self.multiworld.get_player_name(self.player)}'s Witness world doesn't have any" + f" progression items. Please turn on Symbol Shuffle, Door Shuffle or Laser Shuffle.") def create_regions(self): - self.regio.create_regions(self.multiworld, self.player, self.player_logic) + self.regio.create_regions(self, self.player_logic) - def create_items(self): + # Set rules early so extra locations can be created based on the results of exploring collection states + + set_rules(self) + + # Add event items and tie them to event locations (e.g. laser activations). + + event_locations = [] + + for event_location in self.locat.EVENT_LOCATION_TABLE: + item_obj = self.create_item( + self.player_logic.EVENT_ITEM_PAIRS[event_location] + ) + location_obj = self.multiworld.get_location(event_location, self.player) + location_obj.place_locked_item(item_obj) + self.own_itempool.append(item_obj) + + event_locations.append(location_obj) + + # Place other locked items + dog_puzzle_skip = self.create_item("Puzzle Skip") + self.multiworld.get_location("Town Pet the Dog", self.player).place_locked_item(dog_puzzle_skip) + + self.own_itempool.append(dog_puzzle_skip) + + self.items_placed_early.append("Puzzle Skip") + + # Pick an early item to place on the tutorial gate. + early_items = [item for item in self.items.get_early_items() if item in self.items.get_mandatory_items()] + if early_items: + random_early_item = self.multiworld.random.choice(early_items) + if self.options.puzzle_randomization == 1: + # In Expert, only tag the item as early, rather than forcing it onto the gate. + self.multiworld.local_early_items[self.player][random_early_item] = 1 + else: + # Force the item onto the tutorial gate check and remove it from our random pool. + gate_item = self.create_item(random_early_item) + self.multiworld.get_location("Tutorial Gate Open", self.player).place_locked_item(gate_item) + self.own_itempool.append(gate_item) + self.items_placed_early.append(random_early_item) + + # There are some really restrictive settings in The Witness. + # They are rarely played, but when they are, we add some extra sphere 1 locations. + # This is done both to prevent generation failures, but also to make the early game less linear. + # Only sweeps for events because having this behavior be random based on Tutorial Gate would be strange. + + state = CollectionState(self.multiworld) + state.sweep_for_events(locations=event_locations) + + num_early_locs = sum(1 for loc in self.multiworld.get_reachable_locations(state, self.player) if loc.address) + + # Adjust the needed size for sphere 1 based on how restrictive the settings are in terms of items - # Determine pool size. Note that the dog location is included in the location list, so this needs to be -1. - pool_size: int = len(self.locat.CHECK_LOCATION_TABLE) - len(self.locat.EVENT_LOCATION_TABLE) - 1 + needed_size = 3 + needed_size += self.options.puzzle_randomization == 1 + needed_size += self.options.shuffle_symbols + needed_size += self.options.shuffle_doors > 0 + + # Then, add checks in order until the required amount of sphere 1 checks is met. + + extra_checks = [ + ("First Hallway Room", "First Hallway Bend"), + ("First Hallway", "First Hallway Straight"), + ("Desert Outside", "Desert Surface 3"), + ] + + for i in range(num_early_locs, needed_size): + if not extra_checks: + break + + region, loc = extra_checks.pop(0) + self.locat.add_location_late(loc) + self.multiworld.get_region(region, self.player).add_locations({loc: self.location_name_to_id[loc]}) + + player = self.multiworld.get_player_name(self.player) + + warning(f"""Location "{loc}" had to be added to {player}'s world due to insufficient sphere 1 size.""") + + def create_items(self): + # Determine pool size. + pool_size: int = len(self.locat.CHECK_LOCATION_TABLE) - len(self.locat.EVENT_LOCATION_TABLE) # Fill mandatory items and remove precollected and/or starting items from the pool. item_pool: Dict[str, int] = self.items.get_mandatory_items() + # Remove one copy of each item that was placed early + for already_placed in self.items_placed_early: + pool_size -= 1 + + if already_placed not in item_pool: + continue + + if item_pool[already_placed] == 1: + item_pool.pop(already_placed) + else: + item_pool[already_placed] -= 1 + for precollected_item_name in [item.name for item in self.multiworld.precollected_items[self.player]]: if precollected_item_name in item_pool: if item_pool[precollected_item_name] == 1: @@ -131,17 +226,18 @@ def create_items(self): self.multiworld.push_precollected(self.create_item(inventory_item_name)) if len(item_pool) > pool_size: - error_string = "The Witness world has too few locations ({num_loc}) to place its necessary items " \ - "({num_item})." - error(error_string.format(num_loc=pool_size, num_item=len(item_pool))) + error(f"{self.multiworld.get_player_name(self.player)}'s Witness world has too few locations ({pool_size})" + f" to place its necessary items ({len(item_pool)}).") return remaining_item_slots = pool_size - sum(item_pool.values()) # Add puzzle skips. - num_puzzle_skips = get_option_value(self.multiworld, self.player, "puzzle_skip_amount") + num_puzzle_skips = self.options.puzzle_skip_amount + if num_puzzle_skips > remaining_item_slots: - warning(f"The Witness world has insufficient locations to place all requested puzzle skips.") + warning(f"{self.multiworld.get_player_name(self.player)}'s Witness world has insufficient locations" + f" to place all requested puzzle skips.") num_puzzle_skips = remaining_item_slots item_pool["Puzzle Skip"] = num_puzzle_skips remaining_item_slots -= num_puzzle_skips @@ -150,45 +246,17 @@ def create_items(self): if remaining_item_slots > 0: item_pool.update(self.items.get_filler_items(remaining_item_slots)) - # Add event items and tie them to event locations (e.g. laser activations). - for event_location in self.locat.EVENT_LOCATION_TABLE: - item_obj = self.create_item( - self.player_logic.EVENT_ITEM_PAIRS[event_location] - ) - location_obj = self.multiworld.get_location(event_location, self.player) - location_obj.place_locked_item(item_obj) - - # BAD DOG GET BACK HERE WITH THAT PUZZLE SKIP YOU'RE POLLUTING THE ITEM POOL - self.multiworld.get_location("Town Pet the Dog", self.player)\ - .place_locked_item(self.create_item("Puzzle Skip")) - - # Pick an early item to place on the tutorial gate. - early_items = [item for item in self.items.get_early_items() if item in item_pool] - if early_items: - random_early_item = self.multiworld.random.choice(early_items) - if get_option_value(self.multiworld, self.player, "puzzle_randomization") == 1: - # In Expert, only tag the item as early, rather than forcing it onto the gate. - self.multiworld.local_early_items[self.player][random_early_item] = 1 - else: - # Force the item onto the tutorial gate check and remove it from our random pool. - self.multiworld.get_location("Tutorial Gate Open", self.player)\ - .place_locked_item(self.create_item(random_early_item)) - if item_pool[random_early_item] == 1: - item_pool.pop(random_early_item) - else: - item_pool[random_early_item] -= 1 - # Generate the actual items. for item_name, quantity in sorted(item_pool.items()): - self.multiworld.itempool += [self.create_item(item_name) for _ in range(0, quantity)] + new_items = [self.create_item(item_name) for _ in range(0, quantity)] + + self.own_itempool += new_items + self.multiworld.itempool += new_items if self.items.item_data[item_name].local_only: self.multiworld.local_items[self.player].value.add(item_name) - def set_rules(self): - set_rules(self.multiworld, self.player, self.player_logic, self.locat) - def fill_slot_data(self) -> dict: - hint_amount = get_option_value(self.multiworld, self.player, "hint_amount") + hint_amount = self.options.hint_amount.value credits_hint = ( "This Randomizer is brought to you by", @@ -199,9 +267,9 @@ def fill_slot_data(self) -> dict: audio_logs = get_audio_logs().copy() if hint_amount != 0: - generated_hints = make_hints(self.multiworld, self.player, hint_amount) + generated_hints = make_hints(self, hint_amount, self.own_itempool) - self.multiworld.per_slot_randoms[self.player].shuffle(audio_logs) + self.random.shuffle(audio_logs) duplicates = min(3, len(audio_logs) // hint_amount) @@ -216,7 +284,7 @@ def fill_slot_data(self) -> dict: audio_log = audio_logs.pop() self.log_ids_to_hints[int(audio_log, 16)] = credits_hint - joke_hints = generate_joke_hints(self.multiworld, self.player, len(audio_logs)) + joke_hints = generate_joke_hints(self, len(audio_logs)) while audio_logs: audio_log = audio_logs.pop() @@ -226,10 +294,10 @@ def fill_slot_data(self) -> dict: slot_data = self._get_slot_data() - for option_name in the_witness_options: - slot_data[option_name] = get_option_value( - self.multiworld, self.player, option_name - ) + for option_name in (attr.name for attr in dataclasses.fields(TheWitnessOptions) + if attr not in dataclasses.fields(PerGameCommonOptions)): + option = getattr(self.options, option_name) + slot_data[option_name] = bool(option.value) if isinstance(option, Toggle) else option.value return slot_data @@ -257,36 +325,35 @@ class WitnessLocation(Location): Archipelago Location for The Witness """ game: str = "The Witness" - check_hex: int = -1 + entity_hex: int = -1 def __init__(self, player: int, name: str, address: Optional[int], parent, ch_hex: int = -1): super().__init__(player, name, address, parent) - self.check_hex = ch_hex + self.entity_hex = ch_hex -def create_region(world: MultiWorld, player: int, name: str, - locat: WitnessPlayerLocations, region_locations=None, exits=None): +def create_region(world: WitnessWorld, name: str, locat: WitnessPlayerLocations, region_locations=None, exits=None): """ Create an Archipelago Region for The Witness """ - ret = Region(name, player, world) + ret = Region(name, world.player, world.multiworld) if region_locations: for location in region_locations: loc_id = locat.CHECK_LOCATION_TABLE[location] - check_hex = -1 - if location in StaticWitnessLogic.CHECKS_BY_NAME: - check_hex = int( - StaticWitnessLogic.CHECKS_BY_NAME[location]["checkHex"], 0 + entity_hex = -1 + if location in StaticWitnessLogic.ENTITIES_BY_NAME: + entity_hex = int( + StaticWitnessLogic.ENTITIES_BY_NAME[location]["entity_hex"], 0 ) location = WitnessLocation( - player, location, loc_id, ret, check_hex + world.player, location, loc_id, ret, entity_hex ) ret.locations.append(location) if exits: for single_exit in exits: - ret.exits.append(Entrance(player, single_exit, ret)) + ret.exits.append(Entrance(world.player, single_exit, ret)) return ret diff --git a/worlds/witness/hints.py b/worlds/witness/hints.py index 8a9dab54bc18..24302f0c6724 100644 --- a/worlds/witness/hints.py +++ b/worlds/witness/hints.py @@ -1,5 +1,9 @@ -from BaseClasses import MultiWorld -from .Options import is_option_enabled, get_option_value +from typing import Tuple, List, TYPE_CHECKING + +from BaseClasses import Item + +if TYPE_CHECKING: + from . import WitnessWorld joke_hints = [ "Quaternions break my brain", @@ -113,16 +117,16 @@ ] -def get_always_hint_items(multiworld: MultiWorld, player: int): +def get_always_hint_items(world: "WitnessWorld"): always = [ "Boat", - "Caves Exits to Main Island", + "Caves Shortcuts", "Progressive Dots", ] - difficulty = get_option_value(multiworld, player, "puzzle_randomization") - discards = is_option_enabled(multiworld, player, "shuffle_discarded_panels") - wincon = get_option_value(multiworld, player, "victory_condition") + difficulty = world.options.puzzle_randomization + discards = world.options.shuffle_discarded_panels + wincon = world.options.victory_condition if discards: if difficulty == 1: @@ -131,12 +135,15 @@ def get_always_hint_items(multiworld: MultiWorld, player: int): always.append("Triangles") if wincon == 0: - always.append("Mountain Bottom Floor Final Room Entry (Door)") + always += ["Mountain Bottom Floor Final Room Entry (Door)", "Mountain Bottom Floor Doors"] + + if wincon == 1: + always += ["Challenge Entry (Panel)", "Caves Panels"] return always -def get_always_hint_locations(multiworld: MultiWorld, player: int): +def get_always_hint_locations(_: "WitnessWorld"): return { "Challenge Vault Box", "Mountain Bottom Floor Discard", @@ -146,19 +153,34 @@ def get_always_hint_locations(multiworld: MultiWorld, player: int): } -def get_priority_hint_items(multiworld: MultiWorld, player: int): +def get_priority_hint_items(world: "WitnessWorld"): priority = { "Caves Mountain Shortcut (Door)", "Caves Swamp Shortcut (Door)", - "Negative Shapers", - "Sound Dots", - "Colored Dots", - "Stars + Same Colored Symbol", "Swamp Entry (Panel)", "Swamp Laser Shortcut (Door)", } - if is_option_enabled(multiworld, player, "shuffle_lasers"): + if world.options.shuffle_symbols: + symbols = [ + "Progressive Dots", + "Progressive Stars", + "Shapers", + "Rotated Shapers", + "Negative Shapers", + "Arrows", + "Triangles", + "Eraser", + "Black/White Squares", + "Colored Squares", + "Colored Dots", + "Sound Dots", + "Symmetry" + ] + + priority.update(world.random.sample(symbols, 5)) + + if world.options.shuffle_lasers: lasers = [ "Symmetry Laser", "Town Laser", @@ -172,18 +194,18 @@ def get_priority_hint_items(multiworld: MultiWorld, player: int): "Shadows Laser", ] - if get_option_value(multiworld, player, "shuffle_doors") >= 2: + if world.options.shuffle_doors >= 2: priority.add("Desert Laser") - priority.update(multiworld.per_slot_randoms[player].sample(lasers, 5)) + priority.update(world.random.sample(lasers, 5)) else: lasers.append("Desert Laser") - priority.update(multiworld.per_slot_randoms[player].sample(lasers, 6)) + priority.update(world.random.sample(lasers, 6)) return priority -def get_priority_hint_locations(multiworld: MultiWorld, player: int): +def get_priority_hint_locations(_: "WitnessWorld"): return { "Swamp Purple Underwater", "Shipwreck Vault Box", @@ -201,89 +223,100 @@ def get_priority_hint_locations(multiworld: MultiWorld, player: int): } -def make_hint_from_item(multiworld: MultiWorld, player: int, item: str): - location_obj = multiworld.find_item(item, player).item.location +def make_hint_from_item(world: "WitnessWorld", item_name: str, own_itempool: List[Item]): + locations = [item.location for item in own_itempool if item.name == item_name and item.location] + + if not locations: + return None + + location_obj = world.random.choice(locations) location_name = location_obj.name - if location_obj.player != player: - location_name += " (" + multiworld.get_player_name(location_obj.player) + ")" - return location_name, item, location_obj.address if (location_obj.player == player) else -1 + if location_obj.player != world.player: + location_name += " (" + world.multiworld.get_player_name(location_obj.player) + ")" + + return location_name, item_name, location_obj.address if (location_obj.player == world.player) else -1 -def make_hint_from_location(multiworld: MultiWorld, player: int, location: str): - location_obj = multiworld.get_location(location, player) - item_obj = multiworld.get_location(location, player).item +def make_hint_from_location(world: "WitnessWorld", location: str): + location_obj = world.multiworld.get_location(location, world.player) + item_obj = world.multiworld.get_location(location, world.player).item item_name = item_obj.name - if item_obj.player != player: - item_name += " (" + multiworld.get_player_name(item_obj.player) + ")" + if item_obj.player != world.player: + item_name += " (" + world.multiworld.get_player_name(item_obj.player) + ")" - return location, item_name, location_obj.address if (location_obj.player == player) else -1 + return location, item_name, location_obj.address if (location_obj.player == world.player) else -1 -def make_hints(multiworld: MultiWorld, player: int, hint_amount: int): +def make_hints(world: "WitnessWorld", hint_amount: int, own_itempool: List[Item]): hints = list() prog_items_in_this_world = { - item.name for item in multiworld.get_items() - if item.player == player and item.code and item.advancement + item.name for item in own_itempool if item.advancement and item.code and item.location } loc_in_this_world = { - location.name for location in multiworld.get_locations(player) - if location.address + location.name for location in world.multiworld.get_locations(world.player) if location.address } always_locations = [ - location for location in get_always_hint_locations(multiworld, player) + location for location in get_always_hint_locations(world) if location in loc_in_this_world ] always_items = [ - item for item in get_always_hint_items(multiworld, player) + item for item in get_always_hint_items(world) if item in prog_items_in_this_world ] priority_locations = [ - location for location in get_priority_hint_locations(multiworld, player) + location for location in get_priority_hint_locations(world) if location in loc_in_this_world ] priority_items = [ - item for item in get_priority_hint_items(multiworld, player) + item for item in get_priority_hint_items(world) if item in prog_items_in_this_world ] always_hint_pairs = dict() for item in always_items: - hint_pair = make_hint_from_item(multiworld, player, item) + hint_pair = make_hint_from_item(world, item, own_itempool) - if hint_pair[2] == 158007: # Tutorial Gate Open + if not hint_pair or hint_pair[2] == 158007: # Tutorial Gate Open continue always_hint_pairs[hint_pair[0]] = (hint_pair[1], True, hint_pair[2]) for location in always_locations: - hint_pair = make_hint_from_location(multiworld, player, location) + hint_pair = make_hint_from_location(world, location) always_hint_pairs[hint_pair[0]] = (hint_pair[1], False, hint_pair[2]) priority_hint_pairs = dict() for item in priority_items: - hint_pair = make_hint_from_item(multiworld, player, item) + hint_pair = make_hint_from_item(world, item, own_itempool) - if hint_pair[2] == 158007: # Tutorial Gate Open + if not hint_pair or hint_pair[2] == 158007: # Tutorial Gate Open continue priority_hint_pairs[hint_pair[0]] = (hint_pair[1], True, hint_pair[2]) for location in priority_locations: - hint_pair = make_hint_from_location(multiworld, player, location) + hint_pair = make_hint_from_location(world, location) priority_hint_pairs[hint_pair[0]] = (hint_pair[1], False, hint_pair[2]) + already_hinted_locations = set() + for loc, item in always_hint_pairs.items(): + if loc in already_hinted_locations: + continue + if item[1]: hints.append((f"{item[0]} can be found at {loc}.", item[2])) else: hints.append((f"{loc} contains {item[0]}.", item[2])) - multiworld.per_slot_randoms[player].shuffle(hints) # shuffle always hint order in case of low hint amount + already_hinted_locations.add(loc) + + world.random.shuffle(hints) # shuffle always hint order in case of low hint amount remaining_hints = hint_amount - len(hints) priority_hint_amount = int(max(0.0, min(len(priority_hint_pairs) / 2, remaining_hints / 2))) @@ -291,22 +324,27 @@ def make_hints(multiworld: MultiWorld, player: int, hint_amount: int): prog_items_in_this_world = sorted(list(prog_items_in_this_world)) locations_in_this_world = sorted(list(loc_in_this_world)) - multiworld.per_slot_randoms[player].shuffle(prog_items_in_this_world) - multiworld.per_slot_randoms[player].shuffle(locations_in_this_world) + world.random.shuffle(prog_items_in_this_world) + world.random.shuffle(locations_in_this_world) priority_hint_list = list(priority_hint_pairs.items()) - multiworld.per_slot_randoms[player].shuffle(priority_hint_list) + world.random.shuffle(priority_hint_list) for _ in range(0, priority_hint_amount): next_priority_hint = priority_hint_list.pop() loc = next_priority_hint[0] item = next_priority_hint[1] + if loc in already_hinted_locations: + continue + if item[1]: hints.append((f"{item[0]} can be found at {loc}.", item[2])) else: hints.append((f"{loc} contains {item[0]}.", item[2])) - next_random_hint_is_item = multiworld.per_slot_randoms[player].randrange(0, 2) # Moving this to the new system is in the bigger refactoring PR + already_hinted_locations.add(loc) + + next_random_hint_is_item = world.random.randrange(0, 2) while len(hints) < hint_amount: if next_random_hint_is_item: @@ -314,16 +352,28 @@ def make_hints(multiworld: MultiWorld, player: int, hint_amount: int): next_random_hint_is_item = not next_random_hint_is_item continue - hint = make_hint_from_item(multiworld, player, prog_items_in_this_world.pop()) + hint = make_hint_from_item(world, prog_items_in_this_world.pop(), own_itempool) + + if not hint or hint[0] in already_hinted_locations: + continue + hints.append((f"{hint[1]} can be found at {hint[0]}.", hint[2])) + + already_hinted_locations.add(hint[0]) else: - hint = make_hint_from_location(multiworld, player, locations_in_this_world.pop()) + hint = make_hint_from_location(world, locations_in_this_world.pop()) + + if hint[0] in already_hinted_locations: + continue + hints.append((f"{hint[0]} contains {hint[1]}.", hint[2])) + already_hinted_locations.add(hint[0]) + next_random_hint_is_item = not next_random_hint_is_item return hints -def generate_joke_hints(multiworld: MultiWorld, player: int, amount: int): - return [(x, -1) for x in multiworld.per_slot_randoms[player].sample(joke_hints, amount)] +def generate_joke_hints(world: "WitnessWorld", amount: int) -> List[Tuple[str, int]]: + return [(x, -1) for x in world.random.sample(joke_hints, amount)] diff --git a/worlds/witness/items.py b/worlds/witness/items.py index 82c79047f3fb..15c693b25dd4 100644 --- a/worlds/witness/items.py +++ b/worlds/witness/items.py @@ -2,18 +2,20 @@ Defines progression, junk and event items for The Witness """ import copy + from dataclasses import dataclass -from typing import Optional, Dict, List, Set +from typing import Optional, Dict, List, Set, TYPE_CHECKING from BaseClasses import Item, MultiWorld, ItemClassification -from .Options import get_option_value, is_option_enabled, the_witness_options - from .locations import ID_START, WitnessPlayerLocations from .player_logic import WitnessPlayerLogic from .static_logic import ItemDefinition, DoorItemDefinition, ProgressiveItemDefinition, ItemCategory, \ StaticWitnessLogic, WeightedItemDefinition from .utils import build_weighted_int_list +if TYPE_CHECKING: + from . import WitnessWorld + NUM_ENERGY_UPGRADES = 4 @@ -59,7 +61,7 @@ def __init__(self): classification = ItemClassification.progression StaticWitnessItems.item_groups.setdefault("Doors", []).append(item_name) elif definition.category is ItemCategory.LASER: - classification = ItemClassification.progression + classification = ItemClassification.progression_skip_balancing StaticWitnessItems.item_groups.setdefault("Lasers", []).append(item_name) elif definition.category is ItemCategory.USEFUL: classification = ItemClassification.useful @@ -90,11 +92,12 @@ class WitnessPlayerItems: Class that defines Items for a single world """ - def __init__(self, multiworld: MultiWorld, player: int, logic: WitnessPlayerLogic, locat: WitnessPlayerLocations): + def __init__(self, world: "WitnessWorld", logic: WitnessPlayerLogic, locat: WitnessPlayerLocations): """Adds event items after logic changes due to options""" - self._world: MultiWorld = multiworld - self._player_id: int = player + self._world: "WitnessWorld" = world + self._multiworld: MultiWorld = world.multiworld + self._player_id: int = world.player self._logic: WitnessPlayerLogic = logic self._locations: WitnessPlayerLocations = locat @@ -102,19 +105,33 @@ def __init__(self, multiworld: MultiWorld, player: int, logic: WitnessPlayerLogi self.item_data: Dict[str, ItemData] = copy.deepcopy(StaticWitnessItems.item_data) # Remove all progression items that aren't actually in the game. - self.item_data = {name: data for (name, data) in self.item_data.items() - if data.classification is not ItemClassification.progression or - name in logic.PROG_ITEMS_ACTUALLY_IN_THE_GAME} + self.item_data = { + name: data for (name, data) in self.item_data.items() + if data.classification not in + {ItemClassification.progression, ItemClassification.progression_skip_balancing} + or name in logic.PROG_ITEMS_ACTUALLY_IN_THE_GAME + } # Adjust item classifications based on game settings. - eps_shuffled = get_option_value(self._world, self._player_id, "shuffle_EPs") != 0 + eps_shuffled = self._world.options.shuffle_EPs + come_to_you = self._world.options.elevators_come_to_you for item_name, item_data in self.item_data.items(): - if not eps_shuffled and item_name in ["Monastery Garden Entry (Door)", "Monastery Shortcuts"]: + if not eps_shuffled and item_name in {"Monastery Garden Entry (Door)", + "Monastery Shortcuts", + "Quarry Boathouse Hook Control (Panel)", + "Windmill Turn Control (Panel)"}: # Downgrade doors that only gate progress in EP shuffle. item_data.classification = ItemClassification.useful - elif item_name in ["River Monastery Shortcut (Door)", "Jungle & River Shortcuts", - "Monastery Shortcut (Door)", - "Orchard Second Gate (Door)"]: + elif not come_to_you and not eps_shuffled and item_name in {"Quarry Elevator Control (Panel)", + "Swamp Long Bridge (Panel)"}: + # These Bridges/Elevators are not logical access because they may leave you stuck. + item_data.classification = ItemClassification.useful + elif item_name in {"River Monastery Garden Shortcut (Door)", + "Monastery Laser Shortcut (Door)", + "Orchard Second Gate (Door)", + "Jungle Bamboo Laser Shortcut (Door)", + "Keep Pressure Plates 2 Exit (Door)", + "Caves Elevator Controls (Panel)"}: # Downgrade doors that don't gate progress. item_data.classification = ItemClassification.useful @@ -122,8 +139,11 @@ def __init__(self, multiworld: MultiWorld, player: int, logic: WitnessPlayerLogi self._mandatory_items: Dict[str, int] = {} # Add progression items to the mandatory item list. - for item_name, item_data in {name: data for (name, data) in self.item_data.items() - if data.classification == ItemClassification.progression}.items(): + progression_dict = { + name: data for (name, data) in self.item_data.items() + if data.classification in {ItemClassification.progression, ItemClassification.progression_skip_balancing} + } + for item_name, item_data in progression_dict.items(): if isinstance(item_data.definition, ProgressiveItemDefinition): num_progression = len(self._logic.MULTI_LISTS[item_name]) self._mandatory_items[item_name] = num_progression @@ -170,7 +190,7 @@ def get_filler_items(self, quantity: int) -> Dict[str, int]: remaining_quantity -= len(output) # Read trap configuration data. - trap_weight = get_option_value(self._world, self._player_id, "trap_percentage") / 100 + trap_weight = self._world.options.trap_percentage / 100 filler_weight = 1 - trap_weight # Add filler items to the list. @@ -198,15 +218,14 @@ def get_early_items(self) -> List[str]: Returns items that are ideal for placing on extremely early checks, like the tutorial gate. """ output: Set[str] = set() - if "shuffle_symbols" not in the_witness_options.keys() \ - or is_option_enabled(self._world, self._player_id, "shuffle_symbols"): - if get_option_value(self._world, self._player_id, "shuffle_doors") > 0: + if self._world.options.shuffle_symbols: + if self._world.options.shuffle_doors: output = {"Dots", "Black/White Squares", "Symmetry"} else: output = {"Dots", "Black/White Squares", "Symmetry", "Shapers", "Stars"} - if is_option_enabled(self._world, self._player_id, "shuffle_discarded_panels"): - if get_option_value(self._world, self._player_id, "puzzle_randomization") == 1: + if self._world.options.shuffle_discarded_panels: + if self._world.options.puzzle_randomization == 1: output.add("Arrows") else: output.add("Triangles") @@ -217,7 +236,7 @@ def get_early_items(self) -> List[str]: # Remove items that are mentioned in any plando options. (Hopefully, in the future, plando will get resolved # before create_items so that we'll be able to check placed items instead of just removing all items mentioned # regardless of whether or not they actually wind up being manually placed. - for plando_setting in self._world.plando_items[self._player_id]: + for plando_setting in self._multiworld.plando_items[self._player_id]: if plando_setting.get("from_pool", True): for item_setting_key in [key for key in ["item", "items"] if key in plando_setting]: if type(plando_setting[item_setting_key]) is str: @@ -243,6 +262,7 @@ def get_door_ids_in_pool(self) -> List[int]: for item_name, item_data in {name: data for name, data in self.item_data.items() if isinstance(data.definition, DoorItemDefinition)}.items(): output += [int(hex_string, 16) for hex_string in item_data.definition.panel_id_hexes] + return output def get_symbol_ids_not_in_pool(self) -> List[int]: diff --git a/worlds/witness/locations.py b/worlds/witness/locations.py index b33e276e3ad8..d20be2794056 100644 --- a/worlds/witness/locations.py +++ b/worlds/witness/locations.py @@ -1,11 +1,14 @@ """ Defines constants for different types of locations in the game """ +from typing import TYPE_CHECKING -from .Options import is_option_enabled, get_option_value from .player_logic import WitnessPlayerLogic from .static_logic import StaticWitnessLogic +if TYPE_CHECKING: + from . import WitnessWorld + ID_START = 158000 @@ -19,22 +22,29 @@ class StaticWitnessLocations: "Tutorial Front Left", "Tutorial Back Left", "Tutorial Back Right", + "Tutorial Patio Floor", "Tutorial Gate Open", "Outside Tutorial Vault Box", "Outside Tutorial Discard", "Outside Tutorial Shed Row 5", "Outside Tutorial Tree Row 9", + "Outside Tutorial Outpost Entry Panel", + "Outside Tutorial Outpost Exit Panel", "Glass Factory Discard", "Glass Factory Back Wall 5", "Glass Factory Front 3", "Glass Factory Melting 3", + "Symmetry Island Lower Panel", "Symmetry Island Right 5", "Symmetry Island Back 6", "Symmetry Island Left 7", + "Symmetry Island Upper Panel", "Symmetry Island Scenery Outlines 5", + "Symmetry Island Laser Yellow 3", + "Symmetry Island Laser Blue 3", "Symmetry Island Laser Panel", "Orchard Apple Tree 5", @@ -49,9 +59,15 @@ class StaticWitnessLocations: "Desert Final Bent 3", "Desert Laser Panel", + "Quarry Entry 1 Panel", + "Quarry Entry 2 Panel", + "Quarry Stoneworks Entry Left Panel", + "Quarry Stoneworks Entry Right Panel", "Quarry Stoneworks Lower Row 6", "Quarry Stoneworks Upper Row 8", + "Quarry Stoneworks Control Room Left", "Quarry Stoneworks Control Room Right", + "Quarry Stoneworks Stairs Panel", "Quarry Boathouse Intro Right", "Quarry Boathouse Intro Left", "Quarry Boathouse Front Row 5", @@ -84,15 +100,32 @@ class StaticWitnessLocations: "Monastery Inside 4", "Monastery Laser Panel", + "Town Cargo Box Entry Panel", "Town Cargo Box Discard", "Town Tall Hexagonal", + "Town Church Entry Panel", "Town Church Lattice", + "Town Maze Panel", "Town Rooftop Discard", "Town Red Rooftop 5", "Town Wooden Roof Lower Row 5", "Town Wooden Rooftop", + "Town Windmill Entry Panel", + "Town RGB House Entry Panel", "Town Laser Panel", + "Town RGB Room Left", + "Town RGB Room Right", + "Town Sound Room Right", + + "Windmill Theater Entry Panel", + "Theater Exit Left Panel", + "Theater Exit Right Panel", + "Theater Tutorial Video", + "Theater Desert Video", + "Theater Jungle Video", + "Theater Shipwreck Video", + "Theater Mountain Video", "Theater Discard", "Jungle Discard", @@ -102,24 +135,33 @@ class StaticWitnessLocations: "Jungle Laser Panel", "River Vault Box", + "River Monastery Garden Shortcut Panel", + "Bunker Entry Panel", "Bunker Intro Left 5", "Bunker Intro Back 4", "Bunker Glass Room 3", "Bunker UV Room 2", "Bunker Laser Panel", + "Swamp Entry Panel", "Swamp Intro Front 6", "Swamp Intro Back 8", "Swamp Between Bridges Near Row 4", "Swamp Cyan Underwater 5", "Swamp Platform Row 4", + "Swamp Platform Shortcut Right Panel", "Swamp Between Bridges Far Row 4", "Swamp Red Underwater 4", + "Swamp Purple Underwater", "Swamp Beyond Rotating Bridge 4", "Swamp Blue Underwater 5", "Swamp Laser Panel", + "Swamp Laser Shortcut Right Panel", + "Treehouse First Door Panel", + "Treehouse Second Door Panel", + "Treehouse Third Door Panel", "Treehouse Yellow Bridge 9", "Treehouse First Purple Bridge 5", "Treehouse Second Purple Bridge 7", @@ -129,22 +171,11 @@ class StaticWitnessLocations: "Treehouse Laser Discard", "Treehouse Right Orange Bridge 12", "Treehouse Laser Panel", + "Treehouse Drawbridge Panel", "Mountainside Discard", "Mountainside Vault Box", - "Mountaintop River Shape", - "Tutorial Patio Floor", - "Quarry Stoneworks Control Room Left", - "Theater Tutorial Video", - "Theater Desert Video", - "Theater Jungle Video", - "Theater Shipwreck Video", - "Theater Mountain Video", - "Town RGB Room Left", - "Town RGB Room Right", - "Town Sound Room Right", - "Swamp Purple Underwater", "First Hallway EP", "Tutorial Cloud EP", @@ -316,46 +347,10 @@ class StaticWitnessLocations: "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", - "Quarry Obelisk Side 5", - "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 Mountain Shortcut Panel", + "Caves Swamp Shortcut Panel", - CAVES_LOCATIONS = { "Caves Blue Tunnel Right First 4", "Caves Blue Tunnel Left First 1", "Caves Blue Tunnel Left Second 5", @@ -378,17 +373,22 @@ class StaticWitnessLocations: "Caves Left Upstairs Single", "Caves Left Upstairs Left Row 5", + "Caves Challenge Entry Panel", + "Challenge Tunnels Entry Panel", + "Tunnels Vault Box", "Theater Challenge Video", + "Tunnels Town Shortcut Panel", + "Caves Skylight EP", "Challenge Water EP", "Tunnels Theater Flowers EP", "Tutorial Gate EP", - } - MOUNTAIN_UNREACHABLE_FROM_BEHIND = { - "Mountaintop Trap Door Triple Exit", + "Mountaintop Mountain Entry Panel", + + "Mountain Floor 1 Light Bridge Controller", "Mountain Floor 1 Right Row 5", "Mountain Floor 1 Left Row 7", @@ -403,46 +403,84 @@ class StaticWitnessLocations: "Mountain Bottom Floor Yellow Bridge EP", "Mountain Bottom Floor Blue Bridge EP", "Mountain Floor 2 Pink Bridge EP", - } - MOUNTAIN_REACHABLE_FROM_BEHIND = { "Mountain Floor 2 Elevator Discard", "Mountain Bottom Floor Giant Puzzle", + "Mountain Bottom Floor Final Room Entry Left", + "Mountain Bottom Floor Final Room Entry Right", + + "Mountain Bottom Floor Caves Entry Panel", + "Mountain Final Room Left Pillar 4", "Mountain Final Room Right Pillar 4", - } - MOUNTAIN_EXTRAS = { "Challenge Vault Box", "Theater Challenge Video", - "Mountain Bottom Floor Discard" + "Mountain Bottom Floor Discard", + } + + 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", + "Quarry Obelisk Side 5", + "Town Obelisk Side 1", + "Town Obelisk Side 2", + "Town Obelisk Side 3", + "Town Obelisk Side 4", + "Town Obelisk Side 5", + "Town Obelisk Side 6", } ALL_LOCATIONS_TO_ID = dict() @staticmethod - def get_id(chex): + def get_id(chex: str): """ Calculates the location ID for any given location """ - return StaticWitnessLogic.CHECKS_BY_HEX[chex]["id"] + return StaticWitnessLogic.ENTITIES_BY_HEX[chex]["id"] @staticmethod - def get_event_name(panel_hex): + def get_event_name(panel_hex: str): """ Returns the event name of any given panel. """ - action = " Opened" if StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]["panelType"] == "Door" else " Solved" + action = " Opened" if StaticWitnessLogic.ENTITIES_BY_HEX[panel_hex]["entityType"] == "Door" else " Solved" - return StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]["checkName"] + action + return StaticWitnessLogic.ENTITIES_BY_HEX[panel_hex]["checkName"] + action def __init__(self): all_loc_to_id = { panel_obj["checkName"]: self.get_id(chex) - for chex, panel_obj in StaticWitnessLogic.CHECKS_BY_HEX.items() + for chex, panel_obj in StaticWitnessLogic.ENTITIES_BY_HEX.items() if panel_obj["id"] } @@ -459,84 +497,44 @@ class WitnessPlayerLocations: Class that defines locations for a single player """ - def __init__(self, world, player, player_logic: WitnessPlayerLogic): + def __init__(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic): """Defines locations AFTER logic changes due to options""" self.PANEL_TYPES_TO_SHUFFLE = {"General", "Laser"} self.CHECK_LOCATIONS = StaticWitnessLocations.GENERAL_LOCATIONS.copy() - doors = get_option_value(world, player, "shuffle_doors") >= 2 - earlyutm = is_option_enabled(world, player, "early_secret_area") - victory = get_option_value(world, player, "victory_condition") - mount_lasers = get_option_value(world, player, "mountain_lasers") - chal_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 - postgame = postgame | StaticWitnessLocations.MOUNTAIN_EXTRAS - - self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | postgame - - mountain_enterable_from_top = victory == 0 or victory == 1 or (victory == 3 and chal_lasers > mount_lasers) - - if earlyutm or doors: # in non-doors, there is no way to get symbol-locked by the final pillars (currently) - postgame -= StaticWitnessLocations.CAVES_LOCATIONS - - if (doors or earlyutm) and (victory == 0 or (victory == 2 and mount_lasers > chal_lasers)): - postgame -= {"Challenge Vault Box", "Theater Challenge Video"} - - if doors or mountain_enterable_from_top: - postgame -= StaticWitnessLocations.MOUNTAIN_REACHABLE_FROM_BEHIND - - if mountain_enterable_from_top: - postgame -= StaticWitnessLocations.MOUNTAIN_UNREACHABLE_FROM_BEHIND - - if (victory == 0 and doors) or victory == 1 or (victory == 2 and mount_lasers > chal_lasers and doors): - postgame -= {"Mountain Bottom Floor Discard"} - - if is_option_enabled(world, player, "shuffle_discarded_panels"): + if world.options.shuffle_discarded_panels: self.PANEL_TYPES_TO_SHUFFLE.add("Discard") - if is_option_enabled(world, player, "shuffle_vault_boxes"): + if world.options.shuffle_vault_boxes: self.PANEL_TYPES_TO_SHUFFLE.add("Vault") - if get_option_value(world, player, "shuffle_EPs") == 1: + if world.options.shuffle_EPs == 1: self.PANEL_TYPES_TO_SHUFFLE.add("EP") - elif get_option_value(world, player, "shuffle_EPs") == 2: + elif world.options.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"] + obelisk_loc_hex = StaticWitnessLogic.ENTITIES_BY_NAME[obelisk_loc]["entity_hex"] 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.discard(StaticWitnessLogic.ENTITIES_BY_HEX[player_logic.VICTORY_LOCATION]["checkName"]) self.CHECK_LOCATIONS = self.CHECK_LOCATIONS - { - StaticWitnessLogic.CHECKS_BY_HEX[check_hex]["checkName"] - for check_hex in player_logic.COMPLETELY_DISABLED_CHECKS + StaticWitnessLogic.ENTITIES_BY_HEX[entity_hex]["checkName"] + for entity_hex in player_logic.COMPLETELY_DISABLED_ENTITIES | player_logic.PRECOMPLETED_LOCATIONS } self.CHECK_PANELHEX_TO_ID = { - StaticWitnessLogic.CHECKS_BY_NAME[ch]["checkHex"]: StaticWitnessLocations.ALL_LOCATIONS_TO_ID[ch] + StaticWitnessLogic.ENTITIES_BY_NAME[ch]["entity_hex"]: 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 + if StaticWitnessLogic.ENTITIES_BY_NAME[ch]["entityType"] in self.PANEL_TYPES_TO_SHUFFLE } - dog_hex = StaticWitnessLogic.CHECKS_BY_NAME["Town Pet the Dog"]["checkHex"] + dog_hex = StaticWitnessLogic.ENTITIES_BY_NAME["Town Pet the Dog"]["entity_hex"] dog_id = StaticWitnessLocations.ALL_LOCATIONS_TO_ID["Town Pet the Dog"] self.CHECK_PANELHEX_TO_ID[dog_hex] = dog_id @@ -554,9 +552,14 @@ def __init__(self, world, player, player_logic: WitnessPlayerLogic): } check_dict = { - StaticWitnessLogic.CHECKS_BY_HEX[location]["checkName"]: - StaticWitnessLocations.get_id(StaticWitnessLogic.CHECKS_BY_HEX[location]["checkHex"]) + StaticWitnessLogic.ENTITIES_BY_HEX[location]["checkName"]: + StaticWitnessLocations.get_id(StaticWitnessLogic.ENTITIES_BY_HEX[location]["entity_hex"]) for location in self.CHECK_PANELHEX_TO_ID } self.CHECK_LOCATION_TABLE = {**self.EVENT_LOCATION_TABLE, **check_dict} + + def add_location_late(self, entity_name: str): + entity_hex = StaticWitnessLogic.ENTITIES_BY_NAME[entity_name]["entity_hex"] + self.CHECK_LOCATION_TABLE[entity_hex] = entity_name + self.CHECK_PANELHEX_TO_ID[entity_hex] = StaticWitnessLocations.get_id(entity_hex) diff --git a/worlds/witness/player_logic.py b/worlds/witness/player_logic.py index be1a34aedfcf..cfd36c09be24 100644 --- a/worlds/witness/player_logic.py +++ b/worlds/witness/player_logic.py @@ -16,22 +16,22 @@ """ import copy -from typing import Set, Dict, cast, List +from collections import defaultdict +from typing import cast, TYPE_CHECKING from logging import warning -from BaseClasses import MultiWorld from .static_logic import StaticWitnessLogic, DoorItemDefinition, ItemCategory, ProgressiveItemDefinition -from .utils import define_new_region, get_disable_unrandomized_list, parse_lambda, get_early_utm_list, \ - get_symbol_shuffle_list, get_door_panel_shuffle_list, get_doors_complex_list, get_doors_max_list, \ - get_doors_simple_list, get_laser_shuffle, get_ep_all_individual, get_ep_obelisks, get_ep_easy, get_ep_no_eclipse, \ - get_ep_no_caves, get_ep_no_mountain, get_ep_no_videos -from .Options import is_option_enabled, get_option_value, the_witness_options +from .utils import * + +if TYPE_CHECKING: + from . import WitnessWorld class WitnessPlayerLogic: """WITNESS LOGIC CLASS""" - def reduce_req_within_region(self, panel_hex): + @lru_cache(maxsize=None) + def reduce_req_within_region(self, panel_hex: str) -> FrozenSet[FrozenSet[str]]: """ Panels in this game often only turn on when other panels are solved. Those other panels may have different item requirements. @@ -40,14 +40,14 @@ def reduce_req_within_region(self, panel_hex): Panels outside of the same region will still be checked manually. """ - if panel_hex in self.COMPLETELY_DISABLED_CHECKS or panel_hex in self.PRECOMPLETED_LOCATIONS: + if panel_hex in self.COMPLETELY_DISABLED_ENTITIES or panel_hex in self.IRRELEVANT_BUT_NOT_DISABLED_ENTITIES: return frozenset() - check_obj = self.REFERENCE_LOGIC.CHECKS_BY_HEX[panel_hex] + entity_obj = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[panel_hex] these_items = frozenset({frozenset()}) - if check_obj["id"]: + if entity_obj["id"]: these_items = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["items"] these_items = frozenset({ @@ -58,6 +58,8 @@ def reduce_req_within_region(self, panel_hex): for subset in these_items: self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI.update(subset) + these_panels = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["panels"] + if panel_hex in self.DOOR_ITEMS_BY_ID: door_items = frozenset({frozenset([item]) for item in self.DOOR_ITEMS_BY_ID[panel_hex]}) @@ -68,14 +70,21 @@ def reduce_req_within_region(self, panel_hex): for items_option in these_items: all_options.add(items_option.union(dependentItem)) + # 0x28A0D depends on another entity for *non-power* reasons -> This dependency needs to be preserved... if panel_hex != "0x28A0D": return frozenset(all_options) - else: # 0x28A0D depends on another entity for *non-power* reasons -> This dependency needs to be preserved - these_items = all_options + # ...except in Expert, where that dependency doesn't exist, but now there *is* a power dependency. + # In the future, it would be wise to make a distinction between "power dependencies" and other dependencies. + if any("0x28998" in option for option in these_panels): + return frozenset(all_options) - these_panels = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["panels"] + these_items = all_options - these_panels = frozenset({panels - self.PRECOMPLETED_LOCATIONS for panels in these_panels}) + disabled_eps = {eHex for eHex in self.COMPLETELY_DISABLED_ENTITIES + if self.REFERENCE_LOGIC.ENTITIES_BY_HEX[eHex]["entityType"] == "EP"} + + these_panels = frozenset({panels - disabled_eps + for panels in these_panels}) if these_panels == frozenset({frozenset()}): return these_items @@ -85,40 +94,30 @@ def reduce_req_within_region(self, panel_hex): for option in these_panels: dependent_items_for_option = frozenset({frozenset()}) - for option_panel in option: - dep_obj = self.REFERENCE_LOGIC.CHECKS_BY_HEX.get(option_panel) - - if option_panel in self.COMPLETELY_DISABLED_CHECKS: - new_items = frozenset() - elif option_panel in {"7 Lasers", "11 Lasers", "PP2 Weirdness", "Theater to Tunnels"}: - new_items = frozenset({frozenset([option_panel])}) - # If a panel turns on when a panel in a different region turns on, - # the latter panel will be an "event panel", unless it ends up being - # a location itself. This prevents generation failures. - elif dep_obj["region"]["name"] != check_obj["region"]["name"]: - new_items = frozenset({frozenset([option_panel])}) - self.EVENT_PANELS_FROM_PANELS.add(option_panel) - elif option_panel in self.ALWAYS_EVENT_NAMES_BY_HEX.keys(): - new_items = frozenset({frozenset([option_panel])}) - self.EVENT_PANELS_FROM_PANELS.add(option_panel) - else: - new_items = self.reduce_req_within_region(option_panel) - - updated_items = set() + for option_entity in option: + dep_obj = self.REFERENCE_LOGIC.ENTITIES_BY_HEX.get(option_entity) - for items_option in dependent_items_for_option: - for items_option2 in new_items: - updated_items.add(items_option.union(items_option2)) + if option_entity in self.EVENT_NAMES_BY_HEX: + new_items = frozenset({frozenset([option_entity])}) + elif option_entity in {"7 Lasers", "11 Lasers", "PP2 Weirdness", "Theater to Tunnels"}: + new_items = frozenset({frozenset([option_entity])}) + else: + new_items = self.reduce_req_within_region(option_entity) + if dep_obj["region"] and entity_obj["region"] != dep_obj["region"]: + new_items = frozenset( + frozenset(possibility | {dep_obj["region"]["name"]}) + for possibility in new_items + ) - dependent_items_for_option = updated_items + dependent_items_for_option = dnf_and([dependent_items_for_option, new_items]) for items_option in these_items: for dependentItem in dependent_items_for_option: all_options.add(items_option.union(dependentItem)) - return frozenset(all_options) + return dnf_remove_redundancies(frozenset(all_options)) - def make_single_adjustment(self, adj_type, line): + def make_single_adjustment(self, adj_type: str, line: str): from . import StaticWitnessItems """Makes a single logic adjustment based on additional logic file""" @@ -148,9 +147,9 @@ def make_single_adjustment(self, adj_type, line): self.THEORETICAL_ITEMS.discard(item_name) if isinstance(StaticWitnessLogic.all_items[item_name], ProgressiveItemDefinition): - self.THEORETICAL_ITEMS_NO_MULTI\ - .difference_update(cast(ProgressiveItemDefinition, - StaticWitnessLogic.all_items[item_name]).child_item_names) + self.THEORETICAL_ITEMS_NO_MULTI.difference_update( + cast(ProgressiveItemDefinition, StaticWitnessLogic.all_items[item_name]).child_item_names + ) else: self.THEORETICAL_ITEMS_NO_MULTI.discard(item_name) @@ -165,25 +164,15 @@ def make_single_adjustment(self, adj_type, line): if adj_type == "Event Items": line_split = line.split(" - ") + new_event_name = line_split[0] hex_set = line_split[1].split(",") - for hex_code in hex_set: - self.ALWAYS_EVENT_NAMES_BY_HEX[hex_code] = line_split[0] - - """ - Should probably do this differently... - Events right now depend on a panel. - That seems bad. - """ - - to_remove = set() - - for hex_code, event_name in self.ALWAYS_EVENT_NAMES_BY_HEX.items(): - if hex_code not in hex_set and event_name == line_split[0]: - to_remove.add(hex_code) + for entity, event_name in self.EVENT_NAMES_BY_HEX.items(): + if event_name == new_event_name: + self.DONT_MAKE_EVENTS.add(entity) - for remove in to_remove: - del self.ALWAYS_EVENT_NAMES_BY_HEX[remove] + for hex_code in hex_set: + self.EVENT_NAMES_BY_HEX[hex_code] = new_event_name return @@ -196,9 +185,10 @@ def make_single_adjustment(self, adj_type, line): if len(line_split) > 2: required_items = parse_lambda(line_split[2]) - items_actually_in_the_game = [item_name for item_name, item_definition - in StaticWitnessLogic.all_items.items() - if item_definition.category is ItemCategory.SYMBOL] + items_actually_in_the_game = [ + item_name for item_name, item_definition in StaticWitnessLogic.all_items.items() + if item_definition.category is ItemCategory.SYMBOL + ] required_items = frozenset( subset.intersection(items_actually_in_the_game) for subset in required_items @@ -213,116 +203,204 @@ def make_single_adjustment(self, adj_type, line): if adj_type == "Disabled Locations": panel_hex = line[:7] - self.COMPLETELY_DISABLED_CHECKS.add(panel_hex) + self.COMPLETELY_DISABLED_ENTITIES.add(panel_hex) + + return + + if adj_type == "Irrelevant Locations": + panel_hex = line[:7] + + self.IRRELEVANT_BUT_NOT_DISABLED_ENTITIES.add(panel_hex) return if adj_type == "Region Changes": new_region_and_options = define_new_region(line + ":") - + self.CONNECTIONS_BY_REGION_NAME[new_region_and_options[0]["name"]] = new_region_and_options[1] return + if adj_type == "New Connections": + line_split = line.split(" - ") + source_region = line_split[0] + target_region = line_split[1] + panel_set_string = line_split[2] + + for connection in self.CONNECTIONS_BY_REGION_NAME[source_region]: + if connection[0] == target_region: + self.CONNECTIONS_BY_REGION_NAME[source_region].remove(connection) + + if panel_set_string == "TrueOneWay": + self.CONNECTIONS_BY_REGION_NAME[source_region].add( + (target_region, frozenset({frozenset(["TrueOneWay"])})) + ) + else: + new_lambda = connection[1] | parse_lambda(panel_set_string) + self.CONNECTIONS_BY_REGION_NAME[source_region].add((target_region, new_lambda)) + break + else: # Execute if loop did not break. TIL this is a thing you can do! + new_conn = (target_region, parse_lambda(panel_set_string)) + self.CONNECTIONS_BY_REGION_NAME[source_region].add(new_conn) + if adj_type == "Added Locations": if "0x" in line: - line = StaticWitnessLogic.CHECKS_BY_HEX[line]["checkName"] + line = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[line]["checkName"] self.ADDED_CHECKS.add(line) - if adj_type == "Precompleted Locations": - self.PRECOMPLETED_LOCATIONS.add(line) - - def make_options_adjustments(self, world, player): + def make_options_adjustments(self, world: "WitnessWorld"): """Makes logic adjustments based on options""" adjustment_linesets_in_order = [] - if get_option_value(world, player, "victory_condition") == 0: + # Postgame + + doors = world.options.shuffle_doors >= 2 + lasers = world.options.shuffle_lasers + early_caves = world.options.early_caves > 0 + victory = world.options.victory_condition + mnt_lasers = world.options.mountain_lasers + chal_lasers = world.options.challenge_lasers + + mountain_enterable_from_top = victory == 0 or victory == 1 or (victory == 3 and chal_lasers > mnt_lasers) + + if not world.options.shuffle_postgame: + if not (early_caves or doors): + adjustment_linesets_in_order.append(get_caves_exclusion_list()) + if not victory == 1: + adjustment_linesets_in_order.append(get_path_to_challenge_exclusion_list()) + adjustment_linesets_in_order.append(get_challenge_vault_box_exclusion_list()) + adjustment_linesets_in_order.append(get_beyond_challenge_exclusion_list()) + + if not ((doors or early_caves) and (victory == 0 or (victory == 2 and mnt_lasers > chal_lasers))): + adjustment_linesets_in_order.append(get_beyond_challenge_exclusion_list()) + if not victory == 1: + adjustment_linesets_in_order.append(get_challenge_vault_box_exclusion_list()) + + if not (doors or mountain_enterable_from_top): + adjustment_linesets_in_order.append(get_mountain_lower_exclusion_list()) + + if not mountain_enterable_from_top: + adjustment_linesets_in_order.append(get_mountain_upper_exclusion_list()) + + if not ((victory == 0 and doors) or victory == 1 or (victory == 2 and mnt_lasers > chal_lasers and doors)): + if doors: + adjustment_linesets_in_order.append(get_bottom_floor_discard_exclusion_list()) + else: + adjustment_linesets_in_order.append(get_bottom_floor_discard_nondoors_exclusion_list()) + + if victory == 2 and chal_lasers >= mnt_lasers: + adjustment_linesets_in_order.append(["Disabled Locations:", "0xFFF00 (Mountain Box Long)"]) + + # Exclude Discards / Vaults + + if not world.options.shuffle_discarded_panels: + # In disable_non_randomized, the discards are needed for alternate activation triggers, UNLESS both + # (remote) doors and lasers are shuffled. + if not world.options.disable_non_randomized_puzzles or (doors and lasers): + adjustment_linesets_in_order.append(get_discard_exclusion_list()) + + if doors: + adjustment_linesets_in_order.append(get_bottom_floor_discard_exclusion_list()) + + if not world.options.shuffle_vault_boxes: + adjustment_linesets_in_order.append(get_vault_exclusion_list()) + if not victory == 1: + adjustment_linesets_in_order.append(get_challenge_vault_box_exclusion_list()) + + # Victory Condition + + if victory == 0: self.VICTORY_LOCATION = "0x3D9A9" - elif get_option_value(world, player, "victory_condition") == 1: + elif victory == 1: self.VICTORY_LOCATION = "0x0356B" - elif get_option_value(world, player, "victory_condition") == 2: + elif victory == 2: self.VICTORY_LOCATION = "0x09F7F" - elif get_option_value(world, player, "victory_condition") == 3: + elif victory == 3: self.VICTORY_LOCATION = "0xFFF00" - if get_option_value(world, player, "challenge_lasers") <= 7: + if chal_lasers <= 7: adjustment_linesets_in_order.append([ "Requirement Changes:", "0xFFF00 - 11 Lasers - True", ]) - if is_option_enabled(world, player, "disable_non_randomized_puzzles"): + if world.options.disable_non_randomized_puzzles: adjustment_linesets_in_order.append(get_disable_unrandomized_list()) - if is_option_enabled(world, player, "shuffle_symbols") or "shuffle_symbols" not in the_witness_options.keys(): + if world.options.shuffle_symbols: adjustment_linesets_in_order.append(get_symbol_shuffle_list()) - if get_option_value(world, player, "EP_difficulty") == 0: + if world.options.EP_difficulty == 0: adjustment_linesets_in_order.append(get_ep_easy()) - elif get_option_value(world, player, "EP_difficulty") == 1: + elif world.options.EP_difficulty == 1: adjustment_linesets_in_order.append(get_ep_no_eclipse()) - if not is_option_enabled(world, player, "shuffle_vault_boxes"): - adjustment_linesets_in_order.append(get_ep_no_videos()) - - doors = get_option_value(world, player, "shuffle_doors") >= 2 - earlyutm = is_option_enabled(world, player, "early_secret_area") - victory = get_option_value(world, player, "victory_condition") - mount_lasers = get_option_value(world, player, "mountain_lasers") - chal_lasers = get_option_value(world, player, "challenge_lasers") - - excluse_postgame = not is_option_enabled(world, player, "shuffle_postgame") - - if excluse_postgame and not (earlyutm or doors): - adjustment_linesets_in_order.append(get_ep_no_caves()) - - mountain_enterable_from_top = victory == 0 or victory == 1 or (victory == 3 and chal_lasers > mount_lasers) - if excluse_postgame and not mountain_enterable_from_top: - adjustment_linesets_in_order.append(get_ep_no_mountain()) - - if get_option_value(world, player, "shuffle_doors") == 1: - adjustment_linesets_in_order.append(get_door_panel_shuffle_list()) - - if get_option_value(world, player, "shuffle_doors") == 2: - adjustment_linesets_in_order.append(get_doors_simple_list()) - - if get_option_value(world, player, "shuffle_doors") == 3: - adjustment_linesets_in_order.append(get_doors_complex_list()) - - if get_option_value(world, player, "shuffle_doors") == 4: - adjustment_linesets_in_order.append(get_doors_max_list()) - - if is_option_enabled(world, player, "early_secret_area"): - adjustment_linesets_in_order.append(get_early_utm_list()) + if world.options.door_groupings == 1: + if world.options.shuffle_doors == 1: + adjustment_linesets_in_order.append(get_simple_panels()) + elif world.options.shuffle_doors == 2: + adjustment_linesets_in_order.append(get_simple_doors()) + elif world.options.shuffle_doors == 3: + adjustment_linesets_in_order.append(get_simple_doors()) + adjustment_linesets_in_order.append(get_simple_additional_panels()) + else: + if world.options.shuffle_doors == 1: + adjustment_linesets_in_order.append(get_complex_door_panels()) + adjustment_linesets_in_order.append(get_complex_additional_panels()) + elif world.options.shuffle_doors == 2: + adjustment_linesets_in_order.append(get_complex_doors()) + elif world.options.shuffle_doors == 3: + adjustment_linesets_in_order.append(get_complex_doors()) + adjustment_linesets_in_order.append(get_complex_additional_panels()) + + if world.options.shuffle_boat: + adjustment_linesets_in_order.append(get_boat()) + + if world.options.early_caves == 2: + adjustment_linesets_in_order.append(get_early_caves_start_list()) + + if world.options.early_caves == 1 and not doors: + adjustment_linesets_in_order.append(get_early_caves_list()) + + if world.options.elevators_come_to_you: + adjustment_linesets_in_order.append(get_elevators_come_to_you()) for item in self.YAML_ADDED_ITEMS: adjustment_linesets_in_order.append(["Items:", item]) - if is_option_enabled(world, player, "shuffle_lasers"): + if lasers: adjustment_linesets_in_order.append(get_laser_shuffle()) - if get_option_value(world, player, "shuffle_EPs") == 0: # No EP Shuffle - adjustment_linesets_in_order.append(["Disabled Locations:"] + get_ep_all_individual()[1:]) - adjustment_linesets_in_order.append(["Disabled Locations:"] + get_ep_obelisks()[1:]) + if world.options.shuffle_EPs: + ep_gen = ((ep_hex, ep_obj) for (ep_hex, ep_obj) in self.REFERENCE_LOGIC.ENTITIES_BY_HEX.items() + if ep_obj["entityType"] == "EP") - elif get_option_value(world, player, "shuffle_EPs") == 1: # Individual EPs + for ep_hex, ep_obj in ep_gen: + obelisk = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[self.REFERENCE_LOGIC.EP_TO_OBELISK_SIDE[ep_hex]] + obelisk_name = obelisk["checkName"] + ep_name = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[ep_hex]["checkName"] + self.EVENT_NAMES_BY_HEX[ep_hex] = f"{obelisk_name} - {ep_name}" + else: adjustment_linesets_in_order.append(["Disabled Locations:"] + get_ep_obelisks()[1:]) + if world.options.shuffle_EPs == 0: + adjustment_linesets_in_order.append(["Irrelevant Locations:"] + get_ep_all_individual()[1:]) + yaml_disabled_eps = [] for yaml_disabled_location in self.YAML_DISABLED_LOCATIONS: - if yaml_disabled_location not in StaticWitnessLogic.CHECKS_BY_NAME: + if yaml_disabled_location not in self.REFERENCE_LOGIC.ENTITIES_BY_NAME: continue - loc_obj = StaticWitnessLogic.CHECKS_BY_NAME[yaml_disabled_location] + loc_obj = self.REFERENCE_LOGIC.ENTITIES_BY_NAME[yaml_disabled_location] - if loc_obj["panelType"] == "EP" and get_option_value(world, player, "shuffle_EPs") == 2: - yaml_disabled_eps.append(loc_obj["checkHex"]) + if loc_obj["entityType"] == "EP" and world.options.shuffle_EPs != 0: + yaml_disabled_eps.append(loc_obj["entity_hex"]) - if loc_obj["panelType"] in {"EP", "General"}: - self.EXCLUDED_LOCATIONS.add(loc_obj["checkHex"]) + if loc_obj["entityType"] in {"EP", "General", "Vault", "Discard"}: + self.EXCLUDED_LOCATIONS.add(loc_obj["entity_hex"]) - adjustment_linesets_in_order.append(["Precompleted Locations:"] + yaml_disabled_eps) + adjustment_linesets_in_order.append(["Disabled Locations:"] + yaml_disabled_eps) for adjustment_lineset in adjustment_linesets_in_order: current_adjustment_type = None @@ -337,15 +415,19 @@ def make_options_adjustments(self, world, player): self.make_single_adjustment(current_adjustment_type, line) + for entity_id in self.COMPLETELY_DISABLED_ENTITIES: + if entity_id in self.DOOR_ITEMS_BY_ID: + del self.DOOR_ITEMS_BY_ID[entity_id] + def make_dependency_reduced_checklist(self): """ Turns dependent check set into semi-independent check set """ - for check_hex in self.DEPENDENT_REQUIREMENTS_BY_HEX.keys(): - indep_requirement = self.reduce_req_within_region(check_hex) + for entity_hex in self.DEPENDENT_REQUIREMENTS_BY_HEX.keys(): + indep_requirement = self.reduce_req_within_region(entity_hex) - self.REQUIREMENTS_BY_HEX[check_hex] = indep_requirement + self.REQUIREMENTS_BY_HEX[entity_hex] = indep_requirement for item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI: if item not in self.THEORETICAL_ITEMS: @@ -360,71 +442,76 @@ def make_dependency_reduced_checklist(self): else: self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.add(item) - def make_event_item_pair(self, panel): - """ - Makes a pair of an event panel and its event item - """ - action = " Opened" if StaticWitnessLogic.CHECKS_BY_HEX[panel]["panelType"] == "Door" else " Solved" + for region, connections in self.CONNECTIONS_BY_REGION_NAME.items(): + new_connections = [] - name = StaticWitnessLogic.CHECKS_BY_HEX[panel]["checkName"] + action - if panel not in self.EVENT_ITEM_NAMES: - if StaticWitnessLogic.CHECKS_BY_HEX[panel]["panelType"] == "EP": - obelisk = StaticWitnessLogic.CHECKS_BY_HEX[StaticWitnessLogic.EP_TO_OBELISK_SIDE[panel]]["checkName"] + for connection in connections: + overall_requirement = frozenset() - self.EVENT_ITEM_NAMES[panel] = obelisk + " - " + StaticWitnessLogic.CHECKS_BY_HEX[panel]["checkName"] + for option in connection[1]: + individual_entity_requirements = [] + for entity in option: + if entity in self.EVENT_NAMES_BY_HEX or entity not in self.REFERENCE_LOGIC.ENTITIES_BY_HEX: + individual_entity_requirements.append(frozenset({frozenset({entity})})) + else: + entity_req = self.reduce_req_within_region(entity) - else: - warning("Panel \"" + name + "\" does not have an associated event name.") - self.EVENT_ITEM_NAMES[panel] = name + " Event" - pair = (name, self.EVENT_ITEM_NAMES[panel]) - return pair + if self.REFERENCE_LOGIC.ENTITIES_BY_HEX[entity]["region"]: + region_name = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[entity]["region"]["name"] + entity_req = dnf_and([entity_req, frozenset({frozenset({region_name})})]) - def make_event_panel_lists(self): - """ - Special event panel data structures - """ + individual_entity_requirements.append(entity_req) - self.ALWAYS_EVENT_NAMES_BY_HEX[self.VICTORY_LOCATION] = "Victory" + overall_requirement |= dnf_and(individual_entity_requirements) - for region_name, connections in self.CONNECTIONS_BY_REGION_NAME.items(): - for connection in connections: - for panel_req in connection[1]: - for panel in panel_req: - if panel == "TrueOneWay": - continue + new_connections.append((connection[0], overall_requirement)) - if self.REFERENCE_LOGIC.CHECKS_BY_HEX[panel]["region"]["name"] != region_name: - self.EVENT_PANELS_FROM_REGIONS.add(panel) + self.CONNECTIONS_BY_REGION_NAME[region] = new_connections - self.EVENT_PANELS.update(self.EVENT_PANELS_FROM_PANELS) - self.EVENT_PANELS.update(self.EVENT_PANELS_FROM_REGIONS) + def make_event_item_pair(self, panel: str): + """ + Makes a pair of an event panel and its event item + """ + action = " Opened" if self.REFERENCE_LOGIC.ENTITIES_BY_HEX[panel]["entityType"] == "Door" else " Solved" + + name = self.REFERENCE_LOGIC.ENTITIES_BY_HEX[panel]["checkName"] + action + if panel not in self.EVENT_NAMES_BY_HEX: + warning("Panel \"" + name + "\" does not have an associated event name.") + self.EVENT_NAMES_BY_HEX[panel] = name + " Event" + pair = (name, self.EVENT_NAMES_BY_HEX[panel]) + return pair + + def make_event_panel_lists(self): + self.EVENT_NAMES_BY_HEX[self.VICTORY_LOCATION] = "Victory" - for always_hex, always_item in self.ALWAYS_EVENT_NAMES_BY_HEX.items(): - self.ALWAYS_EVENT_HEX_CODES.add(always_hex) - self.EVENT_PANELS.add(always_hex) - self.EVENT_ITEM_NAMES[always_hex] = always_item + for event_hex, event_name in self.EVENT_NAMES_BY_HEX.items(): + if event_hex in self.COMPLETELY_DISABLED_ENTITIES: + continue + self.EVENT_PANELS.add(event_hex) for panel in self.EVENT_PANELS: pair = self.make_event_item_pair(panel) self.EVENT_ITEM_PAIRS[pair[0]] = pair[1] - def __init__(self, world: MultiWorld, player: int, disabled_locations: Set[str], start_inv: Dict[str, int]): + def __init__(self, world: "WitnessWorld", disabled_locations: Set[str], start_inv: Dict[str, int]): self.YAML_DISABLED_LOCATIONS = disabled_locations self.YAML_ADDED_ITEMS = start_inv self.EVENT_PANELS_FROM_PANELS = set() self.EVENT_PANELS_FROM_REGIONS = set() + self.IRRELEVANT_BUT_NOT_DISABLED_ENTITIES = set() + self.THEORETICAL_ITEMS = set() self.THEORETICAL_ITEMS_NO_MULTI = set() - self.MULTI_AMOUNTS = dict() + self.MULTI_AMOUNTS = defaultdict(lambda: 1) self.MULTI_LISTS = dict() self.PROG_ITEMS_ACTUALLY_IN_THE_GAME_NO_MULTI = set() self.PROG_ITEMS_ACTUALLY_IN_THE_GAME = set() - self.DOOR_ITEMS_BY_ID: Dict[str, List[int]] = {} + self.DOOR_ITEMS_BY_ID: Dict[str, List[str]] = {} self.STARTING_INVENTORY = set() - self.DIFFICULTY = get_option_value(world, player, "puzzle_randomization") + self.DIFFICULTY = world.options.puzzle_randomization.value if self.DIFFICULTY == 0: self.REFERENCE_LOGIC = StaticWitnessLogic.sigma_normal @@ -441,106 +528,30 @@ def __init__(self, world: MultiWorld, player: int, disabled_locations: Set[str], # At the end, we will have EVENT_ITEM_PAIRS for all the necessary ones. self.EVENT_PANELS = set() self.EVENT_ITEM_PAIRS = dict() - self.ALWAYS_EVENT_HEX_CODES = set() - self.COMPLETELY_DISABLED_CHECKS = set() + self.DONT_MAKE_EVENTS = set() + self.COMPLETELY_DISABLED_ENTITIES = set() self.PRECOMPLETED_LOCATIONS = set() self.EXCLUDED_LOCATIONS = set() self.ADDED_CHECKS = set() self.VICTORY_LOCATION = "0x0356B" - self.EVENT_ITEM_NAMES = { - "0x09D9B": "Monastery Shutters Open", - "0x193A6": "Monastery Laser Panel Activates", - "0x00037": "Monastery Branch Panels Activate", - "0x0A079": "Access to Bunker Laser", - "0x0A3B5": "Door to Tutorial Discard Opens", - "0x00139": "Keep Hedges 1 Knowledge", - "0x019DC": "Keep Hedges 2 Knowledge", - "0x019E7": "Keep Hedges 3 Knowledge", - "0x01A0F": "Keep Hedges 4 Knowledge", - "0x033EA": "Pressure Plates 1 Knowledge", - "0x01BE9": "Pressure Plates 2 Knowledge", - "0x01CD3": "Pressure Plates 3 Knowledge", - "0x01D3F": "Pressure Plates 4 Knowledge", - "0x09F7F": "Mountain Access", - "0x0367C": "Quarry Laser Stoneworks Requirement Met", - "0x009A1": "Swamp Between Bridges Far 1 Activates", - "0x00006": "Swamp Cyan Water Drains", - "0x00990": "Swamp Between Bridges Near Row 1 Activates", - "0x0A8DC": "Intro 6 Activates", - "0x0000A": "Swamp Beyond Rotating Bridge 1 Access", - "0x09E86": "Mountain Floor 2 Blue Bridge Access", - "0x09ED8": "Mountain Floor 2 Yellow Bridge Access", - "0x0A3D0": "Quarry Laser Boathouse Requirement Met", - "0x00596": "Swamp Red Water Drains", - "0x00E3A": "Swamp Purple Water Drains", - "0x0343A": "Door to Symmetry Island Powers On", - "0xFFF00": "Mountain Bottom Floor Discard Turns On", - "0x17CA6": "All Boat Panels Turn On", - "0x17CDF": "All Boat Panels Turn On", - "0x09DB8": "All Boat Panels Turn On", - "0x17C95": "All Boat Panels Turn On", - "0x0A054": "Couch EP solvable", - "0x03BB0": "Town Church Lattice Vision From Outside", - "0x28AC1": "Town Wooden Rooftop Turns On", - "0x28A69": "Town Tower 1st Door Opens", - "0x28ACC": "Town Tower 2nd Door Opens", - "0x28AD9": "Town Tower 3rd Door Opens", - "0x28B39": "Town Tower 4th Door Opens", - "0x03675": "Quarry Stoneworks Ramp Activation From Above", - "0x03679": "Quarry Stoneworks Lift Lowering While Standing On It", - "0x2FAF6": "Tutorial Gate Secret Solution Knowledge", - "0x079DF": "Town Tall Hexagonal Turns On", - "0x17DA2": "Right Orange Bridge Fully Extended", - "0x19B24": "Shadows Intro Patterns Visible", - "0x2700B": "Open Door to Treehouse Laser House", - "0x00055": "Orchard Apple Trees 4 Turns On", - "0x17DDB": "Left Orange Bridge Fully Extended", - "0x03535": "Shipwreck Video Pattern Knowledge", - "0x03542": "Mountain Video Pattern Knowledge", - "0x0339E": "Desert Video Pattern Knowledge", - "0x03481": "Tutorial Video Pattern Knowledge", - "0x03702": "Jungle Video Pattern Knowledge", - "0x0356B": "Challenge Video Pattern Knowledge", - "0x0A15F": "Desert Laser Panel Shutters Open (1)", - "0x012D7": "Desert Laser Panel Shutters Open (2)", - "0x03613": "Treehouse Orange Bridge 13 Turns On", - "0x17DEC": "Treehouse Laser House Access Requirement", - "0x03C08": "Town Church Entry Opens", - "0x17D02": "Windmill Blades Spinning", - "0x0A0C9": "Cargo Box EP completable", - "0x09E39": "Pink Light Bridge Extended", - "0x17CC4": "Rails EP available", - "0x2896A": "Bridge Underside EP available", - "0x00064": "First Tunnel EP visible", - "0x03553": "Tutorial Video EPs availble", - "0x17C79": "Bunker Door EP available", - "0x275FF": "Stoneworks Light EPs available", - "0x17E2B": "Remaining Purple Sand EPs available", - "0x03852": "Ramp EPs requirement", - "0x334D8": "RGB panels & EPs solvable", - "0x03750": "Left Garden EP available", - "0x03C0C": "RGB Flowers EP requirement", - "0x01CD5": "Pressure Plates 3 EP requirement", - "0x3865F": "Ramp EPs access requirement", - } - self.ALWAYS_EVENT_NAMES_BY_HEX = { - "0x00509": "Symmetry Laser Activation", - "0x012FB": "Desert Laser Activation", + self.EVENT_NAMES_BY_HEX = { + "0x00509": "+1 Laser (Symmetry Laser)", + "0x012FB": "+1 Laser (Desert Laser)", "0x09F98": "Desert Laser Redirection", - "0x01539": "Quarry Laser Activation", - "0x181B3": "Shadows Laser Activation", - "0x014BB": "Keep Laser Activation", - "0x17C65": "Monastery Laser Activation", - "0x032F9": "Town Laser Activation", - "0x00274": "Jungle Laser Activation", - "0x0C2B2": "Bunker Laser Activation", - "0x00BF6": "Swamp Laser Activation", - "0x028A4": "Treehouse Laser Activation", - "0x09F7F": "Mountaintop Trap Door Turns On", - "0x17C34": "Mountain Access", + "0x01539": "+1 Laser (Quarry Laser)", + "0x181B3": "+1 Laser (Shadows Laser)", + "0x014BB": "+1 Laser (Keep Laser)", + "0x17C65": "+1 Laser (Monastery Laser)", + "0x032F9": "+1 Laser (Town Laser)", + "0x00274": "+1 Laser (Jungle Laser)", + "0x0C2B2": "+1 Laser (Bunker Laser)", + "0x00BF6": "+1 Laser (Swamp Laser)", + "0x028A4": "+1 Laser (Treehouse Laser)", + "0x09F7F": "Mountain Entry", + "0xFFF00": "Bottom Floor Discard Turns On", } - self.make_options_adjustments(world, player) + self.make_options_adjustments(world) self.make_dependency_reduced_checklist() self.make_event_panel_lists() diff --git a/worlds/witness/regions.py b/worlds/witness/regions.py index 0e15cafe10fd..2187010bac07 100644 --- a/worlds/witness/regions.py +++ b/worlds/witness/regions.py @@ -2,13 +2,17 @@ Defines Region for The Witness, assigns locations to them, and connects them with the proper requirements """ +from typing import FrozenSet, TYPE_CHECKING, Dict, Tuple, List -from BaseClasses import MultiWorld, Entrance +from BaseClasses import Entrance, Region +from Utils import KeyedDefaultDict from .static_logic import StaticWitnessLogic -from .Options import get_option_value from .locations import WitnessPlayerLocations, StaticWitnessLocations from .player_logic import WitnessPlayerLogic +if TYPE_CHECKING: + from . import WitnessWorld + class WitnessRegions: """Class that defines Witness Regions""" @@ -16,62 +20,81 @@ class WitnessRegions: locat = None logic = None - def make_lambda(self, panel_hex_to_solve_set, world, player, player_logic): + @staticmethod + def make_lambda(item_requirement: FrozenSet[FrozenSet[str]], world: "WitnessWorld"): + from .rules import _meets_item_requirements + """ Lambdas are made in a for loop, so the values have to be captured This function is for that purpose """ - return lambda state: state._witness_can_solve_panels( - panel_hex_to_solve_set, world, player, player_logic, self.locat - ) + return _meets_item_requirements(item_requirement, world) - def connect(self, world: MultiWorld, player: int, source: str, target: str, player_logic: WitnessPlayerLogic, - panel_hex_to_solve_set=frozenset({frozenset()}), backwards: bool = False): + def connect_if_possible(self, world: "WitnessWorld", source: str, target: str, req: FrozenSet[FrozenSet[str]], + regions_by_name: Dict[str, Region], backwards: bool = False): """ connect two regions and set the corresponding requirement """ - source_region = world.get_region(source, player) - target_region = world.get_region(target, player) + + # Remove any possibilities where being in the target region would be required anyway. + real_requirement = frozenset({option for option in req if target not in option}) + + # There are some connections that should only be done one way. If this is a backwards connection, check for that + if backwards: + real_requirement = frozenset({option for option in real_requirement if "TrueOneWay" not in option}) + + # Dissolve any "True" or "TrueOneWay" + real_requirement = frozenset({option - {"True", "TrueOneWay"} for option in real_requirement}) + + # If there is no way to actually use this connection, don't even bother making it. + if not real_requirement: + return + + # We don't need to check for the accessibility of the source region. + final_requirement = frozenset({option - frozenset({source}) for option in real_requirement}) + + source_region = regions_by_name[source] + target_region = regions_by_name[target] backwards = " Backwards" if backwards else "" + connection_name = source + " to " + target + backwards connection = Entrance( - player, - source + " to " + target + backwards, + world.player, + connection_name, source_region ) - connection.access_rule = self.make_lambda(panel_hex_to_solve_set, world, player, player_logic) + connection.access_rule = self.make_lambda(final_requirement, world) source_region.exits.append(connection) connection.connect(target_region) - def create_regions(self, world, player: int, player_logic: WitnessPlayerLogic): + self.created_entrances[(source, target)].append(connection) + + # Register any necessary indirect connections + mentioned_regions = { + single_unlock for option in final_requirement for single_unlock in option + if single_unlock in self.reference_logic.ALL_REGIONS_BY_NAME + } + + for dependent_region in mentioned_regions: + world.multiworld.register_indirect_condition(regions_by_name[dependent_region], connection) + + def create_regions(self, world: "WitnessWorld", player_logic: WitnessPlayerLogic): """ Creates all the regions for The Witness """ from . import create_region - world.regions += [ - create_region(world, player, 'Menu', self.locat, None, ["The Splashscreen?"]), - ] - - difficulty = get_option_value(world, player, "puzzle_randomization") - - if difficulty == 1: - reference_logic = StaticWitnessLogic.sigma_expert - elif difficulty == 0: - reference_logic = StaticWitnessLogic.sigma_normal - else: - reference_logic = StaticWitnessLogic.vanilla - all_locations = set() + regions_by_name = dict() - for region_name, region in reference_logic.ALL_REGIONS_BY_NAME.items(): + for region_name, region in self.reference_logic.ALL_REGIONS_BY_NAME.items(): locations_for_this_region = [ - reference_logic.CHECKS_BY_HEX[panel]["checkName"] for panel in region["panels"] - if reference_logic.CHECKS_BY_HEX[panel]["checkName"] in self.locat.CHECK_LOCATION_TABLE + self.reference_logic.ENTITIES_BY_HEX[panel]["checkName"] for panel in region["panels"] + if self.reference_logic.ENTITIES_BY_HEX[panel]["checkName"] in self.locat.CHECK_LOCATION_TABLE ] locations_for_this_region += [ StaticWitnessLocations.get_event_name(panel) for panel in region["panels"] @@ -80,34 +103,45 @@ def create_regions(self, world, player: int, player_logic: WitnessPlayerLogic): all_locations = all_locations | set(locations_for_this_region) - world.regions += [ - create_region(world, player, region_name, self.locat, locations_for_this_region) - ] + new_region = create_region(world, region_name, self.locat, locations_for_this_region) + + regions_by_name[region_name] = new_region - for region_name, region in reference_logic.ALL_REGIONS_BY_NAME.items(): + for region_name, region in self.reference_logic.ALL_REGIONS_BY_NAME.items(): for connection in player_logic.CONNECTIONS_BY_REGION_NAME[region_name]: - if connection[1] == frozenset({frozenset(["TrueOneWay"])}): - self.connect(world, player, region_name, connection[0], player_logic, frozenset({frozenset()})) + self.connect_if_possible(world, region_name, connection[0], connection[1], regions_by_name) + self.connect_if_possible(world, connection[0], region_name, connection[1], regions_by_name, True) + + # find regions that are completely disconnected from the start node and remove them + regions_to_check = {"Menu"} + reachable_regions = {"Menu"} + + while regions_to_check: + next_region = regions_to_check.pop() + region_obj = regions_by_name[next_region] + + for exit in region_obj.exits: + target = exit.connected_region + + if target.name in reachable_regions: continue - backwards_connections = set() + regions_to_check.add(target.name) + reachable_regions.add(target.name) - for subset in connection[1]: - if all({panel in player_logic.DOOR_ITEMS_BY_ID for panel in subset}): - if all({reference_logic.CHECKS_BY_HEX[panel]["id"] is None for panel in subset}): - backwards_connections.add(subset) + final_regions_list = [v for k, v in regions_by_name.items() if k in reachable_regions] - if backwards_connections: - self.connect( - world, player, connection[0], region_name, player_logic, - frozenset(backwards_connections), True - ) + world.multiworld.regions += final_regions_list - self.connect(world, player, region_name, connection[0], player_logic, connection[1]) + def __init__(self, locat: WitnessPlayerLocations, world: "WitnessWorld"): + difficulty = world.options.puzzle_randomization.value - world.get_entrance("The Splashscreen?", player).connect( - world.get_region('First Hallway', player) - ) + if difficulty == 0: + self.reference_logic = StaticWitnessLogic.sigma_normal + elif difficulty == 1: + self.reference_logic = StaticWitnessLogic.sigma_expert + elif difficulty == 2: + self.reference_logic = StaticWitnessLogic.vanilla - def __init__(self, locat: WitnessPlayerLocations): self.locat = locat + self.created_entrances: Dict[Tuple[str, str], List[Entrance]] = KeyedDefaultDict(lambda _: []) diff --git a/worlds/witness/rules.py b/worlds/witness/rules.py index 4cf3054af6fd..07fea23b14ba 100644 --- a/worlds/witness/rules.py +++ b/worlds/witness/rules.py @@ -3,223 +3,218 @@ depending on the items received """ -# pylint: disable=E1101 +from typing import TYPE_CHECKING, Callable, FrozenSet -from BaseClasses import MultiWorld +from BaseClasses import CollectionState from .player_logic import WitnessPlayerLogic -from .Options import is_option_enabled, get_option_value from .locations import WitnessPlayerLocations -from . import StaticWitnessLogic -from worlds.AutoWorld import LogicMixin +from . import StaticWitnessLogic, WitnessRegions from worlds.generic.Rules import set_rule +if TYPE_CHECKING: + from . import WitnessWorld -class WitnessLogic(LogicMixin): +laser_hexes = [ + "0x028A4", + "0x00274", + "0x032F9", + "0x01539", + "0x181B3", + "0x0C2B2", + "0x00509", + "0x00BF6", + "0x014BB", + "0x012FB", + "0x17C65", +] + + +def _has_laser(laser_hex: str, world: "WitnessWorld", player: int) -> Callable[[CollectionState], bool]: + if laser_hex == "0x012FB": + return lambda state: ( + _can_solve_panel(laser_hex, world, world.player, world.player_logic, world.locat)(state) + and state.has("Desert Laser Redirection", player) + ) + else: + return _can_solve_panel(laser_hex, world, world.player, world.player_logic, world.locat) + + +def _has_lasers(amount: int, world: "WitnessWorld") -> Callable[[CollectionState], bool]: + laser_lambdas = [] + + for laser_hex in laser_hexes: + has_laser_lambda = _has_laser(laser_hex, world, world.player) + + laser_lambdas.append(has_laser_lambda) + + return lambda state: sum(laser_lambda(state) for laser_lambda in laser_lambdas) >= amount + + +def _can_solve_panel(panel: str, world: "WitnessWorld", player: int, player_logic: WitnessPlayerLogic, + locat: WitnessPlayerLocations) -> Callable[[CollectionState], bool]: + """ + Determines whether a panel can be solved + """ + + panel_obj = player_logic.REFERENCE_LOGIC.ENTITIES_BY_HEX[panel] + entity_name = panel_obj["checkName"] + + if entity_name + " Solved" in locat.EVENT_LOCATION_TABLE: + return lambda state: state.has(player_logic.EVENT_ITEM_PAIRS[entity_name + " Solved"], player) + else: + return make_lambda(panel, world) + + +def _can_move_either_direction(state: CollectionState, source: str, target: str, regio: WitnessRegions) -> bool: + entrance_forward = regio.created_entrances[(source, target)] + entrance_backward = regio.created_entrances[(source, target)] + + return ( + any(entrance.can_reach(state) for entrance in entrance_forward) + or + any(entrance.can_reach(state) for entrance in entrance_backward) + ) + + +def _can_do_expert_pp2(state: CollectionState, world: "WitnessWorld") -> bool: + player = world.player + + hedge_2_access = ( + _can_move_either_direction(state, "Keep 2nd Maze", "Keep", world.regio) + ) + + hedge_3_access = ( + _can_move_either_direction(state, "Keep 3rd Maze", "Keep", world.regio) + or _can_move_either_direction(state, "Keep 3rd Maze", "Keep 2nd Maze", world.regio) + and hedge_2_access + ) + + hedge_4_access = ( + _can_move_either_direction(state, "Keep 4th Maze", "Keep", world.regio) + or _can_move_either_direction(state, "Keep 4th Maze", "Keep 3rd Maze", world.regio) + and hedge_3_access + ) + + hedge_access = ( + _can_move_either_direction(state, "Keep 4th Maze", "Keep Tower", world.regio) + and state.can_reach("Keep", "Region", player) + and hedge_4_access + ) + + backwards_to_fourth = ( + state.can_reach("Keep", "Region", player) + and _can_move_either_direction(state, "Keep 4th Pressure Plate", "Keep Tower", world.regio) + and ( + _can_move_either_direction(state, "Keep", "Keep Tower", world.regio) + or hedge_access + ) + ) + + shadows_shortcut = ( + state.can_reach("Main Island", "Region", player) + and _can_move_either_direction(state, "Keep 4th Pressure Plate", "Shadows", world.regio) + ) + + backwards_access = ( + _can_move_either_direction(state, "Keep 3rd Pressure Plate", "Keep 4th Pressure Plate", world.regio) + and (backwards_to_fourth or shadows_shortcut) + ) + + front_access = ( + _can_move_either_direction(state, "Keep 2nd Pressure Plate", "Keep", world.regio) + and state.can_reach("Keep", "Region", player) + ) + + return front_access and backwards_access + + +def _can_do_theater_to_tunnels(state: CollectionState, world: "WitnessWorld") -> bool: + direct_access = ( + _can_move_either_direction(state, "Tunnels", "Windmill Interior", world.regio) + and _can_move_either_direction(state, "Theater", "Windmill Interior", world.regio) + ) + + theater_from_town = ( + _can_move_either_direction(state, "Town", "Windmill Interior", world.regio) + and _can_move_either_direction(state, "Theater", "Windmill Interior", world.regio) + or _can_move_either_direction(state, "Town", "Theater", world.regio) + ) + + tunnels_from_town = ( + _can_move_either_direction(state, "Tunnels", "Windmill Interior", world.regio) + and _can_move_either_direction(state, "Town", "Windmill Interior", world.regio) + or _can_move_either_direction(state, "Tunnels", "Town", world.regio) + ) + + return direct_access or theater_from_town and tunnels_from_town + + +def _has_item(item: str, world: "WitnessWorld", player: int, + player_logic: WitnessPlayerLogic, locat: WitnessPlayerLocations) -> Callable[[CollectionState], bool]: + if item in player_logic.REFERENCE_LOGIC.ALL_REGIONS_BY_NAME: + return lambda state: state.can_reach(item, "Region", player) + if item == "7 Lasers": + laser_req = world.options.mountain_lasers.value + return _has_lasers(laser_req, world) + if item == "11 Lasers": + laser_req = world.options.challenge_lasers.value + return _has_lasers(laser_req, world) + elif item == "PP2 Weirdness": + return lambda state: _can_do_expert_pp2(state, world) + elif item == "Theater to Tunnels": + return lambda state: _can_do_theater_to_tunnels(state, world) + if item in player_logic.EVENT_PANELS: + return _can_solve_panel(item, world, player, player_logic, locat) + + prog_item = StaticWitnessLogic.get_parent_progressive_item(item) + return lambda state: state.has(prog_item, player, player_logic.MULTI_AMOUNTS[item]) + + +def _meets_item_requirements(requirements: FrozenSet[FrozenSet[str]], + world: "WitnessWorld") -> Callable[[CollectionState], bool]: """ - Logic macros that get reused + Checks whether item and panel requirements are met for + a panel """ - def _witness_has_lasers(self, world, player: int, amount: int) -> bool: - regular_lasers = not is_option_enabled(world, player, "shuffle_lasers") - - lasers = 0 - - place_names = [ - "Symmetry", "Desert", "Town", "Monastery", "Keep", - "Quarry", "Treehouse", "Jungle", "Bunker", "Swamp", "Shadows" - ] - - for place in place_names: - has_laser = self.has(place + " Laser", player) - - has_laser = has_laser or (regular_lasers and self.has(place + " Laser Activation", player)) - - if place == "Desert": - has_laser = has_laser and self.has("Desert Laser Redirection", player) - - lasers += int(has_laser) - - return lasers >= amount - - def _witness_can_solve_panel(self, panel, world, player, player_logic: WitnessPlayerLogic, locat): - """ - Determines whether a panel can be solved - """ - - panel_obj = StaticWitnessLogic.CHECKS_BY_HEX[panel] - check_name = panel_obj["checkName"] - - if (check_name + " Solved" in locat.EVENT_LOCATION_TABLE - and not self.has(player_logic.EVENT_ITEM_PAIRS[check_name + " Solved"], player)): - return False - if (check_name + " Solved" not in locat.EVENT_LOCATION_TABLE - and not self._witness_meets_item_requirements(panel, world, player, player_logic, locat)): - return False - return True - - def _witness_meets_item_requirements(self, panel, world, player, player_logic: WitnessPlayerLogic, locat): - """ - Checks whether item and panel requirements are met for - a panel - """ - - panel_req = player_logic.REQUIREMENTS_BY_HEX[panel] - - for option in panel_req: - if len(option) == 0: - return True - - valid_option = True - - for item in option: - if item == "7 Lasers": - laser_req = get_option_value(world, player, "mountain_lasers") - - if not self._witness_has_lasers(world, player, laser_req): - valid_option = False - break - elif item == "11 Lasers": - laser_req = get_option_value(world, player, "challenge_lasers") - - if not self._witness_has_lasers(world, player, laser_req): - valid_option = False - break - elif item == "PP2 Weirdness": - hedge_2_access = ( - self.can_reach("Keep 2nd Maze to Keep", "Entrance", player) - or self.can_reach("Keep to Keep 2nd Maze", "Entrance", player) - ) - - hedge_3_access = ( - self.can_reach("Keep 3rd Maze to Keep", "Entrance", player) - or self.can_reach("Keep 2nd Maze to Keep 3rd Maze", "Entrance", player) - and hedge_2_access - ) - - hedge_4_access = ( - self.can_reach("Keep 4th Maze to Keep", "Entrance", player) - or self.can_reach("Keep 3rd Maze to Keep 4th Maze", "Entrance", player) - and hedge_3_access - ) - - hedge_access = ( - self.can_reach("Keep 4th Maze to Keep Tower", "Entrance", player) - and self.can_reach("Keep", "Region", player) - and hedge_4_access - ) - - backwards_to_fourth = ( - self.can_reach("Keep", "Region", player) - and self.can_reach("Keep 4th Pressure Plate to Keep Tower", "Entrance", player) - and ( - self.can_reach("Keep Tower to Keep", "Entrance", player) - or hedge_access - ) - ) - - shadows_shortcut = ( - self.can_reach("Main Island", "Region", player) - and self.can_reach("Keep 4th Pressure Plate to Shadows", "Entrance", player) - ) - - backwards_access = ( - self.can_reach("Keep 3rd Pressure Plate to Keep 4th Pressure Plate", "Entrance", player) - and (backwards_to_fourth or shadows_shortcut) - ) - - front_access = ( - self.can_reach("Keep to Keep 2nd Pressure Plate", 'Entrance', player) - and self.can_reach("Keep", "Region", player) - ) - - if not (front_access and backwards_access): - valid_option = False - break - elif item == "Theater to Tunnels": - direct_access = ( - self.can_reach("Tunnels to Windmill Interior", "Entrance", player) - and self.can_reach("Windmill Interior to Theater", "Entrance", player) - ) - - theater_from_town = ( - self.can_reach("Town to Windmill Interior", "Entrance", player) - and self.can_reach("Windmill Interior to Theater", "Entrance", player) - or self.can_reach("Theater to Town", "Entrance", player) - ) - - tunnels_from_town = ( - self.can_reach("Tunnels to Windmill Interior", "Entrance", player) - and self.can_reach("Town to Windmill Interior", "Entrance", player) - or self.can_reach("Tunnels to Town", "Entrance", player) - ) - - if not (direct_access or theater_from_town and tunnels_from_town): - valid_option = False - break - elif item in player_logic.EVENT_PANELS: - if not self._witness_can_solve_panel(item, world, player, player_logic, locat): - valid_option = False - break - elif not self.has(item, player): - # The player doesn't have the item. Check to see if it's part of a progressive item and, if so, the - # player has enough of that. - prog_item = StaticWitnessLogic.get_parent_progressive_item(item) - if prog_item is item or not self.has(prog_item, player, player_logic.MULTI_AMOUNTS[item]): - valid_option = False - break - - if valid_option: - return True - - return False - - def _witness_can_solve_panels(self, panel_hex_to_solve_set, world, player, player_logic: WitnessPlayerLogic, locat): - """ - Checks whether a set of panels can be solved. - """ - - for option in panel_hex_to_solve_set: - if len(option) == 0: - return True - - valid_option = True - - for panel in option: - if not self._witness_can_solve_panel(panel, world, player, player_logic, locat): - valid_option = False - break - - if valid_option: - return True - return False - - -def make_lambda(check_hex, world, player, player_logic, locat): + lambda_conversion = [ + [_has_item(item, world, world.player, world.player_logic, world.locat) for item in subset] + for subset in requirements + ] + + return lambda state: any( + all(condition(state) for condition in sub_requirement) + for sub_requirement in lambda_conversion + ) + + +def make_lambda(entity_hex: str, world: "WitnessWorld") -> Callable[[CollectionState], bool]: """ Lambdas are created in a for loop so values need to be captured """ - return lambda state: state._witness_meets_item_requirements( - check_hex, world, player, player_logic, locat - ) + entity_req = world.player_logic.REQUIREMENTS_BY_HEX[entity_hex] + + return _meets_item_requirements(entity_req, world) -def set_rules(world: MultiWorld, player: int, player_logic: WitnessPlayerLogic, locat: WitnessPlayerLocations): +def set_rules(world: "WitnessWorld"): """ Sets all rules for all locations """ - for location in locat.CHECK_LOCATION_TABLE: + for location in world.locat.CHECK_LOCATION_TABLE: real_location = location - if location in locat.EVENT_LOCATION_TABLE: + if location in world.locat.EVENT_LOCATION_TABLE: real_location = location[:-7] - panel = StaticWitnessLogic.CHECKS_BY_NAME[real_location] - check_hex = panel["checkHex"] + associated_entity = world.player_logic.REFERENCE_LOGIC.ENTITIES_BY_NAME[real_location] + entity_hex = associated_entity["entity_hex"] + + rule = make_lambda(entity_hex, world) - rule = make_lambda(check_hex, world, player, player_logic, locat) + location = world.multiworld.get_location(location, world.player) - set_rule(world.get_location(location, player), rule) + set_rule(location, rule) - world.completion_condition[player] = \ - lambda state: state.has('Victory', player) + world.multiworld.completion_condition[world.player] = lambda state: state.has('Victory', world.player) diff --git a/worlds/witness/settings/Door_Panel_Shuffle.txt b/worlds/witness/settings/Door_Panel_Shuffle.txt deleted file mode 100644 index 80195cfb9968..000000000000 --- a/worlds/witness/settings/Door_Panel_Shuffle.txt +++ /dev/null @@ -1,31 +0,0 @@ -Items: -Glass Factory Entry (Panel) -Symmetry Island Lower (Panel) -Symmetry Island Upper (Panel) -Desert Light Room Entry (Panel) -Desert Flood Controls (Panel) -Quarry Stoneworks Entry (Panel) -Quarry Stoneworks Ramp Controls (Panel) -Quarry Stoneworks Lift Controls (Panel) -Quarry Boathouse Ramp Height Control (Panel) -Quarry Boathouse Ramp Horizontal Control (Panel) -Shadows Door Timer (Panel) -Monastery Entry Left (Panel) -Monastery Entry Right (Panel) -Town Tinted Glass Door (Panel) -Town Church Entry (Panel) -Town Maze Panel (Drop-Down Staircase) (Panel) -Windmill Entry (Panel) -Treehouse First & Second Doors (Panel) -Treehouse Third Door (Panel) -Treehouse Laser House Door Timer (Panel) -Treehouse Drawbridge (Panel) -Jungle Popup Wall (Panel) -Bunker Entry (Panel) -Bunker Tinted Glass Door (Panel) -Bunker Elevator Control (Panel) -Swamp Entry (Panel) -Swamp Sliding Bridge (Panel) -Swamp Rotating Bridge (Panel) -Swamp Maze Control (Panel) -Boat \ No newline at end of file diff --git a/worlds/witness/settings/Door_Shuffle/Boat.txt b/worlds/witness/settings/Door_Shuffle/Boat.txt new file mode 100644 index 000000000000..6494b455cf79 --- /dev/null +++ b/worlds/witness/settings/Door_Shuffle/Boat.txt @@ -0,0 +1,2 @@ +Items: +Boat \ No newline at end of file diff --git a/worlds/witness/settings/Door_Shuffle/Complex_Additional_Panels.txt b/worlds/witness/settings/Door_Shuffle/Complex_Additional_Panels.txt new file mode 100644 index 000000000000..79bda7ea2281 --- /dev/null +++ b/worlds/witness/settings/Door_Shuffle/Complex_Additional_Panels.txt @@ -0,0 +1,25 @@ +Items: +Desert Flood Controls (Panel) +Desert Light Control (Panel) +Quarry Elevator Control (Panel) +Quarry Stoneworks Ramp Controls (Panel) +Quarry Stoneworks Lift Controls (Panel) +Quarry Boathouse Ramp Height Control (Panel) +Quarry Boathouse Ramp Horizontal Control (Panel) +Quarry Boathouse Hook Control (Panel) +Monastery Shutters Control (Panel) +Town Maze Rooftop Bridge (Panel) +Town RGB Control (Panel) +Windmill Turn Control (Panel) +Theater Video Input (Panel) +Bunker Drop-Down Door Controls (Panel) +Bunker Elevator Control (Panel) +Swamp Sliding Bridge (Panel) +Swamp Rotating Bridge (Panel) +Swamp Long Bridge (Panel) +Swamp Maze Controls (Panel) +Mountain Floor 1 Light Bridge (Panel) +Mountain Floor 2 Light Bridge Near (Panel) +Mountain Floor 2 Light Bridge Far (Panel) +Mountain Floor 2 Elevator Control (Panel) +Caves Elevator Controls (Panel) \ No newline at end of file diff --git a/worlds/witness/settings/Door_Shuffle/Complex_Door_Panels.txt b/worlds/witness/settings/Door_Shuffle/Complex_Door_Panels.txt new file mode 100644 index 000000000000..472403962065 --- /dev/null +++ b/worlds/witness/settings/Door_Shuffle/Complex_Door_Panels.txt @@ -0,0 +1,38 @@ +Items: +Glass Factory Entry (Panel) +Tutorial Outpost Entry (Panel) +Tutorial Outpost Exit (Panel) +Symmetry Island Lower (Panel) +Symmetry Island Upper (Panel) +Desert Light Room Entry (Panel) +Desert Flood Room Entry (Panel) +Quarry Entry 1 (Panel) +Quarry Entry 2 (Panel) +Quarry Stoneworks Entry (Panel) +Shadows Door Timer (Panel) +Keep Hedge Maze 1 (Panel) +Keep Hedge Maze 2 (Panel) +Keep Hedge Maze 3 (Panel) +Keep Hedge Maze 4 (Panel) +Monastery Entry Left (Panel) +Monastery Entry Right (Panel) +Town RGB House Entry (Panel) +Town Church Entry (Panel) +Town Maze Stairs (Panel) +Town Windmill Entry (Panel) +Town Cargo Box Entry (Panel) +Theater Entry (Panel) +Theater Exit (Panel) +Treehouse First & Second Doors (Panel) +Treehouse Third Door (Panel) +Treehouse Laser House Door Timer (Panel) +Treehouse Drawbridge (Panel) +Jungle Popup Wall (Panel) +Bunker Entry (Panel) +Bunker Tinted Glass Door (Panel) +Swamp Entry (Panel) +Swamp Platform Shortcut (Panel) +Caves Entry (Panel) +Challenge Entry (Panel) +Tunnels Entry (Panel) +Tunnels Town Shortcut (Panel) \ No newline at end of file diff --git a/worlds/witness/settings/Doors_Complex.txt b/worlds/witness/settings/Door_Shuffle/Complex_Doors.txt similarity index 94% rename from worlds/witness/settings/Doors_Complex.txt rename to worlds/witness/settings/Door_Shuffle/Complex_Doors.txt index d8da6783b0c5..2f2b32171079 100644 --- a/worlds/witness/settings/Doors_Complex.txt +++ b/worlds/witness/settings/Door_Shuffle/Complex_Doors.txt @@ -12,6 +12,7 @@ Desert Light Room Entry (Door) Desert Pond Room Entry (Door) Desert Flood Room Entry (Door) Desert Elevator Room Entry (Door) +Desert Elevator (Door) Quarry Entry 1 (Door) Quarry Entry 2 (Door) Quarry Stoneworks Entry (Door) @@ -39,13 +40,13 @@ Keep Pressure Plates 3 Exit (Door) Keep Pressure Plates 4 Exit (Door) Keep Shadows Shortcut (Door) Keep Tower Shortcut (Door) -Monastery Shortcut (Door) +Monastery Laser Shortcut (Door) Monastery Entry Inner (Door) Monastery Entry Outer (Door) Monastery Garden Entry (Door) Town Cargo Box Entry (Door) Town Wooden Roof Stairs (Door) -Town Tinted Glass Door +Town RGB House Entry (Door) Town Church Entry (Door) Town Maze Stairs (Door) Town Windmill Entry (Door) @@ -59,7 +60,7 @@ Theater Exit Left (Door) Theater Exit Right (Door) Jungle Bamboo Laser Shortcut (Door) Jungle Popup Wall (Door) -River Monastery Shortcut (Door) +River Monastery Garden Shortcut (Door) Bunker Entry (Door) Bunker Tinted Glass Door Bunker UV Room Entry (Door) @@ -115,7 +116,7 @@ Quarry Stoneworks Entry Right Panel Quarry Stoneworks Entry Left Panel Quarry Stoneworks Side Exit Panel Quarry Stoneworks Roof Exit Panel -Quarry Stoneworks Stair Control +Quarry Stoneworks Stairs Panel Quarry Boathouse Second Barrier Panel Shadows Door Timer Inside Shadows Door Timer Outside @@ -133,15 +134,15 @@ Keep Pressure Plates 3 Keep Pressure Plates 4 Keep Shadows Shortcut Panel Keep Tower Shortcut Panel -Monastery Shortcut Panel +Monastery Laser Shortcut Panel Monastery Entry Left Monastery Entry Right Monastery Outside 3 Town Cargo Box Entry Panel Town Wooden Roof Lower Row 5 -Town Tinted Glass Door Panel +Town RGB House Entry Panel Town Church Entry Panel -Town Maze Stair Control +Town Maze Panel Town Windmill Entry Panel Town Sound Room Right Town Red Rooftop 5 @@ -153,7 +154,7 @@ Theater Exit Left Panel Theater Exit Right Panel Jungle Laser Shortcut Panel Jungle Popup Wall Control -River Monastery Shortcut Panel +River Monastery Garden Shortcut Panel Bunker Entry Panel Bunker Tinted Glass Door Panel Bunker Glass Room 3 @@ -171,10 +172,10 @@ Swamp Laser Shortcut Right Panel Treehouse First Door Panel Treehouse Second Door Panel Treehouse Third Door Panel -Treehouse Bridge Control +Treehouse Drawbridge Panel Treehouse Left Orange Bridge 15 Treehouse Right Orange Bridge 12 -Treehouse Laser House Door Timer Outside Control +Treehouse Laser House Door Timer Outside Treehouse Laser House Door Timer Inside Mountain Floor 1 Left Row 7 Mountain Floor 1 Right Row 5 diff --git a/worlds/witness/settings/Door_Shuffle/Elevators_Come_To_You.txt b/worlds/witness/settings/Door_Shuffle/Elevators_Come_To_You.txt new file mode 100644 index 000000000000..78d245f9f0b5 --- /dev/null +++ b/worlds/witness/settings/Door_Shuffle/Elevators_Come_To_You.txt @@ -0,0 +1,11 @@ +New Connections: +Quarry - Quarry Elevator - TrueOneWay +Outside Quarry - Quarry Elevator - TrueOneWay +Outside Bunker - Bunker Elevator - TrueOneWay +Outside Swamp - Swamp Long Bridge - TrueOneWay +Swamp Near Boat - Swamp Long Bridge - TrueOneWay +Town Red Rooftop - Town Maze Rooftop - TrueOneWay + + +Requirement Changes: +0x035DE - 0x17E2B - True \ No newline at end of file diff --git a/worlds/witness/settings/Door_Shuffle/Simple_Additional_Panels.txt b/worlds/witness/settings/Door_Shuffle/Simple_Additional_Panels.txt new file mode 100644 index 000000000000..c16ce737629a --- /dev/null +++ b/worlds/witness/settings/Door_Shuffle/Simple_Additional_Panels.txt @@ -0,0 +1,11 @@ +Items: +Desert Control Panels +Quarry Elevator Control (Panel) +Quarry Stoneworks Control Panels +Quarry Boathouse Control Panels +Monastery Shutters Control (Panel) +Town Control Panels +Windmill & Theater Control Panels +Bunker Control Panels +Swamp Control Panels +Mountain & Caves Control Panels \ No newline at end of file diff --git a/worlds/witness/settings/Doors_Simple.txt b/worlds/witness/settings/Door_Shuffle/Simple_Doors.txt similarity index 74% rename from worlds/witness/settings/Doors_Simple.txt rename to worlds/witness/settings/Door_Shuffle/Simple_Doors.txt index 309874b131b9..91a7132ec113 100644 --- a/worlds/witness/settings/Doors_Simple.txt +++ b/worlds/witness/settings/Door_Shuffle/Simple_Doors.txt @@ -1,44 +1,33 @@ Items: -Glass Factory Back Wall (Door) -Quarry Boathouse Dock (Door) Outside Tutorial Outpost Doors -Glass Factory Entry (Door) +Glass Factory Doors Symmetry Island Doors Orchard Gates -Desert Doors -Quarry Main Entry -Quarry Stoneworks Entry (Door) -Quarry Stoneworks Shortcuts -Quarry Boathouse Barriers -Shadows Timed Door -Shadows Laser Room Door -Shadows Barriers +Desert Doors & Elevator +Quarry Entry Doors +Quarry Stoneworks Doors +Quarry Boathouse Doors +Shadows Laser Room Doors +Shadows Lower Doors Keep Hedge Maze Doors Keep Pressure Plates Doors Keep Shortcuts -Monastery Entry +Monastery Entry Doors Monastery Shortcuts Town Doors Town Tower Doors -Theater Entry (Door) -Theater Exit -Jungle & River Shortcuts -Jungle Popup Wall (Door) +Windmill & Theater Doors +Jungle Doors Bunker Doors Swamp Doors -Swamp Laser Shortcut (Door) +Swamp Shortcuts Swamp Water Pumps Treehouse Entry Doors -Treehouse Drawbridge (Door) -Treehouse Laser House Entry (Door) -Mountain Floor 1 Exit (Door) -Mountain Floor 2 Stairs & Doors -Mountain Bottom Floor Giant Puzzle Exit (Door) -Mountain Bottom Floor Final Room Entry (Door) -Mountain Bottom Floor Doors to Caves -Caves Doors to Challenge -Caves Exits to Main Island -Challenge Tunnels Entry (Door) +Treehouse Upper Doors +Mountain Floor 1 & 2 Doors +Mountain Bottom Floor Doors +Caves Doors +Caves Shortcuts Tunnels Doors Added Locations: @@ -60,7 +49,7 @@ Quarry Stoneworks Entry Right Panel Quarry Stoneworks Entry Left Panel Quarry Stoneworks Side Exit Panel Quarry Stoneworks Roof Exit Panel -Quarry Stoneworks Stair Control +Quarry Stoneworks Stairs Panel Quarry Boathouse Second Barrier Panel Shadows Door Timer Inside Shadows Door Timer Outside @@ -78,15 +67,15 @@ Keep Pressure Plates 3 Keep Pressure Plates 4 Keep Shadows Shortcut Panel Keep Tower Shortcut Panel -Monastery Shortcut Panel +Monastery Laser Shortcut Panel Monastery Entry Left Monastery Entry Right Monastery Outside 3 Town Cargo Box Entry Panel Town Wooden Roof Lower Row 5 -Town Tinted Glass Door Panel +Town RGB House Entry Panel Town Church Entry Panel -Town Maze Stair Control +Town Maze Panel Town Windmill Entry Panel Town Sound Room Right Town Red Rooftop 5 @@ -98,7 +87,7 @@ Theater Exit Left Panel Theater Exit Right Panel Jungle Laser Shortcut Panel Jungle Popup Wall Control -River Monastery Shortcut Panel +River Monastery Garden Shortcut Panel Bunker Entry Panel Bunker Tinted Glass Door Panel Bunker Glass Room 3 @@ -116,10 +105,10 @@ Swamp Laser Shortcut Right Panel Treehouse First Door Panel Treehouse Second Door Panel Treehouse Third Door Panel -Treehouse Bridge Control +Treehouse Drawbridge Panel Treehouse Left Orange Bridge 15 Treehouse Right Orange Bridge 12 -Treehouse Laser House Door Timer Outside Control +Treehouse Laser House Door Timer Outside Treehouse Laser House Door Timer Inside Mountain Floor 1 Left Row 7 Mountain Floor 1 Right Row 5 diff --git a/worlds/witness/settings/Door_Shuffle/Simple_Panels.txt b/worlds/witness/settings/Door_Shuffle/Simple_Panels.txt new file mode 100644 index 000000000000..79da154491b7 --- /dev/null +++ b/worlds/witness/settings/Door_Shuffle/Simple_Panels.txt @@ -0,0 +1,22 @@ +Items: +Symmetry Island Panels +Tutorial Outpost Panels +Desert Panels +Quarry Outside Panels +Quarry Stoneworks Panels +Quarry Boathouse Panels +Keep Hedge Maze Panels +Monastery Panels +Town Church & RGB House Panels +Town Maze Panels +Windmill & Theater Panels +Town Cargo Box Entry (Panel) +Treehouse Panels +Bunker Panels +Swamp Panels +Mountain Panels +Caves Panels +Tunnels Panels +Glass Factory Entry (Panel) +Shadows Door Timer (Panel) +Jungle Popup Wall (Panel) \ No newline at end of file diff --git a/worlds/witness/settings/Doors_Max.txt b/worlds/witness/settings/Doors_Max.txt deleted file mode 100644 index e722b61ca0c0..000000000000 --- a/worlds/witness/settings/Doors_Max.txt +++ /dev/null @@ -1,211 +0,0 @@ -Items: -Outside Tutorial Outpost Path (Door) -Outside Tutorial Outpost Entry (Door) -Outside Tutorial Outpost Exit (Door) -Glass Factory Entry (Door) -Glass Factory Back Wall (Door) -Symmetry Island Lower (Door) -Symmetry Island Upper (Door) -Orchard First Gate (Door) -Orchard Second Gate (Door) -Desert Light Room Entry (Door) -Desert Pond Room Entry (Door) -Desert Flood Room Entry (Door) -Desert Elevator Room Entry (Door) -Quarry Entry 1 (Door) -Quarry Entry 2 (Door) -Quarry Stoneworks Entry (Door) -Quarry Stoneworks Side Exit (Door) -Quarry Stoneworks Roof Exit (Door) -Quarry Stoneworks Stairs (Door) -Quarry Boathouse Dock (Door) -Quarry Boathouse First Barrier (Door) -Quarry Boathouse Second Barrier (Door) -Shadows Timed Door -Shadows Laser Entry Right (Door) -Shadows Laser Entry Left (Door) -Shadows Quarry Barrier (Door) -Shadows Ledge Barrier (Door) -Keep Hedge Maze 1 Exit (Door) -Keep Pressure Plates 1 Exit (Door) -Keep Hedge Maze 2 Shortcut (Door) -Keep Hedge Maze 2 Exit (Door) -Keep Hedge Maze 3 Shortcut (Door) -Keep Hedge Maze 3 Exit (Door) -Keep Hedge Maze 4 Shortcut (Door) -Keep Hedge Maze 4 Exit (Door) -Keep Pressure Plates 2 Exit (Door) -Keep Pressure Plates 3 Exit (Door) -Keep Pressure Plates 4 Exit (Door) -Keep Shadows Shortcut (Door) -Keep Tower Shortcut (Door) -Monastery Shortcut (Door) -Monastery Entry Inner (Door) -Monastery Entry Outer (Door) -Monastery Garden Entry (Door) -Town Cargo Box Entry (Door) -Town Wooden Roof Stairs (Door) -Town Tinted Glass Door -Town Church Entry (Door) -Town Maze Stairs (Door) -Town Windmill Entry (Door) -Town RGB House Stairs (Door) -Town Tower Second (Door) -Town Tower First (Door) -Town Tower Fourth (Door) -Town Tower Third (Door) -Theater Entry (Door) -Theater Exit Left (Door) -Theater Exit Right (Door) -Jungle Bamboo Laser Shortcut (Door) -Jungle Popup Wall (Door) -River Monastery Shortcut (Door) -Bunker Entry (Door) -Bunker Tinted Glass Door -Bunker UV Room Entry (Door) -Bunker Elevator Room Entry (Door) -Swamp Entry (Door) -Swamp Between Bridges First Door -Swamp Platform Shortcut Door -Swamp Cyan Water Pump (Door) -Swamp Between Bridges Second Door -Swamp Red Water Pump (Door) -Swamp Red Underwater Exit (Door) -Swamp Blue Water Pump (Door) -Swamp Purple Water Pump (Door) -Swamp Laser Shortcut (Door) -Treehouse First (Door) -Treehouse Second (Door) -Treehouse Third (Door) -Treehouse Drawbridge (Door) -Treehouse Laser House Entry (Door) -Mountain Floor 1 Exit (Door) -Mountain Floor 2 Staircase Near (Door) -Mountain Floor 2 Exit (Door) -Mountain Floor 2 Staircase Far (Door) -Mountain Bottom Floor Giant Puzzle Exit (Door) -Mountain Bottom Floor Final Room Entry (Door) -Mountain Bottom Floor Rock (Door) -Caves Entry (Door) -Caves Pillar Door -Caves Mountain Shortcut (Door) -Caves Swamp Shortcut (Door) -Challenge Entry (Door) -Challenge Tunnels Entry (Door) -Tunnels Theater Shortcut (Door) -Tunnels Desert Shortcut (Door) -Tunnels Town Shortcut (Door) - -Desert Flood Controls (Panel) -Quarry Stoneworks Ramp Controls (Panel) -Quarry Stoneworks Lift Controls (Panel) -Quarry Boathouse Ramp Height Control (Panel) -Quarry Boathouse Ramp Horizontal Control (Panel) -Bunker Elevator Control (Panel) -Swamp Sliding Bridge (Panel) -Swamp Rotating Bridge (Panel) -Swamp Maze Control (Panel) -Boat - -Added Locations: -Outside Tutorial Outpost Entry Panel -Outside Tutorial Outpost Exit Panel -Glass Factory Entry Panel -Glass Factory Back Wall 5 -Symmetry Island Lower Panel -Symmetry Island Upper Panel -Orchard Apple Tree 3 -Orchard Apple Tree 5 -Desert Light Room Entry Panel -Desert Light Room 3 -Desert Flood Room Entry Panel -Desert Flood Room 6 -Quarry Entry 1 Panel -Quarry Entry 2 Panel -Quarry Stoneworks Entry Right Panel -Quarry Stoneworks Entry Left Panel -Quarry Stoneworks Side Exit Panel -Quarry Stoneworks Roof Exit Panel -Quarry Stoneworks Stair Control -Quarry Boathouse Second Barrier Panel -Shadows Door Timer Inside -Shadows Door Timer Outside -Shadows Far 8 -Shadows Near 5 -Shadows Intro 3 -Shadows Intro 5 -Keep Hedge Maze 1 -Keep Pressure Plates 1 -Keep Hedge Maze 2 -Keep Hedge Maze 3 -Keep Hedge Maze 4 -Keep Pressure Plates 2 -Keep Pressure Plates 3 -Keep Pressure Plates 4 -Keep Shadows Shortcut Panel -Keep Tower Shortcut Panel -Monastery Shortcut Panel -Monastery Entry Left -Monastery Entry Right -Monastery Outside 3 -Town Cargo Box Entry Panel -Town Wooden Roof Lower Row 5 -Town Tinted Glass Door Panel -Town Church Entry Panel -Town Maze Stair Control -Town Windmill Entry Panel -Town Sound Room Right -Town Red Rooftop 5 -Town Church Lattice -Town Tall Hexagonal -Town Wooden Rooftop -Windmill Theater Entry Panel -Theater Exit Left Panel -Theater Exit Right Panel -Jungle Laser Shortcut Panel -Jungle Popup Wall Control -River Monastery Shortcut Panel -Bunker Entry Panel -Bunker Tinted Glass Door Panel -Bunker Glass Room 3 -Bunker UV Room 2 -Swamp Entry Panel -Swamp Platform Row 4 -Swamp Platform Shortcut Right Panel -Swamp Blue Underwater 5 -Swamp Between Bridges Near Row 4 -Swamp Cyan Underwater 5 -Swamp Red Underwater 4 -Swamp Beyond Rotating Bridge 4 -Swamp Beyond Rotating Bridge 4 -Swamp Laser Shortcut Right Panel -Treehouse First Door Panel -Treehouse Second Door Panel -Treehouse Third Door Panel -Treehouse Bridge Control -Treehouse Left Orange Bridge 15 -Treehouse Right Orange Bridge 12 -Treehouse Laser House Door Timer Outside Control -Treehouse Laser House Door Timer Inside -Mountain Floor 1 Left Row 7 -Mountain Floor 1 Right Row 5 -Mountain Floor 1 Back Row 3 -Mountain Floor 1 Trash Pillar 2 -Mountain Floor 2 Near Row 5 -Mountain Floor 2 Light Bridge Controller Near -Mountain Floor 2 Light Bridge Controller Far -Mountain Floor 2 Far Row 6 -Mountain Bottom Floor Giant Puzzle -Mountain Bottom Floor Final Room Entry Left -Mountain Bottom Floor Final Room Entry Right -Mountain Bottom Floor Discard -Mountain Bottom Floor Rock Control -Mountain Bottom Floor Caves Entry Panel -Caves Lone Pillar -Caves Mountain Shortcut Panel -Caves Swamp Shortcut Panel -Caves Challenge Entry Panel -Challenge Tunnels Entry Panel -Tunnels Theater Shortcut Panel -Tunnels Desert Shortcut Panel -Tunnels Town Shortcut Panel \ No newline at end of file diff --git a/worlds/witness/settings/EP_Shuffle/EP_All.txt b/worlds/witness/settings/EP_Shuffle/EP_All.txt index 51af5e38502e..939adc36e814 100644 --- a/worlds/witness/settings/EP_Shuffle/EP_All.txt +++ b/worlds/witness/settings/EP_Shuffle/EP_All.txt @@ -1,136 +1,136 @@ Added Locations: -0x0332B -0x03367 -0x28B8A -0x037B6 -0x037B2 -0x000F7 -0x3351D -0x0053C -0x00771 -0x335C8 -0x335C9 -0x337F8 -0x037BB -0x220E4 -0x220E5 -0x334B9 -0x334BC -0x22106 -0x0A14C -0x0A14D -0x03ABC -0x03ABE -0x03AC0 -0x03AC4 -0x03AC5 -0x03BE2 -0x03BE3 -0x0A409 -0x006E5 -0x006E6 -0x006E7 -0x034A7 -0x034AD -0x034AF -0x03DAB -0x03DAC -0x03DAD -0x03E01 -0x289F4 -0x289F5 -0x0053D -0x0053E -0x00769 -0x33721 -0x220A7 -0x220BD -0x03B22 -0x03B23 -0x03B24 -0x03B25 -0x03A79 -0x28ABD -0x28ABE -0x3388F -0x28B29 -0x28B2A -0x018B6 -0x033BE -0x033BF -0x033DD -0x033E5 -0x28AE9 -0x3348F -0x001A3 -0x335AE -0x000D3 -0x035F5 -0x09D5D -0x09D5E -0x09D63 -0x3370E -0x035DE -0x03601 -0x03603 -0x03D0D -0x3369A -0x336C8 -0x33505 -0x03A9E -0x016B2 -0x3365F -0x03731 -0x036CE -0x03C07 -0x03A93 -0x03AA6 -0x3397C -0x0105D -0x0A304 -0x035CB -0x035CF -0x28A7B -0x005F6 -0x00859 -0x17CB9 -0x28A4A -0x334B6 -0x0069D -0x00614 -0x28A4C -0x289CF -0x289D1 -0x33692 -0x03E77 -0x03E7C -0x035C7 -0x01848 -0x03D06 -0x33530 -0x33600 -0x28A2F -0x28A37 -0x334A3 -0x3352F -0x33857 -0x33879 -0x03C19 -0x28B30 -0x035C9 -0x03335 -0x03412 -0x038A6 -0x038AA -0x03E3F -0x03E40 -0x28B8E -0x28B91 -0x03BCE -0x03BCF -0x03BD1 -0x339B6 -0x33A20 -0x33A29 -0x33A2A -0x33B06 \ No newline at end of file +0x0332B (Glass Factory Black Line Reflection EP) +0x03367 (Glass Factory Black Line EP) +0x28B8A (Vase EP) +0x037B6 (Windmill First Blade EP) +0x037B2 (Windmill Second Blade EP) +0x000F7 (Windmill Third Blade EP) +0x3351D (Sand Snake EP) +0x0053C (Facade Right EP) +0x00771 (Facade Left EP) +0x335C8 (Stairs Left EP) +0x335C9 (Stairs Right EP) +0x337F8 (Flood Room EP) +0x037BB (Elevator EP) +0x220E4 (Broken Wall Straight EP) +0x220E5 (Broken Wall Bend EP) +0x334B9 (Shore EP) +0x334BC (Island EP) +0x22106 (Desert EP) +0x0A14C (Pond Room Near Reflection EP) +0x0A14D (Pond Room Far Reflection EP) +0x03ABC (Long Arch Moss EP) +0x03ABE (Straight Left Moss EP) +0x03AC0 (Pop-up Wall Moss EP) +0x03AC4 (Short Arch Moss EP) +0x03AC5 (Green Leaf Moss EP) +0x03BE2 (Monastery Garden Left EP) +0x03BE3 (Monastery Garden Right EP) +0x0A409 (Monastery Wall EP) +0x006E5 (Facade Left Near EP) +0x006E6 (Facade Left Far Short EP) +0x006E7 (Facade Left Far Long EP) +0x034A7 (Left Shutter EP) +0x034AD (Middle Shutter EP) +0x034AF (Right Shutter EP) +0x03DAB (Facade Right Near EP) +0x03DAC (Facade Left Stairs EP) +0x03DAD (Facade Right Stairs EP) +0x03E01 (Grass Stairs EP) +0x289F4 (Entrance EP) +0x289F5 (Tree Halo EP) +0x0053D (Rock Shadow EP) +0x0053E (Sand Shadow EP) +0x00769 (Burned House Beach EP) +0x33721 (Buoy EP) +0x220A7 (Right Orange Bridge EP) +0x220BD (Both Orange Bridges EP) +0x03B22 (Circle Far EP) +0x03B23 (Circle Left EP) +0x03B24 (Circle Near EP) +0x03B25 (Shipwreck CCW Underside EP) +0x03A79 (Stern EP) +0x28ABD (Rope Inner EP) +0x28ABE (Rope Outer EP) +0x3388F (Couch EP) +0x28B29 (Shipwreck Green EP) +0x28B2A (Shipwreck CW Underside EP) +0x018B6 (Pressure Plates 4 Right Exit EP) +0x033BE (Pressure Plates 1 EP) +0x033BF (Pressure Plates 2 EP) +0x033DD (Pressure Plates 3 EP) +0x033E5 (Pressure Plates 4 Left Exit EP) +0x28AE9 (Path EP) +0x3348F (Hedges EP) +0x001A3 (River Shape EP) +0x335AE (Cloud Cycle EP) +0x000D3 (Green Room Flowers EP) +0x035F5 (Tinted Door EP) +0x09D5D (Yellow Bridge EP) +0x09D5E (Blue Bridge EP) +0x09D63 (Pink Bridge EP) +0x3370E (Arch Black EP) +0x035DE (Purple Sand Bottom EP) +0x03601 (Purple Sand Top EP) +0x03603 (Purple Sand Middle EP) +0x03D0D (Bunker Yellow Line EP) +0x3369A (Arch White Left EP) +0x336C8 (Arch White Right EP) +0x33505 (Bush EP) +0x03A9E (Purple Underwater Right EP) +0x016B2 (Rotating Bridge CCW EP) +0x3365F (Boat EP) +0x03731 (Long Bridge Side EP) +0x036CE (Rotating Bridge CW EP) +0x03C07 (Apparent River EP) +0x03A93 (Purple Underwater Left EP) +0x03AA6 (Cyan Underwater Sliding Bridge EP) +0x3397C (Skylight EP) +0x0105D (Sliding Bridge Left EP) +0x0A304 (Sliding Bridge Right EP) +0x035CB (Bamboo CCW EP) +0x035CF (Bamboo CW EP) +0x28A7B (Quarry Stoneworks Rooftop Vent EP) +0x005F6 (Hook EP) +0x00859 (Moving Ramp EP) +0x17CB9 (Railroad EP) +0x28A4A (Shore EP) +0x334B6 (Entrance Pipe EP) +0x0069D (Ramp EP) +0x00614 (Lift EP) +0x28A4C (Sand Pile EP) +0x289CF (Rock Line EP) +0x289D1 (Rock Line Reflection EP) +0x33692 (Brown Bridge EP) +0x03E77 (Red Flowers EP) +0x03E7C (Purple Flowers EP) +0x035C7 (Tractor EP) +0x01848 (EP) +0x03D06 (Garden EP) +0x33530 (Cloud EP) +0x33600 (Patio Flowers EP) +0x28A2F (Town Sewer EP) +0x28A37 (Town Long Sewer EP) +0x334A3 (Path EP) +0x3352F (Gate EP) +0x33857 (Tutorial EP) +0x33879 (Tutorial Reflection EP) +0x03C19 (Tutorial Moss EP) +0x28B30 (Water EP) +0x035C9 (Cargo Box EP) +0x03335 (Tower Underside Third EP) +0x03412 (Tower Underside Fourth EP) +0x038A6 (Tower Underside First EP) +0x038AA (Tower Underside Second EP) +0x03E3F (RGB House Red EP) +0x03E40 (RGB House Green EP) +0x28B8E (Maze Bridge Underside EP) +0x28B91 (Thundercloud EP) +0x03BCE (Black Line Tower EP) +0x03BCF (Black Line Redirect EP) +0x03BD1 (Black Line Church EP) +0x339B6 (Eclipse EP) +0x33A20 (Theater Flowers EP) +0x33A29 (Window EP) +0x33A2A (Door EP) +0x33B06 (Church EP) diff --git a/worlds/witness/settings/EP_Shuffle/EP_Easy.txt b/worlds/witness/settings/EP_Shuffle/EP_Easy.txt index 939055169a75..6f9c80fc0a94 100644 --- a/worlds/witness/settings/EP_Shuffle/EP_Easy.txt +++ b/worlds/witness/settings/EP_Shuffle/EP_Easy.txt @@ -1,14 +1,17 @@ -Precompleted Locations: -0x339B6 -0x335AE -0x3388F -0x33A20 -0x037B2 -0x000F7 -0x28B29 -0x33857 -0x33879 -0x016B2 -0x036CE -0x03B25 -0x28B2A \ No newline at end of file +Disabled Locations: +0x339B6 (Eclipse EP) +0x335AE (Cloud Cycle EP) +0x3388F (Couch EP) +0x33A20 (Theater Flowers EP) +0x037B2 (Windmill Second Blade EP) +0x000F7 (Windmill Third Blade EP) +0x28B29 (Shipwreck Green EP) +0x33857 (Tutorial EP) +0x33879 (Tutorial Reflection EP) +0x016B2 (Rotating Bridge CCW EP) +0x036CE (Rotating Bridge CW EP) +0x03B25 (Shipwreck CCW Underside EP) +0x28B2A (Shipwreck CW Underside EP) +0x09D63 (Mountain Pink Bridge EP) +0x09D5E (Mountain Blue Bridge EP) +0x09D5D (Mountain Yellow Bridge EP) diff --git a/worlds/witness/settings/EP_Shuffle/EP_NoCavesEPs.txt b/worlds/witness/settings/EP_Shuffle/EP_NoCavesEPs.txt deleted file mode 100644 index 3bb318a69ee9..000000000000 --- a/worlds/witness/settings/EP_Shuffle/EP_NoCavesEPs.txt +++ /dev/null @@ -1,5 +0,0 @@ -Precompleted Locations: -0x3397C -0x33A20 -0x3352F -0x28B30 \ No newline at end of file diff --git a/worlds/witness/settings/EP_Shuffle/EP_NoEclipse.txt b/worlds/witness/settings/EP_Shuffle/EP_NoEclipse.txt index d41badfa1802..f241957c823a 100644 --- a/worlds/witness/settings/EP_Shuffle/EP_NoEclipse.txt +++ b/worlds/witness/settings/EP_Shuffle/EP_NoEclipse.txt @@ -1,2 +1,2 @@ -Precompleted Locations: -0x339B6 \ No newline at end of file +Disabled Locations: +0x339B6 (Eclipse EP) diff --git a/worlds/witness/settings/EP_Shuffle/EP_NoMountainEPs.txt b/worlds/witness/settings/EP_Shuffle/EP_NoMountainEPs.txt deleted file mode 100644 index 3558d77ad888..000000000000 --- a/worlds/witness/settings/EP_Shuffle/EP_NoMountainEPs.txt +++ /dev/null @@ -1,4 +0,0 @@ -Precompleted Locations: -0x09D63 -0x09D5D -0x09D5E \ No newline at end of file diff --git a/worlds/witness/settings/EP_Shuffle/EP_Sides.txt b/worlds/witness/settings/EP_Shuffle/EP_Sides.txt index 1da52ffb8959..82ab63329500 100644 --- a/worlds/witness/settings/EP_Shuffle/EP_Sides.txt +++ b/worlds/witness/settings/EP_Shuffle/EP_Sides.txt @@ -1,34 +1,35 @@ Added Locations: -0xFFE00 -0xFFE01 -0xFFE02 -0xFFE03 -0xFFE04 -0xFFE10 -0xFFE11 -0xFFE12 -0xFFE13 -0xFFE14 -0xFFE15 -0xFFE20 -0xFFE21 -0xFFE22 -0xFFE23 -0xFFE24 -0xFFE25 -0xFFE30 -0xFFE31 -0xFFE32 -0xFFE33 -0xFFE34 -0xFFE35 -0xFFE40 -0xFFE41 -0xFFE42 -0xFFE43 -0xFFE50 -0xFFE51 -0xFFE52 -0xFFE53 -0xFFE54 -0xFFE55 \ No newline at end of file +0xFFE00 (Desert Obelisk Side 1) +0xFFE01 (Desert Obelisk Side 2) +0xFFE02 (Desert Obelisk Side 3) +0xFFE03 (Desert Obelisk Side 4) +0xFFE04 (Desert Obelisk Side 5) +0xFFE10 (Monastery Obelisk Side 1) +0xFFE11 (Monastery Obelisk Side 2) +0xFFE12 (Monastery Obelisk Side 3) +0xFFE13 (Monastery Obelisk Side 4) +0xFFE14 (Monastery Obelisk Side 5) +0xFFE15 (Monastery Obelisk Side 6) +0xFFE20 (Treehouse Obelisk Side 1) +0xFFE21 (Treehouse Obelisk Side 2) +0xFFE22 (Treehouse Obelisk Side 3) +0xFFE23 (Treehouse Obelisk Side 4) +0xFFE24 (Treehouse Obelisk Side 5) +0xFFE25 (Treehouse Obelisk Side 6) +0xFFE30 (River Obelisk Side 1) +0xFFE31 (River Obelisk Side 2) +0xFFE32 (River Obelisk Side 3) +0xFFE33 (River Obelisk Side 4) +0xFFE34 (River Obelisk Side 5) +0xFFE35 (River Obelisk Side 6) +0xFFE40 (Quarry Obelisk Side 1) +0xFFE41 (Quarry Obelisk Side 2) +0xFFE42 (Quarry Obelisk Side 3) +0xFFE43 (Quarry Obelisk Side 4) +0xFFE44 (Quarry Obelisk Side 5) +0xFFE50 (Town Obelisk Side 1) +0xFFE51 (Town Obelisk Side 2) +0xFFE52 (Town Obelisk Side 3) +0xFFE53 (Town Obelisk Side 4) +0xFFE54 (Town Obelisk Side 5) +0xFFE55 (Town Obelisk Side 6) diff --git a/worlds/witness/settings/EP_Shuffle/EP_Videos.txt b/worlds/witness/settings/EP_Shuffle/EP_Videos.txt deleted file mode 100644 index c4aaca13a676..000000000000 --- a/worlds/witness/settings/EP_Shuffle/EP_Videos.txt +++ /dev/null @@ -1,6 +0,0 @@ -Precompleted Locations: -0x339B6 -0x33A29 -0x33A2A -0x33B06 -0x33A20 \ No newline at end of file diff --git a/worlds/witness/settings/Early_Caves.txt b/worlds/witness/settings/Early_Caves.txt new file mode 100644 index 000000000000..48c8056bc7b6 --- /dev/null +++ b/worlds/witness/settings/Early_Caves.txt @@ -0,0 +1,6 @@ +Items: +Caves Shortcuts + +Remove Items: +Caves Mountain Shortcut (Door) +Caves Swamp Shortcut (Door) \ No newline at end of file diff --git a/worlds/witness/settings/Early_UTM.txt b/worlds/witness/settings/Early_Caves_Start.txt similarity index 65% rename from worlds/witness/settings/Early_UTM.txt rename to worlds/witness/settings/Early_Caves_Start.txt index b04aa3d33916..a16a6d02bb9f 100644 --- a/worlds/witness/settings/Early_UTM.txt +++ b/worlds/witness/settings/Early_Caves_Start.txt @@ -1,8 +1,8 @@ Items: -Caves Exits to Main Island +Caves Shortcuts Starting Inventory: -Caves Exits to Main Island +Caves Shortcuts Remove Items: Caves Mountain Shortcut (Door) diff --git a/worlds/witness/settings/Disable_Unrandomized.txt b/worlds/witness/settings/Exclusions/Disable_Unrandomized.txt similarity index 70% rename from worlds/witness/settings/Disable_Unrandomized.txt rename to worlds/witness/settings/Exclusions/Disable_Unrandomized.txt index 3cd7ec1fb5eb..2419bde06c14 100644 --- a/worlds/witness/settings/Disable_Unrandomized.txt +++ b/worlds/witness/settings/Exclusions/Disable_Unrandomized.txt @@ -2,16 +2,20 @@ Event Items: Monastery Laser Activation - 0x00A5B,0x17CE7,0x17FA9 Bunker Laser Activation - 0x00061,0x17D01,0x17C42 Shadows Laser Activation - 0x00021,0x17D28,0x17C71 +Town Tower 4th Door Opens - 0x17CFB,0x3C12B,0x17CF7 +Jungle Popup Wall Lifts - 0x17FA0,0x17D27,0x17F9B,0x17CAB Requirement Changes: 0x17C65 - 0x00A5B | 0x17CE7 | 0x17FA9 0x0C2B2 - 0x00061 | 0x17D01 | 0x17C42 0x181B3 - 0x00021 | 0x17D28 | 0x17C71 -0x28B39 - True - Reflection 0x17CAB - True - True +0x17CA4 - True - True +0x1475B - 0x17FA0 | 0x17D27 | 0x17F9B | 0x17CAB 0x2779A - 0x17CFB | 0x3C12B | 0x17CF7 Disabled Locations: +0x28B39 (Town Tall Hexagonal) 0x03505 (Tutorial Gate Close) 0x0C335 (Tutorial Pillar) 0x0C373 (Tutorial Patio Floor) @@ -25,6 +29,11 @@ Disabled Locations: 0x00055 (Orchard Apple Tree 3) 0x032F7 (Orchard Apple Tree 4) 0x032FF (Orchard Apple Tree 5) +0x334DB (Door Timer Outside) +0x334DC (Door Timer Inside) +0x19B24 (Timed Door) - 0x334DB +0x194B2 (Laser Entry Right) +0x19665 (Laser Entry Left) 0x198B5 (Shadows Intro 1) 0x198BD (Shadows Intro 2) 0x198BF (Shadows Intro 3) @@ -47,11 +56,22 @@ Disabled Locations: 0x197E8 (Shadows Near 4) 0x197E5 (Shadows Near 5) 0x19650 (Shadows Laser) +0x19865 (Quarry Barrier) +0x0A2DF (Quarry Barrier 2) +0x1855B (Ledge Barrier) +0x19ADE (Ledge Barrier 2) 0x00139 (Keep Hedge Maze 1) 0x019DC (Keep Hedge Maze 2) 0x019E7 (Keep Hedge Maze 3) 0x01A0F (Keep Hedge Maze 4) 0x0360E (Laser Hedges) +0x01954 (Hedge 1 Exit) +0x018CE (Hedge 2 Shortcut) +0x019D8 (Hedge 2 Exit) +0x019B5 (Hedge 3 Shortcut) +0x019E6 (Hedge 3 Exit) +0x0199A (Hedge 4 Shortcut) +0x01A0E (Hedge 4 Exit) 0x03307 (First Gate) 0x03313 (Second Gate) 0x0C128 (Entry Inner) @@ -61,16 +81,20 @@ Disabled Locations: 0x00290 (Monastery Outside 1) 0x00038 (Monastery Outside 2) 0x00037 (Monastery Outside 3) +0x03750 (Garden Entry) +0x09D9B (Monastery Shutters Control) 0x193A7 (Monastery Inside 1) 0x193AA (Monastery Inside 2) 0x193AB (Monastery Inside 3) 0x193A6 (Monastery Inside 4) -0x17CA4 (Monastery Laser) +0x17CA4 (Monastery Laser Panel) +0x0364E (Monastery Laser Shortcut Door) +0x03713 (Monastery Laser Shortcut Panel) 0x18590 (Transparent) - True - Symmetry & Environment 0x28AE3 (Vines) - 0x18590 - Shadows Follow & Environment 0x28938 (Apple Tree) - 0x28AE3 - Environment 0x079DF (Triple Exit) - 0x28938 - Shadows Avoid & Environment & Reflection -0x28B39 (Tall Hexagonal) - 0x079DF & 0x2896A - Reflection +0x00815 (Theater Video Input) 0x03553 (Theater Tutorial Video) 0x03552 (Theater Desert Video) 0x0354E (Theater Jungle Video) @@ -84,7 +108,8 @@ Disabled Locations: 0x0070F (Second Row 2) 0x0087D (Second Row 3) 0x002C7 (Second Row 4) -0x17CAA (Monastery Shortcut Panel) +0x17CAA (Monastery Garden Shortcut Panel) +0x0CF2A (Monastery Garden Shortcut) 0x0C2A4 (Bunker Entry) 0x17C79 (Tinted Glass Door) 0x0C2A3 (UV Room Entry) @@ -110,19 +135,16 @@ Disabled Locations: 0x09DE0 (Bunker Laser) 0x0A079 (Bunker Elevator Control) -0x17CAA (River Garden Entry Panel) - -Precompleted Locations: -0x034A7 -0x034AD -0x034AF -0x339B6 -0x33A29 -0x33A2A -0x33B06 -0x3352F -0x33600 -0x035F5 -0x000D3 -0x33A20 -0x03BE2 +0x034A7 (Monastery Left Shutter EP) +0x034AD (Monastery Middle Shutter EP) +0x034AF (Monastery Right Shutter EP) +0x339B6 (Theater Eclipse EP) +0x33A29 (Theater Window EP) +0x33A2A (Theater Door EP) +0x33B06 (Theater Church EP) +0x3352F (Tutorial Gate EP) +0x33600 (Tutorial Patio Flowers EP) +0x035F5 (Bunker Tinted Door EP) +0x000D3 (Bunker Green Room Flowers EP) +0x33A20 (Theater Flowers EP) +0x03BE2 (Monastery Garden Left EP) diff --git a/worlds/witness/settings/Exclusions/Discards.txt b/worlds/witness/settings/Exclusions/Discards.txt new file mode 100644 index 000000000000..e46d1dd82b1b --- /dev/null +++ b/worlds/witness/settings/Exclusions/Discards.txt @@ -0,0 +1,15 @@ +Disabled Locations: +0x17CFB (Outside Tutorial Discard) +0x3C12B (Glass Factory Discard) +0x17CE7 (Desert Discard) +0x17CF0 (Quarry Discard) +0x17D27 (Keep Discard) +0x17D28 (Shipwreck Discard) +0x17D01 (Town Cargo Box Discard) +0x17C71 (Town Rooftop Discard) +0x17CF7 (Theater Discard) +0x17F9B (Jungle Discard) +0x17FA9 (Treehouse Green Bridge Discard) +0x17C42 (Mountainside Discard) +0x17F93 (Mountain Floor 2 Elevator Discard) +0x17FA0 (Treehouse Laser Discard) diff --git a/worlds/witness/settings/Exclusions/Vaults.txt b/worlds/witness/settings/Exclusions/Vaults.txt new file mode 100644 index 000000000000..f23a13183326 --- /dev/null +++ b/worlds/witness/settings/Exclusions/Vaults.txt @@ -0,0 +1,31 @@ +Disabled Locations: +0x033D4 (Outside Tutorial Vault) +0x03481 (Outside Tutorial Vault Box) +0x033D0 (Outside Tutorial Vault Door) +0x0CC7B (Desert Vault) +0x0339E (Desert Vault Box) +0x03444 (Desert Vault Door) +0x00AFB (Shipwreck Vault) +0x03535 (Shipwreck Vault Box) +0x17BB4 (Shipwreck Vault Door) +0x15ADD (River Vault) +0x03702 (River Vault Box) +0x15287 (River Vault Door) +0x002A6 (Mountainside Vault) +0x03542 (Mountainside Vault Box) +0x00085 (Mountainside Vault Door) +0x2FAF6 (Tunnels Vault Box) +0x00815 (Theater Video Input) +0x03553 (Theater Tutorial Video) +0x03552 (Theater Desert Video) +0x0354E (Theater Jungle Video) +0x03549 (Theater Challenge Video) +0x0354F (Theater Shipwreck Video) +0x03545 (Theater Mountain Video) +0x03505 (Tutorial Gate Close) +0x339B6 (Theater clipse EP) +0x33A29 (Theater Window EP) +0x33A2A (Theater Door EP) +0x33B06 (Theater Church EP) +0x33A20 (Theater Flowers EP) +0x3352F (Tutorial Gate EP) diff --git a/worlds/witness/settings/Postgame/Beyond_Challenge.txt b/worlds/witness/settings/Postgame/Beyond_Challenge.txt new file mode 100644 index 000000000000..5cd20b6a5e40 --- /dev/null +++ b/worlds/witness/settings/Postgame/Beyond_Challenge.txt @@ -0,0 +1,4 @@ +Disabled Locations: +0x03549 (Challenge Video) + +0x339B6 (Eclipse EP) diff --git a/worlds/witness/settings/Postgame/Bottom_Floor_Discard.txt b/worlds/witness/settings/Postgame/Bottom_Floor_Discard.txt new file mode 100644 index 000000000000..8f7d6a257a53 --- /dev/null +++ b/worlds/witness/settings/Postgame/Bottom_Floor_Discard.txt @@ -0,0 +1,2 @@ +Disabled Locations: +0x17FA2 (Mountain Bottom Floor Discard) diff --git a/worlds/witness/settings/Postgame/Bottom_Floor_Discard_NonDoors.txt b/worlds/witness/settings/Postgame/Bottom_Floor_Discard_NonDoors.txt new file mode 100644 index 000000000000..5ea7c578d8bf --- /dev/null +++ b/worlds/witness/settings/Postgame/Bottom_Floor_Discard_NonDoors.txt @@ -0,0 +1,6 @@ +Disabled Locations: +0x17FA2 (Mountain Bottom Floor Discard) +0x17F33 (Rock Open Door) +0x00FF8 (Caves Entry Panel) +0x334E1 (Rock Control) +0x2D77D (Caves Entry Door) diff --git a/worlds/witness/settings/Postgame/Caves.txt b/worlds/witness/settings/Postgame/Caves.txt new file mode 100644 index 000000000000..aadb4c3f96e7 --- /dev/null +++ b/worlds/witness/settings/Postgame/Caves.txt @@ -0,0 +1,65 @@ +Disabled Locations: +0x335AB (Elevator Inside Control) +0x335AC (Elevator Upper Outside Control) +0x3369D (Elevator Lower Outside Control) +0x00190 (Blue Tunnel Right First 1) +0x00558 (Blue Tunnel Right First 2) +0x00567 (Blue Tunnel Right First 3) +0x006FE (Blue Tunnel Right First 4) +0x01A0D (Blue Tunnel Left First 1) +0x008B8 (Blue Tunnel Left Second 1) +0x00973 (Blue Tunnel Left Second 2) +0x0097B (Blue Tunnel Left Second 3) +0x0097D (Blue Tunnel Left Second 4) +0x0097E (Blue Tunnel Left Second 5) +0x00994 (Blue Tunnel Right Second 1) +0x334D5 (Blue Tunnel Right Second 2) +0x00995 (Blue Tunnel Right Second 3) +0x00996 (Blue Tunnel Right Second 4) +0x00998 (Blue Tunnel Right Second 5) +0x009A4 (Blue Tunnel Left Third 1) +0x018A0 (Blue Tunnel Right Third 1) +0x00A72 (Blue Tunnel Left Fourth 1) +0x32962 (First Floor Left) +0x32966 (First Floor Grounded) +0x01A31 (First Floor Middle) +0x00B71 (First Floor Right) +0x288EA (First Wooden Beam) +0x288FC (Second Wooden Beam) +0x289E7 (Third Wooden Beam) +0x288AA (Fourth Wooden Beam) +0x17FB9 (Left Upstairs Single) +0x0A16B (Left Upstairs Left Row 1) +0x0A2CE (Left Upstairs Left Row 2) +0x0A2D7 (Left Upstairs Left Row 3) +0x0A2DD (Left Upstairs Left Row 4) +0x0A2EA (Left Upstairs Left Row 5) +0x0008F (Right Upstairs Left Row 1) +0x0006B (Right Upstairs Left Row 2) +0x0008B (Right Upstairs Left Row 3) +0x0008C (Right Upstairs Left Row 4) +0x0008A (Right Upstairs Left Row 5) +0x00089 (Right Upstairs Left Row 6) +0x0006A (Right Upstairs Left Row 7) +0x0006C (Right Upstairs Left Row 8) +0x00027 (Right Upstairs Right Row 1) +0x00028 (Right Upstairs Right Row 2) +0x00029 (Right Upstairs Right Row 3) +0x021D7 (Mountain Shortcut Panel) +0x2D73F (Mountain Shortcut Door) +0x17CF2 (Swamp Shortcut Panel) +0x2D859 (Swamp Shortcut Door) +0x039B4 (Tunnels Entry Panel) +0x0348A (Tunnels Entry Door) +0x2FAF6 (Vault Box) +0x27732 (Tunnels Theater Shortcut Panel) +0x27739 (Tunnels Theater Shortcut Door) +0x2773D (Tunnels Desert Shortcut Panel) +0x27263 (Tunnels Desert Shortcut Door) +0x09E85 (Tunnels Town Shortcut Panel) +0x09E87 (Tunnels Town Shortcut Door) + +0x3397C (Skylight EP) +0x28B30 (Water EP) +0x33A20 (Theater Flowers EP) +0x3352F (Gate EP) diff --git a/worlds/witness/settings/Postgame/Challenge_Vault_Box.txt b/worlds/witness/settings/Postgame/Challenge_Vault_Box.txt new file mode 100644 index 000000000000..d65900418c61 --- /dev/null +++ b/worlds/witness/settings/Postgame/Challenge_Vault_Box.txt @@ -0,0 +1,3 @@ +Disabled Locations: +0x0356B (Challenge Vault Box) +0x04D75 (Vault Door) diff --git a/worlds/witness/settings/Postgame/Mountain_Lower.txt b/worlds/witness/settings/Postgame/Mountain_Lower.txt new file mode 100644 index 000000000000..354e3feb82c3 --- /dev/null +++ b/worlds/witness/settings/Postgame/Mountain_Lower.txt @@ -0,0 +1,27 @@ +Disabled Locations: +0x17F93 (Elevator Discard) +0x09EEB (Elevator Control Panel) +0x09FC1 (Giant Puzzle Bottom Left) +0x09F8E (Giant Puzzle Bottom Right) +0x09F01 (Giant Puzzle Top Right) +0x09EFF (Giant Puzzle Top Left) +0x09FDA (Giant Puzzle) +0x09F89 (Exit Door) +0x01983 (Final Room Entry Left) +0x01987 (Final Room Entry Right) +0x0C141 (Final Room Entry Door) +0x0383A (Right Pillar 1) +0x09E56 (Right Pillar 2) +0x09E5A (Right Pillar 3) +0x33961 (Right Pillar 4) +0x0383D (Left Pillar 1) +0x0383F (Left Pillar 2) +0x03859 (Left Pillar 3) +0x339BB (Left Pillar 4) +0x3D9A6 (Elevator Door Closer Left) +0x3D9A7 (Elevator Door Close Right) +0x3C113 (Elevator Entry Left) +0x3C114 (Elevator Entry Right) +0x3D9AA (Back Wall Left) +0x3D9A8 (Back Wall Right) +0x3D9A9 (Elevator Start) diff --git a/worlds/witness/settings/Postgame/Mountain_Upper.txt b/worlds/witness/settings/Postgame/Mountain_Upper.txt new file mode 100644 index 000000000000..e2b0765f533c --- /dev/null +++ b/worlds/witness/settings/Postgame/Mountain_Upper.txt @@ -0,0 +1,41 @@ +Disabled Locations: +0x17C34 (Mountain Entry Panel) +0x09E39 (Light Bridge Controller) +0x09E7A (Right Row 1) +0x09E71 (Right Row 2) +0x09E72 (Right Row 3) +0x09E69 (Right Row 4) +0x09E7B (Right Row 5) +0x09E73 (Left Row 1) +0x09E75 (Left Row 2) +0x09E78 (Left Row 3) +0x09E79 (Left Row 4) +0x09E6C (Left Row 5) +0x09E6F (Left Row 6) +0x09E6B (Left Row 7) +0x33AF5 (Back Row 1) +0x33AF7 (Back Row 2) +0x09F6E (Back Row 3) +0x09EAD (Trash Pillar 1) +0x09EAF (Trash Pillar 2) +0x09E54 (Mountain Floor 1 Exit Door) +0x09FD3 (Near Row 1) +0x09FD4 (Near Row 2) +0x09FD6 (Near Row 3) +0x09FD7 (Near Row 4) +0x09FD8 (Near Row 5) +0x09FFB (Staircase Near Door) +0x09EDD (Elevator Room Entry Door) +0x09E86 (Light Bridge Controller Near) +0x09FCC (Far Row 1) +0x09FCE (Far Row 2) +0x09FCF (Far Row 3) +0x09FD0 (Far Row 4) +0x09FD1 (Far Row 5) +0x09FD2 (Far Row 6) +0x09E07 (Staircase Far Door) +0x09ED8 (Light Bridge Controller Far) + +0x09D63 (Pink Bridge EP) +0x09D5D (Yellow Bridge EP) +0x09D5E (Blue Bridge EP) diff --git a/worlds/witness/settings/Postgame/Path_To_Challenge.txt b/worlds/witness/settings/Postgame/Path_To_Challenge.txt new file mode 100644 index 000000000000..3f9239cc4832 --- /dev/null +++ b/worlds/witness/settings/Postgame/Path_To_Challenge.txt @@ -0,0 +1,30 @@ +Disabled Locations: +0x0356B (Vault Box) +0x04D75 (Vault Door) +0x17F33 (Rock Open Door) +0x00FF8 (Caves Entry Panel) +0x334E1 (Rock Control) +0x2D77D (Caves Entry Door) +0x09DD5 (Lone Pillar) +0x019A5 (Caves Pillar Door) +0x0A16E (Challenge Entry Panel) +0x0A19A (Challenge Entry Door) +0x0A332 (Start Timer) +0x0088E (Small Basic) +0x00BAF (Big Basic) +0x00BF3 (Square) +0x00C09 (Maze Map) +0x00CDB (Stars and Dots) +0x0051F (Symmetry) +0x00524 (Stars and Shapers) +0x00CD4 (Big Basic 2) +0x00CB9 (Choice Squares Right) +0x00CA1 (Choice Squares Middle) +0x00C80 (Choice Squares Left) +0x00C68 (Choice Squares 2 Right) +0x00C59 (Choice Squares 2 Middle) +0x00C22 (Choice Squares 2 Left) +0x034F4 (Maze Hidden 1) +0x034EC (Maze Hidden 2) +0x1C31A (Dots Pillar) +0x1C319 (Squares Pillar) diff --git a/worlds/witness/static_logic.py b/worlds/witness/static_logic.py index 8dc2a05de56d..29c171d45c33 100644 --- a/worlds/witness/static_logic.py +++ b/worlds/witness/static_logic.py @@ -73,31 +73,34 @@ def read_logic_file(self, lines): location_id = line_split.pop(0) - check_name_full = line_split.pop(0) + entity_name_full = line_split.pop(0) - check_hex = check_name_full[0:7] - check_name = check_name_full[9:-1] + entity_hex = entity_name_full[0:7] + entity_name = entity_name_full[9:-1] required_panel_lambda = line_split.pop(0) - full_check_name = current_region["shortName"] + " " + check_name + full_entity_name = current_region["shortName"] + " " + entity_name if location_id == "Door" or location_id == "Laser": - self.CHECKS_BY_HEX[check_hex] = { - "checkName": full_check_name, - "checkHex": check_hex, - "region": current_region, + self.ENTITIES_BY_HEX[entity_hex] = { + "checkName": full_entity_name, + "entity_hex": entity_hex, + "region": None, "id": None, - "panelType": location_id + "entityType": location_id } - self.CHECKS_BY_NAME[self.CHECKS_BY_HEX[check_hex]["checkName"]] = self.CHECKS_BY_HEX[check_hex] + self.ENTITIES_BY_NAME[self.ENTITIES_BY_HEX[entity_hex]["checkName"]] = self.ENTITIES_BY_HEX[entity_hex] - self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[check_hex] = { + self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = { "panels": parse_lambda(required_panel_lambda) } - current_region["panels"].append(check_hex) + # Lasers and Doors exist in a region, but don't have a regional *requirement* + # If a laser is activated, you don't need to physically walk up to it for it to count + # As such, logically, they behave more as if they were part of the "Entry" region + self.ALL_REGIONS_BY_NAME["Entry"]["panels"].append(entity_hex) continue required_item_lambda = line_split.pop(0) @@ -108,18 +111,18 @@ def read_logic_file(self, lines): "Laser Pressure Plates", "Desert Laser Redirect" } - is_vault_or_video = "Vault" in check_name or "Video" in check_name + is_vault_or_video = "Vault" in entity_name or "Video" in entity_name - if "Discard" in check_name: + if "Discard" in entity_name: location_type = "Discard" - elif is_vault_or_video or check_name == "Tutorial Gate Close": + elif is_vault_or_video or entity_name == "Tutorial Gate Close": location_type = "Vault" - elif check_name in laser_names: + elif entity_name in laser_names: location_type = "Laser" - elif "Obelisk Side" in check_name: + elif "Obelisk Side" in entity_name: location_type = "Obelisk Side" - full_check_name = check_name - elif "EP" in check_name: + full_entity_name = entity_name + elif "EP" in entity_name: location_type = "EP" else: location_type = "General" @@ -140,32 +143,35 @@ def read_logic_file(self, lines): eps_ints = {int(h, 16) for h in eps} - self.OBELISK_SIDE_ID_TO_EP_HEXES[int(check_hex, 16)] = eps_ints + self.OBELISK_SIDE_ID_TO_EP_HEXES[int(entity_hex, 16)] = eps_ints for ep_hex in eps: - self.EP_TO_OBELISK_SIDE[ep_hex] = check_hex + self.EP_TO_OBELISK_SIDE[ep_hex] = entity_hex - self.CHECKS_BY_HEX[check_hex] = { - "checkName": full_check_name, - "checkHex": check_hex, + self.ENTITIES_BY_HEX[entity_hex] = { + "checkName": full_entity_name, + "entity_hex": entity_hex, "region": current_region, "id": int(location_id), - "panelType": location_type + "entityType": location_type } - self.ENTITY_ID_TO_NAME[check_hex] = full_check_name + self.ENTITY_ID_TO_NAME[entity_hex] = full_entity_name - self.CHECKS_BY_NAME[self.CHECKS_BY_HEX[check_hex]["checkName"]] = self.CHECKS_BY_HEX[check_hex] - self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[check_hex] = requirement + self.ENTITIES_BY_NAME[self.ENTITIES_BY_HEX[entity_hex]["checkName"]] = self.ENTITIES_BY_HEX[entity_hex] + self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX[entity_hex] = requirement - current_region["panels"].append(check_hex) + current_region["panels"].append(entity_hex) + + def __init__(self, lines=None): + if lines is None: + lines = get_sigma_normal_logic() - def __init__(self, lines=get_sigma_normal_logic()): # All regions with a list of panels in them and the connections to other regions, before logic adjustments self.ALL_REGIONS_BY_NAME = dict() self.STATIC_CONNECTIONS_BY_REGION_NAME = dict() - self.CHECKS_BY_HEX = dict() - self.CHECKS_BY_NAME = dict() + self.ENTITIES_BY_HEX = dict() + self.ENTITIES_BY_NAME = dict() self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX = dict() self.OBELISK_SIDE_ID_TO_EP_HEXES = dict() @@ -187,8 +193,8 @@ class StaticWitnessLogic: OBELISK_SIDE_ID_TO_EP_HEXES = dict() - CHECKS_BY_HEX = dict() - CHECKS_BY_NAME = dict() + ENTITIES_BY_HEX = dict() + ENTITIES_BY_NAME = dict() STATIC_DEPENDENT_REQUIREMENTS_BY_HEX = dict() EP_TO_OBELISK_SIDE = dict() @@ -262,8 +268,8 @@ def __init__(self): self.ALL_REGIONS_BY_NAME.update(self.sigma_normal.ALL_REGIONS_BY_NAME) self.STATIC_CONNECTIONS_BY_REGION_NAME.update(self.sigma_normal.STATIC_CONNECTIONS_BY_REGION_NAME) - self.CHECKS_BY_HEX.update(self.sigma_normal.CHECKS_BY_HEX) - self.CHECKS_BY_NAME.update(self.sigma_normal.CHECKS_BY_NAME) + self.ENTITIES_BY_HEX.update(self.sigma_normal.ENTITIES_BY_HEX) + self.ENTITIES_BY_NAME.update(self.sigma_normal.ENTITIES_BY_NAME) self.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX.update(self.sigma_normal.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX) self.OBELISK_SIDE_ID_TO_EP_HEXES.update(self.sigma_normal.OBELISK_SIDE_ID_TO_EP_HEXES) diff --git a/worlds/witness/utils.py b/worlds/witness/utils.py index 72dc10fd0617..fbb670fd0877 100644 --- a/worlds/witness/utils.py +++ b/worlds/witness/utils.py @@ -1,6 +1,6 @@ from functools import lru_cache from math import floor -from typing import List, Collection +from typing import List, Collection, FrozenSet, Tuple, Dict, Any, Set from pkgutil import get_data @@ -33,7 +33,7 @@ def build_weighted_int_list(inputs: Collection[float], total: int) -> List[int]: return rounded_output -def define_new_region(region_string): +def define_new_region(region_string: str) -> Tuple[Dict[str, Any], Set[Tuple[str, FrozenSet[FrozenSet[str]]]]]: """ Returns a region object by parsing a line in the logic file """ @@ -66,7 +66,7 @@ def define_new_region(region_string): return region_obj, options -def parse_lambda(lambda_string): +def parse_lambda(lambda_string) -> FrozenSet[FrozenSet[str]]: """ Turns a lambda String literal like this: a | b & c into a set of sets like this: {{a}, {b, c}} @@ -97,86 +97,168 @@ def __get__(self, instance, class_): @lru_cache(maxsize=None) -def get_adjustment_file(adjustment_file): +def get_adjustment_file(adjustment_file: str) -> List[str]: data = get_data(__name__, adjustment_file).decode('utf-8') return [line.strip() for line in data.split("\n")] -def get_disable_unrandomized_list(): - return get_adjustment_file("settings/Disable_Unrandomized.txt") +def get_disable_unrandomized_list() -> List[str]: + return get_adjustment_file("settings/Exclusions/Disable_Unrandomized.txt") -def get_early_utm_list(): - return get_adjustment_file("settings/Early_UTM.txt") +def get_early_caves_list() -> List[str]: + return get_adjustment_file("settings/Early_Caves.txt") -def get_symbol_shuffle_list(): +def get_early_caves_start_list() -> List[str]: + return get_adjustment_file("settings/Early_Caves_Start.txt") + + +def get_symbol_shuffle_list() -> List[str]: return get_adjustment_file("settings/Symbol_Shuffle.txt") -def get_door_panel_shuffle_list(): - return get_adjustment_file("settings/Door_Panel_Shuffle.txt") +def get_complex_doors() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Complex_Doors.txt") + + +def get_simple_doors() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Simple_Doors.txt") + +def get_complex_door_panels() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Complex_Door_Panels.txt") -def get_doors_simple_list(): - return get_adjustment_file("settings/Doors_Simple.txt") +def get_complex_additional_panels() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Complex_Additional_Panels.txt") -def get_doors_complex_list(): - return get_adjustment_file("settings/Doors_Complex.txt") +def get_simple_panels() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Simple_Panels.txt") -def get_doors_max_list(): - return get_adjustment_file("settings/Doors_Max.txt") +def get_simple_additional_panels() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Simple_Additional_Panels.txt") -def get_laser_shuffle(): + +def get_boat() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Boat.txt") + + +def get_laser_shuffle() -> List[str]: return get_adjustment_file("settings/Laser_Shuffle.txt") -def get_audio_logs(): +def get_audio_logs() -> List[str]: return get_adjustment_file("settings/Audio_Logs.txt") -def get_ep_all_individual(): +def get_ep_all_individual() -> List[str]: return get_adjustment_file("settings/EP_Shuffle/EP_All.txt") -def get_ep_obelisks(): +def get_ep_obelisks() -> List[str]: return get_adjustment_file("settings/EP_Shuffle/EP_Sides.txt") -def get_ep_easy(): +def get_ep_easy() -> List[str]: return get_adjustment_file("settings/EP_Shuffle/EP_Easy.txt") -def get_ep_no_eclipse(): +def get_ep_no_eclipse() -> List[str]: return get_adjustment_file("settings/EP_Shuffle/EP_NoEclipse.txt") -def get_ep_no_caves(): - return get_adjustment_file("settings/EP_Shuffle/EP_NoCavesEPs.txt") +def get_vault_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Exclusions/Vaults.txt") + + +def get_discard_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Exclusions/Discards.txt") + + +def get_caves_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Caves.txt") + + +def get_beyond_challenge_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Beyond_Challenge.txt") + + +def get_bottom_floor_discard_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Bottom_Floor_Discard.txt") + + +def get_bottom_floor_discard_nondoors_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Bottom_Floor_Discard_NonDoors.txt") -def get_ep_no_mountain(): - return get_adjustment_file("settings/EP_Shuffle/EP_NoMountainEPs.txt") +def get_mountain_upper_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Mountain_Upper.txt") -def get_ep_no_videos(): - return get_adjustment_file("settings/EP_Shuffle/EP_Videos.txt") +def get_challenge_vault_box_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Challenge_Vault_Box.txt") -def get_sigma_normal_logic(): +def get_path_to_challenge_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Path_To_Challenge.txt") + + +def get_mountain_lower_exclusion_list() -> List[str]: + return get_adjustment_file("settings/Postgame/Mountain_Lower.txt") + + +def get_elevators_come_to_you() -> List[str]: + return get_adjustment_file("settings/Door_Shuffle/Elevators_Come_To_You.txt") + + +def get_sigma_normal_logic() -> List[str]: return get_adjustment_file("WitnessLogic.txt") -def get_sigma_expert_logic(): +def get_sigma_expert_logic() -> List[str]: return get_adjustment_file("WitnessLogicExpert.txt") -def get_vanilla_logic(): +def get_vanilla_logic() -> List[str]: return get_adjustment_file("WitnessLogicVanilla.txt") -def get_items(): +def get_items() -> List[str]: return get_adjustment_file("WitnessItems.txt") + + +def dnf_remove_redundancies(dnf_requirement: FrozenSet[FrozenSet[str]]) -> FrozenSet[FrozenSet[str]]: + """Removes any redundant terms from a logical formula in disjunctive normal form. + This means removing any terms that are a superset of any other term get removed. + This is possible because of the boolean absorption law: a | (a & b) = a""" + to_remove = set() + + for option1 in dnf_requirement: + for option2 in dnf_requirement: + if option2 < option1: + to_remove.add(option1) + + return dnf_requirement - to_remove + + +def dnf_and(dnf_requirements: List[FrozenSet[FrozenSet[str]]]) -> FrozenSet[FrozenSet[str]]: + """ + performs the "and" operator on a list of logical formula in disjunctive normal form, represented as a set of sets. + A logical formula might look like this: {{a, b}, {c, d}}, which would mean "a & b | c & d". + These can be easily and-ed by just using the boolean distributive law: (a | b) & c = a & c | a & b. + """ + current_overall_requirement = frozenset({frozenset()}) + + for next_dnf_requirement in dnf_requirements: + new_requirement: Set[FrozenSet[str]] = set() + + for option1 in current_overall_requirement: + for option2 in next_dnf_requirement: + new_requirement.add(option1 | option2) + + current_overall_requirement = frozenset(new_requirement) + + return dnf_remove_redundancies(current_overall_requirement)