extends Node2D const DURATION := 0.85 static var _sounds: Dictionary = {} static var _last_sound_ms := -1000 var tint := Color("91dbea") var quality := 0 var age := 0.0 static func spawn(parent: Node, at: Vector2, color: Color, rarity: int = 0, screen_audio: bool = false) -> Node2D: var effect := Node2D.new() effect.set_script(load("res://scripts/items/loot_reveal_effect.gd")) effect.tint = color effect.quality = clampi(rarity,0,4) effect.position = at parent.add_child(effect) # Simultaneous drops share one chime, keeping battles from becoming too loud. var now := Time.get_ticks_msec() if now-_last_sound_ms >= 100: _last_sound_ms = now var audio: Node if screen_audio: audio = AudioStreamPlayer.new() else: audio = AudioStreamPlayer2D.new() audio.max_distance = 1200.0 audio.attenuation = 1.5 audio.stream = sound(quality_band(rarity)) audio.volume_db = -12.0 if AudioServer.get_bus_index("SFX") >= 0: audio.bus = &"SFX" effect.add_child(audio) audio.play() return effect static func quality_band(rarity: int) -> int: return 1 if rarity >= 3 else 0 static func sound(band: int = 0) -> AudioStreamWAV: if _sounds.has(band): return _sounds[band] var rate := 22050 var length := 0.65 var data := PackedByteArray() data.resize(int(rate*length)*2) for index in int(rate*length): var t := float(index)/rate var value := 0.0 for note in 3: var elapsed := t-note*0.075 if elapsed < 0.0: continue var frequency: float = [659.25,830.61,987.77][note]*(1.25 if band > 0 else 1.0) var envelope := minf(elapsed/0.006,1.0)*exp(-elapsed*9.0) value += (sin(TAU*frequency*elapsed)+0.18*sin(TAU*frequency*2.0*elapsed))*envelope*0.18 data.encode_s16(index*2,clampi(roundi(value*32767),-32768,32767)) var stream := AudioStreamWAV.new() stream.format = AudioStreamWAV.FORMAT_16_BITS stream.mix_rate = rate stream.data = data _sounds[band] = stream return stream func _ready() -> void: z_index = 30 func _process(delta: float) -> void: age += delta if age >= DURATION: queue_free() return queue_redraw() func _draw() -> void: var progress := clampf(age/DURATION,0.0,1.0) var fade := pow(1.0-progress,2.0) var radius := 16.0+75.0*(1.0-pow(1.0-progress,3.0)) for layer in range(4,0,-1): draw_circle(Vector2.ZERO,12.0+layer*8.0,Color(tint,fade*0.035)) draw_arc(Vector2.ZERO,radius,0,TAU,64,Color(tint,fade*0.8),1.4,true) for index in 14+quality*2: var angle := index*2.39996 var direction := Vector2.from_angle(angle) var distance := (18.0+float(index%4)*8.0)+progress*(42.0+float(index%3)*18.0) var point := direction*distance draw_line(point,point-direction*(3.0+8.0*(1.0-progress)),Color(tint,fade),1.5,true) var beam := maxf(0.0,1.0-age/0.45) draw_line(Vector2(0,12),Vector2(0,-92-quality*12),Color(tint,beam*0.65),2.0,true) draw_line(Vector2(-10,0),Vector2(10,0),Color.WHITE*Color(1,1,1,beam),2.0,true)