@tool class_name GunkAlarm extends SignalNode ## Raises the grunk alert when triggered. const ALERT_DELTA := 1 const JITTER_SCALE_FACTOR := 0.15 const JITTER_INFLATION_FACTOR := 1.5 var _busy := false @onready var pulse_listener_timer: Timer = %PulseListenerTimer @onready var animation_player: AnimationPlayer = $FrameSkipper/Rumbler3D/AlarmMesh/AnimationPlayer @onready var trigger_animation: AnimationPlayer = %TriggerAnimation @onready var pulse_animation: AnimationPlayer = %PulseAnimation @onready var bud: MeshInstance3D = $FrameSkipper/Rumbler3D/AlarmMesh/Armature/Skeleton3D/Bud @onready var alarm_sfx: AudioStreamPlayer3D = %AlarmSFX ## Trigger this alarm. ## ## Will not trigger if this alarm is busy (e.g. on cooldown) func trigger() -> void: if not _busy: _busy = true Game.manager.raise_alert(ALERT_DELTA) animation_player.play("trigger") trigger_animation.play("trigger") alarm_sfx.play() ## Pulse this alarm, resetting the pulse countdown until triggering. ## ## Note that alarms will not begin the pulse countdown until receiving the first pulse. ## On networks without a heart, the pulse timeout will be completely ignored. func pulse() -> void: pulse_animation.seek(0) pulse_animation.play("pulse") func _process(delta: float) -> void: if Engine.is_editor_hint(): return super._process(delta) # TODO actual model & animation var shader: ShaderMaterial = bud.get_surface_override_material(0) var damage := pct_damage() shader.set_shader_parameter("jitter_time_scale", pow(damage * JITTER_SCALE_FACTOR, 1.2)) shader.set_shader_parameter("vertex_inflation", pow(damage * JITTER_INFLATION_FACTOR, 3)) # TODO pulse animation func _on_animation_finished(anim_name: StringName) -> void: if anim_name == "trigger": _busy = false