The Messenger: Fix various portal shuffle issues (#2976)
* put constants in a bit more sensical order * fix accidental incorrect scoping * fix plando rules not being respected * add docstrings for the plando functions * fix the portal output pools being overwritten * use shuffle and pop instead of removing by content so plando can go to the same area twice * move portal pool rebuilding outside mapping creation * remove plando_connection cleansing since it isn't shared with transition shuffle
This commit is contained in:
		
							parent
							
								
									5f0112e783
								
							
						
					
					
						commit
						b7ac6a4cbd
					
				|  | @ -1,3 +1,4 @@ | |||
| from copy import deepcopy | ||||
| from typing import List, TYPE_CHECKING | ||||
| 
 | ||||
| from BaseClasses import CollectionState, PlandoOptions | ||||
|  | @ -18,24 +19,6 @@ PORTALS = [ | |||
| ] | ||||
| 
 | ||||
| 
 | ||||
| REGION_ORDER = [ | ||||
|     "Autumn Hills", | ||||
|     "Forlorn Temple", | ||||
|     "Catacombs", | ||||
|     "Bamboo Creek", | ||||
|     "Howling Grotto", | ||||
|     "Quillshroom Marsh", | ||||
|     "Searing Crags", | ||||
|     "Glacial Peak", | ||||
|     "Tower of Time", | ||||
|     "Cloud Ruins", | ||||
|     "Underworld", | ||||
|     "Riviere Turquoise", | ||||
|     "Elemental Skylands", | ||||
|     "Sunken Shrine", | ||||
| ] | ||||
| 
 | ||||
| 
 | ||||
| SHOP_POINTS = { | ||||
|     "Autumn Hills": [ | ||||
|         "Climbing Claws", | ||||
|  | @ -204,30 +187,48 @@ CHECKPOINTS = { | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| REGION_ORDER = [ | ||||
|     "Autumn Hills", | ||||
|     "Forlorn Temple", | ||||
|     "Catacombs", | ||||
|     "Bamboo Creek", | ||||
|     "Howling Grotto", | ||||
|     "Quillshroom Marsh", | ||||
|     "Searing Crags", | ||||
|     "Glacial Peak", | ||||
|     "Tower of Time", | ||||
|     "Cloud Ruins", | ||||
|     "Underworld", | ||||
|     "Riviere Turquoise", | ||||
|     "Elemental Skylands", | ||||
|     "Sunken Shrine", | ||||
| ] | ||||
| 
 | ||||
| 
 | ||||
| def shuffle_portals(world: "MessengerWorld") -> None: | ||||
|     def create_mapping(in_portal: str, warp: str) -> None: | ||||
|         nonlocal available_portals | ||||
|     """shuffles the output of the portals from the main hub""" | ||||
|     def create_mapping(in_portal: str, warp: str) -> str: | ||||
|         """assigns the chosen output to the input""" | ||||
|         parent = out_to_parent[warp] | ||||
|         exit_string = f"{parent.strip(' ')} - " | ||||
| 
 | ||||
|         if "Portal" in warp: | ||||
|             exit_string += "Portal" | ||||
|             world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}00")) | ||||
|         elif warp_point in SHOP_POINTS[parent]: | ||||
|             exit_string += f"{warp_point} Shop" | ||||
|             world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}1{SHOP_POINTS[parent].index(warp_point)}")) | ||||
|         elif warp in SHOP_POINTS[parent]: | ||||
|             exit_string += f"{warp} Shop" | ||||
|             world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}1{SHOP_POINTS[parent].index(warp)}")) | ||||
|         else: | ||||
|             exit_string += f"{warp_point} Checkpoint" | ||||
|             world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}2{CHECKPOINTS[parent].index(warp_point)}")) | ||||
|             exit_string += f"{warp} Checkpoint" | ||||
|             world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}2{CHECKPOINTS[parent].index(warp)}")) | ||||
| 
 | ||||
|         world.spoiler_portal_mapping[in_portal] = exit_string | ||||
|         connect_portal(world, in_portal, exit_string) | ||||
| 
 | ||||
|         available_portals.remove(warp) | ||||
|         if shuffle_type < ShufflePortals.option_anywhere: | ||||
|             available_portals = [port for port in available_portals if port not in shop_points[parent]] | ||||
|         return parent | ||||
| 
 | ||||
|     def handle_planned_portals(plando_connections: List[PlandoConnection]) -> None: | ||||
|         """checks the provided plando connections for portals and connects them""" | ||||
|         for connection in plando_connections: | ||||
|             if connection.entrance not in PORTALS: | ||||
|                 continue | ||||
|  | @ -236,22 +237,28 @@ def shuffle_portals(world: "MessengerWorld") -> None: | |||
|             world.plando_portals.append(connection.entrance) | ||||
| 
 | ||||
|     shuffle_type = world.options.shuffle_portals | ||||
|     shop_points = SHOP_POINTS.copy() | ||||
|     shop_points = deepcopy(SHOP_POINTS) | ||||
|     for portal in PORTALS: | ||||
|         shop_points[portal].append(f"{portal} Portal") | ||||
|     if shuffle_type > ShufflePortals.option_shops: | ||||
|         shop_points.update(CHECKPOINTS) | ||||
|         for area, points in CHECKPOINTS.items(): | ||||
|             shop_points[area] += points | ||||
|     out_to_parent = {checkpoint: parent for parent, checkpoints in shop_points.items() for checkpoint in checkpoints} | ||||
|     available_portals = [val for zone in shop_points.values() for val in zone] | ||||
|     world.random.shuffle(available_portals) | ||||
| 
 | ||||
|     plando = world.multiworld.plando_connections[world.player] | ||||
|     if plando and world.multiworld.plando_options & PlandoOptions.connections: | ||||
|         handle_planned_portals(plando) | ||||
|         world.multiworld.plando_connections[world.player] = [connection for connection in plando | ||||
|                                                              if connection.entrance not in PORTALS] | ||||
| 
 | ||||
|     for portal in PORTALS: | ||||
|         warp_point = world.random.choice(available_portals) | ||||
|         create_mapping(portal, warp_point) | ||||
|         if portal in world.plando_portals: | ||||
|             continue | ||||
|         warp_point = available_portals.pop() | ||||
|         parent = create_mapping(portal, warp_point) | ||||
|         if shuffle_type < ShufflePortals.option_anywhere: | ||||
|             available_portals = [port for port in available_portals if port not in shop_points[parent]] | ||||
|             world.random.shuffle(available_portals) | ||||
| 
 | ||||
| 
 | ||||
| def connect_portal(world: "MessengerWorld", portal: str, out_region: str) -> None: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue