diff --git a/components/flag_carry_component.gd b/components/flag_carry_component.gd
index d3235e3..5b0980e 100644
--- a/components/flag_carry_component.gd
+++ b/components/flag_carry_component.gd
@@ -1,6 +1,24 @@
+# This file is part of open-fpsz.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
class_name FlagCarryComponent extends Node
+## This component allows its entity to grab, carry and throw flags
+##
+## To work correctly the owner MUST set an attachment point for carried flags
+## and a sensor to detect when flags are within grab range
-@export var throw_velocity : float = 10.0
+@export var max_throw_speed : float = 10.0
@export var attachment : Node3D
@export var sensor : Area3D
@@ -20,11 +38,12 @@ func _grab(flag : Flag):
flag.grab()
_carried_flag = flag
-func throw():
+@rpc("call_local")
+func _drop(throw_speed : float):
if _is_carrying():
_carried_flag.drop()
- _carried_flag.linear_velocity = attachment.global_basis.z * throw_velocity
_carried_flag.rotation_degrees.x = 0.0
+ _carried_flag.linear_velocity = attachment.global_basis.z * throw_speed
_carried_flag = null
func _is_carrying() -> bool:
@@ -33,3 +52,9 @@ func _is_carrying() -> bool:
func _sensor_on_body_entered(collider):
if collider is Flag:
_grab.rpc(collider)
+
+func drop():
+ _drop.rpc(0.0)
+
+func throw():
+ _drop.rpc(max_throw_speed)
diff --git a/components/health_component.gd b/components/health_component.gd
index 15daa99..1d13446 100644
--- a/components/health_component.gd
+++ b/components/health_component.gd
@@ -1,15 +1,15 @@
# This file is part of open-fpsz.
-#
+#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
class_name HealthComponent extends Area3D
diff --git a/components/health_component.tscn b/components/health_component.tscn
index 8f7350a..6dd6121 100644
--- a/components/health_component.tscn
+++ b/components/health_component.tscn
@@ -1,12 +1,8 @@
-[gd_scene load_steps=3 format=3 uid="uid://bof3mg7wgxrmn"]
+[gd_scene load_steps=2 format=3 uid="uid://bof3mg7wgxrmn"]
[ext_resource type="Script" path="res://components/health_component.gd" id="1_00xis"]
-[ext_resource type="Shape3D" uid="uid://dkwljsgaflf31" path="res://entities/player/collision_shape.res" id="2_sgbmt"]
[node name="HealthComponent" type="Area3D"]
collision_layer = 4
collision_mask = 0
script = ExtResource("1_00xis")
-
-[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
-shape = ExtResource("2_sgbmt")
diff --git a/entities/player/collision_shape.res b/entities/player/collision_shape.res
deleted file mode 100644
index 16a86b7..0000000
Binary files a/entities/player/collision_shape.res and /dev/null differ
diff --git a/entities/player/collision_shape.tres b/entities/player/collision_shape.tres
new file mode 100644
index 0000000..0195e9e
--- /dev/null
+++ b/entities/player/collision_shape.tres
@@ -0,0 +1,4 @@
+[gd_resource type="CapsuleShape3D" format=3 uid="uid://cb8esdlnottdn"]
+
+[resource]
+radius = 0.25
diff --git a/entities/player/player.gd b/entities/player/player.gd
index 759905e..29ebb6d 100644
--- a/entities/player/player.gd
+++ b/entities/player/player.gd
@@ -36,6 +36,7 @@ enum PlayerState { PLAYER_ALIVE, PLAYER_DEAD }
set(id):
player_id = id
$PlayerInput.set_multiplayer_authority(id)
+@export var nickname : String
@onready var input : PlayerInput = $PlayerInput
@onready var camera = $SpringArm3D/Camera3D
@@ -45,7 +46,7 @@ enum PlayerState { PLAYER_ALIVE, PLAYER_DEAD }
@onready var weapon = $SpringArm3D/Inventory/SpaceGun
@onready var animation_player : AnimationPlayer = $AnimationPlayer
@onready var health_component = $HealthComponent
-@onready var flag_carry_component = $FlagCarryComponent
+@onready var flag_carry_component : FlagCarryComponent = $FlagCarryComponent
@onready var spring_arm_height = $SpringArm3D.position.y
@onready var _original_weapon_transform : Transform3D = weapon.transform
@onready var flag_carry_attachment = $SpringArm3D/FlagCarryAttachment
@@ -65,7 +66,6 @@ func _ready():
health_component.health_zeroed.connect(_die)
if _is_first_person():
camera.current = true
- flag_carry_attachment.hide()
remove_child($ThirdPerson)
else:
remove_child($HUD)
@@ -214,6 +214,11 @@ func _die():
if _is_first_person():
animation_player.stop()
)
+ flag_carry_component.drop()
+
+@rpc("call_local")
+func set_nickname(value):
+ nickname = value
func respawn(location):
linear_velocity = Vector3()
diff --git a/entities/player/player.tscn b/entities/player/player.tscn
index ae12017..d17c267 100644
--- a/entities/player/player.tscn
+++ b/entities/player/player.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=21 format=3 uid="uid://cbhx1xme0sb7k"]
[ext_resource type="Script" path="res://entities/player/player.gd" id="1_mk68k"]
-[ext_resource type="Shape3D" uid="uid://dkwljsgaflf31" path="res://entities/player/collision_shape.res" id="2_8rtw3"]
[ext_resource type="PackedScene" uid="uid://drbefw6akui2v" path="res://entities/player/assets/vanguard.tscn" id="2_beyex"]
+[ext_resource type="Shape3D" uid="uid://cb8esdlnottdn" path="res://entities/player/collision_shape.tres" id="2_vjqny"]
[ext_resource type="PackedScene" uid="uid://bcv81ku26xo" path="res://interfaces/hud/hud.tscn" id="3_ccety"]
[ext_resource type="PackedScene" uid="uid://c8co0qa2omjmh" path="res://weapons/space_gun/space_gun.tscn" id="4_lhn5w"]
[ext_resource type="PackedScene" uid="uid://dn1tcakam5egs" path="res://weapons/space_gun/projectile.tscn" id="5_lvaut"]
@@ -180,6 +180,9 @@ properties/3/replication_mode = 2
properties/4/path = NodePath(".:player_state")
properties/4/spawn = true
properties/4/replication_mode = 2
+properties/5/path = NodePath(".:nickname")
+properties/5/spawn = true
+properties/5/replication_mode = 2
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_5j4ew"]
properties/0/path = NodePath(".:direction")
@@ -210,11 +213,11 @@ visible = false
mesh = SubResource("CapsuleMesh_vmqfq")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
-shape = ExtResource("2_8rtw3")
+shape = ExtResource("2_vjqny")
[node name="ShapeCast3D" type="ShapeCast3D" parent="."]
transform = Transform3D(1.05, 0, 0, 0, 1.05, 0, 0, 0, 1.05, 0, 0, 0)
-shape = ExtResource("2_8rtw3")
+shape = ExtResource("2_vjqny")
target_position = Vector3(0, 0, 0)
collision_mask = 2147483656
collide_with_areas = true
@@ -225,7 +228,7 @@ collision_mask = 8
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="Sensor"]
-shape = ExtResource("2_8rtw3")
+shape = ExtResource("2_vjqny")
[node name="HUD" parent="." instance=ExtResource("3_ccety")]
@@ -252,8 +255,10 @@ transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, -0.
[node name="HealthComponent" parent="." instance=ExtResource("5_t6i6e")]
+[node name="CollisionShape3D" type="CollisionShape3D" parent="HealthComponent"]
+shape = ExtResource("2_vjqny")
+
[node name="FlagCarryComponent" parent="." node_paths=PackedStringArray("attachment", "sensor") instance=ExtResource("7_e7s1a")]
-throw_velocity = 20.0
attachment = NodePath("../SpringArm3D/FlagCarryAttachment")
sensor = NodePath("../Sensor")
diff --git a/interfaces/hud/iff.gd b/interfaces/hud/iff.gd
index e064c21..41d0941 100644
--- a/interfaces/hud/iff.gd
+++ b/interfaces/hud/iff.gd
@@ -1,15 +1,15 @@
# This file is part of open-fpsz.
-#
+#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
extends Node2D
@@ -28,7 +28,7 @@ func _process(_delta):
else:
_v_box_container.show()
- _player_name_label.text = player.name
+ _player_name_label.text = player.nickname
position = camera.unproject_position(attach_point.global_position)
var viewport_size : Vector2 = get_viewport_rect().size
position.x = clampf(position.x, 0, viewport_size.x - _v_box_container.size.x)
diff --git a/interfaces/menus/boot/boot.tscn b/interfaces/menus/boot/boot.tscn
index 82c6d8d..d752e80 100644
--- a/interfaces/menus/boot/boot.tscn
+++ b/interfaces/menus/boot/boot.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=3 uid="uid://bjctlqvs33nqy"]
+[gd_scene load_steps=6 format=3 uid="uid://bjctlqvs33nqy"]
[ext_resource type="Texture2D" uid="uid://c1tjamjm8qjog" path="res://interfaces/menus/boot/background.webp" id="1_ph586"]
@@ -10,6 +10,13 @@ signal start_demo
func _on_demo_pressed():
start_demo.emit()
+
+func _on_multiplayer_pressed():
+ $Main.hide()
+ $Multiplayer.show()
+
+func _on_quit_pressed():
+ get_tree().quit()
"
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_krqeq"]
@@ -20,9 +27,11 @@ script/source = "class_name MultiplayerPanel extends PanelContainer
const DEFAULT_HOST : String = \"localhost\"
const DEFAULT_PORT : int = 9000
+const CONFIG_FILE_PATH : String = \"user://settings.cfg\"
-var _join_address = RegEx.new()
-var _registered_ports = RegEx.new()
+var _join_address : RegEx = RegEx.new()
+var _registered_ports : RegEx = RegEx.new()
+var _config_file : ConfigFile = ConfigFile.new()
signal start_server(port)
signal join_server(host, port)
@@ -34,8 +43,21 @@ func _ready():
# see https://datatracker.ietf.org/doc/html/rfc1700
_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'^(?[a-zA-Z0-9.-]+)(:(?: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
+func _load_config():
+ var error : Error = _config_file.load(CONFIG_FILE_PATH)
+ if error != OK:
+ return
+
+ var profile_name : String = _config_file.get_value(\"profile\", \"name\", \"Newblood\")
+ %ProfileName.text = profile_name
+
+func _on_save_pressed():
+ _config_file.set_value(\"profile\", \"name\", %ProfileName.text)
+ _config_file.save(CONFIG_FILE_PATH)
+
func _on_menu_pressed():
hide()
owner.get_node(\"Main\").show()
@@ -53,8 +75,8 @@ func _on_host_pressed():
else: # port is not valid
push_warning(\"A valid port number in the range 1024-65535 is required.\")
return
-
- start_server.emit(port)
+
+ start_server.emit(port, %ProfileName.text)
func _on_join_pressed():
var addr = [DEFAULT_HOST, DEFAULT_PORT]
@@ -66,7 +88,7 @@ func _on_join_pressed():
if rport: addr[1] = int(rport)
$Modal.show()
- join_server.emit(addr[0], addr[1])
+ join_server.emit(addr[0], addr[1], %ProfileName.text)
func _on_connected_to_server():
$Modal.hide()
@@ -79,17 +101,6 @@ func _on_connection_failed():
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_snh7i"]
bg_color = Color(0, 0.5, 0.5, 0.25)
-[sub_resource type="GDScript" id="GDScript_yqbr7"]
-script/source = "extends PanelContainer
-
-func _on_multiplayer_pressed():
- hide()
- owner.get_node(\"Multiplayer\").show()
-
-func _on_quit_pressed():
- get_tree().quit()
-"
-
[node name="BootMenu" type="CanvasLayer"]
script = SubResource("GDScript_jd8xf")
@@ -156,6 +167,10 @@ layout_mode = 2
disabled = true
text = "Delete"
+[node name="Save" type="Button" parent="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox"]
+layout_mode = 2
+text = "Save"
+
[node name="Spacer" type="MarginContainer" parent="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox"]
layout_mode = 2
size_flags_vertical = 3
@@ -313,7 +328,6 @@ offset_right = 313.0
grow_vertical = 2
size_flags_horizontal = 0
theme_override_styles/panel = SubResource("StyleBoxFlat_snh7i")
-script = SubResource("GDScript_yqbr7")
[node name="MarginContainer" type="MarginContainer" parent="Main"]
layout_mode = 2
@@ -342,6 +356,7 @@ text = "Quit"
[connection signal="join_server" from="Multiplayer" to="." method="_on_multiplayer_join_server"]
[connection signal="start_server" from="Multiplayer" to="." method="_on_multiplayer_start_server"]
+[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox/Save" to="Multiplayer" method="_on_save_pressed"]
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox/Menu" to="Multiplayer" method="_on_menu_pressed"]
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Profile/MarginContainer/HBoxContainer/LeftBox/Quit" to="Multiplayer" method="_on_quit_pressed"]
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Join/MarginContainer/HBoxContainer/LeftBox/Join" to="Multiplayer" method="_on_join_pressed"]
@@ -352,5 +367,5 @@ text = "Quit"
[connection signal="pressed" from="Multiplayer/MarginContainer/TabContainer/Host/MarginContainer/HBoxContainer/LeftBox/Quit" to="Multiplayer" method="_on_quit_pressed"]
[connection signal="text_changed" from="Multiplayer/MarginContainer/TabContainer/Host/MarginContainer/HBoxContainer/RightBox/ServerPort" to="Multiplayer/MarginContainer/TabContainer/Host/MarginContainer/HBoxContainer/RightBox/ServerPort" method="_on_text_changed"]
[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Demo" to="." method="_on_demo_pressed"]
-[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Multiplayer" to="Main" method="_on_multiplayer_pressed"]
-[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Quit" to="Main" method="_on_quit_pressed"]
+[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Multiplayer" to="." method="_on_multiplayer_pressed"]
+[connection signal="pressed" from="Main/MarginContainer/VBoxContainer/Quit" to="." method="_on_quit_pressed"]
diff --git a/main.tscn b/main.tscn
index 10288e1..2fa6731 100644
--- a/main.tscn
+++ b/main.tscn
@@ -24,20 +24,20 @@ func _start_demo():
add_child(mode)
$BootMenu.hide()
-func _start_server(port):
+func _start_server(port, nickname):
if mode: mode.queue_free()
mode = MULTIPLAYER.instantiate()
add_child(mode)
- mode.start_server(port)
+ mode.start_server(port, nickname)
$BootMenu.hide()
-func _join_server(host, port):
+func _join_server(host, port, nickname):
if mode: mode.queue_free()
mode = MULTIPLAYER.instantiate()
add_child(mode)
mode.connected_to_server.connect($BootMenu/Multiplayer._on_connected_to_server)
mode.connection_failed.connect($BootMenu/Multiplayer._on_connection_failed)
- mode.join_server(host, port)
+ mode.join_server(host, port, nickname)
func _unhandled_input(event):
# exit the program
diff --git a/modes/multiplayer.tscn b/modes/multiplayer.tscn
index a2d3e5a..8d9f249 100644
--- a/modes/multiplayer.tscn
+++ b/modes/multiplayer.tscn
@@ -23,7 +23,7 @@ signal connection_failed
func load_map(scene : PackedScene):
map.add_child(scene.instantiate())
-func start_server(port):
+func start_server(port, nickname):
var peer = ENetMultiplayerPeer.new()
peer.create_server(port, MAX_CLIENTS)
@@ -34,23 +34,21 @@ func start_server(port):
multiplayer.peer_connected.connect(add_player)
multiplayer.peer_disconnected.connect(remove_player)
- for id in multiplayer.get_peers():
- add_player(id)
-
if DisplayServer.get_name() != \"headless\":
- add_player(1)
+ add_player(1, nickname)
add_flag()
-func join_server(host, port):
+func join_server(host, port, nickname):
var peer = ENetMultiplayerPeer.new()
peer.create_client(host, port)
- multiplayer.connected_to_server.connect(_on_connected_to_server)
+ multiplayer.connected_to_server.connect(_on_connected_to_server.bind(nickname))
multiplayer.connection_failed.connect(_on_connection_failed)
multiplayer.multiplayer_peer = peer
-func _on_connected_to_server():
+func _on_connected_to_server(nickname):
connected_to_server.emit()
+ _join_match.rpc(nickname)
func _on_connection_failed():
connection_failed.emit()
@@ -58,10 +56,11 @@ func _on_connection_failed():
func respawn_player(player):
player.respawn(Vector3(0.0, 150.0, 0.0))
-func add_player(peer_id : int):
+func add_player(peer_id : int, nickname : String):
var player : Player = PLAYER.instantiate()
player.name = str(peer_id)
player.player_id = peer_id
+ player.nickname = nickname
player.position = Vector3(0.0, 150.0, 0.0)
players.add_child(player)
player.died.connect(respawn_player)
@@ -73,6 +72,12 @@ func remove_player(peer_id : int):
players.get_node(node_name).queue_free()
print(\"Peer `%s` disconnected\" % node_name)
+@rpc(\"any_peer\")
+func _join_match(nickname):
+ if multiplayer.is_server():
+ add_player(multiplayer.get_remote_sender_id(), nickname)
+
+
func add_flag():
var flag : Flag = FLAG.instantiate()
flag.position = Vector3(5.0, 100.0, 0.0)
diff --git a/weapons/space_gun/projectile_trail.gd b/weapons/space_gun/projectile_trail.gd
index 1296fe8..ac8606a 100644
--- a/weapons/space_gun/projectile_trail.gd
+++ b/weapons/space_gun/projectile_trail.gd
@@ -1,15 +1,15 @@
# This file is part of open-fpsz.
-#
+#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
-#
+#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
class_name Trail3D extends MeshInstance3D
@@ -54,7 +54,7 @@ func _process(delta):
if(_old_pos - get_global_transform().origin).length() > _motion_delta and _trail_enabled:
_append_point() # Create new point
_old_pos = get_global_transform().origin # Update previous position to current position coordinates
-
+
# Update the lifespan
var p = 0
var max_points = _points.size()
@@ -64,29 +64,29 @@ func _process(delta):
_remove_point(p)
p -= 1
if (p < 0): p = 0
-
+
max_points = _points.size()
p += 1
-
+
mesh.clear_surfaces()
-
+
# If less than 2 points, stop rendering trail
if _points.size() < 2:
return
-
+
# Render new mesh for each point
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
-
+
for i in range(_points.size()):
var t = float(i) / (_points.size() - 1.0)
var curr_color = _start_color.lerp(_end_color, 1 - t)
mesh.surface_set_color(curr_color)
-
+
var curr_width = _widths[i][0] - pow(1 - t, _scale_acceleration) * _widths[i][1]
-
+
var t0 = i / _points.size()
var t1 = t
-
+
mesh.surface_set_uv(Vector2(t0, 0))
mesh.surface_add_vertex(to_local(_points[i] + curr_width))
mesh.surface_set_uv(Vector2(t1, 1))