diff --git a/src/equipment/point_spray/point_spray.tscn b/src/equipment/point_spray/point_spray.tscn index c0fbdb0..e30787b 100644 --- a/src/equipment/point_spray/point_spray.tscn +++ b/src/equipment/point_spray/point_spray.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=10 format=3 uid="uid://cc102xko0u6yj"] +[gd_scene load_steps=12 format=3 uid="uid://cc102xko0u6yj"] [ext_resource type="Script" uid="uid://dngia2ldbccv7" path="res://src/equipment/point_spray/point_spray.gd" id="1_2yl2v"] [ext_resource type="Material" uid="uid://c00gndxoepuqh" path="res://assets/materials/laser_spray.tres" id="2_0pfy3"] [ext_resource type="Texture2D" uid="uid://bn0gcsy37ahto" path="res://assets/ui/hud/reticle_large.png" id="2_qcl8j"] [ext_resource type="PackedScene" uid="uid://b8vradbaw61ga" path="res://src/equipment/laser_cast/laser_cast.tscn" id="3_qmoff"] +[ext_resource type="Script" uid="uid://b274q7uvn0cvp" path="res://src/ui/rumbler_3d.gd" id="5_k4cg5"] [sub_resource type="CylinderMesh" id="CylinderMesh_j5thb"] material = ExtResource("2_0pfy3") @@ -19,7 +20,7 @@ initial_velocity_min = 3.5 initial_velocity_max = 3.5 gravity = Vector3(0, 0, 0) -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6k0bn"] +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_k4cg5"] vertex_color_use_as_albedo = true albedo_color = Color(0, 1, 0.301961, 0.392157) emission_enabled = true @@ -34,7 +35,7 @@ particles_anim_v_frames = 1 particles_anim_loop = false [sub_resource type="QuadMesh" id="QuadMesh_fgb4j"] -material = SubResource("StandardMaterial3D_6k0bn") +material = SubResource("StandardMaterial3D_k4cg5") size = Vector2(0.005, 0.005) [sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_vwgy4"] @@ -44,38 +45,59 @@ initial_velocity_min = 8.0 initial_velocity_max = 8.0 gravity = Vector3(0, 0, 0) +[sub_resource type="CapsuleMesh" id="CapsuleMesh_k4cg5"] +radius = 0.025 +height = 0.3 + [node name="PointSpray" type="Node3D"] script = ExtResource("1_2yl2v") -[node name="LaserCast" parent="." node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_qmoff")] -unique_name_in_owner = true -parent_tool = NodePath("..") +[node name="Muzzle" type="Marker3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.997564, -0.0697565, 0, 0.0697565, 0.997564, 0, 0, -0.15) -[node name="SprayEffect" type="MeshInstance3D" parent="."] +[node name="LaserCast" parent="Muzzle" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_qmoff")] unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, -1) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) +parent_tool = NodePath("../..") + +[node name="SprayEffect" type="MeshInstance3D" parent="Muzzle"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, -4.47035e-08, -1, 0, 1, -4.47035e-08, 0, 0, -1) layers = 2 sorting_offset = 1.0 mesh = SubResource("CylinderMesh_j5thb") +skeleton = NodePath("../..") -[node name="BeamParticles1" type="GPUParticles3D" parent="."] +[node name="BeamParticles1" type="GPUParticles3D" parent="Muzzle"] unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) amount = 16 lifetime = 0.5 local_coords = true process_material = SubResource("ParticleProcessMaterial_nc5qr") draw_pass_1 = SubResource("QuadMesh_fgb4j") -[node name="BeamParticles2" type="GPUParticles3D" parent="."] +[node name="BeamParticles2" type="GPUParticles3D" parent="Muzzle"] unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) lifetime = 0.2 local_coords = true process_material = SubResource("ParticleProcessMaterial_vwgy4") draw_pass_1 = SubResource("QuadMesh_fgb4j") -[node name="Decal" type="Decal" parent="."] +[node name="Decal" type="Decal" parent="Muzzle"] transform = Transform3D(1, 0, 0, 0, -4.47035e-08, -1, 0, 1, -4.47035e-08, 0, 0, -1) size = Vector3(0.2, 2, 0.2) texture_albedo = ExtResource("2_qcl8j") texture_emission = ExtResource("2_qcl8j") cull_mask = 1048573 + +[node name="Rumbler" type="Node3D" parent="."] +unique_name_in_owner = true +script = ExtResource("5_k4cg5") + +[node name="SprayNozzle" type="MeshInstance3D" parent="Rumbler"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0) +layers = 2 +mesh = SubResource("CapsuleMesh_k4cg5") +skeleton = NodePath("../../..") diff --git a/src/equipment/spray.gd b/src/equipment/spray.gd index 49de01e..1ef74ab 100644 --- a/src/equipment/spray.gd +++ b/src/equipment/spray.gd @@ -1,9 +1,13 @@ class_name Spray extends Tool ## Base class for spraygun tools +const RUMBLE_INTENSITY = 0.002 +const RUMBLE_DROPOFF = 0.8 + @onready var spray_effect: MeshInstance3D = %SprayEffect @onready var beam_particles_1: GPUParticles3D = %BeamParticles1 @onready var beam_particles_2: GPUParticles3D = %BeamParticles2 +@onready var rumbler: Rumbler3D = %Rumbler func _spray() -> void: @@ -16,9 +20,11 @@ func _fire() -> void: spray_effect.visible = true beam_particles_1.emitting = true beam_particles_2.emitting = true + rumbler.intensity = RUMBLE_INTENSITY func _idle() -> void: spray_effect.visible = false beam_particles_1.emitting = false beam_particles_2.emitting = false + rumbler.intensity *= RUMBLE_DROPOFF diff --git a/src/equipment/wide_spray/wide_spray.tscn b/src/equipment/wide_spray/wide_spray.tscn index 30f001f..b16c841 100644 --- a/src/equipment/wide_spray/wide_spray.tscn +++ b/src/equipment/wide_spray/wide_spray.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=15 format=3 uid="uid://d2hnxr5l6w2x4"] +[gd_scene load_steps=17 format=3 uid="uid://d2hnxr5l6w2x4"] [ext_resource type="Script" uid="uid://dv40fyim2g2fa" path="res://src/equipment/wide_spray/wide_spray.gd" id="1_ggkto"] [ext_resource type="Material" uid="uid://c00gndxoepuqh" path="res://assets/materials/laser_spray.tres" id="2_26efp"] @@ -6,6 +6,7 @@ [ext_resource type="PackedScene" uid="uid://b8vradbaw61ga" path="res://src/equipment/laser_cast/laser_cast.tscn" id="3_xahet"] [ext_resource type="Texture2D" uid="uid://carrggw6kp14w" path="res://assets/ui/hud/reticle_left.png" id="4_rotxf"] [ext_resource type="Texture2D" uid="uid://wp03nuwt8hp5" path="res://assets/ui/hud/reticle_right.png" id="5_xo3vu"] +[ext_resource type="Script" uid="uid://b274q7uvn0cvp" path="res://src/ui/rumbler_3d.gd" id="7_ku0nd"] [sub_resource type="CylinderMesh" id="CylinderMesh_48buk"] material = ExtResource("2_26efp") @@ -46,29 +47,12 @@ initial_velocity_min = 8.0 initial_velocity_max = 8.0 gravity = Vector3(0, 0, 0) -[sub_resource type="Animation" id="Animation_ay2b7"] -resource_name = "rotate" -length = 0.1 -step = 0.0333 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Pivot:rotation") -tracks/0/interp = 2 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.1), -"transitions": PackedFloat32Array(1.618, 1), -"update": 0, -"values": [Vector3(0, 0, 0), Vector3(0, 0, 1.5708)] -} - [sub_resource type="Animation" id="Animation_ku0nd"] length = 0.001 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("Pivot:rotation") +tracks/0/path = NodePath("Muzzle/Pivot:rotation") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -78,82 +62,106 @@ tracks/0/keys = { "values": [Vector3(0, 0, 0)] } +[sub_resource type="Animation" id="Animation_ay2b7"] +resource_name = "rotate" +length = 0.1 +step = 0.0333 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Muzzle/Pivot:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1.618, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 0, 1.5708)] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_fmqw2"] _data = { &"RESET": SubResource("Animation_ku0nd"), &"rotate": SubResource("Animation_ay2b7") } +[sub_resource type="BoxMesh" id="BoxMesh_fmqw2"] +size = Vector3(0.05, 0.05, 0.3) + [node name="WideSpray" type="Node3D"] script = ExtResource("1_ggkto") -[node name="Pivot" type="Node3D" parent="."] +[node name="Muzzle" type="Marker3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.997564, -0.0697565, 0, 0.0697565, 0.997564, 0, 0, -0.15) -[node name="SprayCasts" type="Node3D" parent="Pivot"] +[node name="Pivot" type="Node3D" parent="Muzzle"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0) + +[node name="SprayCasts" type="Node3D" parent="Muzzle/Pivot"] unique_name_in_owner = true -[node name="LaserCast" parent="Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +[node name="LaserCast" parent="Muzzle/Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(-0.5, 0, -2) -parent_tool = NodePath("../../..") +parent_tool = NodePath("../../../..") -[node name="LaserCast2" parent="Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +[node name="LaserCast2" parent="Muzzle/Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(-0.333, 0, -2) -parent_tool = NodePath("../../..") +parent_tool = NodePath("../../../..") -[node name="LaserCast3" parent="Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +[node name="LaserCast3" parent="Muzzle/Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(-0.167, 0, -2) -parent_tool = NodePath("../../..") +parent_tool = NodePath("../../../..") -[node name="LaserCast4" parent="Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] -parent_tool = NodePath("../../..") +[node name="LaserCast4" parent="Muzzle/Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +parent_tool = NodePath("../../../..") -[node name="LaserCast5" parent="Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +[node name="LaserCast5" parent="Muzzle/Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(0.167, 0, -2) -parent_tool = NodePath("../../..") +parent_tool = NodePath("../../../..") -[node name="LaserCast6" parent="Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +[node name="LaserCast6" parent="Muzzle/Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(0.333, 0, -2) -parent_tool = NodePath("../../..") +parent_tool = NodePath("../../../..") -[node name="LaserCast7" parent="Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] +[node name="LaserCast7" parent="Muzzle/Pivot/SprayCasts" node_paths=PackedStringArray("parent_tool") instance=ExtResource("3_xahet")] target_position = Vector3(0.5, 0, -2) -parent_tool = NodePath("../../..") +parent_tool = NodePath("../../../..") -[node name="SprayEffect" type="MeshInstance3D" parent="Pivot"] +[node name="SprayEffect" type="MeshInstance3D" parent="Muzzle/Pivot"] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -0.15, 0, 1, -6.55671e-09, 0, 0, -1) layers = 2 sorting_offset = 1.0 mesh = SubResource("CylinderMesh_48buk") -skeleton = NodePath("../..") +skeleton = NodePath("../../..") -[node name="ReticleDecals" type="Node3D" parent="Pivot"] +[node name="ReticleDecals" type="Node3D" parent="Muzzle/Pivot"] -[node name="CrosshairDecal" type="Decal" parent="Pivot/ReticleDecals"] +[node name="CrosshairDecal" type="Decal" parent="Muzzle/Pivot/ReticleDecals"] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, -1) size = Vector3(0.2, 2, 0.2) texture_albedo = ExtResource("3_78jy6") cull_mask = 1048573 -[node name="LeftPivot" type="Node3D" parent="Pivot/ReticleDecals"] +[node name="LeftPivot" type="Node3D" parent="Muzzle/Pivot/ReticleDecals"] transform = Transform3D(0.970296, 0, 0.241922, 0, 1, 0, -0.241922, 0, 0.970296, 0, 0, 0) -[node name="LeftDecal" type="Decal" parent="Pivot/ReticleDecals/LeftPivot"] +[node name="LeftDecal" type="Decal" parent="Muzzle/Pivot/ReticleDecals/LeftPivot"] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, -1) size = Vector3(0.2, 2, 0.2) texture_albedo = ExtResource("4_rotxf") cull_mask = 1048573 -[node name="RightPivot" type="Node3D" parent="Pivot/ReticleDecals"] +[node name="RightPivot" type="Node3D" parent="Muzzle/Pivot/ReticleDecals"] transform = Transform3D(0.970296, 0, -0.241922, 0, 1, 0, 0.241922, 0, 0.970296, 0, 0, 0) -[node name="RightDecal" type="Decal" parent="Pivot/ReticleDecals/RightPivot"] +[node name="RightDecal" type="Decal" parent="Muzzle/Pivot/ReticleDecals/RightPivot"] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, -1) size = Vector3(0.2, 2, 0.2) texture_albedo = ExtResource("5_xo3vu") cull_mask = 1048573 -[node name="BeamParticles1" type="GPUParticles3D" parent="Pivot"] +[node name="BeamParticles1" type="GPUParticles3D" parent="Muzzle/Pivot"] unique_name_in_owner = true amount = 16 lifetime = 0.5 @@ -161,7 +169,7 @@ local_coords = true process_material = SubResource("ParticleProcessMaterial_pr4yq") draw_pass_1 = SubResource("QuadMesh_trcry") -[node name="BeamParticles2" type="GPUParticles3D" parent="Pivot"] +[node name="BeamParticles2" type="GPUParticles3D" parent="Muzzle/Pivot"] unique_name_in_owner = true lifetime = 0.2 local_coords = true @@ -174,4 +182,13 @@ libraries = { &"": SubResource("AnimationLibrary_fmqw2") } +[node name="Rumbler" type="Node3D" parent="."] +unique_name_in_owner = true +script = ExtResource("7_ku0nd") + +[node name="SprayNozzle" type="MeshInstance3D" parent="Rumbler"] +layers = 2 +mesh = SubResource("BoxMesh_fmqw2") +skeleton = NodePath("../../..") + [connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_finished"] diff --git a/src/player/player.gd b/src/player/player.gd index ca99138..4c3661e 100644 --- a/src/player/player.gd +++ b/src/player/player.gd @@ -19,11 +19,13 @@ var firing := false @onready var player_hud: PlayerHUD = %PlayerHUD @onready var camera_pivot: CameraController = %CameraPivot -@onready var tool_muzzle: Marker3D = %ToolMuzzle -@onready var tool_rumbler: Rumbler3D = %ToolRumbler @onready var interact_ray: RayCast3D = %InteractRay +@onready var tool_mount: ToolMount = %ToolMount +@onready var point_spray: PointSpray = %PointSpray +@onready var wide_spray: WideSpray = %WideSpray + func get_speed() -> float: if is_on_floor(): @@ -41,8 +43,8 @@ func get_friction() -> float: return AIR_FRICTION -func get_tool() -> Spray: - return tool_muzzle.get_child(0) +func get_tool() -> Tool: + return tool_mount.get_active() func _physics_process(delta: float) -> void: @@ -50,17 +52,27 @@ func _physics_process(delta: float) -> void: var interactive: Interactive = interact_ray.get_collider() as Interactive player_hud.select_interactive(interactive) + # World interaction if interactive and Input.is_action_just_pressed("interact"): interactive.activate() + # Tool selection + if Input.is_action_just_pressed("select_next_tool"): + tool_mount.set_active_relative(1) + elif Input.is_action_just_pressed("select_prev_tool"): + tool_mount.set_active_relative(-1) + elif Input.is_action_just_pressed("select_point_spray"): + tool_mount.set_active(point_spray) + elif Input.is_action_just_pressed("select_wide_spray"): + tool_mount.set_active(wide_spray) + + # Tool use if Input.is_action_pressed("fire"): get_tool().fire() firing = true - tool_rumbler.intensity = 0.002 else: get_tool().idle() firing = false - tool_rumbler.intensity *= 0.8 if Input.is_action_just_pressed("switch_mode"): get_tool().switch_mode() diff --git a/src/player/player.tscn b/src/player/player.tscn index e208a98..4f82069 100644 --- a/src/player/player.tscn +++ b/src/player/player.tscn @@ -2,13 +2,11 @@ [ext_resource type="Script" uid="uid://buwh0g1ga2aka" path="res://src/player/player.gd" id="1_npueo"] [ext_resource type="Script" uid="uid://cx1yt0drthpw3" path="res://src/player/camera_controller.gd" id="2_veeqv"] +[ext_resource type="PackedScene" uid="uid://cc102xko0u6yj" path="res://src/equipment/point_spray/point_spray.tscn" id="3_6wgkm"] [ext_resource type="PackedScene" uid="uid://d2hnxr5l6w2x4" path="res://src/equipment/wide_spray/wide_spray.tscn" id="3_ibq07"] -[ext_resource type="Script" uid="uid://b274q7uvn0cvp" path="res://src/ui/rumbler_3d.gd" id="5_ipd7g"] +[ext_resource type="Script" uid="uid://cwy3akimaeib" path="res://src/player/tool_mount.gd" id="3_jiejy"] [ext_resource type="PackedScene" uid="uid://dq1x21tq06dud" path="res://src/ui/hud/player_hud.tscn" id="5_jvafu"] -[sub_resource type="BoxMesh" id="BoxMesh_ua7a2"] -size = Vector3(0.05, 0.05, 0.3) - [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_s7f0r"] height = 1.9 @@ -20,23 +18,18 @@ unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) script = ExtResource("2_veeqv") -[node name="ToolMount" type="Node3D" parent="CameraPivot"] +[node name="ToolMount" type="Node3D" parent="CameraPivot" node_paths=PackedStringArray("initial_tool")] +unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, -0.1, -0.1) +script = ExtResource("3_jiejy") +initial_tool = NodePath("PointSpray") -[node name="ToolMuzzle" type="Marker3D" parent="CameraPivot/ToolMount"] +[node name="PointSpray" parent="CameraPivot/ToolMount" instance=ExtResource("3_6wgkm")] unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, 0.997564, -0.0697565, 0, 0.0697565, 0.997564, 0, 0, -0.15) -[node name="WideSpray" parent="CameraPivot/ToolMount/ToolMuzzle" instance=ExtResource("3_ibq07")] - -[node name="ToolRumbler" type="Node3D" parent="CameraPivot/ToolMount"] +[node name="WideSpray" parent="CameraPivot/ToolMount" instance=ExtResource("3_ibq07")] unique_name_in_owner = true -script = ExtResource("5_ipd7g") - -[node name="SprayNozzle" type="MeshInstance3D" parent="CameraPivot/ToolMount/ToolRumbler"] -layers = 2 -mesh = SubResource("BoxMesh_ua7a2") -skeleton = NodePath("../../..") +visible = false [node name="Camera3D" type="Camera3D" parent="CameraPivot"] current = true diff --git a/src/player/tool_mount.gd b/src/player/tool_mount.gd new file mode 100644 index 0000000..ffe48c9 --- /dev/null +++ b/src/player/tool_mount.gd @@ -0,0 +1,36 @@ +class_name ToolMount extends Node3D +## Access controller for the player's active & available tools + +@export var initial_tool: Tool + +var _active: Tool + + +func _ready() -> void: + set_active(initial_tool) + + +## Returns the currently-active tool. +func get_active() -> Tool: + return _active + + +## Sets the given tool as active. +## +## The tool should be a child of this mount. +func set_active(tool: Tool) -> void: + for c: Node3D in get_children(): + c.visible = false + # TODO unequip animation? + _active = tool + _active.visible = true + # TODO equip animation? + + +## Sets the active tool by index relative to the currently-active tool. +## +## Use this for "select next/prev tool" functions. +func set_active_relative(delta: int) -> void: + var active_idx := _active.get_index() + var new_idx := wrapi(active_idx + delta, 0, get_child_count()) + set_active(get_child(new_idx) as Tool) diff --git a/src/player/tool_mount.gd.uid b/src/player/tool_mount.gd.uid new file mode 100644 index 0000000..a0296da --- /dev/null +++ b/src/player/tool_mount.gd.uid @@ -0,0 +1 @@ +uid://cwy3akimaeib