neon-sprawl/client/scripts/npc_runtime_hud_state.gd

46 lines
1.6 KiB
GDScript

extends RefCounted
## NEO-97: local windup display mirror between [code]npc-runtime-snapshot[/code] polls.
## Uses receive tick + server [code]windupRemainingSeconds[/code] — no client windup scheduling.
var _windup_at_receive: Dictionary = {}
var _ticks_msec_at_receive: Dictionary = {}
func apply_snapshot(snapshot: Dictionary) -> void:
_windup_at_receive.clear()
_ticks_msec_at_receive.clear()
var now_msec: int = Time.get_ticks_msec()
var instances: Variant = snapshot.get("npcInstances", null)
if instances == null or not instances is Array:
return
for row_variant in instances as Array:
if not row_variant is Dictionary:
continue
var row: Dictionary = row_variant
var instance_id: String = str(row.get("npcInstanceId", "")).strip_edges()
if instance_id.is_empty():
continue
var telegraph: Variant = row.get("activeTelegraph", null)
if telegraph == null or not telegraph is Dictionary:
continue
var remaining: float = float((telegraph as Dictionary).get("windupRemainingSeconds", 0.0))
if remaining <= 0.0:
continue
_windup_at_receive[instance_id] = remaining
_ticks_msec_at_receive[instance_id] = now_msec
func display_windup_remaining(instance_id: String) -> float:
var id: String = instance_id.strip_edges()
if id.is_empty() or not _windup_at_receive.has(id):
return 0.0
var anchor: float = float(_windup_at_receive[id])
var start_msec: int = int(_ticks_msec_at_receive.get(id, 0))
var elapsed: float = (Time.get_ticks_msec() - start_msec) * 0.001
return maxf(0.0, anchor - elapsed)
func has_active_windup(instance_id: String) -> bool:
return display_windup_remaining(instance_id) > 0.0