feat: added rocket noises and smoke trails and adjusted AoE of rockets and damage falloff on AoE

This commit is contained in:
DottsGit
2026-06-05 13:32:10 -04:00
parent a85e0952c5
commit 6af87eb7bd
28 changed files with 259 additions and 14 deletions
+132 -5
View File
@@ -1,16 +1,141 @@
extends Projectile
class_name ExplosiveProjectile
var explosion_radius: float = 5.0
var explosion_radius: float = 2.5
var explosion_knockback: float = 20.0
var can_self_damage: bool = false
var falloff_curve: float = 1.0 # 1.0 is linear, 2.0 is quadratic (steep drop)
var flight_sound: AudioStreamPlayer3D
var smoke_sys: GPUParticles3D
var jet_sys: GPUParticles3D
static var _smoke_tex: GradientTexture2D
static func get_smoke_texture() -> GradientTexture2D:
if _smoke_tex: return _smoke_tex
_smoke_tex = GradientTexture2D.new()
_smoke_tex.fill = GradientTexture2D.FILL_RADIAL
_smoke_tex.fill_from = Vector2(0.5, 0.5)
_smoke_tex.fill_to = Vector2(1.0, 1.0)
var g = Gradient.new()
g.add_point(0.0, Color(1, 1, 1, 1))
g.add_point(0.5, Color(1, 1, 1, 0.5))
g.add_point(1.0, Color(1, 1, 1, 0))
_smoke_tex.gradient = g
_smoke_tex.width = 64
_smoke_tex.height = 64
return _smoke_tex
func _ready() -> void:
super._ready()
_setup_effects()
func destroy() -> void:
if is_instance_valid(smoke_sys):
smoke_sys.emitting = false
var p = smoke_sys.get_parent()
if p:
var trans = smoke_sys.global_transform
p.remove_child(smoke_sys)
get_tree().current_scene.add_child(smoke_sys)
smoke_sys.global_transform = trans
var timer = smoke_sys.get_tree().create_timer(smoke_sys.lifetime)
timer.timeout.connect(smoke_sys.queue_free)
if is_instance_valid(jet_sys):
jet_sys.emitting = false
var p = jet_sys.get_parent()
if p:
var trans = jet_sys.global_transform
p.remove_child(jet_sys)
get_tree().current_scene.add_child(jet_sys)
jet_sys.global_transform = trans
var timer = jet_sys.get_tree().create_timer(jet_sys.lifetime)
timer.timeout.connect(jet_sys.queue_free)
super.destroy()
func _setup_effects() -> void:
# Audio
flight_sound = AudioStreamPlayer3D.new()
flight_sound.stream = load("res://assets/sounds/rocket_flight.wav")
flight_sound.autoplay = true
if flight_sound.stream is AudioStreamWAV:
flight_sound.stream.loop_mode = AudioStreamWAV.LOOP_FORWARD
flight_sound.unit_size = 50.0
flight_sound.max_db = 6.0
flight_sound.volume_db = 6.0
add_child(flight_sound)
flight_sound.play()
# Jet Fire Particles
jet_sys = GPUParticles3D.new()
var jet_mat = ParticleProcessMaterial.new()
jet_mat.direction = Vector3(0, 0, 1) # Backwards (since model looks at -Z)
jet_mat.spread = 10.0
jet_mat.initial_velocity_min = 1.0
jet_mat.initial_velocity_max = 2.0
jet_mat.gravity = Vector3.ZERO
var jet_mesh = BoxMesh.new()
jet_mesh.size = Vector3(0.05, 0.05, 0.05)
var mat = StandardMaterial3D.new()
mat.albedo_color = Color(1.0, 0.6, 0.0)
mat.emission_enabled = true
mat.emission = Color(1.0, 0.5, 0.0)
jet_mesh.material = mat
jet_sys.draw_pass_1 = jet_mesh
jet_sys.process_material = jet_mat
jet_sys.amount = 16
jet_sys.lifetime = 0.2
jet_sys.position = Vector3(0, 0, 0.1)
add_child(jet_sys)
# Smoke Trail
smoke_sys = GPUParticles3D.new()
var smoke_mat = ParticleProcessMaterial.new()
smoke_mat.direction = Vector3(0, 0, 1)
smoke_mat.spread = 5.0
smoke_mat.initial_velocity_min = 0.0
smoke_mat.initial_velocity_max = 0.5
smoke_mat.gravity = Vector3(0, 0.5, 0)
var grad = Gradient.new()
grad.add_point(0.0, Color(0.5, 0.5, 0.5, 0.8))
grad.add_point(1.0, Color(0.8, 0.8, 0.8, 0.0))
var grad_tex = GradientTexture1D.new()
grad_tex.gradient = grad
smoke_mat.color_ramp = grad_tex
var curve = Curve.new()
curve.add_point(Vector2(0.0, 1.0))
curve.add_point(Vector2(1.0, 3.0))
var curve_tex = CurveTexture.new()
curve_tex.curve = curve
smoke_mat.scale_curve = curve_tex
var smoke_mesh = QuadMesh.new()
smoke_mesh.size = Vector2(0.2, 0.2)
var s_mat = StandardMaterial3D.new()
s_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
s_mat.vertex_color_use_as_albedo = true
s_mat.albedo_texture = get_smoke_texture()
s_mat.billboard_mode = BaseMaterial3D.BILLBOARD_PARTICLES
s_mat.billboard_keep_scale = true
smoke_mesh.material = s_mat
smoke_sys.draw_pass_1 = smoke_mesh
smoke_sys.process_material = smoke_mat
smoke_sys.amount = 32
smoke_sys.lifetime = 1.5
smoke_sys.position = Vector3(0, 0, 0.15)
add_child(smoke_sys)
func _on_hit(result: Dictionary) -> void:
if not result.collider.has_method("take_damage"):
ImpactSpawner.spawn(get_tree(), "crater", result.position, result.normal, explosion_radius * 1.5)
_explode(result.position)
queue_free()
destroy()
func _explode(pos: Vector3) -> void:
var space_state = get_world_3d().direct_space_state
@@ -49,10 +174,12 @@ func _explode(pos: Vector3) -> void:
# Normalised distance (0 = epicenter, 1 = edge)
var ndist = dist / explosion_radius
var intensity = clampf(1.0 - pow(ndist, falloff_curve), 0.0, 1.0)
var falloff = clampf(pow(ndist, falloff_curve), 0.0, 1.0)
var damage_intensity = lerpf(1.0, 0.33, falloff)
var knockback_intensity = 1.0 - falloff
var final_damage = damage * intensity
var final_knockback = explosion_knockback * intensity
var final_damage = damage * damage_intensity
var final_knockback = explosion_knockback * knockback_intensity
# Knockback direction: from explosion pos to target
var dir = (target_pos - pos).normalized()