Randoloot/scripts/game/hull_damage_visual.gd
2026-10-25 22:38:13 +01:00

67 lines
2.6 KiB
GDScript

extends Node2D
static var _soft: GradientTexture2D
var _sparks: Array[Dictionary] = []
var _smoke: Array[Dictionary] = []
var _timer := 0.0
var _last_hit := -1.0
var _age := 0.0
func _ready() -> void:
z_index = 3
if _soft == null:
_soft = GradientTexture2D.new()
_soft.width = 48
_soft.height = 48
_soft.fill = GradientTexture2D.FILL_RADIAL
_soft.fill_from = Vector2(0.5,0.5)
_soft.fill_to = Vector2(1,0.5)
var gradient := Gradient.new()
gradient.set_color(0,Color.WHITE)
gradient.set_color(1,Color(1,1,1,0))
_soft.gradient = gradient
func hit(at: Vector2, direction: Vector2, kind: int) -> void:
if _age-_last_hit<0.08: return
_last_hit = _age
var owner := get_parent() as Node2D
var radius := float(owner.get_visual_size())*0.4 if owner.has_method("get_visual_size") else 24.0
var local := owner.to_local(at).limit_length(radius)
var point := owner.to_global(local)
for i in 7:
if _sparks.size()>=36: _sparks.pop_front()
_sparks.append({"point":point,"velocity":(-direction).rotated(randf_range(-1.4,1.4))*randf_range(20,75),"age":0.0,"life":randf_range(0.12,0.3),"kind":kind})
func _process(delta: float) -> void:
_age += delta
var owner := get_parent()
if owner.has_method("is_mini_boosting") and (bool(owner.get("_is_destroyed")) or bool(owner.get("is_docked"))):
_sparks.clear()
_smoke.clear()
queue_redraw()
return
_timer -= delta
var ratio := float(owner.get("hull"))/maxf(1.0,float(owner.get("max_hull")))
if ratio<0.35 and ratio>0 and _timer<=0:
_timer = 0.15+ratio*0.6
var local := Vector2(-8 if int(_age*3)%2 else 8,7)
_smoke.append({"point":owner.to_global(local),"velocity":owner.velocity*0.15+Vector2(randf_range(-4,4),-6),"age":0.0,"life":0.65,"radius":randf_range(3,6)})
if _smoke.size()>10: _smoke.pop_front()
for pool in [_sparks,_smoke]:
for i in range(pool.size()-1,-1,-1):
pool[i].age += delta
pool[i].point += pool[i].velocity*delta
if pool[i].age >= pool[i].life: pool.remove_at(i)
queue_redraw()
func _draw() -> void:
for puff in _smoke:
var t := float(puff.age)/float(puff.life)
var radius := float(puff.radius)*(1+t*1.8)
draw_texture_rect(_soft,Rect2(to_local(puff.point)-Vector2.ONE*radius,Vector2.ONE*radius*2),false,Color(0.35,0.26,0.22,(1-t)*0.3))
if t<0.2: draw_circle(to_local(puff.point),1.2,Color(1,0.48,0.12,(1-t*5)*0.8))
for spark in _sparks:
var fade := 1.0-float(spark.age)/float(spark.life)
var point := to_local(spark.point)
var color: Color = [Color("ffc176"),Color("8de4ff"),Color("a4ff70")][int(spark.kind)]
draw_line(point,point-to_local(global_position+spark.velocity.normalized()*4),Color(color,fade),1.0,true)