| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | """
 | 
					
						
							|  |  |  | Defines Region for The Witness, assigns locations to them, | 
					
						
							|  |  |  | and connects them with the proper requirements | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from BaseClasses import MultiWorld, Entrance | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  | from .static_logic import StaticWitnessLogic | 
					
						
							|  |  |  | from .Options import get_option_value | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  | from .locations import WitnessPlayerLocations, StaticWitnessLocations | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | from .player_logic import WitnessPlayerLogic | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WitnessRegions: | 
					
						
							|  |  |  |     """Class that defines Witness Regions""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     locat = None | 
					
						
							|  |  |  |     logic = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def make_lambda(self, panel_hex_to_solve_set, world, player, player_logic): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Lambdas are made in a for loop, so the values have to be captured | 
					
						
							|  |  |  |         This function is for that purpose | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return lambda state: state._witness_can_solve_panels( | 
					
						
							|  |  |  |             panel_hex_to_solve_set, world, player, player_logic, self.locat | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def connect(self, world: MultiWorld, player: int, source: str, target: str, player_logic: WitnessPlayerLogic, | 
					
						
							| 
									
										
										
										
											2023-03-03 00:08:24 +01:00
										 |  |  |                 panel_hex_to_solve_set=frozenset({frozenset()}), backwards: bool = False): | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         connect two regions and set the corresponding requirement | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         source_region = world.get_region(source, player) | 
					
						
							|  |  |  |         target_region = world.get_region(target, player) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 00:08:24 +01:00
										 |  |  |         backwards = " Backwards" if backwards else "" | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |         connection = Entrance( | 
					
						
							|  |  |  |             player, | 
					
						
							| 
									
										
										
										
											2023-03-03 00:08:24 +01:00
										 |  |  |             source + " to " + target + backwards, | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |             source_region | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         connection.access_rule = self.make_lambda(panel_hex_to_solve_set, world, player, player_logic) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         source_region.exits.append(connection) | 
					
						
							|  |  |  |         connection.connect(target_region) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self, world, player: int, player_logic: WitnessPlayerLogic): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Creates all the regions for The Witness | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         from . import create_region | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         world.regions += [ | 
					
						
							|  |  |  |             create_region(world, player, 'Menu', self.locat, None, ["The Splashscreen?"]), | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |         difficulty = get_option_value(world, player, "puzzle_randomization") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if difficulty == 1: | 
					
						
							|  |  |  |             reference_logic = StaticWitnessLogic.sigma_expert | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  |         elif difficulty == 0: | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |             reference_logic = StaticWitnessLogic.sigma_normal | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  |         else: | 
					
						
							|  |  |  |             reference_logic = StaticWitnessLogic.vanilla | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |         all_locations = set() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |         for region_name, region in reference_logic.ALL_REGIONS_BY_NAME.items(): | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |             locations_for_this_region = [ | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |                 reference_logic.CHECKS_BY_HEX[panel]["checkName"] for panel in region["panels"] | 
					
						
							|  |  |  |                 if reference_logic.CHECKS_BY_HEX[panel]["checkName"] in self.locat.CHECK_LOCATION_TABLE | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |             ] | 
					
						
							|  |  |  |             locations_for_this_region += [ | 
					
						
							| 
									
										
										
										
											2023-02-01 21:18:07 +01:00
										 |  |  |                 StaticWitnessLocations.get_event_name(panel) for panel in region["panels"] | 
					
						
							|  |  |  |                 if StaticWitnessLocations.get_event_name(panel) in self.locat.EVENT_LOCATION_TABLE | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             all_locations = all_locations | set(locations_for_this_region) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             world.regions += [ | 
					
						
							| 
									
										
										
										
											2022-09-18 04:20:59 +02:00
										 |  |  |                 create_region(world, player, region_name, self.locat, locations_for_this_region) | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |         for region_name, region in reference_logic.ALL_REGIONS_BY_NAME.items(): | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  |             for connection in player_logic.CONNECTIONS_BY_REGION_NAME[region_name]: | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |                 if connection[1] == frozenset({frozenset(["TrueOneWay"])}): | 
					
						
							|  |  |  |                     self.connect(world, player, region_name, connection[0], player_logic, frozenset({frozenset()})) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 00:08:24 +01:00
										 |  |  |                 backwards_connections = set() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  |                 for subset in connection[1]: | 
					
						
							|  |  |  |                     if all({panel in player_logic.DOOR_ITEMS_BY_ID for panel in subset}): | 
					
						
							| 
									
										
										
										
											2022-10-09 04:13:52 +02:00
										 |  |  |                         if all({reference_logic.CHECKS_BY_HEX[panel]["id"] is None for panel in subset}): | 
					
						
							| 
									
										
										
										
											2023-03-03 00:08:24 +01:00
										 |  |  |                             backwards_connections.add(subset) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if backwards_connections: | 
					
						
							|  |  |  |                     self.connect( | 
					
						
							|  |  |  |                         world, player, connection[0], region_name, player_logic, | 
					
						
							|  |  |  |                         frozenset(backwards_connections), True | 
					
						
							|  |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2022-07-17 12:56:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 self.connect(world, player, region_name, connection[0], player_logic, connection[1]) | 
					
						
							| 
									
										
										
										
											2022-04-29 00:42:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         world.get_entrance("The Splashscreen?", player).connect( | 
					
						
							|  |  |  |             world.get_region('First Hallway', player) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, locat: WitnessPlayerLocations): | 
					
						
							|  |  |  |         self.locat = locat |