class_name IVInsertion extends Node3D ## IV insertion sequence. Presents an IV arm in front of the seated player, ## plays a short needle-approach + tape-press animation, then emits ## `iv_completed` which starts the treatment timer. signal iv_completed @export var auto_hide_on_complete: bool = true @export var needle_approach_time: float = 1.2 @export var tape_press_time: float = 0.6 @export var hold_time: float = 0.5 @onready var needle: Node3D = $Arm/Needle @onready var tape: Node3D = $Arm/Tape var _needle_start: Vector3 var _needle_end: Vector3 var _tape_hidden_scale: Vector3 = Vector3(1, 0.01, 1) var _tape_shown_scale: Vector3 = Vector3.ONE var _running: bool = false func _ready() -> void: visible = false if needle: _needle_start = needle.position # Needle ends pressed into the arm (move toward the arm along +Z/-Y a touch). _needle_end = needle.position + Vector3(0, -0.04, -0.08) if tape: tape.scale = _tape_hidden_scale ## Begin the IV insertion sequence. Safe to wire directly to `player_seated`. func begin_sequence() -> void: if _running: return _running = true visible = true if needle: needle.position = _needle_start if tape: tape.scale = _tape_hidden_scale var tween := create_tween() tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) # Needle approaches and presses in. if needle: tween.tween_property(needle, "position", _needle_end, needle_approach_time) # Tape presses on. if tape: tween.tween_property(tape, "scale", _tape_shown_scale, tape_press_time) # Brief hold, then finish. tween.tween_interval(hold_time) tween.tween_callback(_on_sequence_finished) func _on_sequence_finished() -> void: _running = false if auto_hide_on_complete: visible = false iv_completed.emit()