87 lines
2.8 KiB
GDScript
87 lines
2.8 KiB
GDScript
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)
|