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