extends Node3D @export var _splash_small_sound: AudioStreamPlayer3D @export var _splash_small_quiet_sound: AudioStreamPlayer3D @export var _model: Node3D @export var _splash_particles: GPUParticles3D @export var body: RigidBody3D ## no longer exists and shouldn't be considered, but not ready to be freed yet @export var is_dead := false var _in_splash_range := {} ## something to ignore var sender_body: PhysicsBody3D func _ready() -> void: body.process_mode = Node.PROCESS_MODE_DISABLED func _process(delta: float) -> void: if not is_multiplayer_authority(): return global_position = body.global_position @rpc("authority", "call_local", "reliable") func _disable_body() -> void: # not using synchronizer for this because it ends up enabling processing # on other clients (func() -> void: body.process_mode = Node.PROCESS_MODE_DISABLED).call_deferred() func _on_body_entered(p_body: Node3D) -> void: if p_body == sender_body: return if p_body.is_in_group("voids"): queue_free() return for area: Area3D in _in_splash_range: area.get_parent_node_3d().water.rpc_id(1) _splash_small_sound.play() _splash_small_quiet_sound.play() _splash_particles.emitting = true is_dead = true _model.hide() _disable_body.rpc() await _splash_small_sound.finished if _splash_small_quiet_sound.playing: await _splash_small_quiet_sound.finished queue_free() func _on_splash_area_entered(area: Area3D) -> void: _in_splash_range[area] = true func _on_splash_area_exited(area: Area3D) -> void: _in_splash_range.erase(area) @rpc("authority", "call_local", "reliable") func set_global_pos(new: Vector3) -> void: global_position = new body.global_position = new body.reset_physics_interpolation()