version: 6 # Filler item. special_names: "A Job Well Done" # Symbol items. special_names: "Age Symbol" special_names: "Anagram Symbol" special_names: "Boxes Symbol" special_names: "Cross Symbol" special_names: "Eval Symbol" special_names: "Example Symbol" special_names: "Gender Symbol" special_names: "Job Symbol" special_names: "Lingo Symbol" special_names: "Null Symbol" special_names: "Planet Symbol" special_names: "Pyramid Symbol" special_names: "Question Symbol" special_names: "Sound Symbol" special_names: "Sparkles Symbol" special_names: "Stars Symbol" special_names: "Sun Symbol" special_names: "Sweet Symbol" special_names: "Zero Symbol" # Anti collectable traps special_names: "Anti A" special_names: "Anti B" special_names: "Anti C" special_names: "Anti D" special_names: "Anti E" special_names: "Anti F" special_names: "Anti G" special_names: "Anti H" special_names: "Anti I" special_names: "Anti J" special_names: "Anti K" special_names: "Anti L" special_names: "Anti M" special_names: "Anti N" special_names: "Anti O" special_names: "Anti P" special_names: "Anti Q" special_names: "Anti R" special_names: "Anti S" special_names: "Anti T" special_names: "Anti U" special_names: "Anti V" special_names: "Anti W" special_names: "Anti X" special_names: "Anti Y" special_names: "Anti Z" ef='/lingo2-archipelago/refs/?id=5e9db785dd35baababbef2f321e42fe177b4a491'>refs log blame commit diff stats
path: root/apworld/regions.py
blob: 4f1dd5561c547c21b43c4c09fcc53c3dafd2d61c (plain) (tree)
1
2
3
4
5
6
7

                                

                                                            
                                     

                                            





                                                        
                                                                                                   
 

                                                                                                 
                                                                          



                                              

                                                                                                          
                                                                             

                                                 





                                                                                                    




                                                              




                                                                                                                      
                                                 

                                           



                                                      
 
                                                                               


                                                                 


                                                                             






                                                                                   
                                                                                       









                                                                                    
                                                                                     





                                                                                 
                                                                                         











                                                                                                             

                       
                                                           
                                                                                      
                                                                               




                                                         

                                         
                                                                                         

                                                
from typing import TYPE_CHECKING

from BaseClasses import Region, ItemClassification, Entrance
from .items import Lingo2Item
from .locations import Lingo2Location
from .player_logic import AccessRequirements
from .rules import make_location_lambda

if TYPE_CHECKING:
    from . import Lingo2World


def create_region(room, world: "Lingo2World") -> Region:
    return Region(world.static_logic.get_room_region_name(room.id), world.player, world.multiworld)


def create_locations(room, new_region: Region, world: "Lingo2World", regions: dict[str, Region]):
    for location in world.player_logic.locations_by_room.get(room.id, {}):
        reqs = location.reqs.copy()
        if new_region.name in reqs.rooms:
            reqs.rooms.remove(new_region.name)

        new_location = Lingo2Location(world.player, world.static_logic.location_id_to_name[location.code],
                                      location.code, new_region)
        new_location.access_rule = make_location_lambda(reqs, world, regions)
        new_region.locations.append(new_location)

    for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items():
        new_location = Lingo2Location(world.player, event_name, None, new_region)
        event_item = Lingo2Item(item_name, ItemClassification.progression, None, world.player)
        new_location.place_locked_item(event_item)
        new_region.locations.append(new_location)

def create_regions(world: "Lingo2World"):
    regions = {
        "Menu": Region("Menu", world.player, world.multiworld)
    }

    region_and_room = []

    # Create the regions in two stages. First, make the actual region objects and memoize them. Then, add all of the
    # locations. This allows us to reference the actual region objects in the access rules for the locations, which is
    # faster than having to look them up during access checking.
    for room in world.static_logic.objects.rooms:
        region = create_region(room, world)
        regions[region.name] = region
        region_and_room.append((region, room))

    for (region, room) in region_and_room:
        create_locations(room, region, world, regions)

    regions["Menu"].connect(regions["The Entry - Starting Room"], "Start Game")

    # TODO: The requirements of the opposite trigger also matter.
    for connection in world.static_logic.objects.connections:
        if connection.roof_access and not world.options.daedalus_roof_access:
            continue

        from_region = world.static_logic.get_room_region_name(connection.from_room)
        to_region = world.static_logic.get_room_region_name(connection.to_room)
        connection_name = f"{from_region} -> {to_region}"

        reqs = AccessRequirements()

        if connection.HasField("required_door"):
            reqs.merge(world.player_logic.get_door_open_reqs(connection.required_door))

            door = world.static_logic.objects.doors[connection.required_door]
            wmap = world.static_logic.objects.maps[door.map_id]
            connection_name = f"{connection_name} (using {wmap.name} - {door.name})"

        if connection.HasField("port"):
            port = world.static_logic.objects.ports[connection.port]
            connection_name = f"{connection_name} (via port {port.name})"

            if port.HasField("required_door"):
                reqs.merge(world.player_logic.get_door_open_reqs(port.required_door))

        if connection.HasField("painting"):
            painting = world.static_logic.objects.paintings[connection.painting]
            connection_name = f"{connection_name} (via painting {painting.name})"

            if painting.HasField("required_door"):
                reqs.merge(world.player_logic.get_door_open_reqs(painting.required_door))

        if connection.HasField("panel"):
            proxy = connection.panel
            reqs.merge(world.player_logic.get_panel_reqs(proxy.panel,
                                                         proxy.answer if proxy.HasField("answer") else None))

            panel = world.static_logic.objects.panels[proxy.panel]
            if proxy.HasField("answer"):
                connection_name = f"{connection_name} (via panel {panel.name}/{proxy.answer})"
            else:
                connection_name = f"{connection_name} (via panel {panel.name})"

        reqs.simplify()

        if from_region in regions and to_region in regions:
            connection = Entrance(world.player, connection_name, regions[from_region])
            connection.access_rule = make_location_lambda(reqs, world, regions)

            regions[from_region].exits.append(connection)
            connection.connect(regions[to_region])

            for region in reqs.rooms:
                if region == from_region:
                    continue
                world.multiworld.register_indirect_condition(regions[region], connection)

    world.multiworld.regions += regions.values()