From 424f5d4a830fb43f86c76d73d795412890d55bc2 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Mon, 22 Sep 2025 12:05:18 -0400 Subject: [Apworld] Added worldport shuffle --- apworld/regions.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'apworld/regions.py') diff --git a/apworld/regions.py b/apworld/regions.py index 993eec8..a7d9a1c 100644 --- a/apworld/regions.py +++ b/apworld/regions.py @@ -1,6 +1,8 @@ from typing import TYPE_CHECKING +import BaseClasses from BaseClasses import Region, ItemClassification, Entrance +from entrance_rando import randomize_entrances from .items import Lingo2Item from .locations import Lingo2Location from .player_logic import AccessRequirements @@ -76,6 +78,9 @@ def create_regions(world: "Lingo2World"): port = world.static_logic.objects.ports[connection.port] connection_name = f"{connection_name} (via port {port.name})" + if world.options.shuffle_worldports and not port.no_shuffle: + continue + if port.HasField("required_door"): reqs.merge(world.player_logic.get_door_open_reqs(port.required_door)) @@ -116,3 +121,68 @@ def create_regions(world: "Lingo2World"): world.multiworld.register_indirect_condition(regions[region], connection) world.multiworld.regions += regions.values() + + +def shuffle_entrances(world: "Lingo2World"): + er_entrances: list[Entrance] = [] + er_exits: list[Entrance] = [] + + port_id_by_name: dict[str, int] = {} + + for port in world.static_logic.objects.ports: + if port.no_shuffle: + continue + + port_region_name = world.static_logic.get_room_region_name(port.room_id) + port_region = world.multiworld.get_region(port_region_name, world.player) + + connection_name = f"{port_region_name} - {port.name}" + port_id_by_name[connection_name] = port.id + + entrance = port_region.create_er_target(connection_name) + entrance.randomization_type = BaseClasses.EntranceType.TWO_WAY + + er_exit = port_region.create_exit(connection_name) + er_exit.randomization_type = BaseClasses.EntranceType.TWO_WAY + + if port.HasField("required_door"): + door_reqs = world.player_logic.get_door_open_reqs(port.required_door) + er_exit.access_rule = make_location_lambda(door_reqs, world, None) + + for region in door_reqs.get_referenced_rooms(): + world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player), + er_exit) + + er_entrances.append(entrance) + er_exits.append(er_exit) + + result = randomize_entrances(world, True, {0:[0]}, False, er_entrances, + er_exits) + + for (f, to) in result.pairings: + world.port_pairings[port_id_by_name[f]] = port_id_by_name[to] + + +def connect_ports_from_ut(port_pairings: dict[int, int], world: "Lingo2World"): + for fpid, tpid in port_pairings.items(): + from_port = world.static_logic.objects.ports[fpid] + to_port = world.static_logic.objects.ports[tpid] + + from_region_name = world.static_logic.get_room_region_name(from_port.room_id) + to_region_name = world.static_logic.get_room_region_name(to_port.room_id) + + from_region = world.multiworld.get_region(from_region_name, world.player) + to_region = world.multiworld.get_region(to_region_name, world.player) + + connection = Entrance(world.player, f"{from_region_name} - {from_port.name}", from_region) + + if from_port.HasField("required_door"): + door_reqs = world.player_logic.get_door_open_reqs(from_port.required_door) + connection.access_rule = make_location_lambda(door_reqs, world, None) + + for region in door_reqs.get_referenced_rooms(): + world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player), + connection) + + from_region.exits.append(connection) + connection.connect(to_region) -- cgit 1.4.1