aboutsummaryrefslogtreecommitdiff
path: root/game/src/Game/MusicConductor/MusicConductor.gd
blob: b4b660a8fa31c9251de749d1f9fd111cd3d9f500 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
extends Node

signal song_paused(paused : bool)
signal song_started(track_id : int)
## Only triggers when song naturally ends
signal song_finished(track_id : int)
signal song_scrubbed(percentage : float, seconds : float)

# REQUIREMENTS
# * SS-67
@export_dir var music_directory : String
@export var first_song_name : String

@export var _audio_stream_player : AudioStreamPlayer

var _selected_track := 0
var _available_songs : Array[SongInfo] = []
var _auto_play_next_song : bool = true

## True if music player should be visible.
## Used to keep keep consistency between scene changes
var is_music_player_visible : bool = true

var _has_startup_happened : bool = false

func get_all_song_names() -> PackedStringArray:
   var songNames : PackedStringArray = []
   for si : SongInfo in _available_songs:
      songNames.append(si.song_name)
   return songNames

func get_current_song_index() -> int:
   return _selected_track

func get_current_song_name() -> String:
   return _available_songs[_selected_track].song_name

func scrub_song_by_percentage(percentage: float) -> void:
   var percentInSeconds : float = (percentage / 100.0) * _audio_stream_player.stream.get_length()
   _audio_stream_player.play(percentInSeconds)
   song_scrubbed.emit(percentage, percentInSeconds)

func get_current_song_progress_percentage() -> float:
   return 100 * (_audio_stream_player.get_playback_position() / _audio_stream_player.stream.get_length())

func is_paused() -> bool:
   return _audio_stream_player.stream_paused

func set_paused(paused : bool) -> void:
   _audio_stream_player.stream_paused = paused
   song_paused.emit(paused)

func toggle_play_pause() -> void:
   set_paused(not is_paused())

func start_current_song() -> void:
   _audio_stream_player.stream = _available_songs[_selected_track].song_stream
   _audio_stream_player.play()
   song_started.emit(_selected_track)

# REQUIREMENTS
# * SS-70
func start_song_by_index(id: int) -> void:
   _selected_track = id
   start_current_song()

# REQUIREMENTS
# * SS-69
func select_next_song() -> void:
   _selected_track = (_selected_track + 1) % len(_available_songs)
   start_current_song()

func select_previous_song() -> void:
   _selected_track = (len(_available_songs) - 1) if (_selected_track == 0) else (_selected_track - 1)
   start_current_song()

# REQUIREMENTS
# * SND-2, SND-3
func _ready() -> void:
   var dir := DirAccess.open(music_directory)
   for fname : String in dir.get_files():
      if fname.ends_with(".import"):
         fname = fname.get_basename()
         if fname.get_basename() == first_song_name:
            _selected_track = _available_songs.size()
         _available_songs.append(SongInfo.new(music_directory, fname))
   start_current_song()

func set_startup_music(play : bool) -> void:
   if not _has_startup_happened:
      _has_startup_happened = true
      set_paused(not play)

func _on_audio_stream_player_finished() -> void:
   song_finished.emit(_selected_track)
   if _auto_play_next_song:
      select_next_song()
      start_current_song()