feat: Implement core multiplayer features including user authentication, profile management, lobby, game mode managers, and leaderboard.
This commit is contained in:
+183
-11
@@ -12,6 +12,9 @@ extends Control
|
||||
@onready var server_option = $MainMenuPanel/VBoxContainer/ServerSelectionSection/ServerOption
|
||||
@onready var server_ip_input = $MainMenuPanel/VBoxContainer/ServerSelectionSection/ServerIPInput
|
||||
|
||||
# Leaderboard Reference
|
||||
@onready var leaderboard_btn = $MainMenuPanel/VBoxContainer/ButtonSection/LeaderboardBtn
|
||||
|
||||
# UI References - Room List
|
||||
@onready var room_list_panel = $RoomListPanel
|
||||
@onready var room_list = $RoomListPanel/VBoxContainer/RoomList
|
||||
@@ -42,9 +45,23 @@ extends Control
|
||||
@onready var enable_timer_label = $LobbyPanel/TopBar/SettingsSection/EnableTimerLabel
|
||||
@onready var scarcity_option = $LobbyPanel/TopBar/SettingsSection/ScarcityOption
|
||||
@onready var scarcity_label = $LobbyPanel/TopBar/SettingsSection/ScarcityLabel
|
||||
@onready var scarcity_spacer = $LobbyPanel/TopBar/SettingsSection/ScarcitySpacer
|
||||
@onready var spawn_spacer = $LobbyPanel/TopBar/SettingsSection/SpawnSpacer
|
||||
@onready var timer_spacer = $LobbyPanel/TopBar/SettingsSection/TimerSpacer
|
||||
@onready var game_mode_option = $LobbyPanel/TopBar/SettingsSection/GameModeOption
|
||||
@onready var game_mode_text_label = $LobbyPanel/TopBar/SettingsSection/GameModeTextLabel
|
||||
|
||||
# Custom Settings Containers
|
||||
var sng_settings_container: HBoxContainer
|
||||
var sng_go_option: OptionButton
|
||||
var sng_stop_option: OptionButton
|
||||
var sng_goals_option: OptionButton
|
||||
|
||||
var doors_settings_container: HBoxContainer
|
||||
var doors_swap_option: OptionButton
|
||||
var doors_refresh_option: OptionButton
|
||||
var doors_goals_option: OptionButton
|
||||
|
||||
# UI References - Player Slots
|
||||
@onready var players_container = $LobbyPanel/PlayersContainer
|
||||
@onready var players_container2 = $LobbyPanel/PlayersContainer2
|
||||
@@ -75,6 +92,8 @@ var admin_panel_instance: Control
|
||||
# Store current match ID for copy function
|
||||
var current_match_id: String = ""
|
||||
|
||||
var leaderboard_panel_instance: Control
|
||||
|
||||
# Server Selection Controls (Now in tscn)
|
||||
# var server_option: OptionButton
|
||||
# var server_ip_input: LineEdit
|
||||
@@ -92,6 +111,9 @@ func _ready():
|
||||
# Get player slot references
|
||||
_setup_player_slots()
|
||||
|
||||
# Setup Game Mode specific UI dynamically
|
||||
_create_custom_settings_ui()
|
||||
|
||||
# Set player name from profile and configure input visibility
|
||||
if player_name_input:
|
||||
# Get the parent container for the input to hide/show properly
|
||||
@@ -118,6 +140,8 @@ func _ready():
|
||||
main_menu_profile_btn.pressed.connect(_on_profile_btn_pressed)
|
||||
if lobby_settings_btn:
|
||||
lobby_settings_btn.pressed.connect(_on_settings_pressed)
|
||||
if leaderboard_btn:
|
||||
leaderboard_btn.pressed.connect(_on_leaderboard_pressed)
|
||||
|
||||
# Connect Server Selection signals
|
||||
if server_option:
|
||||
@@ -176,6 +200,13 @@ func _ready():
|
||||
LobbyManager.game_mode_changed.connect(_on_game_mode_changed)
|
||||
LobbyManager.player_list_changed.connect(_update_player_slots)
|
||||
|
||||
LobbyManager.sng_go_duration_changed.connect(_on_sng_update)
|
||||
LobbyManager.sng_stop_duration_changed.connect(_on_sng_update)
|
||||
LobbyManager.sng_required_goals_changed.connect(_on_sng_update)
|
||||
LobbyManager.doors_swap_time_changed.connect(_on_doors_update)
|
||||
LobbyManager.doors_refresh_time_changed.connect(_on_doors_update)
|
||||
LobbyManager.doors_required_goals_changed.connect(_on_doors_update)
|
||||
|
||||
# Connect NakamaManager signals
|
||||
NakamaManager.connected_to_nakama.connect(_on_connected_to_nakama)
|
||||
NakamaManager.connection_failed.connect(_on_connection_failed)
|
||||
@@ -331,6 +362,116 @@ func _on_back_pressed() -> void:
|
||||
_show_panel("main_menu")
|
||||
connection_status.text = ""
|
||||
|
||||
func _update_settings_visibility() -> void:
|
||||
var is_host = LobbyManager.is_host
|
||||
var is_freemode = LobbyManager.game_mode == "Freemode"
|
||||
|
||||
# Duration
|
||||
var show_duration = is_freemode
|
||||
duration_option.visible = is_host and show_duration
|
||||
duration_text_label.visible = not is_host and show_duration
|
||||
$LobbyPanel/TopBar/SettingsSection/DurationLabel.visible = show_duration
|
||||
|
||||
# Random Spawn
|
||||
var show_spawn = is_freemode
|
||||
random_spawn_check.visible = is_host and show_spawn
|
||||
random_spawn_label.visible = not is_host and show_spawn
|
||||
if spawn_spacer: spawn_spacer.visible = show_spawn
|
||||
|
||||
# Timer
|
||||
var show_timer = is_freemode
|
||||
enable_timer_check.visible = is_host and show_timer
|
||||
enable_timer_label.visible = not is_host and show_timer
|
||||
if timer_spacer: timer_spacer.visible = show_timer
|
||||
|
||||
# Scarcity
|
||||
var show_scarcity = is_freemode
|
||||
if scarcity_option: scarcity_option.visible = is_host and show_scarcity
|
||||
if scarcity_label: scarcity_label.visible = not is_host and show_scarcity
|
||||
if scarcity_spacer: scarcity_spacer.visible = show_scarcity
|
||||
|
||||
# Custom mode sets
|
||||
var is_sng = LobbyManager.game_mode == "Stop n Go"
|
||||
if sng_settings_container:
|
||||
sng_settings_container.visible = is_sng
|
||||
sng_go_option.disabled = not is_host
|
||||
sng_stop_option.disabled = not is_host
|
||||
sng_goals_option.disabled = not is_host
|
||||
|
||||
var is_doors = LobbyManager.game_mode == "Tekton Doors"
|
||||
if doors_settings_container:
|
||||
doors_settings_container.visible = is_doors
|
||||
doors_swap_option.disabled = not is_host
|
||||
doors_refresh_option.disabled = not is_host
|
||||
doors_goals_option.disabled = not is_host
|
||||
|
||||
func _create_custom_settings_ui() -> void:
|
||||
var settings_section = $LobbyPanel/TopBar/SettingsSection
|
||||
if not settings_section: return
|
||||
|
||||
# Stop n Go
|
||||
sng_settings_container = HBoxContainer.new()
|
||||
sng_settings_container.visible = false
|
||||
settings_section.add_child(sng_settings_container)
|
||||
|
||||
_add_label(sng_settings_container, "Go Time:")
|
||||
sng_go_option = OptionButton.new()
|
||||
sng_go_option.add_item("10s"); sng_go_option.add_item("15s"); sng_go_option.add_item("25s")
|
||||
sng_go_option.item_selected.connect(func(idx): if LobbyManager.is_host: LobbyManager.set_sng_go_duration([10, 15, 25][idx]))
|
||||
sng_settings_container.add_child(sng_go_option)
|
||||
|
||||
_add_label(sng_settings_container, "Stop Time:")
|
||||
sng_stop_option = OptionButton.new()
|
||||
sng_stop_option.add_item("3s"); sng_stop_option.add_item("4s"); sng_stop_option.add_item("5s")
|
||||
sng_stop_option.item_selected.connect(func(idx): if LobbyManager.is_host: LobbyManager.set_sng_stop_duration([3, 4, 5][idx]))
|
||||
sng_settings_container.add_child(sng_stop_option)
|
||||
|
||||
_add_label(sng_settings_container, "Req Goals:")
|
||||
sng_goals_option = OptionButton.new()
|
||||
sng_goals_option.add_item("5"); sng_goals_option.add_item("8"); sng_goals_option.add_item("12")
|
||||
sng_goals_option.item_selected.connect(func(idx): if LobbyManager.is_host: LobbyManager.set_sng_required_goals([5, 8, 12][idx]))
|
||||
sng_settings_container.add_child(sng_goals_option)
|
||||
|
||||
# Tekton Doors
|
||||
doors_settings_container = HBoxContainer.new()
|
||||
doors_settings_container.visible = false
|
||||
settings_section.add_child(doors_settings_container)
|
||||
|
||||
_add_label(doors_settings_container, "Swap Wait:")
|
||||
doors_swap_option = OptionButton.new()
|
||||
doors_swap_option.add_item("10s"); doors_swap_option.add_item("15s"); doors_swap_option.add_item("30s")
|
||||
doors_swap_option.item_selected.connect(func(idx): if LobbyManager.is_host: LobbyManager.set_doors_swap_time([10, 15, 30][idx]))
|
||||
doors_settings_container.add_child(doors_swap_option)
|
||||
|
||||
_add_label(doors_settings_container, "Tile Refresh:")
|
||||
doors_refresh_option = OptionButton.new()
|
||||
doors_refresh_option.add_item("15s"); doors_refresh_option.add_item("25s"); doors_refresh_option.add_item("40s")
|
||||
doors_refresh_option.item_selected.connect(func(idx): if LobbyManager.is_host: LobbyManager.set_doors_refresh_time([15, 25, 40][idx]))
|
||||
doors_settings_container.add_child(doors_refresh_option)
|
||||
|
||||
_add_label(doors_settings_container, "Req Goals:")
|
||||
doors_goals_option = OptionButton.new()
|
||||
doors_goals_option.add_item("5"); doors_goals_option.add_item("8"); doors_goals_option.add_item("12")
|
||||
doors_goals_option.item_selected.connect(func(idx): if LobbyManager.is_host: LobbyManager.set_doors_required_goals([5, 8, 12][idx]))
|
||||
doors_settings_container.add_child(doors_goals_option)
|
||||
|
||||
# Move Game Mode selector to the far right
|
||||
var gm_spacer = settings_section.get_node_or_null("GameModeSpacer")
|
||||
var gm_option = settings_section.get_node_or_null("GameModeOption")
|
||||
var gm_label = settings_section.get_node_or_null("GameModeTextLabel")
|
||||
|
||||
if gm_spacer: settings_section.move_child(gm_spacer, -1)
|
||||
if gm_option: settings_section.move_child(gm_option, -1)
|
||||
if gm_label: settings_section.move_child(gm_label, -1)
|
||||
|
||||
func _add_label(parent: Control, text: String):
|
||||
var spacer = Control.new()
|
||||
spacer.custom_minimum_size = Vector2(10, 0)
|
||||
parent.add_child(spacer)
|
||||
var lbl = Label.new()
|
||||
lbl.text = text
|
||||
parent.add_child(lbl)
|
||||
|
||||
# =============================================================================
|
||||
# Lobby Button Handlers
|
||||
# =============================================================================
|
||||
@@ -393,7 +534,32 @@ func _on_game_mode_changed(mode: String) -> void:
|
||||
break
|
||||
if game_mode_text_label:
|
||||
game_mode_text_label.text = mode
|
||||
|
||||
_update_settings_visibility()
|
||||
|
||||
func _on_sng_update(_val: int = 0) -> void:
|
||||
if not sng_go_option: return
|
||||
|
||||
var go_idx = [10, 15, 25].find(LobbyManager.sng_go_duration)
|
||||
if go_idx != -1: sng_go_option.selected = go_idx
|
||||
|
||||
var stop_idx = [3, 4, 5].find(LobbyManager.sng_stop_duration)
|
||||
if stop_idx != -1: sng_stop_option.selected = stop_idx
|
||||
|
||||
var goals_idx = [5, 8, 12].find(LobbyManager.sng_required_goals)
|
||||
if goals_idx != -1: sng_goals_option.selected = goals_idx
|
||||
|
||||
func _on_doors_update(_val: int = 0) -> void:
|
||||
if not doors_swap_option: return
|
||||
|
||||
var swap_idx = [10, 15, 30].find(LobbyManager.doors_swap_time)
|
||||
if swap_idx != -1: doors_swap_option.selected = swap_idx
|
||||
|
||||
var refresh_idx = [15, 25, 40].find(LobbyManager.doors_refresh_time)
|
||||
if refresh_idx != -1: doors_refresh_option.selected = refresh_idx
|
||||
|
||||
var goals_idx = [5, 8, 12].find(LobbyManager.doors_required_goals)
|
||||
if goals_idx != -1: doors_goals_option.selected = goals_idx
|
||||
|
||||
func _update_random_spawn_label(enabled: bool) -> void:
|
||||
if random_spawn_label:
|
||||
@@ -431,6 +597,18 @@ func _on_settings_pressed():
|
||||
if settings_menu:
|
||||
settings_menu.open()
|
||||
|
||||
func _on_leaderboard_pressed() -> void:
|
||||
if not leaderboard_panel_instance:
|
||||
var leaderboard_panel_scene := load("res://scenes/ui/leaderboard_panel.tscn")
|
||||
if leaderboard_panel_scene:
|
||||
leaderboard_panel_instance = leaderboard_panel_scene.instantiate()
|
||||
leaderboard_panel_instance.closed.connect(func(): leaderboard_panel_instance.hide())
|
||||
add_child(leaderboard_panel_instance)
|
||||
|
||||
if leaderboard_panel_instance:
|
||||
leaderboard_panel_instance.show_panel()
|
||||
# Center it and apply some offset if needed
|
||||
|
||||
func _go_to_login() -> void:
|
||||
if get_tree():
|
||||
get_tree().change_scene_to_file("res://scenes/ui/login_screen.tscn")
|
||||
@@ -463,15 +641,7 @@ func _on_room_joined(room_data: Dictionary) -> void:
|
||||
host_banner.visible = is_host
|
||||
start_game_btn.visible = is_host
|
||||
|
||||
# Duration: host sees dropdown, clients see text
|
||||
duration_option.visible = is_host
|
||||
duration_text_label.visible = not is_host
|
||||
|
||||
random_spawn_check.visible = is_host
|
||||
random_spawn_label.visible = not is_host
|
||||
|
||||
enable_timer_check.visible = is_host
|
||||
enable_timer_label.visible = not is_host
|
||||
_update_settings_visibility()
|
||||
|
||||
# Update values from LobbyManager
|
||||
_on_match_duration_changed(LobbyManager.match_duration)
|
||||
@@ -479,10 +649,12 @@ func _on_room_joined(room_data: Dictionary) -> void:
|
||||
_on_enable_cycle_timer_changed(LobbyManager.enable_cycle_timer)
|
||||
|
||||
# Scarcity Update
|
||||
if scarcity_option: scarcity_option.visible = is_host
|
||||
if scarcity_label: scarcity_label.visible = not is_host
|
||||
_on_scarcity_mode_changed(LobbyManager.scarcity_mode)
|
||||
|
||||
# Initial UI sync for custom modes
|
||||
_on_sng_update()
|
||||
_on_doors_update()
|
||||
|
||||
# Area selector: only host can interact
|
||||
area_left_btn.disabled = not is_host
|
||||
area_right_btn.disabled = not is_host
|
||||
|
||||
Reference in New Issue
Block a user