diff options
Diffstat (limited to 'apworld/context.py')
| -rw-r--r-- | apworld/context.py | 33 |
1 files changed, 33 insertions, 0 deletions
| diff --git a/apworld/context.py b/apworld/context.py index e5ba3cf..86392f9 100644 --- a/apworld/context.py +++ b/apworld/context.py | |||
| @@ -49,6 +49,7 @@ class Lingo2Manager: | |||
| 49 | worldports: set[int] | 49 | worldports: set[int] |
| 50 | goaled: bool | 50 | goaled: bool |
| 51 | latches: set[int] | 51 | latches: set[int] |
| 52 | hinted_locations: set[int] | ||
| 52 | 53 | ||
| 53 | def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): | 54 | def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): |
| 54 | self.game_ctx = game_ctx | 55 | self.game_ctx = game_ctx |
| @@ -67,6 +68,7 @@ class Lingo2Manager: | |||
| 67 | self.worldports = set() | 68 | self.worldports = set() |
| 68 | self.goaled = False | 69 | self.goaled = False |
| 69 | self.latches = set() | 70 | self.latches = set() |
| 71 | self.hinted_locations = set() | ||
| 70 | 72 | ||
| 71 | def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: | 73 | def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: |
| 72 | ret: dict[str, int] = {} | 74 | ret: dict[str, int] = {} |
| @@ -99,6 +101,12 @@ class Lingo2Manager: | |||
| 99 | 101 | ||
| 100 | return ret | 102 | return ret |
| 101 | 103 | ||
| 104 | def update_hinted_locations(self, new_locs: set[int]) -> set[int]: | ||
| 105 | ret = new_locs.difference(self.hinted_locations) | ||
| 106 | self.hinted_locations.update(new_locs) | ||
| 107 | |||
| 108 | return ret | ||
| 109 | |||
| 102 | 110 | ||
| 103 | class Lingo2GameContext: | 111 | class Lingo2GameContext: |
| 104 | server: Endpoint | None | 112 | server: Endpoint | None |
| @@ -285,6 +293,17 @@ class Lingo2GameContext: | |||
| 285 | 293 | ||
| 286 | async_start(self.send_msgs([msg]), name="set ignored locations") | 294 | async_start(self.send_msgs([msg]), name="set ignored locations") |
| 287 | 295 | ||
| 296 | def send_update_hinted_locations(self, hinted_locations): | ||
| 297 | if self.server is None: | ||
| 298 | return | ||
| 299 | |||
| 300 | msg = { | ||
| 301 | "cmd": "UpdateHintedLocations", | ||
| 302 | "locations": hinted_locations, | ||
| 303 | } | ||
| 304 | |||
| 305 | async_start(self.send_msgs([msg]), name="update hinted locations") | ||
| 306 | |||
| 288 | async def send_msgs(self, msgs: list[Any]) -> None: | 307 | async def send_msgs(self, msgs: list[Any]) -> None: |
| 289 | """ `msgs` JSON serializable """ | 308 | """ `msgs` JSON serializable """ |
| 290 | if not self.server or not self.server.socket.open or self.server.socket.closed: | 309 | if not self.server or not self.server.socket.open or self.server.socket.closed: |
| @@ -299,6 +318,7 @@ class Lingo2ClientContext(CommonContext): | |||
| 299 | items_handling = 0b111 | 318 | items_handling = 0b111 |
| 300 | 319 | ||
| 301 | slot_data: dict[str, Any] | None | 320 | slot_data: dict[str, Any] | None |
| 321 | hints_data_storage_key: str | ||
| 302 | victory_data_storage_key: str | 322 | victory_data_storage_key: str |
| 303 | 323 | ||
| 304 | def __init__(self, server_address: str | None = None, password: str | None = None): | 324 | def __init__(self, server_address: str | None = None, password: str | None = None): |
| @@ -336,6 +356,7 @@ class Lingo2ClientContext(CommonContext): | |||
| 336 | self.manager.tracker.set_checked_locations(self.checked_locations) | 356 | self.manager.tracker.set_checked_locations(self.checked_locations) |
| 337 | self.manager.game_ctx.send_accessible_locations() | 357 | self.manager.game_ctx.send_accessible_locations() |
| 338 | 358 | ||
| 359 | self.hints_data_storage_key = f"_read_hints_{self.team}_{self.slot}" | ||
| 339 | self.victory_data_storage_key = f"_read_client_status_{self.team}_{self.slot}" | 360 | self.victory_data_storage_key = f"_read_client_status_{self.team}_{self.slot}" |
| 340 | 361 | ||
| 341 | self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2"), | 362 | self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2"), |
| @@ -463,6 +484,8 @@ class Lingo2ClientContext(CommonContext): | |||
| 463 | for k, v in args["keys"].items(): | 484 | for k, v in args["keys"].items(): |
| 464 | if k == self.victory_data_storage_key: | 485 | if k == self.victory_data_storage_key: |
| 465 | self.handle_status_update(v) | 486 | self.handle_status_update(v) |
| 487 | elif k == self.hints_data_storage_key: | ||
| 488 | self.update_hints() | ||
| 466 | elif cmd == "SetReply": | 489 | elif cmd == "SetReply": |
| 467 | if args["key"] == self.get_datastorage_key("keyboard1"): | 490 | if args["key"] == self.get_datastorage_key("keyboard1"): |
| 468 | self.handle_keyboard_update(1, args) | 491 | self.handle_keyboard_update(1, args) |
| @@ -482,6 +505,8 @@ class Lingo2ClientContext(CommonContext): | |||
| 482 | self.manager.game_ctx.send_update_latches(updates) | 505 | self.manager.game_ctx.send_update_latches(updates) |
| 483 | elif args["key"] == self.get_datastorage_key("ignored_locations"): | 506 | elif args["key"] == self.get_datastorage_key("ignored_locations"): |
| 484 | self.manager.game_ctx.send_ignored_locations(args["value"]) | 507 | self.manager.game_ctx.send_ignored_locations(args["value"]) |
| 508 | elif args["key"] == self.hints_data_storage_key: | ||
| 509 | self.update_hints() | ||
| 485 | 510 | ||
| 486 | def get_datastorage_key(self, name: str): | 511 | def get_datastorage_key(self, name: str): |
| 487 | return f"Lingo2_{self.slot}_{name}" | 512 | return f"Lingo2_{self.slot}_{name}" |
| @@ -599,6 +624,14 @@ class Lingo2ClientContext(CommonContext): | |||
| 599 | }] | 624 | }] |
| 600 | }]) | 625 | }]) |
| 601 | 626 | ||
| 627 | def update_hints(self): | ||
| 628 | hints = self.stored_data.get(self.hints_data_storage_key, []) | ||
| 629 | |||
| 630 | hinted_locations = set(hint["location"] for hint in hints if hint["finding_player"] == self.slot) | ||
| 631 | updates = self.manager.update_hinted_locations(hinted_locations) | ||
| 632 | if len(updates) > 0: | ||
| 633 | self.manager.game_ctx.send_update_hinted_locations(updates) | ||
| 634 | |||
| 602 | 635 | ||
| 603 | async def pipe_loop(manager: Lingo2Manager): | 636 | async def pipe_loop(manager: Lingo2Manager): |
| 604 | while not manager.client_ctx.exit_event.is_set(): | 637 | while not manager.client_ctx.exit_event.is_set(): |
