🍻 Shoot straight and clean up mode management

This commit is contained in:
anyreso 2024-04-24 07:08:24 +00:00
parent 8a15bdbd43
commit 81bcd95d42
12 changed files with 262 additions and 327 deletions

View file

@ -2,9 +2,9 @@
[ext_resource type="PackedScene" uid="uid://4naw661fqmjg" path="res://entities/player/assets/vanguard.glb" id="1_d2ik6"]
[ext_resource type="Script" path="res://entities/player/assets/vanguard.gd" id="2_c22xr"]
[ext_resource type="PackedScene" uid="uid://c8co0qa2omjmh" path="res://entities/weapons/space_gun/space_gun.tscn" id="3_c7kd6"]
[ext_resource type="PackedScene" uid="uid://bjcn37ops3bro" path="res://entities/weapons/space_gun/assets/disclauncher.glb" id="3_s13xh"]
[sub_resource type="Animation" id="Animation_a6skd"]
[sub_resource type="Animation" id="Animation_bdd76"]
resource_name = "t_pose"
length = 0.0333333
tracks/0/type = "position_3d"
@ -379,7 +379,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.354872, -0.0338185, -0.004324, 0.934293)
[sub_resource type="Animation" id="Animation_ggabv"]
[sub_resource type="Animation" id="Animation_8iaxi"]
resource_name = "run_left"
length = 0.5
loop_mode = 1
@ -755,7 +755,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="Animation" id="Animation_nbrwa"]
[sub_resource type="Animation" id="Animation_pvd7g"]
resource_name = "jump_up"
length = 0.533333
tracks/0/type = "position_3d"
@ -1130,7 +1130,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="Animation" id="Animation_001mg"]
[sub_resource type="Animation" id="Animation_s40u7"]
resource_name = "idle"
length = 2.1
loop_mode = 1
@ -1506,7 +1506,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="Animation" id="Animation_8nhf0"]
[sub_resource type="Animation" id="Animation_pddls"]
resource_name = "run_backward"
length = 0.5
loop_mode = 1
@ -1882,7 +1882,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="Animation" id="Animation_tq1m2"]
[sub_resource type="Animation" id="Animation_3ql0w"]
resource_name = "run_forward"
length = 0.5
loop_mode = 1
@ -2258,7 +2258,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="Animation" id="Animation_p6pta"]
[sub_resource type="Animation" id="Animation_jep8n"]
resource_name = "run_right"
length = 0.5
loop_mode = 1
@ -2634,7 +2634,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="Animation" id="Animation_kpnct"]
[sub_resource type="Animation" id="Animation_6ahn1"]
resource_name = "death"
length = 2.83333
tracks/0/type = "position_3d"
@ -3009,7 +3009,7 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="Animation" id="Animation_k5qbp"]
[sub_resource type="Animation" id="Animation_pkley"]
resource_name = "jump_loop"
loop_mode = 1
tracks/0/type = "position_3d"
@ -3384,17 +3384,17 @@ tracks/52/interp = 1
tracks/52/loop_wrap = true
tracks/52/keys = PackedFloat32Array(0, 1, 0.624011, -9.44547e-08, 0.04919, 0.779865)
[sub_resource type="AnimationLibrary" id="AnimationLibrary_hxhxq"]
[sub_resource type="AnimationLibrary" id="AnimationLibrary_rvkv6"]
_data = {
"death": SubResource("Animation_kpnct"),
"idle": SubResource("Animation_001mg"),
"jump": SubResource("Animation_k5qbp"),
"jump_up": SubResource("Animation_nbrwa"),
"run_backward": SubResource("Animation_8nhf0"),
"run_forward": SubResource("Animation_tq1m2"),
"run_left": SubResource("Animation_ggabv"),
"run_right": SubResource("Animation_p6pta"),
"t_pose": SubResource("Animation_a6skd")
"death": SubResource("Animation_6ahn1"),
"idle": SubResource("Animation_s40u7"),
"jump": SubResource("Animation_pkley"),
"jump_up": SubResource("Animation_pvd7g"),
"run_backward": SubResource("Animation_pddls"),
"run_forward": SubResource("Animation_3ql0w"),
"run_left": SubResource("Animation_8iaxi"),
"run_right": SubResource("Animation_jep8n"),
"t_pose": SubResource("Animation_bdd76")
}
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_lw37l"]
@ -3453,7 +3453,6 @@ input_2/auto_advance = false
input_2/reset = true
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_1ok7t"]
graph_offset = Vector2(-328.518, -6.27956)
nodes/Death/node = SubResource("AnimationNodeOneShot_ncg4i")
nodes/Death/position = Vector2(860, 380)
"nodes/Death 2/node" = SubResource("AnimationNodeAnimation_lw37l")
@ -3474,18 +3473,20 @@ nodes/output/position = Vector2(1300, 160)
node_connections = [&"Death", 0, &"Death 2", &"GroundSpeed", 0, &"Locomotion", &"OneShot", 0, &"JumpUp", &"OneShot", 1, &"JumpLoop", &"Transition", 0, &"GroundSpeed", &"Transition", 1, &"OneShot", &"Transition", 2, &"Death", &"output", 0, &"Transition"]
[node name="Vanguard" instance=ExtResource("1_d2ik6")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.61612e-06, 0.000176162, 0.000105232)
script = ExtResource("2_c22xr")
[node name="Skeleton3D" parent="Node" index="0"]
bones/0/position = Vector3(0.0091125, 0.978834, 0.00716115)
bones/0/rotation = Quaternion(-0.0304238, -0.416145, -0.0281289, 0.908354)
bones/2/rotation = Quaternion(-0.00126834, -0.00431537, 0.019369, 0.999802)
bones/4/rotation = Quaternion(0.0745231, -0.00841037, 0.0181398, 0.997019)
bones/6/rotation = Quaternion(0.168689, -0.0033058, 0.0113768, 0.985598)
bones/8/rotation = Quaternion(0.678951, -0.411553, 0.402316, 0.455842)
bones/10/rotation = Quaternion(0.208378, -0.0845422, -0.32573, 0.918331)
bones/12/rotation = Quaternion(0.0793166, 0.208833, -0.74794, 0.625048)
bones/14/rotation = Quaternion(0.0322551, 0.0838214, -0.13899, 0.986213)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00146306, 0, -0.00178421)
bones/0/position = Vector3(-0.0048219, 0.946668, 0.00678214)
bones/0/rotation = Quaternion(-0.0341192, -0.409249, -0.0209221, 0.911545)
bones/2/rotation = Quaternion(-0.00595832, -0.0014545, 0.0101407, 0.99993)
bones/4/rotation = Quaternion(0.0691268, 0.00227406, 0.0147948, 0.997496)
bones/6/rotation = Quaternion(0.160951, 0.00623474, 0.0096637, 0.986895)
bones/8/rotation = Quaternion(0.675761, -0.399581, 0.409695, 0.464577)
bones/10/rotation = Quaternion(0.212344, -0.0870591, -0.287653, 0.929831)
bones/12/rotation = Quaternion(0.0811501, 0.206806, -0.754068, 0.618084)
bones/14/rotation = Quaternion(0.00943715, 0.0971687, -0.145046, 0.984597)
bones/20/rotation = Quaternion(-0.123455, 0.0248346, 0.23344, 0.964183)
bones/24/rotation = Quaternion(0.0450683, -0.000817796, 0.0508488, 0.997689)
bones/26/rotation = Quaternion(0.100545, -1.16532e-07, 0.00792588, 0.994901)
@ -3499,12 +3500,13 @@ bones/44/rotation = Quaternion(0.633142, 6.48257e-09, 0.04991, 0.772425)
bones/50/rotation = Quaternion(0.729888, -4.88266e-08, 0.0575362, 0.681141)
bones/52/rotation = Quaternion(0.624011, -9.63141e-08, 0.04919, 0.779865)
bones/54/rotation = Quaternion(-1.18924e-16, 2.81961e-21, -4.50738e-10, 1)
bones/56/rotation = Quaternion(-0.0282395, 0.0506182, -0.0137337, 0.998224)
bones/58/rotation = Quaternion(-0.0161163, 0.300902, -0.0735058, 0.950682)
bones/62/rotation = Quaternion(0.672582, 0.38819, -0.440775, 0.450177)
bones/64/rotation = Quaternion(0.378653, -0.28528, 0.144158, 0.868594)
bones/66/rotation = Quaternion(0.558028, -0.577928, 0.408015, 0.433737)
bones/68/rotation = Quaternion(0.0146346, -0.253118, 0.0594528, 0.965496)
bones/56/rotation = Quaternion(-0.0254885, 0.0439755, -0.00910637, 0.998666)
bones/58/rotation = Quaternion(-0.0119802, 0.289956, -0.0527053, 0.955513)
bones/62/rotation = Quaternion(0.689943, 0.375565, -0.410267, 0.463261)
bones/64/rotation = Quaternion(0.337746, -0.290519, 0.159479, 0.880961)
bones/66/rotation = Quaternion(0.540371, -0.580679, 0.406779, 0.453147)
bones/68/position = Vector3(0.000474975, 0.275475, 0.035475)
bones/68/rotation = Quaternion(0.0150529, -0.289001, 0.0720108, 0.954498)
bones/70/rotation = Quaternion(0.155965, 0.0109114, -0.00107202, 0.987702)
bones/72/rotation = Quaternion(0.563923, 4.19095e-08, -0.0577906, 0.823803)
bones/74/rotation = Quaternion(0.285209, 0.0197164, -0.0936782, 0.953673)
@ -3521,22 +3523,22 @@ bones/100/rotation = Quaternion(-6.44756e-14, -1.4372e-11, -3.12192e-10, 1)
bones/102/rotation = Quaternion(0.179829, 0.0890365, -0.000307644, 0.97966)
bones/104/rotation = Quaternion(0.388149, 1.28057e-07, -0.0397774, 0.920738)
bones/106/rotation = Quaternion(0.372324, -1.37021e-07, -0.0381557, 0.927318)
bones/110/rotation = Quaternion(-0.139688, 0.221395, 0.964738, 0.0274396)
bones/112/rotation = Quaternion(-0.373597, -0.00959325, -0.0354531, 0.926864)
bones/114/rotation = Quaternion(0.517785, 0.099108, 0.0311123, 0.849181)
bones/116/rotation = Quaternion(0.358209, 0.0547665, 0.027865, 0.931617)
bones/120/rotation = Quaternion(0.15189, 0.197526, 0.967067, -0.0518993)
bones/122/rotation = Quaternion(-0.393453, -0.0720602, 0.0315744, 0.915972)
bones/124/rotation = Quaternion(0.357526, -0.0428325, 0.0112871, 0.932852)
bones/126/rotation = Quaternion(0.421703, -0.0297867, 0.00958528, 0.906194)
bones/110/rotation = Quaternion(-0.167577, 0.223934, 0.958827, 0.0492099)
bones/112/rotation = Quaternion(-0.466474, -0.0088339, -0.0232928, 0.884184)
bones/114/rotation = Quaternion(0.575696, 0.0793941, -0.0250592, 0.813414)
bones/116/rotation = Quaternion(0.355062, 0.0493655, 0.0246355, 0.933213)
bones/120/rotation = Quaternion(0.115252, 0.282473, 0.945749, -0.111737)
bones/122/rotation = Quaternion(-0.494906, -0.0647935, 0.0183973, 0.866332)
bones/124/rotation = Quaternion(0.417677, -0.0431149, 0.00625689, 0.90755)
bones/126/rotation = Quaternion(0.397818, -0.0427722, -0.00601182, 0.916447)
[node name="HandAttachment" type="BoneAttachment3D" parent="Node/Skeleton3D" index="0"]
transform = Transform3D(-0.17714, 0.0688076, 0.981778, 0.933879, 0.326602, 0.145608, -0.310631, 0.942654, -0.122112, -0.237544, 1.16641, 0.0838305)
transform = Transform3D(-0.152214, 0.0548832, 0.986823, 0.933991, 0.334546, 0.125459, -0.323252, 0.94078, -0.102183, -0.261612, 1.14328, 0.0896011)
bone_name = "mixamorigRightHand"
bone_idx = 14
[node name="SpaceGun" parent="Node/Skeleton3D/HandAttachment" index="0" instance=ExtResource("3_c7kd6")]
transform = Transform3D(-0.181021, 0.947541, -0.263434, -0.081767, 0.252432, 0.964154, 0.980074, 0.196072, 0.0317819, -0.0066033, 0.122139, 0.016189)
[node name="SpaceGun" parent="Node/Skeleton3D/HandAttachment" index="0" instance=ExtResource("3_s13xh")]
transform = Transform3D(-0.210484, 0.94927, -0.233628, -0.00594419, 0.237735, 0.971312, 0.977578, 0.205834, -0.0443972, 0.0325471, 0.363239, 0.0339617)
[node name="SpineIK" type="SkeletonIK3D" parent="Node/Skeleton3D" index="3"]
process_priority = 1
@ -3551,7 +3553,7 @@ playback_default_blend_time = 0.2
[node name="AnimationTree" type="AnimationTree" parent="." index="2"]
libraries = {
"": SubResource("AnimationLibrary_hxhxq")
"": SubResource("AnimationLibrary_rvkv6")
}
tree_root = SubResource("AnimationNodeBlendTree_1ok7t")
anim_player = NodePath("../AnimationPlayer")

