Files
tekton/scripts/controllers/candy_cannon_controller.gd
T

101 lines
3.4 KiB
GDScript

extends Node3D
class_name CandyCannonController
@export var is_static_turret: bool = true
@onready var ring1 = $Ring1 if has_node("Ring1") else null
@onready var ring2 = $Ring2 if has_node("Ring2") else null
@onready var ring3 = $Ring3 if has_node("Ring3") else null
@onready var tank = $Tank if has_node("Tank") else null
func _ready() -> void:
pass
func _process(delta: float) -> void:
if ring1: ring1.rotate_y(delta * 1.5)
if ring2: ring2.rotate_x(delta * -1.0)
if ring3: ring3.rotate_z(delta * 1.2)
if tank and tank.mesh and tank.mesh.material:
var mat = tank.mesh.material as StandardMaterial3D
if mat:
# Gentle pulse of the candy tank
var pulse = (sin(Time.get_ticks_msec() / 300.0) + 1.0) * 0.5
mat.emission_energy_multiplier = 1.0 + (pulse * 2.0)
@rpc("authority", "call_local", "reliable")
func play_animation_rpc(anim_name: String) -> void:
# Stub for future model animations
pass
func spawn_projectile(target_world_pos: Vector3, duration: float) -> void:
var projectile = MeshInstance3D.new()
var sphere = SphereMesh.new()
sphere.radius = 0.3
sphere.height = 0.6
projectile.mesh = sphere
var mat = StandardMaterial3D.new()
mat.albedo_color = Color(1.0, 0.4, 0.8) # Candy pink for Gauntlet
mat.emission_enabled = true
mat.emission = Color(1.0, 0.4, 0.8)
mat.emission_energy_multiplier = 3.0
projectile.material_override = mat
get_tree().get_root().add_child(projectile)
# Start projectile slightly above the cannon center
projectile.global_position = global_position + Vector3(0, 3.0, 0)
var tween = create_tween()
if not tween:
projectile.queue_free()
return
# VFX trail
var particles = GPUParticles3D.new()
var pmat = ParticleProcessMaterial.new()
pmat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_SPHERE
pmat.emission_sphere_radius = 0.3
pmat.gravity = Vector3(0, 0, 0)
pmat.scale_min = 0.1
pmat.scale_max = 0.3
particles.process_material = pmat
var pmesh = SphereMesh.new()
pmesh.radius = 0.1
pmesh.height = 0.2
var spatial_mat = StandardMaterial3D.new()
spatial_mat.albedo_color = Color(1.0, 0.6, 0.9)
spatial_mat.emission_enabled = true
spatial_mat.emission = Color(1.0, 0.6, 0.9)
pmesh.material = spatial_mat
particles.draw_pass_1 = pmesh
particles.amount = 16
particles.lifetime = 0.4
projectile.add_child(particles)
tween.set_parallel(true)
tween.tween_property(projectile, "global_position:x", target_world_pos.x, duration).set_trans(Tween.TRANS_LINEAR)
tween.tween_property(projectile, "global_position:z", target_world_pos.z, duration).set_trans(Tween.TRANS_LINEAR)
var mid_y = max(global_position.y, target_world_pos.y) + 4.0
var tween_y = create_tween()
tween_y.tween_property(projectile, "global_position:y", mid_y, duration / 2.0).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
tween_y.tween_property(projectile, "global_position:y", target_world_pos.y, duration / 2.0).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN).set_delay(duration / 2.0)
# Add some spin to the projectile
var spin_tween = create_tween()
spin_tween.set_loops()
spin_tween.tween_property(projectile, "rotation", Vector3(PI*2, PI*2, PI*2), 0.5).as_relative()
tween.chain().tween_callback(func():
spin_tween.kill()
projectile.queue_free()
)
func can_rpc() -> bool:
if not multiplayer.has_multiplayer_peer(): return false
return multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED