extends Node2D var _effect_color := Color(1.0,0.72,0.32) var _elapsed := 0.0 var _duration := 0.30 var _is_explosion := false var _kind := DamageTypes.Type.ENERGY var _normal := Vector2.UP var _directions: Array[Vector2] = [] var _speeds: Array[float] = [] var _sizes: Array[float] = [] func configure(is_explosion: bool, effect_color: Color) -> void: _is_explosion = is_explosion _effect_color = effect_color _duration = 0.58 if is_explosion else 0.30 _seed_sparks() func configure_contact(kind: int, incoming: Vector2) -> void: _kind = clampi(kind,0,2) _normal = -incoming.normalized() if incoming.length_squared()>0.001 else Vector2.UP _effect_color = [Color("ffc071"),Color("68d9ff"),Color("88f35b")][_kind] if not _is_explosion: _duration = [0.28,0.34,0.44][_kind] _seed_sparks() func _seed_sparks() -> void: _directions.clear() _speeds.clear() _sizes.clear() var count := 22 if _is_explosion else (13 if _kind==0 else 8) for i in count: var angle := randf_range(-1.35,1.35) var direction := Vector2.RIGHT.rotated(randf()*TAU) if _is_explosion else _normal.rotated(angle) _directions.append(direction) _speeds.append(randf_range(65,230) if _kind==0 else randf_range(25,100)) _sizes.append(randf_range(1.1,2.4)) func _ready() -> void: z_index = 30 add_to_group("combat_impacts") if get_tree().get_nodes_in_group("combat_impacts").size()>72: for old in get_tree().get_nodes_in_group("combat_impacts"): if old!=self and not old.is_queued_for_deletion(): old.queue_free() break func _process(delta: float) -> void: _elapsed += delta if _elapsed>=_duration: queue_free() else: queue_redraw() func _draw() -> void: var t := clampf(_elapsed/_duration,0,1) var fade := 1.0-t var flash := maxf(0.0,1.0-t*4.0) var glow_radius := 20.0 if _is_explosion else 9.0 for layer in range(4,0,-1): draw_circle(Vector2.ZERO,glow_radius*float(layer)/4.0,Color(_effect_color,flash*0.035)) draw_circle(Vector2.ZERO,2.5*flash,Color(_effect_color.lightened(0.8),flash)) if _is_explosion: draw_arc(Vector2.ZERO,7+t*65,0,TAU,48,Color(_effect_color,fade*0.5),1.5,true) if _kind==DamageTypes.Type.ENERGY: for i in 4: var angle := float(i)*TAU/4+_normal.angle()+t*0.4 draw_arc(Vector2.ZERO,4+t*18,angle,angle+0.8,10,Color(_effect_color,fade*0.65),1.1,true) var a := Vector2.RIGHT.rotated(angle)*4 var b := Vector2.RIGHT.rotated(angle+0.25)*(9+t*12) draw_polyline(PackedVector2Array([a,(a+b)*0.5+Vector2(2,-2),b]),Color(_effect_color,fade*0.65),1.0,true) elif _kind==DamageTypes.Type.RADIATION: for i in 3: var angle := i*TAU/3+t*2 draw_arc(Vector2.ZERO,5+t*17,angle,angle+0.95,12,Color(_effect_color,fade*0.4),1.2,true) for i in _directions.size(): var direction := _directions[i] var point := direction*_speeds[i]*_elapsed if _kind==DamageTypes.Type.KINETIC: draw_line(point-direction*(3+fade*7),point,Color(_effect_color,fade),_sizes[i]*fade+0.4,true) if i%3==0: draw_line(point+Vector2(-1,0),point+Vector2(1,1),Color(0.65,0.72,0.79,fade),2.0,true) else: draw_circle(point,_sizes[i]*fade,Color(_effect_color,fade*0.75))