diff --git a/asset_dev/hud_tools/toothbrush.xcf b/asset_dev/hud_tools/toothbrush.xcf new file mode 100644 index 0000000..290ed0c Binary files /dev/null and b/asset_dev/hud_tools/toothbrush.xcf differ diff --git a/assets/ui/hud/tools/toothbrush_idle.png b/assets/ui/hud/tools/toothbrush_idle.png new file mode 100644 index 0000000..e497834 --- /dev/null +++ b/assets/ui/hud/tools/toothbrush_idle.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:042bdb0aae76a3391db725e80b5fc3128644b8bcc6643d85181125cca8a6f4bf +size 3089 diff --git a/assets/ui/hud/tools/toothbrush_idle.png.import b/assets/ui/hud/tools/toothbrush_idle.png.import new file mode 100644 index 0000000..2c52fbc --- /dev/null +++ b/assets/ui/hud/tools/toothbrush_idle.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://6vc3ye0jnqy4" +path="res://.godot/imported/toothbrush_idle.png-f85a40b4d7c618db0b32cc32041af225.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/ui/hud/tools/toothbrush_idle.png" +dest_files=["res://.godot/imported/toothbrush_idle.png-f85a40b4d7c618db0b32cc32041af225.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/ui/hud/tools/toothbrush_used.png b/assets/ui/hud/tools/toothbrush_used.png new file mode 100644 index 0000000..b25dadd --- /dev/null +++ b/assets/ui/hud/tools/toothbrush_used.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b90fea0bc4bb98945c0e367a3eeb571e5a8a45a8f8067f1b3ee1c2aa628923a +size 3082 diff --git a/assets/ui/hud/tools/toothbrush_used.png.import b/assets/ui/hud/tools/toothbrush_used.png.import new file mode 100644 index 0000000..a5f6238 --- /dev/null +++ b/assets/ui/hud/tools/toothbrush_used.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djisqgfxhsrs2" +path="res://.godot/imported/toothbrush_used.png-b8a3a66b8a3234e351d72840d6cf781c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/ui/hud/tools/toothbrush_used.png" +dest_files=["res://.godot/imported/toothbrush_used.png-b8a3a66b8a3234e351d72840d6cf781c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/project.godot b/project.godot index 9c673ab..564d310 100644 --- a/project.godot +++ b/project.godot @@ -107,6 +107,11 @@ interact={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) ] } +switch_mode={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} select_point_spray={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":49,"key_label":0,"unicode":49,"location":0,"echo":false,"script":null) @@ -117,9 +122,9 @@ select_wide_spray={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":50,"key_label":0,"unicode":50,"location":0,"echo":false,"script":null) ] } -switch_mode={ +select_brush={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":51,"key_label":0,"unicode":51,"location":0,"echo":false,"script":null) ] } select_next_tool={ diff --git a/src/equipment/toothbrush/toothbrush.gd b/src/equipment/toothbrush/toothbrush.gd new file mode 100644 index 0000000..3220bf9 --- /dev/null +++ b/src/equipment/toothbrush/toothbrush.gd @@ -0,0 +1,36 @@ +extends Tool +# the wimpy toothbrush + +const PAINT_COLOR := Color(1, 0, 0, 0.3) +const BRUSH_SCALE := 0.2 + +@onready var raycast: RayCast3D = %Raycast + +@onready var texture_idle: TextureRect = %TextureIdle +@onready var texture_used: TextureRect = %TextureUsed +@onready var brush_animation: AnimationPlayer = %BrushAnimation + + +func _fire() -> void: + if raycast.is_colliding(): + brush_animation.play("brush") + var collider := raycast.get_collider() + if collider is GunkBody: + (collider as GunkBody).paint_dot( + raycast.get_collision_point(), + raycast.get_collision_normal(), + BRUSH_SCALE, + PAINT_COLOR + ) + if collider is GunkNode: + (collider as GunkNode).hit() + else: + brush_animation.stop() + + texture_idle.visible = false + texture_used.visible = true + + +func _idle() -> void: + texture_idle.visible = true + texture_used.visible = false diff --git a/src/equipment/toothbrush/toothbrush.gd.uid b/src/equipment/toothbrush/toothbrush.gd.uid new file mode 100644 index 0000000..a107a91 --- /dev/null +++ b/src/equipment/toothbrush/toothbrush.gd.uid @@ -0,0 +1 @@ +uid://d1e003a8jg3gm diff --git a/src/equipment/toothbrush/toothbrush.tscn b/src/equipment/toothbrush/toothbrush.tscn new file mode 100644 index 0000000..c2d2eff --- /dev/null +++ b/src/equipment/toothbrush/toothbrush.tscn @@ -0,0 +1,123 @@ +[gd_scene load_steps=8 format=3 uid="uid://qknkdy6aics1"] + +[ext_resource type="Script" uid="uid://d1e003a8jg3gm" path="res://src/equipment/toothbrush/toothbrush.gd" id="1_ivelq"] +[ext_resource type="Script" uid="uid://dj2x7x5qkbym1" path="res://src/ui/canvas_projector.gd" id="2_awr0g"] +[ext_resource type="Texture2D" uid="uid://6vc3ye0jnqy4" path="res://assets/ui/hud/tools/toothbrush_idle.png" id="3_sxute"] +[ext_resource type="Texture2D" uid="uid://djisqgfxhsrs2" path="res://assets/ui/hud/tools/toothbrush_used.png" id="4_atd0h"] + +[sub_resource type="Animation" id="Animation_atd0h"] +resource_name = "brush" +length = 0.6 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("HUDTool/NozzleMarker/HUDElement/Pivot/TextureUsed:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 0, 0), +"points": PackedFloat32Array(-40, -0.1, 0, 0.1, 0, 40, -0.1, 0, 0.1, 0, -40, -0.1, 0, 0.1, 0), +"times": PackedFloat32Array(0, 0.3, 0.6) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("HUDTool/NozzleMarker/HUDElement/Pivot/TextureUsed:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0), +"points": PackedFloat32Array(0, -0.2, 0, 0.3, 140, 0, -0.3, -140, 0.2, 0), +"times": PackedFloat32Array(0, 0.6) +} + +[sub_resource type="Animation" id="Animation_8x7qe"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("HUDTool/NozzleMarker/HUDElement/Pivot/TextureUsed:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("HUDTool/NozzleMarker/HUDElement/Pivot/TextureUsed:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.2, 0, 0.2, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_8x7qe"] +_data = { +&"RESET": SubResource("Animation_8x7qe"), +&"brush": SubResource("Animation_atd0h") +} + +[node name="Toothbrush" type="Node3D"] +script = ExtResource("1_ivelq") +metadata/_custom_type_script = "uid://caygiek3vmx1g" + +[node name="Raycast" type="RayCast3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 0.997564, -0.0697565, 0, 0.0697565, 0.997564, 0, 0, -0.15) +target_position = Vector3(0, 0, -1) +collision_mask = 4 + +[node name="HUDTool" type="Node3D" parent="."] +unique_name_in_owner = true + +[node name="NozzleMarker" type="Marker3D" parent="HUDTool"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.2) +script = ExtResource("2_awr0g") + +[node name="HUDElement" type="Control" parent="HUDTool/NozzleMarker"] +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Pivot" type="Control" parent="HUDTool/NozzleMarker/HUDElement"] +anchors_preset = 0 +offset_left = -200.0 +offset_top = -256.0 +offset_right = -200.0 +offset_bottom = -256.0 + +[node name="TextureIdle" type="TextureRect" parent="HUDTool/NozzleMarker/HUDElement/Pivot"] +unique_name_in_owner = true +texture_filter = 1 +layout_mode = 0 +offset_right = 64.0 +offset_bottom = 128.0 +scale = Vector2(5, 5) +texture = ExtResource("3_sxute") + +[node name="TextureUsed" type="TextureRect" parent="HUDTool/NozzleMarker/HUDElement/Pivot"] +unique_name_in_owner = true +visible = false +texture_filter = 1 +layout_mode = 0 +offset_right = 64.0 +offset_bottom = 128.0 +scale = Vector2(5, 5) +texture = ExtResource("4_atd0h") + +[node name="BrushAnimation" type="AnimationPlayer" parent="."] +unique_name_in_owner = true +libraries = { +&"": SubResource("AnimationLibrary_8x7qe") +} diff --git a/src/player/player.gd b/src/player/player.gd index 4c3661e..7be6cbf 100644 --- a/src/player/player.gd +++ b/src/player/player.gd @@ -25,6 +25,7 @@ var firing := false @onready var tool_mount: ToolMount = %ToolMount @onready var point_spray: PointSpray = %PointSpray @onready var wide_spray: WideSpray = %WideSpray +@onready var toothbrush: Tool = %Toothbrush func get_speed() -> float: @@ -65,6 +66,8 @@ func _physics_process(delta: float) -> void: tool_mount.set_active(point_spray) elif Input.is_action_just_pressed("select_wide_spray"): tool_mount.set_active(wide_spray) + elif Input.is_action_just_pressed("select_brush"): + tool_mount.set_active(toothbrush) # Tool use if Input.is_action_pressed("fire"): diff --git a/src/player/player.tscn b/src/player/player.tscn index 4f82069..21a2331 100644 --- a/src/player/player.tscn +++ b/src/player/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=8 format=3 uid="uid://bwe2jdmvinhqd"] +[gd_scene load_steps=9 format=3 uid="uid://bwe2jdmvinhqd"] [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"] @@ -6,6 +6,7 @@ [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://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"] +[ext_resource type="PackedScene" uid="uid://qknkdy6aics1" path="res://src/equipment/toothbrush/toothbrush.tscn" id="6_o822w"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_s7f0r"] height = 1.9 @@ -31,6 +32,10 @@ unique_name_in_owner = true unique_name_in_owner = true visible = false +[node name="Toothbrush" parent="CameraPivot/ToolMount" instance=ExtResource("6_o822w")] +unique_name_in_owner = true +visible = false + [node name="Camera3D" type="Camera3D" parent="CameraPivot"] current = true diff --git a/src/world/gunk_body/gunk_body.gd b/src/world/gunk_body/gunk_body.gd index 20fa6b9..5da46e2 100644 --- a/src/world/gunk_body/gunk_body.gd +++ b/src/world/gunk_body/gunk_body.gd @@ -195,18 +195,20 @@ func _get_px(point: Vector3, normal: Vector3) -> Vector2: ## Paint a dot on the gunk mask. -func paint_dot(point: Vector3, normal: Vector3, radius: float) -> void: +func paint_dot(point: Vector3, normal: Vector3, radius: float, color: Color = MASK_COLOR) -> void: var px := _get_px(point, normal) if px == Vector2.INF: return mask_control.queue_draw( - func() -> void: mask_control.draw_circle(px, radius, MASK_COLOR, true, -1, true) + func() -> void: mask_control.draw_circle(px, radius, color, true, -1, true) ) ## Paint a continuous line on the gunk mask if called on successive frames. -func paint_continuous(point: Vector3, normal: Vector3, width: float) -> void: +func paint_continuous( + point: Vector3, normal: Vector3, width: float, color: Color = MASK_COLOR +) -> void: var px := _get_px(point, normal) if _polyline_buffer and px.distance_to(_polyline_buffer[0]) <= CONTINUITY_LIMIT: _polyline_buffer.push_front(px) @@ -214,14 +216,14 @@ func paint_continuous(point: Vector3, normal: Vector3, width: float) -> void: _polyline_buffer.pop_back() var polyline := PackedVector2Array(_polyline_buffer) mask_control.queue_draw( - func() -> void: mask_control.draw_polyline(polyline, MASK_COLOR, width * 2, true) + func() -> void: mask_control.draw_polyline(polyline, color, width * 2, true) ) else: _polyline_buffer = [px] # Always paint a circle, to round out corners & cap ends mask_control.queue_draw( - func() -> void: mask_control.draw_circle(px, width, MASK_COLOR, true, -1, true) + func() -> void: mask_control.draw_circle(px, width, color, true, -1, true) ) _continued_paint_this_frame = true