742 lines
20 KiB
GDScript
742 lines
20 KiB
GDScript
extends Node
|
|
|
|
## GameController - Top-level controller managing menu and game states
|
|
|
|
enum State {
|
|
MENU,
|
|
DECK_BUILDER,
|
|
GAME_SETUP,
|
|
PLAYING,
|
|
PAUSED,
|
|
LOGIN,
|
|
REGISTER,
|
|
ONLINE_LOBBY,
|
|
ONLINE_GAME,
|
|
PROFILE,
|
|
LEADERBOARD
|
|
}
|
|
|
|
var current_state: State = State.MENU
|
|
|
|
# Menu window size (matches project.godot viewport)
|
|
const MENU_SIZE := Vector2i(460, 689)
|
|
# Deck builder window size
|
|
const DECK_BUILDER_SIZE := Vector2i(1600, 900)
|
|
# Game setup window size
|
|
const GAME_SETUP_SIZE := Vector2i(800, 600)
|
|
# Game window size
|
|
const GAME_SIZE := Vector2i(2160, 980)
|
|
# Login screen size
|
|
const LOGIN_SIZE := Vector2i(400, 500)
|
|
# Register screen size
|
|
const REGISTER_SIZE := Vector2i(400, 600)
|
|
# Online lobby size
|
|
const ONLINE_LOBBY_SIZE := Vector2i(600, 700)
|
|
# Profile screen size
|
|
const PROFILE_SIZE := Vector2i(600, 700)
|
|
# Leaderboard screen size
|
|
const LEADERBOARD_SIZE := Vector2i(600, 700)
|
|
|
|
# Scene references
|
|
var main_menu: MainMenu = null
|
|
var deck_builder: DeckBuilder = null
|
|
var game_setup_menu: GameSetupMenu = null
|
|
var game_scene: Node3D = null
|
|
var pause_menu: PauseMenu = null
|
|
var login_screen: LoginScreen = null
|
|
var register_screen: RegisterScreen = null
|
|
var online_lobby: OnlineLobby = null
|
|
var profile_screen: ProfileScreen = null
|
|
var leaderboard_screen: LeaderboardScreen = null
|
|
|
|
# Selected decks for gameplay
|
|
var selected_deck: Deck = null
|
|
var player1_deck: Array = [] # Card IDs for player 1
|
|
var player2_deck: Array = [] # Card IDs for player 2
|
|
|
|
# AI settings
|
|
var is_vs_ai: bool = false
|
|
var ai_difficulty: int = AIStrategy.Difficulty.NORMAL
|
|
|
|
# Online game settings
|
|
var is_online_game: bool = false
|
|
var online_game_data: Dictionary = {}
|
|
var online_pause_menu: Control = null
|
|
|
|
# Preload the main game scene script
|
|
const MainScript = preload("res://scripts/Main.gd")
|
|
|
|
func _ready() -> void:
|
|
process_mode = Node.PROCESS_MODE_ALWAYS
|
|
_show_main_menu()
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if event is InputEventKey and event.pressed:
|
|
if event.keycode == KEY_ESCAPE:
|
|
match current_state:
|
|
State.DECK_BUILDER:
|
|
_on_deck_builder_back()
|
|
State.GAME_SETUP:
|
|
_on_game_setup_back()
|
|
State.PLAYING:
|
|
_show_pause_menu()
|
|
State.PAUSED:
|
|
_hide_pause_menu()
|
|
State.LOGIN:
|
|
_on_login_back()
|
|
State.REGISTER:
|
|
_on_register_back()
|
|
State.ONLINE_LOBBY:
|
|
_on_online_lobby_back()
|
|
State.ONLINE_GAME:
|
|
_show_online_pause_menu()
|
|
State.PROFILE:
|
|
_on_profile_back()
|
|
State.LEADERBOARD:
|
|
_on_leaderboard_back()
|
|
|
|
func _show_main_menu() -> void:
|
|
# Clean up any existing game
|
|
if game_scene:
|
|
game_scene.queue_free()
|
|
game_scene = null
|
|
|
|
if pause_menu:
|
|
pause_menu.queue_free()
|
|
pause_menu = null
|
|
|
|
# Switch back to small borderless menu window
|
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
|
|
DisplayServer.window_set_size(MENU_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - MENU_SIZE.x) / 2,
|
|
(screen.y - MENU_SIZE.y) / 2
|
|
))
|
|
|
|
# Reset viewport to main menu size
|
|
get_tree().root.content_scale_size = MENU_SIZE
|
|
|
|
# Clean up deck builder if exists
|
|
if deck_builder:
|
|
deck_builder.queue_free()
|
|
deck_builder = null
|
|
|
|
# Clean up game setup menu if exists
|
|
if game_setup_menu:
|
|
game_setup_menu.queue_free()
|
|
game_setup_menu = null
|
|
|
|
# Clean up login screen if exists
|
|
if login_screen:
|
|
login_screen.queue_free()
|
|
login_screen = null
|
|
|
|
# Clean up register screen if exists
|
|
if register_screen:
|
|
register_screen.queue_free()
|
|
register_screen = null
|
|
|
|
# Clean up online lobby if exists
|
|
if online_lobby:
|
|
online_lobby.queue_free()
|
|
online_lobby = null
|
|
|
|
# Clean up profile screen if exists
|
|
if profile_screen:
|
|
profile_screen.queue_free()
|
|
profile_screen = null
|
|
|
|
# Clean up leaderboard screen if exists
|
|
if leaderboard_screen:
|
|
leaderboard_screen.queue_free()
|
|
leaderboard_screen = null
|
|
|
|
if not main_menu:
|
|
main_menu = MainMenu.new()
|
|
add_child(main_menu)
|
|
main_menu.play_game.connect(_on_start_game)
|
|
main_menu.deck_builder.connect(_on_deck_builder)
|
|
main_menu.online_game.connect(_on_online_game)
|
|
|
|
main_menu.visible = true
|
|
current_state = State.MENU
|
|
|
|
func _on_start_game() -> void:
|
|
# Hide menu
|
|
if main_menu:
|
|
main_menu.visible = false
|
|
|
|
# Show game setup menu
|
|
_show_game_setup_menu()
|
|
|
|
|
|
func _on_deck_builder() -> void:
|
|
# Hide menu
|
|
if main_menu:
|
|
main_menu.visible = false
|
|
|
|
# Switch to deck builder window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, false)
|
|
DisplayServer.window_set_size(DECK_BUILDER_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - DECK_BUILDER_SIZE.x) / 2,
|
|
(screen.y - DECK_BUILDER_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to deck builder size
|
|
get_tree().root.content_scale_size = DECK_BUILDER_SIZE
|
|
|
|
# Create deck builder
|
|
if not deck_builder:
|
|
deck_builder = DeckBuilder.new()
|
|
add_child(deck_builder)
|
|
deck_builder.back_pressed.connect(_on_deck_builder_back)
|
|
deck_builder.deck_selected.connect(_on_deck_selected)
|
|
|
|
deck_builder.visible = true
|
|
current_state = State.DECK_BUILDER
|
|
|
|
|
|
func _on_deck_builder_back() -> void:
|
|
if deck_builder:
|
|
deck_builder.visible = false
|
|
_show_main_menu()
|
|
|
|
|
|
func _show_game_setup_menu() -> void:
|
|
# Switch to game setup window size (borderless like main menu)
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
|
|
DisplayServer.window_set_size(GAME_SETUP_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - GAME_SETUP_SIZE.x) / 2,
|
|
(screen.y - GAME_SETUP_SIZE.y) / 2
|
|
))
|
|
|
|
# Resize the root viewport to match the window size to avoid letterboxing
|
|
get_tree().root.content_scale_size = GAME_SETUP_SIZE
|
|
|
|
# Create game setup menu
|
|
if not game_setup_menu:
|
|
game_setup_menu = GameSetupMenu.new()
|
|
add_child(game_setup_menu)
|
|
game_setup_menu.back_pressed.connect(_on_game_setup_back)
|
|
game_setup_menu.start_game_requested.connect(_on_game_setup_start)
|
|
|
|
game_setup_menu.visible = true
|
|
current_state = State.GAME_SETUP
|
|
|
|
|
|
func _on_game_setup_back() -> void:
|
|
if game_setup_menu:
|
|
game_setup_menu.visible = false
|
|
_show_main_menu()
|
|
|
|
|
|
func _on_game_setup_start(p1_deck: Array, p2_deck: Array, p_is_vs_ai: bool = false, p_ai_difficulty: int = AIStrategy.Difficulty.NORMAL) -> void:
|
|
player1_deck = p1_deck
|
|
player2_deck = p2_deck
|
|
is_vs_ai = p_is_vs_ai
|
|
ai_difficulty = p_ai_difficulty
|
|
|
|
if game_setup_menu:
|
|
game_setup_menu.visible = false
|
|
|
|
# Switch to game window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, false)
|
|
DisplayServer.window_set_size(GAME_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - GAME_SIZE.x) / 2,
|
|
(screen.y - GAME_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to game size
|
|
get_tree().root.content_scale_size = GAME_SIZE
|
|
|
|
_start_new_game()
|
|
|
|
|
|
func _on_deck_selected(deck: Deck) -> void:
|
|
selected_deck = deck
|
|
if deck_builder:
|
|
deck_builder.visible = false
|
|
|
|
# Switch to game window size and start game
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, false)
|
|
DisplayServer.window_set_size(GAME_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - GAME_SIZE.x) / 2,
|
|
(screen.y - GAME_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to game size
|
|
get_tree().root.content_scale_size = GAME_SIZE
|
|
|
|
_start_new_game()
|
|
|
|
func _start_new_game() -> void:
|
|
# Make sure game isn't paused
|
|
get_tree().paused = false
|
|
|
|
# Clean up existing game
|
|
if game_scene:
|
|
game_scene.queue_free()
|
|
game_scene = null
|
|
|
|
# Reset GameManager state
|
|
if GameManager:
|
|
GameManager.is_game_active = false
|
|
GameManager.game_state = null
|
|
|
|
# Create new game scene
|
|
game_scene = Node3D.new()
|
|
game_scene.set_script(MainScript)
|
|
|
|
# Pass deck configurations if available
|
|
if player1_deck.size() > 0:
|
|
game_scene.player1_deck = player1_deck
|
|
if player2_deck.size() > 0:
|
|
game_scene.player2_deck = player2_deck
|
|
|
|
# Pass AI configuration
|
|
game_scene.is_vs_ai = is_vs_ai
|
|
game_scene.ai_difficulty = ai_difficulty
|
|
|
|
add_child(game_scene)
|
|
|
|
# Create pause menu
|
|
if not pause_menu:
|
|
pause_menu = PauseMenu.new()
|
|
add_child(pause_menu)
|
|
pause_menu.resume_game.connect(_on_resume_game)
|
|
pause_menu.restart_game.connect(_on_restart_game)
|
|
pause_menu.return_to_menu.connect(_on_return_to_menu)
|
|
|
|
current_state = State.PLAYING
|
|
|
|
func _show_pause_menu() -> void:
|
|
if pause_menu:
|
|
pause_menu.show_menu()
|
|
current_state = State.PAUSED
|
|
|
|
func _hide_pause_menu() -> void:
|
|
if pause_menu:
|
|
pause_menu.hide_menu()
|
|
current_state = State.PLAYING
|
|
|
|
func _on_resume_game() -> void:
|
|
current_state = State.PLAYING
|
|
|
|
func _on_restart_game() -> void:
|
|
_start_new_game()
|
|
|
|
func _on_return_to_menu() -> void:
|
|
_show_main_menu()
|
|
|
|
|
|
# ======= ONLINE PLAY =======
|
|
|
|
func _on_online_game() -> void:
|
|
# Hide menu
|
|
if main_menu:
|
|
main_menu.visible = false
|
|
|
|
# Check if already authenticated
|
|
if NetworkManager and NetworkManager.is_authenticated:
|
|
_show_online_lobby()
|
|
else:
|
|
_show_login_screen()
|
|
|
|
|
|
func _show_login_screen() -> void:
|
|
# Switch to login screen window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
|
|
DisplayServer.window_set_size(LOGIN_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - LOGIN_SIZE.x) / 2,
|
|
(screen.y - LOGIN_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to login size
|
|
get_tree().root.content_scale_size = LOGIN_SIZE
|
|
|
|
# Create login screen
|
|
if not login_screen:
|
|
login_screen = LoginScreen.new()
|
|
add_child(login_screen)
|
|
login_screen.login_successful.connect(_on_login_successful)
|
|
login_screen.register_requested.connect(_on_register_requested)
|
|
login_screen.back_pressed.connect(_on_login_back)
|
|
|
|
login_screen.visible = true
|
|
login_screen.focus_email()
|
|
current_state = State.LOGIN
|
|
|
|
|
|
func _on_login_back() -> void:
|
|
if login_screen:
|
|
login_screen.visible = false
|
|
login_screen.clear_form()
|
|
_show_main_menu()
|
|
|
|
|
|
func _on_login_successful(_user_data: Dictionary) -> void:
|
|
if login_screen:
|
|
login_screen.visible = false
|
|
login_screen.clear_form()
|
|
_show_online_lobby()
|
|
|
|
|
|
func _on_register_requested() -> void:
|
|
if login_screen:
|
|
login_screen.visible = false
|
|
login_screen.clear_form()
|
|
_show_register_screen()
|
|
|
|
|
|
func _show_register_screen() -> void:
|
|
# Switch to register screen window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
|
|
DisplayServer.window_set_size(REGISTER_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - REGISTER_SIZE.x) / 2,
|
|
(screen.y - REGISTER_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to register size
|
|
get_tree().root.content_scale_size = REGISTER_SIZE
|
|
|
|
# Create register screen
|
|
if not register_screen:
|
|
register_screen = RegisterScreen.new()
|
|
add_child(register_screen)
|
|
register_screen.registration_successful.connect(_on_registration_successful)
|
|
register_screen.login_requested.connect(_on_login_from_register)
|
|
register_screen.back_pressed.connect(_on_register_back)
|
|
|
|
register_screen.visible = true
|
|
register_screen.focus_email()
|
|
current_state = State.REGISTER
|
|
|
|
|
|
func _on_register_back() -> void:
|
|
if register_screen:
|
|
register_screen.visible = false
|
|
register_screen.clear_form()
|
|
_show_main_menu()
|
|
|
|
|
|
func _on_registration_successful(_message: String) -> void:
|
|
# After successful registration, show login screen
|
|
if register_screen:
|
|
register_screen.visible = false
|
|
register_screen.clear_form()
|
|
_show_login_screen()
|
|
|
|
|
|
func _on_login_from_register() -> void:
|
|
if register_screen:
|
|
register_screen.visible = false
|
|
register_screen.clear_form()
|
|
_show_login_screen()
|
|
|
|
|
|
func _show_online_lobby() -> void:
|
|
# Switch to online lobby window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
|
|
DisplayServer.window_set_size(ONLINE_LOBBY_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - ONLINE_LOBBY_SIZE.x) / 2,
|
|
(screen.y - ONLINE_LOBBY_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to online lobby size
|
|
get_tree().root.content_scale_size = ONLINE_LOBBY_SIZE
|
|
|
|
# Create online lobby
|
|
if not online_lobby:
|
|
online_lobby = OnlineLobby.new()
|
|
add_child(online_lobby)
|
|
online_lobby.back_pressed.connect(_on_online_lobby_back)
|
|
online_lobby.game_starting.connect(_on_online_game_starting)
|
|
online_lobby.profile_requested.connect(_show_profile_screen)
|
|
online_lobby.leaderboard_requested.connect(_show_leaderboard_screen)
|
|
|
|
# Connect to game_ended signal for handling online game completion
|
|
if NetworkManager and not NetworkManager.game_ended.is_connected(_on_online_game_ended):
|
|
NetworkManager.game_ended.connect(_on_online_game_ended)
|
|
|
|
online_lobby.visible = true
|
|
current_state = State.ONLINE_LOBBY
|
|
|
|
|
|
func _on_online_lobby_back() -> void:
|
|
if online_lobby:
|
|
online_lobby.visible = false
|
|
_show_main_menu()
|
|
|
|
|
|
func _on_online_game_starting(game_data: Dictionary) -> void:
|
|
if online_lobby:
|
|
online_lobby.visible = false
|
|
|
|
# Store game data
|
|
online_game_data = game_data
|
|
is_online_game = true
|
|
|
|
var opponent = game_data.get("opponent", {})
|
|
print("Starting online game against: ", opponent.get("username", "Unknown"))
|
|
print("Game ID: ", game_data.get("game_id", ""))
|
|
print("Local player index: ", game_data.get("your_player_index", 0))
|
|
print("First player: ", game_data.get("first_player", 0))
|
|
|
|
# Switch to game window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, false)
|
|
DisplayServer.window_set_size(GAME_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - GAME_SIZE.x) / 2,
|
|
(screen.y - GAME_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to game size
|
|
get_tree().root.content_scale_size = GAME_SIZE
|
|
|
|
_start_online_game(game_data)
|
|
|
|
|
|
func _start_online_game(game_data: Dictionary) -> void:
|
|
# Make sure game isn't paused
|
|
get_tree().paused = false
|
|
|
|
# Clean up existing game
|
|
if game_scene:
|
|
game_scene.queue_free()
|
|
game_scene = null
|
|
|
|
# Reset GameManager state
|
|
if GameManager:
|
|
GameManager.is_game_active = false
|
|
GameManager.game_state = null
|
|
|
|
# Create new game scene
|
|
game_scene = Node3D.new()
|
|
game_scene.set_script(MainScript)
|
|
|
|
# Mark as online game
|
|
game_scene.is_online_game = true
|
|
|
|
# Get the deck ID from NetworkManager (set when joining queue/room)
|
|
var deck_id = game_data.get("deck_id", "")
|
|
var local_player_index = game_data.get("your_player_index", 0)
|
|
|
|
# Load the selected deck for the local player
|
|
var local_deck = _load_deck_by_id(deck_id)
|
|
|
|
# For online games, player positions are swapped based on index
|
|
# The local player is always displayed on the bottom (player 1 position visually)
|
|
# But the game logic uses the server-assigned indices
|
|
if local_player_index == 0:
|
|
game_scene.player1_deck = local_deck
|
|
game_scene.player2_deck = [] # Opponent's deck is hidden
|
|
else:
|
|
game_scene.player1_deck = [] # Opponent's deck is hidden
|
|
game_scene.player2_deck = local_deck
|
|
|
|
# Pass game configuration
|
|
game_scene.is_vs_ai = false
|
|
game_scene.online_game_data = game_data
|
|
|
|
add_child(game_scene)
|
|
|
|
# Setup online game specifics after scene is added
|
|
game_scene.setup_online_game(game_data)
|
|
|
|
# Create online pause menu (no restart option, has forfeit)
|
|
_create_online_pause_menu()
|
|
|
|
current_state = State.ONLINE_GAME
|
|
|
|
|
|
func _load_deck_by_id(deck_id: String) -> Array:
|
|
# Load deck from CardDatabase saved decks or starter decks
|
|
if deck_id.is_empty():
|
|
# Use default starter deck
|
|
return CardDatabase.get_starter_deck_ids("Fire Starter")
|
|
|
|
# Check saved decks
|
|
var saved_decks = CardDatabase.get_saved_decks()
|
|
for deck in saved_decks:
|
|
if deck.get("id", "") == deck_id:
|
|
return deck.get("card_ids", [])
|
|
|
|
# Check starter decks
|
|
var starter_decks = CardDatabase.get_starter_decks()
|
|
for deck in starter_decks:
|
|
if deck.get("id", "") == deck_id:
|
|
return deck.get("card_ids", [])
|
|
|
|
# Fallback to first starter deck
|
|
return CardDatabase.get_starter_deck_ids("Fire Starter")
|
|
|
|
|
|
func _create_online_pause_menu() -> void:
|
|
if online_pause_menu:
|
|
online_pause_menu.queue_free()
|
|
|
|
online_pause_menu = Control.new()
|
|
online_pause_menu.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
online_pause_menu.visible = false
|
|
|
|
# Semi-transparent background
|
|
var bg = ColorRect.new()
|
|
bg.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
bg.color = Color(0, 0, 0, 0.7)
|
|
online_pause_menu.add_child(bg)
|
|
|
|
# Menu container
|
|
var container = VBoxContainer.new()
|
|
container.set_anchors_preset(Control.PRESET_CENTER)
|
|
container.custom_minimum_size = Vector2(300, 200)
|
|
container.add_theme_constant_override("separation", 20)
|
|
online_pause_menu.add_child(container)
|
|
|
|
# Title
|
|
var title = Label.new()
|
|
title.text = "PAUSED"
|
|
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
title.add_theme_font_size_override("font_size", 32)
|
|
container.add_child(title)
|
|
|
|
# Resume button
|
|
var resume_btn = Button.new()
|
|
resume_btn.text = "Resume"
|
|
resume_btn.custom_minimum_size = Vector2(200, 50)
|
|
resume_btn.pressed.connect(_hide_online_pause_menu)
|
|
container.add_child(resume_btn)
|
|
|
|
# Forfeit button
|
|
var forfeit_btn = Button.new()
|
|
forfeit_btn.text = "Forfeit Game"
|
|
forfeit_btn.custom_minimum_size = Vector2(200, 50)
|
|
forfeit_btn.pressed.connect(_on_forfeit_game)
|
|
container.add_child(forfeit_btn)
|
|
|
|
add_child(online_pause_menu)
|
|
|
|
|
|
func _show_online_pause_menu() -> void:
|
|
if online_pause_menu:
|
|
online_pause_menu.visible = true
|
|
get_tree().paused = true
|
|
|
|
|
|
func _hide_online_pause_menu() -> void:
|
|
if online_pause_menu:
|
|
online_pause_menu.visible = false
|
|
get_tree().paused = false
|
|
|
|
|
|
func _on_forfeit_game() -> void:
|
|
# Send concede to server
|
|
if NetworkManager:
|
|
NetworkManager.send_concede()
|
|
|
|
_hide_online_pause_menu()
|
|
# Game end will be handled by the game_ended signal
|
|
|
|
|
|
func _on_online_game_ended(_result: Dictionary) -> void:
|
|
is_online_game = false
|
|
online_game_data = {}
|
|
|
|
if online_pause_menu:
|
|
online_pause_menu.queue_free()
|
|
online_pause_menu = null
|
|
|
|
# Return to online lobby after a delay
|
|
await get_tree().create_timer(3.0).timeout
|
|
_show_online_lobby()
|
|
|
|
|
|
# ======= PROFILE SCREEN =======
|
|
|
|
func _show_profile_screen() -> void:
|
|
# Hide online lobby
|
|
if online_lobby:
|
|
online_lobby.visible = false
|
|
|
|
# Switch to profile screen window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
|
|
DisplayServer.window_set_size(PROFILE_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - PROFILE_SIZE.x) / 2,
|
|
(screen.y - PROFILE_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to profile size
|
|
get_tree().root.content_scale_size = PROFILE_SIZE
|
|
|
|
# Create profile screen
|
|
if not profile_screen:
|
|
profile_screen = ProfileScreen.new()
|
|
add_child(profile_screen)
|
|
profile_screen.back_pressed.connect(_on_profile_back)
|
|
else:
|
|
profile_screen.refresh()
|
|
|
|
profile_screen.visible = true
|
|
current_state = State.PROFILE
|
|
|
|
|
|
func _on_profile_back() -> void:
|
|
if profile_screen:
|
|
profile_screen.visible = false
|
|
_show_online_lobby()
|
|
|
|
|
|
# ======= LEADERBOARD SCREEN =======
|
|
|
|
func _show_leaderboard_screen() -> void:
|
|
# Hide online lobby
|
|
if online_lobby:
|
|
online_lobby.visible = false
|
|
|
|
# Switch to leaderboard screen window size
|
|
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
|
|
DisplayServer.window_set_size(LEADERBOARD_SIZE)
|
|
var screen := DisplayServer.screen_get_size()
|
|
DisplayServer.window_set_position(Vector2i(
|
|
(screen.x - LEADERBOARD_SIZE.x) / 2,
|
|
(screen.y - LEADERBOARD_SIZE.y) / 2
|
|
))
|
|
|
|
# Set viewport to leaderboard size
|
|
get_tree().root.content_scale_size = LEADERBOARD_SIZE
|
|
|
|
# Create leaderboard screen
|
|
if not leaderboard_screen:
|
|
leaderboard_screen = LeaderboardScreen.new()
|
|
add_child(leaderboard_screen)
|
|
leaderboard_screen.back_pressed.connect(_on_leaderboard_back)
|
|
else:
|
|
leaderboard_screen.refresh()
|
|
|
|
leaderboard_screen.visible = true
|
|
current_state = State.LEADERBOARD
|
|
|
|
|
|
func _on_leaderboard_back() -> void:
|
|
if leaderboard_screen:
|
|
leaderboard_screen.visible = false
|
|
_show_online_lobby()
|