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.py61
1 files changed, 44 insertions, 17 deletions
diff --git a/apworld/regions.py b/apworld/regions.py index 2f9b571..313fd02 100644 --- a/apworld/regions.py +++ b/apworld/regions.py
@@ -4,9 +4,9 @@ import BaseClasses
4from BaseClasses import Region, ItemClassification, Entrance 4from BaseClasses import Region, ItemClassification, Entrance
5from entrance_rando import randomize_entrances 5from entrance_rando import randomize_entrances
6from .items import Lingo2Item 6from .items import Lingo2Item
7from .locations import Lingo2Location 7from .locations import Lingo2Location, LetterPlacementType, Lingo2Entrance
8from .options import FastTravelAccess
8from .player_logic import AccessRequirements 9from .player_logic import AccessRequirements
9from .rules import make_location_lambda
10 10
11if TYPE_CHECKING: 11if TYPE_CHECKING:
12 from . import Lingo2World 12 from . import Lingo2World
@@ -21,13 +21,17 @@ def create_locations(room, new_region: Region, world: "Lingo2World", regions: di
21 reqs = location.reqs.copy() 21 reqs = location.reqs.copy()
22 reqs.remove_room(new_region.name) 22 reqs.remove_room(new_region.name)
23 23
24 new_location = Lingo2Location(world.player, world.static_logic.location_id_to_name[location.code], 24 new_location = Lingo2Location.non_event_location(world, location.code, new_region)
25 location.code, new_region) 25 new_location.set_access_rule(reqs, regions)
26 new_location.access_rule = make_location_lambda(reqs, world, regions) 26 if world.options.restrict_letter_placements:
27 if location.is_letter:
28 new_location.set_up_letter_rule(LetterPlacementType.FORCE)
29 else:
30 new_location.set_up_letter_rule(LetterPlacementType.DISALLOW)
27 new_region.locations.append(new_location) 31 new_region.locations.append(new_location)
28 32
29 for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items(): 33 for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items():
30 new_location = Lingo2Location(world.player, event_name, None, new_region) 34 new_location = Lingo2Location.event_location(world, event_name, new_region)
31 if world.for_tracker and item_name == "Victory": 35 if world.for_tracker and item_name == "Victory":
32 new_location.goal = True 36 new_location.goal = True
33 37
@@ -41,12 +45,11 @@ def create_locations(room, new_region: Region, world: "Lingo2World", regions: di
41 if port.no_shuffle: 45 if port.no_shuffle:
42 continue 46 continue
43 47
44 new_location = Lingo2Location(world.player, f"Worldport {port.id} Entered", None, new_region) 48 new_location = Lingo2Location.event_location(world, f"Worldport {port.id} Entered", new_region)
45 new_location.port_id = port.id 49 new_location.port_id = port.id
46 50
47 if port.HasField("required_door"): 51 if port.HasField("required_door"):
48 new_location.access_rule = \ 52 new_location.set_access_rule(world.player_logic.get_door_open_reqs(port.required_door), regions)
49 make_location_lambda(world.player_logic.get_door_open_reqs(port.required_door), world, regions)
50 53
51 new_region.locations.append(new_location) 54 new_region.locations.append(new_location)
52 55
@@ -135,6 +138,10 @@ def create_regions(world: "Lingo2World"):
135 if connection.HasField("cyan_ending") and connection.cyan_ending and world.options.strict_cyan_ending: 138 if connection.HasField("cyan_ending") and connection.cyan_ending and world.options.strict_cyan_ending:
136 world.player_logic.add_solution_reqs(reqs, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz") 139 world.player_logic.add_solution_reqs(reqs, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")
137 140
141 if (connection.HasField("mint_ending") and connection.mint_ending
142 and world.player_logic.custom_mint_ending is not None):
143 world.player_logic.add_solution_reqs(reqs, world.player_logic.custom_mint_ending)
144
138 reqs.simplify() 145 reqs.simplify()
139 reqs.remove_room(from_region) 146 reqs.remove_room(from_region)
140 147
@@ -144,8 +151,8 @@ def create_regions(world: "Lingo2World"):
144 # what regions are dead ends. 151 # what regions are dead ends.
145 continue 152 continue
146 153
147 connection = Entrance(world.player, connection_name, regions[from_region]) 154 connection = Lingo2Entrance(world, connection_name, regions[from_region])
148 connection.access_rule = make_location_lambda(reqs, world, regions) 155 connection.set_access_rule(reqs, regions)
149 156
150 regions[from_region].exits.append(connection) 157 regions[from_region].exits.append(connection)
151 connection.connect(regions[to_region]) 158 connection.connect(regions[to_region])
@@ -153,6 +160,25 @@ def create_regions(world: "Lingo2World"):
153 for region in reqs.get_referenced_rooms(): 160 for region in reqs.get_referenced_rooms():
154 world.multiworld.register_indirect_condition(regions[region], connection) 161 world.multiworld.register_indirect_condition(regions[region], connection)
155 162
163 if world.options.fast_travel_access != FastTravelAccess.option_vanilla:
164 for rte_map_id in world.player_logic.rte_mapping:
165 rte_map = world.static_logic.objects.maps[rte_map_id]
166 to_region = world.static_logic.get_room_region_name(rte_map.rte_room)
167
168 if to_region not in regions:
169 continue
170
171 connection_name = f"Return to {to_region}"
172 connection = Lingo2Entrance(world, connection_name, regions["Menu"])
173 regions["Menu"].exits.append(connection)
174 connection.connect(regions[to_region])
175
176 if world.options.fast_travel_access == FastTravelAccess.option_items:
177 reqs = AccessRequirements()
178 reqs.items.add(world.static_logic.get_map_rte_item_name(rte_map_id))
179
180 connection.set_access_rule(reqs, regions)
181
156 world.multiworld.regions += regions.values() 182 world.multiworld.regions += regions.values()
157 183
158 184
@@ -184,13 +210,13 @@ def shuffle_entrances(world: "Lingo2World"):
184 from_region = world.multiworld.get_region(from_region_name, world.player) 210 from_region = world.multiworld.get_region(from_region_name, world.player)
185 to_region = world.multiworld.get_region(to_region_name, world.player) 211 to_region = world.multiworld.get_region(to_region_name, world.player)
186 212
187 connection = Entrance(world.player, f"{from_region_name} - {chosen_port.display_name}", from_region) 213 connection = Lingo2Entrance(world, f"{from_region_name} - {chosen_port.display_name}", from_region)
188 from_region.exits.append(connection) 214 from_region.exits.append(connection)
189 connection.connect(to_region) 215 connection.connect(to_region)
190 216
191 if chosen_port.HasField("required_door"): 217 if chosen_port.HasField("required_door"):
192 door_reqs = world.player_logic.get_door_open_reqs(chosen_port.required_door) 218 door_reqs = world.player_logic.get_door_open_reqs(chosen_port.required_door)
193 connection.access_rule = make_location_lambda(door_reqs, world, None) 219 connection.set_access_rule(door_reqs, None)
194 220
195 for region in door_reqs.get_referenced_rooms(): 221 for region in door_reqs.get_referenced_rooms():
196 world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player), 222 world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player),
@@ -206,12 +232,13 @@ def shuffle_entrances(world: "Lingo2World"):
206 entrance = port_region.create_er_target(connection_name) 232 entrance = port_region.create_er_target(connection_name)
207 entrance.randomization_type = BaseClasses.EntranceType.TWO_WAY 233 entrance.randomization_type = BaseClasses.EntranceType.TWO_WAY
208 234
209 er_exit = port_region.create_exit(connection_name) 235 er_exit = Lingo2Entrance(world, connection_name, port_region)
236 port_region.exits.append(er_exit)
210 er_exit.randomization_type = BaseClasses.EntranceType.TWO_WAY 237 er_exit.randomization_type = BaseClasses.EntranceType.TWO_WAY
211 238
212 if port.HasField("required_door"): 239 if port.HasField("required_door"):
213 door_reqs = world.player_logic.get_door_open_reqs(port.required_door) 240 door_reqs = world.player_logic.get_door_open_reqs(port.required_door)
214 er_exit.access_rule = make_location_lambda(door_reqs, world, None) 241 er_exit.set_access_rule(door_reqs, None)
215 242
216 for region in door_reqs.get_referenced_rooms(): 243 for region in door_reqs.get_referenced_rooms():
217 world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player), 244 world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player),
@@ -238,7 +265,7 @@ def connect_ports_from_ut(port_pairings: dict[int, int], world: "Lingo2World"):
238 from_region = world.multiworld.get_region(from_region_name, world.player) 265 from_region = world.multiworld.get_region(from_region_name, world.player)
239 to_region = world.multiworld.get_region(to_region_name, world.player) 266 to_region = world.multiworld.get_region(to_region_name, world.player)
240 267
241 connection = Entrance(world.player, f"{from_region_name} - {from_port.display_name}", from_region) 268 connection = Lingo2Entrance(world, f"{from_region_name} - {from_port.display_name}", from_region)
242 269
243 reqs = AccessRequirements() 270 reqs = AccessRequirements()
244 if from_port.HasField("required_door"): 271 if from_port.HasField("required_door"):
@@ -248,7 +275,7 @@ def connect_ports_from_ut(port_pairings: dict[int, int], world: "Lingo2World"):
248 reqs.items.add(f"Worldport {fpid} Entered") 275 reqs.items.add(f"Worldport {fpid} Entered")
249 276
250 if not reqs.is_empty(): 277 if not reqs.is_empty():
251 connection.access_rule = make_location_lambda(reqs, world, None) 278 connection.set_access_rule(reqs, None)
252 279
253 for region in reqs.get_referenced_rooms(): 280 for region in reqs.get_referenced_rooms():
254 world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player), 281 world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player),