Sort the scripts and scenes into folders

main/ holds the main window and top bar, quiz/ the quiz and its parts,
player/ the music player, popups/ every popup and what they share, data/ the
songs, players, playlist and settings, server/ the MusicServer client,
common/ the list row and GameLog, and themes/ the themes and style boxes.
This commit is contained in:
Sansan committed 2026-10-06 11:57:29 +02:00
1 parent a0428e3475
commit d77b72159d
115 files changed
+94 -84

No files matched your search

+298
View File
@@ -0,0 +1,298 @@
class_name Quiz
extends Control
## The quiz: the song that is playing, the playlist, the players and their points, and
## the popups opened from here (settings, character select, winner and log).
##
## The main window shows the quiz below its top bar. Pictures and buttons keep the
## positions they had in the main window, so the quiz fills the whole window and lets
## clicks through where it has nothing.
## Emitted when another MusicServer is picked in the settings, after the quiz has
## reloaded from it.
signal server_changed
## Emitted with a line for the game log, e.g. when a player gets a point.
signal event_logged(text: String)
var songs: Array = []
var current_player_row: PlayerRow
## True while statistics are off because a player won, until points are reset.
var stats_paused_by_win: bool = false
## Dims the window behind an open popup and keeps clicks from reaching the buttons under it.
var popup_backdrop: PopupBackdrop
@onready var open_button: Button = $Open
@onready var file_dialog: FileDialog = $FileDialog
@onready var inspiration_list: InspirationList = $InspirationList
@onready var now_playing: NowPlaying = $NowPlaying
@onready var players_panel: PlayersPanel = $PlayersPanel
@onready var toolbar: QuizToolbar = $QuizToolbar
@onready var settings_popup: SettingsPopup = $SettingsPopup
@onready var winner_popup: WinnerPopup = %WinnerPopup
@onready var song_controls: SongControls = $SongControls
@onready var song_loader: SongLoader = $SongLoader
@onready var music_list_panel: MusicListPanel = $MusicListPanel
@onready var character_select_popup: CharacterSelectPopup = %CharacterSelectPopup
@onready var music_player: MusicPlayer = $MusicPlayer
@onready var debug_label: Label = $DebugLabel
func _ready() -> void:
popup_backdrop = PopupBackdrop.add_to(self, _popups())
if OS.has_feature("debug"):
GameLog.debug("is_debug")
debug_label.visible = true
Settings.is_debug = true
settings_popup.set_winning_score(5)
settings_popup.set_selected_server(4)
song_controls.next_pressed.connect(play_next_song)
song_controls.show_answer_pressed.connect(show_answer_pressed)
toolbar.sound_test_pressed.connect(music_player.get_sound_test_song)
toolbar.settings_pressed.connect(show_settings)
toolbar.reset_playlist_pressed.connect(reset_playlist)
toolbar.reset_points_pressed.connect(reset_points)
song_loader.song_list_loaded.connect(update_song_list)
song_loader.song_added.connect(_on_song_added)
character_select_popup.character_selected.connect(_on_new_character_selected)
music_list_panel.song_clicked.connect(song_object_clicked)
players_panel.player_added.connect(_on_player_added)
players_panel.player_removed.connect(_on_player_removed)
players_panel.change_character_requested.connect(_on_change_character_requested)
music_player.play_next_song.connect(play_next_song)
music_player.update_song_list.connect(update_song_list)
settings_popup.server_changed.connect(_on_server_changed)
settings_popup.visibility_changed.connect(_on_settings_popup_visibility_changed)
open_button.pressed.connect(open)
inspiration_list.load_from_server()
song_loader.load_song_list()
character_select_popup.load_characters()
func _input(event: InputEvent) -> void:
if event is InputEventKey and event.pressed:
if event.alt_pressed && event.keycode == KEY_UP:
GameLog.debug("Alt + UP pressed")
music_player.change_volume(0.05)
if event.alt_pressed && event.keycode == KEY_DOWN:
GameLog.debug("Alt + DOWN pressed")
music_player.change_volume(-0.05)
if event.alt_pressed && event.ctrl_pressed && event.keycode == KEY_LEFT:
GameLog.debug("Ctrl + Alt + LEFT pressed")
music_player.restart()
elif event.alt_pressed && event.keycode == KEY_LEFT:
GameLog.debug("Alt + LEFT pressed")
music_player.seek(-5)
if event.alt_pressed && event.keycode == KEY_RIGHT:
GameLog.debug("Alt + RIGHT pressed")
music_player.seek(5)
## Disables the buttons that use the song list while the server syncs it.
func lock_for_sync() -> void:
toolbar.set_locked(true)
song_controls.set_locked(true)
## Reloads from the server after a sync and starts a new game.
func on_sync_finished() -> void:
refresh_from_server()
toolbar.set_locked(false)
song_controls.set_locked(false)
reset_points()
## Reloads the soundtracks, playlist and characters from the server.
func refresh_from_server() -> void:
GameLog.debug("refresh_from_server")
inspiration_list.load_from_server()
reset_playlist()
character_select_popup.load_characters()
func _on_server_changed() -> void:
GameLog.debug("_on_server_changed")
refresh_from_server()
reset_points()
server_changed.emit()
func show_answer_pressed() -> void:
GameLog.debug("show_answer_pressed")
Playlist.song_is_answered()
update_song_list()
func play_next_song() -> void:
GameLog.debug("play_next_song ", Playlist.latest_played_song)
if Playlist.first_song_played:
Playlist.set_latest_played_song()
Playlist.first_song_played = true
music_player.play_song_object(Playlist.latest_played_song)
if !(Playlist.get_preloaded_songs() > 0):
song_controls.set_next_enabled(false)
song_loader.fetch_song_if_idle()
func _popups() -> Array[BasePopup]:
return [settings_popup, character_select_popup, winner_popup]
# The cache size can be changed in the settings. Waiting until the settings are closed
# avoids starting downloads while the user is still clicking the number up and down.
func _on_settings_popup_visibility_changed() -> void:
if !settings_popup.visible:
song_loader.fill_cache()
func _on_song_added() -> void:
song_controls.set_next_enabled(true)
if Settings.is_debug:
update_song_list()
func update_song_list() -> void:
GameLog.debug("update_song_list")
if Playlist.currently_playing_song >= 0:
now_playing.show_song(Playlist.get_current_soundtrack_title(),
Playlist.get_current_song_title())
music_list_panel.refresh()
func song_object_clicked(song_no: int) -> void:
GameLog.debug("Clicked Song Object: ", Playlist.song_object_array[song_no].to_string())
if !Settings.character_select_open:
if Playlist.get_song(song_no) == null:
GameLog.debug("has no song, need to download")
var song_downloaded: Callable = func song_downloaded(body: PackedByteArray) -> void:
var sound: AudioStream = AudioStreamMP3.new()
sound.data = body
Playlist.add_song_to_song_object(song_no, sound)
music_player.play_song_object(song_no)
MusicServerClient.fetch_song(song_no, song_downloaded)
else:
GameLog.debug("song already downloaded")
music_player.play_song_object(song_no)
func reset_playlist() -> void:
GameLog.debug("reset_playlist")
var playlist_reset_done: Callable = func playlist_reset_done() -> void:
Playlist.reset_playlist()
song_loader.load_song_list()
MusicServerClient.reset_playlist(playlist_reset_done)
func reset_points() -> void:
GameLog.debug("reset_points")
for player_objects: PlayerObject in Settings.player_array:
player_objects.reset_points()
players_panel.reload()
# A new game starts, so turn statistics back on if winning turned them off
if stats_paused_by_win:
Settings.add_to_stats = true
stats_paused_by_win = false
func show_settings() -> void:
GameLog.debug("show_settings")
settings_popup.open()
# Each new player's points reach the music player, the log and the winner popup.
func _on_player_added(new_player_object: PlayerObject) -> void:
new_player_object.first_point_triggered.connect(music_player._on_point_triggered.bind("first"))
new_player_object.match_point_triggered.connect(music_player._on_point_triggered.bind("match"))
new_player_object.winner_triggered.connect(_on_player_won.bind(new_player_object))
new_player_object.point_given_sound.connect(_on_make_point_given_sound)
new_player_object.player_point_given.connect(_on_point_given.bind(new_player_object))
new_player_object.player_point_taken.connect(_on_point_taken.bind(new_player_object))
func _on_point_given(player_object: PlayerObject) -> void:
GameLog.debug("_on_point_given")
event_logged.emit(player_object.player_name + " got a point")
if Playlist.currently_playing_song >= 0:
Playlist.add_point(player_object.id)
update_song_list()
func _on_make_point_given_sound() -> void:
music_player.play_sound_effect(preload("res://sounds/itemopen.wav"))
func _on_point_taken(player_object: PlayerObject) -> void:
GameLog.debug("_on_point_taken")
event_logged.emit(player_object.player_name + " lost a point")
music_player.play_sound_effect(preload("res://sounds/itemequip.wav"))
if Playlist.currently_playing_song >= 0:
Playlist.remove_point(player_object.id)
update_song_list()
func _on_player_won(player_object: PlayerObject) -> void:
GameLog.debug("_on_player_won")
winner_popup.show_winner(player_object)
music_player.play_song(preload("res://sounds/winning.mp3"))
# Songs played after the game is won don't count towards the statistics
if Settings.add_to_stats:
Settings.add_to_stats = false
stats_paused_by_win = true
func _on_player_removed(player_object: PlayerObject) -> void:
Playlist.remove_player_from_list(player_object.id)
update_song_list()
func _on_change_character_requested(new_player: PlayerRow, player_name: String) -> void:
GameLog.debug("_on_player_change_character_clicked")
current_player_row = new_player
GameLog.debug("Change character for: " + player_name)
character_select_popup.show_grid(player_name)
func _on_new_character_selected(character_texture: ImageTexture) -> void:
GameLog.debug("_on_new_character_selected")
current_player_row.new_character_selected(character_texture)
###Local
var local_path: String = '/Users/sebastian/ResilioSync/Sorterat_test/Metal Gear Solid 4 - Guns of the Patriots/2-16 Metal Gear Saga.mp3'
func open() -> void:
file_dialog.popup()
func _on_file_dialog_dir_selected(path: String) -> void:
GameLog.debug(path)
dir_contents(path)
func dir_contents(path: String) -> void:
var dir: DirAccess = DirAccess.open(path)
if dir:
dir.list_dir_begin()
var file_name: String = dir.get_next()
songs.clear()
var soundtracks: Array = []
while file_name != "":
if dir.current_is_dir():
#GameLog.debug("Found directory: " + file_name)
soundtracks.append(file_name)
else:
#GameLog.debug("Found file: " + file_name)
if file_name.ends_with(".mp3"):
songs.append(path + "/" + file_name)
file_name = dir.get_next()
inspiration_list.show_soundtracks(soundtracks)
else:
GameLog.warning("An error occurred when trying to access the path.")