feat(gameplay): perles collectibles + recette amulette de soin
Area3D Pearl flottant/tournant qui émet une couleur nacrée, spawned périodiquement près du joueur (PearlSpawner, 3 max, intervalle 9s, zone haute du seafloor). Collecte automatique au contact, ajout à l'inventaire (item 105 Perle). Nouvelle recette : 2 perles + 1 corail rouge → Amulette de soin (item 106, consommable). Spawner désactivé sur serveur dédié headless. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
62
scripts/world/Pearl.gd
Normal file
62
scripts/world/Pearl.gd
Normal file
@@ -0,0 +1,62 @@
|
||||
extends Area3D
|
||||
|
||||
signal collected(item_id: int)
|
||||
|
||||
const ITEM_ID_PEARL: int = 105
|
||||
|
||||
var _time: float = 0.0
|
||||
var _mesh: MeshInstance3D = null
|
||||
var _collected: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
monitoring = true
|
||||
monitorable = false
|
||||
body_entered.connect(_on_body_entered)
|
||||
_build_visual()
|
||||
_build_shape()
|
||||
|
||||
|
||||
func _build_visual() -> void:
|
||||
_mesh = MeshInstance3D.new()
|
||||
var sphere := SphereMesh.new()
|
||||
sphere.radius = 0.22
|
||||
sphere.height = 0.44
|
||||
sphere.radial_segments = 12
|
||||
sphere.rings = 8
|
||||
_mesh.mesh = sphere
|
||||
|
||||
var mat := StandardMaterial3D.new()
|
||||
mat.albedo_color = Color(0.96, 0.96, 1.0, 1.0)
|
||||
mat.metallic = 0.3
|
||||
mat.roughness = 0.08
|
||||
mat.emission_enabled = true
|
||||
mat.emission = Color(0.85, 0.92, 1.0)
|
||||
mat.emission_energy_multiplier = 0.8
|
||||
_mesh.material_override = mat
|
||||
|
||||
add_child(_mesh)
|
||||
|
||||
|
||||
func _build_shape() -> void:
|
||||
var shape := CollisionShape3D.new()
|
||||
var s := SphereShape3D.new()
|
||||
s.radius = 0.75
|
||||
shape.shape = s
|
||||
add_child(shape)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_time += delta
|
||||
if _mesh != null:
|
||||
_mesh.position.y = sin(_time * 2.0) * 0.18
|
||||
_mesh.rotation.y += delta * 1.4
|
||||
|
||||
|
||||
func _on_body_entered(body: Node) -> void:
|
||||
if _collected:
|
||||
return
|
||||
if body.is_in_group("player"):
|
||||
_collected = true
|
||||
collected.emit(ITEM_ID_PEARL)
|
||||
queue_free()
|
||||
Reference in New Issue
Block a user