8 Commits
0.0.1 ... main

Author SHA1 Message Date
b4ba96cf63 #20 #24 Winnersong can be stopped. Inspirationlist speed can be changed. Some other small fixes
All checks were successful
Build / build (push) Successful in 1m36s
2025-12-27 14:05:56 +01:00
2a32cc34ef Sync result can be seen multiple times
All checks were successful
Build / build (push) Successful in 1m19s
Publish / build (push) Successful in 1m33s
2025-11-15 15:02:21 +01:00
bae5831a3e #22: Now block add player if player name is empty
All checks were successful
Build / build (push) Successful in 1m21s
#23: Add a log for when points are given to players
#25: Fixed some graphical stuff
#26: Changed so the same character can be on a song multiple times
#27: Turning off statistics after win
2025-11-15 14:53:51 +01:00
c6ed3c8e53 #17 #18: Removed Debug text in release and fixed bug with new character select screen
All checks were successful
Build / build (push) Successful in 1m31s
Publish / build (push) Successful in 1m32s
2025-11-13 18:17:25 +01:00
166705f2ab #4 #5 Added a new character select window that now fetches images from the server
All checks were successful
Build / build (push) Successful in 1m31s
Publish / build (push) Successful in 2m39s
2025-11-07 20:46:45 +01:00
734a463db9 #8: Added functionality to cache more than one song
All checks were successful
Build / build (push) Successful in 1m25s
2025-10-26 20:48:35 +01:00
4e6e37775d #2 #6 #7 Added a new sync screen that shows progress during sync
All checks were successful
Build / build (push) Successful in 1m22s
2025-09-19 22:15:37 +02:00
3e4d417b4f #1: Fixed bug with inspiration list and search list not updating on sync and server changed
All checks were successful
Build / build (push) Successful in 1m30s
2025-08-24 12:00:29 +02:00
39 changed files with 1370 additions and 287 deletions

View File

@@ -9,7 +9,7 @@ on:
branches: [main, develop]
env:
GODOT_VERSION: 4.4
GODOT_VERSION: 4.5
PROJECT_PATH: .
#GAME_VERSION: 0.0.8
#GAME_VERSION: ${{gitea.ref_name}}

View File

@@ -10,7 +10,7 @@ on:
- '*.*'
env:
GODOT_VERSION: 4.4
GODOT_VERSION: 4.5
PROJECT_PATH: .
PROJECT_NAME: MusicPlayer
GAME_VERSION: ${{gitea.ref_name}}

View File

@@ -1,19 +0,0 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://n2g8jddr85h2"
path="res://.godot/imported/01. Opening.mp3-3b470cf2b258d9ffad574f672712bdc3.mp3str"
[deps]
source_file="res://01. Opening.mp3"
dest_files=["res://.godot/imported/01. Opening.mp3-3b470cf2b258d9ffad574f672712bdc3.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@@ -1,36 +1,34 @@
extends ScrollContainer
var SCROLL = 0
var delay = 0.02 #seconds
var wait = 0
var SPEED: int = 1
var SCROLL: float = 0
var delay: float = 0.02 #seconds
var wait: float = 0
# Called when the node enters the scene tree for the first time.
func _ready():
func _ready() -> void:
wait = delay
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
func _process(delta: float) -> void:
wait -= delta
if wait < 0:
wait = delay
#SCROLL DOWN
if SCROLL == 1:
if (scroll_vertical + get_v_scroll_bar().page) < get_v_scroll_bar().max_value:
scroll_vertical += SPEED
scroll_vertical += Settings.inspiration_list_speed
else:
scroll_back_up()
#SCROLL UP
elif SCROLL == -1:
if scroll_vertical != 0:
scroll_vertical -= SPEED
scroll_vertical -= Settings.inspiration_list_speed
else:
scroll_to_bottom()
func scroll_back_up():
func scroll_back_up() -> void:
SCROLL = -1
func scroll_to_bottom():
func scroll_to_bottom() -> void:
scroll_vertical = 0 #Reset to top first.
SCROLL = 1

33
Log.tscn Normal file
View File

@@ -0,0 +1,33 @@
[gd_scene load_steps=2 format=3 uid="uid://bijh5h5yrivm3"]
[ext_resource type="Script" uid="uid://cw41y87l64qo7" path="res://log.gd" id="1_q72ua"]
[node name="Control" type="Control"]
custom_minimum_size = Vector2(700, 700)
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_q72ua")
[node name="LogPanel" type="Panel" parent="."]
unique_name_in_owner = true
visibility_layer = 513
custom_minimum_size = Vector2(700, 700)
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="LogScrollContainer" type="ScrollContainer" parent="LogPanel"]
custom_minimum_size = Vector2(700, 700)
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="LogVBoxContainer" type="VBoxContainer" parent="LogPanel/LogScrollContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(700, 700)
layout_mode = 2
theme_override_constants/separation = 1

View File

