diff --git a/entities/player/assets/vanguard.tscn b/entities/player/assets/vanguard.tscn index 3050893..6d571ac 100644 --- a/entities/player/assets/vanguard.tscn +++ b/entities/player/assets/vanguard.tscn @@ -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") diff --git a/entities/player/player.gd b/entities/player/player.gd index 727182f..75bd6c9 100644 --- a/entities/player/player.gd +++ b/entities/player/player.gd @@ -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: diff --git a/entities/player/player.tscn b/entities/player/player.tscn index 9e99c3d..f821659 100644 --- a/entities/player/player.tscn +++ b/entities/player/player.tscn @@ -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"] diff --git a/entities/weapons/space_gun/assets/disclauncher.glb b/entities/weapons/space_gun/assets/disclauncher.glb index 5c319b3..a57cce8 100644 Binary files a/entities/weapons/space_gun/assets/disclauncher.glb and b/entities/weapons/space_gun/assets/disclauncher.glb differ diff --git a/entities/weapons/space_gun/space_gun.gd b/entities/weapons/space_gun/space_gun.gd index 939d174..cdc3b1d 100644 --- a/entities/weapons/space_gun/space_gun.gd +++ b/entities/weapons/space_gun/space_gun.gd @@ -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 diff --git a/entities/weapons/space_gun/space_gun.tscn b/entities/weapons/space_gun/space_gun.tscn index 91cf752..64ab1e4 100644 --- a/entities/weapons/space_gun/space_gun.tscn +++ b/entities/weapons/space_gun/space_gun.tscn @@ -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"] diff --git a/environments/desert.tres b/environments/desert.tres index d55112b..097fe5d 100644 --- a/environments/desert.tres +++ b/environments/desert.tres @@ -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") diff --git a/interfaces/menus/boot/boot.tscn b/interfaces/menus/boot/boot.tscn index f32d9af..67fa3f0 100644 --- a/interfaces/menus/boot/boot.tscn +++ b/interfaces/menus/boot/boot.tscn @@ -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 diff --git a/main.tscn b/main.tscn index b6999d0..14fe0f0 100644 --- a/main.tscn +++ b/main.tscn @@ -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"] diff --git a/modes/demo.tscn b/modes/demo.tscn index fc90ac3..3fe8a59 100644 --- a/modes/demo.tscn +++ b/modes/demo.tscn @@ -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) " diff --git a/modes/multiplayer.gd b/modes/multiplayer.gd new file mode 100644 index 0000000..9a91d49 --- /dev/null +++ b/modes/multiplayer.gd @@ -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 . +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) diff --git a/modes/multiplayer.tscn b/modes/multiplayer.tscn index df1397c..7f504b0 100644 --- a/modes/multiplayer.tscn +++ b/modes/multiplayer.tscn @@ -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")