Save the quiz and continue it after a restart; load characters from a folder
The quiz is saved to current_quiz.json in the config folder after every change, and the game goes on where it was when it starts again: the players with their points and characters, every song with who got a point for it and whether it was played, answered or is playing, and the songs downloaded ahead with their files. The song that was playing is ready to play again. Songs whose files are gone are downloaded again. On a server, the saved songs are checked against the server's playlist. If it changed, e.g. after a sync, or another server is used, the quiz starts over with the same players. A quiz from a music folder continues offline, including how far a prepared quiz has come. A new game is saved like any other change, and a file that can't be read starts a new quiz. Characters can be read from a folder picked in Settings instead of the server, for this session. A music folder with a characters folder brings its own characters, e.g. for a themed quiz; that folder is not counted as a soundtrack. When the characters come from somewhere else, players pick their characters again. Closes #11, closes #44
This commit is contained in:
1 parent
4a934840f6
commit
e4352a9f34
33 files changed
+2886
-499
No files matched your search
+57
-11
@@ -15,22 +15,39 @@ signal song_list_loaded
|
||||
## Emitted when a new song has been downloaded and added to the Playlist.
|
||||
signal song_added
|
||||
|
||||
## Emitted when the songs of a saved quiz could not be continued, because the server's
|
||||
## playlist no longer has them, e.g. after a sync. The quiz starts over.
|
||||
signal saved_songs_dropped
|
||||
|
||||
## Seconds to wait before retrying a download step that failed.
|
||||
var retry_seconds: float = 5.0
|
||||
|
||||
|
||||
## Loads the songs already in the server playlist, then starts preloading new ones.
|
||||
## Preloading waits for the list, because loading the list clears the playlist.
|
||||
func load_song_list() -> void:
|
||||
##
|
||||
## With [param saved], the songs of a saved quiz are used where they match the server's
|
||||
## playlist, so who got points and what was answered or downloaded ahead is kept. When
|
||||
## the server's playlist no longer has them, they are dropped and
|
||||
## [signal saved_songs_dropped] is emitted.
|
||||
func load_song_list(saved: QuizSave = null) -> void:
|
||||
GameLog.debug("load_song_list")
|
||||
if Settings.is_offline():
|
||||
_start_folder_playlist()
|
||||
_start_folder_playlist(saved)
|
||||
return
|
||||
var song_list_fetched: Callable = func song_list_fetched(songs: Array[SongInfo]) -> void:
|
||||
if Settings.is_offline():
|
||||
return
|
||||
Playlist.clear_song_list()
|
||||
for info: SongInfo in songs:
|
||||
var continued: int = 0
|
||||
if saved != null && !saved.songs.is_empty():
|
||||
if saved_songs_match(saved.songs, songs):
|
||||
continued = saved.songs.size()
|
||||
_continue_songs(saved)
|
||||
else:
|
||||
GameLog.warning("The server's playlist changed, so the saved quiz starts over")
|
||||
saved_songs_dropped.emit()
|
||||
for info: SongInfo in songs.slice(continued):
|
||||
var new_song_object: SongObject = SongObject.new()
|
||||
new_song_object.song_number = info.song_no
|
||||
new_song_object.soundtrack_title = info.soundtrack
|
||||
@@ -38,12 +55,38 @@ func load_song_list() -> void:
|
||||
new_song_object.is_answered = true
|
||||
new_song_object.has_played = true
|
||||
Playlist.add_to_playlist(new_song_object)
|
||||
Playlist.update_last_played_song()
|
||||
# Songs already on the server were played before, so the game starts after them
|
||||
Playlist.game_start_song = Playlist.song_object_array.size()
|
||||
if continued == 0:
|
||||
Playlist.update_last_played_song()
|
||||
# Songs already on the server were played before, so the game starts after them
|
||||
Playlist.game_start_song = Playlist.song_object_array.size()
|
||||
song_list_loaded.emit()
|
||||
fetch_song_if_idle()
|
||||
MusicServerClient.fetch_song_list(song_list_fetched, _retry_later.bind(load_song_list))
|
||||
# Songs downloaded ahead before a restart already fill some of the cache
|
||||
fill_cache()
|
||||
MusicServerClient.fetch_song_list(song_list_fetched,
|
||||
_retry_later.bind(load_song_list.bind(saved)))
|
||||
|
||||
|
||||
## Whether [param saved_songs] are the first songs of the server's playlist [param songs]:
|
||||
## the same numbers, soundtracks and titles in the same order.
|
||||
static func saved_songs_match(saved_songs: Array[SongObject], songs: Array[SongInfo]) -> bool:
|
||||
if saved_songs.size() > songs.size():
|
||||
return false
|
||||
for i: int in saved_songs.size():
|
||||
if saved_songs[i].song_number != songs[i].song_no \
|
||||
|| saved_songs[i].soundtrack_title != songs[i].soundtrack \
|
||||
|| saved_songs[i].song_title != songs[i].song:
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
# Puts the saved songs in the playlist, where the quiz was
|
||||
func _continue_songs(saved: QuizSave) -> void:
|
||||
for song_object: SongObject in saved.songs:
|
||||
Playlist.add_to_playlist(song_object)
|
||||
Playlist.currently_playing_song = saved.currently_playing_song
|
||||
Playlist.latest_played_song = saved.latest_played_song
|
||||
Playlist.game_start_song = saved.game_start_song
|
||||
Playlist.first_song_played = saved.first_song_played
|
||||
|
||||
|
||||
## Starts downloading one more song, which keeps downloading until the cache is full.
|
||||
@@ -114,14 +157,17 @@ func _retry_later(step: Callable) -> void:
|
||||
step.call())
|
||||
|
||||
|
||||
# A music folder has no playlist on a server, so the game starts with an empty one
|
||||
func _start_folder_playlist() -> void:
|
||||
# A music folder has no playlist on a server, so the game starts with an empty one, or
|
||||
# with the saved quiz's songs
|
||||
func _start_folder_playlist(saved: QuizSave = null) -> void:
|
||||
Playlist.clear_song_list()
|
||||
Playlist.update_last_played_song()
|
||||
Playlist.game_start_song = 0
|
||||
if saved != null && !saved.songs.is_empty():
|
||||
_continue_songs(saved)
|
||||
Playlist.is_song_downloading = false
|
||||
song_list_loaded.emit()
|
||||
fetch_song_if_idle()
|
||||
fill_cache()
|
||||
|
||||
|
||||
# Picks songs from the music folder until enough are ready. A prepared quiz runs out
|
||||
|
||||
Reference in new issue
Block a user