Skip to content

Commit b7ac6a4

Browse files
The Messenger: Fix various portal shuffle issues (ArchipelagoMW#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
1 parent 5f0112e commit b7ac6a4

File tree

1 file changed

+41
-34
lines changed

1 file changed

+41
-34
lines changed

worlds/messenger/portals.py

+41-34
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from copy import deepcopy
12
from typing import List, TYPE_CHECKING
23

34
from BaseClasses import CollectionState, PlandoOptions
@@ -18,24 +19,6 @@
1819
]
1920

2021

21-
REGION_ORDER = [
22-
"Autumn Hills",
23-
"Forlorn Temple",
24-
"Catacombs",
25-
"Bamboo Creek",
26-
"Howling Grotto",
27-
"Quillshroom Marsh",
28-
"Searing Crags",
29-
"Glacial Peak",
30-
"Tower of Time",
31-
"Cloud Ruins",
32-
"Underworld",
33-
"Riviere Turquoise",
34-
"Elemental Skylands",
35-
"Sunken Shrine",
36-
]
37-
38-
3922
SHOP_POINTS = {
4023
"Autumn Hills": [
4124
"Climbing Claws",
@@ -204,30 +187,48 @@
204187
}
205188

206189

190+
REGION_ORDER = [
191+
"Autumn Hills",
192+
"Forlorn Temple",
193+
"Catacombs",
194+
"Bamboo Creek",
195+
"Howling Grotto",
196+
"Quillshroom Marsh",
197+
"Searing Crags",
198+
"Glacial Peak",
199+
"Tower of Time",
200+
"Cloud Ruins",
201+
"Underworld",
202+
"Riviere Turquoise",
203+
"Elemental Skylands",
204+
"Sunken Shrine",
205+
]
206+
207+
207208
def shuffle_portals(world: "MessengerWorld") -> None:
208-
def create_mapping(in_portal: str, warp: str) -> None:
209-
nonlocal available_portals
209+
"""shuffles the output of the portals from the main hub"""
210+
def create_mapping(in_portal: str, warp: str) -> str:
211+
"""assigns the chosen output to the input"""
210212
parent = out_to_parent[warp]
211213
exit_string = f"{parent.strip(' ')} - "
212214

213215
if "Portal" in warp:
214216
exit_string += "Portal"
215217
world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}00"))
216-
elif warp_point in SHOP_POINTS[parent]:
217-
exit_string += f"{warp_point} Shop"
218-
world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}1{SHOP_POINTS[parent].index(warp_point)}"))
218+
elif warp in SHOP_POINTS[parent]:
219+
exit_string += f"{warp} Shop"
220+
world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}1{SHOP_POINTS[parent].index(warp)}"))
219221
else:
220-
exit_string += f"{warp_point} Checkpoint"
221-
world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}2{CHECKPOINTS[parent].index(warp_point)}"))
222+
exit_string += f"{warp} Checkpoint"
223+
world.portal_mapping.append(int(f"{REGION_ORDER.index(parent)}2{CHECKPOINTS[parent].index(warp)}"))
222224

223225
world.spoiler_portal_mapping[in_portal] = exit_string
224226
connect_portal(world, in_portal, exit_string)
225227

226-
available_portals.remove(warp)
227-
if shuffle_type < ShufflePortals.option_anywhere:
228-
available_portals = [port for port in available_portals if port not in shop_points[parent]]
228+
return parent
229229

230230
def handle_planned_portals(plando_connections: List[PlandoConnection]) -> None:
231+
"""checks the provided plando connections for portals and connects them"""
231232
for connection in plando_connections:
232233
if connection.entrance not in PORTALS:
233234
continue
@@ -236,22 +237,28 @@ def handle_planned_portals(plando_connections: List[PlandoConnection]) -> None:
236237
world.plando_portals.append(connection.entrance)
237238

238239
shuffle_type = world.options.shuffle_portals
239-
shop_points = SHOP_POINTS.copy()
240+
shop_points = deepcopy(SHOP_POINTS)
240241
for portal in PORTALS:
241242
shop_points[portal].append(f"{portal} Portal")
242243
if shuffle_type > ShufflePortals.option_shops:
243-
shop_points.update(CHECKPOINTS)
244+
for area, points in CHECKPOINTS.items():
245+
shop_points[area] += points
244246
out_to_parent = {checkpoint: parent for parent, checkpoints in shop_points.items() for checkpoint in checkpoints}
245247
available_portals = [val for zone in shop_points.values() for val in zone]
248+
world.random.shuffle(available_portals)
246249

247250
plando = world.multiworld.plando_connections[world.player]
248251
if plando and world.multiworld.plando_options & PlandoOptions.connections:
249252
handle_planned_portals(plando)
250-
world.multiworld.plando_connections[world.player] = [connection for connection in plando
251-
if connection.entrance not in PORTALS]
253+
252254
for portal in PORTALS:
253-
warp_point = world.random.choice(available_portals)
254-
create_mapping(portal, warp_point)
255+
if portal in world.plando_portals:
256+
continue
257+
warp_point = available_portals.pop()
258+
parent = create_mapping(portal, warp_point)
259+
if shuffle_type < ShufflePortals.option_anywhere:
260+
available_portals = [port for port in available_portals if port not in shop_points[parent]]
261+
world.random.shuffle(available_portals)
255262

256263

257264
def connect_portal(world: "MessengerWorld", portal: str, out_region: str) -> None:

0 commit comments

Comments
 (0)