98 lines
8.1 KiB
GDScript
98 lines
8.1 KiB
GDScript
extends Node
|
|
|
|
signal finished
|
|
|
|
@onready var node_speech = $speech
|
|
@onready var node_music = $music
|
|
|
|
const greet := [preload("res://assets/audio/clips/greet/voc_en_greet_goodmorning.mp3"), preload("res://assets/audio/clips/greet/voc_en_greet_hello.mp3")]
|
|
const its := preload("res://assets/audio/clips/misc/voc_en_its.mp3")
|
|
const minutes := ["res://assets/audio/clips/time/minute/voc_en_min_00.mp3", "res://assets/audio/clips/time/minute/voc_en_min_01.mp3", "res://assets/audio/clips/time/minute/voc_en_min_02.mp3", "res://assets/audio/clips/time/minute/voc_en_min_03.mp3", "res://assets/audio/clips/time/minute/voc_en_min_04.mp3", "res://assets/audio/clips/time/minute/voc_en_min_05.mp3", "res://assets/audio/clips/time/minute/voc_en_min_06.mp3", "res://assets/audio/clips/time/minute/voc_en_min_07.mp3", "res://assets/audio/clips/time/minute/voc_en_min_08.mp3", "res://assets/audio/clips/time/minute/voc_en_min_09.mp3", "res://assets/audio/clips/time/minute/voc_en_min_10.mp3", "res://assets/audio/clips/time/minute/voc_en_min_11.mp3", "res://assets/audio/clips/time/minute/voc_en_min_12.mp3", "res://assets/audio/clips/time/minute/voc_en_min_13.mp3", "res://assets/audio/clips/time/minute/voc_en_min_14.mp3", "res://assets/audio/clips/time/minute/voc_en_min_15.mp3", "res://assets/audio/clips/time/minute/voc_en_min_16.mp3", "res://assets/audio/clips/time/minute/voc_en_min_17.mp3", "res://assets/audio/clips/time/minute/voc_en_min_18.mp3", "res://assets/audio/clips/time/minute/voc_en_min_19.mp3", "res://assets/audio/clips/time/minute/voc_en_min_20.mp3", "res://assets/audio/clips/time/minute/voc_en_min_21.mp3", "res://assets/audio/clips/time/minute/voc_en_min_22.mp3", "res://assets/audio/clips/time/minute/voc_en_min_23.mp3", "res://assets/audio/clips/time/minute/voc_en_min_24.mp3", "res://assets/audio/clips/time/minute/voc_en_min_25.mp3", "res://assets/audio/clips/time/minute/voc_en_min_26.mp3", "res://assets/audio/clips/time/minute/voc_en_min_27.mp3", "res://assets/audio/clips/time/minute/voc_en_min_28.mp3", "res://assets/audio/clips/time/minute/voc_en_min_29.mp3", "res://assets/audio/clips/time/minute/voc_en_min_30.mp3", "res://assets/audio/clips/time/minute/voc_en_min_31.mp3", "res://assets/audio/clips/time/minute/voc_en_min_32.mp3", "res://assets/audio/clips/time/minute/voc_en_min_33.mp3", "res://assets/audio/clips/time/minute/voc_en_min_34.mp3", "res://assets/audio/clips/time/minute/voc_en_min_35.mp3", "res://assets/audio/clips/time/minute/voc_en_min_36.mp3", "res://assets/audio/clips/time/minute/voc_en_min_37.mp3", "res://assets/audio/clips/time/minute/voc_en_min_38.mp3", "res://assets/audio/clips/time/minute/voc_en_min_39.mp3", "res://assets/audio/clips/time/minute/voc_en_min_40.mp3", "res://assets/audio/clips/time/minute/voc_en_min_41.mp3", "res://assets/audio/clips/time/minute/voc_en_min_42.mp3", "res://assets/audio/clips/time/minute/voc_en_min_43.mp3", "res://assets/audio/clips/time/minute/voc_en_min_44.mp3", "res://assets/audio/clips/time/minute/voc_en_min_45.mp3", "res://assets/audio/clips/time/minute/voc_en_min_46.mp3", "res://assets/audio/clips/time/minute/voc_en_min_47.mp3", "res://assets/audio/clips/time/minute/voc_en_min_48.mp3", "res://assets/audio/clips/time/minute/voc_en_min_49.mp3", "res://assets/audio/clips/time/minute/voc_en_min_50.mp3", "res://assets/audio/clips/time/minute/voc_en_min_51.mp3", "res://assets/audio/clips/time/minute/voc_en_min_52.mp3", "res://assets/audio/clips/time/minute/voc_en_min_53.mp3", "res://assets/audio/clips/time/minute/voc_en_min_54.mp3", "res://assets/audio/clips/time/minute/voc_en_min_55.mp3", "res://assets/audio/clips/time/minute/voc_en_min_56.mp3", "res://assets/audio/clips/time/minute/voc_en_min_57.mp3", "res://assets/audio/clips/time/minute/voc_en_min_58.mp3", "res://assets/audio/clips/time/minute/voc_en_min_59.mp3"]
|
|
const hours := ["res://assets/audio/clips/time/hour/voc_en_hour_01.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_02.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_03.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_04.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_05.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_06.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_07.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_08.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_09.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_10.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_11.mp3", "res://assets/audio/clips/time/hour/voc_en_hour_12.mp3"]
|
|
const am_pm := [preload("res://assets/audio/clips/time/am pm/voc_en_ampm_am.mp3"), preload("res://assets/audio/clips/time/am pm/voc_en_ampm_pm.mp3")]
|
|
const weekday := [preload("res://assets/audio/clips/time/weekday/voc_en_week_0.mp3"), preload("res://assets/audio/clips/time/weekday/voc_en_week_1.mp3"), preload("res://assets/audio/clips/time/weekday/voc_en_week_2.mp3"), preload("res://assets/audio/clips/time/weekday/voc_en_week_3.mp3"), preload("res://assets/audio/clips/time/weekday/voc_en_week_4.mp3"), preload("res://assets/audio/clips/time/weekday/voc_en_week_5.mp3"), preload("res://assets/audio/clips/time/weekday/voc_en_week_6.mp3")]
|
|
const weather := [preload("res://assets/audio/clips/weather/voc_en_weather_cloudy.mp3"), preload("res://assets/audio/clips/weather/voc_en_weather_foggy.mp3"), preload("res://assets/audio/clips/weather/voc_en_weather_partlycloudy.mp3"), preload("res://assets/audio/clips/weather/voc_en_weather_rainy.mp3"), preload("res://assets/audio/clips/weather/voc_en_weather_snowy.mp3"), preload("res://assets/audio/clips/weather/voc_en_weather_stormy.mp3"), preload("res://assets/audio/clips/weather/voc_en_weather_sunny.mp3")]
|
|
|
|
const music := [preload("res://assets/audio/clips/music/music_cloudy.wav"), preload("res://assets/audio/clips/music/music_foggy.wav"), preload("res://assets/audio/clips/music/music_partlycloudy.wav"), preload("res://assets/audio/clips/music/music_rainy.wav"), preload("res://assets/audio/clips/music/music_snowy.wav"), preload("res://assets/audio/clips/music/music_stormy.wav"), preload("res://assets/audio/clips/music/music_sunny.wav"), preload("res://assets/audio/clips/music/music_unknown.wav")]
|
|
|
|
var tween: Tween
|
|
|
|
var A_finished = true
|
|
var B_finished = true
|
|
|
|
func play(moment: Moment, day: int, weather_idx: int, music_weather_override = null, play_music: bool = true, speak_time: bool = true):
|
|
stop()
|
|
if tween:
|
|
tween.kill()
|
|
node_speech.volume_db = 0
|
|
node_music.volume_db = 0
|
|
A_finished = !speak_time
|
|
B_finished = !play_music
|
|
var out := []
|
|
if speak_time:
|
|
out = [
|
|
1.0, # sleep for 1 second
|
|
greet[0] if moment.is_morning() else greet[1],
|
|
its,
|
|
load(hours[int(moment.hour - 1) % 12]),
|
|
load(minutes[moment.minute]),
|
|
am_pm[0 if moment.is_am() else 1],
|
|
weekday[day],
|
|
]
|
|
var tune = music[Constants.WEATHER.UNKNOWN]
|
|
if weather_idx < Constants.WEATHER.UNKNOWN:
|
|
out.append(self.weather[weather_idx])
|
|
tune = music[weather_idx]
|
|
|
|
if music_weather_override != null:
|
|
tune = music[music_weather_override]
|
|
|
|
if speak_time:
|
|
node_speech.play_all(out)
|
|
if play_music:
|
|
node_music.stream = tune
|
|
node_music.play()
|
|
|
|
if A_finished and B_finished:
|
|
finished.emit()
|
|
|
|
func stop(fadeout: float = 0.0):
|
|
if tween:
|
|
tween.kill()
|
|
if fadeout > 0:
|
|
print("fadeout ", fadeout)
|
|
tween = get_tree().create_tween()
|
|
tween.set_parallel(true)
|
|
tween.tween_property(node_music, "volume_db", -60.0, fadeout)
|
|
tween.tween_property(node_speech, "volume_db", -60.0, fadeout)
|
|
tween.set_parallel(false)
|
|
tween.tween_interval(fadeout)
|
|
tween.play()
|
|
await tween.finished
|
|
node_music.stop()
|
|
node_speech.stop()
|
|
|
|
# Godot 4 quirk: manual AudioStreamPlayer.stop() does not emit the `finished`
|
|
# signal (Godot 3 did), so the all_finished/finished handlers don't run and
|
|
# A_finished/B_finished would otherwise stay false from a prior play() —
|
|
# leaving is_playing() stuck at true and blocking the next play().
|
|
A_finished = true
|
|
B_finished = true
|
|
|
|
node_speech.volume_db = 0
|
|
node_music.volume_db = 0
|
|
|
|
func is_playing():
|
|
return !(A_finished and B_finished)
|
|
|
|
func _on_speech_all_finished():
|
|
A_finished = true
|
|
if A_finished and B_finished:
|
|
finished.emit()
|
|
|
|
|
|
func _on_music_finished():
|
|
B_finished = true
|
|
if A_finished and B_finished:
|
|
finished.emit()
|