Merge branch 'feat/map-selector' into 'develop'

 add a map selector for multiplayer hosting

See merge request open-fpsz/open-fpsz!72
This commit is contained in:
anyreso 2024-04-25 21:08:55 +00:00
commit bcd857b235
21 changed files with 110 additions and 62 deletions

View file

@ -6,6 +6,7 @@
[ext_resource type="PackedScene" uid="uid://bcgkc5fhhyauv" path="res://entities/flag/waypoint.tscn" id="3_tu6jg"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_4ymrw"]
friction = 0.5
bounce = 0.5
[sub_resource type="BoxShape3D" id="BoxShape3D_fkf1k"]

View file

@ -51,6 +51,9 @@ signal join_server(host : String, port : int)
@onready var modal : Control = $Modal
@onready var menu : CanvasLayer = get_parent()
@onready var game : Node3D = get_tree().current_scene
@onready var map_selector : OptionButton = %MapSelector
@export var tab_container : TabContainer
func _ready() -> void:
@ -58,7 +61,12 @@ func _ready() -> void:
_registered_ports.compile(r'^(?:102[4-9]|10[3-9]\\d|1[1-9]\\d{2}|[2-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])$')
_join_address.compile(r'^(?<host>[a-zA-Z0-9.-]+)(:(?<port>:102[4-9]|10[3-9]\\d|1[1-9]\\d{2}|[2-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5]))?$')
_load_config()
hide() # start hidden
call_deferred(\"_populate_map_selector\")
func _populate_map_selector() -> void:
for map : PackedScene in game.maps:
var map_name : String = map._bundled.names[0]
map_selector.add_item(map_name)
func _load_config() -> void:
var error : Error = _config_file.load(CONFIG_FILE_PATH)
@ -406,6 +414,12 @@ unique_name_in_owner = true
layout_mode = 2
placeholder_text = "9000"
[node name="MapSelector" type="OptionButton" parent="Multiplayer/MarginContainer/VBoxContainer/TabContainer/Host/MarginContainer/HBoxContainer/RightBox"]
unique_name_in_owner = true
layout_mode = 2
clip_text = true
allow_reselect = true
[node name="Modal" type="Panel" parent="Multiplayer"]
visible = false
layout_mode = 2

View file

@ -1,8 +1,9 @@
[gd_scene load_steps=5 format=3 uid="uid://ma1if3sjox6i"]
[gd_scene load_steps=6 format=3 uid="uid://ma1if3sjox6i"]
[ext_resource type="PackedScene" uid="uid://boviiugcnfyrj" path="res://modes/demo.tscn" id="1_50a80"]
[ext_resource type="PackedScene" uid="uid://bjctlqvs33nqy" path="res://interfaces/menus/boot/boot.tscn" id="1_acy5o"]
[ext_resource type="PackedScene" uid="uid://bvwxfgygm2xb8" path="res://modes/multiplayer.tscn" id="2_g8xeb"]
[ext_resource type="Resource" uid="uid://dut5f1sq0wfeb" path="res://maps/maps.tres" id="3_1ipir"]
[sub_resource type="GDScript" id="GDScript_e61dq"]
script/source = "class_name Game extends Node3D
@ -11,6 +12,11 @@ script/source = "class_name Game extends Node3D
@export var SINGLEPLAYER : PackedScene
@export var MULTIPLAYER : PackedScene
@export_category(\"Maps\")
@export var _maps_resource : ArrayPackedSceneResource
@onready var maps : Array[PackedScene] = _maps_resource.get_items()
var mode : Node:
set(new_mode):
# clean up previous mode
@ -36,7 +42,7 @@ func _unhandled_input(event : InputEvent) -> void:
# reset game mode
mode = null
# check for debug build
if not OS.is_debug_build():
if OS.is_debug_build():
# exit with success
get_tree().quit(0)
else:
@ -63,7 +69,11 @@ func _start_demo() -> void:
func _start_server(port : int, nickname : String) -> void:
mode = MULTIPLAYER.instantiate()
mode.start_server(port, nickname)
mode.start_server({
\"port\": port,
\"nickname\": nickname,
\"map\": maps[clamp($BootMenu/Multiplayer.map_selector.selected, 0, len(maps))]
})
$BootMenu.hide()
func _join_server(host : String, port : int, nickname : String) -> void:
@ -77,5 +87,6 @@ func _join_server(host : String, port : int, nickname : String) -> void:
script = SubResource("GDScript_e61dq")
SINGLEPLAYER = ExtResource("1_50a80")
MULTIPLAYER = ExtResource("2_g8xeb")
_maps_resource = ExtResource("3_1ipir")
[node name="BootMenu" parent="." instance=ExtResource("1_acy5o")]

View file

@ -1,11 +1,20 @@
[gd_scene load_steps=5 format=3 uid="uid://btlkog4b87p4x"]
[gd_scene load_steps=6 format=3 uid="uid://btlkog4b87p4x"]
[ext_resource type="Terrain3DStorage" uid="uid://wgmg245njt8e" path="res://maps/desert/resources/storage.res" id="1_7nbyj"]
[ext_resource type="Environment" uid="uid://nw62ce5cglvs" path="res://environments/desert.tres" id="1_e1o3u"]
[ext_resource type="Terrain3DMaterial" uid="uid://c3isipd4wqxpk" path="res://maps/desert/resources/material.tres" id="2_psdr0"]
[ext_resource type="Terrain3DTextureList" uid="uid://d1j24k8sq8qpj" path="res://maps/desert/resources/textures.tres" id="3_aowug"]
[ext_resource type="Script" path="res://maps/map.gd" id="4_cl7fm"]
[node name="Desert" type="Node3D"]
[node name="Desert" type="Terrain3D" node_paths=PackedStringArray("_flagstand", "_player_spawns_root")]
storage = ExtResource("1_7nbyj")
material = ExtResource("2_psdr0")
texture_list = ExtResource("3_aowug")
collision_layer = 2147483648
collision_mask = 2147483648
script = ExtResource("4_cl7fm")
_flagstand = NodePath("FlagStand")
_player_spawns_root = NodePath("PlayerSpawns")
[node name="Sunlight" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.5, 0.55667, -0.663414, 0, 0.766044, 0.642788, 0.866025, -0.321394, 0.383022, -1613.38, 2730.74, 446.64)
@ -14,9 +23,13 @@ shadow_enabled = true
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = ExtResource("1_e1o3u")
[node name="Terrain3D" type="Terrain3D" parent="."]
storage = ExtResource("1_7nbyj")
material = ExtResource("2_psdr0")
texture_list = ExtResource("3_aowug")
collision_layer = 2147483648
collision_mask = 2147483648
[node name="PlayerSpawns" type="Node" parent="."]
[node name="Spawn1" type="Marker3D" parent="PlayerSpawns"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1024, 172.13, 1024)
[node name="Spawn2" type="Marker3D" parent="PlayerSpawns"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1161.42, 174.535, 909.901)
[node name="FlagStand" type="Marker3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 878.613, 134.55, 916.185)

View file

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

View file

@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://ddprscrpsofah"
path.bptc="res://.godot/imported/ground037_alb_ht.png-e94bcf81dfd35d432692c06ac781741b.bptc.ctex"
path.bptc="res://.godot/imported/ground037_alb_ht.png-b65037b7797c79d182d5e53b32e49a98.bptc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://maps/genesis/textures/ground037_alb_ht.png"
dest_files=["res://.godot/imported/ground037_alb_ht.png-e94bcf81dfd35d432692c06ac781741b.bptc.ctex"]
source_file="res://maps/genesis/assets/textures/ground037_alb_ht.png"
dest_files=["res://.godot/imported/ground037_alb_ht.png-b65037b7797c79d182d5e53b32e49a98.bptc.ctex"]
[params]

View file

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

View file

@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://c1ots7w6i0i1q"
path.bptc="res://.godot/imported/ground037_nrm_rgh.png-81b0e480d48434b2b70dcb00c9b9be8a.bptc.ctex"
path.bptc="res://.godot/imported/ground037_nrm_rgh.png-9e25ec612e0ce15ff2c117ec4096a8f7.bptc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://maps/genesis/textures/ground037_nrm_rgh.png"
dest_files=["res://.godot/imported/ground037_nrm_rgh.png-81b0e480d48434b2b70dcb00c9b9be8a.bptc.ctex"]
source_file="res://maps/genesis/assets/textures/ground037_nrm_rgh.png"
dest_files=["res://.godot/imported/ground037_nrm_rgh.png-9e25ec612e0ce15ff2c117ec4096a8f7.bptc.ctex"]
[params]

View file

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 2.5 MiB

View file

@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://br7bfxcxh60df"
path.bptc="res://.godot/imported/rock030_alb_ht.png-194ac44f1664ad902e6112d7c538b8ea.bptc.ctex"
path.bptc="res://.godot/imported/rock030_alb_ht.png-264f70712792662fedd23fe3bac9e221.bptc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://maps/genesis/textures/rock030_alb_ht.png"
dest_files=["res://.godot/imported/rock030_alb_ht.png-194ac44f1664ad902e6112d7c538b8ea.bptc.ctex"]
source_file="res://maps/genesis/assets/textures/rock030_alb_ht.png"
dest_files=["res://.godot/imported/rock030_alb_ht.png-264f70712792662fedd23fe3bac9e221.bptc.ctex"]
[params]

View file

Before

Width:  |  Height:  |  Size: 3.1 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

View file

@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cr72kjil43vgj"
path.bptc="res://.godot/imported/rock030_nrm_rgh.png-4c72231defef9c07b29c49d8904a13df.bptc.ctex"
path.bptc="res://.godot/imported/rock030_nrm_rgh.png-ca17d43269b25394f8e7aa1fa0631681.bptc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://maps/genesis/textures/rock030_nrm_rgh.png"
dest_files=["res://.godot/imported/rock030_nrm_rgh.png-4c72231defef9c07b29c49d8904a13df.bptc.ctex"]
source_file="res://maps/genesis/assets/textures/rock030_nrm_rgh.png"
dest_files=["res://.godot/imported/rock030_nrm_rgh.png-ca17d43269b25394f8e7aa1fa0631681.bptc.ctex"]
[params]

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://chbno00ugl6te"]
[gd_scene load_steps=6 format=3 uid="uid://chbno00ugl6te"]
[ext_resource type="Environment" uid="uid://d2ahijqqspw5f" path="res://environments/default.tres" id="1_3nr12"]
[ext_resource type="Script" path="res://maps/map.gd" id="1_6ysiv"]
@ -6,54 +6,40 @@
[ext_resource type="Terrain3DMaterial" uid="uid://bd4lr5sxu8xu" path="res://maps/genesis/resources/material.res" id="2_o2y3d"]
[ext_resource type="Terrain3DTextureList" uid="uid://dnqa8kxgm3xuw" path="res://maps/genesis/resources/textures.res" id="3_1cww7"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_k2vhq"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_5ytwx"]
[node name="Map" type="Node" node_paths=PackedStringArray("_flagstand", "_player_spawns_root")]
script = ExtResource("1_6ysiv")
_flagstand = NodePath("Terrain3D/FlagPillar/CSGCylinder3D/FlagStand")
_player_spawns_root = NodePath("Terrain3D/PlayerSpawns")
[node name="Terrain3D" type="Terrain3D" parent="."]
[node name="Genesis" type="Terrain3D" node_paths=PackedStringArray("_flagstand", "_player_spawns_root")]
storage = ExtResource("1_a88qe")
material = ExtResource("2_o2y3d")
texture_list = ExtResource("3_1cww7")
collision_layer = 2147483648
collision_mask = 2147483648
mesh_size = 24
script = ExtResource("1_6ysiv")
_flagstand = NodePath("FlagPillar/CSGCylinder3D/FlagStand")
_player_spawns_root = NodePath("PlayerSpawns")
[node name="PlayerSpawns" type="Node" parent="Terrain3D"]
[node name="PlayerSpawns" type="Node" parent="."]
[node name="Spawn1" type="Marker3D" parent="Terrain3D/PlayerSpawns"]
[node name="Spawn1" type="Marker3D" parent="PlayerSpawns"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 95.5378, -32.735)
visible = false
[node name="MeshInstance3D" type="MeshInstance3D" parent="Terrain3D/PlayerSpawns/Spawn1"]
mesh = SubResource("CapsuleMesh_k2vhq")
[node name="Spawn2" type="Marker3D" parent="Terrain3D/PlayerSpawns"]
[node name="Spawn2" type="Marker3D" parent="PlayerSpawns"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 98.3078, 18.061)
visible = false
[node name="MeshInstance3D" type="MeshInstance3D" parent="Terrain3D/PlayerSpawns/Spawn2"]
mesh = SubResource("CapsuleMesh_5ytwx")
[node name="FlagPillar" type="CSGCombiner3D" parent="Terrain3D"]
[node name="FlagPillar" type="CSGCombiner3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 2.83726, 0, 0, 0, 1, 0, 94.6411, 0)
use_collision = true
collision_layer = 2147483648
collision_mask = 0
[node name="CSGBox3D" type="CSGBox3D" parent="Terrain3D/FlagPillar"]
[node name="CSGBox3D" type="CSGBox3D" parent="FlagPillar"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9311, 0)
size = Vector3(0.5, 6, 0.5)
[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Terrain3D/FlagPillar"]
[node name="CSGCylinder3D" type="CSGCylinder3D" parent="FlagPillar"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.42967, 0)
height = 5.0
[node name="FlagStand" type="Marker3D" parent="Terrain3D/FlagPillar/CSGCylinder3D"]
[node name="FlagStand" type="Marker3D" parent="FlagPillar/CSGCylinder3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.53822, 0)
[node name="Sunlight" type="DirectionalLight3D" parent="."]

Binary file not shown.

View file

@ -1,4 +1,4 @@
class_name Map extends Node
class_name Map extends Terrain3D
@export var _flagstand : Node3D
@export var _player_spawns_root : Node
@ -13,4 +13,3 @@ func get_player_spawn() -> Node3D:
var spawn_index : int = _rng.randi_range(0, spawn_count - 1)
var spawn_selected : Node3D = _player_spawns_root.get_child(spawn_index)
return spawn_selected

9
maps/maps.tres Normal file
View file

@ -0,0 +1,9 @@
[gd_resource type="Resource" script_class="ArrayPackedSceneResource" load_steps=4 format=3 uid="uid://dut5f1sq0wfeb"]
[ext_resource type="PackedScene" uid="uid://chbno00ugl6te" path="res://maps/genesis/genesis.tscn" id="1_7kpvp"]
[ext_resource type="PackedScene" uid="uid://btlkog4b87p4x" path="res://maps/desert/desert.tscn" id="2_8vsif"]
[ext_resource type="Script" path="res://types/resources/array_packed_scene.gd" id="3_by6r1"]
[resource]
script = ExtResource("3_by6r1")
_packed_scenes = Array[PackedScene]([ExtResource("1_7kpvp"), ExtResource("2_8vsif")])

View file

@ -15,7 +15,6 @@
class_name Multiplayer extends Node
@export_category("Parameters")
@export var MAP : PackedScene
@export var PLAYER : PackedScene
@export var FLAG : PackedScene
@export var MAX_CLIENTS : int = 24
@ -38,15 +37,20 @@ func _ready() -> void:
_flag_carrier_scoring_timer.timeout.connect(_on_flag_carrier_scoring_timer_timeout)
add_child(_flag_carrier_scoring_timer)
func start_server(port : int, nickname : String) -> void:
func start_server(config : Dictionary) -> void:
# Check if required parameters are missing
var required_params : Array[String] = ["port", "map", "nickname"]
for param in required_params:
if not config.has(param):
print("Missing param in server config:", param)
return
# server setup
var peer : ENetMultiplayerPeer = ENetMultiplayerPeer.new()
peer.create_server(port, MAX_CLIENTS)
peer.create_server(config["port"], MAX_CLIENTS)
multiplayer.multiplayer_peer = peer
_load_map.call_deferred(MAP, nickname)
multiplayer.peer_disconnected.connect(remove_player)
_load_map.call_deferred(config["map"], config["nickname"])
func join_server(host : String, port : int, nickname : String) -> void:
var peer : ENetMultiplayerPeer = ENetMultiplayerPeer.new()

View file

@ -1,6 +1,5 @@
[gd_scene load_steps=6 format=3 uid="uid://bvwxfgygm2xb8"]
[gd_scene load_steps=5 format=3 uid="uid://bvwxfgygm2xb8"]
[ext_resource type="PackedScene" uid="uid://chbno00ugl6te" path="res://maps/genesis/genesis.tscn" id="1_nulvv"]
[ext_resource type="Script" path="res://modes/multiplayer.gd" id="1_r1kd6"]
[ext_resource type="PackedScene" uid="uid://cbhx1xme0sb7k" path="res://entities/player/player.tscn" id="2_og1vb"]
[ext_resource type="PackedScene" uid="uid://c88l3h0ph00c7" path="res://entities/flag/flag.tscn" id="3_h0rie"]
@ -8,7 +7,6 @@
[node name="Multiplayer" type="Node"]
script = ExtResource("1_r1kd6")
MAP = ExtResource("1_nulvv")
PLAYER = ExtResource("2_og1vb")
FLAG = ExtResource("3_h0rie")

View file

@ -0,0 +1,6 @@
class_name ArrayPackedSceneResource extends Resource
@export var _packed_scenes : Array[PackedScene] = []
func get_items() -> Array[PackedScene]:
return _packed_scenes

View file

@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="ArrayPackedSceneResource" load_steps=2 format=3 uid="uid://cpnargstkucch"]
[ext_resource type="Script" path="res://types/resources/array_packed_scene.gd" id="1_r1ygd"]
[resource]
script = ExtResource("1_r1ygd")
_packed_scenes = Array[PackedScene]([])