View file

@ -106,9 +106,6 @@ func _fire_primary() -> void:
weapon.transform = _original_weapon_transform
weapon.fire_primary()
weapon.transform = current_weapon_transform
if _is_pawn():
animation_player.stop()
animation_player.play("shoot")
func _jump() -> void:
if _is_player_dead():
@ -158,11 +155,8 @@ func _process(_delta : float) -> void:
iff.show()
if not _is_pawn():
$Smoothing/ThirdPerson/PlayerMesh.global_transform.basis = Basis.from_euler(Vector3(0.0, input.camera_rotation.x + PI, 0.0))
else:
if animation_player.current_animation == "shoot":
pass
else:
animation_player.play("idle")
elif not %Inventory/SpaceGun/Mesh/AnimationPlayer.is_playing():
%Inventory/SpaceGun/Mesh/AnimationPlayer.play("idle")
%SpringArm3D.global_transform.basis = Basis.from_euler(Vector3(input.camera_rotation.y, input.camera_rotation.x, 0.0))
func _physics_process(delta : float) -> void:

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=21 format=3 uid="uid://cbhx1xme0sb7k"]
[gd_scene load_steps=18 format=3 uid="uid://cbhx1xme0sb7k"]
[ext_resource type="Script" path="res://entities/player/player.gd" id="1_mk68k"]
[ext_resource type="PackedScene" uid="uid://drbefw6akui2v" path="res://entities/player/assets/vanguard.tscn" id="2_beyex"]
@ -22,57 +22,6 @@ absorbent = true
material = SubResource("StandardMaterial3D_1hdqa")
radius = 0.25
[sub_resource type="Animation" id="Animation_cb46l"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Smoothing/SpringArm3D:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.0001),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(0, 0.5, 0), Vector3(0, 0.5, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Smoothing/SpringArm3D:rotation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 0, 0)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0.15, -0.3, -0.2)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:rotation")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 3.14159, 0)]
}
[sub_resource type="Animation" id="Animation_yqgrk"]
resource_name = "death"
tracks/0/type = "value"
@ -100,68 +49,9 @@ tracks/1/keys = {
"values": [Vector3(0, 0, 0), Vector3(-1.35254, 0, 0)]
}
[sub_resource type="Animation" id="Animation_as2v0"]
resource_name = "idle"
length = 3.0
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1.5),
"transitions": PackedFloat32Array(-2, -2),
"update": 0,
"values": [Vector3(0.15, -0.3, -0.2), Vector3(0.15, -0.3, -0.2)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:rotation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 1.5),
"transitions": PackedFloat32Array(-2, -2),
"update": 0,
"values": [Vector3(0, 3.14159, 0), Vector3(0.0698132, 3.14159, 0)]
}
[sub_resource type="Animation" id="Animation_p84l0"]
resource_name = "shoot"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(0.5, 1),
"update": 0,
"values": [Vector3(0.15, -0.3, -0.2), Vector3(0.15, -0.3, -0.2)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Smoothing/SpringArm3D/Inventory/SpaceGun:rotation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(0.5, 1),
"update": 0,
"values": [Vector3(-0.0584511, 3.14159, 8.83593e-09), Vector3(0, 3.14159, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_hg307"]
_data = {
"RESET": SubResource("Animation_cb46l"),
"death": SubResource("Animation_yqgrk"),
"idle": SubResource("Animation_as2v0"),
"shoot": SubResource("Animation_p84l0")
"death": SubResource("Animation_yqgrk")
}
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_rqdp6"]
@ -274,9 +164,10 @@ fov = 90.0
near = 0.1
[node name="Inventory" type="Node3D" parent="Smoothing/SpringArm3D"]
unique_name_in_owner = true
[node name="SpaceGun" parent="Smoothing/SpringArm3D/Inventory" node_paths=PackedStringArray("holder") instance=ExtResource("4_6jh57")]
transform = Transform3D(-1, 0, 2.53518e-06, 0, 1, 0, -2.53518e-06, 0, -1, 0.15, -0.3, -0.2)
transform = Transform3D(-1, 0, 2.53518e-06, 0, 1, 0, -2.53518e-06, 0, -1, 0.15, -0.3, -0.55)
holder = NodePath("../../../..")
[node name="SpineIKTarget" type="Node3D" parent="Smoothing/SpringArm3D"]

View file

@ -32,18 +32,25 @@ func can_fire() -> bool:
return weapon_state == WeaponState.WEAPON_READY
func fire_primary() -> void:
# check permission
if not can_fire():
return
# init projectile
var projectile : Node = PROJECTILE.instantiate()
# configure projectile
projectile.shooter = holder
projectile.transform = nozzle.global_transform
projectile.velocity = nozzle.global_basis.z.normalized() * projectile.speed
projectile.shooter = holder
var inheritance_factor : float = clamp(inheritance, 0., 1.)
projectile.velocity += (inventory.owner.linear_velocity * inheritance_factor)
# play the fire animation
$Mesh/AnimationPlayer.play("fire")
# add projectile as sibling of the owner
inventory.owner.add_sibling(projectile)
# ensure projectile does not collide with owner
var collider : ShapeCast3D = projectile.shape_cast
collider.add_exception(inventory.owner)
# update states
weapon_state = WeaponState.WEAPON_RELOADING
await get_tree().create_timer(reload_time).timeout
weapon_state = WeaponState.WEAPON_READY

View file

@ -8,7 +8,27 @@
script = ExtResource("1_6sm4s")
PROJECTILE = ExtResource("2_wvneg")
[node name="disclauncher" parent="." instance=ExtResource("3_5k2xm")]
[node name="Mesh" parent="." instance=ExtResource("3_5k2xm")]
[node name="Skeleton3D" parent="Mesh/Armature" index="0"]
bones/0/scale = Vector3(1, 1, 1)
bones/1/rotation = Quaternion(-0.707107, 5.33851e-08, 5.33851e-08, 0.707107)
bones/1/scale = Vector3(1, 1, 1)
bones/2/rotation = Quaternion(-0.707107, 5.33851e-08, 5.33851e-08, 0.707107)
bones/2/scale = Vector3(1, 1, 1)
bones/3/rotation = Quaternion(-0.707107, 5.33851e-08, 5.33851e-08, 0.707107)
bones/3/scale = Vector3(1, 1, 1)
[node name="grip" parent="Mesh/Armature/Skeleton3D" index="0"]
transform = Transform3D(1, -4.26326e-14, -2.13163e-14, 2.84217e-14, 1, -3.57628e-07, 3.2684e-14, 3.57628e-07, 1, -1.42109e-14, -2.98023e-07, 2.38419e-07)
[node name="main" parent="Mesh/Armature/Skeleton3D" index="1"]
transform = Transform3D(1, -4.26326e-14, -2.13163e-14, 2.84217e-14, 1, -3.57628e-07, 3.2684e-14, 3.57628e-07, 1, -1.42109e-14, -2.98023e-07, 2.38419e-07)
[node name="sides" parent="Mesh/Armature/Skeleton3D" index="2"]
transform = Transform3D(1, -4.26326e-14, -2.13163e-14, 2.84217e-14, 1, -3.57628e-07, 3.2684e-14, 3.57628e-07, 1, -1.42109e-14, -2.98023e-07, 2.38419e-07)
[node name="Nozzle" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.111355, 0.540839)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.27)
[editable path="Mesh"]

View file

@ -6,7 +6,6 @@ sky_horizon_color = Color(0.819608, 0.592157, 0.556863, 1)
sky_curve = 0.235375
ground_bottom_color = Color(0.819608, 0.592157, 0.556863, 1)
ground_horizon_color = Color(0.819608, 0.592157, 0.556863, 1)
ground_curve = 0.02
[sub_resource type="Sky" id="Sky_mobku"]
sky_material = SubResource("ProceduralSkyMaterial_8mbvu")

View file

@ -36,7 +36,7 @@ func _show_menu(menu : PanelContainer) -> void:
bg_color = Color(0.501961, 0.501961, 0.501961, 0.25098)
[sub_resource type="GDScript" id="GDScript_tc1bm"]
script/source = "class_name Multiplayer extends PanelContainer
script/source = "extends PanelContainer
const DEFAULT_HOST : String = \"localhost\"
const DEFAULT_PORT : int = 9000

View file

@ -11,46 +11,41 @@ script/source = "class_name Game extends Node3D
@export var SINGLEPLAYER : PackedScene
@export var MULTIPLAYER : PackedScene
var mode : Node
var mode : Node:
set(new_mode):
# clean up previous mode
if mode != null:
mode.queue_free()
# keep reference to new mode
mode = new_mode
# setup new mode
if new_mode != null:
add_child(new_mode)
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
else:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
func _ready() -> void:
$BootMenu.start_demo.connect(_start_demo)
$BootMenu/Multiplayer.start_server.connect(_start_server)
$BootMenu/Multiplayer.join_server.connect(_join_server)
func _start_demo() -> void:
_set_game_mode(SINGLEPLAYER.instantiate())
$BootMenu.hide()
func _start_server(port : int, nickname : String) -> void:
_set_game_mode(MULTIPLAYER.instantiate())
mode.start_server(port, nickname)
$BootMenu.hide()
func _join_server(host : String, port : int, nickname : String) -> void:
_set_game_mode(MULTIPLAYER.instantiate())
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, nickname)
func _input(event : InputEvent) -> void:
if event.is_action_pressed(\"exit\"):
_set_game_mode(null)
multiplayer.multiplayer_peer.close()
$BootMenu.show()
func _set_game_mode(new_mode : Node) -> void:
if mode != null:
remove_child(mode)
mode.queue_free()
mode = new_mode
if mode == null:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
else:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
add_child(mode)
func _unhandled_input(event : InputEvent) -> void:
# escape key pressed
if event.is_action_pressed(\"exit\"):
# game modes cleanup
if mode is Multiplayer:
multiplayer.multiplayer_peer.close()
# reset game mode
mode = null
# check for debug build
if not OS.is_debug_build():
# exit with success
get_tree().quit(0)
else:
# show boot menu
$BootMenu.show()
# switch window mode
if event.is_action_pressed(\"window_mode\"):
if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN:
@ -64,6 +59,21 @@ func _unhandled_input(event : InputEvent) -> void:
elif Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
func _start_demo() -> void:
mode = SINGLEPLAYER.instantiate()
$BootMenu.hide()
func _start_server(port : int, nickname : String) -> void:
mode = MULTIPLAYER.instantiate()
mode.start_server(port, nickname)
$BootMenu.hide()
func _join_server(host : String, port : int, nickname : String) -> void:
mode = MULTIPLAYER.instantiate()
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, nickname)
"
[node name="Game" type="Node3D"]

View file

@ -16,7 +16,7 @@ script/source = "extends Node
func _ready() -> void:
player_node.died.connect(respawn_player)
func respawn_player(player : Player) -> void:
func respawn_player(player : Player, _killer_id : int) -> void:
player.respawn(player_respawn_location)
"

128
modes/multiplayer.gd Normal file
View file

@ -0,0 +1,128 @@
# 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 <https://www.gnu.org/licenses/>.
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
@export var RESPAWN_TIME : float = 3.0
@onready var players : Node = $Players
@onready var objectives : Node = $Objectives
@onready var map : Node = $Map
@onready var scoreboard : Scoreboard = $Scoreboard
@onready var scoreboard_ui : Node = $ScoreboardUI
var _map_manager : Map
signal connected_to_server
signal connection_failed
func start_server(port : int, nickname : String) -> void:
var peer : ENetMultiplayerPeer = ENetMultiplayerPeer.new()
peer.create_server(port, MAX_CLIENTS)
multiplayer.multiplayer_peer = peer
_load_map.call_deferred(MAP, nickname)
multiplayer.peer_disconnected.connect(remove_player)
func join_server(host : String, port : int, nickname : String) -> void:
var peer : ENetMultiplayerPeer = ENetMultiplayerPeer.new()
peer.create_client(host, port)
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(nickname : String) -> void:
connected_to_server.emit()
scoreboard.request_scoreboard_from_authority.rpc()
_join_match.rpc(nickname)
func _on_connection_failed() -> void:
connection_failed.emit()
func _on_player_died(player : Player, killer_id : int) -> void:
if player.player_id != killer_id:
var node_name : String = str(killer_id)
if players.has_node(node_name):
var killer : Player = players.get_node(node_name)
scoreboard.increment_kill_count(killer)
scoreboard.add_score_to_player(killer, 10)
scoreboard.broadcast_player_score_update(killer)
await get_tree().create_timer(RESPAWN_TIME).timeout
respawn_player(player)
func respawn_player(player : Player) -> void:
var spawn_location : Vector3 = _map_manager.get_player_spawn().position
player.respawn(spawn_location)
func add_player(peer_id : int, nickname : String) -> void:
var player : Player = PLAYER.instantiate()
player.name = str(peer_id)
player.player_id = peer_id
player.nickname = nickname
player.global_position = _map_manager.get_player_spawn().position
players.add_child(player)
player.died.connect(_on_player_died)
scoreboard.add_entry(player)
print("Peer `%s` connected" % player.name)
func remove_player(peer_id : int) -> void:
var node_name : String = str(peer_id)
if players.has_node(node_name):
var player : Player = players.get_node(node_name)
scoreboard.remove_entry(player)
player.die(-1)
player.queue_free()
print("Peer `%s` disconnected" % node_name)
func _load_map(scene : PackedScene, nickname : String) -> void:
var map_scene : Node = scene.instantiate()
_map_manager = map_scene
map_scene.ready.connect(_add_flag)
if DisplayServer.get_name() != "headless":
add_player(1, nickname)
map.add_child(map_scene)
func _add_flag() -> void:
var flag : Flag = FLAG.instantiate()
flag.global_position = _map_manager.get_flagstand().global_position
objectives.add_child(flag)
func _unhandled_input(event : InputEvent) -> void:
if event.is_action_pressed("scoreboard"):
var entries : Array = scoreboard.get_entries()
for entry : Scoreboard.ScoreboardEntry in entries:
var entry_label : Label = Label.new()
entry_label.text = "%s | kills: %s | score: %s" % [entry.nickname, entry.kills, entry.score]
%Scores.add_child(entry_label)
scoreboard_ui.show()
elif event.is_action_released("scoreboard"):
scoreboard_ui.hide()
for score_label in %Scores.get_children():
score_label.queue_free()
@rpc("any_peer")
func _join_match(nickname : String) -> void:
if is_multiplayer_authority():
add_player(multiplayer.get_remote_sender_id(), nickname)
func _exit_tree() -> void:
if is_multiplayer_authority():
multiplayer.peer_disconnected.disconnect(remove_player)

View file

@ -1,129 +1,13 @@
[gd_scene load_steps=6 format=3 uid="uid://bvwxfgygm2xb8"]
[ext_resource type="Script" path="res://modes/multiplayer.gd" id="1_4t1ad"]
[ext_resource type="PackedScene" uid="uid://chbno00ugl6te" path="res://maps/genesis/genesis.tscn" id="1_nulvv"]
[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"]
[ext_resource type="Script" path="res://modes/scoreboard.gd" id="4_n0mhp"]
[sub_resource type="GDScript" id="GDScript_1qrbp"]
script/source = "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
@export var RESPAWN_TIME : float = 3.0
@onready var players : Node = $Players
@onready var objectives : Node = $Objectives
@onready var map : Node = $Map
@onready var scoreboard : Scoreboard = $Scoreboard
@onready var scoreboard_ui : Node = $ScoreboardUI
var _map_manager : Map
signal connected_to_server
signal connection_failed
func start_server(port : int, nickname : String) -> void:
var peer : ENetMultiplayerPeer = ENetMultiplayerPeer.new()
peer.create_server(port, MAX_CLIENTS)
multiplayer.multiplayer_peer = peer
_load_map.call_deferred(MAP, nickname)
multiplayer.peer_disconnected.connect(remove_player)
func join_server(host : String, port : int, nickname : String) -> void:
var peer : ENetMultiplayerPeer = ENetMultiplayerPeer.new()
peer.create_client(host, port)
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(nickname : String) -> void:
connected_to_server.emit()
scoreboard.request_scoreboard_from_authority.rpc()
_join_match.rpc(nickname)
func _on_connection_failed() -> void:
connection_failed.emit()
func _on_player_died(player : Player, killer_id : int) -> void:
if player.player_id != killer_id:
var node_name : String = str(killer_id)
if players.has_node(node_name):
var killer : Player = players.get_node(node_name)
scoreboard.increment_kill_count(killer)
scoreboard.add_score_to_player(killer, 10)
scoreboard.broadcast_player_score_update(killer)
await get_tree().create_timer(RESPAWN_TIME).timeout
respawn_player(player)
func respawn_player(player : Player) -> void:
var spawn_location : Vector3 = _map_manager.get_player_spawn().position
player.respawn(spawn_location)
func add_player(peer_id : int, nickname : String) -> void:
var player : Player = PLAYER.instantiate()
player.name = str(peer_id)
player.player_id = peer_id
player.nickname = nickname
player.global_position = _map_manager.get_player_spawn().position
players.add_child(player)
player.died.connect(_on_player_died)
scoreboard.add_entry(player)
print(\"Peer `%s` connected\" % player.name)
func remove_player(peer_id : int) -> void:
var node_name : String = str(peer_id)
if players.has_node(node_name):
var player : Player = players.get_node(node_name)
scoreboard.remove_entry(player)
player.die(-1)
player.queue_free()
print(\"Peer `%s` disconnected\" % node_name)
func _load_map(scene : PackedScene, nickname : String) -> void:
var map_scene : Node = scene.instantiate()
_map_manager = map_scene
map_scene.ready.connect(_add_flag)
if DisplayServer.get_name() != \"headless\":
add_player(1, nickname)
map.add_child(map_scene)
func _add_flag() -> void:
var flag : Flag = FLAG.instantiate()
flag.global_position = _map_manager.get_flagstand().global_position
objectives.add_child(flag)
func _unhandled_input(event : InputEvent) -> void:
if event.is_action_pressed(\"scoreboard\"):
var entries : Array = scoreboard.get_entries()
for entry : Scoreboard.ScoreboardEntry in entries:
var entry_label : Label = Label.new()
entry_label.text = \"%s | kills: %s | score: %s\" % [entry.nickname, entry.kills, entry.score]
%Scores.add_child(entry_label)
scoreboard_ui.show()
elif event.is_action_released(\"scoreboard\"):
scoreboard_ui.hide()
for score_label in %Scores.get_children():
score_label.queue_free()
@rpc(\"any_peer\")
func _join_match(nickname : String) -> void:
if is_multiplayer_authority():
add_player(multiplayer.get_remote_sender_id(), nickname)
func _exit_tree() -> void:
if is_multiplayer_authority():
multiplayer.peer_disconnected.disconnect(remove_player)
"
[node name="Multiplayer" type="Node"]
script = SubResource("GDScript_1qrbp")
script = ExtResource("1_4t1ad")
MAP = ExtResource("1_nulvv")
PLAYER = ExtResource("2_og1vb")
FLAG = ExtResource("3_h0rie")