Add interactive mushroom pickup and highlight mechanics with pop sound
Some checks failed
Deploy Promiscuity Auth API / deploy (push) Successful in 1m1s
Deploy Promiscuity Character API / deploy (push) Has been cancelled
Deploy Promiscuity Crafting API / deploy (push) Has been cancelled
Deploy Promiscuity Inventory API / deploy (push) Has been cancelled
Deploy Promiscuity Locations API / deploy (push) Has been cancelled
Deploy Promiscuity Mail API / deploy (push) Has been cancelled
Deploy Promiscuity World API / deploy (push) Has been cancelled
k8s smoke test / test (push) Has been cancelled
Some checks failed
Deploy Promiscuity Auth API / deploy (push) Successful in 1m1s
Deploy Promiscuity Character API / deploy (push) Has been cancelled
Deploy Promiscuity Crafting API / deploy (push) Has been cancelled
Deploy Promiscuity Inventory API / deploy (push) Has been cancelled
Deploy Promiscuity Locations API / deploy (push) Has been cancelled
Deploy Promiscuity Mail API / deploy (push) Has been cancelled
Deploy Promiscuity World API / deploy (push) Has been cancelled
k8s smoke test / test (push) Has been cancelled
This commit is contained in:
parent
e6a442c98b
commit
09e6b4cc90
@ -6,11 +6,20 @@ extends Node3D
|
|||||||
@export var max_mushrooms_in_radius := 3
|
@export var max_mushrooms_in_radius := 3
|
||||||
@export var check_radius := 1.5
|
@export var check_radius := 1.5
|
||||||
@export var max_total_mushrooms := 50
|
@export var max_total_mushrooms := 50
|
||||||
|
@export var interact_radius := 2.0
|
||||||
|
@export var look_at_threshold := 0.95
|
||||||
|
|
||||||
static var total_mushrooms := 0
|
static var total_mushrooms := 0
|
||||||
|
|
||||||
@onready var spread_timer: Timer = $SpreadTimer
|
@onready var spread_timer: Timer = $SpreadTimer
|
||||||
@onready var ground_ray: RayCast3D = $GroundRay
|
@onready var ground_ray: RayCast3D = $GroundRay
|
||||||
|
@onready var cap: MeshInstance3D = $Cap
|
||||||
|
@onready var stem: MeshInstance3D = $Stem
|
||||||
|
|
||||||
|
var _player_in_range := false
|
||||||
|
var _is_highlighted := false
|
||||||
|
var highlight_mat: StandardMaterial3D
|
||||||
|
var _audio_player: AudioStreamPlayer3D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
total_mushrooms += 1
|
total_mushrooms += 1
|
||||||
@ -20,6 +29,111 @@ func _ready() -> void:
|
|||||||
scale = Vector3.ONE * randf_range(0.8, 1.2)
|
scale = Vector3.ONE * randf_range(0.8, 1.2)
|
||||||
rotation.y = randf_range(0, TAU)
|
rotation.y = randf_range(0, TAU)
|
||||||
|
|
||||||
|
# Setup interaction area
|
||||||
|
var area = Area3D.new()
|
||||||
|
add_child(area)
|
||||||
|
var shape = CollisionShape3D.new()
|
||||||
|
var sphere = SphereShape3D.new()
|
||||||
|
sphere.radius = interact_radius
|
||||||
|
shape.shape = sphere
|
||||||
|
area.add_child(shape)
|
||||||
|
|
||||||
|
area.body_entered.connect(_on_body_entered)
|
||||||
|
area.body_exited.connect(_on_body_exited)
|
||||||
|
|
||||||
|
highlight_mat = StandardMaterial3D.new()
|
||||||
|
highlight_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||||
|
highlight_mat.albedo_color = Color(1.0, 1.0, 1.0, 0.3)
|
||||||
|
highlight_mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||||
|
|
||||||
|
_audio_player = AudioStreamPlayer3D.new()
|
||||||
|
_audio_player.stream = preload("res://assets/audio/pop.ogg")
|
||||||
|
add_child(_audio_player)
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
if not _player_in_range:
|
||||||
|
_set_highlight(false)
|
||||||
|
return
|
||||||
|
|
||||||
|
var cam = get_viewport().get_camera_3d()
|
||||||
|
if not cam:
|
||||||
|
_set_highlight(false)
|
||||||
|
return
|
||||||
|
|
||||||
|
var dir_to_mushroom = (global_position - cam.global_position).normalized()
|
||||||
|
var forward = -cam.global_transform.basis.z
|
||||||
|
var my_dot = forward.dot(dir_to_mushroom)
|
||||||
|
|
||||||
|
if my_dot > look_at_threshold:
|
||||||
|
# Check if we are the most directly looked-at mushroom in range
|
||||||
|
var is_best = true
|
||||||
|
for mushroom in get_tree().get_nodes_in_group("mushrooms"):
|
||||||
|
if mushroom == self or not mushroom.get("_player_in_range"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
var m_dir = (mushroom.global_position - cam.global_position).normalized()
|
||||||
|
var m_dot = forward.dot(m_dir)
|
||||||
|
|
||||||
|
if m_dot > my_dot:
|
||||||
|
is_best = false
|
||||||
|
break
|
||||||
|
elif m_dot == my_dot and mushroom.get_instance_id() > get_instance_id():
|
||||||
|
# Tie breaker
|
||||||
|
is_best = false
|
||||||
|
break
|
||||||
|
|
||||||
|
_set_highlight(is_best)
|
||||||
|
else:
|
||||||
|
_set_highlight(false)
|
||||||
|
|
||||||
|
func _set_highlight(value: bool) -> void:
|
||||||
|
if _is_highlighted == value: return
|
||||||
|
_is_highlighted = value
|
||||||
|
|
||||||
|
if value:
|
||||||
|
if cap: cap.material_overlay = highlight_mat
|
||||||
|
if stem: stem.material_overlay = highlight_mat
|
||||||
|
else:
|
||||||
|
if cap: cap.material_overlay = null
|
||||||
|
if stem: stem.material_overlay = null
|
||||||
|
|
||||||
|
func _on_body_entered(body: Node3D) -> void:
|
||||||
|
if body.is_in_group("player"):
|
||||||
|
_player_in_range = true
|
||||||
|
|
||||||
|
func _on_body_exited(body: Node3D) -> void:
|
||||||
|
if body.is_in_group("player"):
|
||||||
|
_player_in_range = false
|
||||||
|
_set_highlight(false)
|
||||||
|
|
||||||
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
|
if _is_highlighted and event.is_action_pressed("interact"):
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
_collect_mushroom()
|
||||||
|
|
||||||
|
func _collect_mushroom() -> void:
|
||||||
|
# Disable interaction and visuals
|
||||||
|
_is_highlighted = false
|
||||||
|
_set_highlight(false)
|
||||||
|
_player_in_range = false
|
||||||
|
|
||||||
|
if cap: cap.visible = false
|
||||||
|
if stem: stem.visible = false
|
||||||
|
|
||||||
|
# Stop spreading logic
|
||||||
|
spread_timer.stop()
|
||||||
|
|
||||||
|
# Disable processing so it can't be interacted with again
|
||||||
|
set_process_unhandled_input(false)
|
||||||
|
set_process(false)
|
||||||
|
|
||||||
|
# Play sound
|
||||||
|
_audio_player.play()
|
||||||
|
|
||||||
|
# Wait for sound to finish, then free
|
||||||
|
await _audio_player.finished
|
||||||
|
queue_free()
|
||||||
|
|
||||||
func _setup_timer() -> void:
|
func _setup_timer() -> void:
|
||||||
spread_timer.wait_time = randf_range(spread_interval_min, spread_interval_max)
|
spread_timer.wait_time = randf_range(spread_interval_min, spread_interval_max)
|
||||||
spread_timer.start()
|
spread_timer.start()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user