feat(client): add interaction prompt system (#405)
Server-driven interaction prompt that displays "E - Talk" when near an interactable NPC. Decodes v4 nearby_interactions from snapshot, stores in GameState, renders via InteractionPrompt UI with fade animation. Extensible interface (get_interaction_target/get_selected_verb) for future radial verb menu (v0.2). - Protocol: decode nearby_interactions array with nested VerbOption structs, entity relationship/observation fields, tick_rate in GameTime - GameState: store/clear nearby_interactions per snapshot - SimBridge: test mode generates v4 format with structured verbs - InteractionPrompt: PanelContainer with fade in/out, polls GameState - Tests: 19 new test cases covering protocol, state, sim bridge, UI, encoding - Fixture assertions updated for v4 protocol version Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,9 @@ var visibility_sectors: Dictionary = {} # Vector2i -> "Forward"/"Peripheral"
|
||||
# refined when the server assigns explicit player entity IDs).
|
||||
var player_entity_id: int = 1
|
||||
|
||||
# v4 fields (#404/#405)
|
||||
var nearby_interactions: Array = [] # [{entity_id, entity_type, distance, verbs: [{kind, label, priority, available}]}]
|
||||
|
||||
func apply_snapshot(snapshot: Dictionary) -> void:
|
||||
current_snapshot = snapshot
|
||||
|
||||
@@ -54,6 +57,12 @@ func apply_snapshot(snapshot: Dictionary) -> void:
|
||||
if snapshot.has("player_facing") and snapshot.player_facing is String:
|
||||
player_facing = snapshot.player_facing
|
||||
|
||||
# v4: nearby_interactions (#404/#405)
|
||||
if snapshot.has("nearby_interactions") and snapshot.nearby_interactions is Array:
|
||||
nearby_interactions = snapshot.nearby_interactions
|
||||
else:
|
||||
nearby_interactions = []
|
||||
|
||||
# v2: visible_tiles with visibility sectors
|
||||
# Derives visible_positions when not explicitly provided (real server mode)
|
||||
if snapshot.has("visible_tiles") and snapshot.visible_tiles is Array and snapshot.visible_tiles.size() > 0:
|
||||
|
||||
@@ -294,20 +294,34 @@ func _test_snapshot() -> Dictionary:
|
||||
"visibility": sector,
|
||||
})
|
||||
|
||||
# v4: nearby_interactions when NPC is nearby and visible (#404/#405)
|
||||
var nearby: Array = []
|
||||
if npc_dist <= 2 and _test_has_los(Vector2i(px, py), npc_pos):
|
||||
nearby.append({
|
||||
"entity_id": 2,
|
||||
"entity_type": "Npc",
|
||||
"distance": npc_dist,
|
||||
"verbs": [
|
||||
{"kind": "Talk", "label": "Talk", "priority": 0, "available": true},
|
||||
{"kind": "ExamineNpc", "label": "Examine", "priority": 1, "available": true},
|
||||
],
|
||||
})
|
||||
|
||||
return {
|
||||
"tick": _test_tick,
|
||||
"version": 2,
|
||||
"version": 4,
|
||||
"game_time": {
|
||||
"day": 0,
|
||||
"time_of_day": _test_tick * 10,
|
||||
"day_phase": "Morning",
|
||||
"paused": false,
|
||||
"tick_rate": "Full",
|
||||
},
|
||||
"player_facing": _test_facing,
|
||||
"entities": entities,
|
||||
"tiles": _test_tiles(),
|
||||
"visible_tiles": _test_visible_tiles(),
|
||||
"visible_positions": _test_visible_positions(),
|
||||
"nearby_interactions": nearby,
|
||||
}
|
||||
|
||||
# Generate a small test room: 8x6 room with walls, a door, and floor
|
||||
|
||||
Reference in New Issue
Block a user