diff --git a/node_3d.tscn b/Game.tscn similarity index 88% rename from node_3d.tscn rename to Game.tscn index 8f41630..2b6a7c1 100644 --- a/node_3d.tscn +++ b/Game.tscn @@ -1,28 +1,28 @@ [gd_scene load_steps=18 format=3 uid="uid://bx0bbrwdr0h40"] -[ext_resource type="Script" path="res://HexGrid3D/HexGrid3D.gd" id="2_xcbqy"] -[ext_resource type="Script" path="res://WebLightChecker.gd" id="6_uu0ab"] -[ext_resource type="Texture2D" uid="uid://cilgpyanfb3a8" path="res://Testbed/textures/wood_table_001_diff_4k.jpg" id="6_x76sf"] -[ext_resource type="Texture2D" uid="uid://diamo44e2x4if" path="res://Testbed/textures/wood_table_001_disp_4k.png" id="7_xr322"] -[ext_resource type="Script" path="res://BuildMenu.gd" id="8_lxt1e"] -[ext_resource type="Texture2D" uid="uid://b6ejmikbfrprs" path="res://Testbed/textures/wood_table_001_rough_4k.jpg" id="8_wvt2u"] -[ext_resource type="PackedScene" uid="uid://bo8hgq66dbbb6" path="res://UI/insect_button.tscn" id="11_pmmaq"] -[ext_resource type="Script" path="res://Misc/RTSCamera3D.gd" id="12_o7k50"] +[ext_resource type="Script" path="res://Misc/RTSCamera3D.gd" id="1_dtmfo"] +[ext_resource type="Script" path="res://HexGrid3D/HexGrid3D.gd" id="2_suxca"] +[ext_resource type="Texture2D" uid="uid://cilgpyanfb3a8" path="res://Testbed/textures/wood_table_001_diff_4k.jpg" id="3_w3jge"] +[ext_resource type="Texture2D" uid="uid://diamo44e2x4if" path="res://Testbed/textures/wood_table_001_disp_4k.png" id="4_b7cy7"] +[ext_resource type="Texture2D" uid="uid://b6ejmikbfrprs" path="res://Testbed/textures/wood_table_001_rough_4k.jpg" id="5_lck42"] +[ext_resource type="Script" path="res://WebLightChecker.gd" id="6_41m5i"] +[ext_resource type="Script" path="res://UI/BuildMenu.gd" id="7_1oc55"] +[ext_resource type="PackedScene" uid="uid://bo8hgq66dbbb6" path="res://UI/insect_button.tscn" id="8_lfn34"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_u8oxs"] -albedo_texture = ExtResource("6_x76sf") -roughness_texture = ExtResource("8_wvt2u") +albedo_texture = ExtResource("3_w3jge") +roughness_texture = ExtResource("5_lck42") roughness_texture_channel = 4 normal_enabled = true normal_scale = 0.1 -normal_texture = ExtResource("7_xr322") +normal_texture = ExtResource("4_b7cy7") heightmap_scale = 1.0 heightmap_deep_parallax = true heightmap_min_layers = 1 heightmap_max_layers = 1 -heightmap_texture = ExtResource("7_xr322") +heightmap_texture = ExtResource("4_b7cy7") refraction_scale = 0.28 -refraction_texture = ExtResource("7_xr322") +refraction_texture = ExtResource("4_b7cy7") texture_filter = 5 [sub_resource type="PlaneMesh" id="PlaneMesh_cu5ir"] @@ -63,11 +63,11 @@ modulate_color = Color(1, 1, 1, 0.639216) [node name="Camera3D" type="Camera3D" parent="."] transform = Transform3D(1, 0, 0, 0, 0.5, 0.866025, 0, -0.866025, 0.5, 0, 6, 5) -script = ExtResource("12_o7k50") +script = ExtResource("1_dtmfo") edge_panning_enabled = false [node name="HexGrid" type="Node3D" parent="."] -script = ExtResource("2_xcbqy") +script = ExtResource("2_suxca") [node name="PlacementVisualizer" type="Node3D" parent="HexGrid"] @@ -85,7 +85,7 @@ transform = Transform3D(0.843961, -0.46784, 0.262404, -0.0775016, 0.377705, 0.92 light_color = Color(1, 0.941176, 0.823529, 1) shadow_enabled = true directional_shadow_blend_splits = true -script = ExtResource("6_uu0ab") +script = ExtResource("6_41m5i") [node name="BuildMenu" type="Control" parent="."] layout_mode = 3 @@ -96,7 +96,7 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 0 mouse_filter = 2 -script = ExtResource("8_lxt1e") +script = ExtResource("7_1oc55") [node name="PanelContainer" type="PanelContainer" parent="BuildMenu"] layout_mode = 1 @@ -153,7 +153,7 @@ alignment = 1 layout_mode = 2 mouse_filter = 0 -[node name="BeeButton" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/LocalPlayerInsects" instance=ExtResource("11_pmmaq")] +[node name="BeeButton" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/LocalPlayerInsects" instance=ExtResource("8_lfn34")] layout_mode = 2 [node name="VSeparator" type="VSeparator" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/LocalPlayerInsects"] @@ -172,6 +172,6 @@ mouse_filter = 0 [node name="VSeparator" type="VSeparator" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/RemotePlayerInsects"] layout_mode = 2 -[node name="BeeButton" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/RemotePlayerInsects" instance=ExtResource("11_pmmaq")] +[node name="BeeButton" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/RemotePlayerInsects" instance=ExtResource("8_lfn34")] layout_mode = 2 is_black = true diff --git a/Globals/GameData.gd b/Globals/GameData.gd index e468f07..da5193b 100644 --- a/Globals/GameData.gd +++ b/Globals/GameData.gd @@ -1,5 +1,9 @@ extends Node +const WEBSOCKET_ENDPOINT: String = "wss://dev.bytesandpieces.xyz:9088" + var is_player_black: bool = true -var debug: bool = true +var debug: bool = false var allow_selecting_in_stack: bool = false + +var lobby_code: String = "" diff --git a/HexGrid3D/HexGrid3D.gd b/HexGrid3D/HexGrid3D.gd index f4443e5..a5fd905 100644 --- a/HexGrid3D/HexGrid3D.gd +++ b/HexGrid3D/HexGrid3D.gd @@ -328,7 +328,10 @@ func _on_insect_placement_cancelled() -> void: for child in placement_visualizer.get_children(): child.queue_free() -func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void: +@rpc("any_peer", "call_local") +func place_insect_tile(resource_path: String, is_black: bool, pos: Vector4i) -> void: + var resource = load(resource_path) + var tile_copy = INSECT_TILE.instantiate() var hex_pos = cube_to_world_pos(pos) @@ -347,6 +350,12 @@ func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> var tween = get_tree().create_tween() tween.tween_property(tile_copy, "position", target_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO) + + +func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void: + var resource_path = resource.resource_path + place_insect_tile.rpc(resource_path, is_black, pos) + func can_move(tile: InsectTile) -> bool: return can_hive_exist_without_tile(tile) @@ -415,7 +424,10 @@ func _on_insect_tile_selected(tile: InsectTile) -> void: func get_tile(pos: Vector4i) -> InsectTile: return used_cells.get(pos) -func _on_insect_tile_moved(tile: InsectTile, target: Vector4i) -> void: +@rpc("any_peer", "call_local") +func move_insect_tile(tile_coords: Vector4i, target: Vector4i) -> void: + var tile: InsectTile = used_cells[tile_coords] + # Remove from old stack if tile.coordinates.w > 0: var below: Vector4i = tile.coordinates + Vector4i(0, 0, 0, -1) @@ -444,6 +456,9 @@ func _on_insect_tile_moved(tile: InsectTile, target: Vector4i) -> void: used_cells[below].hat = tile # Add to new stack + +func _on_insect_tile_moved(tile: InsectTile, target: Vector4i) -> void: + move_insect_tile.rpc(tile.coordinates, target) func get_same_neighbours(cell1: Vector4i, cell2: Vector4i) -> Array[Vector4i]: var neighbours1 = get_neighbours(cell1).filter(is_cell_not_empty) diff --git a/InsectButton.gd b/InsectButton.gd index 8e032fd..14df72d 100644 --- a/InsectButton.gd +++ b/InsectButton.gd @@ -4,7 +4,7 @@ class_name InsectButton @onready var hex = $Hex @onready var tile_count_label = $Hex/TileCountLabel @onready var insect_icon = $Hex/InsectIcon -const BEE = preload("res://Tile/Prefabs/Bee.tres") +var BEE = load("res://Tile/Prefabs/Bee.tres") @export var insect_resource: TileResource = BEE const HEX_BLACK = preload("res://InsectTiles/Assets/UI/hex_black.svg") @@ -12,6 +12,8 @@ const HEX_WHITE = preload("res://InsectTiles/Assets/UI/hex_white.svg") @export var is_black: bool = false +var disable_amount_display: bool = false + var tile_count: int = 1 var selected: bool = false @@ -83,6 +85,9 @@ func refresh_state() -> void: func _ready() -> void: update_color(is_black) + if disable_amount_display: + $Hex/TileCountLabel.visible = false + GameEvents.insect_selected.connect(_on_insect_selected) GameEvents.insect_placement_cancelled.connect(_on_placement_cancelled) GameEvents.insect_placed.connect(_on_insect_placed) @@ -133,6 +138,9 @@ func _on_pressed(): if is_empty(): return + if GameData.is_player_black != is_black and not GameData.debug: + return + selected = true GameEvents.insect_selected.emit(self, is_black) diff --git a/Multiplayer/LobbyInfo.gd b/Multiplayer/LobbyInfo.gd new file mode 100644 index 0000000..8a15bf2 --- /dev/null +++ b/Multiplayer/LobbyInfo.gd @@ -0,0 +1,69 @@ +extends CanvasLayer + +@onready var insect_icons: HBoxContainer = $PanelContainer/VBoxContainer/InsectIcons + +@onready var lobby_code: Label = $PanelContainer/VBoxContainer/LobbyCode +const INSECT_BUTTON = preload("res://UI/insect_button.tscn") + +const insect_resources = [ + preload("res://Tile/Prefabs/Ant.tres"), + preload("res://Tile/Prefabs/Bee.tres"), + preload("res://Tile/Prefabs/Beetle.tres"), + preload("res://Tile/Prefabs/Grasshopper.tres"), + preload("res://Tile/Prefabs/Ladybug.tres"), + preload("res://Tile/Prefabs/Mosquito.tres"), + preload("res://Tile/Prefabs/Pillbug.tres"), + preload("res://Tile/Prefabs/Spider.tres") +] + +var insect_data = { + +} + +func prepare_insect_data() -> void: + var c: int = 65 + + for i in insect_resources: + for k in 2: + insect_data[String.chr(c)] = {"resource": i, "is_black": k%2 != 0} + c = c + 1 + + +@onready var start_game_button = $PanelContainer/VBoxContainer/StartGameButton + +func _on_connect() -> void: + lobby_code.text = "Waiting for the host to start the game..." + +# Called when the node enters the scene tree for the first time. +func _ready(): + multiplayer.connected_to_server.connect(_on_connect) + + if not multiplayer.is_server(): + return + + insect_icons.visible = true + start_game_button.visible = true + + lobby_code.text = GameData.lobby_code + + prepare_insect_data() + + for c in GameData.lobby_code: + var b = INSECT_BUTTON.instantiate() + b.deactivated = true + b.disabled = true + b.disable_amount_display = true + var data = insect_data[c] + b.is_black = data.is_black + b.insect_resource = data.resource + insect_icons.add_child(b) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + + +func _on_button_pressed(): + WSClient.stop() + get_tree().change_scene_to_file("res://main_menu.tscn") diff --git a/Multiplayer/Multiplayer.gd b/Multiplayer/Multiplayer.gd new file mode 100644 index 0000000..8f50002 --- /dev/null +++ b/Multiplayer/Multiplayer.gd @@ -0,0 +1,60 @@ +extends Node + +var has_opponent: bool = false +@onready var start_game_button = $LobbyInfo/PanelContainer/VBoxContainer/StartGameButton +@onready var game = $Game + +func _ready(): + multiplayer.connected_to_server.connect(_mp_server_connected) + multiplayer.connection_failed.connect(_mp_server_disconnect) + multiplayer.server_disconnected.connect(_mp_server_disconnect) + multiplayer.peer_connected.connect(_mp_peer_connected) + multiplayer.peer_disconnected.connect(_mp_peer_disconnected) + +func _mp_peer_disconnected(id: int) -> void: + has_opponent = false + start_game_button.disabled = true + + if id == 1: + # 1 is always the server + # So we better get going back to the main menu? + WSClient.close() + get_tree().change_scene_to_file("res://main_menu.tscn") + # Maybe just display a "server close + return + +func _log(msg): + print(msg) + +func _mp_server_connected(): + _log("[Multiplayer] Server connected (I am %d)" % WSClient.rtc_mp.get_unique_id()) + #pass_initial_playerdata.rpc_id(1, multiplayer.get_unique_id(), GameState.player_name) + +func _mp_server_disconnect(): + _log("[Multiplayer] Server disconnected (I am %d)" % WSClient.rtc_mp.get_unique_id()) + get_tree().change_scene_to_file("res://main_menu.tscn") + +func _mp_peer_connected(id: int): + _log("[Multiplayer] Peer %d connected" % id) + has_opponent = true + start_game_button.disabled = false + +@onready var lobby_info = $LobbyInfo + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass + +@rpc("any_peer", "call_local") +func load_game() -> void: + # Hide menu + # load game scene + lobby_info.visible = false + var game_scene = preload("res://Game.tscn").instantiate() + game.add_child(game_scene) + +func _on_start_game_button_pressed(): + # tell other peer to now load the world via rpc + load_game.rpc() + pass # Replace with function body. diff --git a/Multiplayer/Multiplayer.tscn b/Multiplayer/Multiplayer.tscn new file mode 100644 index 0000000..e7a6590 --- /dev/null +++ b/Multiplayer/Multiplayer.tscn @@ -0,0 +1,47 @@ +[gd_scene load_steps=3 format=3 uid="uid://bh31hq1uwqdts"] + +[ext_resource type="Script" path="res://Multiplayer/Multiplayer.gd" id="1_0n82x"] +[ext_resource type="Script" path="res://Multiplayer/LobbyInfo.gd" id="2_wf1xe"] + +[node name="Multiplayer" type="Node"] +script = ExtResource("1_0n82x") + +[node name="Game" type="Node" parent="."] + +[node name="LobbyInfo" type="CanvasLayer" parent="."] +script = ExtResource("2_wf1xe") + +[node name="PanelContainer" type="PanelContainer" parent="LobbyInfo"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="LobbyInfo/PanelContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +alignment = 1 + +[node name="LobbyCode" type="Label" parent="LobbyInfo/PanelContainer/VBoxContainer"] +layout_mode = 2 +horizontal_alignment = 1 + +[node name="InsectIcons" type="HBoxContainer" parent="LobbyInfo/PanelContainer/VBoxContainer"] +visible = false +layout_mode = 2 + +[node name="StartGameButton" type="Button" parent="LobbyInfo/PanelContainer/VBoxContainer"] +visible = false +layout_mode = 2 +disabled = true +text = "Start Game" + +[node name="Button" type="Button" parent="LobbyInfo/PanelContainer/VBoxContainer"] +layout_mode = 2 +text = "Back to menu" + +[node name="PauseMenu" type="CanvasLayer" parent="."] + +[connection signal="pressed" from="LobbyInfo/PanelContainer/VBoxContainer/StartGameButton" to="." method="_on_start_game_button_pressed"] +[connection signal="pressed" from="LobbyInfo/PanelContainer/VBoxContainer/Button" to="LobbyInfo" method="_on_button_pressed"] diff --git a/BuildMenu.gd b/UI/BuildMenu.gd similarity index 100% rename from BuildMenu.gd rename to UI/BuildMenu.gd diff --git a/UI/insect_button.tscn b/UI/insect_button.tscn index 3fc9e94..f7d91c0 100644 --- a/UI/insect_button.tscn +++ b/UI/insect_button.tscn @@ -12,7 +12,6 @@ custom_minimum_size = Vector2(64, 64) ignore_texture_size = true stretch_mode = 0 script = ExtResource("1_scd5m") -is_black = null [node name="Hex" type="TextureRect" parent="."] texture_filter = 6 diff --git a/UI/join_menu.gd b/UI/join_menu.gd new file mode 100644 index 0000000..ade6356 --- /dev/null +++ b/UI/join_menu.gd @@ -0,0 +1,21 @@ +extends Control + +@onready var lobby_code_input = $PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/LobbyCodeInput + +func _ready(): + WSClient.lobby_joined.connect(_on_lobby_joined) + +func _on_lobby_joined(lobby: String) -> void: + GameData.lobby_code = lobby + + get_tree().change_scene_to_file("res://Multiplayer/Multiplayer.tscn") + +func _process(delta): + pass + +func _on_back_button_pressed(): + get_tree().change_scene_to_file("res://main_menu.tscn") + +func _on_connect_button_pressed(): + GameData.is_player_black = true + WSClient.start(GameData.WEBSOCKET_ENDPOINT, lobby_code_input.text) diff --git a/UI/join_menu.tscn b/UI/join_menu.tscn new file mode 100644 index 0000000..33dc605 --- /dev/null +++ b/UI/join_menu.tscn @@ -0,0 +1,61 @@ +[gd_scene load_steps=2 format=3 uid="uid://byp1oxm5a86xg"] + +[ext_resource type="Script" path="res://UI/join_menu.gd" id="1_hswn2"] + +[node name="JoinMenu" 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_hswn2") + +[node name="PanelContainer" type="PanelContainer" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -115.0 +offset_top = -76.5 +offset_right = 115.0 +offset_bottom = 76.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 15 +theme_override_constants/margin_top = 15 +theme_override_constants/margin_right = 15 +theme_override_constants/margin_bottom = 15 + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 15 + +[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="LobbyCodeLabel" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "Lobby-Code: " + +[node name="LobbyCodeInput" type="LineEdit" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +theme_override_constants/minimum_character_width = 6 +max_length = 6 +shortcut_keys_enabled = false + +[node name="ConnectButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Connect" + +[node name="BackButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Back to menu" + +[connection signal="pressed" from="PanelContainer/MarginContainer/VBoxContainer/ConnectButton" to="." method="_on_connect_button_pressed"] +[connection signal="pressed" from="PanelContainer/MarginContainer/VBoxContainer/BackButton" to="." method="_on_back_button_pressed"] diff --git a/main_menu.gd b/main_menu.gd index 206b4e7..01f1673 100644 --- a/main_menu.gd +++ b/main_menu.gd @@ -1,44 +1,26 @@ extends Control -const WEBSOCKET_ENDPOINT: String = "wss://dev.bytesandpieces.xyz:9088" - -const insect_resources = [ - preload("res://Tile/Prefabs/Ant.tres"), - preload("res://Tile/Prefabs/Bee.tres"), - preload("res://Tile/Prefabs/Beetle.tres"), - preload("res://Tile/Prefabs/Grasshopper.tres"), - preload("res://Tile/Prefabs/Ladybug.tres"), - preload("res://Tile/Prefabs/Mosquito.tres"), - preload("res://Tile/Prefabs/Pillbug.tres"), - preload("res://Tile/Prefabs/Spider.tres") -] - -var insect_data = { - -} - -func prepare_insect_data() -> void: - var c: int = 65 - - #for i in insect_resources: - #for k in 2: - #print(String.chr(c)) - #c = c + 1 - # Called when the node enters the scene tree for the first time. func _ready() -> void: - prepare_insect_data() - WSClient.lobby_joined.connect(_on_lobby_joined) func _on_lobby_joined(lobby: String) -> void: - pass - + GameData.lobby_code = lobby + + get_tree().change_scene_to_file("res://Multiplayer/Multiplayer.tscn") + # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: pass +func _on_host_button_pressed(): + GameData.is_player_black = false + WSClient.start(GameData.WEBSOCKET_ENDPOINT, "") -func _on_button_pressed() -> void: - WSClient.start(WEBSOCKET_ENDPOINT, "", false) - pass # Replace with function body. + +func _on_join_button_pressed(): + get_tree().change_scene_to_file("res://UI/join_menu.tscn") + + +func _on_exit_button_pressed(): + get_tree().quit() diff --git a/main_menu.tscn b/main_menu.tscn index b49ac77..f44a480 100644 --- a/main_menu.tscn +++ b/main_menu.tscn @@ -11,16 +11,43 @@ grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_q3q3u") -[node name="Button" type="Button" parent="."] -layout_mode = 0 -offset_right = 8.0 -offset_bottom = 8.0 -text = "Test WebRTC" +[node name="PanelContainer" type="PanelContainer" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -62.0 +offset_top = -76.5 +offset_right = 62.0 +offset_bottom = 76.5 +grow_horizontal = 2 +grow_vertical = 2 -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 0 -offset_top = 56.0 -offset_right = 40.0 -offset_bottom = 96.0 +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 15 +theme_override_constants/margin_top = 15 +theme_override_constants/margin_right = 15 +theme_override_constants/margin_bottom = 15 -[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"] +layout_mode = 2 +theme_override_constants/separation = 15 + +[node name="HostButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Host Game" + +[node name="JoinButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Join Game" + +[node name="ExitButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Exit" + +[connection signal="pressed" from="PanelContainer/MarginContainer/VBoxContainer/HostButton" to="." method="_on_host_button_pressed"] +[connection signal="pressed" from="PanelContainer/MarginContainer/VBoxContainer/JoinButton" to="." method="_on_join_button_pressed"] +[connection signal="pressed" from="PanelContainer/MarginContainer/VBoxContainer/ExitButton" to="." method="_on_exit_button_pressed"]