diff --git a/src/effects/dust_spray.tscn b/src/effects/dust_spray.tscn index 27cbb42..648b06c 100644 --- a/src/effects/dust_spray.tscn +++ b/src/effects/dust_spray.tscn @@ -19,6 +19,7 @@ initial_velocity_max = 4.5 gravity = Vector3(0, 1.4, 0) damping_min = 5.955 damping_max = 5.955 +attractor_interaction_enabled = false scale_over_velocity_curve = SubResource("CurveTexture_hx0vd") [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4jho1"] diff --git a/src/effects/floating_dust.tscn b/src/effects/floating_dust.tscn index ded9e3d..1b48464 100644 --- a/src/effects/floating_dust.tscn +++ b/src/effects/floating_dust.tscn @@ -26,6 +26,7 @@ spread = 100.0 initial_velocity_min = 0.05 initial_velocity_max = 0.15 gravity = Vector3(0, 0, 0) +attractor_interaction_enabled = false scale_curve = SubResource("CurveTexture_w3xaq") color_ramp = SubResource("GradientTexture1D_w3xaq") turbulence_enabled = true diff --git a/src/effects/grunk_splatter/grunk_splatter.tscn b/src/effects/grunk_splatter/grunk_splatter.tscn index 37c64cc..c1d2368 100644 --- a/src/effects/grunk_splatter/grunk_splatter.tscn +++ b/src/effects/grunk_splatter/grunk_splatter.tscn @@ -33,6 +33,7 @@ direction = Vector3(0, 0, 0) spread = 180.0 initial_velocity_min = 8.0 initial_velocity_max = 8.0 +attractor_interaction_enabled = false scale_curve = SubResource("CurveTexture_t00bd") color_ramp = SubResource("GradientTexture1D_bt63p") @@ -77,6 +78,7 @@ direction = Vector3(0, 1, 0) spread = 0.0 initial_velocity_max = 0.05 gravity = Vector3(0, -0.3, 0) +attractor_interaction_enabled = false scale_curve = SubResource("CurveTexture_72g1e") color = Color(0.9, 0.983333, 1, 1) alpha_curve = SubResource("CurveTexture_2iem1") @@ -108,6 +110,7 @@ radius = 2.0 [node name="GrunkSplatter" type="GPUParticles3D"] sorting_offset = 9.0 +emitting = false amount = 64 lifetime = 0.3 one_shot = true @@ -119,6 +122,7 @@ script = ExtResource("2_grvat") [node name="SubSplatter" type="GPUParticles3D" parent="."] unique_name_in_owner = true sorting_offset = 9.0 +emitting = false amount = 4 lifetime = 0.3 one_shot = true diff --git a/src/effects/gunk_dust.tscn b/src/effects/gunk_dust.tscn index 7f52088..0aa8096 100644 --- a/src/effects/gunk_dust.tscn +++ b/src/effects/gunk_dust.tscn @@ -1,35 +1,52 @@ -[gd_scene load_steps=7 format=3 uid="uid://c3iv00vmdqxp0"] - -[ext_resource type="Texture2D" uid="uid://bwpyjfo1j4wis" path="res://assets/particles/dust/dust_3.png" id="1_hqns8"] +[gd_scene load_steps=8 format=3 uid="uid://c3iv00vmdqxp0"] [sub_resource type="Gradient" id="Gradient_o6g24"] -colors = PackedColorArray(0, 0.101961, 0.301961, 1, 0, 0.0313726, 0.101961, 1) +offsets = PackedFloat32Array(0, 0.376344) +colors = PackedColorArray(0, 0.101961, 0.301961, 1, 0, 0.015, 0.05, 1) [sub_resource type="GradientTexture1D" id="GradientTexture1D_mlqhf"] gradient = SubResource("Gradient_o6g24") -[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_ykxlg"] -direction = Vector3(0, 1, 0) -initial_velocity_min = 1.0 -initial_velocity_max = 1.0 -gravity = Vector3(0, -4, 0) -color_ramp = SubResource("GradientTexture1D_mlqhf") +[sub_resource type="Curve" id="Curve_pjcdo"] +_limits = [0.0, 12.0, 0.0, 1.0] +_data = [Vector2(0, 12), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 2 -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_v20ab"] -transparency = 1 +[sub_resource type="CurveTexture" id="CurveTexture_smx5b"] +curve = SubResource("Curve_pjcdo") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_ykxlg"] +angle_min = -184.7 +angle_max = 239.3 +direction = Vector3(0, 0, -1) +spread = 90.0 +initial_velocity_min = 2.0 +initial_velocity_max = 2.0 +angular_velocity_min = -360.0 +angular_velocity_max = 360.0 +gravity = Vector3(0, -1, 0) +damping_min = 1.0 +damping_max = 1.0 +damping_curve = SubResource("CurveTexture_smx5b") +scale_min = 0.8 +color_ramp = SubResource("GradientTexture1D_mlqhf") +hue_variation_min = -2.23517e-08 +hue_variation_max = 0.00999998 +collision_mode = 2 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_pjcdo"] vertex_color_use_as_albedo = true -albedo_texture = ExtResource("1_hqns8") -texture_filter = 2 billboard_mode = 3 +billboard_keep_scale = true particles_anim_h_frames = 1 particles_anim_v_frames = 1 particles_anim_loop = false -[sub_resource type="QuadMesh" id="QuadMesh_1ijv1"] -material = SubResource("StandardMaterial3D_v20ab") -size = Vector2(0.1, 0.1) +[sub_resource type="BoxMesh" id="BoxMesh_smx5b"] +material = SubResource("StandardMaterial3D_pjcdo") +size = Vector3(0.03, 0.03, 0.03) [node name="GunkDust" type="GPUParticles3D"] -lifetime = 0.4 +lifetime = 0.6 process_material = SubResource("ParticleProcessMaterial_ykxlg") -draw_pass_1 = SubResource("QuadMesh_1ijv1") +draw_pass_1 = SubResource("BoxMesh_smx5b") diff --git a/src/effects/laser_dust.tscn b/src/effects/laser_dust.tscn index 6257beb..dcfe21c 100644 --- a/src/effects/laser_dust.tscn +++ b/src/effects/laser_dust.tscn @@ -15,6 +15,7 @@ spread = 180.0 initial_velocity_min = 2.0 initial_velocity_max = 2.0 gravity = Vector3(0, 0, 0) +attractor_interaction_enabled = false scale_curve = SubResource("CurveTexture_7ktnl") [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fhbna"] diff --git a/src/equipment/point_spray/point_spray.tscn b/src/equipment/point_spray/point_spray.tscn index 4f39504..c5a9fd4 100644 --- a/src/equipment/point_spray/point_spray.tscn +++ b/src/equipment/point_spray/point_spray.tscn @@ -24,6 +24,7 @@ spread = 4.0 initial_velocity_min = 3.5 initial_velocity_max = 3.5 gravity = Vector3(0, 0, 0) +attractor_interaction_enabled = false [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_k4cg5"] vertex_color_use_as_albedo = true @@ -49,6 +50,7 @@ spread = 4.0 initial_velocity_min = 8.0 initial_velocity_max = 8.0 gravity = Vector3(0, 0, 0) +attractor_interaction_enabled = false [sub_resource type="CapsuleMesh" id="CapsuleMesh_k4cg5"] radius = 0.025 diff --git a/src/equipment/wide_spray/wide_spray.tscn b/src/equipment/wide_spray/wide_spray.tscn index aa6ea1b..a128e8d 100644 --- a/src/equipment/wide_spray/wide_spray.tscn +++ b/src/equipment/wide_spray/wide_spray.tscn @@ -27,6 +27,7 @@ flatness = 0.82 initial_velocity_min = 3.5 initial_velocity_max = 3.5 gravity = Vector3(0, 0, 0) +attractor_interaction_enabled = false [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6k0bn"] vertex_color_use_as_albedo = true @@ -52,6 +53,7 @@ flatness = 0.82 initial_velocity_min = 8.0 initial_velocity_max = 8.0 gravity = Vector3(0, 0, 0) +attractor_interaction_enabled = false [sub_resource type="BoxMesh" id="BoxMesh_fmqw2"] size = Vector3(0.05, 0.05, 0.3) diff --git a/src/player/player.tscn b/src/player/player.tscn index f764e4c..5695bc6 100644 --- a/src/player/player.tscn +++ b/src/player/player.tscn @@ -691,6 +691,15 @@ throw_force = 400.0 unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1) +[node name="GrunkDustAttractor" type="GPUParticlesAttractorSphere3D" parent="CameraPosition/CameraPivot"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.23, -0.285, -0.1) +strength = 30.0 +radius = 8.0 + +[node name="GrunkDustCullingPlane" type="GPUParticlesCollisionBox3D" parent="CameraPosition/CameraPivot"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.15) +size = Vector3(10, 10, 0.2) + [node name="StandingCollider" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0) shape = SubResource("CapsuleShape3D_s7f0r") diff --git a/src/player/tool_mount.gd b/src/player/tool_mount.gd index b37bee8..6d737b9 100644 --- a/src/player/tool_mount.gd +++ b/src/player/tool_mount.gd @@ -40,8 +40,9 @@ func set_active(tool: Tool, force: bool = false) -> void: return for c: Node3D in get_children(): - c.visible = false - # TODO unequip animation? + if c is Tool: + c.visible = false + # TODO unequip animation? _active = tool _active.visible = true _active.on_equip() @@ -56,7 +57,7 @@ func set_active_relative(delta: int) -> void: while true: var new_idx := wrapi(active_idx + delta, 0, get_child_count()) var tool := get_child(new_idx) as Tool - if tool.unlocked(): + if tool and tool.unlocked(): set_active(tool) return # If the next tool is not unlocked, try the one after diff --git a/src/world/gunkable/gunk_dust.gd b/src/world/gunkable/gunk_dust.gd new file mode 100644 index 0000000..f766d8d --- /dev/null +++ b/src/world/gunkable/gunk_dust.gd @@ -0,0 +1,25 @@ +extends GPUParticles3D + +@export var emit_scale := 0.1 + +var _last_clear_total := 0.0 +var _emitting_this_frame := false + + +func _on_gunkable_clear_total_updated(clear_total: float) -> void: + var delta := maxf(clear_total - _last_clear_total, 0) + + amount_ratio = clampf(delta * emit_scale, 0, 1) + if delta > 0: + _emitting_this_frame = true + + _last_clear_total = clear_total + + +func _on_gunkable_painted_at_point(point: Vector3, normal: Vector3) -> void: + look_at_from_position(point, point + normal, global_basis.y) + + +func _process(_delta: float) -> void: + emitting = _emitting_this_frame + _emitting_this_frame = false diff --git a/src/world/gunkable/gunk_dust.gd.uid b/src/world/gunkable/gunk_dust.gd.uid new file mode 100644 index 0000000..a40863e --- /dev/null +++ b/src/world/gunkable/gunk_dust.gd.uid @@ -0,0 +1 @@ +uid://b88k7m1mwrd0v diff --git a/src/world/gunkable/gunkable.gd b/src/world/gunkable/gunkable.gd index b0b2738..791c04e 100644 --- a/src/world/gunkable/gunkable.gd +++ b/src/world/gunkable/gunkable.gd @@ -4,6 +4,9 @@ class_name Gunkable extends Node ## Emitted from the main thread after the clear total is asynchronously updated. signal clear_total_updated(clear_total: float) +## Emitted from the main thread any time a point is painted +signal painted_at_point(point: Vector3, normal: Vector3) + const CONTINUITY_LIMIT := 32 const BUFFER_LIMIT := 3 const FACE_EPSILON := 0.01 @@ -212,6 +215,7 @@ func paint_dot(point: Vector3, normal: Vector3, radius: float, color: Color = MA mask_control.queue_draw( func() -> void: mask_control.draw_circle(px, radius, color, true, -1, true) ) + painted_at_point.emit(point, normal) ## Paint a continuous line on the gunk mask if called on successive frames. @@ -235,6 +239,7 @@ func paint_continuous( func() -> void: mask_control.draw_circle(px, width, color, true, -1, true) ) _continued_paint_this_frame = true + painted_at_point.emit(point, normal) ## Add a segment to the multiline to paint this frame. @@ -248,6 +253,7 @@ func add_to_multiline( _multiline_buffer.append(px_a) _multiline_buffer.append(px_b) _multiline_width = width + painted_at_point.emit(point_a, normal_a) func _process(_delta: float) -> void: diff --git a/src/world/gunkable/gunkable.tscn b/src/world/gunkable/gunkable.tscn index 3666ab1..7d5e881 100644 --- a/src/world/gunkable/gunkable.tscn +++ b/src/world/gunkable/gunkable.tscn @@ -1,7 +1,13 @@ -[gd_scene load_steps=3 format=3 uid="uid://cdi5sl60mw1po"] +[gd_scene load_steps=6 format=3 uid="uid://cdi5sl60mw1po"] [ext_resource type="Script" uid="uid://co0g2klfmor48" path="res://src/world/gunkable/gunkable.gd" id="1_47xoo"] [ext_resource type="Script" uid="uid://bom5qysgfvap1" path="res://src/world/gunkable/draw_controller.gd" id="2_srn13"] +[ext_resource type="PackedScene" uid="uid://c3iv00vmdqxp0" path="res://src/effects/gunk_dust.tscn" id="3_vad3y"] +[ext_resource type="Script" uid="uid://b88k7m1mwrd0v" path="res://src/world/gunkable/gunk_dust.gd" id="4_3mpo3"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_3mpo3"] +radius = 0.1 +height = 1.0 [node name="Gunkable" type="Node" groups=["Persistent"]] script = ExtResource("1_47xoo") @@ -42,6 +48,21 @@ grow_horizontal = 2 grow_vertical = 2 script = ExtResource("2_srn13") +[node name="GunkDust" parent="." instance=ExtResource("3_vad3y")] +top_level = true +emitting = false +amount = 64 +lifetime = 1.2 +script = ExtResource("4_3mpo3") +emit_scale = 0.08 + +[node name="DebugMesh" type="MeshInstance3D" parent="GunkDust"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0) +visible = false +mesh = SubResource("CapsuleMesh_3mpo3") + +[connection signal="clear_total_updated" from="." to="GunkDust" method="_on_gunkable_clear_total_updated"] +[connection signal="painted_at_point" from="." to="GunkDust" method="_on_gunkable_painted_at_point"] [connection signal="visibility_changed" from="MaskViewport/MaskClear" to="MaskViewport/MaskControl" method="_set_dirty"] [connection signal="visibility_changed" from="MaskViewport/MaskTexture" to="MaskViewport/MaskControl" method="_set_dirty"] [connection signal="draw" from="MaskViewport/MaskControl" to="." method="_on_mask_painted"]