diff options
Diffstat (limited to 'client/gui/overlays/lobby/lobby.gd')
-rw-r--r-- | client/gui/overlays/lobby/lobby.gd | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/client/gui/overlays/lobby/lobby.gd b/client/gui/overlays/lobby/lobby.gd new file mode 100644 index 00000000..3971dbb3 --- /dev/null +++ b/client/gui/overlays/lobby/lobby.gd @@ -0,0 +1,204 @@ +# Hurry Curry! - a game about cooking +# Copyright (C) 2025 Hurry Curry! contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +extends Control +class_name Lobby + +const MAX_BOT_COUNT_PER_TYPE: int = 3 +const PLAYER = preload("res://gui/overlays/lobby/player.tscn") + +var map_count +var selected_map := 0 +var selected_map_name: String + +var bots_enabled := false +var bot_counts := {} +var bot_reset_buttons := {} +var bot_inc_buttons := {} +var bot_dec_buttons := {} + +@onready var game: Game = $"../Game" +@onready var player_container = $PlayerList/VBoxContainer/Players + +@onready var map_name_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Name +@onready var map_player_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Players +@onready var map_difficulty_label = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/Map/Difficulty +@onready var map_list_container = $Sidebar/Bottom/MarginContainer/VBoxContainer/MapList/VBoxContainer +@onready var map_list = $Sidebar/Bottom/MarginContainer/VBoxContainer/MapList + +@onready var map_selector = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer +@onready var prev_map = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer/Left +@onready var next_map = $Sidebar/Bottom/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer2/Right + +@onready var bots_container = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots +@onready var bot_settings = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom/BotSettings +@onready var bot_settings_conainer = $Sidebar/Bottom/MarginContainer/VBoxContainer/Bots/ScrollContainerCustom + +@onready var join_spectate = $Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/JoinSpectate +@onready var start_button = $Sidebar/Bottom/MarginContainer/VBoxContainer/VBoxContainer/Start + +func _ready(): + game.update_players.connect(update_players) + initialize() + game.data_updated.connect(initialize) + game.join_state_updated.connect(_on_game_join_state_updated) + _on_game_join_state_updated(game.join_state) + check_for_music() + +func initialize(): + map_count = game.maps.size() + + for c in map_list_container.get_children(): + c.queue_free() + for c in bot_settings.get_children(): + c.queue_free() + + var i := 0 + for m in game.maps: + var b := Button.new() + b.name = m[0] + b.text = "%s (%d)" % [m[1]["name"], m[1]["players"]] + b.pressed.connect(select_map.bind(i)) + b.focus_entered.connect(select_map.bind(i)) + map_list_container.add_child(b) + i += 1 + select_map(0) + + for algo_id: String in game.bot_algos: + if algo_id == "customer" or algo_id == "test": + continue + + bot_counts[algo_id] = 0 + + var h := HBoxContainer.new() + h.name = algo_id + var add := Button.new() + add.text = "+" + var reset := Button.new() + reset.size_flags_horizontal = SIZE_EXPAND_FILL + var remove := Button.new() + remove.text = "-" + bot_reset_buttons[algo_id] = reset + bot_inc_buttons[algo_id] = add + bot_dec_buttons[algo_id] = remove + update_bot_reset_text(algo_id) + add.pressed.connect(increase_bot_count.bind(algo_id)) + reset.pressed.connect(reset_bot_count.bind(algo_id)) + remove.pressed.connect(decrease_bot_count.bind(algo_id)) + h.add_child(remove) + h.add_child(reset) + h.add_child(add) + bot_settings.add_child(h) + +func select_map(i: int): + if i >= map_count: + return + selected_map = i + var map_data: Dictionary = game.maps[i][1] + map_name_label.text = map_data["name"] + map_player_label.text = tr("c.map.players_recommended").format([roundi(map_data["players"])]) + map_difficulty_label.text = tr("c.map.difficulty.%d" % (map_data["difficulty"] - 1)) + selected_map_name = game.maps[i][0] + if not game.menu.covered: + map_list_container.get_child(i).grab_focus() + +func increase_bot_count(algo_id: String): + bot_counts[algo_id] += 1 + update_bot_reset_text(algo_id) + +func decrease_bot_count(algo_id: String): + bot_counts[algo_id] -= 1 + update_bot_reset_text(algo_id) + +func reset_bot_count(algo_id: String): + bot_counts[algo_id] = 0 + update_bot_reset_text(algo_id) + +func update_bot_reset_text(algo_id: String): + var display_name: String = tr("s.bot.%s" % algo_id) + bot_reset_buttons[algo_id].text = "%s (%d)" % [display_name, bot_counts[algo_id]] + bot_inc_buttons[algo_id].disabled = not bot_counts[algo_id] < MAX_BOT_COUNT_PER_TYPE + bot_dec_buttons[algo_id].disabled = not bot_counts[algo_id] > 0 + +func update_players(player_list: Dictionary): + for i in player_container.get_children(): + i.queue_free() + + for i in player_list.keys(): + var p: PlayerTag = PLAYER.instantiate() + player_container.add_child(p) + p.setup(player_list[i].username) + +func _input(_event): + if not visible: + return + + if Input.is_action_just_pressed("previous") and not prev_map.disabled: + prev_map.emit_signal("pressed") + elif Input.is_action_just_pressed("next") and not next_map.disabled: + next_map.emit_signal("pressed") + +func _on_left_pressed(): + selected_map = (selected_map - 1) % map_count + select_map(selected_map) + +func _on_right_pressed(): + selected_map = (selected_map + 1) % map_count + select_map(selected_map) + +func _on_start_pressed(): + if selected_map_name != null: + var start_msg := "/start %s" % selected_map_name + + if bots_enabled: + for k in bot_counts.keys(): + for i in range(bot_counts[k]): + start_msg += "\ncreate-bot %s" % k + + game.mp.send_chat(game.my_player_id, start_msg) + Sound.play_music("stop") # TODO: Game music enter + +func _on_game_join_state_updated(state: Game.JoinState): + match state: + Game.JoinState.JOINED: + map_selector.show() + map_list.show() + bots_container.show() + start_button.disabled = false + join_spectate.disabled = false + join_spectate.text = tr("c.menu.ingame.spectate") + Game.JoinState.SPECTATING: + map_selector.hide() + map_list.hide() + bots_container.hide() + start_button.disabled = true + join_spectate.disabled = false + join_spectate.text = tr("c.menu.ingame.join") + Game.JoinState.WAITING: + join_spectate.disabled = true + +func _on_join_spectate_pressed(): + game.toggle_join() + +func check_for_music(): + if visible: + Sound.play_music("Lobby") + else: + Sound.play_music("stop") # TODO: Game music enter + +func _on_enable_bots_toggled(toggled_on): + bots_enabled = toggled_on + bot_settings_conainer.visible = toggled_on + bots_container.size_flags_vertical = SIZE_EXPAND_FILL if toggled_on else SIZE_FILL |