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"
|
||||
# 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):
|
||||
"""Disable puzzles that cannot be randomized.
|
||||
Non randomized puzzles are Shadows, Monastery, and Greenhouse.
|
||||
"""Disables puzzles that cannot be randomized.
|
||||
This includes many puzzles that heavily involve the environment, such as Shadows, Monastery or Orchard.
|
||||
The lasers for those areas will be activated as you solve optional puzzles throughout the island."""
|
||||
display_name = "Disable non randomized puzzles"
|
||||
|
||||
|
||||
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")"""
|
||||
display_name = "Early Secret Area"
|
||||
|
||||
|
||||
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"
|
||||
|
||||
|
||||
class ShuffleDoors(Toggle):
|
||||
"""Many doors around the island will have their panels turned off initially.
|
||||
You will need to find the items that power the panels to open those doors."""
|
||||
class ShuffleLasers(Toggle):
|
||||
"""If on, the 11 lasers are turned into items and will activate on their own upon receiving them.
|
||||
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"
|
||||
option_none = 0
|
||||
option_panels = 1
|
||||
option_doors_simple = 2
|
||||
option_doors_complex = 3
|
||||
option_max = 4
|
||||
|
||||
|
||||
class ShuffleDiscardedPanels(Toggle):
|
||||
"""Discarded Panels will have items on them.
|
||||
Solving certain Discarded Panels may still be necessary even if off!"""
|
||||
"""Add Discarded Panels into the location pool.
|
||||
Solving certain Discarded Panels may still be necessary to beat the game, even if this is off."""
|
||||
|
||||
display_name = "Shuffle Discarded Panels"
|
||||
|
||||
|
||||
|
@ -52,9 +63,10 @@ class ShuffleUncommonLocations(Toggle):
|
|||
display_name = "Shuffle Uncommon Locations"
|
||||
|
||||
|
||||
class ShuffleHardLocations(Toggle):
|
||||
"""Adds some harder locations into the game, e.g. Mountain Secret Area panels"""
|
||||
display_name = "Shuffle Hard Locations"
|
||||
class ShufflePostgame(Toggle):
|
||||
"""Adds locations into the pool that are guaranteed to be locked behind your goal. Use this if you don't play with
|
||||
forfeit on victory."""
|
||||
display_name = "Shuffle Postgame"
|
||||
|
||||
|
||||
class VictoryCondition(Choice):
|
||||
|
@ -103,16 +115,17 @@ class PuzzleSkipAmount(Range):
|
|||
|
||||
the_witness_options: Dict[str, type] = {
|
||||
# "hard_mode": HardMode,
|
||||
"shuffle_symbols": ShuffleSymbols,
|
||||
"shuffle_doors": ShuffleDoors,
|
||||
"shuffle_lasers": ShuffleLasers,
|
||||
"disable_non_randomized_puzzles": DisableNonRandomizedPuzzles,
|
||||
"shuffle_discarded_panels": ShuffleDiscardedPanels,
|
||||
"shuffle_vault_boxes": ShuffleVaultBoxes,
|
||||
"shuffle_uncommon": ShuffleUncommonLocations,
|
||||
"shuffle_hard": ShuffleHardLocations,
|
||||
"shuffle_postgame": ShufflePostgame,
|
||||
"victory_condition": VictoryCondition,
|
||||
"trap_percentage": TrapPercentage,
|
||||
"early_secret_area": EarlySecretArea,
|
||||
# "shuffle_symbols": ShuffleSymbols,
|
||||
# "shuffle_doors": ShuffleDoors,
|
||||
"mountain_lasers": MountainLasers,
|
||||
"challenge_lasers": ChallengeLasers,
|
||||
"puzzle_skip_amount": PuzzleSkipAmount,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
Progression:
|
||||
0 - Dots
|
||||
1 - Colored Dots
|
||||
2 - Full Dots
|
||||
3 - Invisible Dots
|
||||
5 - Sound Dots
|
||||
10 - Symmetry
|
||||
20 - Triangles
|
||||
|
@ -12,6 +14,7 @@ Progression:
|
|||
61 - Stars + Same Colored Symbol
|
||||
71 - Black/White Squares
|
||||
72 - Colored Squares
|
||||
80 - Arrows
|
||||
|
||||
Usefuls:
|
||||
101 - Functioning Brain - False
|
||||
|
@ -23,3 +26,173 @@ Boosts:
|
|||
Traps:
|
||||
600 - Slowness
|
||||
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"
|
||||
topology_present = False
|
||||
data_version = 2
|
||||
data_version = 5
|
||||
|
||||
static_logic = StaticWitnessLogic()
|
||||
static_locat = StaticWitnessLocations()
|
||||
|
@ -53,11 +53,18 @@ class WitnessWorld(World):
|
|||
'seed': self.world.random.randint(0, 1000000),
|
||||
'victory_location': int(self.player_logic.VICTORY_LOCATION, 16),
|
||||
'panelhex_to_id': self.locat.CHECK_PANELHEX_TO_ID,
|
||||
'doorhex_to_id': self.player_logic.DOOR_DICT_FOR_CLIENT,
|
||||
'door_connections_to_sever': self.player_logic.DOOR_CONNECTIONS_TO_SEVER
|
||||
'item_id_to_door_hexes': self.items.ITEM_ID_TO_DOOR_HEX,
|
||||
'door_hexes': self.items.DOORS,
|
||||
'symbols_not_in_the_game': self.items.SYMBOLS_NOT_IN_THE_GAME
|
||||
}
|
||||
|
||||
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.locat = WitnessPlayerLocations(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
|
||||
|
||||
# Put good item on first check if symbol shuffle is on
|
||||
# symbols = is_option_enabled(self.world, self.player, "shuffle_symbols")
|
||||
symbols = True
|
||||
symbols = is_option_enabled(self.world, self.player, "shuffle_symbols")
|
||||
|
||||
if symbols:
|
||||
random_good_item = self.world.random.choice(self.items.GOOD_ITEMS)
|
||||
|
||||
first_check = self.world.get_location(
|
||||
"Tutorial Gate Open", self.player
|
||||
)
|
||||
|
@ -91,6 +98,10 @@ class WitnessWorld(World):
|
|||
|
||||
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:
|
||||
witness_item = self.create_item(item)
|
||||
for i in range(0, self.items.EXTRA_AMOUNTS[item]):
|
||||
|
|
|
@ -51,12 +51,15 @@ class StaticWitnessItems:
|
|||
def __init__(self):
|
||||
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":
|
||||
continue
|
||||
|
||||
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:
|
||||
item_tab[item[0]] = ItemData(
|
||||
158000 + item[1], False, False, True
|
||||
|
@ -89,23 +92,39 @@ class WitnessPlayerItems:
|
|||
self.ITEM_TABLE = copy.copy(StaticWitnessItems.ALL_ITEM_TABLE)
|
||||
self.PROGRESSION_TABLE = dict()
|
||||
|
||||
self.ITEM_ID_TO_DOOR_HEX = dict()
|
||||
self.DOORS = set()
|
||||
|
||||
self.SYMBOLS_NOT_IN_THE_GAME = set()
|
||||
|
||||
self.EXTRA_AMOUNTS = {
|
||||
"Functioning Brain": 1,
|
||||
"Puzzle Skip": get_option_value(world, player, "puzzle_skip_amount")
|
||||
}
|
||||
|
||||
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]]
|
||||
if item in StaticWitnessLogic.ALL_SYMBOL_ITEMS:
|
||||
self.SYMBOLS_NOT_IN_THE_GAME.add(StaticWitnessItems.ALL_ITEM_TABLE[item[0]].code)
|
||||
else:
|
||||
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")
|
||||
|
||||
if "shuffle_symbols" not in the_witness_options.keys():
|
||||
symbols = True
|
||||
|
||||
doors = is_option_enabled(world, player, "shuffle_doors")
|
||||
doors = get_option_value(world, player, "shuffle_doors")
|
||||
|
||||
if doors and symbols:
|
||||
self.GOOD_ITEMS = [
|
||||
|
@ -117,10 +136,10 @@ class WitnessPlayerItems:
|
|||
"Shapers", "Symmetry"
|
||||
]
|
||||
|
||||
if is_option_enabled(world, player, "shuffle_discarded_panels"):
|
||||
self.GOOD_ITEMS.append("Triangles")
|
||||
if not is_option_enabled(world, player, "disable_non_randomized_puzzles"):
|
||||
self.GOOD_ITEMS.append("Colored Squares")
|
||||
if is_option_enabled(world, player, "shuffle_discarded_panels"):
|
||||
self.GOOD_ITEMS.append("Triangles")
|
||||
if not is_option_enabled(world, player, "disable_non_randomized_puzzles"):
|
||||
self.GOOD_ITEMS.append("Colored Squares")
|
||||
|
||||
for event_location in locat.EVENT_LOCATION_TABLE:
|
||||
location = player_logic.EVENT_ITEM_PAIRS[event_location]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Defines constants for different types of locations in the game
|
||||
"""
|
||||
|
||||
from .Options import is_option_enabled
|
||||
from .Options import is_option_enabled, get_option_value
|
||||
from .player_logic import StaticWitnessLogic, WitnessPlayerLogic
|
||||
|
||||
|
||||
|
@ -42,7 +42,7 @@ class StaticWitnessLocations:
|
|||
"Symmetry Island Colored Dots 6",
|
||||
"Symmetry Island Fading Lines 7",
|
||||
"Symmetry Island Scenery Outlines 5",
|
||||
"Symmetry Island Laser",
|
||||
"Symmetry Island Laser Panel",
|
||||
|
||||
"Orchard Apple Tree 5",
|
||||
|
||||
|
@ -52,7 +52,7 @@ class StaticWitnessLocations:
|
|||
"Desert Artificial Light Reflection 3",
|
||||
"Desert Pond Reflection 5",
|
||||
"Desert Flood Reflection 6",
|
||||
"Desert Laser",
|
||||
"Desert Laser Panel",
|
||||
|
||||
"Quarry Mill Eraser and Dots 6",
|
||||
"Quarry Mill Eraser and Squares 8",
|
||||
|
@ -63,34 +63,34 @@ class StaticWitnessLocations:
|
|||
"Quarry Boathouse Stars & Eraser & Shapers 2",
|
||||
"Quarry Boathouse Stars & Eraser & Shapers 5",
|
||||
"Quarry Discard",
|
||||
"Quarry Laser",
|
||||
"Quarry Laser Panel",
|
||||
|
||||
"Shadows Lower Avoid 8",
|
||||
"Shadows Environmental Avoid 8",
|
||||
"Shadows Follow 5",
|
||||
"Shadows Laser",
|
||||
"Shadows Laser Panel",
|
||||
|
||||
"Keep Hedge Maze 4",
|
||||
"Keep Pressure Plates 4",
|
||||
"Keep Discard",
|
||||
"Keep Laser Hedges",
|
||||
"Keep Laser Pressure Plates",
|
||||
"Keep Laser Panel Hedges",
|
||||
"Keep Laser Panel Pressure Plates",
|
||||
|
||||
"Shipwreck Vault Box",
|
||||
"Shipwreck Discard",
|
||||
|
||||
"Monastery Rhombic Avoid 3",
|
||||
"Monastery Branch Follow 2",
|
||||
"Monastery Laser",
|
||||
"Monastery Laser Panel",
|
||||
|
||||
"Town Cargo Box Discard",
|
||||
"Town Hexagonal Reflection",
|
||||
"Town Square Avoid",
|
||||
"Town Church Lattice",
|
||||
"Town Rooftop Discard",
|
||||
"Town Symmetry Squares 5 + Dots",
|
||||
"Town Full Dot Grid Shapers 5",
|
||||
"Town Shapers & Dots & Eraser",
|
||||
"Town Laser",
|
||||
"Town Laser Panel",
|
||||
|
||||
"Theater Discard",
|
||||
|
||||
|
@ -98,7 +98,7 @@ class StaticWitnessLocations:
|
|||
"Jungle Waves 3",
|
||||
"Jungle Waves 7",
|
||||
"Jungle Popup Wall 6",
|
||||
"Jungle Laser",
|
||||
"Jungle Laser Panel",
|
||||
|
||||
"River Vault Box",
|
||||
|
||||
|
@ -106,7 +106,7 @@ class StaticWitnessLocations:
|
|||
"Bunker Drawn Squares 9",
|
||||
"Bunker Drawn Squares through Tinted Glass 3",
|
||||
"Bunker Drop-Down Door Squares 2",
|
||||
"Bunker Laser",
|
||||
"Bunker Laser Panel",
|
||||
|
||||
"Swamp Seperatable Shapers 6",
|
||||
"Swamp Combinable Shapers 8",
|
||||
|
@ -117,7 +117,7 @@ class StaticWitnessLocations:
|
|||
"Swamp Red Underwater Negative Shapers 4",
|
||||
"Swamp More Rotated Shapers 4",
|
||||
"Swamp Blue Underwater Negative Shapers 5",
|
||||
"Swamp Laser",
|
||||
"Swamp Laser Panel",
|
||||
|
||||
"Treehouse Yellow Bridge 9",
|
||||
"Treehouse First Purple Bridge 5",
|
||||
|
@ -125,21 +125,12 @@ class StaticWitnessLocations:
|
|||
"Treehouse Green Bridge 7",
|
||||
"Treehouse Green Bridge Discard",
|
||||
"Treehouse Left Orange Bridge 15",
|
||||
"Treehouse Burned House Discard",
|
||||
"Treehouse Burnt House Discard",
|
||||
"Treehouse Right Orange Bridge 12",
|
||||
"Treehouse Laser",
|
||||
"Treehouse Laser Panel",
|
||||
|
||||
"Mountaintop Discard",
|
||||
"Mountaintop Vault Box",
|
||||
|
||||
"Inside Mountain Obscured Vision 5",
|
||||
"Inside Mountain Moving Background 7",
|
||||
"Inside Mountain Physically Obstructed 3",
|
||||
"Inside Mountain Angled Inside Trash 2",
|
||||
"Inside Mountain Color Cycle 5",
|
||||
"Inside Mountain Same Solution 6",
|
||||
"Inside Mountain Elevator Discard",
|
||||
"Inside Mountain Giant Puzzle",
|
||||
}
|
||||
|
||||
UNCOMMON_LOCATIONS = {
|
||||
|
@ -156,35 +147,53 @@ class StaticWitnessLocations:
|
|||
"Swamp Underwater Back Optional",
|
||||
}
|
||||
|
||||
HARD_LOCATIONS = {
|
||||
"Inside Mountain Secret Area Dot Grid Triangles 4",
|
||||
"Inside Mountain Secret Area Symmetry Triangles",
|
||||
"Inside Mountain Secret Area Stars & Squares and Triangles 2",
|
||||
"Inside Mountain Secret Area Shapers and Triangles 2",
|
||||
"Inside Mountain Secret Area Symmetry Shapers",
|
||||
"Inside Mountain Secret Area Broken and Negative Shapers",
|
||||
"Inside Mountain Secret Area Broken Shapers",
|
||||
CAVES_LOCATIONS = {
|
||||
"Inside Mountain Caves Dot Grid Triangles 4",
|
||||
"Inside Mountain Caves Symmetry Triangles",
|
||||
"Inside Mountain Caves Stars & Squares and Triangles 2",
|
||||
"Inside Mountain Caves Shapers and Triangles 2",
|
||||
"Inside Mountain Caves Symmetry Shapers",
|
||||
"Inside Mountain Caves Broken and Negative Shapers",
|
||||
"Inside Mountain Caves Broken Shapers",
|
||||
|
||||
"Inside Mountain Secret Area Rainbow Squares",
|
||||
"Inside Mountain Secret Area Squares & Stars and Colored Eraser",
|
||||
"Inside Mountain Secret Area Rotated Broken Shapers",
|
||||
"Inside Mountain Secret Area Stars and Squares",
|
||||
"Inside Mountain Secret Area Lone Pillar",
|
||||
"Inside Mountain Secret Area Wooden Beam Shapers",
|
||||
"Inside Mountain Secret Area Wooden Beam Squares and Shapers",
|
||||
"Inside Mountain Secret Area Wooden Beam Stars and Squares",
|
||||
"Inside Mountain Secret Area Wooden Beam Shapers and Stars",
|
||||
"Inside Mountain Secret Area Upstairs Invisible Dots 8",
|
||||
"Inside Mountain Secret Area Upstairs Invisible Dot Symmetry 3",
|
||||
"Inside Mountain Secret Area Upstairs Dot Grid Negative Shapers",
|
||||
"Inside Mountain Secret Area Upstairs Dot Grid Rotated Shapers",
|
||||
"Inside Mountain Caves Rainbow Squares",
|
||||
"Inside Mountain Caves Squares & Stars and Colored Eraser",
|
||||
"Inside Mountain Caves Rotated Broken Shapers",
|
||||
"Inside Mountain Caves Stars and Squares",
|
||||
"Inside Mountain Caves Lone Pillar",
|
||||
"Inside Mountain Caves Wooden Beam Shapers",
|
||||
"Inside Mountain Caves Wooden Beam Squares and Shapers",
|
||||
"Inside Mountain Caves Wooden Beam Stars and Squares",
|
||||
"Inside Mountain Caves Wooden Beam Shapers and Stars",
|
||||
"Inside Mountain Caves Upstairs Invisible Dots 8",
|
||||
"Inside Mountain Caves Upstairs Invisible Dot Symmetry 3",
|
||||
"Inside Mountain Caves Upstairs Dot Grid Negative Shapers",
|
||||
"Inside Mountain Caves Upstairs Dot Grid Rotated Shapers",
|
||||
|
||||
"Challenge Vault Box",
|
||||
"Theater Walkway Vault Box",
|
||||
"Inside Mountain Bottom Layer Discard",
|
||||
"Theater Challenge Video",
|
||||
}
|
||||
|
||||
MOUNTAIN_UNREACHABLE_FROM_BEHIND = {
|
||||
"Mountaintop Trap Door Triple Exit",
|
||||
|
||||
"Inside Mountain Obscured Vision 5",
|
||||
"Inside Mountain Moving Background 7",
|
||||
"Inside Mountain Physically Obstructed 3",
|
||||
"Inside Mountain Angled Inside Trash 2",
|
||||
"Inside Mountain Color Cycle 5",
|
||||
"Inside Mountain Same Solution 6",
|
||||
}
|
||||
|
||||
MOUNTAIN_REACHABLE_FROM_BEHIND = {
|
||||
"Inside Mountain Elevator Discard",
|
||||
"Inside Mountain Giant Puzzle",
|
||||
|
||||
"Inside Mountain Final Room Left Pillar 4",
|
||||
"Inside Mountain Final Room Right Pillar 4",
|
||||
}
|
||||
|
||||
ALL_LOCATIONS_TO_ID = dict()
|
||||
|
||||
@staticmethod
|
||||
|
@ -193,12 +202,7 @@ class StaticWitnessLocations:
|
|||
Calculates the location ID for any given location
|
||||
"""
|
||||
|
||||
panel_offset = StaticWitnessLogic.CHECKS_BY_HEX[chex]["idOffset"]
|
||||
type_offset = StaticWitnessLocations.TYPE_OFFSETS[
|
||||
StaticWitnessLogic.CHECKS_BY_HEX[chex]["panelType"]
|
||||
]
|
||||
|
||||
return StaticWitnessLocations.ID_START + panel_offset + type_offset
|
||||
return StaticWitnessLogic.CHECKS_BY_HEX[chex]["id"]
|
||||
|
||||
@staticmethod
|
||||
def get_event_name(panel_hex):
|
||||
|
@ -213,6 +217,7 @@ class StaticWitnessLocations:
|
|||
all_loc_to_id = {
|
||||
panel_obj["checkName"]: self.get_id(chex)
|
||||
for chex, panel_obj in StaticWitnessLogic.CHECKS_BY_HEX.items()
|
||||
if panel_obj["id"]
|
||||
}
|
||||
|
||||
all_loc_to_id = dict(
|
||||
|
@ -229,12 +234,34 @@ class WitnessPlayerLocations:
|
|||
"""
|
||||
|
||||
def __init__(self, world, player, player_logic: WitnessPlayerLogic):
|
||||
"""Defines locations AFTER logic changes due to options"""
|
||||
|
||||
self.PANEL_TYPES_TO_SHUFFLE = {"General", "Laser"}
|
||||
self.CHECK_LOCATIONS = (
|
||||
StaticWitnessLocations.GENERAL_LOCATIONS
|
||||
)
|
||||
|
||||
"""Defines locations AFTER logic changes due to options"""
|
||||
doors = get_option_value(world, player, "shuffle_doors")
|
||||
earlyutm = is_option_enabled(world, player, "early_secret_area")
|
||||
victory = get_option_value(world, player, "victory_condition")
|
||||
lasers = get_option_value(world, player, "challenge_lasers")
|
||||
laser_shuffle = get_option_value(world, player, "shuffle_lasers")
|
||||
|
||||
postgame = set()
|
||||
postgame = postgame | StaticWitnessLocations.CAVES_LOCATIONS
|
||||
postgame = postgame | StaticWitnessLocations.MOUNTAIN_REACHABLE_FROM_BEHIND
|
||||
postgame = postgame | StaticWitnessLocations.MOUNTAIN_UNREACHABLE_FROM_BEHIND
|
||||
|
||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | postgame
|
||||
|
||||
if earlyutm or doors >= 2 or (victory == 1 and (lasers <= 11 or laser_shuffle)):
|
||||
postgame -= StaticWitnessLocations.CAVES_LOCATIONS
|
||||
|
||||
if doors >= 2:
|
||||
postgame -= StaticWitnessLocations.MOUNTAIN_REACHABLE_FROM_BEHIND
|
||||
|
||||
if victory != 2:
|
||||
postgame -= StaticWitnessLocations.MOUNTAIN_UNREACHABLE_FROM_BEHIND
|
||||
|
||||
if is_option_enabled(world, player, "shuffle_discarded_panels"):
|
||||
self.PANEL_TYPES_TO_SHUFFLE.add("Discard")
|
||||
|
@ -245,18 +272,11 @@ class WitnessPlayerLocations:
|
|||
if is_option_enabled(world, player, "shuffle_uncommon"):
|
||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.UNCOMMON_LOCATIONS
|
||||
|
||||
if is_option_enabled(world, player, "shuffle_hard"):
|
||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.HARD_LOCATIONS
|
||||
|
||||
if is_option_enabled(world, player, "shuffle_symbols") and is_option_enabled(world, player, "shuffle_doors"):
|
||||
if is_option_enabled(world, player, "disable_non_randomized_puzzles"):
|
||||
# This particular combination of logic settings leads to logic so restrictive that generation can fail
|
||||
# Hence, we add some extra sphere 0 locations
|
||||
|
||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | StaticWitnessLocations.EXTRA_LOCATIONS
|
||||
|
||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS | player_logic.ADDED_CHECKS
|
||||
|
||||
if not is_option_enabled(world, player, "shuffle_postgame"):
|
||||
self.CHECK_LOCATIONS -= postgame
|
||||
|
||||
self.CHECK_LOCATIONS = self.CHECK_LOCATIONS - {
|
||||
StaticWitnessLogic.CHECKS_BY_HEX[check_hex]["checkName"]
|
||||
for check_hex in player_logic.COMPLETELY_DISABLED_CHECKS
|
||||
|
@ -272,7 +292,7 @@ class WitnessPlayerLocations:
|
|||
)
|
||||
|
||||
event_locations = {
|
||||
p for p in player_logic.NECESSARY_EVENT_PANELS
|
||||
p for p in player_logic.EVENT_PANELS
|
||||
}
|
||||
|
||||
self.EVENT_LOCATION_TABLE = {
|
||||
|
|
|
@ -18,22 +18,15 @@ When the world has parsed its options, a second function is called to finalize t
|
|||
import copy
|
||||
from BaseClasses import MultiWorld
|
||||
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
|
||||
|
||||
|
||||
class WitnessPlayerLogic:
|
||||
"""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):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
these_items = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["items"]
|
||||
check_obj = StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]
|
||||
|
||||
real_items = {item[0] for item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME}
|
||||
these_items = frozenset({frozenset()})
|
||||
|
||||
if check_obj["id"]:
|
||||
these_items = self.DEPENDENT_REQUIREMENTS_BY_HEX[panel_hex]["items"]
|
||||
|
||||
these_items = frozenset({
|
||||
subset.intersection(real_items)
|
||||
subset.intersection(self.PROG_ITEMS_ACTUALLY_IN_THE_GAME)
|
||||
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"]
|
||||
|
||||
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()}):
|
||||
return these_items
|
||||
|
||||
all_options = set()
|
||||
|
||||
check_obj = StaticWitnessLogic.CHECKS_BY_HEX[panel_hex]
|
||||
|
||||
for option in these_panels:
|
||||
dependent_items_for_option = frozenset({frozenset()})
|
||||
|
||||
for option_panel in option:
|
||||
new_items = set()
|
||||
dep_obj = StaticWitnessLogic.CHECKS_BY_HEX.get(option_panel)
|
||||
|
||||
if option_panel in {"7 Lasers", "11 Lasers"}:
|
||||
new_items = frozenset({frozenset([option_panel])})
|
||||
# If a panel turns on when a panel in a different region turns on,
|
||||
|
@ -101,8 +101,34 @@ class WitnessPlayerLogic:
|
|||
return frozenset(all_options)
|
||||
|
||||
def make_single_adjustment(self, adj_type, line):
|
||||
from . import StaticWitnessItems
|
||||
"""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":
|
||||
line_split = line.split(" - ")
|
||||
hex_set = line_split[1].split(",")
|
||||
|
@ -130,18 +156,20 @@ class WitnessPlayerLogic:
|
|||
if adj_type == "Requirement Changes":
|
||||
line_split = line.split(" - ")
|
||||
|
||||
required_items = parse_lambda(line_split[2])
|
||||
items_actually_in_the_game = {item[0] for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS}
|
||||
required_items = frozenset(
|
||||
subset.intersection(items_actually_in_the_game)
|
||||
for subset in required_items
|
||||
)
|
||||
|
||||
requirement = {
|
||||
"panels": parse_lambda(line_split[1]),
|
||||
"items": required_items
|
||||
}
|
||||
|
||||
if len(line_split) > 2:
|
||||
required_items = parse_lambda(line_split[2])
|
||||
items_actually_in_the_game = {item[0] for item in StaticWitnessLogic.ALL_SYMBOL_ITEMS}
|
||||
required_items = frozenset(
|
||||
subset.intersection(items_actually_in_the_game)
|
||||
for subset in required_items
|
||||
)
|
||||
|
||||
requirement["items"] = required_items
|
||||
|
||||
self.DEPENDENT_REQUIREMENTS_BY_HEX[line_split[0]] = requirement
|
||||
|
||||
return
|
||||
|
@ -151,11 +179,6 @@ class WitnessPlayerLogic:
|
|||
|
||||
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
|
||||
|
||||
if adj_type == "Region Changes":
|
||||
|
@ -189,18 +212,25 @@ class WitnessPlayerLogic:
|
|||
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():
|
||||
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"):
|
||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME.update(StaticWitnessLogic.ALL_DOOR_ITEMS)
|
||||
if get_option_value(world, player, "shuffle_doors") == 1:
|
||||
adjustment_linesets_in_order.append(get_door_panel_shuffle_list())
|
||||
|
||||
if get_option_value(world, player, "shuffle_doors") == 2:
|
||||
adjustment_linesets_in_order.append(get_doors_simple_list())
|
||||
|
||||
if get_option_value(world, player, "shuffle_doors") == 3:
|
||||
adjustment_linesets_in_order.append(get_doors_complex_list())
|
||||
|
||||
if get_option_value(world, player, "shuffle_doors") == 4:
|
||||
adjustment_linesets_in_order.append(get_doors_max_list())
|
||||
|
||||
if is_option_enabled(world, player, "early_secret_area"):
|
||||
adjustment_linesets_in_order.append(get_early_utm_list())
|
||||
else:
|
||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME = {
|
||||
item for item in self.PROG_ITEMS_ACTUALLY_IN_THE_GAME
|
||||
if item[0] != "Mountaintop River Shape Power On"
|
||||
}
|
||||
|
||||
if is_option_enabled(world, player, "shuffle_lasers"):
|
||||
adjustment_linesets_in_order.append(get_laser_shuffle())
|
||||
|
||||
for adjustment_lineset in adjustment_linesets_in_order:
|
||||
current_adjustment_type = None
|
||||
|
@ -233,62 +263,32 @@ class WitnessPlayerLogic:
|
|||
pair = (name, self.EVENT_ITEM_NAMES[panel])
|
||||
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):
|
||||
"""
|
||||
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.ORIGINAL_EVENT_PANELS.update(self.EVENT_PANELS_FROM_PANELS)
|
||||
self.ORIGINAL_EVENT_PANELS.update(self.EVENT_PANELS_FROM_REGIONS)
|
||||
for region_name, connections in self.CONNECTIONS_BY_REGION_NAME.items():
|
||||
for connection in connections:
|
||||
for panel_req in connection[1]:
|
||||
for panel in panel_req:
|
||||
if panel == "TrueOneWay":
|
||||
continue
|
||||
|
||||
for panel in self.EVENT_PANELS_FROM_REGIONS:
|
||||
for region_name, region in StaticWitnessLogic.ALL_REGIONS_BY_NAME.items():
|
||||
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
|
||||
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)
|
||||
if StaticWitnessLogic.CHECKS_BY_HEX[panel]["region"]["name"] != region_name:
|
||||
self.EVENT_PANELS_FROM_REGIONS.add(panel)
|
||||
|
||||
for event_panel in self.EVENT_PANELS_FROM_PANELS:
|
||||
for panel, panel_req in self.REQUIREMENTS_BY_HEX.items():
|
||||
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.NECESSARY_EVENT_PANELS.add(event_panel)
|
||||
self.EVENT_PANELS.update(self.EVENT_PANELS_FROM_PANELS)
|
||||
self.EVENT_PANELS.update(self.EVENT_PANELS_FROM_REGIONS)
|
||||
|
||||
for always_hex, always_item in self.ALWAYS_EVENT_NAMES_BY_HEX.items():
|
||||
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
|
||||
|
||||
for panel in self.NECESSARY_EVENT_PANELS:
|
||||
for panel in self.EVENT_PANELS:
|
||||
pair = self.make_event_item_pair(panel)
|
||||
self.EVENT_ITEM_PAIRS[pair[0]] = pair[1]
|
||||
|
||||
|
@ -297,8 +297,8 @@ class WitnessPlayerLogic:
|
|||
self.EVENT_PANELS_FROM_REGIONS = set()
|
||||
|
||||
self.PROG_ITEMS_ACTUALLY_IN_THE_GAME = set()
|
||||
self.DOOR_DICT_FOR_CLIENT = dict()
|
||||
self.DOOR_CONNECTIONS_TO_SEVER = set()
|
||||
self.DOOR_ITEMS_BY_ID = dict()
|
||||
self.STARTING_INVENTORY = set()
|
||||
|
||||
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)
|
||||
|
@ -306,8 +306,7 @@ class WitnessPlayerLogic:
|
|||
|
||||
# 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.
|
||||
self.ORIGINAL_EVENT_PANELS = set()
|
||||
self.NECESSARY_EVENT_PANELS = set()
|
||||
self.EVENT_PANELS = set()
|
||||
self.EVENT_ITEM_PAIRS = dict()
|
||||
self.ALWAYS_EVENT_HEX_CODES = set()
|
||||
self.COMPLETELY_DISABLED_CHECKS = set()
|
||||
|
@ -320,42 +319,63 @@ class WitnessPlayerLogic:
|
|||
"0x00037": "Monastery Branch Panels Activate",
|
||||
"0x0A079": "Access to Bunker Laser",
|
||||
"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",
|
||||
"0x09F7F": "Mountain Access",
|
||||
"0x0367C": "Quarry Laser Mill Requirement Met",
|
||||
"0x009A1": "Swamp Rotating Bridge Near Side",
|
||||
"0x009A1": "Swamp Rotated Shapers 1 Activates",
|
||||
"0x00006": "Swamp Cyan Water Drains",
|
||||
"0x00990": "Swamp Broken Shapers 1 Activates",
|
||||
"0x0A8DC": "Lower Avoid 6 Activates",
|
||||
"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",
|
||||
"0x00596": "Swamp Red Water Drains",
|
||||
"0x28B39": "Town Tower 4th Door Opens",
|
||||
"0x00E3A": "Swamp Purple Water Drains",
|
||||
"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 = {
|
||||
"0x0360D": "Symmetry Laser Activation",
|
||||
"0x03608": "Desert Laser Activation",
|
||||
"0x00509": "Symmetry Laser Activation",
|
||||
"0x012FB": "Desert Laser Activation",
|
||||
"0x09F98": "Desert Laser Redirection",
|
||||
"0x03612": "Quarry Laser Activation",
|
||||
"0x19650": "Shadows Laser Activation",
|
||||
"0x0360E": "Keep Laser Activation",
|
||||
"0x03317": "Keep Laser Activation",
|
||||
"0x17CA4": "Monastery Laser Activation",
|
||||
"0x032F5": "Town Laser Activation",
|
||||
"0x03616": "Jungle Laser Activation",
|
||||
"0x09DE0": "Bunker Laser Activation",
|
||||
"0x03615": "Swamp Laser Activation",
|
||||
"0x03613": "Treehouse Laser Activation",
|
||||
"0x01539": "Quarry Laser Activation",
|
||||
"0x181B3": "Shadows Laser Activation",
|
||||
"0x014BB": "Keep Laser Activation",
|
||||
"0x17C65": "Monastery Laser Activation",
|
||||
"0x032F9": "Town Laser Activation",
|
||||
"0x00274": "Jungle Laser Activation",
|
||||
"0x0C2B2": "Bunker Laser Activation",
|
||||
"0x00BF6": "Swamp Laser Activation",
|
||||
"0x028A4": "Treehouse Laser Activation",
|
||||
"0x03535": "Shipwreck Video Pattern Knowledge",
|
||||
"0x03542": "Mountain Video Pattern Knowledge",
|
||||
"0x0339E": "Desert Video Pattern Knowledge",
|
||||
"0x03481": "Tutorial Video Pattern Knowledge",
|
||||
"0x03702": "Jungle Video Pattern Knowledge",
|
||||
"0x2FAF6": "Theater Walkway Video Pattern Knowledge",
|
||||
"0x0356B": "Challenge Video Pattern Knowledge",
|
||||
"0x09F7F": "Mountaintop Trap Door Turns On",
|
||||
"0x17C34": "Mountain Access",
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ class WitnessRegions:
|
|||
source_region = world.get_region(source, player)
|
||||
target_region = world.get_region(target, player)
|
||||
|
||||
#print(source_region)
|
||||
#print(target_region)
|
||||
#print("---")
|
||||
|
||||
connection = Entrance(
|
||||
player,
|
||||
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]:
|
||||
if connection[0] == "Entry":
|
||||
continue
|
||||
self.connect(world, player, region_name,
|
||||
connection[0], player_logic, connection[1])
|
||||
self.connect(world, player, connection[0],
|
||||
region_name, player_logic, connection[1])
|
||||
|
||||
if connection[1] == frozenset({frozenset(["TrueOneWay"])}):
|
||||
self.connect(world, player, region_name, connection[0], player_logic, frozenset({frozenset()}))
|
||||
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_region('First Hallway', player)
|
||||
|
|
|
@ -22,6 +22,21 @@ class WitnessLogic(LogicMixin):
|
|||
def _witness_has_lasers(self, world, player: int, amount: int) -> bool:
|
||||
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("Desert Laser Activation", player)
|
||||
and self.has("Desert Laser Redirection", player))
|
||||
|
@ -48,11 +63,8 @@ class WitnessLogic(LogicMixin):
|
|||
if (check_name + " Solved" in locat.EVENT_LOCATION_TABLE
|
||||
and not self.has(player_logic.EVENT_ITEM_PAIRS[check_name + " Solved"], player)):
|
||||
return False
|
||||
if panel not in player_logic.ORIGINAL_EVENT_PANELS and not self.can_reach(check_name, "Location", player):
|
||||
return False
|
||||
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)):
|
||||
if (check_name + " Solved" not in locat.EVENT_LOCATION_TABLE
|
||||
and not self._witness_meets_item_requirements(panel, world, player, player_logic, locat)):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -79,8 +91,10 @@ class WitnessLogic(LogicMixin):
|
|||
if not self._witness_has_lasers(world, player, get_option_value(world, player, "challenge_lasers")):
|
||||
valid_option = False
|
||||
break
|
||||
elif item in player_logic.ORIGINAL_EVENT_PANELS:
|
||||
valid_option = self._witness_can_solve_panel(item, world, player, player_logic, locat)
|
||||
elif item in player_logic.EVENT_PANELS:
|
||||
if not self._witness_can_solve_panel(item, world, player, player_logic, locat):
|
||||
valid_option = False
|
||||
break
|
||||
elif not self.has(item, player):
|
||||
valid_option = False
|
||||
break
|
||||
|
@ -90,24 +104,6 @@ class WitnessLogic(LogicMixin):
|
|||
|
||||
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):
|
||||
"""
|
||||
Checks whether a set of panels can be solved.
|
||||
|
@ -120,7 +116,12 @@ class WitnessLogic(LogicMixin):
|
|||
valid_option = True
|
||||
|
||||
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
|
||||
break
|
||||
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
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
|
||||
Monastery Laser Activation - 0x00A5B,0x17CE7,0x17FA9,0x17CA4
|
||||
Bunker Laser Activation - 0x00061,0x17D01,0x17C42
|
||||
Shadows Laser Activation - 0x00021,0x17D28,0x17C71
|
||||
|
||||
Requirement Changes:
|
||||
0x17CA4 - True - True
|
||||
0x28B39 - 0x2896A - Reflection
|
||||
0x17C65 - 0x00A5B | 0x17CE7 | 0x17FA9 | 0x17CA4
|
||||
0x0C2B2 - 0x00061 | 0x17D01 | 0x17C42
|
||||
0x181B3 - 0x00021 | 0x17D28 | 0x17C71
|
||||
0x28B39 - True - Reflection
|
||||
0x17CAB - True - True
|
||||
|
||||
Region Changes:
|
||||
Quarry (Quarry) - Outside Quarry - 0x17C09 - Quarry Mill - 0x275ED - Quarry Mill - 0x17CAC
|
||||
|
||||
Disabled Locations:
|
||||
0x03505 (Tutorial Gate Close)
|
||||
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:
|
||||
ALL_SYMBOL_ITEMS = set()
|
||||
ALL_DOOR_ITEMS = set()
|
||||
ALL_DOOR_ITEMS_AS_DICT = dict()
|
||||
ALL_USEFULS = set()
|
||||
ALL_TRAPS = 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()
|
||||
|
||||
EVENT_PANELS_FROM_REGIONS = set()
|
||||
|
@ -47,35 +46,23 @@ class StaticWitnessLogic:
|
|||
if line == "Usefuls:":
|
||||
current_set = self.ALL_USEFULS
|
||||
continue
|
||||
if line == "Doors:":
|
||||
current_set = self.ALL_DOOR_ITEMS
|
||||
continue
|
||||
if line == "":
|
||||
continue
|
||||
|
||||
line_split = line.split(" - ")
|
||||
|
||||
if current_set is not self.ALL_USEFULS:
|
||||
current_set.add((line_split[1], int(line_split[0])))
|
||||
else:
|
||||
if current_set is self.ALL_USEFULS:
|
||||
current_set.add((line_split[1], int(line_split[0]), line_split[2] == "True"))
|
||||
elif current_set is self.ALL_DOOR_ITEMS:
|
||||
new_door = (line_split[1], int(line_split[0]), frozenset(line_split[2].split(",")))
|
||||
current_set.add(new_door)
|
||||
self.ALL_DOOR_ITEMS_AS_DICT[line_split[1]] = new_door
|
||||
else:
|
||||
current_set.add((line_split[1], int(line_split[0])))
|
||||
|
||||
path = os.path.join(os.path.dirname(__file__), "Door_Shuffle.txt")
|
||||
with open(path, "r", encoding="utf-8") as file:
|
||||
for line in file.readlines():
|
||||
line = line.strip()
|
||||
|
||||
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):
|
||||
"""
|
||||
Reads the logic file and does the initial population of data structures
|
||||
|
@ -84,10 +71,7 @@ class StaticWitnessLogic:
|
|||
with open(path, "r", encoding="utf-8") as file:
|
||||
current_region = dict()
|
||||
|
||||
discard_ids = 0
|
||||
normal_panel_ids = 0
|
||||
vault_ids = 0
|
||||
laser_ids = 0
|
||||
counter = 0
|
||||
|
||||
for line in file.readlines():
|
||||
line = line.strip()
|
||||
|
@ -95,7 +79,7 @@ class StaticWitnessLogic:
|
|||
if line == "":
|
||||
continue
|
||||
|
||||
if line[0] != "0":
|
||||
if line[-1] == ":":
|
||||
new_region_and_connections = define_new_region(line)
|
||||
current_region = new_region_and_connections[0]
|
||||
region_name = current_region["name"]
|
||||
|
@ -105,12 +89,33 @@ class StaticWitnessLogic:
|
|||
|
||||
line_split = line.split(" - ")
|
||||
|
||||
location_id = line_split.pop(0)
|
||||
|
||||
check_name_full = line_split.pop(0)
|
||||
|
||||
check_hex = check_name_full[0:7]
|
||||
check_name = check_name_full[9:-1]
|
||||
|
||||
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)
|
||||
|
||||
laser_names = {
|
||||
|
@ -123,53 +128,14 @@ class StaticWitnessLogic:
|
|||
|
||||
if "Discard" in check_name:
|
||||
location_type = "Discard"
|
||||
location_id = discard_ids
|
||||
discard_ids += 1
|
||||
elif is_vault_or_video or check_name == "Tutorial Gate Close":
|
||||
location_type = "Vault"
|
||||
location_id = vault_ids
|
||||
vault_ids += 1
|
||||
elif check_name in laser_names:
|
||||
location_type = "Laser"
|
||||
location_id = laser_ids
|
||||
laser_ids += 1
|
||||
else:
|
||||
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)
|
||||
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)
|
||||
|
||||
|
@ -182,7 +148,7 @@ class StaticWitnessLogic:
|
|||
"checkName": current_region["shortName"] + " " + check_name,
|
||||
"checkHex": check_hex,
|
||||
"region": current_region,
|
||||
"idOffset": location_id,
|
||||
"id": int(location_id),
|
||||
"panelType": location_type
|
||||
}
|
||||
|
||||
|
|
|
@ -98,9 +98,39 @@ def get_adjustment_file(adjustment_file):
|
|||
|
||||
@cache_argsless
|
||||
def get_disable_unrandomized_list():
|
||||
return get_adjustment_file("Disable_Unrandomized.txt")
|
||||
return get_adjustment_file("settings/Disable_Unrandomized.txt")
|
||||
|
||||
|
||||
@cache_argsless
|
||||
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