@@ -8,8 +8,6 @@ extends Control
# 386 LOC 12/6 - 2024
##TODO
# 13. Fix graphics in lists
# 14. Fix layout
# 15. Fix for local play
@onready
@@ -55,13 +53,13 @@ var sound_test_button: Button = $SoundTestButton
var sync_button: Button = $SyncButton
@onready
var sync_popup: PopupPanel = $SyncPopupPanel
var sync_window: Control = %SyncWindow
@onready
var settings_button: Button = $SettingsButton
@onready
var settings_popup: PopupPanel = $SettingsPopupPanel
var settings_window: Control = $SettingsWindow
@onready
var statistics_button: Button = $StatisticsButton
@@ -96,6 +94,9 @@ var player_container: VBoxContainer = $Players/VBoxContainer
@onready
var character_select: Control = $CharacterSelect
@onready
var new_character_select: Control = %NewCharacterSelect
@onready
var search_button: Button = $SearchButton
@@ -118,10 +119,10 @@ var coming_label: Label = $AboutPopupPanel/VBoxContainer/HBoxContainer/CommingLa
var winner_popup: PopupPanel = $WinnerPopupPanel
@onready
var winner_label: Label = $WinnerPopupPanel/WinnerLabel
var winner_label: Label = %WinnerLabel
@onready
var winner_picture: TextureRect = $WinnerPopupPanel/WinnerPicture
var winner_picture: TextureRect = %WinnerPicture
@onready
var auto_repeat_song_button: CheckButton = $RepeatSongCheckButton
@@ -129,8 +130,14 @@ var auto_repeat_song_button: CheckButton = $RepeatSongCheckButton
@onready
var music_player_container: PanelContainer = $MusicPlayer
var player := preload("res://Player.tscn")
var song_list_object := preload("res://song_list_object.tscn")
@onready
var log: Control = %Log
@onready
var debug_label: Label = $DebugLabel
var player: PackedScene = preload("res://Player.tscn")
var song_list_object: PackedScene = preload("res://song_list_object.tscn")
var songs: Array= []
var games: Array = []
@@ -138,18 +145,17 @@ var current_player: Node
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var is_debug: bool = OS.has_feature("debug")
var debug: bool = OS.has_feature("debug")
var is_mac: bool = OS.has_feature("macos")
if is_debug:
if debug:
print("is_debug")
##Settings.default_path = "http://localhost:8080"
##Settings.selected_server = 3
Settings.default_path = "http://localhost:8080"
Settings.selected_server = 3
Settings.winning_score = 5
debug_label.visible = true
Settings.is_debug = true
settings_window.set_winning_score(5)
settings_window.set_selected_server(4)
if is_mac:
print("is_mac")
next_button.pressed.connect(fetch_song.bind(false))
next_button.pressed.connect(play_next_song)
show_answer_button.pressed.connect(show_answer_pressed)
search_button.pressed.connect(show_search)
sync_button.pressed.connect(sync_games)
@@ -161,9 +167,14 @@ func _ready() -> void:
reset_points_button.pressed.connect(reset_points)
character_select.connect("character_selected", _on_character_selected)
new_character_select.connect("new_new_character_selected", _on_new_character_selected)
new_player_name_field.connect("enter_key_pressed", add_player)
music_player_container.connect("play_next_song", fetch_song.bind(false))
music_player_container.connect("play_next_song", play_next_song)
music_player_container.connect("update_song_list", update_song_list)
settings_window.connect("server_changed", server_updated)
sync_window.connect("sync_started", _on_sync_started)
sync_window.connect("sync_finished", _on_sync_finished)
add_players_button.pressed.connect(add_players)
add_player_button.pressed.connect(add_player)
@@ -172,7 +183,9 @@ func _ready() -> void:
get_suggestion_list()
fetch_song_list_at_start()
fetch_song(true)
fetch_song()
search_view.get_list_of_games()
new_character_select.load_characters()
func _input(event: InputEvent) -> void:
if event is InputEventKey and event.pressed:
@@ -194,60 +207,75 @@ func _input(event: InputEvent) -> void:
if event.alt_pressed && event.keycode == KEY_ENTER:
print("Alt + Enter pressed")
Settings.fullscreen = !Settings.fullscreen
settings_window.fullscreen_button.button_pressed = Settings.fullscreen
if Settings.fullscreen == true:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
if Settings.fullscreen == false:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
if event.alt_pressed && event.keycode == KEY_L:
log.visible = !log.visible
func server_updated() -> void:
print("server_updated")
update_from_server()
reset_points()
func update_from_server() -> void:
print("update_from_server")
search_view.get_list_of_games()
get_suggestion_list()
reset_playlist()
new_character_select.load_characters()
func repeat_song() -> void:
Settings.auto_repeat_song = !Settings.auto_repeat_song
func show_answer_pressed() -> void:
print("show_answer_pressed")
print("show_answer_pressed song_object: ", Settings.song_object_array[Settings.latest_played_song]._to_string())
Settings.song_object_array[Settings.latest_played_song].is_answered = true
Playlist.song_is_answered()
update_song_list()
func fetch_song_list_at_start() -> void:
print("fetch_song_list_at_start")
var fetch_song_list_at_start_done: Callable = func fetch_songs_at_start_done(data) -> void:
Settings.song_object_array = []
Playlist.clear_song_list()
if data == null:
Settings.latest_played_song = Settings.song_object_array.size()
Playlist.update_last_played_song()
update_song_list()
return
if typeof(data) == TYPE_ARRAY:
for d in data:
for d: Dictionary in data:
var new_song_object: SongObject = SongObject.new()
new_song_object.song_number = d.SongNo
new_song_object.game_title = d.Game
new_song_object.song_title = d.Song
new_song_object.is_answered = true
new_song_object.has_played = true
Settings.song_object_array.append(new_song_object)
Playlist.add_to_playlist(new_song_object)
else:
print("Unexpected data")
Settings.latest_played_song = Settings.song_object_array.size()
Playlist.update_last_played_song()
update_song_list()
Settings.make_request2("/music/list", fetch_song_list_at_start_done, true)
func play_next_song() -> void:
print("play_next_song ", Playlist.latest_played_song)
if Playlist.first_song_played:
Playlist.set_latest_played_song()
Playlist.first_song_played = true
music_player_container.play_song_object(Playlist.latest_played_song)
if !(Playlist.get_preloaded_songs() > 0):
next_button.disabled = true
if !Playlist.is_song_downloading:
fetch_song()
#not first "/music/addPlayed"
#"/music/rand"
#"/music/addQue"
#"/music/info"
func fetch_song(first_time: bool) -> void:
func fetch_song() -> void:
print("fetch_song")
if !first_time:
if Settings.song_object_array[Settings.latest_played_song].has_played && !Settings.song_object_array[Settings.latest_played_song].is_answered:
Settings.song_object_array[Settings.latest_played_song].is_answered = true
Settings.latest_played_song = Settings.song_object_array.size() - 1
music_player_container.play_song_object(Settings.latest_played_song)
if Settings.add_to_stats :
print("add to stats")
Settings.make_request3("/music/addPlayed")
next_button.disabled = true
Playlist.is_song_downloading = true
var url: String = ""
if Settings.use_low_played_mode:
url = "/music/rand/low"
@@ -269,8 +297,14 @@ func fetch_song(first_time: bool) -> void:
new_song_object.song_title = data_received.Song
print("new_song_object: ", new_song_object.to_string())
Settings.song_object_array.append(new_song_object)
Playlist.add_to_playlist(new_song_object)
next_button.disabled = false
if Playlist.should_preload_more_songs():
fetch_song()
else:
Playlist.is_song_downloading = false
if Settings.is_debug:
update_song_list()
Settings.make_request2("/music/info", fetch_song_info_done, true)
Settings.make_request2("/music/addQue", added_to_que_done, false)
@@ -279,13 +313,11 @@ func fetch_song(first_time: bool) -> void:
func update_song_list() -> void:
print("update_song_list")
if Settings.currently_playing_song >= 0:
game_label.text = Settings.song_object_array[Settings.currently_playing_song].get_game_title()
song_label.text = Settings.song_object_array[Settings.currently_playing_song].get_song_title()
if Playlist.currently_playing_song >= 0:
game_label.text = Playlist.get_current_game_title()
song_label.text = Playlist.get_current_song_title()
Settings.delete_children(music_list)
for s: SongObject in Settings.song_object_array:
if !s.has_played:
return
for s: SongObject in Playlist.get_playlist():
var new_song_list_object: SongListObject = song_list_object.instantiate()
new_song_list_object.song_object = s
new_song_list_object.gui_input.connect(song_object_clicked.bind(s.song_number))
@@ -293,28 +325,26 @@ func update_song_list() -> void:
func song_object_clicked(event: InputEvent, song_no: int) -> void:
if (event is InputEventMouseButton && event.pressed && event.button_index == MOUSE_BUTTON_LEFT):
print("Clicked Song Object: ", Settings.song_object_array[song_no].to_string())
if Settings.song_object_array[song_no].song == null:
print("has no song, need to download")
var song_downloaded: Callable = func song_downloaded(body: PackedByteArray) -> void:
var sound: AudioStream = AudioStreamMP3.new()
sound.data = body
Settings.song_object_array[song_no].song = sound
print("Clicked Song Object: ", Playlist.song_object_array[song_no].to_string())
if Settings.character_select_open == false:
if Playlist.get_song(song_no) == null:
print("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_container.play_song_object(song_no)
Settings.make_request2("/music?song=" + str(song_no), song_downloaded, true)
else:
print("song already downloaded")
music_player_container.play_song_object(song_no)
Settings.make_request2("/music?song=" + str(song_no), song_downloaded, true)
else:
print("song already downloaded")
music_player_container.play_song_object(song_no)
func reset_playlist() -> void:
print("reset_playlist")
var playlist_reset_done: Callable = func playlist_reset_done() -> void:
Settings.currently_playing_song = -1
Settings.latest_played_song = 0
Settings.song_object_array.clear()
Playlist.reset_playlist()
fetch_song_list_at_start()
fetch_song(true)
fetch_song()
Settings.make_request2("/music/reset", playlist_reset_done, false)
@@ -334,7 +364,7 @@ func show_about() -> void:
func show_settings() -> void:
print("show_settings")
settings_popup.visible = true
settings_window.visible = true
func get_statistics() -> void:
print("get_statistics")
@@ -343,34 +373,30 @@ func get_statistics() -> void:
func sync_games() -> void:
print("sync_games")
sync_button.disabled = true
var games_synced: Callable = func games_synced() -> void:
sync_button.disabled = false
sync_popup.visible = true
print("games_synced")
reset_playlist()
get_suggestion_list()
search_view.get_list_of_games()
sync_window.start_sync()
var new_games_synced: Callable = func new_games_synced(synced) -> void:
sync_button.disabled = false
sync_popup.visible = true
print("games_synced")
print("synced: ", synced)
reset_playlist()
get_suggestion_list()
search_view.get_list_of_games()
if Settings.quick_sync == true:
Settings.make_request2("/sync/new", new_games_synced, true)
else:
Settings.make_request2("/sync/quick", games_synced, false)
func _on_sync_started() -> void:
print("_on_sync_started")
sync_button.disabled = false
sound_test_button.disabled = true
reset_playlist_button.disabled = true
show_answer_button.disabled = true
next_button.disabled = true
func _on_sync_finished() -> void:
print("_on_sync_finished")
update_from_server()
sound_test_button.disabled = false
reset_playlist_button.disabled = false
show_answer_button.disabled = false
reset_points()
func get_suggestion_list() -> void:
print("get_suggestion_list")
var populate_list: Callable = func populate_list(array) -> void:
if typeof(array) == TYPE_ARRAY:
games = []
Settings.delete_children(inspiration_list)
games.append_array(array)
for game: String in games:
var inspiration_label: Label = Label.new()
@@ -392,16 +418,17 @@ func add_players() -> void:
func add_player() -> void:
print("add_player")
var new_player_object: PlayerObject = PlayerObject.new(new_player_name_field.text, Settings.player_array.size())
new_player_name_field.text = ""
Settings.player_array.append(new_player_object)
new_player_object.connect("first_point_triggerd", music_player_container._on_point_triggered.bind("first"))
new_player_object.connect("match_point_triggerd", music_player_container._on_point_triggered.bind("match"))
new_player_object.connect("winner_triggerd", _on_player_won.bind(new_player_object.id))
new_player_object.connect("point_given_sound", _on_make_point_given_sound)
new_player_object.connect("player_point_given", _on_point_given.bind(new_player_object.id))
new_player_object.connect("player_point_taken", _on_point_taken.bind(new_player_object.id))
load_players()
if new_player_name_field.text != "":
var new_player_object: PlayerObject = PlayerObject.new(new_player_name_field.text, Settings.player_array.size())
new_player_name_field.text = ""
Settings.player_array.append(new_player_object)
new_player_object.connect("first_point_triggerd", music_player_container._on_point_triggered.bind("first"))
new_player_object.connect("match_point_triggerd", music_player_container._on_point_triggered.bind("match"))
new_player_object.connect("winner_triggerd", _on_player_won.bind(new_player_object.id))
new_player_object.connect("point_given_sound", _on_make_point_given_sound)
new_player_object.connect("player_point_given", _on_point_given.bind(new_player_object.id))
new_player_object.connect("player_point_taken", _on_point_taken.bind(new_player_object.id))
load_players()
func load_players() -> void:
print("load_players")
@@ -421,8 +448,9 @@ func load_players() -> void:
func _on_point_given(player_given_point: int) -> void:
print("_on_point_given")
if Settings.currently_playing_song >= 0:
Settings.song_object_array[Settings.currently_playing_song].add_point(player_given_point)
log.add_log_row(Settings.player_array[player_given_point].player_name + " got a point")
if Playlist.currently_playing_song >= 0:
Playlist.add_point(player_given_point)
update_song_list()
func _on_make_point_given_sound() -> void:
@@ -430,39 +458,43 @@ func _on_make_point_given_sound() -> void:
func _on_point_taken(player_taken_point: int) -> void:
print("_on_point_taken")
log.add_log_row(Settings.player_array[player_taken_point].player_name + " lost a point")
music_player_container.play_sound_effect(preload("res://sounds/itemequip.wav"))
if Settings.currently_playing_song >= 0:
Settings.song_object_array[Settings.currently_playing_song].remove_point(player_taken_point)
if Playlist.currently_playing_song >= 0:
Playlist.remove_point(player_taken_point)
update_song_list()
func _on_player_won(winning_player_id: int) -> void:
print("_on_player_won")
winner_popup.visible = true
winner_label.text = Settings.player_array[winning_player_id].player_name + " won!!"
winner_picture.custom_minimum_size = Vector2(80, 40)
winner_picture.ignore_texture_size = true
winner_picture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT
winner_picture.custom_minimum_size = Vector2(692, 300)
winner_picture.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
winner_picture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
winner_picture.texture = Settings.player_array[winning_player_id].character
music_player_container.play_sound(preload("res://sounds/winning.mp3"))
music_player_container.play_song(preload("res://sounds/winning.mp3"))
Settings.add_to_stats = false
func _on_player_removed(player_to_remove: int) -> void:
print("_on_player_removed ", player_to_remove)
Settings.player_array.remove_at(player_to_remove)
load_players()
for song_list_object: SongObject in Settings.song_object_array:
Settings.song_object_array[song_list_object.song_number].players_given_point.remove_at(Settings.song_object_array[song_list_object.song_number].players_given_point.find(player_to_remove))
Playlist.remove_player_from_list(player_to_remove)
update_song_list()
func _on_player_change_character_clicked(new_player: Node) -> void:
print("_on_player_change_character_clicked")
current_player = new_player
character_select.visible = true
new_character_select.show_grid()
func _on_character_selected(file_name: String) -> void:
print("_on_character_selected")
character_select.visible = false
current_player._on_control_character_selected_clicked(file_name)
current_player.character_selected(file_name)
func _on_new_character_selected(character_texture: ImageTexture) -> void:
print("_on_new_character_selected")
current_player.new_character_selected(character_texture)
func show_search() -> void:
print("show_search")

View File

@@ -1,16 +1,19 @@
[gd_scene load_steps=26 format=3 uid="uid://xwq863o6uvsu"]
[gd_scene load_steps=29 format=3 uid="uid://xwq863o6uvsu"]
[ext_resource type="Script" uid="uid://b8f4g15cas2j2" path="res://MainWindow.gd" id="1_eu0t5"]
[ext_resource type="PackedScene" uid="uid://b16on0oscg1bv" path="res://CharacterSelect.tscn" id="2_76kf4"]
[ext_resource type="Script" uid="uid://elgn7gkxgagq" path="res://InsperationScrollContainer.gd" id="2_gxtxm"]
[ext_resource type="Texture2D" uid="uid://bcfmpd7h512ef" path="res://icons/person_add_light.svg" id="5_31tjv"]
[ext_resource type="PackedScene" uid="uid://ds15cgsf8vpvc" path="res://MusicPlayer.tscn" id="5_emn36"]
[ext_resource type="PackedScene" uid="uid://cdy4kvemwaiom" path="res://new_character_select.tscn" id="6_dhrvg"]
[ext_resource type="Script" uid="uid://gf1bk6xbe3j" path="res://MusicListScrollContainer.gd" id="7_dj026"]
[ext_resource type="Script" uid="uid://cgakje8gb37tf" path="res://PlayerNameField.gd" id="7_qsdfy"]
[ext_resource type="Theme" uid="uid://rxexo3ur85as" path="res://LightGrayTheme.tres" id="7_wxbv6"]
[ext_resource type="PackedScene" uid="uid://bxydgil1yifps" path="res://SearchWindow.tscn" id="9_5ijvr"]
[ext_resource type="PackedScene" uid="uid://dpdem7pdxweb5" path="res://SyncWindow.tscn" id="10_yxw0b"]
[ext_resource type="Texture2D" uid="uid://r4as0nmtoa7p" path="res://noCharacter.png" id="11_1qef0"]
[ext_resource type="PackedScene" uid="uid://dldpeo5y3l5hq" path="res://SettingsWindow.tscn" id="11_k62u5"]
[ext_resource type="PackedScene" uid="uid://bijh5h5yrivm3" path="res://Log.tscn" id="14_26rwn"]
[sub_resource type="LabelSettings" id="LabelSettings_ychxr"]
font_size = 25
@@ -77,7 +80,7 @@ offset_bottom = 56.0
[node name="Title" type="Label" parent="."]
texture_filter = 1
layout_mode = 2
layout_mode = 0
offset_left = 64.0
offset_top = 12.0
offset_right = 369.0
@@ -88,7 +91,7 @@ label_settings = SubResource("LabelSettings_ychxr")
[node name="Open" type="Button" parent="."]
visible = false
layout_mode = 2
layout_mode = 0
offset_left = 1296.0
offset_top = 66.0
offset_right = 1346.0
@@ -314,6 +317,7 @@ offset_top = 944.0
offset_right = 368.0
offset_bottom = 975.0
focus_mode = 0
disabled = true
action_mode = 0
shortcut = SubResource("Shortcut_d6fml")
text = "Randomize new track"
@@ -371,21 +375,34 @@ offset_top = 96.0
offset_right = 56.0
offset_bottom = 96.0
[node name="SyncPopupPanel" type="PopupPanel" parent="."]
initial_position = 2
size = Vector2i(140, 70)
[node name="SyncWindow" parent="." instance=ExtResource("10_yxw0b")]
unique_name_in_owner = true
visible = false
layout_mode = 1
offset_left = 401.0
offset_top = 153.0
offset_right = 401.0
offset_bottom = 153.0
[node name="Label" type="Label" parent="SyncPopupPanel"]
texture_filter = 1
offset_left = 4.0
offset_top = 4.0
offset_right = 136.0
offset_bottom = 66.0
text = "Games synced!"
horizontal_alignment = 1
vertical_alignment = 1
[node name="SettingsWindow" parent="." instance=ExtResource("11_k62u5")]
visible = false
layout_mode = 1
offset_left = 720.0
offset_top = 153.0
offset_right = 720.0
offset_bottom = 153.0
[node name="NewCharacterSelect" parent="." instance=ExtResource("6_dhrvg")]
unique_name_in_owner = true
visible = false
layout_mode = 1
offset_left = 420.0
offset_top = 165.0
offset_right = 1572.0
offset_bottom = 805.0
[node name="StatisticsPopupPanel" type="PopupPanel" parent="."]
oversampling_override = 1.0
initial_position = 2
size = Vector2i(450, 100)
@@ -409,6 +426,7 @@ horizontal_alignment = 1
vertical_alignment = 1
[node name="AboutPopupPanel" type="PopupPanel" parent="."]
oversampling_override = 1.0
initial_position = 2
size = Vector2i(848, 710)
@@ -469,35 +487,40 @@ Change some buttons to icons
Add shortcuts"
autowrap_mode = 2
[node name="SettingsPopupPanel" type="PopupPanel" parent="."]
initial_position = 2
size = Vector2i(268, 233)
[node name="SettingsWindow" parent="SettingsPopupPanel" instance=ExtResource("11_k62u5")]
offset_left = 4.0
offset_top = 4.0
offset_right = 264.0
offset_bottom = 354.0
[node name="WinnerPopupPanel" type="PopupPanel" parent="."]
oversampling_override = 1.0
initial_position = 2
size = Vector2i(600, 350)
size = Vector2i(700, 350)
[node name="WinnerPicture" type="TextureRect" parent="WinnerPopupPanel"]
[node name="Panel" type="Panel" parent="WinnerPopupPanel"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_top = 4.0
offset_right = 596.0
offset_right = 696.0
offset_bottom = 346.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="WinnerPopupPanel/Panel"]
layout_mode = 0
offset_right = 692.0
offset_bottom = 342.0
alignment = 1
[node name="WinnerPicture" type="TextureRect" parent="WinnerPopupPanel/Panel/VBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(692, 300)
layout_mode = 2
texture = ExtResource("11_1qef0")
expand_mode = 2
stretch_mode = 4
expand_mode = 3
stretch_mode = 5
[node name="WinnerLabel" type="Label" parent="WinnerPopupPanel"]
[node name="WinnerLabel" type="Label" parent="WinnerPopupPanel/Panel/VBoxContainer"]
unique_name_in_owner = true
texture_filter = 1
offset_left = 4.0
offset_top = 4.0
offset_right = 596.0
offset_bottom = 346.0
layout_mode = 2
text = "Sansan won!!"
label_settings = SubResource("LabelSettings_hr75l")
horizontal_alignment = 1
@@ -513,4 +536,26 @@ focus_mode = 0
action_mode = 0
text = "Auto repeat"
[node name="DebugLabel" type="Label" parent="."]
visible = false
layout_mode = 0
offset_left = 974.0
offset_top = 904.0
offset_right = 1014.0
offset_bottom = 927.0
scale = Vector2(3, 3)
text = "DEBUG"
horizontal_alignment = 1
vertical_alignment = 1
autowrap_mode = 2
[node name="Log" parent="." instance=ExtResource("14_26rwn")]
unique_name_in_owner = true
visible = false
layout_mode = 1
offset_left = 562.0
offset_top = 132.0
offset_right = 1262.0
offset_bottom = 832.0
[connection signal="dir_selected" from="FileDialog" to="." method="_on_file_dialog_dir_selected"]

View File

@@ -151,10 +151,8 @@ func play_sound(sound_name: AudioStream) -> void:
if stream != null:
music_time_label.text = format_text(progress_slider.value, stream.get_length())
func play_song(body: PackedByteArray) -> void:
var sound: AudioStream = AudioStreamMP3.new()
sound.data = body
audio_player.stream = sound
func play_song(song: AudioStream) -> void:
audio_player.stream = song
audio_player.play()
sound_player.stop()
song_finished = false
@@ -168,7 +166,7 @@ func play_song_object(song_object_no: int) -> void:
if audio_player.is_playing():
audio_player.stop()
await get_tree().create_timer(0.5).timeout
audio_player.stream = Settings.song_object_array[song_object_no].song
audio_player.stream = Playlist.get_song(song_object_no)
sound_player.stop()
audio_player.play()
song_finished = false
@@ -176,17 +174,21 @@ func play_song_object(song_object_no: int) -> void:
stream = audio_player.stream
progress_slider.max_value = round(stream.get_length())
progress_slider.tick_count = round(stream.get_length() / 60)
Settings.currently_playing_song = song_object_no
Settings.unset_is_playing()
Playlist.set_currently_playing_song(song_object_no)
Playlist.unset_is_playing()
if !Settings.hide_next_track:
print("Show answer now!!")
Settings.song_object_array[song_object_no].is_answered = true
Settings.song_object_array[song_object_no].has_played = true
Settings.song_object_array[song_object_no].is_playing = true
Playlist.song_is_answered(song_object_no)
Playlist.song_has_played(song_object_no)
Playlist.song_is_playing(song_object_no)
update_song_list.emit()
func get_sound_test_song() -> void:
Settings.make_request2("/music/soundTest", play_song, true)
var test_sound: Callable = func test_sound(body: PackedByteArray) -> void:
var sound: AudioStream = AudioStreamMP3.new()
sound.data = body
play_song(sound)
Settings.make_request2("/music/soundTest", test_sound, true)
##### LOCAL
var local_path: String = '/Users/sebastian/ResilioSync/Sorterat_test/Metal Gear Solid 4 - Guns of the Patriots/2-16 Metal Gear Saga.mp3'
@@ -205,4 +207,4 @@ func play_local_song() -> void:
play_sound(load_mp3(local_path))
func sound_test_local() -> void:
play_sound(preload("res://01. Opening.mp3"))
play_sound(preload("res://sounds/01. Opening.mp3"))

View File

@@ -1,7 +1,7 @@
[gd_scene load_steps=10 format=3 uid="uid://ds15cgsf8vpvc"]
[ext_resource type="Script" uid="uid://d1v0rquma6nt8" path="res://MusicPlayer.gd" id="1_t24ra"]
[ext_resource type="AudioStream" uid="uid://n2g8jddr85h2" path="res://01. Opening.mp3" id="2_xti80"]
[ext_resource type="AudioStream" uid="uid://n2g8jddr85h2" path="res://sounds/01. Opening.mp3" id="2_xti80"]
[ext_resource type="Texture2D" uid="uid://comxqfiykp54f" path="res://icons/play_icon_light.svg" id="3_6g308"]
[ext_resource type="Texture2D" uid="uid://ccb6rvbldlgdg" path="res://icons/reload_light_icon.svg" id="4_jleuo"]
[ext_resource type="PackedScene" uid="uid://w400rnew7453" path="res://volume_slider.tscn" id="5_iifuj"]
@@ -86,7 +86,7 @@ scrollable = false
[node name="MusicTimeLabel" type="Label" parent="MusicPlayerContainer"]
layout_mode = 2
text = "1:00 / 3:00"
text = "0:00 / 0:00"
[node name="VolumeSlider" parent="MusicPlayerContainer" instance=ExtResource("5_iifuj")]
custom_minimum_size = Vector2(100, 0)

View File

@@ -56,15 +56,20 @@ func minus_point() -> void:
func change_character() -> void:
change_character_clicked.emit()
func _on_control_character_selected_clicked(file_name: String) -> void:
func character_selected(file_name: String) -> void:
print("Back in player list with: " + file_name)
Settings.player_array[id].character = load("res://characters/" + file_name)
set_player_character()
func new_character_selected(character_texture: ImageTexture) -> void:
print("Back in player list with new")
Settings.player_array[id].character = character_texture
set_player_character()
func set_player_character() -> void:
character.custom_minimum_size = Vector2(80, 40)
character.ignore_texture_size = true
character.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT
character.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT_CENTERED
character.texture_normal = Settings.player_array[id].character
func update_score() -> void:

View File

@@ -42,7 +42,7 @@ theme_override_styles/panel = SubResource("StyleBoxFlat_821k2")
custom_minimum_size = Vector2(130, 40)
layout_mode = 2
size_flags_vertical = 1
text = "Sansansans: 100"
text = ": 0"
vertical_alignment = 1
[node name="Panel3" type="Panel" parent="HBoxContainer"]

View File

@@ -21,7 +21,7 @@ var is_first_point: bool = true
var character: Texture = load("res://noCharacter.png")
func _init(new_name: String, new_id: int):
func _init(new_name: String, new_id: int) -> void:
player_name = new_name
id = new_id
player_score = 0

View File

@@ -1,27 +1,31 @@
extends Control
@onready
var search_list := $ScrollContainer/VBoxContainer
var search_list: VBoxContainer = $ScrollContainer/VBoxContainer
@onready
var clear_button := $ClearButton
var search_panel: Panel = %SearchPanel
@onready
var close_button := $CloseButton
var clear_button: Button = $ClearButton
@onready
var search_bar := $Searchbar
var close_button: Button = $CloseButton
var games := []
@onready
var search_bar: TextEdit = $Searchbar
var games: Array = []
var regex: RegEx
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
get_list_of_games()
clear_button.pressed.connect(clear)
close_button.pressed.connect(close)
search_bar.grab_focus()
search_bar.text_changed.connect(search)
visibility_changed.connect(focus)
regex = RegEx.new()
func focus() -> void:
if self.visible == true:
@@ -35,21 +39,25 @@ func close() -> void:
func search() -> void:
print(search_bar.text)
Settings.delete_children(search_list)
var search_text: String = search_bar.text.to_lower()
for game: String in games:
if is_match_exact(search_bar.text, game):
if is_match_exact(search_text, game):
add_game(game)
var clean_search_text: String = clean_search_term(search_text)
for game: String in games:
if is_match_contains(clean_search_text, clean_game(game)):
add_game(game)
for game: String in games:
if is_match_contains(clean_term(search_bar.text), clean_term(game)):
add_game(game)
for game: String in games:
if is_match_regex(clean_term(search_bar.text), clean_term(game)):
if is_match_regex(clean_search_text, clean_game(game)):
add_game(game)
func clean_term(term: String) -> String:
func clean_search_term(term: String) -> String:
return term.replace(" ", "").replace("é", "e").replace("+", "plus").replace("&", "and").replace("'n", "and")
func clean_game(term: String) -> String:
return term.replace(" ", "").replace("é", "e").replace("+", "plus").replace("&", "and").replace("'n", "and").to_lower()
func is_match_exact(search_term: String, game_name: String) -> bool:
search_term = search_term.to_lower()
game_name = game_name.to_lower()
if search_term == "":
@@ -76,7 +84,7 @@ func is_match_regex(search_term: String, game_name: String) -> bool:
return false
func add_game(game: String) -> void:
var label := Label.new()
var label: Label = Label.new()
label.text = game
print("game: " + game)
label.autowrap_mode = TextServer.AUTOWRAP_WORD
@@ -91,20 +99,21 @@ func check_if_game_exists(game: String) -> bool:
return game_exists
func compile_regex(search_term: String) -> RegEx:
var regex = RegEx.new()
var regText: String = ".*"
for letter in search_term:
for letter: String in search_term:
regText += letter + ".*"
regex.compile(regText)
return regex
func get_list_of_games() -> void:
var handle_games = func handle_games(array):
print("get_list_of_games")
var handle_games: Callable = func handle_games(array: Array) -> void:
if typeof(array) == TYPE_ARRAY:
games = []
Settings.delete_children(search_list)
games.append_array(array)
for game in games:
var label := Label.new()
for game: String in games:
var label: Label = Label.new()
label.text = game
label.autowrap_mode = TextServer.AUTOWRAP_WORD
search_list.add_child(label)
@@ -112,8 +121,58 @@ func get_list_of_games() -> void:
print("Unexpected data")
Settings.make_request2("/music/all/order", handle_games, true)
func _input(event: InputEvent) -> void:
if self.visible == true:
if event is InputEventMouseButton && event.is_pressed():
var evLocal: InputEvent = make_input_local(event)
if !Rect2(Vector2(0, 0), search_panel.size).has_point(evLocal.position):
self.visible = false
func clear() -> void:
search_bar.text = ""
search()
search_bar.grab_focus()
func old_search() -> void:
print(search_bar.text)
Settings.delete_children(search_list)
for game: String in games:
if old_is_match_exact(search_bar.text, game):
add_game(game)
for game: String in games:
if is_match_contains(clean_term(search_bar.text), clean_term(game)):
add_game(game)
for game: String in games:
if old_is_match_regex(clean_term(search_bar.text), clean_term(game)):
add_game(game)
func clean_term(term: String) -> String:
return term.replace(" ", "").replace("é", "e").replace("+", "plus").replace("&", "and").replace("'n", "and").to_lower()
func old_is_match_exact(search_term: String, game_name: String) -> bool:
search_term = search_term.to_lower()
game_name = game_name.to_lower()
if search_term == "":
return true
elif game_name.contains(search_term):
return true
else:
return false
func old_is_match_regex(search_term: String, game_name: String) -> bool:
if search_term == "":
return true
elif compile_regex(search_term).search(game_name):
return true
else:
return false
func old_compile_regex(search_term: String) -> RegEx:
var regex = RegEx.new()
var regText: String = ".*"
for letter in search_term:
regText += letter + ".*"
regex.compile(regText)
return regex

View File

@@ -11,7 +11,8 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_m7bij")
[node name="Panel" type="Panel" parent="."]
[node name="SearchPanel" type="Panel" parent="."]
unique_name_in_owner = true
layout_mode = 0
offset_right = 1152.0
offset_bottom = 640.0
@@ -30,7 +31,7 @@ text = "Clear"
[node name="CloseButton" type="Button" parent="."]
texture_filter = 1
layout_mode = 2
layout_mode = 0
offset_left = 1032.0
offset_top = 24.0
offset_right = 1082.0
@@ -51,7 +52,7 @@ scale = Vector2(2, 2)
placeholder_text = "Search"
[node name="ScrollContainer" type="ScrollContainer" parent="."]
layout_mode = 2
layout_mode = 0
offset_top = 128.0
offset_right = 576.0
offset_bottom = 384.0

View File

@@ -2,11 +2,11 @@ extends Node
var default_path: String = "https://music.sanplex.tech"
var selected_server: int = 0
#var default_path: String = "https://tmusic.sanplex.tech"
#var selected_server: int = 1
var is_local: bool = false
var is_debug: bool = false
var stop_after_current: bool = true
var auto_repeat_song: bool = false
var hide_next_track: bool = true
@@ -14,30 +14,47 @@ var add_to_stats: bool = true
var use_low_played_mode: bool = false
var winning_score: int = 20
var fullscreen: bool = false
var quick_sync: bool = true
var play_local: bool = false
var inspiration_list_speed: int = 1
var player_array: Array[PlayerObject]
var song_object_array: Array[SongObject] = []
var latest_played_song: int = 0
var currently_playing_song: int = -1
var edit_players: bool = false
var currently_syncing: bool = false
var character_select_open: bool = false
var version: String = "1.5.0"
var version: String = "1.7.5"
var whats_new: String = "Changelog:
1.7.5:
#20: The winner song can now be stopped
#24: The speed of the inspiration list can now be changed
1.7.0:
#22: Now block add player if player name is empty
#23: Add a log for when points are given to players
#25: Fixed some graphical stuff
#26: Changed so the same character can be on a song multiple times
#27: Turning off statistics after win
1.6.1:
#17: Removed Debug text in release
#18: Fixed bug with new character select screen
1.6.0:
#1: Fixed bug with inspiration list not reloading after sync
#2: New dialog for sync
#4: Now downloads characters from the server
#5: New character select screen
#6: Now show progress during sync
#7: Blocking all requests to the server during sync
#8: Added functionality to cache more than one song
1.5.0: Made big changes to players and the song list and how the local song list works
0.9.0-Beta: Fixed settings and updated the player view
0.8.0-Beta: Fixed reset buttons and some other small things
0.7.8-Beta: Added shortcuts. Added dialog for winner. Started cleaning code.
0.7.5-Beta: Added settings menu, most things don't do anythig yet
0.7.5-Beta: Added settings menu, most things don't do anything yet
0.7-Beta: Can now hop between songs"
var whats_left: String = "Things left to do:
Fix graphics in lists
Fix layout
Fix for local play
Change some buttons to icons"
Fix for local play"
var shortcuts: String = "Shortcuts:
Alt + S = Search
@@ -73,7 +90,6 @@ func make_request2(address: String, func_name: Callable, expect_data: bool) -> v
elif func_name != null:
func_name.call(data_received)
else:
print("song_received")
print("data_received type: ", type_string(typeof(body)))
func_name.call(body)
@@ -86,7 +102,7 @@ func make_request2(address: String, func_name: Callable, expect_data: bool) -> v
var request_error: int = http_request.request(default_path + address)
if request_error != OK:
push_error("An error occurred in the HTTP request.")
func make_request3(address: String) -> void:
var error_handling: Callable = func(_result: int, response_code: int, _headers: PackedStringArray, _body: PackedByteArray) -> void:
print("request done to address: ", default_path + address)
@@ -100,6 +116,21 @@ func make_request3(address: String) -> void:
var request_error: int = http_request.request(default_path + address)
if request_error != OK:
push_error("An error occurred in the HTTP request.")
func make_put_request(address: String) -> void:
var error_handling: Callable = func(_result: int, response_code: int, _headers: PackedStringArray, _body: PackedByteArray) -> void:
print("request done to address: ", default_path + address)
if response_code != 200:
print("Error: " + str(response_code))
var http_request: HTTPRequest = HTTPRequest.new()
add_child(http_request)
http_request.request_completed.connect(error_handling)
# Perform a GET request. The URL below returns JSON as of writing.
var headers: PackedStringArray = ["Content-Type: application/json"]
var request_error: int = http_request.request(default_path + address, headers, HTTPClient.METHOD_PUT)
if request_error != OK:
push_error("An error occurred in the HTTP request.")
func delete_children(node: Node) -> void:
for n: Node in node.get_children():
@@ -117,7 +148,3 @@ func delete_player_children(node: Node) -> void:
else:
node.remove_child(n)
n.queue_free()
func unset_is_playing() -> void:
for song_object: SongObject in song_object_array:
song_object.is_playing = false

View File

@@ -1,49 +1,74 @@
extends VBoxContainer
extends Control
@onready
var stop_after_current_button := $StopAfterCurrentCheckButton
var settings_panel: Panel = %SettingsPanel
@onready
var hide_next_track_button := $HideNextTrackCheckButton
var stop_after_current_button: CheckButton = %StopAfterCurrentCheckButton
@onready
var add_to_database_button := $AddToDatabaseCheckButton
var hide_next_track_button: CheckButton = %HideNextTrackCheckButton
@onready
var low_played_button := $LowPlayedCheckButton
var add_to_database_button: CheckButton = %AddToDatabaseCheckButton
@onready
var score_label := $HBoxContainer/ScoreLabel
var low_played_button: CheckButton = %LowPlayedCheckButton
@onready
var lower_winning_score_button := $HBoxContainer/LowerButton
var score_label: Label = %ScoreLabel
@onready
var increase_winning_score_button := $HBoxContainer/IncreaseButton
var lower_winning_score_button: Button = %LowerButton
@onready
var select_server_button := $SelectServerButton
var increase_winning_score_button: Button = %IncreaseButton
@onready
var fullscreen_button := $FullscreenButton
var cache_label: Label = %CacheLabel
@onready
var quick_sync_button := $QuickSyncButton
var lower_cache_button: Button = %LowerCacheButton
@onready
var local_button := $LocalButton
var increase_cache_button: Button = %IncreaseCacheButton
@onready
var inspiration_speed_label: Label = %InspirationListSpeedLabel
@onready
var lower_inspiration_speed_button: Button = %LowerInspirationSpeedButton
@onready
var increase_inspiration_speed_button: Button = %IncreaseInspirationSpeedButton
@onready
var select_server_button: OptionButton = %SelectServerButton
@onready
var fullscreen_button: CheckButton = %FullscreenButton
@onready
var local_button: CheckButton = %LocalButton
signal server_changed
# Called when the node enters the scene tree for the first time.
func _ready():
func _ready() -> void:
fullscreen_button.button_pressed = Settings.fullscreen
select_server_button.selected = Settings.selected_server
stop_after_current_button.pressed.connect(stop_after_current)
hide_next_track_button.pressed.connect(hide_next_track)
add_to_database_button.pressed.connect(add_to_database)
low_played_button.pressed.connect(low_played)
lower_winning_score_button.pressed.connect(lower_winning_score)
increase_winning_score_button.pressed.connect(increase_winning_score)
#select_server_button.pressed.connect(select_server)
lower_cache_button.pressed.connect(lower_cache)
increase_cache_button.pressed.connect(increase_cache)
lower_inspiration_speed_button.pressed.connect(lower_inspiration_speed)
increase_inspiration_speed_button.pressed.connect(increase_inspiration_speed)
fullscreen_button.pressed.connect(fullscreen)
quick_sync_button.pressed.connect(quick_sync)
local_button.pressed.connect(local_play)
stop_after_current_button.button_pressed = Settings.stop_after_current
@@ -51,48 +76,90 @@ func _ready():
add_to_database_button.button_pressed = Settings.add_to_stats
low_played_button.button_pressed = Settings.use_low_played_mode
score_label.text = str(Settings.winning_score)
cache_label.text = str(Playlist.number_of_tracks_to_preload)
inspiration_speed_label.text = str(Settings.inspiration_list_speed)
fullscreen_button.button_pressed = Settings.fullscreen
quick_sync_button.button_pressed = Settings.quick_sync
select_server_button.select(Settings.selected_server)
select_server_button.item_selected.connect(select_server)
func _input(event: InputEvent) -> void:
if self.visible == true:
if event is InputEventMouseButton && event.is_pressed():
var evLocal: InputEvent = make_input_local(event)
if !Rect2(Vector2(0, 0), settings_panel.size).has_point(evLocal.position):
self.visible = false
func fullscreen() -> void:
Settings.fullscreen = !Settings.fullscreen
if Settings.fullscreen == true:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
if Settings.fullscreen == false:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
func quick_sync() -> void:
Settings.quick_sync = !Settings.quick_sync
func local_play():
func local_play() -> void:
Settings.play_local = !Settings.play_local
func stop_after_current():
func stop_after_current() -> void:
Settings.stop_after_current = !Settings.stop_after_current
func hide_next_track():
func hide_next_track() -> void:
Settings.hide_next_track = !Settings.hide_next_track
func add_to_database():
func add_to_database() -> void:
Settings.add_to_stats = !Settings.add_to_stats
func low_played():
func low_played() -> void:
Settings.use_low_played_mode = !Settings.use_low_played_mode
func lower_winning_score():
func lower_winning_score() -> void:
Settings.winning_score -= 1
score_label.text = str(Settings.winning_score)
func increase_winning_score():
func increase_winning_score() -> void:
Settings.winning_score += 1
score_label.text = str(Settings.winning_score)
func set_winning_score(new_score: int) -> void:
Settings.winning_score = new_score
score_label.text = str(Settings.winning_score)
func lower_cache() -> void:
Playlist.number_of_tracks_to_preload -= 1
if Playlist.number_of_tracks_to_preload < 1:
Playlist.number_of_tracks_to_preload = 1
cache_label.text = str(Playlist.number_of_tracks_to_preload)
func increase_cache() -> void:
Playlist.number_of_tracks_to_preload += 1
cache_label.text = str(Playlist.number_of_tracks_to_preload)
func lower_inspiration_speed() -> void:
Settings.inspiration_list_speed -= 1
if Settings.inspiration_list_speed < 1:
Settings.inspiration_list_speed = 1
inspiration_speed_label.text = str(Settings.inspiration_list_speed)
func increase_inspiration_speed() -> void:
Settings.inspiration_list_speed += 1
inspiration_speed_label.text = str(Settings.inspiration_list_speed )
func select_server(new_server: int) -> void:
print("select_server")
Settings.default_path = select_server_button.get_item_text(new_server)
Settings.selected_server = new_server
print("Settings.default_path: " + Settings.default_path)
print("Settings.selected_server: " + str(Settings.selected_server))
print("new_server: " + str(new_server))
print("select_server_button.get_item_text(new_server): " + select_server_button.get_item_text(new_server))
server_changed.emit()
func set_selected_server(new_server: int) -> void:
print("set_selected_server")
select_server_button.select(new_server)
Settings.default_path = select_server_button.get_item_text(new_server)
Settings.selected_server = new_server
print("Settings.default_path: " + Settings.default_path)
print("Settings.selected_server: " + str(Settings.selected_server))
print("new_server: " + str(new_server))
print("select_server_button.get_item_text(new_server): " + select_server_button.get_item_text(new_server))
server_changed.emit()

View File

@@ -5,101 +5,185 @@
[sub_resource type="LabelSettings" id="LabelSettings_3xrlm"]
font_size = 25
[node name="VBoxContainer" type="VBoxContainer"]
clip_contents = true
[node name="SettingsControl" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_bt55j")
[node name="Label" type="Label" parent="."]
[node name="SettingsPanel" type="Panel" parent="."]
unique_name_in_owner = true
layout_mode = 0
offset_right = 500.0
offset_bottom = 640.0
[node name="ScrollContainer" type="ScrollContainer" parent="SettingsPanel"]
layout_mode = 0
offset_right = 500.0
offset_bottom = 640.0
[node name="VBoxContainer" type="VBoxContainer" parent="SettingsPanel/ScrollContainer"]
clip_contents = true
layout_mode = 2
size_flags_horizontal = 3
[node name="Label" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Settings"
label_settings = SubResource("LabelSettings_3xrlm")
horizontal_alignment = 1
[node name="StopAfterCurrentCheckButton" type="CheckButton" parent="."]
[node name="StopAfterCurrentCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
button_pressed = true
action_mode = 0
text = "Stop after current"
[node name="HideNextTrackCheckButton" type="CheckButton" parent="."]
[node name="HideNextTrackCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
button_pressed = true
action_mode = 0
text = "Hide next track"
[node name="AddToDatabaseCheckButton" type="CheckButton" parent="."]
[node name="AddToDatabaseCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
action_mode = 0
text = "Turn on played to database"
[node name="LowPlayedCheckButton" type="CheckButton" parent="."]
[node name="LowPlayedCheckButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
action_mode = 0
text = "Use low played mode"
[node name="HBoxContainer" type="HBoxContainer" parent="."]
[node name="HBoxContainer" type="HBoxContainer" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
layout_mode = 2
[node name="Label2" type="Label" parent="HBoxContainer"]
[node name="Label2" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "Winning Score: "
[node name="ScoreLabel" type="Label" parent="HBoxContainer"]
[node name="ScoreLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "20"
[node name="LowerButton" type="Button" parent="HBoxContainer"]
[node name="LowerButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 2.08165e-12)
layout_mode = 2
focus_mode = 0
action_mode = 0
text = "-1"
[node name="IncreaseButton" type="Button" parent="HBoxContainer"]
[node name="IncreaseButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 2.08165e-12)
layout_mode = 2
focus_mode = 0
action_mode = 0
text = "+1"
[node name="SelectServerButton" type="OptionButton" parent="."]
[node name="CacheHBoxContainer" type="HBoxContainer" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
layout_mode = 2
[node name="CacheTitleLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer"]
layout_mode = 2
text = "Predownload songs: "
[node name="CacheLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "1"
[node name="LowerCacheButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 2.08165e-12)
layout_mode = 2
focus_mode = 0
action_mode = 0
text = "-1"
[node name="IncreaseCacheButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/CacheHBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 2.08165e-12)
layout_mode = 2
focus_mode = 0
action_mode = 0
text = "+1"
[node name="InspirationHBoxContainer" type="HBoxContainer" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
layout_mode = 2
[node name="InspirationListSpeedTitle" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer"]
layout_mode = 2
text = "Inspiration List Speed: "
[node name="InspirationListSpeedLabel" type="Label" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "1"
[node name="LowerInspirationSpeedButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 2.08165e-12)
layout_mode = 2
focus_mode = 0
action_mode = 0
text = "-1"
[node name="IncreaseInspirationSpeedButton" type="Button" parent="SettingsPanel/ScrollContainer/VBoxContainer/InspirationHBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 2.08165e-12)
layout_mode = 2
focus_mode = 0
action_mode = 0
text = "+1"
[node name="SelectServerButton" type="OptionButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
selected = 0
item_count = 4
item_count = 5
popup/item_0/text = "https://music.sanplex.tech"
popup/item_0/id = 1
popup/item_1/text = "https://tmusic.sanplex.tech"
popup/item_1/id = 1
popup/item_2/text = "http://192.168.86.100:8085"
popup/item_2/id = 2
popup/item_3/text = "http://localhost:8080"
popup/item_3/id = 3
popup/item_1/id = 2
popup/item_2/text = "https://rmusic.sanplex.tech"
popup/item_2/id = 3
popup/item_3/text = "https://old-music.sanplex.tech"
popup/item_3/id = 4
popup/item_4/text = "http://localhost:8080"
popup/item_4/id = 5
[node name="FullscreenButton" type="CheckButton" parent="."]
[node name="FullscreenButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
text = "Fullscreen"
[node name="QuickSyncButton" type="CheckButton" parent="."]
[node name="QuickSyncButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
visible = false
layout_mode = 2
size_flags_horizontal = 0
button_pressed = true
action_mode = 0
text = "Quick sync"
[node name="LocalButton" type="CheckButton" parent="."]
[node name="LocalButton" type="CheckButton" parent="SettingsPanel/ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 0
disabled = true

View File

@@ -31,7 +31,10 @@ func get_song_title() -> String:
return "??????"
func get_song_info() -> String:
if is_answered:
if Settings.is_debug:
var format_string: String = "%d. %s - %s | played: %s | answered: %s"
return format_string % [(song_number + 1), game_title, song_title, has_played, is_answered]
elif is_answered:
var format_string: String = "%d. %s - %s"
return format_string % [(song_number + 1), game_title, song_title]
else:
@@ -39,8 +42,7 @@ func get_song_info() -> String:
func add_point(id: int) -> void:
print("add_point")
if !players_given_point.has(id):
players_given_point.append(id)
players_given_point.append(id)
players_given_point.sort()
func remove_point(id: int) -> void:

150
SyncWindow.tscn Normal file
View File

@@ -0,0 +1,150 @@
[gd_scene load_steps=3 format=3 uid="uid://dpdem7pdxweb5"]
[ext_resource type="Script" uid="uid://c3ejukwth512a" path="res://sync_window.gd" id="1_8ba47"]
[sub_resource type="LabelSettings" id="LabelSettings_anbfi"]
font_size = 25
[node name="Control" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_8ba47")
[node name="SyncPanel" type="Panel" parent="."]
unique_name_in_owner = true
layout_mode = 0
offset_right = 1152.0
offset_bottom = 640.0
[node name="ScrollContainer" type="ScrollContainer" parent="SyncPanel"]
layout_mode = 0
offset_right = 1152.0
offset_bottom = 640.0
[node name="SyncVBoxContainer" type="VBoxContainer" parent="SyncPanel/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="SyncTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 0
text = "Sync"
label_settings = SubResource("LabelSettings_anbfi")
horizontal_alignment = 1
[node name="NoChangesLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_vertical = 0
text = "No changes since last sync"
label_settings = SubResource("LabelSettings_anbfi")
horizontal_alignment = 1
[node name="ProgressHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
[node name="SyncProgressBar" type="ProgressBar" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/ProgressHBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(1000, 0)
layout_mode = 2
size_flags_horizontal = 6
step = 1.0
rounded = true
[node name="SyncHBoxContainer" type="HBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 4
theme_override_constants/separation = 30
[node name="VSeparator6" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
layout_mode = 2
[node name="GamesAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesAddedVBox"]
layout_mode = 2
text = "GamesAdded"
horizontal_alignment = 1
[node name="GamesAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesReAddedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesReAddedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesReAddedVBox"]
layout_mode = 2
text = "GamesReAdded"
[node name="GamesReAddedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesChangedTitleVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesChangedTitleLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesChangedTitleVBox"]
layout_mode = 2
text = "GamesChangedTitle"
[node name="GamesChangedTitleSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesChangedContentVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesChangedContentLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesChangedContentVBox"]
layout_mode = 2
text = "GamesChangedContent"
[node name="GamesChangedContentSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesRemovedVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="GamesRemovedLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer/GamesRemovedVBox"]
layout_mode = 2
text = "GamesRemoved"
[node name="GamesRemovedSeparator" type="VSeparator" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/SyncHBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="SyncTime" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Sync time: "
horizontal_alignment = 1
[node name="CatchedErrorsVBox" type="VBoxContainer" parent="SyncPanel/ScrollContainer/SyncVBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
[node name="CatchedErrorsLabel" type="Label" parent="SyncPanel/ScrollContainer/SyncVBoxContainer/CatchedErrorsVBox"]
layout_mode = 2
text = "CatchedErrors"
horizontal_alignment = 1
[node name="SyncTimer" type="Timer" parent="."]
unique_name_in_owner = true

46
character.gd Normal file
View File

@@ -0,0 +1,46 @@
class_name Character
extends Control
@onready
var panel: Panel = $Panel
@onready
var character_image: TextureRect = %CharacterTextureRect
@onready
var character_name_label: Label = %CharacterName
signal new_character_selected(img_texture: ImageTexture)
func set_character_name(character_name: String) -> void:
panel.size = Vector2(240, 145)
#margin.size = Vector2(240, 145)
#margin set margin 15, 10, 15, 0
character_name_label.text = character_name.split(".")[0]
character_name_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
var image_fetched: Callable = func image_fetched(image: PackedByteArray) -> void:
var img: Image = Image.new()
var err: Error = img.load_png_from_buffer(image)
if err != OK:
print(err)
var err2: Error = img.load_jpg_from_buffer(image)
if err2 != OK:
print(err2)
var new_image: ImageTexture = ImageTexture.new()
new_image.set_image(img)
character_image.custom_minimum_size = Vector2(200, 100)
character_image.size = Vector2(200, 100)
character_image.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
character_image.size_flags_vertical = Control.SIZE_SHRINK_CENTER
character_image.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
character_image.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
character_image.texture = new_image
Settings.make_request2("/character?name=" + character_name.uri_encode(), image_fetched, true)
func _input(event: InputEvent) -> void:
if self.visible == true && Settings.character_select_open == true:
if event is InputEventMouseButton && event.is_pressed():
var evLocal: InputEvent = make_input_local(event)
if Rect2(Vector2(0, 0), panel.size).has_point(evLocal.position):
print(character_name_label.text)
new_character_selected.emit(character_image.texture)

1
character.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://i35b3scbpwpu

45
character.tscn Normal file
View File

@@ -0,0 +1,45 @@
[gd_scene load_steps=4 format=3 uid="uid://c7ecjj2af6usf"]
[ext_resource type="Script" uid="uid://i35b3scbpwpu" path="res://character.gd" id="1_pjt0s"]
[ext_resource type="Texture2D" uid="uid://cv3hdd6bsruau" path="res://icon.svg" id="2_pjt0s"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pjt0s"]
bg_color = Color(0.302, 0.302, 0.302, 1)
[node name="Control" type="Control"]
layout_mode = 3
anchors_preset = 0
script = ExtResource("1_pjt0s")
[node name="Panel" type="Panel" parent="."]
layout_mode = 0
offset_right = 240.0
offset_bottom = 145.0
theme_override_styles/panel = SubResource("StyleBoxFlat_pjt0s")
[node name="MarginContainer" type="MarginContainer" parent="Panel"]
layout_mode = 0
offset_right = 240.0
offset_bottom = 145.0
theme_override_constants/margin_left = 15
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 15
[node name="VBoxContainer" type="VBoxContainer" parent="Panel/MarginContainer"]
layout_mode = 2
[node name="CharacterTextureRect" type="TextureRect" parent="Panel/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 100)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
texture = ExtResource("2_pjt0s")
expand_mode = 3
stretch_mode = 5
[node name="CharacterName" type="Label" parent="Panel/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Aloy"
horizontal_alignment = 1

29
log.gd Normal file
View File

@@ -0,0 +1,29 @@
extends Control
@onready
var log_panel: Panel = %LogPanel
@onready
var log_box: VBoxContainer = %LogVBoxContainer
var log_rows: Array
func add_log_row(text: String) -> void:
var log_row: String = get_time() + text
log_rows.append(log_row)
update_log()
func update_log() -> void:
print("update_log")
Settings.delete_children(log_box)
for row: String in log_rows:
var log_label: Label = Label.new()
log_label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
log_label.add_theme_font_size_override("font_size", 20)
log_label.text = row
log_label.autowrap_mode = TextServer.AUTOWRAP_WORD
log_box.add_child(log_label)
func get_time() -> String:
var dateTime: Dictionary = Time.get_datetime_dict_from_system()
return "" + str(dateTime.hour) + ":" + str(dateTime.minute) + ":" + str(dateTime.second) + " "

1
log.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://cw41y87l64qo7

81
new_character_select.gd Normal file
View File

@@ -0,0 +1,81 @@
extends Control
@onready
var character_panel: Panel = %CharacterPanel
@onready
var character_grid: GridContainer = %CharacterGridContainer
@onready
var close_timer: Timer = %CloseTimer
signal character_selected(file_name: String)
signal new_new_character_selected(file_name: String)
var character: PackedScene = preload("res://character.tscn")
func _ready() -> void:
close_timer.timeout.connect(_on_close_timeout)
func select_character(file_name: String) -> void:
print("select_character")
character_selected.emit(file_name)
func _on_close_timeout() -> void:
print("_on_close_timeout!")
Settings.character_select_open = false
close_timer.stop()
func load_characters() -> void:
print("load_characters")
var fetch_character_list: Callable = func fetch_character_list(list) -> void:
print("fetch_character_list")
Settings.delete_children(character_grid)
if typeof(list) == TYPE_ARRAY:
for character_name: String in list:
print("character_name ", character_name)
var character_box: Character = character.instantiate()
character_grid.add_child(character_box)
character_box.custom_minimum_size = Vector2(235, 145)
character_box.size = Vector2(235, 145)
character_box.set_character_name(character_name)
character_box.connect("new_character_selected", _on_character_selected)
Settings.make_request2("/characters", fetch_character_list, true)
func show_grid() -> void:
print("show_grid")
close_timer.stop()
self.visible = true
Settings.character_select_open = true
func _on_character_selected(texture: ImageTexture) -> void:
print("_on_character_selected")
self.visible = false
new_new_character_selected.emit(texture)
close_timer.start()
func _input(event: InputEvent) -> void:
if self.visible == true:
if event is InputEventMouseButton && event.is_pressed():
var evLocal: InputEvent = make_input_local(event)
if !Rect2(Vector2(0, 0), character_panel.size).has_point(evLocal.position):
self.visible = false
Settings.character_select_open = false
func load_characters_local() -> void:
var characters: DirAccess = DirAccess.open("res://characters/")
if characters:
characters.list_dir_begin()
var file_name: String = characters.get_next()
while file_name != "":
file_name = file_name.replace('.import', '') # <--- remove the .import
if file_name.ends_with(".png"):
var texture: Resource = load("res://characters/" + file_name)
var texture_btn: TextureButton = TextureButton.new()
character_grid.add_child(texture_btn)
texture_btn.custom_minimum_size = Vector2(80, 40)
texture_btn.ignore_texture_size = true
texture_btn.stretch_mode = TextureButton.STRETCH_KEEP_ASPECT
texture_btn.texture_normal = texture
texture_btn.pressed.connect(select_character.bind(file_name))
file_name = characters.get_next()

View File

@@ -0,0 +1 @@
uid://cvffg87wr6r3y

55
new_character_select.tscn Normal file
View File

@@ -0,0 +1,55 @@
[gd_scene load_steps=3 format=3 uid="uid://cdy4kvemwaiom"]
[ext_resource type="Script" uid="uid://cvffg87wr6r3y" path="res://new_character_select.gd" id="1_h4tdp"]
[sub_resource type="LabelSettings" id="LabelSettings_p4iny"]
font_size = 25
[node name="Control" type="Control"]
layout_mode = 3
anchors_preset = 0
script = ExtResource("1_h4tdp")
[node name="CharacterPanel" type="Panel" parent="."]
unique_name_in_owner = true
layout_mode = 0
offset_right = 1260.0
offset_bottom = 665.0
[node name="VBoxContainer" type="VBoxContainer" parent="CharacterPanel"]
layout_mode = 0
offset_right = 1263.0
offset_bottom = 659.0
size_flags_horizontal = 3
[node name="Label" type="Label" parent="CharacterPanel/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Character Select"
label_settings = SubResource("LabelSettings_p4iny")
horizontal_alignment = 1
[node name="MarginContainer" type="MarginContainer" parent="CharacterPanel/VBoxContainer"]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 10
[node name="ScrollContainer" type="ScrollContainer" parent="CharacterPanel/VBoxContainer/MarginContainer"]
custom_minimum_size = Vector2(0, 600)
layout_mode = 2
size_flags_vertical = 3
horizontal_scroll_mode = 0
[node name="CharacterGridContainer" type="GridContainer" parent="CharacterPanel/VBoxContainer/MarginContainer/ScrollContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(1150, 600)
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/h_separation = 10
theme_override_constants/v_separation = 10
columns = 5
[node name="CloseTimer" type="Timer" parent="CharacterPanel"]
unique_name_in_owner = true

99
playlist.gd Normal file
View File

@@ -0,0 +1,99 @@
extends Node
var song_object_array: Array[SongObject] = []
var latest_played_song: int = 0
var currently_playing_song: int = -1
var first_song_downloaded: bool = false
var first_song_played: bool = false
var number_of_tracks_to_preload: int = 1
var is_song_downloading: bool = false
func get_next_song() -> SongObject:
return song_object_array[latest_played_song]
func set_latest_played_song() -> void:
latest_played_song += 1
if latest_played_song > song_object_array.size() - 1:
latest_played_song = song_object_array.size() - 1
func update_last_played_song() -> void:
latest_played_song = song_object_array.size()
func get_preloaded_songs() -> int:
var number_of_tracks_preloaded: int = 0
for song: SongObject in song_object_array:
if !song.has_played:
number_of_tracks_preloaded += 1
return number_of_tracks_preloaded
func should_preload_more_songs() -> bool:
return number_of_tracks_to_preload > get_preloaded_songs()
func set_last_played_answered() -> void:
if song_object_array[latest_played_song].has_played && !song_object_array[latest_played_song].is_answered:
song_object_array[latest_played_song].is_answered = true
func song_is_answered(song_no: int = currently_playing_song) -> void:
print("show_answer_pressed song_object: ", song_object_array[song_no]._to_string())
song_object_array[song_no].is_answered = true
if Settings.add_to_stats:
print("add to stats: ", song_no)
Settings.make_put_request("/music/played?song="+str(song_no))
func add_to_playlist(new_song_object: SongObject) -> void:
song_object_array.append(new_song_object)
func get_playlist() -> Array[SongObject]:
if Settings.is_debug:
return song_object_array
else:
var temp_list: Array[SongObject] = []
for s: SongObject in song_object_array:
if s.has_played:
temp_list.append(s)
return temp_list
func reset_playlist() -> void:
currently_playing_song = -1
latest_played_song = 0
clear_song_list()
func clear_song_list() -> void:
song_object_array.clear()
func unset_is_playing() -> void:
for song_object: SongObject in song_object_array:
song_object.is_playing = false
func set_currently_playing_song(value: int) -> void:
currently_playing_song = value
func get_current_game_title() -> String:
return song_object_array[currently_playing_song].get_game_title()
func get_current_song_title() -> String:
return song_object_array[currently_playing_song].get_song_title()
func add_point(player_id: int) -> void:
song_object_array[currently_playing_song].add_point(player_id)
func remove_point(player_id: int) -> void:
song_object_array[currently_playing_song].remove_point(player_id)
func remove_player_from_list(player_to_remove: int) -> void:
for song_list_object: SongObject in song_object_array:
song_object_array[song_list_object.song_number].players_given_point.remove_at(song_object_array[song_list_object.song_number].players_given_point.find(player_to_remove))
func get_song(song_no: int) -> AudioStream:
return song_object_array[song_no].song
func add_song_to_song_object(song_no: int, sound: AudioStream) -> void:
song_object_array[song_no].song = sound
func song_has_played(song_no: int = latest_played_song) -> void:
song_object_array[song_no].has_played = true
func song_is_playing(song_no: int = latest_played_song) -> void:
song_object_array[song_no].is_playing = true

1
playlist.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://bgei7qocdnolw

5
progress_response.gd Normal file
View File

@@ -0,0 +1,5 @@
class_name ProgressResponse
extends Node
var progress: String
var total_time: String

1
progress_response.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://e74iuu78stc3

View File

@@ -12,16 +12,16 @@ config_version=5
config/name="MusicPlayer"
run/main_scene="res://MainWindow.tscn"
config/features=PackedStringArray("4.4", "Forward Plus")
config/features=PackedStringArray("4.5", "Forward Plus")
config/icon="res://icon.svg"
[autoload]
Settings="*res://Settings.gd"
Playlist="*res://playlist.gd"
[debug]
settings/stdout/print_fps=true
gdscript/warnings/untyped_declaration=1
gdscript/warnings/inferred_declaration=1

View File

@@ -44,7 +44,7 @@ func update_players() -> void:
if player.id == player_id:
var texture: TextureRect = TextureRect.new()
texture.texture = player.character
texture.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
texture.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
texture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
texture.custom_minimum_size = Vector2(50, 25)
song_list_players.add_child(texture)

View File

@@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://n2g8jddr85h2"
path="res://.godot/imported/01. Opening.mp3-559a476b5f0faf13d7bec359898ef47c.mp3str"
[deps]
source_file="res://sounds/01. Opening.mp3"
dest_files=["res://.godot/imported/01. Opening.mp3-559a476b5f0faf13d7bec359898ef47c.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

10
sync_response.gd Normal file
View File

@@ -0,0 +1,10 @@
class_name SyncResponse
extends Node
var games_added: Array
var games_re_added: Array
var games_changed_title: Array
var games_changed_content: Array
var games_removed: Array
var catched_errors: Array
var total_time: String

1
sync_response.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://dtfsuob2aidl7

201
sync_window.gd Normal file
View File

@@ -0,0 +1,201 @@
extends Control
@onready
var sync_panel: Panel = %SyncPanel
@onready
var sync_title_label: Label = %SyncTitleLabel
@onready
var no_changes_label: Label = %NoChangesLabel
@onready
var progress_hbox: HBoxContainer = %ProgressHBoxContainer
@onready
var sync_hbox: HBoxContainer = %SyncHBoxContainer
@onready
var sync_progress_bar: ProgressBar = %SyncProgressBar
@onready
var games_added_vbox: VBoxContainer = %GamesAddedVBox
@onready
var games_added_separator: VSeparator = %GamesAddedSeparator
@onready
var games_readded_vbox: VBoxContainer = %GamesReAddedVBox
@onready
var games_readded_separator: VSeparator = %GamesReAddedSeparator
@onready
var games_changed_title_vbox: VBoxContainer = %GamesChangedTitleVBox
@onready
var games_changed_title_separator: VSeparator = %GamesChangedTitleSeparator
@onready
var games_changed_content_vbox: VBoxContainer = %GamesChangedContentVBox
@onready
var games_changed_content_separator: VSeparator = %GamesChangedContentSeparator
@onready
var games_removed_vbox: VBoxContainer = %GamesRemovedVBox
@onready
var games_removed_separator: VSeparator = %GamesRemovedSeparator
@onready
var catched_errors_vbox: VBoxContainer = %CatchedErrorsVBox
@onready
var sync_time: Label = %SyncTime
@onready
var sync_timer: Timer = %SyncTimer
var changes: bool = false
var has_synced: bool = false
signal sync_started
signal sync_finished
func _ready() -> void:
sync_timer.timeout.connect(_on_sync_timeout)
func _input(event: InputEvent) -> void:
if self.visible == true:
if event is InputEventMouseButton && event.is_pressed():
var evLocal: InputEvent = make_input_local(event)
if !Rect2(Vector2(0, 0), sync_panel.size).has_point(evLocal.position):
self.visible = false
func start_sync() -> void:
print("start_sync")
self.visible = true
if !has_synced:
var sync_request_sent: Callable = func sync_request_sent() -> void:
sync_timer.start(0.75)
Settings.currently_syncing = true
sync_started.emit()
show_sync_progress()
if !Settings.currently_syncing:
Settings.make_request2("/sync", sync_request_sent, false)
func _on_sync_timeout() -> void:
print("_on_sync_timeout!")
var get_progress: Callable = func get_progress(data_received: Dictionary) -> void:
print("get_progress")
print("data_received: ", data_received)
if data_received != null:
if data_received.has("progress"):
sync_progress_bar.value = int(data_received.progress)
sync_time.text = data_received.time_spent
else:
on_sync_finished(data_received)
Settings.make_request2("/sync/progress", get_progress, true)
func on_sync_finished(data_received: Dictionary) -> void:
has_synced = true
reset_sync_result()
if data_received.games_added != null:
changes = true
list_visible(games_added_vbox, games_added_separator)
make_list(data_received.games_added, games_added_vbox, "GamesAdded")
if data_received.games_re_added != null:
changes = true
list_visible(games_readded_vbox, games_readded_separator)
make_list(data_received.games_re_added, games_readded_vbox, "GamesReAdded")
if data_received.games_changed_title != null:
changes = true
list_visible(games_changed_title_vbox, games_changed_title_separator)
Settings.delete_children(games_changed_title_vbox)
make_header_label(games_changed_title_vbox, "GamesChangedTitle")
var row: int = 0
for old_game_title: String in data_received.games_changed_title:
var label: Label = make_game_label(old_game_title + " changed title to " + data_received.games_changed_title[old_game_title])
if row % 2 != 0:
label.add_theme_color_override("font_color", Color(1, 0.5, 0))
games_changed_title_vbox.add_child(label)
if data_received.games_changed_content != null:
changes = true
list_visible(games_changed_content_vbox, games_changed_content_separator)
make_list(data_received.games_changed_content, games_changed_content_vbox, "GamesChangedContent")
if data_received.games_removed != null:
changes = true
list_visible(games_removed_vbox, games_removed_separator)
make_list(data_received.games_removed, games_removed_vbox, "GamesRemoved")
if data_received.catched_errors != null:
catched_errors_vbox.visible = true
make_list(data_received.catched_errors, catched_errors_vbox, "CatchedErrors")
if !changes:
no_changes_label.visible = true
sync_time.text = data_received.total_time
Settings.currently_syncing = false
sync_timer.stop()
print("sync finished")
show_sync_result()
sync_finished.emit()
func list_visible(vbox: VBoxContainer, seperator: VSeparator) -> void:
vbox.visible = true
seperator.visible = true
func make_header_label(vbox: VBoxContainer, text: String) -> void:
var label: Label = Label.new()
label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
label.add_theme_font_size_override("font_size", 20)
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
label.text = text
vbox.add_child(label)
func make_game_label(text: String) -> Label:
var label: Label = Label.new()
label.set_texture_filter(TextureFilter.TEXTURE_FILTER_NEAREST)
label.add_theme_font_size_override("font_size", 20)
label.text = text
label.autowrap_mode = TextServer.AUTOWRAP_WORD
return label
func reset_sync_result() -> void:
sync_progress_bar.value = 0
sync_time.text = ""
changes = false
no_changes_label.visible = false
games_added_vbox.visible = false
games_added_separator.visible = false
games_readded_vbox.visible = false
games_readded_separator.visible = false
games_changed_title_vbox.visible = false
games_changed_title_separator.visible = false
games_changed_content_vbox.visible = false
games_changed_content_separator.visible = false
games_removed_vbox.visible = false
games_removed_separator.visible = false
catched_errors_vbox.visible = false
func make_list(list: Array, vbox: VBoxContainer, text: String) -> void:
Settings.delete_children(vbox)
make_header_label(vbox, text)
var row: int = 0
for game: String in list:
var label: Label = make_game_label(game)
if row % 2 != 0:
label.add_theme_color_override("font_color", Color(1, 0.5, 0))
vbox.add_child(label)
func show_sync_result() -> void:
sync_title_label.text = "Sync Result"
progress_hbox.visible = false
sync_hbox.visible = true
func show_sync_progress() -> void:
sync_title_label.text = "Sync in Progress"
progress_hbox.visible = true
no_changes_label.visible = false
sync_hbox.visible = false
catched_errors_vbox.visible = false

1
sync_window.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://c3ejukwth512a