about summary refs log tree commit diff stats
path: root/apworld/tracker.py
diff options
context:
space:
mode:
Diffstat (limited to 'apworld/tracker.py')
-rw-r--r--apworld/tracker.py47
1 files changed, 44 insertions, 3 deletions
diff --git a/apworld/tracker.py b/apworld/tracker.py index cf2dbe1..a84c3f8 100644 --- a/apworld/tracker.py +++ b/apworld/tracker.py
@@ -1,6 +1,6 @@
1from typing import TYPE_CHECKING 1from typing import TYPE_CHECKING, Iterator
2 2
3from BaseClasses import MultiWorld, CollectionState, ItemClassification 3from BaseClasses import MultiWorld, CollectionState, ItemClassification, Region, Entrance
4from NetUtils import NetworkItem 4from NetUtils import NetworkItem
5from . import Lingo2World, Lingo2Item 5from . import Lingo2World, Lingo2Item
6from .regions import connect_ports_from_ut 6from .regions import connect_ports_from_ut
@@ -22,6 +22,7 @@ class Tracker:
22 checked_locations: set[int] 22 checked_locations: set[int]
23 accessible_locations: set[int] 23 accessible_locations: set[int]
24 accessible_worldports: set[int] 24 accessible_worldports: set[int]
25 goal_accessible: bool
25 26
26 state: CollectionState 27 state: CollectionState
27 28
@@ -31,6 +32,7 @@ class Tracker:
31 self.checked_locations = set() 32 self.checked_locations = set()
32 self.accessible_locations = set() 33 self.accessible_locations = set()
33 self.accessible_worldports = set() 34 self.accessible_worldports = set()
35 self.goal_accessible = False
34 36
35 def setup_slot(self, slot_data): 37 def setup_slot(self, slot_data):
36 Lingo2World.for_tracker = True 38 Lingo2World.for_tracker = True
@@ -45,7 +47,10 @@ class Tracker:
45 self.world.create_regions() 47 self.world.create_regions()
46 48
47 if self.world.options.shuffle_worldports: 49 if self.world.options.shuffle_worldports:
48 port_pairings = {int(fp): int(tp) for fp, tp in slot_data["port_pairings"].items()} 50 port_pairings = {
51 self.world.static_logic.port_id_by_ap_id[int(fp)]: self.world.static_logic.port_id_by_ap_id[int(tp)]
52 for fp, tp in slot_data["port_pairings"].items()
53 }
49 connect_ports_from_ut(port_pairings, self.world) 54 connect_ports_from_ut(port_pairings, self.world)
50 55
51 self.refresh_state() 56 self.refresh_state()
@@ -91,9 +96,11 @@ class Tracker:
91 PLAYER_NUM), prevent_sweep=True) 96 PLAYER_NUM), prevent_sweep=True)
92 97
93 self.state.sweep_for_advancements() 98 self.state.sweep_for_advancements()
99 self.state.update_reachable_regions(PLAYER_NUM)
94 100
95 self.accessible_locations = set() 101 self.accessible_locations = set()
96 self.accessible_worldports = set() 102 self.accessible_worldports = set()
103 self.goal_accessible = False
97 104
98 for region in self.state.reachable_regions[PLAYER_NUM]: 105 for region in self.state.reachable_regions[PLAYER_NUM]:
99 for location in region.locations: 106 for location in region.locations:
@@ -104,3 +111,37 @@ class Tracker:
104 elif hasattr(location, "port_id"): 111 elif hasattr(location, "port_id"):
105 if location.port_id not in self.manager.worldports: 112 if location.port_id not in self.manager.worldports:
106 self.accessible_worldports.add(location.port_id) 113 self.accessible_worldports.add(location.port_id)
114 elif hasattr(location, "goal") and location.goal:
115 if not self.manager.goaled:
116 self.goal_accessible = True
117
118 def get_path_to_location(self, location_id: int) -> list[str] | None:
119 location_name = self.world.location_id_to_name.get(location_id)
120 location = self.multiworld.get_location(location_name, PLAYER_NUM)
121 return self.get_logical_path(location.parent_region)
122
123 def get_path_to_port(self, port_id: int) -> list[str] | None:
124 port = self.world.static_logic.objects.ports[port_id]
125 region_name = self.world.static_logic.get_room_region_name(port.room_id)
126 region = self.multiworld.get_region(region_name, PLAYER_NUM)
127 return self.get_logical_path(region)
128
129 def get_path_to_goal(self):
130 room_id = self.world.player_logic.goal_room_id
131 region_name = self.world.static_logic.get_room_region_name(room_id)
132 region = self.multiworld.get_region(region_name, PLAYER_NUM)
133 return self.get_logical_path(region)
134
135 def get_logical_path(self, region: Region) -> list[str] | None:
136 if region not in self.state.path:
137 return None
138
139 def flist_to_iter(path_value) -> Iterator[str]:
140 while path_value:
141 region_or_entrance, path_value = path_value
142 yield region_or_entrance
143
144 reversed_path = self.state.path.get(region)
145 flat_path = reversed(list(map(str, flist_to_iter(reversed_path))))
146
147 return list(flat_path)[1::2]