mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
A world's player_logic is accessible from the LingoWorld object, so it's not necessary to also pass the LingoPlayerLogic object through every function that uses both.
94 lines
4.1 KiB
Python
94 lines
4.1 KiB
Python
from typing import Dict, Optional, TYPE_CHECKING
|
|
|
|
from BaseClasses import Entrance, ItemClassification, Region
|
|
from .datatypes import Room, RoomAndDoor
|
|
from .items import LingoItem
|
|
from .locations import LingoLocation
|
|
from .rules import lingo_can_use_entrance, make_location_lambda
|
|
from .static_logic import ALL_ROOMS, PAINTINGS
|
|
|
|
if TYPE_CHECKING:
|
|
from . import LingoWorld
|
|
|
|
|
|
def create_region(room: Room, world: "LingoWorld") -> Region:
|
|
new_region = Region(room.name, world.player, world.multiworld)
|
|
for location in world.player_logic.locations_by_room.get(room.name, {}):
|
|
new_location = LingoLocation(world.player, location.name, location.code, new_region)
|
|
new_location.access_rule = make_location_lambda(location, world)
|
|
new_region.locations.append(new_location)
|
|
if location.name in world.player_logic.event_loc_to_item:
|
|
event_name = world.player_logic.event_loc_to_item[location.name]
|
|
event_item = LingoItem(event_name, ItemClassification.progression, None, world.player)
|
|
new_location.place_locked_item(event_item)
|
|
|
|
return new_region
|
|
|
|
|
|
def connect_entrance(regions: Dict[str, Region], source_region: Region, target_region: Region, description: str,
|
|
door: Optional[RoomAndDoor], world: "LingoWorld"):
|
|
connection = Entrance(world.player, description, source_region)
|
|
connection.access_rule = lambda state: lingo_can_use_entrance(state, target_region.name, door, world)
|
|
|
|
source_region.exits.append(connection)
|
|
connection.connect(target_region)
|
|
|
|
if door is not None:
|
|
effective_room = target_region.name if door.room is None else door.room
|
|
if door.door not in world.player_logic.item_by_door.get(effective_room, {}):
|
|
for region in world.player_logic.calculate_door_requirements(effective_room, door.door, world).rooms:
|
|
world.multiworld.register_indirect_condition(regions[region], connection)
|
|
|
|
|
|
def connect_painting(regions: Dict[str, Region], warp_enter: str, warp_exit: str, world: "LingoWorld") -> None:
|
|
source_painting = PAINTINGS[warp_enter]
|
|
target_painting = PAINTINGS[warp_exit]
|
|
|
|
target_region = regions[target_painting.room]
|
|
source_region = regions[source_painting.room]
|
|
|
|
entrance_name = f"{source_painting.room} to {target_painting.room} ({source_painting.id} Painting)"
|
|
connect_entrance(regions, source_region, target_region, entrance_name, source_painting.required_door, world)
|
|
|
|
|
|
def create_regions(world: "LingoWorld") -> None:
|
|
regions = {
|
|
"Menu": Region("Menu", world.player, world.multiworld)
|
|
}
|
|
|
|
painting_shuffle = world.options.shuffle_paintings
|
|
early_color_hallways = world.options.early_color_hallways
|
|
|
|
# Instantiate all rooms as regions with their locations first.
|
|
for room in ALL_ROOMS:
|
|
regions[room.name] = create_region(room, world)
|
|
|
|
# Connect all created regions now that they exist.
|
|
for room in ALL_ROOMS:
|
|
for entrance in room.entrances:
|
|
# Don't use the vanilla painting connections if we are shuffling paintings.
|
|
if entrance.painting and painting_shuffle:
|
|
continue
|
|
|
|
entrance_name = f"{entrance.room} to {room.name}"
|
|
if entrance.door is not None:
|
|
if entrance.door.room is not None:
|
|
entrance_name += f" (through {entrance.door.room} - {entrance.door.door})"
|
|
else:
|
|
entrance_name += f" (through {room.name} - {entrance.door.door})"
|
|
|
|
connect_entrance(regions, regions[entrance.room], regions[room.name], entrance_name, entrance.door, world)
|
|
|
|
# Add the fake pilgrimage.
|
|
connect_entrance(regions, regions["Outside The Agreeable"], regions["Pilgrim Antechamber"], "Pilgrimage",
|
|
RoomAndDoor("Pilgrim Antechamber", "Pilgrimage"), world)
|
|
|
|
if early_color_hallways:
|
|
regions["Starting Room"].connect(regions["Outside The Undeterred"], "Early Color Hallways")
|
|
|
|
if painting_shuffle:
|
|
for warp_enter, warp_exit in world.player_logic.painting_mapping.items():
|
|
connect_painting(regions, warp_enter, warp_exit, world)
|
|
|
|
world.multiworld.regions += regions.values()
|