From f26cda07db5cb9046088a6f0c4710071c7bcfc69 Mon Sep 17 00:00:00 2001 From: Emily <35015090+EmilyV99@users.noreply.github.com> Date: Sun, 1 Dec 2024 09:16:36 -0500 Subject: [PATCH] Core: Hint Priority fixes (#4315) * Update hint priority docs * Update network protocol.md * Add error on `UpdateHint` trying to change to `HINT_FOUND` * Update network protocol.md * fix: precollected hint priority --- Main.py | 14 +++++++++----- MultiServer.py | 5 +++++ docs/network protocol.md | 17 +++++++++++------ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Main.py b/Main.py index 3a11181bd99f..d105bd4ad0e5 100644 --- a/Main.py +++ b/Main.py @@ -242,6 +242,7 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No def write_multidata(): import NetUtils + from NetUtils import HintStatus slot_data = {} client_versions = {} games = {} @@ -266,10 +267,10 @@ def write_multidata(): for slot in multiworld.player_ids: slot_data[slot] = multiworld.worlds[slot].fill_slot_data() - def precollect_hint(location): + def precollect_hint(location: Location, auto_status: HintStatus): entrance = er_hint_data.get(location.player, {}).get(location.address, "") hint = NetUtils.Hint(location.item.player, location.player, location.address, - location.item.code, False, entrance, location.item.flags, False) + location.item.code, False, entrance, location.item.flags, auto_status) precollected_hints[location.player].add(hint) if location.item.player not in multiworld.groups: precollected_hints[location.item.player].add(hint) @@ -288,13 +289,16 @@ def precollect_hint(location): f"{locations_data[location.player][location.address]}") locations_data[location.player][location.address] = \ location.item.code, location.item.player, location.item.flags + auto_status = HintStatus.HINT_AVOID if location.item.trap else HintStatus.HINT_PRIORITY if location.name in multiworld.worlds[location.player].options.start_location_hints: - precollect_hint(location) + if not location.item.trap: # Unspecified status for location hints, except traps + auto_status = HintStatus.HINT_UNSPECIFIED + precollect_hint(location, auto_status) elif location.item.name in multiworld.worlds[location.item.player].options.start_hints: - precollect_hint(location) + precollect_hint(location, auto_status) elif any([location.item.name in multiworld.worlds[player].options.start_hints for player in multiworld.groups.get(location.item.player, {}).get("players", [])]): - precollect_hint(location) + precollect_hint(location, auto_status) # embedded data package data_package = { diff --git a/MultiServer.py b/MultiServer.py index 80fcd32fd1e3..2561b0692a3c 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1929,6 +1929,11 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'UpdateHint: Invalid Status', "original_cmd": cmd}]) return + if status == HintStatus.HINT_FOUND: + await ctx.send_msgs(client, + [{'cmd': 'InvalidPacket', "type": "arguments", + "text": 'UpdateHint: Cannot manually update status to "HINT_FOUND"', "original_cmd": cmd}]) + return new_hint = new_hint.re_prioritize(ctx, status) if hint == new_hint: return diff --git a/docs/network protocol.md b/docs/network protocol.md index 1c5b2e002289..4331cf971007 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -351,7 +351,7 @@ Sent to the server to update the status of a Hint. The client must be the 'recei | ---- | ---- | ----- | | player | int | The ID of the player whose location is being hinted for. | | location | int | The ID of the location to update the hint for. If no hint exists for this location, the packet is ignored. | -| status | [HintStatus](#HintStatus) | Optional. If included, sets the status of the hint to this status. | +| status | [HintStatus](#HintStatus) | Optional. If included, sets the status of the hint to this status. Cannot set `HINT_FOUND`, or change the status from `HINT_FOUND`. | #### HintStatus An enumeration containing the possible hint states. @@ -359,12 +359,16 @@ An enumeration containing the possible hint states. ```python import enum class HintStatus(enum.IntEnum): - HINT_FOUND = 0 - HINT_UNSPECIFIED = 1 - HINT_NO_PRIORITY = 10 - HINT_AVOID = 20 - HINT_PRIORITY = 30 + HINT_FOUND = 0 # The location has been collected. Status cannot be changed once found. + HINT_UNSPECIFIED = 1 # The receiving player has not specified any status + HINT_NO_PRIORITY = 10 # The receiving player has specified that the item is unneeded + HINT_AVOID = 20 # The receiving player has specified that the item is detrimental + HINT_PRIORITY = 30 # The receiving player has specified that the item is needed ``` +- Hints for items with `ItemClassification.trap` default to `HINT_AVOID`. +- Hints created with `LocationScouts`, `!hint_location`, or similar (hinting a location) default to `HINT_UNSPECIFIED`. +- Hints created with `!hint` or similar (hinting an item for yourself) default to `HINT_PRIORITY`. +- Once a hint is collected, its' status is updated to `HINT_FOUND` automatically, and can no longer be changed. ### StatusUpdate Sent to the server to update on the sender's status. Examples include readiness or goal completion. (Example: defeated Ganon in A Link to the Past) @@ -668,6 +672,7 @@ class Hint(typing.NamedTuple): found: bool entrance: str = "" item_flags: int = 0 + status: HintStatus = HintStatus.HINT_UNSPECIFIED ``` ### Data Package Contents