Merge branch 'feature/menu-system'
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dogqi2c58qdc0"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bkcouefvi7iup" path="res://scripts/star_system.gd" id="1_ig7tw"]
|
||||
[ext_resource type="PackedScene" uid="uid://ojcho3pi3u7n" path="res://scenes/UI/main_menu/main_menu.tscn" id="1_ig7tw"]
|
||||
|
||||
[node name="StarSystem" type="Node3D"]
|
||||
script = ExtResource("1_ig7tw")
|
||||
[node name="StartMenu" type="Node3D" unique_id=1392183658]
|
||||
|
||||
[node name="MainMenu" parent="." unique_id=2099645465 instance=ExtResource("1_ig7tw")]
|
||||
|
||||
35
src/scenes/UI/ingame_menu/ingame_menu.gd
Normal file
35
src/scenes/UI/ingame_menu/ingame_menu.gd
Normal file
@ -0,0 +1,35 @@
|
||||
extends Control
|
||||
|
||||
@onready var resume_button: Button = %ResumeButton
|
||||
@onready var disconnect_button: Button = %DisconnectButton
|
||||
@onready var quit_button: Button = %QuitButton
|
||||
|
||||
func _ready():
|
||||
resume_button.pressed.connect(toggle_menu)
|
||||
disconnect_button.pressed.connect(_on_disconnect_pressed)
|
||||
quit_button.pressed.connect(_on_quit_pressed)
|
||||
|
||||
hide()
|
||||
|
||||
func _input(event):
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
toggle_menu()
|
||||
|
||||
func toggle_menu():
|
||||
visible = !visible
|
||||
|
||||
if visible:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
else:
|
||||
# Only capture mouse if we are actually playing a pawn
|
||||
# You might need a smarter check here depending on game state
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
func _on_disconnect_pressed():
|
||||
NetworkHandler.close_connection()
|
||||
toggle_menu()
|
||||
# Return to main menu
|
||||
get_tree().change_scene_to_file("res://main.tscn")
|
||||
|
||||
func _on_quit_pressed():
|
||||
get_tree().quit()
|
||||
1
src/scenes/UI/ingame_menu/ingame_menu.gd.uid
Normal file
1
src/scenes/UI/ingame_menu/ingame_menu.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://2aoy8ivk2hgl
|
||||
58
src/scenes/UI/ingame_menu/ingame_menu.tscn
Normal file
58
src/scenes/UI/ingame_menu/ingame_menu.tscn
Normal file
@ -0,0 +1,58 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://pausemenu456"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://2aoy8ivk2hgl" path="res://scenes/UI/ingame_menu/ingame_menu.gd" id="1_pm_script"]
|
||||
|
||||
[node name="IngameeMenu" type="Control" unique_id=8878860]
|
||||
process_mode = 3
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_pm_script")
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="." unique_id=1882361500]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0, 0, 0, 0.05)
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="." unique_id=1122355242]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer" unique_id=1948011184]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 15
|
||||
|
||||
[node name="Label" type="Label" parent="CenterContainer/VBoxContainer" unique_id=214886966]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 32
|
||||
text = "Menu"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ResumeButton" type="Button" parent="CenterContainer/VBoxContainer" unique_id=1856665966]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
text = "Resume"
|
||||
|
||||
[node name="DisconnectButton" type="Button" parent="CenterContainer/VBoxContainer" unique_id=4948876]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
text = "Disconnect"
|
||||
|
||||
[node name="QuitButton" type="Button" parent="CenterContainer/VBoxContainer" unique_id=1695513560]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
text = "Quit Game"
|
||||
47
src/scenes/UI/main_menu/main_menu.gd
Normal file
47
src/scenes/UI/main_menu/main_menu.gd
Normal file
@ -0,0 +1,47 @@
|
||||
extends Control
|
||||
|
||||
# @export var lobby_menu: Control
|
||||
# @export var settings_menu: Control
|
||||
|
||||
# Buttons and input fields
|
||||
@onready var host_button: Button = %HostButton
|
||||
@onready var join_button: Button = %JoinButton
|
||||
@onready var settings_button: Button = %SettingsButton
|
||||
@onready var quit_button: Button = %QuitButton
|
||||
@onready var address_entry: LineEdit = %AddressEntry
|
||||
|
||||
func _ready():
|
||||
host_button.pressed.connect(_on_host_pressed)
|
||||
join_button.pressed.connect(_on_join_pressed)
|
||||
quit_button.pressed.connect(_on_quit_pressed)
|
||||
|
||||
# Ensure we start with a clean slate
|
||||
# lobby_menu.visible = false
|
||||
|
||||
# If we just returned from a game, ensure mouse is visible
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
|
||||
func _on_host_pressed():
|
||||
# For a simple test, hosting immediately starts the server and the game
|
||||
NetworkHandler.create_server()
|
||||
NetworkHandler.on_peer_connected(multiplayer.get_unique_id())
|
||||
_transition_to_game()
|
||||
|
||||
func _on_join_pressed():
|
||||
var ip = address_entry.text
|
||||
if ip.is_empty():
|
||||
ip = "127.0.0.1" # Default to localhost
|
||||
|
||||
NetworkHandler.create_client(ip)
|
||||
# The NetworkHandler signals will handle the actual transition once connected
|
||||
# But for UI feedback, we might want to show a "Connecting..." label here.
|
||||
|
||||
func _on_quit_pressed():
|
||||
get_tree().quit()
|
||||
|
||||
func _transition_to_game():
|
||||
# This would typically load the main game scene.
|
||||
# Since your main scene IS the game loop currently, we might need to
|
||||
# just hide the menu if it's an overlay, OR change scenes.
|
||||
# Assuming Main.tscn is the game world:
|
||||
get_tree().change_scene_to_file("res://scripts/star_system.tscn")
|
||||
1
src/scenes/UI/main_menu/main_menu.gd.uid
Normal file
1
src/scenes/UI/main_menu/main_menu.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://dypq4h3hy1l3v
|
||||
78
src/scenes/UI/main_menu/main_menu.tscn
Normal file
78
src/scenes/UI/main_menu/main_menu.tscn
Normal file
@ -0,0 +1,78 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://ojcho3pi3u7n"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dypq4h3hy1l3v" path="res://scenes/UI/main_menu/main_menu.gd" id="1_script"]
|
||||
|
||||
[node name="MainMenu" type="Control" unique_id=2099645465]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="Background" type="ColorRect" parent="." unique_id=2137889995]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.05, 0.05, 0.08, 1)
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="." unique_id=1954458945]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer" unique_id=542164632]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 20
|
||||
|
||||
[node name="Label" type="Label" parent="CenterContainer/VBoxContainer" unique_id=973405608]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 48
|
||||
text = "Millimeters of Aluminium"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="AddressEntry" type="LineEdit" parent="CenterContainer/VBoxContainer" unique_id=994010326]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
placeholder_text = "127.0.0.1"
|
||||
alignment = 1
|
||||
|
||||
[node name="HostButton" type="Button" parent="CenterContainer/VBoxContainer" unique_id=1548149031]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(200, 50)
|
||||
layout_mode = 2
|
||||
text = "Host Game"
|
||||
|
||||
[node name="JoinButton" type="Button" parent="CenterContainer/VBoxContainer" unique_id=1826215269]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(200, 50)
|
||||
layout_mode = 2
|
||||
text = "Join Game"
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="CenterContainer/VBoxContainer" unique_id=811999044]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(200, 50)
|
||||
layout_mode = 2
|
||||
text = "Settings"
|
||||
|
||||
[node name="QuitButton" type="Button" parent="CenterContainer/VBoxContainer" unique_id=1005717980]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(200, 50)
|
||||
layout_mode = 2
|
||||
text = "Quit to Desktop"
|
||||
|
||||
[node name="LobbyMenu" type="Control" parent="." unique_id=604668798]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
@ -106,7 +106,7 @@ func _notification(what):
|
||||
NOTIFICATION_WM_WINDOW_FOCUS_IN:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
NOTIFICATION_EXIT_TREE:
|
||||
print("PlayerController %s exited tree" % multiplayer.get_unique_id())
|
||||
print("PlayerController exited tree")
|
||||
NOTIFICATION_ENTER_TREE:
|
||||
print("PlayerController %s entered tree" % multiplayer.get_unique_id())
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@ func close_connection():
|
||||
multiplayer.multiplayer_peer = null
|
||||
print("Connection closed.")
|
||||
_disconnect_signals()
|
||||
GameManager.reset_game_state()
|
||||
|
||||
func setup_connections():
|
||||
if not multiplayer.peer_connected.is_connected(on_peer_connected):
|
||||
@ -71,12 +72,18 @@ func on_peer_disconnected(peer_id: int) -> void:
|
||||
print("Peer %s lost connection to: %s" % [multiplayer.get_unique_id(), peer_id])
|
||||
# TODO: GameManager should cleanup the player's pawn
|
||||
|
||||
GameManager.remove_player_pawn(peer_id)
|
||||
|
||||
func on_connected_to_server() -> void:
|
||||
print("%s connected to server!" % multiplayer.get_unique_id())
|
||||
# If we are in the main menu, this is the trigger to switch scenes
|
||||
if get_tree().current_scene.name == "MainMenu":
|
||||
get_tree().change_scene_to_file("res://main.tscn")
|
||||
if get_tree().current_scene.name == "StartMenu":
|
||||
print("Transitioning to game scene...")
|
||||
get_tree().change_scene_to_file("res://scripts/star_system.tscn")
|
||||
else:
|
||||
print("Player ID %s: Already in game scene." % multiplayer.get_unique_id())
|
||||
|
||||
func on_server_disconnected() -> void:
|
||||
print("Disconnected from server.")
|
||||
get_tree().change_scene_to_file("res://scenes/UI/main_menu.tscn")
|
||||
get_tree().change_scene_to_file("res://main.tscn")
|
||||
GameManager.reset_game_state()
|
||||
|
||||
@ -26,31 +26,30 @@ func _ready():
|
||||
print("GameManager: game_config.tres not found or used. Using direct 3D scene references.")
|
||||
return
|
||||
|
||||
# Check command-line arguments to determine if this instance should be a server or client.
|
||||
# Godot's "Run Multiple Instances" feature adds "--server" to the main instance.
|
||||
if "--server" in OS.get_cmdline_args():
|
||||
NetworkHandler.create_server()
|
||||
elif "--host" in OS.get_cmdline_args():
|
||||
NetworkHandler.create_server()
|
||||
# Host also acts as a player, so we need to handle its own connection.
|
||||
NetworkHandler.on_peer_connected.call_deferred(1)
|
||||
else:
|
||||
print("GameManager: Starting as CLIENT.")
|
||||
NetworkHandler.create_client()
|
||||
|
||||
func _process(_delta):
|
||||
if find_available_spawner():
|
||||
_try_spawn_waiting_player()
|
||||
if not multiplayer.multiplayer_peer: return
|
||||
if not multiplayer.is_server(): return
|
||||
|
||||
# Called when the game starts (e.g., from _ready() in StarSystemGenerator)
|
||||
func start_game():
|
||||
pass
|
||||
# Safety check: don't try to spawn if the system isn't ready or is deleted
|
||||
if not is_instance_valid(current_star_system): return
|
||||
|
||||
if not waiting_players.is_empty() and find_available_spawner():
|
||||
_try_spawn_waiting_player()
|
||||
|
||||
|
||||
func queue_spawn_player(player_id: int):
|
||||
waiting_players.append(player_id)
|
||||
print("GameManager: Player %d queued for spawn." % player_id)
|
||||
|
||||
func remove_player_pawn(player_id: int):
|
||||
if player_pawns.has(player_id):
|
||||
var pawn = player_pawns[player_id]
|
||||
if is_instance_valid(pawn):
|
||||
pawn.queue_free()
|
||||
player_pawns.erase(player_id)
|
||||
print("GameManager: Removed pawn for player %d." % player_id)
|
||||
else:
|
||||
print("GameManager: No pawn found for player %d to remove." % player_id)
|
||||
|
||||
# function to process the waiting queue.
|
||||
func _try_spawn_waiting_player():
|
||||
@ -84,6 +83,8 @@ func _try_spawn_waiting_player():
|
||||
print("GameManager peer %s: Failed to spawn player %d." % [multiplayer.get_unique_id(), player_id])
|
||||
|
||||
func find_available_spawner() -> Spawner:
|
||||
if not registered_spawners:
|
||||
return null
|
||||
var idx = registered_spawners.find_custom(func(spawner: Spawner) -> bool:
|
||||
return spawner.can_spawn()
|
||||
)
|
||||
@ -155,3 +156,13 @@ func _get_orbital_body_ancestor(node: Node) -> OrbitalBody3D:
|
||||
return current
|
||||
current = current.get_parent()
|
||||
return null
|
||||
|
||||
func reset_game_state():
|
||||
current_star_system = null
|
||||
registered_spawners.clear()
|
||||
waiting_players.clear()
|
||||
player_pawns.clear()
|
||||
player_controllers.clear()
|
||||
|
||||
# Reset any other state variables
|
||||
print("GameManager state cleared.")
|
||||
|
||||
@ -9,6 +9,8 @@ extends Node3D
|
||||
|
||||
var system_data: SystemData
|
||||
|
||||
const PAUSE_MENU_SCENE = preload("res://scenes/UI/ingame_menu/ingame_menu.tscn")
|
||||
|
||||
func _ready():
|
||||
# 1. Create the generator tool.
|
||||
|
||||
@ -30,11 +32,21 @@ func _ready():
|
||||
# We can reconstruct 'system_data' by scanning children if needed,
|
||||
# or just let GameManager find them via 'get_children()'.
|
||||
|
||||
# 2. Tell the generator to build the system within this StarSystem node.
|
||||
|
||||
# 3. Register the completed system with the GameManager.
|
||||
# 2. Register the completed system with the GameManager.
|
||||
GameManager.register_star_system(self)
|
||||
GameManager.start_game()
|
||||
|
||||
# 3. Instantiate UI (Local Player Only)
|
||||
if not DisplayServer.get_name() == "headless":
|
||||
_setup_ui()
|
||||
|
||||
|
||||
func _setup_ui():
|
||||
var canvas_layer = CanvasLayer.new()
|
||||
add_child(canvas_layer)
|
||||
var pause_menu = PAUSE_MENU_SCENE.instantiate()
|
||||
canvas_layer.add_child(pause_menu)
|
||||
|
||||
|
||||
# --- Public API for accessing system data ---
|
||||
func get_star() -> OrbitalBody3D:
|
||||
|
||||
Reference in New Issue
Block a user