The Messenger: Fix Portal Plando Issues (#3838)

* add a more clear error message for a missing exit

* remove portal region from the available pool

* ensure plando portals are in the correct spot in the list and it gets cleared correctly
This commit is contained in:
Aaron Wagener 2024-09-17 17:00:26 -05:00 committed by GitHub
parent 30a0b337a2
commit 4e60f3cc54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 23 additions and 10 deletions

View File

@ -215,13 +215,13 @@ def shuffle_portals(world: "MessengerWorld") -> None:
if "Portal" in warp:
exit_string += "Portal"
world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}00"))
world.portal_mapping.insert(PORTALS.index(in_portal), int(f"{REGION_ORDER.index(parent)}00"))
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)}"))
world.portal_mapping.insert(PORTALS.index(in_portal), int(f"{REGION_ORDER.index(parent)}1{SHOP_POINTS[parent].index(warp)}"))
else:
exit_string += f"{warp} Checkpoint"
world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}2{CHECKPOINTS[parent].index(warp)}"))
world.portal_mapping.insert(PORTALS.index(in_portal), 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)
@ -230,12 +230,15 @@ def shuffle_portals(world: "MessengerWorld") -> None:
def handle_planned_portals(plando_connections: List[PlandoConnection]) -> None:
"""checks the provided plando connections for portals and connects them"""
nonlocal available_portals
for connection in plando_connections:
if connection.entrance not in PORTALS:
continue
# let it crash here if input is invalid
create_mapping(connection.entrance, connection.exit)
available_portals.remove(connection.exit)
parent = create_mapping(connection.entrance, connection.exit)
world.plando_portals.append(connection.entrance)
if shuffle_type < ShufflePortals.option_anywhere:
available_portals = [port for port in available_portals if port not in shop_points[parent]]
shuffle_type = world.options.shuffle_portals
shop_points = deepcopy(SHOP_POINTS)
@ -251,8 +254,13 @@ def shuffle_portals(world: "MessengerWorld") -> None:
plando = world.options.portal_plando.value
if not plando:
plando = world.options.plando_connections.value
if plando and world.multiworld.plando_options & PlandoOptions.connections:
handle_planned_portals(plando)
if plando and world.multiworld.plando_options & PlandoOptions.connections and not world.plando_portals:
try:
handle_planned_portals(plando)
# any failure i expect will trigger on available_portals.remove
except ValueError:
raise ValueError(f"Unable to complete portal plando for Player {world.player_name}. "
f"If you attempted to plando a checkpoint, checkpoints must be shuffled.")
for portal in PORTALS:
if portal in world.plando_portals:
@ -276,8 +284,13 @@ def disconnect_portals(world: "MessengerWorld") -> None:
entrance.connected_region = None
if portal in world.spoiler_portal_mapping:
del world.spoiler_portal_mapping[portal]
if len(world.portal_mapping) > len(world.spoiler_portal_mapping):
world.portal_mapping = world.portal_mapping[:len(world.spoiler_portal_mapping)]
if world.plando_portals:
indexes = [PORTALS.index(portal) for portal in world.plando_portals]
planned_portals = []
for index, portal_coord in enumerate(world.portal_mapping):
if index in indexes:
planned_portals.append(portal_coord)
world.portal_mapping = planned_portals
def validate_portals(world: "MessengerWorld") -> bool: