From b413e5a9c5d5e5e6eff63a74fbb3ecdabf2cc66f Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sun, 2 Nov 2025 13:07:30 -0500 Subject: Prioritize hinted locations in tracker --- apworld/context.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'apworld/context.py') 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: worldports: set[int] goaled: bool latches: set[int] + hinted_locations: set[int] def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): self.game_ctx = game_ctx @@ -67,6 +68,7 @@ class Lingo2Manager: self.worldports = set() self.goaled = False self.latches = set() + self.hinted_locations = set() def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: ret: dict[str, int] = {} @@ -99,6 +101,12 @@ class Lingo2Manager: return ret + def update_hinted_locations(self, new_locs: set[int]) -> set[int]: + ret = new_locs.difference(self.hinted_locations) + self.hinted_locations.update(new_locs) + + return ret + class Lingo2GameContext: server: Endpoint | None @@ -285,6 +293,17 @@ class Lingo2GameContext: async_start(self.send_msgs([msg]), name="set ignored locations") + def send_update_hinted_locations(self, hinted_locations): + if self.server is None: + return + + msg = { + "cmd": "UpdateHintedLocations", + "locations": hinted_locations, + } + + async_start(self.send_msgs([msg]), name="update hinted locations") + async def send_msgs(self, msgs: list[Any]) -> None: """ `msgs` JSON serializable """ if not self.server or not self.server.socket.open or self.server.socket.closed: @@ -299,6 +318,7 @@ class Lingo2ClientContext(CommonContext): items_handling = 0b111 slot_data: dict[str, Any] | None + hints_data_storage_key: str victory_data_storage_key: str def __init__(self, server_address: str | None = None, password: str | None = None): @@ -336,6 +356,7 @@ class Lingo2ClientContext(CommonContext): self.manager.tracker.set_checked_locations(self.checked_locations) self.manager.game_ctx.send_accessible_locations() + self.hints_data_storage_key = f"_read_hints_{self.team}_{self.slot}" self.victory_data_storage_key = f"_read_client_status_{self.team}_{self.slot}" self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2"), @@ -463,6 +484,8 @@ class Lingo2ClientContext(CommonContext): for k, v in args["keys"].items(): if k == self.victory_data_storage_key: self.handle_status_update(v) + elif k == self.hints_data_storage_key: + self.update_hints() elif cmd == "SetReply": if args["key"] == self.get_datastorage_key("keyboard1"): self.handle_keyboard_update(1, args) @@ -482,6 +505,8 @@ class Lingo2ClientContext(CommonContext): self.manager.game_ctx.send_update_latches(updates) elif args["key"] == self.get_datastorage_key("ignored_locations"): self.manager.game_ctx.send_ignored_locations(args["value"]) + elif args["key"] == self.hints_data_storage_key: + self.update_hints() def get_datastorage_key(self, name: str): return f"Lingo2_{self.slot}_{name}" @@ -599,6 +624,14 @@ class Lingo2ClientContext(CommonContext): }] }]) + def update_hints(self): + hints = self.stored_data.get(self.hints_data_storage_key, []) + + hinted_locations = set(hint["location"] for hint in hints if hint["finding_player"] == self.slot) + updates = self.manager.update_hinted_locations(hinted_locations) + if len(updates) > 0: + self.manager.game_ctx.send_update_hinted_locations(updates) + async def pipe_loop(manager: Lingo2Manager): while not manager.client_ctx.exit_event.is_set(): -- cgit 1.4.1