The Witness 0.3.4 features (#780)
New options: Shuffle Doors: Many doors in the game will open on their own upon receiving an item ("key"). Variant - Shuffle Door/Control Panels: Many panels in the game that open doors or control devices in the world will be off until receiving their respective item ("key"). Shuffle Lasers: Lasers no longer activate by solving the laser panel, instead you will get an item that activates the laser. Shuffle Symbols: Now that there is something else to shuffle (doors / door panels), you can turn off Symbol Rando. Shuffle Postgame (replaces "Shuffle Hard"): The randomizer will now determine by your settings which panels are in the "postgame" - Meaning they can only be accessed after you can complete your win condition anyway.
This commit is contained in:
parent
472e114fb9
commit
bd4850b2b5
|
@ -1,30 +0,0 @@
|
||||||
100 - 0x01A54 - None - Glass Factory Entry Door
|
|
||||||
105 - 0x000B0 - 0x0343A - Door to Symmetry Island Lower
|
|
||||||
107 - 0x1C349 - 0x00076 - Door to Symmetry Island Upper
|
|
||||||
110 - 0x0C339 - 0x09F94 - Door to Desert Flood Light Room
|
|
||||||
111 - 0x1C2DF,0x1831E,0x1C260,0x1831C,0x1C2F3,0x1831D,0x1C2B1,0x1831B - None - Desert Flood Room Flood Controls
|
|
||||||
120 - 0x03678 - None - Quarry Mill Ramp Control
|
|
||||||
122 - 0x03679 - 0x014E8 - Quarry Mill Elevator Control
|
|
||||||
125 - 0x03852 - 0x034D4,0x021D5 - Quarry Boathouse Ramp Height Control
|
|
||||||
127 - 0x03858 - 0x021AE - Quarry Boathouse Ramp Horizontal Control
|
|
||||||
131 - 0x334DB,0x334DC - None - Shadows Door Timer
|
|
||||||
150 - 0x00B10 - None - Monastery Entry Door Left
|
|
||||||
151 - 0x00C92 - None - Monastery Entry Door Right
|
|
||||||
162 - 0x28998 - None - Town Door to RGB House
|
|
||||||
163 - 0x28A0D - 0x28998 - Town Door to Church
|
|
||||||
166 - 0x28A79 - None - Town Maze Panel (Drop-Down Staircase)
|
|
||||||
169 - 0x17F5F - None - Windmill Door
|
|
||||||
200 - 0x0288C - None - Treehouse First & Second Door
|
|
||||||
202 - 0x0A182 - None - Treehouse Third Door
|
|
||||||
205 - 0x2700B - None - Treehouse Laser House Door Timer
|
|
||||||
208 - 0x17CBC - None - Treehouse Shortcut Drop-Down Bridge
|
|
||||||
175 - 0x17CAB - 0x002C7 - Jungle Popup Wall
|
|
||||||
180 - 0x17C2E - None - Bunker Entry Door
|
|
||||||
183 - 0x0A099 - 0x09DAF - Inside Bunker Door to Bunker Proper
|
|
||||||
186 - 0x0A079 - None - Bunker Elevator Control
|
|
||||||
190 - 0x0056E - None - Swamp Entry Door
|
|
||||||
192 - 0x00609,0x18488 - 0x181A9 - Swamp Sliding Bridge
|
|
||||||
195 - 0x181F5 - None - Swamp Rotating Bridge
|
|
||||||
197 - 0x17C0A - None - Swamp Maze Control
|
|
||||||
300 - 0x0042D - None - Mountaintop River Shape Panel (Shortcut to Secret Area)
|
|
||||||
310 - 0x17CDF,0x17CC8,0x17CA6,0x09DB8,0x17C95,0x0A054 - None - Boat
|
|
|
@ -1,5 +0,0 @@
|
||||||
Event Items:
|
|
||||||
Shortcut to Secret Area Opens - 0x0042D
|
|
||||||
|
|
||||||
Region Changes:
|
|
||||||
Inside Mountain Secret Area (Inside Mountain Secret Area) - Inside Mountain Path to Secret Area - 0x00FF8 - Main Island - 0x021D7 | 0x0042D - Main Island - 0x17CF2
|
|
|
@ -7,37 +7,48 @@ from Options import Toggle, DefaultOnToggle, Option, Range, Choice
|
||||||
# "Play the randomizer in hardmode"
|
# "Play the randomizer in hardmode"
|
||||||
# display_name = "Hard Mode"
|
# display_name = "Hard Mode"
|
||||||
|
|
||||||
# class UnlockSymbols(DefaultOnToggle):
|
|
||||||
# "All Puzzle symbols of a specific panel need to be unlocked before the panel can be used"
|
|
||||||
# display_name = "Unlock Symbols"
|
|
||||||
|
|
||||||
class DisableNonRandomizedPuzzles(DefaultOnToggle):
|
class DisableNonRandomizedPuzzles(DefaultOnToggle):
|
||||||
"""Disable puzzles that cannot be randomized.
|
"""Disables puzzles that cannot be randomized.
|
||||||
Non randomized puzzles are Shadows, Monastery, and Greenhouse.
|
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 be activated as you solve optional puzzles throughout the island."""
|
||||||
display_name = "Disable non randomized puzzles"
|
display_name = "Disable non randomized puzzles"
|
||||||
|
|
||||||
|
|
||||||
class EarlySecretArea(Toggle):
|
class EarlySecretArea(Toggle):
|
||||||
"""The Mountainside shortcut to the Mountain Secret Area is open from the start.
|
"""Opens the Mountainside shortcut to the Mountain Secret Area from the start.
|
||||||
(Otherwise known as "UTM", "Caves" or the "Challenge Area")"""
|
(Otherwise known as "UTM", "Caves" or the "Challenge Area")"""
|
||||||
display_name = "Early Secret Area"
|
display_name = "Early Secret Area"
|
||||||
|
|
||||||
|
|
||||||
class ShuffleSymbols(DefaultOnToggle):
|
class ShuffleSymbols(DefaultOnToggle):
|
||||||
"""You will need to unlock puzzle symbols as items to be able to solve the panels that contain those symbols."""
|
"""You will need to unlock puzzle symbols as items to be able to solve the panels that contain those symbols.
|
||||||
|
If you turn this off, there will be no progression items in the game unless you turn on door shuffle."""
|
||||||
display_name = "Shuffle Symbols"
|
display_name = "Shuffle Symbols"
|
||||||
|
|
||||||
|
|
||||||
class ShuffleDoors(Toggle):
|
class ShuffleLasers(Toggle):
|
||||||
"""Many doors around the island will have their panels turned off initially.
|
"""If on, the 11 lasers are turned into items and will activate on their own upon receiving them.
|
||||||
You will need to find the items that power the panels to open those doors."""
|
Note: There is a visual bug that can occur with the Desert Laser. It does not affect gameplay - The Laser can still
|
||||||
|
be redirected as normal, for both applications of redirection."""
|
||||||
|
display_name = "Shuffle Lasers"
|
||||||
|
|
||||||
|
|
||||||
|
class ShuffleDoors(Choice):
|
||||||
|
"""If on, opening doors will require their respective "keys".
|
||||||
|
If set to "panels", those keys will unlock the panels on doors.
|
||||||
|
In "doors_simple" and "doors_complex", the doors will magically open by themselves upon receiving the key."""
|
||||||
display_name = "Shuffle Doors"
|
display_name = "Shuffle Doors"
|
||||||
|
option_none = 0
|
||||||
|
option_panels = 1
|
||||||
|
option_doors_simple = 2
|
||||||
|
option_doors_complex = 3
|
||||||
|
option_max = 4
|
||||||
|
|
||||||
|
|
||||||
class ShuffleDiscardedPanels(Toggle):
|
class ShuffleDiscardedPanels(Toggle):
|
||||||
"""Discarded Panels will have items on them.
|
"""Add Discarded Panels into the location pool.
|
||||||
Solving certain Discarded Panels may still be necessary even if off!"""
|
Solving certain Discarded Panels may still be necessary to beat the game, even if this is off."""
|
||||||
|
|
||||||
display_name = "Shuffle Discarded Panels"
|
display_name = "Shuffle Discarded Panels"
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,9 +63,10 @@ class ShuffleUncommonLocations(Toggle):
|
||||||
display_name = "Shuffle Uncommon Locations"
|
display_name = "Shuffle Uncommon Locations"
|
||||||
|
|
||||||
|
|
||||||
class ShuffleHardLocations(Toggle):
|
class ShufflePostgame(Toggle):
|
||||||
"""Adds some harder locations into the game, e.g. Mountain Secret Area panels"""
|
"""Adds locations into the pool that are guaranteed to be locked behind your goal. Use this if you don't play with
|
||||||
display_name = "Shuffle Hard Locations"
|
forfeit on victory."""
|
||||||
|
display_name = "Shuffle Postgame"
|
||||||
|
|
||||||
|
|
||||||
class VictoryCondition(Choice):
|
class VictoryCondition(Choice):
|
||||||
|
@ -103,16 +115,17 @@ class PuzzleSkipAmount(Range):
|
||||||
|
|
||||||
the_witness_options: Dict[str, type] = {
|
the_witness_options: Dict[str, type] = {
|
||||||
# "hard_mode": HardMode,
|
# "hard_mode": HardMode,
|
||||||
|
"shuffle_symbols": ShuffleSymbols,
|
||||||
|
"shuffle_doors": ShuffleDoors,
|
||||||
|
"shuffle_lasers": ShuffleLasers,
|
||||||
"disable_non_randomized_puzzles": DisableNonRandomizedPuzzles,
|
"disable_non_randomized_puzzles": DisableNonRandomizedPuzzles,
|
||||||
"shuffle_discarded_panels": ShuffleDiscardedPanels,
|
"shuffle_discarded_panels": ShuffleDiscardedPanels,
|
||||||
"shuffle_vault_boxes": ShuffleVaultBoxes,
|
"shuffle_vault_boxes": ShuffleVaultBoxes,
|
||||||
"shuffle_uncommon": ShuffleUncommonLocations,
|
"shuffle_uncommon": ShuffleUncommonLocations,
|
||||||
"shuffle_hard": ShuffleHardLocations,
|
"shuffle_postgame": ShufflePostgame,
|
||||||
"victory_condition": VictoryCondition,
|
"victory_condition": VictoryCondition,
|
||||||
"trap_percentage": TrapPercentage,
|
"trap_percentage": TrapPercentage,
|
||||||
"early_secret_area": EarlySecretArea,
|
"early_secret_area": EarlySecretArea,
|
||||||
# "shuffle_symbols": ShuffleSymbols,
|
|
||||||
# "shuffle_doors": ShuffleDoors,
|
|
||||||
"mountain_lasers": MountainLasers,
|
"mountain_lasers": MountainLasers,
|
||||||
"challenge_lasers": ChallengeLasers,
|
"challenge_lasers": ChallengeLasers,
|
||||||
"puzzle_skip_amount": PuzzleSkipAmount,
|
"puzzle_skip_amount": PuzzleSkipAmount,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Progression:
|
Progression:
|
||||||
0 - Dots
|
0 - Dots
|
||||||
1 - Colored Dots
|
1 - Colored Dots
|
||||||
|
2 - Full Dots
|
||||||
|
3 - Invisible Dots
|
||||||
5 - Sound Dots
|
5 - Sound Dots
|
||||||
10 - Symmetry
|
10 - Symmetry
|
||||||
20 - Triangles
|
20 - Triangles
|
||||||
|
@ -12,6 +14,7 @@ Progression:
|
||||||
61 - Stars + Same Colored Symbol
|
61 - Stars + Same Colored Symbol
|
||||||
71 - Black/White Squares
|
71 - Black/White Squares
|
||||||
72 - Colored Squares
|
72 - Colored Squares
|
||||||
|
80 - Arrows
|
||||||
|
|
||||||
Usefuls:
|
Usefuls:
|
||||||
101 - Functioning Brain - False
|
101 - Functioning Brain - False
|
||||||
|
@ -23,3 +26,173 @@ Boosts:
|
||||||
Traps:
|
Traps:
|
||||||
600 - Slowness
|
600 - Slowness
|
||||||
610 - Power Surge
|
610 - Power Surge
|
||||||
|
|
||||||
|
Doors:
|
||||||
|
1100 - Glass Factory Entry Door (Panel) - 0x01A54
|
||||||
|
1105 - Door to Symmetry Island Lower (Panel) - 0x000B0
|
||||||
|
1107 - Door to Symmetry Island Upper (Panel) - 0x1C349
|
||||||
|
1110 - Door to Desert Flood Light Room (Panel) - 0x0C339
|
||||||
|
1111 - Desert Flood Room Flood Controls (Panel) - 0x1C2DF,0x1831E,0x1C260,0x1831C,0x1C2F3,0x1831D,0x1C2B1,0x1831B
|
||||||
|
1119 - Quarry Door to Mill (Panel) - 0x01E5A,0x01E59
|
||||||
|
1120 - Quarry Mill Ramp Controls (Panel) - 0x03678,0x03676
|
||||||
|
1122 - Quarry Mill Elevator Controls (Panel) - 0x03679,0x03675
|
||||||
|
1125 - Quarry Boathouse Ramp Height Control (Panel) - 0x03852
|
||||||
|
1127 - Quarry Boathouse Ramp Horizontal Control (Panel) - 0x03858
|
||||||
|
1131 - Shadows Door Timer (Panel) - 0x334DB,0x334DC
|
||||||
|
1150 - Monastery Entry Door Left (Panel) - 0x00B10
|
||||||
|
1151 - Monastery Entry Door Right (Panel) - 0x00C92
|
||||||
|
1162 - Town Door to RGB House (Panel) - 0x28998
|
||||||
|
1163 - Town Door to Church (Panel) - 0x28A0D
|
||||||
|
1166 - Town Maze Panel (Drop-Down Staircase) (Panel) - 0x28A79
|
||||||
|
1169 - Windmill Door (Panel) - 0x17F5F
|
||||||
|
1200 - Treehouse First & Second Doors (Panel) - 0x0288C,0x02886
|
||||||
|
1202 - Treehouse Third Door (Panel) - 0x0A182
|
||||||
|
1205 - Treehouse Laser House Door Timer (Panel) - 0x2700B,0x334DC
|
||||||
|
1208 - Treehouse Shortcut Drop-Down Bridge (Panel) - 0x17CBC
|
||||||
|
1175 - Jungle Popup Wall (Panel) - 0x17CAB
|
||||||
|
1180 - Bunker Entry Door (Panel) - 0x17C2E
|
||||||
|
1183 - Inside Bunker Door to Bunker Proper (Panel) - 0x0A099
|
||||||
|
1186 - Bunker Elevator Control (Panel) - 0x0A079
|
||||||
|
1190 - Swamp Entry Door (Panel) - 0x0056E
|
||||||
|
1192 - Swamp Sliding Bridge (Panel) - 0x00609,0x18488
|
||||||
|
1195 - Swamp Rotating Bridge (Panel) - 0x181F5
|
||||||
|
1197 - Swamp Maze Control (Panel) - 0x17C0A
|
||||||
|
1310 - Boat - 0x17CDF,0x17CC8,0x17CA6,0x09DB8,0x17C95,0x0A054
|
||||||
|
|
||||||
|
1400 - Caves Mountain Shortcut - 0x2D73F
|
||||||
|
|
||||||
|
1500 - Symmetry Laser - 0x00509
|
||||||
|
1501 - Desert Laser - 0x012FB,0x01317
|
||||||
|
1502 - Quarry Laser - 0x01539
|
||||||
|
1503 - Shadows Laser - 0x181B3
|
||||||
|
1504 - Keep Laser - 0x014BB
|
||||||
|
1505 - Monastery Laser - 0x17C65
|
||||||
|
1506 - Town Laser - 0x032F9
|
||||||
|
1507 - Jungle Laser - 0x00274
|
||||||
|
1508 - Bunker Laser - 0x0C2B2
|
||||||
|
1509 - Swamp Laser - 0x00BF6
|
||||||
|
1510 - Treehouse Laser - 0x028A4
|
||||||
|
|
||||||
|
1600 - Outside Tutorial Optional Door - 0x03BA2
|
||||||
|
1603 - Outside Tutorial Outpost Entry Door - 0x0A170
|
||||||
|
1606 - Outside Tutorial Outpost Exit Door - 0x04CA3
|
||||||
|
1609 - Glass Factory Entry Door - 0x01A29
|
||||||
|
1612 - Glass Factory Back Wall - 0x0D7ED
|
||||||
|
1615 - Symmetry Island Lower Door - 0x17F3E
|
||||||
|
1618 - Symmetry Island Upper Door - 0x18269
|
||||||
|
1619 - Orchard Middle Gate - 0x03307
|
||||||
|
1620 - Orchard Final Gate - 0x03313
|
||||||
|
1621 - Desert Door to Flood Light Room - 0x09FEE
|
||||||
|
1624 - Desert Door to Pond Room - 0x0C2C3
|
||||||
|
1627 - Desert Door to Water Levels Room - 0x0A24B
|
||||||
|
1630 - Desert Door to Elevator Room - 0x0C316
|
||||||
|
1633 - Quarry Main Entry 1 - 0x09D6F
|
||||||
|
1636 - Quarry Main Entry 2 - 0x17C07
|
||||||
|
1639 - Quarry Door to Mill - 0x02010
|
||||||
|
1642 - Quarry Mill Side Door - 0x275FF
|
||||||
|
1645 - Quarry Mill Rooftop Shortcut - 0x17CE8
|
||||||
|
1648 - Quarry Mill Stairs - 0x0368A
|
||||||
|
1651 - Quarry Boathouse Boat Staircase - 0x2769B,0x27163
|
||||||
|
1653 - Quarry Boathouse First Barrier - 0x17C50
|
||||||
|
1654 - Quarry Boathouse Shortcut - 0x3865F
|
||||||
|
1656 - Shadows Timed Door - 0x19B24
|
||||||
|
1657 - Shadows Laser Room Right Door - 0x194B2
|
||||||
|
1660 - Shadows Laser Room Left Door - 0x19665
|
||||||
|
1663 - Shadows Barrier to Quarry - 0x19865,0x0A2DF
|
||||||
|
1666 - Shadows Barrier to Ledge - 0x1855B,0x19ADE
|
||||||
|
1669 - Keep Hedge Maze 1 Exit Door - 0x01954
|
||||||
|
1672 - Keep Pressure Plates 1 Exit Door - 0x01BEC
|
||||||
|
1675 - Keep Hedge Maze 2 Shortcut - 0x018CE
|
||||||
|
1678 - Keep Hedge Maze 2 Exit Door - 0x019D8
|
||||||
|
1681 - Keep Hedge Maze 3 Shortcut - 0x019B5
|
||||||
|
1684 - Keep Hedge Maze 3 Exit Door - 0x019E6
|
||||||
|
1687 - Keep Hedge Maze 4 Shortcut - 0x0199A
|
||||||
|
1690 - Keep Hedge Maze 4 Exit Door - 0x01A0E
|
||||||
|
1693 - Keep Pressure Plates 2 Exit Door - 0x01BEA
|
||||||
|
1696 - Keep Pressure Plates 3 Exit Door - 0x01CD5
|
||||||
|
1699 - Keep Pressure Plates 4 Exit Door - 0x01D40
|
||||||
|
1702 - Keep Shortcut to Shadows - 0x09E3D
|
||||||
|
1705 - Keep Tower Shortcut - 0x04F8F
|
||||||
|
1708 - Monastery Shortcut - 0x0364E
|
||||||
|
1711 - Monastery Inner Door - 0x0C128
|
||||||
|
1714 - Monastery Outer Door - 0x0C153
|
||||||
|
1717 - Monastery Door to Garden - 0x03750
|
||||||
|
1718 - Town Cargo Box Door - 0x0A0C9
|
||||||
|
1720 - Town Wooden Roof Staircase - 0x034F5
|
||||||
|
1723 - Town Tinted Door to RGB House - 0x28A61
|
||||||
|
1726 - Town Door to Church - 0x03BB0
|
||||||
|
1729 - Town Maze Staircase - 0x28AA2
|
||||||
|
1732 - Town Windmill Door - 0x1845B
|
||||||
|
1735 - Town RGB House Staircase - 0x2897B
|
||||||
|
1738 - Town Tower Blue Panels Door - 0x27798
|
||||||
|
1741 - Town Tower Lattice Door - 0x27799
|
||||||
|
1744 - Town Tower Environmental Set Door - 0x2779A
|
||||||
|
1747 - Town Tower Wooden Roof Set Door - 0x2779C
|
||||||
|
1750 - Theater Entry Door - 0x17F88
|
||||||
|
1753 - Theater Exit Door Left - 0x0A16D
|
||||||
|
1756 - Theater Exit Door Right - 0x3CCDF
|
||||||
|
1759 - Jungle Bamboo Shortcut to River - 0x3873B
|
||||||
|
1760 - Jungle Popup Wall - 0x1475B
|
||||||
|
1762 - River Shortcut to Monastery Garden - 0x0CF2A
|
||||||
|
1765 - Bunker Bunker Entry Door - 0x0C2A4
|
||||||
|
1768 - Bunker Tinted Glass Door - 0x17C79
|
||||||
|
1771 - Bunker Door to Ultraviolet Room - 0x0C2A3
|
||||||
|
1774 - Bunker Door to Elevator - 0x0A08D
|
||||||
|
1777 - Swamp Entry Door - 0x00C1C
|
||||||
|
1780 - Swamp Door to Broken Shapers - 0x184B7
|
||||||
|
1783 - Swamp Platform Shortcut Door - 0x38AE6
|
||||||
|
1786 - Swamp Cyan Water Pump - 0x04B7F
|
||||||
|
1789 - Swamp Door to Rotated Shapers - 0x18507
|
||||||
|
1792 - Swamp Red Water Pump - 0x183F2
|
||||||
|
1795 - Swamp Red Underwater Exit - 0x305D5
|
||||||
|
1798 - Swamp Blue Water Pump - 0x18482
|
||||||
|
1801 - Swamp Purple Water Pump - 0x0A1D6
|
||||||
|
1804 - Swamp Near Laser Shortcut - 0x2D880
|
||||||
|
1807 - Treehouse First Door - 0x0C309
|
||||||
|
1810 - Treehouse Second Door - 0x0C310
|
||||||
|
1813 - Treehouse Beyond Yellow Bridge Door - 0x0A181
|
||||||
|
1816 - Treehouse Drawbridge - 0x0C32D
|
||||||
|
1819 - Treehouse Timed Door to Laser House - 0x0C323
|
||||||
|
1822 - Inside Mountain First Layer Exit Door - 0x09E54
|
||||||
|
1825 - Inside Mountain Second Layer Staircase Near - 0x09FFB
|
||||||
|
1828 - Inside Mountain Second Layer Exit Door - 0x09EDD
|
||||||
|
1831 - Inside Mountain Second Layer Staircase Far - 0x09E07
|
||||||
|
1834 - Inside Mountain Giant Puzzle Exit Door - 0x09F89
|
||||||
|
1840 - Inside Mountain Door to Final Room - 0x0C141
|
||||||
|
1843 - Inside Mountain Bottom Layer Rock - 0x17F33
|
||||||
|
1846 - Inside Mountain Door to Secret Area - 0x2D77D
|
||||||
|
1849 - Caves Pillar Door - 0x019A5
|
||||||
|
1855 - Caves Swamp Shortcut - 0x2D859
|
||||||
|
1858 - Challenge Entry Door - 0x0A19A
|
||||||
|
1861 - Challenge Door to Theater Walkway - 0x0348A
|
||||||
|
1864 - Theater Walkway Door to Windmill Interior - 0x27739
|
||||||
|
1867 - Theater Walkway Door to Desert Elevator Room - 0x27263
|
||||||
|
1870 - Theater Walkway Door to Town - 0x09E87
|
||||||
|
|
||||||
|
1903 - Outside Tutorial Outpost Doors - 0x03BA2,0x0A170,0x04CA3
|
||||||
|
1906 - Symmetry Island Doors - 0x17F3E,0x18269
|
||||||
|
1909 - Orchard Gates - 0x03313,0x03307
|
||||||
|
1912 - Desert Doors - 0x09FEE,0x0C2C3,0x0A24B,0x0C316
|
||||||
|
1915 - Quarry Main Entry - 0x09D6F
|
||||||
|
1918 - Quarry Mill Shortcuts - 0x17C07,0x17CE8,0x0368A
|
||||||
|
1921 - Quarry Boathouse Barriers - 0x17C50,0x3865F
|
||||||
|
1924 - Shadows Laser Room Door - 0x194B2,0x19665
|
||||||
|
1927 - Shadows Barriers - 0x19865,0x0A2DF,0x1855B,0x19ADE
|
||||||
|
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 Door - 0x0C128,0x0C153
|
||||||
|
1942 - Monastery Shortcuts - 0x0364E,0x03750
|
||||||
|
1945 - Town Doors - 0x0A0C9,0x034F5,0x28A61,0x03BB0,0x28AA2,0x1845B,0x2897B
|
||||||
|
1948 - Town Tower Doors - 0x27798,0x27799,0x2779A,0x2779C
|
||||||
|
1951 - Theater Exit Door - 0x0A16D,0x3CCDF
|
||||||
|
1954 - Jungle & River Shortcuts - 0x3873B,0x0CF2A
|
||||||
|
1957 - Bunker Doors - 0x0C2A4,0x17C79,0x0C2A3,0x0A08D
|
||||||
|
1960 - Swamp Doors - 0x00C1C,0x184B7,0x38AE6,0x18507
|
||||||
|
1963 - Swamp Water Pumps - 0x04B7F,0x183F2,0x305D5,0x18482,0x0A1D6
|
||||||
|
1966 - Treehouse Entry Doors - 0x0C309,0x0C310,0x0A181
|
||||||
|
1975 - Inside Mountain Second Layer Stairs & Doors - 0x09FFB,0x09EDD,0x09E07
|
||||||
|
1978 - Inside Mountain Bottom Layer Doors to Caves - 0x17F33,0x2D77D
|
||||||
|
1981 - Caves Doors to Challenge - 0x019A5,0x0A19A
|
||||||
|
1984 - Caves Exits to Main Island - 0x2D859,0x2D73F
|
||||||
|
1987 - Theater Walkway Doors - 0x27739,0x27263,0x09E87
|
File diff suppressed because it is too large
Load Diff
|
@ -35,7 +35,7 @@ class WitnessWorld(World):
|
||||||
"""
|
"""
|
||||||
game = "The Witness"
|
game = "The Witness"
|
||||||
topology_present = False
|
topology_present = False
|
||||||
data_version = 2
|
data_version = 5
|
||||||
|
|
||||||
static_logic = StaticWitnessLogic()
|
static_logic = StaticWitnessLogic()
|
||||||
static_locat = StaticWitnessLocations()
|
static_locat = StaticWitnessLocations()
|
||||||
|
@ -53,11 +53,18 @@ class WitnessWorld(World):
|
||||||
'seed': self.world.random.randint(0, 1000000),
|
'seed': self.world.random.randint(0, 1000000),
|
||||||
'victory_location': int(self.player_logic.VICTORY_LOCATION, 16),
|
'victory_location': int(self.player_logic.VICTORY_LOCATION, 16),
|
||||||
'panelhex_to_id': self.locat.CHECK_PANELHEX_TO_ID,
|
'panelhex_to_id': self.locat.CHECK_PANELHEX_TO_ID,
|
||||||
'doorhex_to_id': self.player_logic.DOOR_DICT_FOR_CLIENT,
|
'item_id_to_door_hexes': self.items.ITEM_ID_TO_DOOR_HEX,
|
||||||
'door_connections_to_sever': self.player_logic.DOOR_CONNECTIONS_TO_SEVER
|
'door_hexes': self.items.DOORS,
|
||||||
|
'symbols_not_in_the_game': self.items.SYMBOLS_NOT_IN_THE_GAME
|
||||||
}
|
}
|
||||||
|
|
||||||
def generate_early(self):
|
def generate_early(self):
|
||||||
|
if not (is_option_enabled(self.world, self.player, "shuffle_symbols")
|
||||||
|
or get_option_value(self.world, self.player, "shuffle_doors")
|
||||||
|
or is_option_enabled(self.world, self.player, "shuffle_lasers")):
|
||||||
|
raise Exception("This Witness world doesn't have any progression items. Please turn on Symbol Shuffle, Door"
|
||||||
|
" Shuffle or Laser Shuffle")
|
||||||
|
|
||||||
self.player_logic = WitnessPlayerLogic(self.world, self.player)
|
self.player_logic = WitnessPlayerLogic(self.world, self.player)
|
||||||
self.locat = WitnessPlayerLocations(self.world, self.player, self.player_logic)
|
self.locat = WitnessPlayerLocations(self.world, self.player, self.player_logic)
|
||||||
self.items = WitnessPlayerItems(self.locat, self.world, self.player, self.player_logic)
|
self.items = WitnessPlayerItems(self.locat, self.world, self.player, self.player_logic)
|
||||||
|
@ -78,11 +85,11 @@ class WitnessWorld(World):
|
||||||
less_junk = 0
|
less_junk = 0
|
||||||
|
|
||||||
# Put good item on first check if symbol shuffle is on
|
# Put good item on first check if symbol shuffle is on
|
||||||
# symbols = is_option_enabled(self.world, self.player, "shuffle_symbols")
|
symbols = is_option_enabled(self.world, self.player, "shuffle_symbols")
|
||||||
symbols = True
|
|
||||||
|
|
||||||
if symbols:
|
if symbols:
|
||||||
random_good_item = self.world.random.choice(self.items.GOOD_ITEMS)
|
random_good_item = self.world.random.choice(self.items.GOOD_ITEMS)
|
||||||
|
|
||||||
first_check = self.world.get_location(
|
first_check = self.world.get_location(
|
||||||
"Tutorial Gate Open", self.player
|
"Tutorial Gate Open", self.player
|
||||||
)
|
)
|
||||||
|
@ -91,6 +98,10 @@ class WitnessWorld(World):
|
||||||
|
|
||||||
less_junk = 1
|
less_junk = 1
|
||||||
|
|
||||||
|
for item in self.player_logic.STARTING_INVENTORY:
|
||||||
|
self.world.push_precollected(items_by_name[item])
|
||||||
|
pool.remove(items_by_name[item])
|
||||||
|
|
||||||
for item in self.items.EXTRA_AMOUNTS:
|
for item in self.items.EXTRA_AMOUNTS:
|
||||||
witness_item = self.create_item(item)
|
witness_item = self.create_item(item)
|
||||||
for i in range(0, self.items.EXTRA_AMOUNTS[item]):
|
for i in range(0, self.items.EXTRA_AMOUNTS[item]):
|
||||||
|
|
|
@ -51,12 +51,15 @@ class StaticWitnessItems:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
item_tab = dict()
|
item_tab = dict()
|
||||||
|
|
||||||
for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS.union(StaticWitnessLogic.ALL_DOOR_ITEMS):
|
for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS:
|
||||||
if item[0] == "11 Lasers" or item == "7 Lasers":
|
if item[0] == "11 Lasers" or item == "7 Lasers":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
item_tab[item[0]] = ItemData(158000 + item[1], True, False)
|
item_tab[item[0]] = ItemData(158000 + item[1], True, False)
|
||||||
|
|
||||||
|
for item in StaticWitnessLogic.ALL_DOOR_ITEMS:
|
||||||
|
item_tab[item[0]] = ItemData(158000 + item[1], True, False)
|
||||||
|
|
||||||
for item in StaticWitnessLogic.ALL_TRAPS:
|
for item in StaticWitnessLogic.ALL_TRAPS:
|
||||||
item_tab[item[0]] = ItemData(
|
item_tab[item[0]] = ItemData(
|
||||||
158000 + item[1], False, False, True
|
158000 + item[1], False, False, True
|
||||||
|
@ -89,23 +92,39 @@ class WitnessPlayerItems:
|
||||||
self.ITEM_TABLE = copy.copy(StaticWitnessItems.ALL_ITEM_TABLE)
|
self.ITEM_TABLE = copy.copy(StaticWitnessItems.ALL_ITEM_TABLE)
|
||||||
self.PROGRESSION_TABLE = dict()
|
self.PROGRESSION_TABLE = dict()
|
||||||
|
|
||||||
|
self.ITEM_ID_TO_DOOR_HEX = dict()
|
||||||
|
self.DOORS = set()
|
||||||
|
|
||||||
|
self.SYMBOLS_NOT_IN_THE_GAME = set()
|
||||||
|
|
||||||
self.EXTRA_AMOUNTS = {
|
self.EXTRA_AMOUNTS = {
|
||||||
"Functioning Brain": 1,
|
"Functioning Brain": 1,
|
||||||
"Puzzle Skip": get_option_value(world, player, "puzzle_skip_amount")
|
"Puzzle Skip": get_option_value(world, player, "puzzle_skip_amount")
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS.union(StaticWitnessLogic.ALL_DOOR_ITEMS):
|
for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS.union(StaticWitnessLogic.ALL_DOOR_ITEMS):
|
||||||
if item not in player_logic.PROG_ITEMS_ACTUALLY_IN_THE_GAME:
|
if item[0] not in player_logic.PROG_ITEMS_ACTUALLY_IN_THE_GAME:
|
||||||
del self.ITEM_TABLE[item[0]]
|
del self.ITEM_TABLE[item[0]]
|
||||||
|
if item in StaticWitnessLogic.ALL_SYMBOL_ITEMS:
|
||||||
|
self.SYMBOLS_NOT_IN_THE_GAME.add(StaticWitnessItems.ALL_ITEM_TABLE[item[0]].code)
|
||||||
else:
|
else:
|
||||||
self.PROGRESSION_TABLE[item[0]] = self.ITEM_TABLE[item[0]]
|
self.PROGRESSION_TABLE[item[0]] = self.ITEM_TABLE[item[0]]
|
||||||
|
|
||||||
|
for entity_hex, items in player_logic.DOOR_ITEMS_BY_ID.items():
|
||||||
|
entity_hex_int = int(entity_hex, 16)
|
||||||
|
|
||||||
|
self.DOORS.add(entity_hex_int)
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
item_id = StaticWitnessItems.ALL_ITEM_TABLE[item].code
|
||||||
|
self.ITEM_ID_TO_DOOR_HEX.setdefault(item_id, set()).add(entity_hex_int)
|
||||||
|
|
||||||
symbols = is_option_enabled(world, player, "shuffle_symbols")
|
symbols = is_option_enabled(world, player, "shuffle_symbols")
|
||||||
|
|
||||||
if "shuffle_symbols" not in the_witness_options.keys():
|
if "shuffle_symbols" not in the_witness_options.keys():
|
||||||
symbols = True
|
symbols = True
|
||||||
|
|
||||||
doors = is_option_enabled(world, player, "shuffle_doors")
|
doors = get_option_value(world, player, "shuffle_doors")
|
||||||
|
|
||||||
if doors and symbols:
|
if doors and symbols:
|
||||||
self.GOOD_ITEMS = [
|
self.GOOD_ITEMS = [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Defines constants for different types of locations in the game
|
Defines constants for different types of locations in the game
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .Options import is_option_enabled
|
from .Options import is_option_enabled, get_option_value
|
||||||
from .player_logic import StaticWitnessLogic, WitnessPlayerLogic
|
from .player_logic import StaticWitnessLogic, WitnessPlayerLogic
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class StaticWitnessLocations:
|
||||||
"Symmetry Island Colored Dots 6",
|
"Symmetry Island Colored Dots 6",
|
||||||
"Symmetry Island Fading Lines 7",
|
"Symmetry Island Fading Lines 7",
|
||||||
"Symmetry Island Scenery Outlines 5",
|
"Symmetry Island Scenery Outlines 5",
|
||||||
"Symmetry Island Laser",
|
"Symmetry Island Laser Panel",
|
||||||
|
|
||||||
"Orchard Apple Tree 5",
|
"Orchard Apple Tree 5",
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class StaticWitnessLocations:
|
||||||
"Desert Artificial Light Reflection 3",
|
"Desert Artificial Light Reflection 3",
|
||||||
"Desert Pond Reflection 5",
|
"Desert Pond Reflection 5",
|
||||||
"Desert Flood Reflection 6",
|
"Desert Flood Reflection 6",
|
||||||
"Desert Laser",
|
"Desert Laser Panel",
|
||||||
|
|
||||||
"Quarry Mill Eraser and Dots 6",
|
"Quarry Mill Eraser and Dots 6",
|
||||||
"Quarry Mill Eraser and Squares 8",
|
"Quarry Mill Eraser and Squares 8",
|
||||||
|
@ -63,34 +63,34 @@ class StaticWitnessLocations:
|
||||||
"Quarry Boathouse Stars & Eraser & Shapers 2",
|
"Quarry Boathouse Stars & Eraser & Shapers 2",
|
||||||
"Quarry Boathouse Stars & Eraser & Shapers 5",
|
"Quarry Boathouse Stars & Eraser & Shapers 5",
|
||||||
"Quarry Discard",
|
"Quarry Discard",
|
||||||
"Quarry Laser",
|
"Quarry Laser Panel",
|
||||||
|
|
||||||
"Shadows Lower Avoid 8",
|
"Shadows Lower Avoid 8",
|
||||||
"Shadows Environmental Avoid 8",
|
"Shadows Environmental Avoid 8",
|
||||||
"Shadows Follow 5",
|
"Shadows Follow 5",
|
||||||
"Shadows Laser",
|
"Shadows Laser Panel",
|
||||||
|
|
||||||
"Keep Hedge Maze 4",
|
"Keep Hedge Maze 4",
|
||||||
"Keep Pressure Plates 4",
|
"Keep Pressure Plates 4",
|
||||||
"Keep Discard",
|
"Keep Discard",
|
||||||
"Keep Laser Hedges",
|
"Keep Laser Panel Hedges",
|
||||||
"Keep Laser Pressure Plates",
|
"Keep Laser Panel Pressure Plates",
|
||||||
|
|
||||||
"Shipwreck Vault Box",
|
"Shipwreck Vault Box",
|
||||||
"Shipwreck Discard",
|
"Shipwreck Discard",
|
||||||
|
|
||||||
"Monastery Rhombic Avoid 3",
|
"Monastery Rhombic Avoid 3",
|
||||||
"Monastery Branch Follow 2",
|
"Monastery Branch Follow 2",
|
||||||
"Monastery Laser",
|
"Monastery Laser Panel",
|
||||||
|
|
||||||
"Town Cargo Box Discard",
|
"Town Cargo Box Discard",
|
||||||
"Town Hexagonal Reflection",
|
"Town Hexagonal Reflection",
|
||||||
"Town Square Avoid",
|
"Town Church Lattice",
|
||||||
"Town Rooftop Discard",
|
"Town Rooftop Discard",
|
||||||
"Town Symmetry Squares 5 + Dots",
|
"Town Symmetry Squares 5 + Dots",
|
||||||
"Town Full Dot Grid Shapers 5",
|
"Town Full Dot Grid Shapers 5",
|
||||||
"Town Shapers & Dots & Eraser",
|
"Town Shapers & Dots & Eraser",
|
||||||
"Town Laser",
|
"Town Laser Panel",
|
||||||
|
|
||||||
"Theater Discard",
|
"Theater Discard",
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ class StaticWitnessLocations:
|
||||||
"Jungle Waves 3",
|
"Jungle Waves 3",
|
||||||
"Jungle Waves 7",
|
"Jungle Waves 7",
|
||||||
"Jungle Popup Wall 6",
|
"Jungle Popup Wall 6",
|
||||||
"Jungle Laser",
|
"Jungle Laser Panel",
|
||||||
|
|
||||||
"River Vault Box",
|
"River Vault Box",
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ class StaticWitnessLocations:
|
||||||
"Bunker Drawn Squares 9",
|
"Bunker Drawn Squares 9",
|
||||||
"Bunker Drawn Squares through Tinted Glass 3",
|
"Bunker Drawn Squares through Tinted Glass 3",
|
||||||
"Bunker Drop-Down Door Squares 2",
|
"Bunker Drop-Down Door Squares 2",
|
||||||
"Bunker Laser",
|
"Bunker Laser Panel",
|
||||||
|
|
||||||
"Swamp Seperatable Shapers 6",
|
"Swamp Seperatable Shapers 6",
|
||||||
"Swamp Combinable Shapers 8",
|
"Swamp Combinable Shapers 8",
|
||||||
|
@ -117,7 +117,7 @@ class StaticWitnessLocations:
|
||||||
"Swamp Red Underwater Negative Shapers 4",
|
"Swamp Red Underwater Negative Shapers 4",
|
||||||
"Swamp More Rotated Shapers 4",
|
"Swamp More Rotated Shapers 4",
|
||||||
"Swamp Blue Underwater Negative Shapers 5",
|
"Swamp Blue Underwater Negative Shapers 5",
|
||||||
"Swamp Laser",
|
"Swamp Laser Panel",
|
||||||
|
|
||||||
"Treehouse Yellow Bridge 9",
|
"Treehouse Yellow Bridge 9",
|
||||||
"Treehouse First Purple Bridge 5",
|
"Treehouse First Purple Bridge 5",
|
||||||
|
@ -125,21 +125,12 @@ class StaticWitnessLocations:
|
||||||
"Treehouse Green Bridge 7",
|
"Treehouse Green Bridge 7",
|
||||||
"Treehouse Green Bridge Discard",
|
"Treehouse Green Bridge Discard",
|
||||||
"Treehouse Left Orange Bridge 15",
|
"Treehouse Left Orange Bridge 15",
|
||||||
"Treehouse Burned House Discard",
|
"Treehouse Burnt House Discard",
|
||||||
"Treehouse Right Orange Bridge 12",
|
"Treehouse Right Orange Bridge 12",
|
||||||
"Treehouse Laser",
|
"Treehouse Laser Panel",
|
||||||
|
|
||||||
"Mountaintop Discard",
|
"Mountaintop Discard",
|
||||||
"Mountaintop Vault Box",
|
"Mountaintop Vault Box",
|
||||||
|
|
||||||
"Inside Mountain Obscured Vision 5",
|
|
||||||
"Inside Mountain Moving Background 7",
|
|
||||||
"Inside Mountain Physically Obstructed 3",
|
|
||||||
"Inside Mountain Angled Inside Trash 2",
|
|
||||||
"Inside Mountain Color Cycle 5",
|
|
||||||
"Inside Mountain Same Solution 6",
|
|
||||||
"Inside Mountain Elevator Discard",
|
|
||||||
"Inside Mountain Giant Puzzle",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UNCOMMON_LOCATIONS = {
|
UNCOMMON_LOCATIONS = {
|
||||||
|
@ -156,35 +147,53 @@ class StaticWitnessLocations:
|
||||||
"Swamp Underwater Back Optional",
|
"Swamp Underwater Back Optional",
|
||||||
}
|
}
|
||||||
|
|
||||||
HARD_LOCATIONS = {
|
CAVES_LOCATIONS = {
|
||||||
"Inside Mountain Secret Area Dot Grid Triangles 4",
|
"Inside Mountain Caves Dot Grid Triangles 4",
|
||||||
"Inside Mountain Secret Area Symmetry Triangles",
|
"Inside Mountain Caves Symmetry Triangles",
|
||||||
"Inside Mountain Secret Area Stars & Squares and Triangles 2",
|
"Inside Mountain Caves Stars & Squares and Triangles 2",
|
||||||
"Inside Mountain Secret Area Shapers and Triangles 2",
|
"Inside Mountain Caves Shapers and Triangles 2",
|
||||||
"Inside Mountain Secret Area Symmetry Shapers",
|
"Inside Mountain Caves Symmetry Shapers",
|
||||||
"Inside Mountain Secret Area Broken and Negative Shapers",
|
"Inside Mountain Caves Broken and Negative Shapers",
|
||||||
"Inside Mountain Secret Area Broken Shapers",
|
"Inside Mountain Caves Broken Shapers",
|
||||||
|
|
||||||
"Inside Mountain Secret Area Rainbow Squares",
|
"Inside Mountain Caves Rainbow Squares",
|
||||||
"Inside Mountain Secret Area Squares & Stars and Colored Eraser",
|
"Inside Mountain Caves Squares & Stars and Colored Eraser",
|
||||||
"Inside Mountain Secret Area Rotated Broken Shapers",
|
"Inside Mountain Caves Rotated Broken Shapers",
|
||||||
"Inside Mountain Secret Area Stars and Squares",
|
"Inside Mountain Caves Stars and Squares",
|
||||||
"Inside Mountain Secret Area Lone Pillar",
|
"Inside Mountain Caves Lone Pillar",
|
||||||
"Inside Mountain Secret Area Wooden Beam Shapers",
|
"Inside Mountain Caves Wooden Beam Shapers",
|
||||||
"Inside Mountain Secret Area Wooden Beam Squares and Shapers",
|
"Inside Mountain Caves Wooden Beam Squares and Shapers",
|
||||||
"Inside Mountain Secret Area Wooden Beam Stars and Squares",
|
"Inside Mountain Caves Wooden Beam Stars and Squares",
|
||||||
"Inside Mountain Secret Area Wooden Beam Shapers and Stars",
|
"Inside Mountain Caves Wooden Beam Shapers and Stars",
|
||||||
"Inside Mountain Secret Area Upstairs Invisible Dots 8",
|
"Inside Mountain Caves Upstairs Invisible Dots 8",
|
||||||
"Inside Mountain Secret Area Upstairs Invisible Dot Symmetry 3",
|
"Inside Mountain Caves Upstairs Invisible Dot Symmetry 3",
|
||||||
"Inside Mountain Secret Area Upstairs Dot Grid Negative Shapers",
|
"Inside Mountain Caves Upstairs Dot Grid Negative Shapers",
|
||||||
"Inside Mountain Secret Area Upstairs Dot Grid Rotated Shapers",
|
"Inside Mountain Caves Upstairs Dot Grid Rotated Shapers",
|
||||||
|
|
||||||
"Challenge Vault Box",
|
|
||||||
"Theater Walkway Vault Box",
|
"Theater Walkway Vault Box",
|
||||||
"Inside Mountain Bottom Layer Discard",
|
"Inside Mountain Bottom Layer Discard",
|
||||||
"Theater Challenge Video",
|
"Theater Challenge Video",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOUNTAIN_UNREACHABLE_FROM_BEHIND = {
|
||||||
|
"Mountaintop Trap Door Triple Exit",
|
||||||
|
|
||||||
|
"Inside Mountain Obscured Vision 5",
|
||||||
|
"Inside Mountain Moving Background 7",
|
||||||
|
"Inside Mountain Physically Obstructed 3",
|
||||||
|
"Inside Mountain Angled Inside Trash 2",
|
||||||
|
"Inside Mountain Color Cycle 5",
|
||||||
|
"Inside Mountain Same Solution 6",
|
||||||
|
}
|
||||||
|
|
||||||
|
MOUNTAIN_REACHABLE_FROM_BEHIND = {
|
||||||
|
"Inside Mountain Elevator Discard",
|
||||||
|
"Inside Mountain Giant Puzzle",
|
||||||
|
|
||||||
|
"Inside Mountain Final Room Left Pillar 4",
|
||||||
|
"Inside Mountain Final Room Right Pillar 4",
|
||||||
|
}
|
||||||
|
|
||||||
ALL_LOCATIONS_TO_ID = dict()
|
ALL_LOCATIONS_TO_ID = dict()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -193,12 +202,7 @@ class StaticWitnessLocations:
|
||||||
Calculates the location ID for any given location
|
Calculates the location ID for any given location
|
||||||
"""
|
"""
|
||||||
|
|
||||||
panel_offset = StaticWitnessLogic.CHECKS_BY_HEX[chex]["idOffset"]
|
return StaticWitnessLogic.CHECKS_BY_HEX[chex]["id"]
|
||||||
type_offset = StaticWitnessLocations.TYPE_OFFSETS[
|
|
||||||
StaticWitnessLogic.CHECKS_BY_HEX[chex]["panelType"]
|
|
||||||
]
|
|
||||||
|
|
||||||
return StaticWitnessLocations.ID_START + panel_offset + type_offset
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_event_name(panel_hex):
|
def get_event_name(panel_hex):
|
||||||
|
@ -213,6 +217,7 @@ class StaticWitnessLocations:
|
||||||
all_loc_to_id = {
|
all_loc_to_id = {
|
||||||
panel_obj["checkName"]: self.get_id(chex)
|
panel_obj["checkName"]: self.get_id(chex)
|
||||||
for chex, panel_obj in StaticWitnessLogic.CHECKS_BY_HEX.items()
|
for chex, panel_obj in StaticWitnessLogic.CHECKS_BY_HEX.items()
|
||||||
|
if panel_obj["id"]
|
||||||
}
|
}
|
||||||
|
|
||||||
all_loc_to_id = dict(
|
all_loc_to_id = dict(
|
||||||
|
@ -229,12 +234,34 @@ class WitnessPlayerLocations:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, world, player, player_logic: WitnessPlayerLogic):
|
def __init__(self, world, player, player_logic: WitnessPlayerLogic):
|
||||||
|
"""Defines locations AFTER logic changes due to options"""
|
||||||
|
|
||||||
self.PANEL_TYPES_TO_SHUFFLE = {"General", "Laser"}
|
self.PANEL_TYPES_TO_SHUFFLE = {"General", "Laser"}
|
||||||
self.CHECK_LOCATIONS = (
|
self.CHECK_LOCATIONS = (
|
||||||
StaticWitnessLocations.GENERAL_LOCATIONS
|
StaticWitnessLocations.GENERAL_LOCATIONS
|
||||||
)
|
)
|
||||||
|
|
||||||
"""Defines locations AFTER logic changes due to options"""
|
doors = get_option_value(world, player, "shuffle_doors")
|
||||||
|
earlyutm = is_option_enabled(world, player, "early_secret_area")
|
||||||
|
victory = get_option_value(world, player, "victory_condition")
|
||||||
|
lasers = get_option_value(world, player, "challenge_lasers")
|
||||||
|
laser_shuffle = get_option_value(world, player, "shuffle_lasers")
|
||||||
|
|
||||||
|
postgame = set()
|
||||||
|
postgame = postgame | StaticWitnessLocations.CAVES_LOCATIONS
|
||||||
|
postgame = postgame | StaticWitnessLocations.MOUNTAIN_REACHABLE_FROM_BEHIND
|
||||||
|
postgame = postgame | StaticWitnessLocations.MOUNTAIN_UNREACHABLE_FROM_BEHIND
|
||||||
|
|
||||||
|
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | postgame
|
||||||
|
|
||||||
|
if earlyutm or doors >= 2 or (victory == 1 and (lasers <= 11 or laser_shuffle)):
|
||||||
|
postgame -= StaticWitnessLocations.CAVES_LOCATIONS
|
||||||
|
|
||||||
|
if doors >= 2:
|
||||||
|
postgame -= StaticWitnessLocations.MOUNTAIN_REACHABLE_FROM_BEHIND
|
||||||
|
|
||||||
|
if victory != 2:
|
||||||
|
postgame -= StaticWitnessLocations.MOUNTAIN_UNREACHABLE_FROM_BEHIND
|
||||||
|
|
||||||
if is_option_enabled(world, player, "shuffle_discarded_panels"):
|
if is_option_enabled(world, player, "shuffle_discarded_panels"):
|
||||||
self.PANEL_TYPES_TO_SHUFFLE.add("Discard")
|
self.PANEL_TYPES_TO_SHUFFLE.add("Discard")
|
||||||
|
@ -245,18 +272,11 @@ class WitnessPlayerLocations:
|
||||||
if is_option_enabled(world, player, "shuffle_uncommon"):
|
if is_option_enabled(world, player, "shuffle_uncommon"):
|
||||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.UNCOMMON_LOCATIONS
|
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.UNCOMMON_LOCATIONS
|
||||||
|
|
||||||
if is_option_enabled(world, player, "shuffle_hard"):
|
|
||||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.HARD_LOCATIONS
|
|
||||||
|
|
||||||
if is_option_enabled(world, player, "shuffle_symbols") and is_option_enabled(world, player, "shuffle_doors"):
|
|
||||||
if is_option_enabled(world, player, "disable_non_randomized_puzzles"):
|
|
||||||
# This particular combination of logic settings leads to logic so restrictive that generation can fail
|
|
||||||
# Hence, we add some extra sphere 0 locations
|
|
||||||
|
|
||||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.EXTRA_LOCATIONS
|
|
||||||
|
|
||||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | player_logic.ADDED_CHECKS
|
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | player_logic.ADDED_CHECKS
|
||||||
|
|
||||||
|
if not is_option_enabled(world, player, "shuffle_postgame"):
|
||||||
|
self.CHECK_LOCATIONS -= postgame
|
||||||
|
|
||||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS - {
|
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS - {
|
||||||
StaticWitnessLogic.CHECKS_BY_HEX[check_hex]["checkName"]
|
StaticWitnessLogic.CHECKS_BY_HEX[check_hex]["checkName"]
|
||||||
for check_hex in player_logic.COMPLETELY_DISABLED_CHECKS
|
for check_hex in player_logic.COMPLETELY_DISABLED_CHECKS
|
||||||
|
@ -272,7 +292,7 @@ class WitnessPlayerLocations:
|
||||||
)
|
)
|
||||||
|
|
||||||
event_locations = {
|
event_locations = {
|
||||||
p for p in player_logic.NECESSARY_EVENT_PANELS
|
p for p in player_logic.EVENT_PANELS
|
||||||
}
|
}
|
||||||
|
|
||||||
self.EVENT_LOCATION_TABLE = {
|
self.EVENT_LOCATION_TABLE = {
|
||||||
|
|
|
@ -18,22 +18,15 @@ When the world has parsed its options, a second function is called to finalize t
|
||||||
import copy
|
import copy
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from .static_logic import StaticWitnessLogic
|
from .static_logic import StaticWitnessLogic
|
||||||
from .utils import define_new_region, get_disable_unrandomized_list, parse_lambda, get_early_utm_list
|
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
|
||||||
from .Options import is_option_enabled, get_option_value, the_witness_options
|
from .Options import is_option_enabled, get_option_value, the_witness_options
|
||||||
|
|
||||||
|
|
||||||
class WitnessPlayerLogic:
|
class WitnessPlayerLogic:
|
||||||
"""WITNESS LOGIC CLASS"""
|
"""WITNESS LOGIC CLASS"""
|
||||||
|
|
||||||
def update_door_dict(self, panel_hex):
|
|
||||||
item_id = StaticWitnessLogic.ALL_DOOR_ITEM_IDS_BY_HEX.get(panel_hex)
|
|
||||||
|
|
||||||
if item_id is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.DOOR_DICT_FOR_CLIENT[panel_hex] = item_id
|
|
||||||
self.DOOR_CONNECTIONS_TO_SEVER.update(StaticWitnessLogic.CONNECTIONS_TO_SEVER_BY_DOOR_HEX[panel_hex])
|
|
||||||
|
|
||||||
def reduce_req_within_region(self, panel_hex):
|
def reduce_req_within_region(self, panel_hex):
|
||||||
"""
|
"""
|
||||||
Panels in this game often only turn on when other panels are solved.
|
Panels in this game often only turn on when other panels are solved.
|
||||||
|
@ -43,35 +36,42 @@ class WitnessPlayerLogic:
|
||||||
Panels outside of the same region will still be checked manually.
|
Panels outside of the same region will still be checked manually.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
check_obj = StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]
|
||||||
|
|
||||||
|
these_items = frozenset({frozenset()})
|
||||||
|
|
||||||
|
if check_obj["id"]:
|
||||||
these_items = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["items"]
|
these_items = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["items"]
|
||||||
|
|
||||||
real_items = {item[0] for item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME}
|
|
||||||
|
|
||||||
these_items = frozenset({
|
these_items = frozenset({
|
||||||
subset.intersection(real_items)
|
subset.intersection(self.PROG_ITEMS_ACTUALLY_IN_THE_GAME)
|
||||||
for subset in these_items
|
for subset in these_items
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if panel_hex in self.DOOR_ITEMS_BY_ID:
|
||||||
|
door_items = frozenset({frozenset([item]) for item in self.DOOR_ITEMS_BY_ID[panel_hex]})
|
||||||
|
|
||||||
|
all_options = set()
|
||||||
|
|
||||||
|
for items_option in these_items:
|
||||||
|
for dependentItem in door_items:
|
||||||
|
all_options.add(items_option.union(dependentItem))
|
||||||
|
|
||||||
|
return frozenset(all_options)
|
||||||
|
|
||||||
these_panels = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["panels"]
|
these_panels = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["panels"]
|
||||||
|
|
||||||
if StaticWitnessLogic.DOOR_NAMES_BY_HEX.get(panel_hex) in real_items:
|
|
||||||
self.update_door_dict(panel_hex)
|
|
||||||
|
|
||||||
these_panels = frozenset({frozenset()})
|
|
||||||
|
|
||||||
if these_panels == frozenset({frozenset()}):
|
if these_panels == frozenset({frozenset()}):
|
||||||
return these_items
|
return these_items
|
||||||
|
|
||||||
all_options = set()
|
all_options = set()
|
||||||
|
|
||||||
check_obj = StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]
|
|
||||||
|
|
||||||
for option in these_panels:
|
for option in these_panels:
|
||||||
dependent_items_for_option = frozenset({frozenset()})
|
dependent_items_for_option = frozenset({frozenset()})
|
||||||
|
|
||||||
for option_panel in option:
|
for option_panel in option:
|
||||||
new_items = set()
|
|
||||||
dep_obj = StaticWitnessLogic.CHECKS_BY_HEX.get(option_panel)
|
dep_obj = StaticWitnessLogic.CHECKS_BY_HEX.get(option_panel)
|
||||||
|
|
||||||
if option_panel in {"7 Lasers", "11 Lasers"}:
|
if option_panel in {"7 Lasers", "11 Lasers"}:
|
||||||
new_items = frozenset({frozenset([option_panel])})
|
new_items = frozenset({frozenset([option_panel])})
|
||||||
# If a panel turns on when a panel in a different region turns on,
|
# If a panel turns on when a panel in a different region turns on,
|
||||||
|
@ -101,8 +101,34 @@ class WitnessPlayerLogic:
|
||||||
return frozenset(all_options)
|
return frozenset(all_options)
|
||||||
|
|
||||||
def make_single_adjustment(self, adj_type, line):
|
def make_single_adjustment(self, adj_type, line):
|
||||||
|
from . import StaticWitnessItems
|
||||||
"""Makes a single logic adjustment based on additional logic file"""
|
"""Makes a single logic adjustment based on additional logic file"""
|
||||||
|
|
||||||
|
if adj_type == "Items":
|
||||||
|
if line not in StaticWitnessItems.ALL_ITEM_TABLE:
|
||||||
|
raise RuntimeError("Item \"" + line + "\" does not exit.")
|
||||||
|
|
||||||
|
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.add(line)
|
||||||
|
|
||||||
|
if line in StaticWitnessLogic.ALL_DOOR_ITEMS_AS_DICT:
|
||||||
|
panel_hexes = StaticWitnessLogic.ALL_DOOR_ITEMS_AS_DICT[line][2]
|
||||||
|
for panel_hex in panel_hexes:
|
||||||
|
self.DOOR_ITEMS_BY_ID.setdefault(panel_hex, set()).add(line)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
if adj_type == "Remove Items":
|
||||||
|
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.discard(line)
|
||||||
|
|
||||||
|
if line in StaticWitnessLogic.ALL_DOOR_ITEMS_AS_DICT:
|
||||||
|
panel_hexes = StaticWitnessLogic.ALL_DOOR_ITEMS_AS_DICT[line][2]
|
||||||
|
for panel_hex in panel_hexes:
|
||||||
|
if panel_hex in self.DOOR_ITEMS_BY_ID:
|
||||||
|
self.DOOR_ITEMS_BY_ID[panel_hex].discard(line)
|
||||||
|
|
||||||
|
if adj_type == "Starting Inventory":
|
||||||
|
self.STARTING_INVENTORY.add(line)
|
||||||
|
|
||||||
if adj_type == "Event Items":
|
if adj_type == "Event Items":
|
||||||
line_split = line.split(" - ")
|
line_split = line.split(" - ")
|
||||||
hex_set = line_split[1].split(",")
|
hex_set = line_split[1].split(",")
|
||||||
|
@ -130,6 +156,11 @@ class WitnessPlayerLogic:
|
||||||
if adj_type == "Requirement Changes":
|
if adj_type == "Requirement Changes":
|
||||||
line_split = line.split(" - ")
|
line_split = line.split(" - ")
|
||||||
|
|
||||||
|
requirement = {
|
||||||
|
"panels": parse_lambda(line_split[1]),
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(line_split) > 2:
|
||||||
required_items = parse_lambda(line_split[2])
|
required_items = parse_lambda(line_split[2])
|
||||||
items_actually_in_the_game = {item[0] for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS}
|
items_actually_in_the_game = {item[0] for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS}
|
||||||
required_items = frozenset(
|
required_items = frozenset(
|
||||||
|
@ -137,10 +168,7 @@ class WitnessPlayerLogic:
|
||||||
for subset in required_items
|
for subset in required_items
|
||||||
)
|
)
|
||||||
|
|
||||||
requirement = {
|
requirement["items"] = required_items
|
||||||
"panels": parse_lambda(line_split[1]),
|
|
||||||
"items": required_items
|
|
||||||
}
|
|
||||||
|
|
||||||
self.DEPENDENT_REQUIREMENTS_BY_HEX[line_split[0]] = requirement
|
self.DEPENDENT_REQUIREMENTS_BY_HEX[line_split[0]] = requirement
|
||||||
|
|
||||||
|
@ -151,11 +179,6 @@ class WitnessPlayerLogic:
|
||||||
|
|
||||||
self.COMPLETELY_DISABLED_CHECKS.add(panel_hex)
|
self.COMPLETELY_DISABLED_CHECKS.add(panel_hex)
|
||||||
|
|
||||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME = {
|
|
||||||
item for item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME
|
|
||||||
if item[0] != StaticWitnessLogic.DOOR_NAMES_BY_HEX.get(panel_hex)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if adj_type == "Region Changes":
|
if adj_type == "Region Changes":
|
||||||
|
@ -189,18 +212,25 @@ class WitnessPlayerLogic:
|
||||||
adjustment_linesets_in_order.append(get_disable_unrandomized_list())
|
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 is_option_enabled(world, player, "shuffle_symbols") or "shuffle_symbols" not in the_witness_options.keys():
|
||||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.update(StaticWitnessLogic.ALL_SYMBOL_ITEMS)
|
adjustment_linesets_in_order.append(get_symbol_shuffle_list())
|
||||||
|
|
||||||
if is_option_enabled(world, player, "shuffle_doors"):
|
if get_option_value(world, player, "shuffle_doors") == 1:
|
||||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.update(StaticWitnessLogic.ALL_DOOR_ITEMS)
|
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"):
|
if is_option_enabled(world, player, "early_secret_area"):
|
||||||
adjustment_linesets_in_order.append(get_early_utm_list())
|
adjustment_linesets_in_order.append(get_early_utm_list())
|
||||||
else:
|
|
||||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME = {
|
if is_option_enabled(world, player, "shuffle_lasers"):
|
||||||
item for item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME
|
adjustment_linesets_in_order.append(get_laser_shuffle())
|
||||||
if item[0] != "Mountaintop River Shape Power On"
|
|
||||||
}
|
|
||||||
|
|
||||||
for adjustment_lineset in adjustment_linesets_in_order:
|
for adjustment_lineset in adjustment_linesets_in_order:
|
||||||
current_adjustment_type = None
|
current_adjustment_type = None
|
||||||
|
@ -233,62 +263,32 @@ class WitnessPlayerLogic:
|
||||||
pair = (name, self.EVENT_ITEM_NAMES[panel])
|
pair = (name, self.EVENT_ITEM_NAMES[panel])
|
||||||
return pair
|
return pair
|
||||||
|
|
||||||
def _regions_are_adjacent(self, region1, region2):
|
|
||||||
for connection in self.CONNECTIONS_BY_REGION_NAME[region1]:
|
|
||||||
if connection[0] == region2:
|
|
||||||
return True
|
|
||||||
|
|
||||||
for connection in self.CONNECTIONS_BY_REGION_NAME[region2]:
|
|
||||||
if connection[0] == region1:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def make_event_panel_lists(self):
|
def make_event_panel_lists(self):
|
||||||
"""
|
"""
|
||||||
Special event panel data structures
|
Special event panel data structures
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for region_conn in self.CONNECTIONS_BY_REGION_NAME.values():
|
|
||||||
for region_and_option in region_conn:
|
|
||||||
for panelset in region_and_option[1]:
|
|
||||||
for panel in panelset:
|
|
||||||
self.EVENT_PANELS_FROM_REGIONS.add(panel)
|
|
||||||
|
|
||||||
self.ALWAYS_EVENT_NAMES_BY_HEX[self.VICTORY_LOCATION] = "Victory"
|
self.ALWAYS_EVENT_NAMES_BY_HEX[self.VICTORY_LOCATION] = "Victory"
|
||||||
|
|
||||||
self.ORIGINAL_EVENT_PANELS.update(self.EVENT_PANELS_FROM_PANELS)
|
for region_name, connections in self.CONNECTIONS_BY_REGION_NAME.items():
|
||||||
self.ORIGINAL_EVENT_PANELS.update(self.EVENT_PANELS_FROM_REGIONS)
|
for connection in connections:
|
||||||
|
for panel_req in connection[1]:
|
||||||
for panel in self.EVENT_PANELS_FROM_REGIONS:
|
for panel in panel_req:
|
||||||
for region_name, region in StaticWitnessLogic.ALL_REGIONS_BY_NAME.items():
|
if panel == "TrueOneWay":
|
||||||
for connection in self.CONNECTIONS_BY_REGION_NAME[region_name]:
|
|
||||||
connected_r = connection[0]
|
|
||||||
if connected_r not in StaticWitnessLogic.ALL_REGIONS_BY_NAME:
|
|
||||||
continue
|
continue
|
||||||
if region_name == "Boat" or connected_r == "Boat":
|
|
||||||
continue
|
|
||||||
connected_r = StaticWitnessLogic.ALL_REGIONS_BY_NAME[connected_r]
|
|
||||||
if not any([panel in option for option in connection[1]]):
|
|
||||||
continue
|
|
||||||
if panel not in region["panels"] | connected_r["panels"]:
|
|
||||||
self.NECESSARY_EVENT_PANELS.add(panel)
|
|
||||||
|
|
||||||
for event_panel in self.EVENT_PANELS_FROM_PANELS:
|
if StaticWitnessLogic.CHECKS_BY_HEX[panel]["region"]["name"] != region_name:
|
||||||
for panel, panel_req in self.REQUIREMENTS_BY_HEX.items():
|
self.EVENT_PANELS_FROM_REGIONS.add(panel)
|
||||||
if any([event_panel in item_set for item_set in panel_req]):
|
|
||||||
region1 = StaticWitnessLogic.CHECKS_BY_HEX[panel]["region"]["name"]
|
|
||||||
region2 = StaticWitnessLogic.CHECKS_BY_HEX[event_panel]["region"]["name"]
|
|
||||||
|
|
||||||
if not self._regions_are_adjacent(region1, region2):
|
self.EVENT_PANELS.update(self.EVENT_PANELS_FROM_PANELS)
|
||||||
self.NECESSARY_EVENT_PANELS.add(event_panel)
|
self.EVENT_PANELS.update(self.EVENT_PANELS_FROM_REGIONS)
|
||||||
|
|
||||||
for always_hex, always_item in self.ALWAYS_EVENT_NAMES_BY_HEX.items():
|
for always_hex, always_item in self.ALWAYS_EVENT_NAMES_BY_HEX.items():
|
||||||
self.ALWAYS_EVENT_HEX_CODES.add(always_hex)
|
self.ALWAYS_EVENT_HEX_CODES.add(always_hex)
|
||||||
self.NECESSARY_EVENT_PANELS.add(always_hex)
|
self.EVENT_PANELS.add(always_hex)
|
||||||
self.EVENT_ITEM_NAMES[always_hex] = always_item
|
self.EVENT_ITEM_NAMES[always_hex] = always_item
|
||||||
|
|
||||||
for panel in self.NECESSARY_EVENT_PANELS:
|
for panel in self.EVENT_PANELS:
|
||||||
pair = self.make_event_item_pair(panel)
|
pair = self.make_event_item_pair(panel)
|
||||||
self.EVENT_ITEM_PAIRS[pair[0]] = pair[1]
|
self.EVENT_ITEM_PAIRS[pair[0]] = pair[1]
|
||||||
|
|
||||||
|
@ -297,8 +297,8 @@ class WitnessPlayerLogic:
|
||||||
self.EVENT_PANELS_FROM_REGIONS = set()
|
self.EVENT_PANELS_FROM_REGIONS = set()
|
||||||
|
|
||||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME = set()
|
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME = set()
|
||||||
self.DOOR_DICT_FOR_CLIENT = dict()
|
self.DOOR_ITEMS_BY_ID = dict()
|
||||||
self.DOOR_CONNECTIONS_TO_SEVER = set()
|
self.STARTING_INVENTORY = set()
|
||||||
|
|
||||||
self.CONNECTIONS_BY_REGION_NAME = copy.copy(StaticWitnessLogic.STATIC_CONNECTIONS_BY_REGION_NAME)
|
self.CONNECTIONS_BY_REGION_NAME = copy.copy(StaticWitnessLogic.STATIC_CONNECTIONS_BY_REGION_NAME)
|
||||||
self.DEPENDENT_REQUIREMENTS_BY_HEX = copy.copy(StaticWitnessLogic.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX)
|
self.DEPENDENT_REQUIREMENTS_BY_HEX = copy.copy(StaticWitnessLogic.STATIC_DEPENDENT_REQUIREMENTS_BY_HEX)
|
||||||
|
@ -306,8 +306,7 @@ class WitnessPlayerLogic:
|
||||||
|
|
||||||
# Determining which panels need to be events is a difficult process.
|
# Determining which panels need to be events is a difficult process.
|
||||||
# At the end, we will have EVENT_ITEM_PAIRS for all the necessary ones.
|
# At the end, we will have EVENT_ITEM_PAIRS for all the necessary ones.
|
||||||
self.ORIGINAL_EVENT_PANELS = set()
|
self.EVENT_PANELS = set()
|
||||||
self.NECESSARY_EVENT_PANELS = set()
|
|
||||||
self.EVENT_ITEM_PAIRS = dict()
|
self.EVENT_ITEM_PAIRS = dict()
|
||||||
self.ALWAYS_EVENT_HEX_CODES = set()
|
self.ALWAYS_EVENT_HEX_CODES = set()
|
||||||
self.COMPLETELY_DISABLED_CHECKS = set()
|
self.COMPLETELY_DISABLED_CHECKS = set()
|
||||||
|
@ -320,42 +319,63 @@ class WitnessPlayerLogic:
|
||||||
"0x00037": "Monastery Branch Panels Activate",
|
"0x00037": "Monastery Branch Panels Activate",
|
||||||
"0x0A079": "Access to Bunker Laser",
|
"0x0A079": "Access to Bunker Laser",
|
||||||
"0x0A3B5": "Door to Tutorial Discard Opens",
|
"0x0A3B5": "Door to Tutorial Discard Opens",
|
||||||
|
"0x00139": "Keep Hedges 2 Turns On",
|
||||||
|
"0x019DC": "Keep Hedges 3 Turns On",
|
||||||
|
"0x019E7": "Keep Hedges 4 Turns On",
|
||||||
"0x01D3F": "Keep Laser Panel (Pressure Plates) Activates",
|
"0x01D3F": "Keep Laser Panel (Pressure Plates) Activates",
|
||||||
"0x09F7F": "Mountain Access",
|
"0x09F7F": "Mountain Access",
|
||||||
"0x0367C": "Quarry Laser Mill Requirement Met",
|
"0x0367C": "Quarry Laser Mill Requirement Met",
|
||||||
"0x009A1": "Swamp Rotating Bridge Near Side",
|
"0x009A1": "Swamp Rotated Shapers 1 Activates",
|
||||||
"0x00006": "Swamp Cyan Water Drains",
|
"0x00006": "Swamp Cyan Water Drains",
|
||||||
"0x00990": "Swamp Broken Shapers 1 Activates",
|
"0x00990": "Swamp Broken Shapers 1 Activates",
|
||||||
"0x0A8DC": "Lower Avoid 6 Activates",
|
"0x0A8DC": "Lower Avoid 6 Activates",
|
||||||
"0x0000A": "Swamp More Rotated Shapers 1 Access",
|
"0x0000A": "Swamp More Rotated Shapers 1 Access",
|
||||||
"0x09ED8": "Inside Mountain Second Layer Both Light Bridges Solved",
|
"0x09E86": "Inside Mountain Second Layer Blue Bridge Access",
|
||||||
|
"0x09ED8": "Inside Mountain Second Layer Yellow Bridge Access",
|
||||||
"0x0A3D0": "Quarry Laser Boathouse Requirement Met",
|
"0x0A3D0": "Quarry Laser Boathouse Requirement Met",
|
||||||
"0x00596": "Swamp Red Water Drains",
|
"0x00596": "Swamp Red Water Drains",
|
||||||
"0x28B39": "Town Tower 4th Door Opens",
|
"0x00E3A": "Swamp Purple Water Drains",
|
||||||
"0x0343A": "Door to Symmetry Island Powers On",
|
"0x0343A": "Door to Symmetry Island Powers On",
|
||||||
"0xFFF00": "Inside Mountain Bottom Layer Discard Turns On"
|
"0xFFF00": "Inside Mountain Bottom Layer 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",
|
||||||
|
"0x03BB0": "Town Church Lattice Vision From Outside",
|
||||||
|
"0x28AC1": "Town Shapers & Dots & Eraser 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 Mill Ramp Activation From Above",
|
||||||
|
"0x03679": "Quarry Mill Lift Lowering While Standing On It",
|
||||||
|
"0x2FAF6": "Tutorial Gate Secret Solution Knowledge",
|
||||||
|
"0x079DF": "Town Hexagonal Reflection Turns On",
|
||||||
|
"0x17DA2": "Right Orange Bridge Fully Extended",
|
||||||
|
"0x19B24": "Shadows Lower Avoid Patterns Visible",
|
||||||
|
"0x2700B": "Open Door to Treehouse Laser House",
|
||||||
|
"0x00055": "Orchard Apple Trees 4 Turns On",
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ALWAYS_EVENT_NAMES_BY_HEX = {
|
self.ALWAYS_EVENT_NAMES_BY_HEX = {
|
||||||
"0x0360D": "Symmetry Laser Activation",
|
"0x00509": "Symmetry Laser Activation",
|
||||||
"0x03608": "Desert Laser Activation",
|
"0x012FB": "Desert Laser Activation",
|
||||||
"0x09F98": "Desert Laser Redirection",
|
"0x09F98": "Desert Laser Redirection",
|
||||||
"0x03612": "Quarry Laser Activation",
|
"0x01539": "Quarry Laser Activation",
|
||||||
"0x19650": "Shadows Laser Activation",
|
"0x181B3": "Shadows Laser Activation",
|
||||||
"0x0360E": "Keep Laser Activation",
|
"0x014BB": "Keep Laser Activation",
|
||||||
"0x03317": "Keep Laser Activation",
|
"0x17C65": "Monastery Laser Activation",
|
||||||
"0x17CA4": "Monastery Laser Activation",
|
"0x032F9": "Town Laser Activation",
|
||||||
"0x032F5": "Town Laser Activation",
|
"0x00274": "Jungle Laser Activation",
|
||||||
"0x03616": "Jungle Laser Activation",
|
"0x0C2B2": "Bunker Laser Activation",
|
||||||
"0x09DE0": "Bunker Laser Activation",
|
"0x00BF6": "Swamp Laser Activation",
|
||||||
"0x03615": "Swamp Laser Activation",
|
"0x028A4": "Treehouse Laser Activation",
|
||||||
"0x03613": "Treehouse Laser Activation",
|
|
||||||
"0x03535": "Shipwreck Video Pattern Knowledge",
|
"0x03535": "Shipwreck Video Pattern Knowledge",
|
||||||
"0x03542": "Mountain Video Pattern Knowledge",
|
"0x03542": "Mountain Video Pattern Knowledge",
|
||||||
"0x0339E": "Desert Video Pattern Knowledge",
|
"0x0339E": "Desert Video Pattern Knowledge",
|
||||||
"0x03481": "Tutorial Video Pattern Knowledge",
|
"0x03481": "Tutorial Video Pattern Knowledge",
|
||||||
"0x03702": "Jungle Video Pattern Knowledge",
|
"0x03702": "Jungle Video Pattern Knowledge",
|
||||||
"0x2FAF6": "Theater Walkway Video Pattern Knowledge",
|
"0x0356B": "Challenge Video Pattern Knowledge",
|
||||||
"0x09F7F": "Mountaintop Trap Door Turns On",
|
"0x09F7F": "Mountaintop Trap Door Turns On",
|
||||||
"0x17C34": "Mountain Access",
|
"0x17C34": "Mountain Access",
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,10 @@ class WitnessRegions:
|
||||||
source_region = world.get_region(source, player)
|
source_region = world.get_region(source, player)
|
||||||
target_region = world.get_region(target, player)
|
target_region = world.get_region(target, player)
|
||||||
|
|
||||||
|
#print(source_region)
|
||||||
|
#print(target_region)
|
||||||
|
#print("---")
|
||||||
|
|
||||||
connection = Entrance(
|
connection = Entrance(
|
||||||
player,
|
player,
|
||||||
source + " to " + target + " via " + str(panel_hex_to_solve_set),
|
source + " to " + target + " via " + str(panel_hex_to_solve_set),
|
||||||
|
@ -76,10 +80,17 @@ class WitnessRegions:
|
||||||
for connection in player_logic.CONNECTIONS_BY_REGION_NAME[region_name]:
|
for connection in player_logic.CONNECTIONS_BY_REGION_NAME[region_name]:
|
||||||
if connection[0] == "Entry":
|
if connection[0] == "Entry":
|
||||||
continue
|
continue
|
||||||
self.connect(world, player, region_name,
|
|
||||||
connection[0], player_logic, connection[1])
|
if connection[1] == frozenset({frozenset(["TrueOneWay"])}):
|
||||||
self.connect(world, player, connection[0],
|
self.connect(world, player, region_name, connection[0], player_logic, frozenset({frozenset()}))
|
||||||
region_name, player_logic, connection[1])
|
continue
|
||||||
|
|
||||||
|
for subset in connection[1]:
|
||||||
|
if all({panel in player_logic.DOOR_ITEMS_BY_ID for panel in subset}):
|
||||||
|
if all({StaticWitnessLogic.CHECKS_BY_HEX[panel]["id"] is None for panel in subset}):
|
||||||
|
self.connect(world, player, connection[0], region_name, player_logic, frozenset({subset}))
|
||||||
|
|
||||||
|
self.connect(world, player, region_name, connection[0], player_logic, connection[1])
|
||||||
|
|
||||||
world.get_entrance("The Splashscreen?", player).connect(
|
world.get_entrance("The Splashscreen?", player).connect(
|
||||||
world.get_region('First Hallway', player)
|
world.get_region('First Hallway', player)
|
||||||
|
|
|
@ -22,6 +22,21 @@ class WitnessLogic(LogicMixin):
|
||||||
def _witness_has_lasers(self, world, player: int, amount: int) -> bool:
|
def _witness_has_lasers(self, world, player: int, amount: int) -> bool:
|
||||||
lasers = 0
|
lasers = 0
|
||||||
|
|
||||||
|
if is_option_enabled(world, player, "shuffle_lasers"):
|
||||||
|
lasers += int(self.has("Symmetry Laser", player))
|
||||||
|
lasers += int(self.has("Desert Laser", player)
|
||||||
|
and self.has("Desert Laser Redirection", player))
|
||||||
|
lasers += int(self.has("Town Laser", player))
|
||||||
|
lasers += int(self.has("Monastery Laser", player))
|
||||||
|
lasers += int(self.has("Keep Laser", player))
|
||||||
|
lasers += int(self.has("Quarry Laser", player))
|
||||||
|
lasers += int(self.has("Treehouse Laser", player))
|
||||||
|
lasers += int(self.has("Jungle Laser", player))
|
||||||
|
lasers += int(self.has("Bunker Laser", player))
|
||||||
|
lasers += int(self.has("Swamp Laser", player))
|
||||||
|
lasers += int(self.has("Shadows Laser", player))
|
||||||
|
return lasers >= amount
|
||||||
|
|
||||||
lasers += int(self.has("Symmetry Laser Activation", player))
|
lasers += int(self.has("Symmetry Laser Activation", player))
|
||||||
lasers += int(self.has("Desert Laser Activation", player)
|
lasers += int(self.has("Desert Laser Activation", player)
|
||||||
and self.has("Desert Laser Redirection", player))
|
and self.has("Desert Laser Redirection", player))
|
||||||
|
@ -48,11 +63,8 @@ class WitnessLogic(LogicMixin):
|
||||||
if (check_name + " Solved" in locat.EVENT_LOCATION_TABLE
|
if (check_name + " Solved" in locat.EVENT_LOCATION_TABLE
|
||||||
and not self.has(player_logic.EVENT_ITEM_PAIRS[check_name + " Solved"], player)):
|
and not self.has(player_logic.EVENT_ITEM_PAIRS[check_name + " Solved"], player)):
|
||||||
return False
|
return False
|
||||||
if panel not in player_logic.ORIGINAL_EVENT_PANELS and not self.can_reach(check_name, "Location", player):
|
if (check_name + " Solved" not in locat.EVENT_LOCATION_TABLE
|
||||||
return False
|
and not self._witness_meets_item_requirements(panel, world, player, player_logic, locat)):
|
||||||
if (panel in player_logic.ORIGINAL_EVENT_PANELS
|
|
||||||
and check_name + " Solved" not in locat.EVENT_LOCATION_TABLE
|
|
||||||
and not self._witness_safe_manual_panel_check(panel, world, player, player_logic, locat)):
|
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -79,8 +91,10 @@ class WitnessLogic(LogicMixin):
|
||||||
if not self._witness_has_lasers(world, player, get_option_value(world, player, "challenge_lasers")):
|
if not self._witness_has_lasers(world, player, get_option_value(world, player, "challenge_lasers")):
|
||||||
valid_option = False
|
valid_option = False
|
||||||
break
|
break
|
||||||
elif item in player_logic.ORIGINAL_EVENT_PANELS:
|
elif item in player_logic.EVENT_PANELS:
|
||||||
valid_option = self._witness_can_solve_panel(item, world, player, player_logic, locat)
|
if not self._witness_can_solve_panel(item, world, player, player_logic, locat):
|
||||||
|
valid_option = False
|
||||||
|
break
|
||||||
elif not self.has(item, player):
|
elif not self.has(item, player):
|
||||||
valid_option = False
|
valid_option = False
|
||||||
break
|
break
|
||||||
|
@ -90,24 +104,6 @@ class WitnessLogic(LogicMixin):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _witness_safe_manual_panel_check(self, panel, world, player, player_logic: WitnessPlayerLogic, locat):
|
|
||||||
"""
|
|
||||||
nested can_reach can cause problems, but only if the region being
|
|
||||||
checked is neither of the two original regions from the first
|
|
||||||
can_reach.
|
|
||||||
A nested can_reach is okay here because the only panels this
|
|
||||||
function is called on are panels that exist on either side of all
|
|
||||||
connections they are required for.
|
|
||||||
The spoiler log looks so much nicer this way,
|
|
||||||
it gets rid of a bunch of event items, only leaving a couple. :)
|
|
||||||
"""
|
|
||||||
region = StaticWitnessLogic.CHECKS_BY_HEX[panel]["region"]["name"]
|
|
||||||
|
|
||||||
return (
|
|
||||||
self._witness_meets_item_requirements(panel, world, player, player_logic, locat)
|
|
||||||
and self.can_reach(region, "Region", player)
|
|
||||||
)
|
|
||||||
|
|
||||||
def _witness_can_solve_panels(self, panel_hex_to_solve_set, world, player, player_logic: WitnessPlayerLogic, locat):
|
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.
|
Checks whether a set of panels can be solved.
|
||||||
|
@ -120,7 +116,12 @@ class WitnessLogic(LogicMixin):
|
||||||
valid_option = True
|
valid_option = True
|
||||||
|
|
||||||
for panel in option:
|
for panel in option:
|
||||||
if not self._witness_can_solve_panel(panel, world, player, player_logic, locat):
|
if panel in player_logic.DOOR_ITEMS_BY_ID:
|
||||||
|
if all({not self.has(item, player) for item in player_logic.DOOR_ITEMS_BY_ID[panel]}):
|
||||||
|
valid_option = False
|
||||||
|
break
|
||||||
|
|
||||||
|
elif not self._witness_can_solve_panel(panel, world, player, player_logic, locat):
|
||||||
valid_option = False
|
valid_option = False
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
Event Items:
|
Event Items:
|
||||||
Shadows Laser Activation - 0x00021,0x17D28,0x17C71
|
|
||||||
Keep Laser Activation - 0x03317
|
|
||||||
Bunker Laser Activation - 0x00061,0x17D01,0x17C42
|
|
||||||
Monastery Laser Activation - 0x00A5B,0x17CE7,0x17FA9,0x17CA4
|
|
||||||
Town Tower 4th Door Opens - 0x17CFB,0x3C12B,0x00B8D,0x17CF7
|
Town Tower 4th Door Opens - 0x17CFB,0x3C12B,0x00B8D,0x17CF7
|
||||||
|
Monastery Laser Activation - 0x00A5B,0x17CE7,0x17FA9,0x17CA4
|
||||||
|
Bunker Laser Activation - 0x00061,0x17D01,0x17C42
|
||||||
|
Shadows Laser Activation - 0x00021,0x17D28,0x17C71
|
||||||
|
|
||||||
Requirement Changes:
|
Requirement Changes:
|
||||||
0x17CA4 - True - True
|
0x17C65 - 0x00A5B | 0x17CE7 | 0x17FA9 | 0x17CA4
|
||||||
0x28B39 - 0x2896A - Reflection
|
0x0C2B2 - 0x00061 | 0x17D01 | 0x17C42
|
||||||
|
0x181B3 - 0x00021 | 0x17D28 | 0x17C71
|
||||||
|
0x28B39 - True - Reflection
|
||||||
0x17CAB - True - True
|
0x17CAB - True - True
|
||||||
|
|
||||||
Region Changes:
|
|
||||||
Quarry (Quarry) - Outside Quarry - 0x17C09 - Quarry Mill - 0x275ED - Quarry Mill - 0x17CAC
|
|
||||||
|
|
||||||
Disabled Locations:
|
Disabled Locations:
|
||||||
0x03505 (Tutorial Gate Close)
|
0x03505 (Tutorial Gate Close)
|
||||||
0x0C335 (Tutorial Pillar)
|
0x0C335 (Tutorial Pillar)
|
|
@ -0,0 +1,31 @@
|
||||||
|
Items:
|
||||||
|
Glass Factory Entry Door (Panel)
|
||||||
|
Door to Symmetry Island Lower (Panel)
|
||||||
|
Door to Symmetry Island Upper (Panel)
|
||||||
|
Door to Desert Flood Light Room (Panel)
|
||||||
|
Desert Flood Room Flood Controls (Panel)
|
||||||
|
Quarry Door to Mill (Panel)
|
||||||
|
Quarry Mill Ramp Controls (Panel)
|
||||||
|
Quarry Mill Elevator Controls (Panel)
|
||||||
|
Quarry Boathouse Ramp Height Control (Panel)
|
||||||
|
Quarry Boathouse Ramp Horizontal Control (Panel)
|
||||||
|
Shadows Door Timer (Panel)
|
||||||
|
Monastery Entry Door Left (Panel)
|
||||||
|
Monastery Entry Door Right (Panel)
|
||||||
|
Town Door to RGB House (Panel)
|
||||||
|
Town Door to Church (Panel)
|
||||||
|
Town Maze Panel (Drop-Down Staircase) (Panel)
|
||||||
|
Windmill Door (Panel)
|
||||||
|
Treehouse First & Second Doors (Panel)
|
||||||
|
Treehouse Third Door (Panel)
|
||||||
|
Treehouse Laser House Door Timer (Panel)
|
||||||
|
Treehouse Shortcut Drop-Down Bridge (Panel)
|
||||||
|
Jungle Popup Wall (Panel)
|
||||||
|
Bunker Entry Door (Panel)
|
||||||
|
Inside Bunker Door to Bunker Proper (Panel)
|
||||||
|
Bunker Elevator Control (Panel)
|
||||||
|
Swamp Entry Door (Panel)
|
||||||
|
Swamp Sliding Bridge (Panel)
|
||||||
|
Swamp Rotating Bridge (Panel)
|
||||||
|
Swamp Maze Control (Panel)
|
||||||
|
Boat
|
|
@ -0,0 +1,201 @@
|
||||||
|
Items:
|
||||||
|
Outside Tutorial Optional Door
|
||||||
|
Outside Tutorial Outpost Entry Door
|
||||||
|
Outside Tutorial Outpost Exit Door
|
||||||
|
Glass Factory Entry Door
|
||||||
|
Glass Factory Back Wall
|
||||||
|
Symmetry Island Lower Door
|
||||||
|
Symmetry Island Upper Door
|
||||||
|
Orchard Middle Gate
|
||||||
|
Orchard Final Gate
|
||||||
|
Desert Door to Flood Light Room
|
||||||
|
Desert Door to Pond Room
|
||||||
|
Desert Door to Water Levels Room
|
||||||
|
Desert Door to Elevator Room
|
||||||
|
Quarry Main Entry 1
|
||||||
|
Quarry Main Entry 2
|
||||||
|
Quarry Door to Mill
|
||||||
|
Quarry Mill Side Door
|
||||||
|
Quarry Mill Rooftop Shortcut
|
||||||
|
Quarry Mill Stairs
|
||||||
|
Quarry Boathouse Boat Staircase
|
||||||
|
Quarry Boathouse First Barrier
|
||||||
|
Quarry Boathouse Shortcut
|
||||||
|
Shadows Timed Door
|
||||||
|
Shadows Laser Room Right Door
|
||||||
|
Shadows Laser Room Left Door
|
||||||
|
Shadows Barrier to Quarry
|
||||||
|
Shadows Barrier to Ledge
|
||||||
|
Keep Hedge Maze 1 Exit Door
|
||||||
|
Keep Pressure Plates 1 Exit Door
|
||||||
|
Keep Hedge Maze 2 Shortcut
|
||||||
|
Keep Hedge Maze 2 Exit Door
|
||||||
|
Keep Hedge Maze 3 Shortcut
|
||||||
|
Keep Hedge Maze 3 Exit Door
|
||||||
|
Keep Hedge Maze 4 Shortcut
|
||||||
|
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 Shortcut to Shadows
|
||||||
|
Keep Tower Shortcut
|
||||||
|
Monastery Shortcut
|
||||||
|
Monastery Inner Door
|
||||||
|
Monastery Outer Door
|
||||||
|
Monastery Door to Garden
|
||||||
|
Town Cargo Box Door
|
||||||
|
Town Wooden Roof Staircase
|
||||||
|
Town Tinted Door to RGB House
|
||||||
|
Town Door to Church
|
||||||
|
Town Maze Staircase
|
||||||
|
Town Windmill Door
|
||||||
|
Town RGB House Staircase
|
||||||
|
Town Tower Blue Panels Door
|
||||||
|
Town Tower Lattice Door
|
||||||
|
Town Tower Environmental Set Door
|
||||||
|
Town Tower Wooden Roof Set Door
|
||||||
|
Theater Entry Door
|
||||||
|
Theater Exit Door Left
|
||||||
|
Theater Exit Door Right
|
||||||
|
Jungle Bamboo Shortcut to River
|
||||||
|
Jungle Popup Wall
|
||||||
|
River Shortcut to Monastery Garden
|
||||||
|
Bunker Bunker Entry Door
|
||||||
|
Bunker Tinted Glass Door
|
||||||
|
Bunker Door to Ultraviolet Room
|
||||||
|
Bunker Door to Elevator
|
||||||
|
Swamp Entry Door
|
||||||
|
Swamp Door to Broken Shapers
|
||||||
|
Swamp Platform Shortcut Door
|
||||||
|
Swamp Cyan Water Pump
|
||||||
|
Swamp Door to Rotated Shapers
|
||||||
|
Swamp Red Water Pump
|
||||||
|
Swamp Red Underwater Exit
|
||||||
|
Swamp Blue Water Pump
|
||||||
|
Swamp Purple Water Pump
|
||||||
|
Swamp Near Laser Shortcut
|
||||||
|
Treehouse First Door
|
||||||
|
Treehouse Second Door
|
||||||
|
Treehouse Beyond Yellow Bridge Door
|
||||||
|
Treehouse Drawbridge
|
||||||
|
Treehouse Timed Door to Laser House
|
||||||
|
Inside Mountain First Layer Exit Door
|
||||||
|
Inside Mountain Second Layer Staircase Near
|
||||||
|
Inside Mountain Second Layer Exit Door
|
||||||
|
Inside Mountain Second Layer Staircase Far
|
||||||
|
Inside Mountain Giant Puzzle Exit Door
|
||||||
|
Inside Mountain Door to Final Room
|
||||||
|
Inside Mountain Bottom Layer Rock
|
||||||
|
Inside Mountain Door to Secret Area
|
||||||
|
Caves Pillar Door
|
||||||
|
Caves Mountain Shortcut
|
||||||
|
Caves Swamp Shortcut
|
||||||
|
Challenge Entry Door
|
||||||
|
Challenge Door to Theater Walkway
|
||||||
|
Theater Walkway Door to Windmill Interior
|
||||||
|
Theater Walkway Door to Desert Elevator Room
|
||||||
|
Theater Walkway Door to Town
|
||||||
|
|
||||||
|
Added Locations:
|
||||||
|
Outside Tutorial Door to Outpost Panel
|
||||||
|
Outside Tutorial Exit Door from Outpost Panel
|
||||||
|
Glass Factory Entry Door Panel
|
||||||
|
Glass Factory Vertical Symmetry 5
|
||||||
|
Symmetry Island Door to Symmetry Island Lower Panel
|
||||||
|
Symmetry Island Door to Symmetry Island Upper Panel
|
||||||
|
Orchard Apple Tree 3
|
||||||
|
Orchard Apple Tree 5
|
||||||
|
Desert Door to Desert Flood Light Room Panel
|
||||||
|
Desert Artificial Light Reflection 3
|
||||||
|
Desert Door to Water Levels Room Panel
|
||||||
|
Desert Flood Reflection 6
|
||||||
|
Quarry Door to Quarry 1 Panel
|
||||||
|
Quarry Door to Quarry 2 Panel
|
||||||
|
Quarry Door to Mill Right
|
||||||
|
Quarry Door to Mill Left
|
||||||
|
Quarry Mill Ground Floor Shortcut Door Panel
|
||||||
|
Quarry Mill Door to Outside Quarry Stairs Panel
|
||||||
|
Quarry Mill Stair Control
|
||||||
|
Quarry Boathouse Shortcut Door Panel
|
||||||
|
Shadows Door Timer Inside
|
||||||
|
Shadows Door Timer Outside
|
||||||
|
Shadows Environmental Avoid 8
|
||||||
|
Shadows Follow 5
|
||||||
|
Shadows Lower Avoid 3
|
||||||
|
Shadows Lower Avoid 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 Shortcut to Shadows Panel
|
||||||
|
Keep Tower Shortcut to Keep Panel
|
||||||
|
Monastery Shortcut Door Panel
|
||||||
|
Monastery Door Open Left
|
||||||
|
Monastery Door Open Right
|
||||||
|
Monastery Rhombic Avoid 3
|
||||||
|
Town Cargo Box Panel
|
||||||
|
Town Full Dot Grid Shapers 5
|
||||||
|
Town Tinted Door Panel
|
||||||
|
Town Door to Church Stars Panel
|
||||||
|
Town Maze Stair Control
|
||||||
|
Town Windmill Door Panel
|
||||||
|
Town Sound Room Left
|
||||||
|
Town Sound Room Right
|
||||||
|
Town Symmetry Squares 5 + Dots
|
||||||
|
Town Church Lattice
|
||||||
|
Town Hexagonal Reflection
|
||||||
|
Town Shapers & Dots & Eraser
|
||||||
|
Windmill Door to Front of Theater Panel
|
||||||
|
Theater Door to Cargo Box Left Panel
|
||||||
|
Theater Door to Cargo Box Right Panel
|
||||||
|
Jungle Shortcut to River Panel
|
||||||
|
Jungle Popup Wall Control
|
||||||
|
River Rhombic Avoid to Monastery Garden
|
||||||
|
Bunker Bunker Entry Panel
|
||||||
|
Bunker Door to Bunker Proper Panel
|
||||||
|
Bunker Drawn Squares through Tinted Glass 3
|
||||||
|
Bunker Drop-Down Door Squares 2
|
||||||
|
Swamp Entry Panel
|
||||||
|
Swamp Platform Shapers 4
|
||||||
|
Swamp Platform Shortcut Right Panel
|
||||||
|
Swamp Blue Underwater Negative Shapers 5
|
||||||
|
Swamp Broken Shapers 4
|
||||||
|
Swamp Cyan Underwater Negative Shapers 5
|
||||||
|
Swamp Red Underwater Negative Shapers 4
|
||||||
|
Swamp More Rotated Shapers 4
|
||||||
|
Swamp More Rotated Shapers 4
|
||||||
|
Swamp Near Laser Shortcut Right Panel
|
||||||
|
Treehouse First Door Panel
|
||||||
|
Treehouse Second Door Panel
|
||||||
|
Treehouse Beyond Yellow Bridge 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 Control
|
||||||
|
Inside Mountain Moving Background 7
|
||||||
|
Inside Mountain Obscured Vision 5
|
||||||
|
Inside Mountain Physically Obstructed 3
|
||||||
|
Inside Mountain Angled Inside Trash 2
|
||||||
|
Inside Mountain Color Cycle 5
|
||||||
|
Inside Mountain Light Bridge Controller 2
|
||||||
|
Inside Mountain Light Bridge Controller 3
|
||||||
|
Inside Mountain Same Solution 6
|
||||||
|
Inside Mountain Giant Puzzle
|
||||||
|
Inside Mountain Door to Final Room Left
|
||||||
|
Inside Mountain Door to Final Room Right
|
||||||
|
Inside Mountain Bottom Layer Discard
|
||||||
|
Inside Mountain Rock Control
|
||||||
|
Inside Mountain Secret Area Entry Panel
|
||||||
|
Inside Mountain Caves Lone Pillar
|
||||||
|
Inside Mountain Caves Shortcut to Mountain Panel
|
||||||
|
Inside Mountain Caves Shortcut to Swamp Panel
|
||||||
|
Inside Mountain Caves Challenge Entry Panel
|
||||||
|
Challenge Door to Theater Walkway Panel
|
||||||
|
Theater Walkway Theater Shortcut Panel
|
||||||
|
Theater Walkway Desert Shortcut Panel
|
||||||
|
Theater Walkway Town Shortcut Panel
|
|
@ -0,0 +1,212 @@
|
||||||
|
Items:
|
||||||
|
Outside Tutorial Optional Door
|
||||||
|
Outside Tutorial Outpost Entry Door
|
||||||
|
Outside Tutorial Outpost Exit Door
|
||||||
|
Glass Factory Entry Door
|
||||||
|
Glass Factory Back Wall
|
||||||
|
Symmetry Island Lower Door
|
||||||
|
Symmetry Island Upper Door
|
||||||
|
Orchard Middle Gate
|
||||||
|
Orchard Final Gate
|
||||||
|
Desert Door to Flood Light Room
|
||||||
|
Desert Door to Pond Room
|
||||||
|
Desert Door to Water Levels Room
|
||||||
|
Desert Door to Elevator Room
|
||||||
|
Quarry Main Entry 1
|
||||||
|
Quarry Main Entry 2
|
||||||
|
Quarry Door to Mill
|
||||||
|
Quarry Mill Side Door
|
||||||
|
Quarry Mill Rooftop Shortcut
|
||||||
|
Quarry Mill Stairs
|
||||||
|
Quarry Boathouse Boat Staircase
|
||||||
|
Quarry Boathouse First Barrier
|
||||||
|
Quarry Boathouse Shortcut
|
||||||
|
Shadows Timed Door
|
||||||
|
Shadows Laser Room Right Door
|
||||||
|
Shadows Laser Room Left Door
|
||||||
|
Shadows Barrier to Quarry
|
||||||
|
Shadows Barrier to Ledge
|
||||||
|
Keep Hedge Maze 1 Exit Door
|
||||||
|
Keep Pressure Plates 1 Exit Door
|
||||||
|
Keep Hedge Maze 2 Shortcut
|
||||||
|
Keep Hedge Maze 2 Exit Door
|
||||||
|
Keep Hedge Maze 3 Shortcut
|
||||||
|
Keep Hedge Maze 3 Exit Door
|
||||||
|
Keep Hedge Maze 4 Shortcut
|
||||||
|
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 Shortcut to Shadows
|
||||||
|
Keep Tower Shortcut
|
||||||
|
Monastery Shortcut
|
||||||
|
Monastery Inner Door
|
||||||
|
Monastery Outer Door
|
||||||
|
Monastery Door to Garden
|
||||||
|
Town Cargo Box Door
|
||||||
|
Town Wooden Roof Staircase
|
||||||
|
Town Tinted Door to RGB House
|
||||||
|
Town Door to Church
|
||||||
|
Town Maze Staircase
|
||||||
|
Town Windmill Door
|
||||||
|
Town RGB House Staircase
|
||||||
|
Town Tower Blue Panels Door
|
||||||
|
Town Tower Lattice Door
|
||||||
|
Town Tower Environmental Set Door
|
||||||
|
Town Tower Wooden Roof Set Door
|
||||||
|
Theater Entry Door
|
||||||
|
Theater Exit Door Left
|
||||||
|
Theater Exit Door Right
|
||||||
|
Jungle Bamboo Shortcut to River
|
||||||
|
Jungle Popup Wall
|
||||||
|
River Shortcut to Monastery Garden
|
||||||
|
Bunker Bunker Entry Door
|
||||||
|
Bunker Tinted Glass Door
|
||||||
|
Bunker Door to Ultraviolet Room
|
||||||
|
Bunker Door to Elevator
|
||||||
|
Swamp Entry Door
|
||||||
|
Swamp Door to Broken Shapers
|
||||||
|
Swamp Platform Shortcut Door
|
||||||
|
Swamp Cyan Water Pump
|
||||||
|
Swamp Door to Rotated Shapers
|
||||||
|
Swamp Red Water Pump
|
||||||
|
Swamp Red Underwater Exit
|
||||||
|
Swamp Blue Water Pump
|
||||||
|
Swamp Purple Water Pump
|
||||||
|
Swamp Near Laser Shortcut
|
||||||
|
Treehouse First Door
|
||||||
|
Treehouse Second Door
|
||||||
|
Treehouse Beyond Yellow Bridge Door
|
||||||
|
Treehouse Drawbridge
|
||||||
|
Treehouse Timed Door to Laser House
|
||||||
|
Inside Mountain First Layer Exit Door
|
||||||
|
Inside Mountain Second Layer Staircase Near
|
||||||
|
Inside Mountain Second Layer Exit Door
|
||||||
|
Inside Mountain Second Layer Staircase Far
|
||||||
|
Inside Mountain Giant Puzzle Exit Door
|
||||||
|
Inside Mountain Door to Final Room
|
||||||
|
Inside Mountain Bottom Layer Rock
|
||||||
|
Inside Mountain Door to Secret Area
|
||||||
|
Caves Pillar Door
|
||||||
|
Caves Mountain Shortcut
|
||||||
|
Caves Swamp Shortcut
|
||||||
|
Challenge Entry Door
|
||||||
|
Challenge Door to Theater Walkway
|
||||||
|
Theater Walkway Door to Windmill Interior
|
||||||
|
Theater Walkway Door to Desert Elevator Room
|
||||||
|
Theater Walkway Door to Town
|
||||||
|
|
||||||
|
Desert Flood Room Flood Controls (Panel)
|
||||||
|
Quarry Mill Ramp Controls (Panel)
|
||||||
|
Quarry Mill Elevator 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 Door to Outpost Panel
|
||||||
|
Outside Tutorial Exit Door from Outpost Panel
|
||||||
|
Glass Factory Entry Door Panel
|
||||||
|
Glass Factory Vertical Symmetry 5
|
||||||
|
Symmetry Island Door to Symmetry Island Lower Panel
|
||||||
|
Symmetry Island Door to Symmetry Island Upper Panel
|
||||||
|
Orchard Apple Tree 3
|
||||||
|
Orchard Apple Tree 5
|
||||||
|
Desert Door to Desert Flood Light Room Panel
|
||||||
|
Desert Artificial Light Reflection 3
|
||||||
|
Desert Door to Water Levels Room Panel
|
||||||
|
Desert Flood Reflection 6
|
||||||
|
Quarry Door to Quarry 1 Panel
|
||||||
|
Quarry Door to Quarry 2 Panel
|
||||||
|
Quarry Door to Mill Right
|
||||||
|
Quarry Door to Mill Left
|
||||||
|
Quarry Mill Ground Floor Shortcut Door Panel
|
||||||
|
Quarry Mill Door to Outside Quarry Stairs Panel
|
||||||
|
Quarry Mill Stair Control
|
||||||
|
Quarry Boathouse Shortcut Door Panel
|
||||||
|
Shadows Door Timer Inside
|
||||||
|
Shadows Door Timer Outside
|
||||||
|
Shadows Environmental Avoid 8
|
||||||
|
Shadows Follow 5
|
||||||
|
Shadows Lower Avoid 3
|
||||||
|
Shadows Lower Avoid 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 Shortcut to Shadows Panel
|
||||||
|
Keep Tower Shortcut to Keep Panel
|
||||||
|
Monastery Shortcut Door Panel
|
||||||
|
Monastery Door Open Left
|
||||||
|
Monastery Door Open Right
|
||||||
|
Monastery Rhombic Avoid 3
|
||||||
|
Town Cargo Box Panel
|
||||||
|
Town Full Dot Grid Shapers 5
|
||||||
|
Town Tinted Door Panel
|
||||||
|
Town Door to Church Stars Panel
|
||||||
|
Town Maze Stair Control
|
||||||
|
Town Windmill Door Panel
|
||||||
|
Town Sound Room Left
|
||||||
|
Town Sound Room Right
|
||||||
|
Town Symmetry Squares 5 + Dots
|
||||||
|
Town Church Lattice
|
||||||
|
Town Hexagonal Reflection
|
||||||
|
Town Shapers & Dots & Eraser
|
||||||
|
Windmill Door to Front of Theater Panel
|
||||||
|
Theater Door to Cargo Box Left Panel
|
||||||
|
Theater Door to Cargo Box Right Panel
|
||||||
|
Jungle Shortcut to River Panel
|
||||||
|
Jungle Popup Wall Control
|
||||||
|
River Rhombic Avoid to Monastery Garden
|
||||||
|
Bunker Bunker Entry Panel
|
||||||
|
Bunker Door to Bunker Proper Panel
|
||||||
|
Bunker Drawn Squares through Tinted Glass 3
|
||||||
|
Bunker Drop-Down Door Squares 2
|
||||||
|
Swamp Entry Panel
|
||||||
|
Swamp Platform Shapers 4
|
||||||
|
Swamp Platform Shortcut Right Panel
|
||||||
|
Swamp Blue Underwater Negative Shapers 5
|
||||||
|
Swamp Broken Shapers 4
|
||||||
|
Swamp Cyan Underwater Negative Shapers 5
|
||||||
|
Swamp Red Underwater Negative Shapers 4
|
||||||
|
Swamp More Rotated Shapers 4
|
||||||
|
Swamp More Rotated Shapers 4
|
||||||
|
Swamp Near Laser Shortcut Right Panel
|
||||||
|
Treehouse First Door Panel
|
||||||
|
Treehouse Second Door Panel
|
||||||
|
Treehouse Beyond Yellow Bridge 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 Control
|
||||||
|
Inside Mountain Moving Background 7
|
||||||
|
Inside Mountain Obscured Vision 5
|
||||||
|
Inside Mountain Physically Obstructed 3
|
||||||
|
Inside Mountain Angled Inside Trash 2
|
||||||
|
Inside Mountain Color Cycle 5
|
||||||
|
Inside Mountain Light Bridge Controller 2
|
||||||
|
Inside Mountain Light Bridge Controller 3
|
||||||
|
Inside Mountain Same Solution 6
|
||||||
|
Inside Mountain Giant Puzzle
|
||||||
|
Inside Mountain Door to Final Room Left
|
||||||
|
Inside Mountain Door to Final Room Right
|
||||||
|
Inside Mountain Bottom Layer Discard
|
||||||
|
Inside Mountain Rock Control
|
||||||
|
Inside Mountain Secret Area Entry Panel
|
||||||
|
Inside Mountain Caves Lone Pillar
|
||||||
|
Inside Mountain Caves Shortcut to Mountain Panel
|
||||||
|
Inside Mountain Caves Shortcut to Swamp Panel
|
||||||
|
Inside Mountain Caves Challenge Entry Panel
|
||||||
|
Challenge Door to Theater Walkway Panel
|
||||||
|
Theater Walkway Theater Shortcut Panel
|
||||||
|
Theater Walkway Desert Shortcut Panel
|
||||||
|
Theater Walkway Town Shortcut Panel
|
|
@ -0,0 +1,146 @@
|
||||||
|
Items:
|
||||||
|
Glass Factory Back Wall
|
||||||
|
Quarry Boathouse Boat Staircase
|
||||||
|
Outside Tutorial Outpost Doors
|
||||||
|
Glass Factory Entry Door
|
||||||
|
Symmetry Island Doors
|
||||||
|
Orchard Gates
|
||||||
|
Desert Doors
|
||||||
|
Quarry Main Entry
|
||||||
|
Quarry Door to Mill
|
||||||
|
Quarry Mill Shortcuts
|
||||||
|
Quarry Boathouse Barriers
|
||||||
|
Shadows Timed Door
|
||||||
|
Shadows Laser Room Door
|
||||||
|
Shadows Barriers
|
||||||
|
Keep Hedge Maze Doors
|
||||||
|
Keep Pressure Plates Doors
|
||||||
|
Keep Shortcuts
|
||||||
|
Monastery Entry Door
|
||||||
|
Monastery Shortcuts
|
||||||
|
Town Doors
|
||||||
|
Town Tower Doors
|
||||||
|
Theater Entry Door
|
||||||
|
Theater Exit Door
|
||||||
|
Jungle & River Shortcuts
|
||||||
|
Jungle Popup Wall
|
||||||
|
Bunker Doors
|
||||||
|
Swamp Doors
|
||||||
|
Swamp Near Laser Shortcut
|
||||||
|
Swamp Water Pumps
|
||||||
|
Treehouse Entry Doors
|
||||||
|
Treehouse Drawbridge
|
||||||
|
Treehouse Timed Door to Laser House
|
||||||
|
Inside Mountain First Layer Exit Door
|
||||||
|
Inside Mountain Second Layer Stairs & Doors
|
||||||
|
Inside Mountain Giant Puzzle Exit Door
|
||||||
|
Inside Mountain Door to Final Room
|
||||||
|
Inside Mountain Bottom Layer Doors to Caves
|
||||||
|
Caves Doors to Challenge
|
||||||
|
Caves Exits to Main Island
|
||||||
|
Challenge Door to Theater Walkway
|
||||||
|
Theater Walkway Doors
|
||||||
|
|
||||||
|
Added Locations:
|
||||||
|
Outside Tutorial Door to Outpost Panel
|
||||||
|
Outside Tutorial Exit Door from Outpost Panel
|
||||||
|
Glass Factory Entry Door Panel
|
||||||
|
Glass Factory Vertical Symmetry 5
|
||||||
|
Symmetry Island Door to Symmetry Island Lower Panel
|
||||||
|
Symmetry Island Door to Symmetry Island Upper Panel
|
||||||
|
Orchard Apple Tree 3
|
||||||
|
Orchard Apple Tree 5
|
||||||
|
Desert Door to Desert Flood Light Room Panel
|
||||||
|
Desert Artificial Light Reflection 3
|
||||||
|
Desert Door to Water Levels Room Panel
|
||||||
|
Desert Flood Reflection 6
|
||||||
|
Quarry Door to Quarry 1 Panel
|
||||||
|
Quarry Door to Quarry 2 Panel
|
||||||
|
Quarry Door to Mill Right
|
||||||
|
Quarry Door to Mill Left
|
||||||
|
Quarry Mill Ground Floor Shortcut Door Panel
|
||||||
|
Quarry Mill Door to Outside Quarry Stairs Panel
|
||||||
|
Quarry Mill Stair Control
|
||||||
|
Quarry Boathouse Shortcut Door Panel
|
||||||
|
Shadows Door Timer Inside
|
||||||
|
Shadows Door Timer Outside
|
||||||
|
Shadows Environmental Avoid 8
|
||||||
|
Shadows Follow 5
|
||||||
|
Shadows Lower Avoid 3
|
||||||
|
Shadows Lower Avoid 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 Shortcut to Shadows Panel
|
||||||
|
Keep Tower Shortcut to Keep Panel
|
||||||
|
Monastery Shortcut Door Panel
|
||||||
|
Monastery Door Open Left
|
||||||
|
Monastery Door Open Right
|
||||||
|
Monastery Rhombic Avoid 3
|
||||||
|
Town Cargo Box Panel
|
||||||
|
Town Full Dot Grid Shapers 5
|
||||||
|
Town Tinted Door Panel
|
||||||
|
Town Door to Church Stars Panel
|
||||||
|
Town Maze Stair Control
|
||||||
|
Town Windmill Door Panel
|
||||||
|
Town Sound Room Left
|
||||||
|
Town Sound Room Right
|
||||||
|
Town Symmetry Squares 5 + Dots
|
||||||
|
Town Church Lattice
|
||||||
|
Town Hexagonal Reflection
|
||||||
|
Town Shapers & Dots & Eraser
|
||||||
|
Windmill Door to Front of Theater Panel
|
||||||
|
Theater Door to Cargo Box Left Panel
|
||||||
|
Theater Door to Cargo Box Right Panel
|
||||||
|
Jungle Shortcut to River Panel
|
||||||
|
Jungle Popup Wall Control
|
||||||
|
River Rhombic Avoid to Monastery Garden
|
||||||
|
Bunker Bunker Entry Panel
|
||||||
|
Bunker Door to Bunker Proper Panel
|
||||||
|
Bunker Drawn Squares through Tinted Glass 3
|
||||||
|
Bunker Drop-Down Door Squares 2
|
||||||
|
Swamp Entry Panel
|
||||||
|
Swamp Platform Shapers 4
|
||||||
|
Swamp Platform Shortcut Right Panel
|
||||||
|
Swamp Blue Underwater Negative Shapers 5
|
||||||
|
Swamp Broken Shapers 4
|
||||||
|
Swamp Cyan Underwater Negative Shapers 5
|
||||||
|
Swamp Red Underwater Negative Shapers 4
|
||||||
|
Swamp More Rotated Shapers 4
|
||||||
|
Swamp More Rotated Shapers 4
|
||||||
|
Swamp Near Laser Shortcut Right Panel
|
||||||
|
Treehouse First Door Panel
|
||||||
|
Treehouse Second Door Panel
|
||||||
|
Treehouse Beyond Yellow Bridge 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 Control
|
||||||
|
Inside Mountain Moving Background 7
|
||||||
|
Inside Mountain Obscured Vision 5
|
||||||
|
Inside Mountain Physically Obstructed 3
|
||||||
|
Inside Mountain Angled Inside Trash 2
|
||||||
|
Inside Mountain Color Cycle 5
|
||||||
|
Inside Mountain Light Bridge Controller 2
|
||||||
|
Inside Mountain Light Bridge Controller 3
|
||||||
|
Inside Mountain Same Solution 6
|
||||||
|
Inside Mountain Giant Puzzle
|
||||||
|
Inside Mountain Door to Final Room Left
|
||||||
|
Inside Mountain Door to Final Room Right
|
||||||
|
Inside Mountain Bottom Layer Discard
|
||||||
|
Inside Mountain Rock Control
|
||||||
|
Inside Mountain Secret Area Entry Panel
|
||||||
|
Inside Mountain Caves Lone Pillar
|
||||||
|
Inside Mountain Caves Shortcut to Mountain Panel
|
||||||
|
Inside Mountain Caves Shortcut to Swamp Panel
|
||||||
|
Inside Mountain Caves Challenge Entry Panel
|
||||||
|
Challenge Door to Theater Walkway Panel
|
||||||
|
Theater Walkway Theater Shortcut Panel
|
||||||
|
Theater Walkway Desert Shortcut Panel
|
||||||
|
Theater Walkway Town Shortcut Panel
|
|
@ -0,0 +1,9 @@
|
||||||
|
Items:
|
||||||
|
Caves Exits to Main Island
|
||||||
|
|
||||||
|
Starting Inventory:
|
||||||
|
Caves Exits to Main Island
|
||||||
|
|
||||||
|
Remove Items:
|
||||||
|
Caves Mountain Shortcut
|
||||||
|
Caves Swamp Shortcut
|
|
@ -0,0 +1,12 @@
|
||||||
|
Items:
|
||||||
|
Symmetry Laser
|
||||||
|
Desert Laser
|
||||||
|
Keep Laser
|
||||||
|
Shadows Laser
|
||||||
|
Quarry Laser
|
||||||
|
Town Laser
|
||||||
|
Swamp Laser
|
||||||
|
Jungle Laser
|
||||||
|
Bunker Laser
|
||||||
|
Monastery Laser
|
||||||
|
Treehouse Laser
|
|
@ -0,0 +1,14 @@
|
||||||
|
Items:
|
||||||
|
Dots
|
||||||
|
Colored Dots
|
||||||
|
Sound Dots
|
||||||
|
Symmetry
|
||||||
|
Triangles
|
||||||
|
Eraser
|
||||||
|
Shapers
|
||||||
|
Rotated Shapers
|
||||||
|
Negative Shapers
|
||||||
|
Stars
|
||||||
|
Stars + Same Colored Symbol
|
||||||
|
Black/White Squares
|
||||||
|
Colored Squares
|
|
@ -5,12 +5,11 @@ from .utils import define_new_region, parse_lambda
|
||||||
|
|
||||||
class StaticWitnessLogic:
|
class StaticWitnessLogic:
|
||||||
ALL_SYMBOL_ITEMS = set()
|
ALL_SYMBOL_ITEMS = set()
|
||||||
|
ALL_DOOR_ITEMS = set()
|
||||||
|
ALL_DOOR_ITEMS_AS_DICT = dict()
|
||||||
ALL_USEFULS = set()
|
ALL_USEFULS = set()
|
||||||
ALL_TRAPS = set()
|
ALL_TRAPS = set()
|
||||||
ALL_BOOSTS = set()
|
ALL_BOOSTS = set()
|
||||||
ALL_DOOR_ITEM_IDS_BY_HEX = dict()
|
|
||||||
DOOR_NAMES_BY_HEX = dict()
|
|
||||||
ALL_DOOR_ITEMS = set()
|
|
||||||
CONNECTIONS_TO_SEVER_BY_DOOR_HEX = dict()
|
CONNECTIONS_TO_SEVER_BY_DOOR_HEX = dict()
|
||||||
|
|
||||||
EVENT_PANELS_FROM_REGIONS = set()
|
EVENT_PANELS_FROM_REGIONS = set()
|
||||||
|
@ -47,34 +46,22 @@ class StaticWitnessLogic:
|
||||||
if line == "Usefuls:":
|
if line == "Usefuls:":
|
||||||
current_set = self.ALL_USEFULS
|
current_set = self.ALL_USEFULS
|
||||||
continue
|
continue
|
||||||
|
if line == "Doors:":
|
||||||
|
current_set = self.ALL_DOOR_ITEMS
|
||||||
|
continue
|
||||||
if line == "":
|
if line == "":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
line_split = line.split(" - ")
|
line_split = line.split(" - ")
|
||||||
|
|
||||||
if current_set is not self.ALL_USEFULS:
|
if current_set is self.ALL_USEFULS:
|
||||||
current_set.add((line_split[1], int(line_split[0])))
|
|
||||||
else:
|
|
||||||
current_set.add((line_split[1], int(line_split[0]), line_split[2] == "True"))
|
current_set.add((line_split[1], int(line_split[0]), line_split[2] == "True"))
|
||||||
|
elif current_set is self.ALL_DOOR_ITEMS:
|
||||||
path = os.path.join(os.path.dirname(__file__), "Door_Shuffle.txt")
|
new_door = (line_split[1], int(line_split[0]), frozenset(line_split[2].split(",")))
|
||||||
with open(path, "r", encoding="utf-8") as file:
|
current_set.add(new_door)
|
||||||
for line in file.readlines():
|
self.ALL_DOOR_ITEMS_AS_DICT[line_split[1]] = new_door
|
||||||
line = line.strip()
|
else:
|
||||||
|
current_set.add((line_split[1], int(line_split[0])))
|
||||||
line_split = line.split(" - ")
|
|
||||||
|
|
||||||
hex_set_split = line_split[1].split(",")
|
|
||||||
|
|
||||||
sever_list = line_split[2].split(",")
|
|
||||||
sever_set = {sever_panel for sever_panel in sever_list if sever_panel != "None"}
|
|
||||||
|
|
||||||
for door_hex in hex_set_split:
|
|
||||||
self.ALL_DOOR_ITEM_IDS_BY_HEX[door_hex] = int(line_split[0])
|
|
||||||
self.CONNECTIONS_TO_SEVER_BY_DOOR_HEX[door_hex] = sever_set
|
|
||||||
|
|
||||||
if len(line_split) > 3:
|
|
||||||
self.DOOR_NAMES_BY_HEX[door_hex] = line_split[3]
|
|
||||||
|
|
||||||
def read_logic_file(self):
|
def read_logic_file(self):
|
||||||
"""
|
"""
|
||||||
|
@ -84,10 +71,7 @@ class StaticWitnessLogic:
|
||||||
with open(path, "r", encoding="utf-8") as file:
|
with open(path, "r", encoding="utf-8") as file:
|
||||||
current_region = dict()
|
current_region = dict()
|
||||||
|
|
||||||
discard_ids = 0
|
counter = 0
|
||||||
normal_panel_ids = 0
|
|
||||||
vault_ids = 0
|
|
||||||
laser_ids = 0
|
|
||||||
|
|
||||||
for line in file.readlines():
|
for line in file.readlines():
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
|
@ -95,7 +79,7 @@ class StaticWitnessLogic:
|
||||||
if line == "":
|
if line == "":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if line[0] != "0":
|
if line[-1] == ":":
|
||||||
new_region_and_connections = define_new_region(line)
|
new_region_and_connections = define_new_region(line)
|
||||||
current_region = new_region_and_connections[0]
|
current_region = new_region_and_connections[0]
|
||||||
region_name = current_region["name"]
|
region_name = current_region["name"]
|
||||||
|
@ -105,12 +89,33 @@ class StaticWitnessLogic:
|
||||||
|
|
||||||
line_split = line.split(" - ")
|
line_split = line.split(" - ")
|
||||||
|
|
||||||
|
location_id = line_split.pop(0)
|
||||||
|
|
||||||
check_name_full = line_split.pop(0)
|
check_name_full = line_split.pop(0)
|
||||||
|
|
||||||
check_hex = check_name_full[0:7]
|
check_hex = check_name_full[0:7]
|
||||||
check_name = check_name_full[9:-1]
|
check_name = check_name_full[9:-1]
|
||||||
|
|
||||||
required_panel_lambda = line_split.pop(0)
|
required_panel_lambda = line_split.pop(0)
|
||||||
|
|
||||||
|
if location_id == "Door" or location_id == "Laser":
|
||||||
|
self.CHECKS_BY_HEX[check_hex] = {
|
||||||
|
"checkName": current_region["shortName"] + " " + check_name,
|
||||||
|
"checkHex": check_hex,
|
||||||
|
"region": current_region,
|
||||||
|
"id": None,
|
||||||
|
"panelType": location_id
|
||||||
|
}
|
||||||
|
|
||||||
|
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] = {
|
||||||
|
"panels": parse_lambda(required_panel_lambda)
|
||||||
|
}
|
||||||
|
|
||||||
|
current_region["panels"].add(check_hex)
|
||||||
|
continue
|
||||||
|
|
||||||
required_item_lambda = line_split.pop(0)
|
required_item_lambda = line_split.pop(0)
|
||||||
|
|
||||||
laser_names = {
|
laser_names = {
|
||||||
|
@ -123,53 +128,14 @@ class StaticWitnessLogic:
|
||||||
|
|
||||||
if "Discard" in check_name:
|
if "Discard" in check_name:
|
||||||
location_type = "Discard"
|
location_type = "Discard"
|
||||||
location_id = discard_ids
|
|
||||||
discard_ids += 1
|
|
||||||
elif is_vault_or_video or check_name == "Tutorial Gate Close":
|
elif is_vault_or_video or check_name == "Tutorial Gate Close":
|
||||||
location_type = "Vault"
|
location_type = "Vault"
|
||||||
location_id = vault_ids
|
|
||||||
vault_ids += 1
|
|
||||||
elif check_name in laser_names:
|
elif check_name in laser_names:
|
||||||
location_type = "Laser"
|
location_type = "Laser"
|
||||||
location_id = laser_ids
|
|
||||||
laser_ids += 1
|
|
||||||
else:
|
else:
|
||||||
location_type = "General"
|
location_type = "General"
|
||||||
|
|
||||||
if check_hex == "0x012D7": # Compatibility
|
|
||||||
normal_panel_ids += 1
|
|
||||||
|
|
||||||
if check_hex == "0x17E07": # Compatibility
|
|
||||||
location_id = 112
|
|
||||||
|
|
||||||
elif check_hex == "0xFFF00":
|
|
||||||
location_id = 800
|
|
||||||
|
|
||||||
else:
|
|
||||||
location_id = normal_panel_ids
|
|
||||||
normal_panel_ids += 1
|
|
||||||
|
|
||||||
required_items = parse_lambda(required_item_lambda)
|
required_items = parse_lambda(required_item_lambda)
|
||||||
items_actually_in_the_game = {item[0] for item in self.ALL_SYMBOL_ITEMS}
|
|
||||||
required_items = set(
|
|
||||||
subset.intersection(items_actually_in_the_game)
|
|
||||||
for subset in required_items
|
|
||||||
)
|
|
||||||
|
|
||||||
doors_in_the_game = self.ALL_DOOR_ITEM_IDS_BY_HEX.keys()
|
|
||||||
if check_hex in doors_in_the_game:
|
|
||||||
door_name = current_region["shortName"] + " " + check_name + " Power On"
|
|
||||||
if check_hex in self.DOOR_NAMES_BY_HEX.keys():
|
|
||||||
door_name = self.DOOR_NAMES_BY_HEX[check_hex]
|
|
||||||
|
|
||||||
required_items = set(
|
|
||||||
subset.union(frozenset({door_name}))
|
|
||||||
for subset in required_items
|
|
||||||
)
|
|
||||||
|
|
||||||
self.ALL_DOOR_ITEMS.add(
|
|
||||||
(door_name, self.ALL_DOOR_ITEM_IDS_BY_HEX[check_hex])
|
|
||||||
)
|
|
||||||
|
|
||||||
required_items = frozenset(required_items)
|
required_items = frozenset(required_items)
|
||||||
|
|
||||||
|
@ -182,7 +148,7 @@ class StaticWitnessLogic:
|
||||||
"checkName": current_region["shortName"] + " " + check_name,
|
"checkName": current_region["shortName"] + " " + check_name,
|
||||||
"checkHex": check_hex,
|
"checkHex": check_hex,
|
||||||
"region": current_region,
|
"region": current_region,
|
||||||
"idOffset": location_id,
|
"id": int(location_id),
|
||||||
"panelType": location_type
|
"panelType": location_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,39 @@ def get_adjustment_file(adjustment_file):
|
||||||
|
|
||||||
@cache_argsless
|
@cache_argsless
|
||||||
def get_disable_unrandomized_list():
|
def get_disable_unrandomized_list():
|
||||||
return get_adjustment_file("Disable_Unrandomized.txt")
|
return get_adjustment_file("settings/Disable_Unrandomized.txt")
|
||||||
|
|
||||||
|
|
||||||
@cache_argsless
|
@cache_argsless
|
||||||
def get_early_utm_list():
|
def get_early_utm_list():
|
||||||
return get_adjustment_file("Early_UTM.txt")
|
return get_adjustment_file("settings/Early_UTM.txt")
|
||||||
|
|
||||||
|
|
||||||
|
@cache_argsless
|
||||||
|
def get_symbol_shuffle_list():
|
||||||
|
return get_adjustment_file("settings/Symbol_Shuffle.txt")
|
||||||
|
|
||||||
|
|
||||||
|
@cache_argsless
|
||||||
|
def get_door_panel_shuffle_list():
|
||||||
|
return get_adjustment_file("settings/Door_Panel_Shuffle.txt")
|
||||||
|
|
||||||
|
|
||||||
|
@cache_argsless
|
||||||
|
def get_doors_simple_list():
|
||||||
|
return get_adjustment_file("settings/Doors_Simple.txt")
|
||||||
|
|
||||||
|
|
||||||
|
@cache_argsless
|
||||||
|
def get_doors_complex_list():
|
||||||
|
return get_adjustment_file("settings/Doors_Complex.txt")
|
||||||
|
|
||||||
|
|
||||||
|
@cache_argsless
|
||||||
|
def get_doors_max_list():
|
||||||
|
return get_adjustment_file("settings/Doors_Max.txt")
|
||||||
|
|
||||||
|
|
||||||
|
@cache_argsless
|
||||||
|
def get_laser_shuffle():
|
||||||
|
return get_adjustment_file("settings/Laser_Shuffle.txt")
|
||||||
|
|
Loading…
Reference in New Issue