about summary refs log tree commit diff stats
path: root/apworld/regions.py
diff options
context:
space:
mode:
Diffstat (limited to 'apworld/regions.py')
-rw-r--r--apworld/regions.py47
1 files changed, 40 insertions, 7 deletions
diff --git a/apworld/regions.py b/apworld/regions.py index 14fcaac..4f1dd55 100644 --- a/apworld/regions.py +++ b/apworld/regions.py
@@ -1,6 +1,7 @@
1from typing import TYPE_CHECKING 1from typing import TYPE_CHECKING
2 2
3from BaseClasses import Region 3from BaseClasses import Region, ItemClassification, Entrance
4from .items import Lingo2Item
4from .locations import Lingo2Location 5from .locations import Lingo2Location
5from .player_logic import AccessRequirements 6from .player_logic import AccessRequirements
6from .rules import make_location_lambda 7from .rules import make_location_lambda
@@ -10,30 +11,51 @@ if TYPE_CHECKING:
10 11
11 12
12def create_region(room, world: "Lingo2World") -> Region: 13def create_region(room, world: "Lingo2World") -> Region:
13 new_region = Region(world.static_logic.get_room_region_name(room.id), world.player, world.multiworld) 14 return Region(world.static_logic.get_room_region_name(room.id), world.player, world.multiworld)
14 15
16
17def create_locations(room, new_region: Region, world: "Lingo2World", regions: dict[str, Region]):
15 for location in world.player_logic.locations_by_room.get(room.id, {}): 18 for location in world.player_logic.locations_by_room.get(room.id, {}):
19 reqs = location.reqs.copy()
20 if new_region.name in reqs.rooms:
21 reqs.rooms.remove(new_region.name)
22
16 new_location = Lingo2Location(world.player, world.static_logic.location_id_to_name[location.code], 23 new_location = Lingo2Location(world.player, world.static_logic.location_id_to_name[location.code],
17 location.code, new_region) 24 location.code, new_region)
18 new_location.access_rule = make_location_lambda(location.reqs, world) 25 new_location.access_rule = make_location_lambda(reqs, world, regions)
19 new_region.locations.append(new_location) 26 new_region.locations.append(new_location)
20 27
21 return new_region 28 for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items():
22 29 new_location = Lingo2Location(world.player, event_name, None, new_region)
30 event_item = Lingo2Item(item_name, ItemClassification.progression, None, world.player)
31 new_location.place_locked_item(event_item)
32 new_region.locations.append(new_location)
23 33
24def create_regions(world: "Lingo2World"): 34def create_regions(world: "Lingo2World"):
25 regions = { 35 regions = {
26 "Menu": Region("Menu", world.player, world.multiworld) 36 "Menu": Region("Menu", world.player, world.multiworld)
27 } 37 }
28 38
39 region_and_room = []
40
41 # Create the regions in two stages. First, make the actual region objects and memoize them. Then, add all of the
42 # locations. This allows us to reference the actual region objects in the access rules for the locations, which is
43 # faster than having to look them up during access checking.
29 for room in world.static_logic.objects.rooms: 44 for room in world.static_logic.objects.rooms:
30 region = create_region(room, world) 45 region = create_region(room, world)
31 regions[region.name] = region 46 regions[region.name] = region
47 region_and_room.append((region, room))
32 48
33 regions["Menu"].connect(regions["the_entry - Starting Room"], "Start Game") 49 for (region, room) in region_and_room:
50 create_locations(room, region, world, regions)
51
52 regions["Menu"].connect(regions["The Entry - Starting Room"], "Start Game")
34 53
35 # TODO: The requirements of the opposite trigger also matter. 54 # TODO: The requirements of the opposite trigger also matter.
36 for connection in world.static_logic.objects.connections: 55 for connection in world.static_logic.objects.connections:
56 if connection.roof_access and not world.options.daedalus_roof_access:
57 continue
58
37 from_region = world.static_logic.get_room_region_name(connection.from_room) 59 from_region = world.static_logic.get_room_region_name(connection.from_room)
38 to_region = world.static_logic.get_room_region_name(connection.to_room) 60 to_region = world.static_logic.get_room_region_name(connection.to_room)
39 connection_name = f"{from_region} -> {to_region}" 61 connection_name = f"{from_region} -> {to_region}"
@@ -72,7 +94,18 @@ def create_regions(world: "Lingo2World"):
72 else: 94 else:
73 connection_name = f"{connection_name} (via panel {panel.name})" 95 connection_name = f"{connection_name} (via panel {panel.name})"
74 96
97 reqs.simplify()
98
75 if from_region in regions and to_region in regions: 99 if from_region in regions and to_region in regions:
76 regions[from_region].connect(regions[to_region], connection_name, make_location_lambda(reqs, world)) 100 connection = Entrance(world.player, connection_name, regions[from_region])
101 connection.access_rule = make_location_lambda(reqs, world, regions)
102
103 regions[from_region].exits.append(connection)
104 connection.connect(regions[to_region])
105
106 for region in reqs.rooms:
107 if region == from_region:
108 continue
109 world.multiworld.register_indirect_condition(regions[region], connection)
77 110
78 world.multiworld.regions += regions.values() 111 world.multiworld.regions += regions.values()