diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2025-09-27 11:10:07 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2025-09-27 11:10:07 -0400 |
commit | b524e153ad71e368afbe50da78c4b73c3ac65c5f (patch) | |
tree | 9eb7c03927c227e2459fa1ca970f306180126b34 /apworld/context.py | |
parent | cc6af26a8c0c01538f7220ba2e62ada136fff386 (diff) | |
download | lingo2-archipelago-b524e153ad71e368afbe50da78c4b73c3ac65c5f.tar.gz lingo2-archipelago-b524e153ad71e368afbe50da78c4b73c3ac65c5f.tar.bz2 lingo2-archipelago-b524e153ad71e368afbe50da78c4b73c3ac65c5f.zip |
Added accessible locations tab to game
Diffstat (limited to 'apworld/context.py')
-rw-r--r-- | apworld/context.py | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/apworld/context.py b/apworld/context.py index 05f75a3..2a2149f 100644 --- a/apworld/context.py +++ b/apworld/context.py | |||
@@ -8,9 +8,12 @@ import websockets | |||
8 | 8 | ||
9 | import Utils | 9 | import Utils |
10 | import settings | 10 | import settings |
11 | from BaseClasses import ItemClassification | ||
11 | from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg | 12 | from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg |
12 | from NetUtils import Endpoint, decode, encode | 13 | from NetUtils import Endpoint, decode, encode |
13 | from Utils import async_start | 14 | from Utils import async_start |
15 | from . import Lingo2World | ||
16 | from .tracker import Tracker | ||
14 | 17 | ||
15 | PORT = 43182 | 18 | PORT = 43182 |
16 | MESSAGE_MAX_SIZE = 16*1024*1024 | 19 | MESSAGE_MAX_SIZE = 16*1024*1024 |
@@ -19,9 +22,11 @@ MESSAGE_MAX_SIZE = 16*1024*1024 | |||
19 | class Lingo2GameContext: | 22 | class Lingo2GameContext: |
20 | server: Endpoint | None | 23 | server: Endpoint | None |
21 | client: "Lingo2ClientContext" | 24 | client: "Lingo2ClientContext" |
25 | tracker: Tracker | ||
22 | 26 | ||
23 | def __init__(self): | 27 | def __init__(self): |
24 | self.server = None | 28 | self.server = None |
29 | self.tracker = Tracker() | ||
25 | 30 | ||
26 | def send_connected(self): | 31 | def send_connected(self): |
27 | msg = { | 32 | msg = { |
@@ -84,6 +89,22 @@ class Lingo2GameContext: | |||
84 | 89 | ||
85 | async_start(self.send_msgs([msg]), name="notif") | 90 | async_start(self.send_msgs([msg]), name="notif") |
86 | 91 | ||
92 | def send_accessible_locations(self): | ||
93 | msg = { | ||
94 | "cmd": "AccessibleLocations", | ||
95 | "locations": list(self.tracker.accessible_locations), | ||
96 | } | ||
97 | |||
98 | async_start(self.send_msgs([msg]), name="accessible locations") | ||
99 | |||
100 | def send_update_locations(self, locations): | ||
101 | msg = { | ||
102 | "cmd": "UpdateLocations", | ||
103 | "locations": locations, | ||
104 | } | ||
105 | |||
106 | async_start(self.send_msgs([msg]), name="update locations") | ||
107 | |||
87 | async def send_msgs(self, msgs: list[Any]) -> None: | 108 | async def send_msgs(self, msgs: list[Any]) -> None: |
88 | """ `msgs` JSON serializable """ | 109 | """ `msgs` JSON serializable """ |
89 | if not self.server or not self.server.socket.open or self.server.socket.closed: | 110 | if not self.server or not self.server.socket.open or self.server.socket.closed: |
@@ -119,7 +140,14 @@ class Lingo2ClientContext(CommonContext): | |||
119 | 140 | ||
120 | if self.game_ctx.server is not None: | 141 | if self.game_ctx.server is not None: |
121 | self.game_ctx.send_connected() | 142 | self.game_ctx.send_connected() |
143 | |||
144 | self.game_ctx.tracker.setup_slot(self.slot_data) | ||
145 | elif cmd == "RoomUpdate": | ||
146 | if self.game_ctx.server is not None: | ||
147 | self.game_ctx.send_update_locations(args["checked_locations"]) | ||
122 | elif cmd == "ReceivedItems": | 148 | elif cmd == "ReceivedItems": |
149 | self.game_ctx.tracker.set_collected_items(self.items_received) | ||
150 | |||
123 | if self.game_ctx.server is not None: | 151 | if self.game_ctx.server is not None: |
124 | cur_index = 0 | 152 | cur_index = 0 |
125 | items = [] | 153 | items = [] |
@@ -141,6 +169,9 @@ class Lingo2ClientContext(CommonContext): | |||
141 | items.append(item_msg) | 169 | items.append(item_msg) |
142 | 170 | ||
143 | self.game_ctx.send_item_received(items) | 171 | self.game_ctx.send_item_received(items) |
172 | |||
173 | if any(ItemClassification.progression in ItemClassification(item.flags) for item in args["items"]): | ||
174 | self.game_ctx.send_accessible_locations() | ||
144 | elif cmd == "PrintJSON": | 175 | elif cmd == "PrintJSON": |
145 | if self.game_ctx.server is not None: | 176 | if self.game_ctx.server is not None: |
146 | if "receiving" in args and "item" in args and args["item"].player == self.slot: | 177 | if "receiving" in args and "item" in args and args["item"].player == self.slot: |
@@ -195,6 +226,9 @@ class Lingo2ClientContext(CommonContext): | |||
195 | 226 | ||
196 | self.game_ctx.send_location_info(locations) | 227 | self.game_ctx.send_location_info(locations) |
197 | 228 | ||
229 | if cmd in ["Connected", "RoomUpdate"]: | ||
230 | self.game_ctx.tracker.set_checked_locations(self.checked_locations) | ||
231 | |||
198 | 232 | ||
199 | async def pipe_loop(ctx: Lingo2GameContext): | 233 | async def pipe_loop(ctx: Lingo2GameContext): |
200 | while not ctx.client.exit_event.is_set(): | 234 | while not ctx.client.exit_event.is_set(): |
@@ -205,6 +239,7 @@ async def pipe_loop(ctx: Lingo2GameContext): | |||
205 | logger.info("Connected to Lingo 2!") | 239 | logger.info("Connected to Lingo 2!") |
206 | if ctx.client.auth is not None: | 240 | if ctx.client.auth is not None: |
207 | ctx.send_connected() | 241 | ctx.send_connected() |
242 | ctx.send_accessible_locations() | ||
208 | async for data in ctx.server.socket: | 243 | async for data in ctx.server.socket: |
209 | for msg in decode(data): | 244 | for msg in decode(data): |
210 | await process_game_cmd(ctx, msg) | 245 | await process_game_cmd(ctx, msg) |
@@ -237,10 +272,7 @@ async def process_game_cmd(ctx: Lingo2GameContext, args: dict): | |||
237 | async def run_game(): | 272 | async def run_game(): |
238 | exe_file = settings.get_settings().lingo2_options.exe_file | 273 | exe_file = settings.get_settings().lingo2_options.exe_file |
239 | 274 | ||
240 | from worlds import AutoWorldRegister | 275 | if Lingo2World.zip_path is not None: |
241 | world = AutoWorldRegister.world_types["Lingo 2"] | ||
242 | |||
243 | if world.zip_path is not None: | ||
244 | # This is a packaged apworld. | 276 | # This is a packaged apworld. |
245 | init_scene = pkgutil.get_data(__name__, "client/run_from_apworld.tscn") | 277 | init_scene = pkgutil.get_data(__name__, "client/run_from_apworld.tscn") |
246 | init_path = Utils.local_path("data", "lingo2_init.tscn") | 278 | init_path = Utils.local_path("data", "lingo2_init.tscn") |
@@ -254,7 +286,7 @@ async def run_game(): | |||
254 | "--scene", | 286 | "--scene", |
255 | init_path, | 287 | init_path, |
256 | "--", | 288 | "--", |
257 | str(world.zip_path.absolute()), | 289 | str(Lingo2World.zip_path.absolute()), |
258 | ], | 290 | ], |
259 | cwd=os.path.dirname(exe_file), | 291 | cwd=os.path.dirname(exe_file), |
260 | ) | 292 | ) |