From 3df8247a849b87d2778478eb078653a348da043c Mon Sep 17 00:00:00 2001 From: Rendo Date: Sat, 29 Nov 2025 23:46:16 +0500 Subject: [PATCH] Round system --- levels/prototype_scene.tscn | 129 ++++++++----- materials/Yellowmat.tres | 2 + scenes/molikman.tscn | 136 ++++++++++++-- scenes/weapons/active_bomb.tscn | 5 - scripts/gui/hud/player_round_display.gd | 18 ++ scripts/gui/hud/player_round_display.gd.uid | 1 + scripts/gui/hud/player_round_time.gd | 8 + scripts/gui/hud/player_round_time.gd.uid | 1 + scripts/item_spawner.gd | 6 +- scripts/multiplayer/lobby.gd | 21 +++ scripts/multiplayer/own_visibility_toggle.gd | 3 + scripts/multiplayer/session.gd | 171 ++++++++++++++++++ scripts/multiplayer/team_spawner.gd | 14 +- scripts/object_container.gd | 16 ++ scripts/object_container.gd.uid | 1 + scripts/player/dead_player_spectator.gd | 36 ++++ scripts/player/dead_player_spectator.gd.uid | 1 + scripts/player/player.gd | 9 +- scripts/player/player_camera.gd | 4 +- scripts/player/player_movement.gd | 21 +++ scripts/player/player_movement.gd.uid | 1 + scripts/player/spectator.gd | 4 + scripts/player/states/crouching.gd | 11 +- scripts/player/states/death.gd | 12 ++ scripts/player/states/death.gd.uid | 1 + scripts/player/states/falling.gd | 10 +- scripts/player/states/standing.gd | 13 +- scripts/player/states/walk.gd | 11 +- scripts/weapon_system/bomb/active_bomb.gd | 3 +- scripts/weapon_system/bomb/bomb_main_state.gd | 4 + scripts/weapon_system/weapon_system.gd | 10 +- textures/prototype_256x256.svg | 13 +- 32 files changed, 573 insertions(+), 123 deletions(-) create mode 100644 scripts/gui/hud/player_round_display.gd create mode 100644 scripts/gui/hud/player_round_display.gd.uid create mode 100644 scripts/gui/hud/player_round_time.gd create mode 100644 scripts/gui/hud/player_round_time.gd.uid create mode 100644 scripts/object_container.gd create mode 100644 scripts/object_container.gd.uid create mode 100644 scripts/player/dead_player_spectator.gd create mode 100644 scripts/player/dead_player_spectator.gd.uid create mode 100644 scripts/player/player_movement.gd create mode 100644 scripts/player/player_movement.gd.uid create mode 100644 scripts/player/states/death.gd create mode 100644 scripts/player/states/death.gd.uid diff --git a/levels/prototype_scene.tscn b/levels/prototype_scene.tscn index 027e7d9..c3baba5 100644 --- a/levels/prototype_scene.tscn +++ b/levels/prototype_scene.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=22 format=3 uid="uid://cqrh2cc7m2i7f"] +[gd_scene load_steps=24 format=3 uid="uid://cqrh2cc7m2i7f"] [ext_resource type="Environment" uid="uid://d0cfgtx2yxw13" path="res://environments/prototype_environment.tres" id="1_i6jab"] [ext_resource type="Script" uid="uid://ypgm3aplt78m" path="res://scripts/multiplayer/team_spawner.gd" id="4_pi0y7"] @@ -15,6 +15,7 @@ [ext_resource type="Script" uid="uid://dk1gjbuydemmb" path="res://scripts/multiplayer/plant_site/plant_site.gd" id="8_oujx2"] [ext_resource type="Script" uid="uid://b4cpux52fmx5o" path="res://scripts/multiplayer/plant_site/plant_deadzone.gd" id="9_1wlgq"] [ext_resource type="Material" uid="uid://c6xa4phihtya2" path="res://materials/Redmat.tres" id="9_ysk2e"] +[ext_resource type="Script" uid="uid://3i00rp8urth7" path="res://scripts/object_container.gd" id="11_02ic3"] [sub_resource type="Animation" id="Animation_y6i55"] length = 0.001 @@ -31,7 +32,10 @@ _data = { } [sub_resource type="BoxShape3D" id="BoxShape3D_ysk2e"] -size = Vector3(15.324341, 1.4935913, 21.381592) +size = Vector3(15.324341, 0.96273804, 21.381592) + +[sub_resource type="BoxShape3D" id="BoxShape3D_8bje3"] +size = Vector3(0.8275013, 0.96273804, 1.0796204) [sub_resource type="BoxShape3D" id="BoxShape3D_1wlgq"] size = Vector3(34.28946, 8.172485, 33.813843) @@ -49,6 +53,12 @@ shadow_opacity = 0.72 [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = ExtResource("1_i6jab") +[node name="CSGBox3D29" type="CSGBox3D" parent="."] +transform = Transform3D(0.92477864, 0, 0.38050553, 0, 1, 0, -0.38050553, 0, 0.92477864, 2.3401544, 1.2806039, -9.494778) +use_collision = true +size = Vector3(1.5958366, 1.7258911, 1.7827377) +material = ExtResource("5_foctg") + [node name="CSGCombiner3D" type="CSGCombiner3D" parent="."] use_collision = true collision_mask = 9 @@ -61,23 +71,20 @@ size = Vector3(126.25586, 1, 100.838135) material = ExtResource("4_y6i55") [node name="CSGBox3D18" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20.487278, 2.707026, -9.567705) -size = Vector3(4.0271816, 4.5787354, 5.284851) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20.487278, 3.9812875, -24.729654) +size = Vector3(4.0271816, 7.1272583, 33.69597) material = ExtResource("5_bno23") -[node name="CSGBox3D22" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20.487278, 6.839224, -24.810701) -size = Vector3(4.0271816, 3.7450104, 35.770844) +[node name="CSGBox3D19" type="CSGBox3D" parent="CSGCombiner3D/CSGBox3D18"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.0283356, 4.066929) +operation = 2 +size = Vector3(4.0271816, 5.070587, 6.0345716) material = ExtResource("5_bno23") -[node name="CSGBox3D19" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20.487278, 2.707026, -23.270264) -size = Vector3(4.0271816, 4.5787354, 14.136078) -material = ExtResource("5_bno23") - -[node name="CSGBox3D20" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 20.347204, 2.707026, -39.01053) -size = Vector3(4.307333, 4.5787354, 7.6101303) +[node name="CSGBox3D20" type="CSGBox3D" parent="CSGCombiner3D/CSGBox3D18"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.0283356, -14.085073) +operation = 2 +size = Vector3(4.0271816, 5.070587, 3.538221) material = ExtResource("5_bno23") [node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D"] @@ -86,15 +93,10 @@ size = Vector3(3.9233856, 7.2024536, 17.76538) material = ExtResource("5_bno23") [node name="CSGBox3D25" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.4624505, 2.707026, -10.422279) -size = Vector3(1.047142, 4.5787354, 5.901947) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.4624505, 2.707026, -12.430679) +size = Vector3(1.047142, 4.5787354, 9.918747) material = ExtResource("4_yx0ab") -[node name="CSGBox3D29" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(0.92477864, 0, 0.38050553, 0, 1, 0, -0.38050553, 0, 0.92477864, 2.3401544, 1.2806039, -9.494778) -size = Vector3(1.5958366, 1.7258911, 1.7827377) -material = ExtResource("5_foctg") - [node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8.189109, 2.707026, 24.290133) size = Vector3(3.9233856, 4.5787354, 9.820068) @@ -141,11 +143,6 @@ transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -46. size = Vector3(85.006775, 4.5787354, 5.6578064) material = ExtResource("6_8bje3") -[node name="CSGBox3D14" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(-0.50000006, 0, -0.8660254, 0, 1, 0, 0.8660254, 0, -0.50000006, -48.2127, 2.7070298, -31.084457) -size = Vector3(41.872528, 4.5787354, 35.261032) -material = ExtResource("5_bno23") - [node name="CSGBox3D15" type="CSGBox3D" parent="CSGCombiner3D"] transform = Transform3D(0.8660254, 0, -0.5, 0, 1, 0, 0.5, 0, 0.8660254, -32.975563, 17.84463, 39.652107) size = Vector3(41.872528, 34.853943, 27.1624) @@ -167,19 +164,21 @@ polygon = PackedVector2Array(-1.3562565, -1.5799096, -1.3376074, 1.3967638, 3.46 depth = 14.19 material = ExtResource("5_bno23") -[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.175511, 8.376497, -12.051787) -size = Vector3(9.126762, 15.917679, 8.480011) -material = ExtResource("5_bno23") - -[node name="CSGBox3D17" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -33.36447, 9.907686, -16.614532) -size = Vector3(19.777737, 18.980057, 17.6055) -material = ExtResource("5_bno23") - [node name="CSGBox3D16" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -22.201584, 11.806246, -32.960644) -size = Vector3(29.178907, 22.777176, 17.689468) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -28.345552, 11.806246, -24.122513) +size = Vector3(41.466846, 22.777176, 35.36573) +material = ExtResource("5_bno23") + +[node name="CSGBox3D18" type="CSGBox3D" parent="CSGCombiner3D/CSGBox3D16"] +transform = Transform3D(0.2478614, 0, 0.96879554, 0, 1, 0, -0.96879554, 0, 0.2478614, -0.98422813, -9.519702, 10.0603485) +operation = 2 +size = Vector3(20.900824, 3.737772, 4.796875) +material = ExtResource("5_bno23") + +[node name="CSGBox3D19" type="CSGBox3D" parent="CSGCombiner3D/CSGBox3D16"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 11.064535, -9.519702, 1.6905918) +operation = 2 +size = Vector3(23.704197, 3.737772, 4.796875) material = ExtResource("5_bno23") [node name="CSGBox3D4" type="CSGBox3D" parent="CSGCombiner3D"] @@ -188,13 +187,38 @@ size = Vector3(5.681938, 18.808083, 7.111515) material = ExtResource("6_foctg") [node name="CSGBox3D21" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(0.99998313, 0, -0.005811914, 0, 1, 0, 0.005811914, 0, 0.99998313, 5.4263325, 3.1404138, -35.9143) -size = Vector3(17.193996, 5.445511, 2.406681) +transform = Transform3D(0.99998313, 0, -0.005811914, 0, 1, 0, 0.005811914, 0, 0.99998313, 7.7764754, 2.6420484, -35.90064) +size = Vector3(21.894361, 4.44878, 2.406681) +material = ExtResource("4_yx0ab") + +[node name="CSGBox3D30" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.99998313, 0, -0.005811914, 0, 1, 0, 0.005811914, 0, 0.99998313, -1.0181996, 6.118735, -35.927147) +size = Vector3(1.8304019, 2.8889408, 1.5464945) +material = ExtResource("4_yx0ab") + +[node name="CSGBox3D31" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.99998313, 0, -0.005811914, 0, 1, 0, 0.005811914, 0, 0.99998313, 2.7812057, 6.118735, -35.927147) +size = Vector3(1.8304019, 2.8889408, 1.5464945) +material = ExtResource("4_yx0ab") + +[node name="CSGBox3D32" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.99998313, 0, -0.005811914, 0, 1, 0, 0.005811914, 0, 0.99998313, 8.024893, 6.118735, -35.927147) +size = Vector3(1.8304019, 2.8889408, 1.5464945) +material = ExtResource("4_yx0ab") + +[node name="CSGBox3D33" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.99998313, 0, -0.005811914, 0, 1, 0, 0.005811914, 0, 0.99998313, 12.4400835, 6.118735, -35.927147) +size = Vector3(1.8304019, 2.8889408, 1.5464945) +material = ExtResource("4_yx0ab") + +[node name="CSGBox3D34" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(0.99998313, 0, -0.005811914, 0, 1, 0, 0.005811914, 0, 0.99998313, 17.691769, 6.118735, -35.927147) +size = Vector3(1.8304019, 2.8889408, 1.5464945) material = ExtResource("4_yx0ab") [node name="CSGBox3D24" type="CSGBox3D" parent="CSGCombiner3D"] -transform = Transform3D(1, 0, 0, 0, 0.93200153, -0.3624543, 0, 0.3624543, 0.93200153, 2.6995444, 6.9419756, -39.9535) -size = Vector3(33.342323, 1.3384781, 10.485079) +transform = Transform3D(1, 0, 0, 0, 0.93200153, -0.3624543, 0, 0.3624543, 0.93200153, 5.8547053, 8.527166, -37.974197) +size = Vector3(27.032001, 1.3384781, 6.2376566) material = ExtResource("7_8bje3") [node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D"] @@ -231,7 +255,9 @@ libraries = { } autoplay = "main" -[node name="PlayersContainer" type="Node3D" parent="."] +[node name="PlayersContainer" type="Node3D" parent="." node_paths=PackedStringArray("exlusion_list")] +script = ExtResource("11_02ic3") +exlusion_list = [NodePath("DefenceSpawn"), NodePath("AttackSpawn"), NodePath("SpectatorSpawn"), NodePath("MultiplayerSpawner")] [node name="DefenceSpawn" type="Marker3D" parent="PlayersContainer"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 37.170197, 0.5180037, 9.210396) @@ -254,7 +280,9 @@ spawn_radius = 10.0 _spawnable_scenes = PackedStringArray("uid://dpsr6ug3pkb40", "uid://ckjabjcvgki6n") spawn_path = NodePath("..") -[node name="DynamicObjectsContainer" type="Node3D" parent="."] +[node name="DynamicObjectsContainer" type="Node3D" parent="." node_paths=PackedStringArray("exlusion_list")] +script = ExtResource("11_02ic3") +exlusion_list = [NodePath("MultiplayerSpawner"), NodePath("Bomb")] [node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="DynamicObjectsContainer"] _spawnable_scenes = PackedStringArray("uid://dtbpyfdawb02b", "uid://cxdgk74ln5xpn", "uid://dgfqppi21c2u0") @@ -288,8 +316,14 @@ collision_mask = 16 script = ExtResource("8_oujx2") [node name="CollisionShape3D" type="CollisionShape3D" parent="PlantA"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.484192, 0.24679565, 3.1519775) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.484192, -0.018630981, 3.1519775) shape = SubResource("BoxShape3D_ysk2e") +debug_color = Color(0.96, 0, 0.5279997, 0.9411765) + +[node name="CollisionShape3D2" type="CollisionShape3D" parent="PlantA"] +transform = Transform3D(0.92546135, 0, 0.37884247, 0, 1, 0, -0.37884247, 0, 0.92546135, 0.7677882, 0.9896631, 11.913087) +shape = SubResource("BoxShape3D_8bje3") +debug_color = Color(0.96, 0, 0.5279997, 0.9411765) [node name="PlantADeadzone" type="Area3D" parent="." node_paths=PackedStringArray("bound_plant")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 9.00709, -26.598661) @@ -305,3 +339,6 @@ shape = SubResource("BoxShape3D_1wlgq") [node name="CollisionShape3D2" type="CollisionShape3D" parent="PlantADeadzone"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.8295212, -7.2330484, 25.29969) shape = SubResource("BoxShape3D_5uqia") + +[node name="DefaultCamera" type="Camera3D" parent="."] +transform = Transform3D(0.6629243, -0.44385082, 0.60293275, 0.022305315, 0.81667197, 0.57667094, -0.7483541, -0.36884052, 0.5512919, 17.194904, 16.47376, -9.509804) diff --git a/materials/Yellowmat.tres b/materials/Yellowmat.tres index 27777a5..3185d05 100644 --- a/materials/Yellowmat.tres +++ b/materials/Yellowmat.tres @@ -5,3 +5,5 @@ [resource] albedo_texture = ExtResource("1_anv2g") uv1_offset = Vector3(0.5, 0.5, 0.5) +uv1_triplanar = true +uv2_offset = Vector3(0.5, 0.5, 0.5) diff --git a/scenes/molikman.tscn b/scenes/molikman.tscn index 46b6aeb..0a21eaa 100644 --- a/scenes/molikman.tscn +++ b/scenes/molikman.tscn @@ -1,15 +1,15 @@ -[gd_scene load_steps=29 format=3 uid="uid://dpsr6ug3pkb40"] +[gd_scene load_steps=34 format=3 uid="uid://dpsr6ug3pkb40"] [ext_resource type="Script" uid="uid://3dphlay25fih" path="res://scripts/player/player.gd" id="1_g2els"] [ext_resource type="Script" uid="uid://dalwlndejfdhm" path="res://scripts/player/crosshair.gd" id="3_dqkch"] [ext_resource type="Script" uid="uid://bjhbdh6xsjgnn" path="res://scripts/player/player_camera.gd" id="3_qhqgy"] [ext_resource type="PackedScene" uid="uid://bc21f85o0ovc1" path="res://models/characters/viewmodels/molikman_hands.glb" id="4_dqkch"] -[ext_resource type="Script" uid="uid://6c14qse4vnra" path="res://scripts/player/player_raycast.gd" id="4_fjrip"] [ext_resource type="Script" uid="uid://bmecgup3kcua7" path="res://scripts/weapon_system/weapon_system.gd" id="4_qlg0r"] [ext_resource type="Script" uid="uid://dd5mp72dq43v6" path="res://scripts/multiplayer/own_visibility_toggle.gd" id="4_smehm"] [ext_resource type="Script" uid="uid://5gwpjiswnegn" path="res://scripts/player/collision_team_updater.gd" id="7_a8ls1"] [ext_resource type="Script" uid="uid://7gmgcaxfh8sb" path="res://scripts/debug/property_shower.gd" id="7_oprun"] [ext_resource type="Script" uid="uid://3777rkbebgjm" path="res://scripts/state_machine/machine.gd" id="8_f1ej7"] +[ext_resource type="Script" uid="uid://bl8gfrrc512q2" path="res://scripts/player/dead_player_spectator.gd" id="8_rwwcc"] [ext_resource type="PackedScene" uid="uid://c2r8dbudbs7l3" path="res://models/characters/worldmodels/molikman_ingame.glb" id="8_smehm"] [ext_resource type="Script" uid="uid://bv8sgx78s8hwn" path="res://scripts/player/states/crouching.gd" id="9_oprun"] [ext_resource type="Script" uid="uid://dmy6ahci16los" path="res://scripts/debug/inventory_preview.gd" id="9_ownlk"] @@ -18,8 +18,12 @@ [ext_resource type="Script" uid="uid://cwasvwhm5yg0o" path="res://scripts/player/states/walk.gd" id="11_qfm1y"] [ext_resource type="Script" uid="uid://cq4i0afwesdm3" path="res://scripts/player/states/falling.gd" id="12_fulsm"] [ext_resource type="Script" uid="uid://gan0amqbhi4i" path="res://scripts/gui/hud/player_ammo_display.gd" id="12_iortg"] +[ext_resource type="Script" uid="uid://bala54fa32e35" path="res://scripts/gui/hud/player_round_display.gd" id="13_x73hv"] +[ext_resource type="Script" uid="uid://bos7nftlx8tv3" path="res://scripts/gui/hud/player_round_time.gd" id="13_xar7t"] [ext_resource type="Script" uid="uid://xsgfbuyje35p" path="res://scripts/player/player_pickup.gd" id="17_fjvrb"] [ext_resource type="Script" uid="uid://doevvmbvhlig8" path="res://scripts/weapon_system/starting_weapon_spawner.gd" id="17_ownlk"] +[ext_resource type="Script" uid="uid://bs4y647h5rdfr" path="res://scripts/player/player_movement.gd" id="19_70eug"] +[ext_resource type="Script" uid="uid://tb140f8fweug" path="res://scripts/player/states/death.gd" id="19_rwwcc"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_u8vuu"] resource_local_to_scene = true @@ -97,6 +101,30 @@ tracks/3/keys = { "update": 0, "values": [Vector3(0, 1.1793717, 0)] } +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("molikman_ingame:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("CollisionShape3D:disabled") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} [sub_resource type="Animation" id="Animation_oprun"] resource_name = "crouch" @@ -149,10 +177,51 @@ tracks/3/keys = { "values": [Vector3(0, 1.1793717, 0), Vector3(0, 0.6695229, 0)] } +[sub_resource type="Animation" id="Animation_rwwcc"] +resource_name = "die" +length = 0.25 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("molikman_ingame:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.23333333), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(1.5707964, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("molikman_ingame:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.23333333), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1.1793717, 0), Vector3(0, 0.019058675, 1.1753564)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("CollisionShape3D:disabled") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_a8ls1"] _data = { &"RESET": SubResource("Animation_a8ls1"), -&"crouch": SubResource("Animation_oprun") +&"crouch": SubResource("Animation_oprun"), +&"die": SubResource("Animation_rwwcc") } [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3xmak"] @@ -169,7 +238,7 @@ weapon_models = { } [node name="molikman_ingame" parent="." instance=ExtResource("8_smehm")] -transform = Transform3D(0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 1.1793717, 0) +transform = Transform3D(0.75, 0, 0, 0, 0.74999994, 0, 0, 0, 0.74999994, 0, 1.1793717, 0) [node name="VisibleEnabler" type="Node" parent="molikman_ingame"] script = ExtResource("4_smehm") @@ -199,13 +268,9 @@ visible = false [node name="VisibleDisabler" type="Node" parent="Camera3D/molikman_hands"] script = ExtResource("4_smehm") -[node name="RayCast3D" type="RayCast3D" parent="Camera3D"] -target_position = Vector3(0, 0, -1000) -script = ExtResource("4_fjrip") - -[node name="TeamUpdater" type="Node" parent="Camera3D/RayCast3D" node_paths=PackedStringArray("player")] -script = ExtResource("7_a8ls1") -player = NodePath("../../..") +[node name="DeadSpectator" type="Camera3D" parent="Camera3D"] +fov = 90.0 +script = ExtResource("8_rwwcc") [node name="StandArea" type="Area3D" parent="."] collision_layer = 0 @@ -293,6 +358,29 @@ grow_vertical = 0 label_settings = SubResource("LabelSettings_x73hv") script = ExtResource("12_iortg") +[node name="RoundData" type="HBoxContainer" parent="HUD"] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -20.0 +offset_right = 20.0 +offset_bottom = 40.0 +grow_horizontal = 2 + +[node name="RoundDisplayOur" type="Label" parent="HUD/RoundData"] +layout_mode = 2 +script = ExtResource("13_x73hv") +our_side = true + +[node name="RoundTime" type="Label" parent="HUD/RoundData"] +layout_mode = 2 +script = ExtResource("13_xar7t") + +[node name="RoundDisplayTheir" type="Label" parent="HUD/RoundData"] +layout_mode = 2 +script = ExtResource("13_x73hv") + [node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] replication_config = SubResource("SceneReplicationConfig_qhqgy") @@ -301,39 +389,51 @@ script = ExtResource("8_f1ej7") current_state = NodePath("Stand") metadata/_custom_type_script = "uid://3777rkbebgjm" -[node name="Crouch" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("stand_up_area", "player", "animation_player", "weapon_system")] +[node name="Crouch" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("stand_up_area", "player", "player_movement", "animation_player", "weapon_system")] script = ExtResource("9_oprun") max_speed = 3.0 acceleration = 50.0 deceleration = 50.0 stand_up_area = NodePath("../../StandArea") player = NodePath("../..") +player_movement = NodePath("../../PlayerMovement") animation_player = NodePath("../../AnimationPlayer") weapon_system = NodePath("../../WeaponSystem") -[node name="Stand" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("player", "weapon_system")] +[node name="Stand" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("player", "player_movement", "weapon_system")] script = ExtResource("10_a8ls1") max_speed = 6.0 acceleration = 100.0 deceleration = 50.0 JUMP_VELOCITY = 6.0 player = NodePath("../..") +player_movement = NodePath("../../PlayerMovement") weapon_system = NodePath("../../WeaponSystem") -[node name="Walk" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("player", "weapon_system")] +[node name="Walk" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("player", "player_movement", "weapon_system")] script = ExtResource("11_qfm1y") max_speed = 3.0 acceleration = 50.0 deceleration = 50.0 player = NodePath("../..") +player_movement = NodePath("../../PlayerMovement") weapon_system = NodePath("../../WeaponSystem") -[node name="Fall" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("player", "weapon_system")] +[node name="Fall" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("player", "player_movement", "weapon_system")] script = ExtResource("12_fulsm") player = NodePath("../..") +player_movement = NodePath("../../PlayerMovement") acceleration = 25.0 weapon_system = NodePath("../../WeaponSystem") +[node name="Death" type="Node" parent="BodyStateMachine" node_paths=PackedStringArray("animation_player")] +script = ExtResource("19_rwwcc") +animation_player = NodePath("../../AnimationPlayer") + +[node name="PlayerMovement" type="Node" parent="." node_paths=PackedStringArray("player")] +script = ExtResource("19_70eug") +player = NodePath("..") + [node name="WeaponSystem" type="Node" parent="." node_paths=PackedStringArray("animation_player", "camera", "player")] script = ExtResource("4_qlg0r") animation_player = NodePath("../Camera3D/molikman_hands/AnimationPlayer") @@ -371,8 +471,12 @@ weapon_system = NodePath("../WeaponSystem") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8543701, 0) shape = SubResource("CapsuleShape3D_3xmak") +[connection signal="died" from="." to="molikman_ingame/VisibleEnabler" method="reverse"] +[connection signal="died" from="." to="Camera3D/molikman_hands/VisibleDisabler" method="reverse"] +[connection signal="died" from="." to="WeaponSystem" method="disable"] +[connection signal="died" from="." to="Camera3D/DeadSpectator" method="set_active"] +[connection signal="died" from="." to="BodyStateMachine/Death" method="on_death"] [connection signal="health_changed" from="." to="HUD/Healthbar" method="on_hp_changed"] -[connection signal="spawned" from="." to="Camera3D/RayCast3D/TeamUpdater" method="on_spawned"] [connection signal="spawned" from="." to="TeamUpdater" method="on_spawned"] [connection signal="ammo_updated" from="WeaponSystem" to="HUD/AmmoDisplay" method="on_ammo_updated"] diff --git a/scenes/weapons/active_bomb.tscn b/scenes/weapons/active_bomb.tscn index 0ee1b9a..d77a6bc 100644 --- a/scenes/weapons/active_bomb.tscn +++ b/scenes/weapons/active_bomb.tscn @@ -16,8 +16,3 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1307683, 0) [node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] replication_config = SubResource("SceneReplicationConfig_yh58y") - -[node name="Timer" type="Timer" parent="."] -wait_time = 5.0 -one_shot = true -autostart = true diff --git a/scripts/gui/hud/player_round_display.gd b/scripts/gui/hud/player_round_display.gd new file mode 100644 index 0000000..7c076da --- /dev/null +++ b/scripts/gui/hud/player_round_display.gd @@ -0,0 +1,18 @@ +extends Label + +@export var our_side: bool + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + if our_side: + match Lobby.get_team(): + Session.TEAMS.DEFENCE: + text = str(Session.defender_score) + Session.TEAMS.ATTACK, Session.TEAMS.SPECTATE, Session.TEAMS.UNASSIGNED: + text = str(Session.attacker_score) + else: + match Lobby.get_team(): + Session.TEAMS.DEFENCE: + text = str(Session.attacker_score) + Session.TEAMS.ATTACK, Session.TEAMS.SPECTATE, Session.TEAMS.UNASSIGNED: + text = str(Session.defender_score) diff --git a/scripts/gui/hud/player_round_display.gd.uid b/scripts/gui/hud/player_round_display.gd.uid new file mode 100644 index 0000000..e797b4c --- /dev/null +++ b/scripts/gui/hud/player_round_display.gd.uid @@ -0,0 +1 @@ +uid://bala54fa32e35 diff --git a/scripts/gui/hud/player_round_time.gd b/scripts/gui/hud/player_round_time.gd new file mode 100644 index 0000000..f7faaaa --- /dev/null +++ b/scripts/gui/hud/player_round_time.gd @@ -0,0 +1,8 @@ +extends Label + +func _process(_delta: float) -> void: + var seconds_u = int(round(Session.reference_round_time)) + var seconds = seconds_u % 60 + @warning_ignore("integer_division") + var minutes = seconds_u / 60 + text = str(minutes)+":"+str(seconds).pad_zeros(2) diff --git a/scripts/gui/hud/player_round_time.gd.uid b/scripts/gui/hud/player_round_time.gd.uid new file mode 100644 index 0000000..f2a3e78 --- /dev/null +++ b/scripts/gui/hud/player_round_time.gd.uid @@ -0,0 +1 @@ +uid://bos7nftlx8tv3 diff --git a/scripts/item_spawner.gd b/scripts/item_spawner.gd index 9822f71..93468c1 100644 --- a/scripts/item_spawner.gd +++ b/scripts/item_spawner.gd @@ -3,11 +3,11 @@ extends Node3D @export var item: PackedScene func _ready() -> void: - deferred_spawn.call_deferred() + if multiplayer.is_server(): + Session.round_started.connect(spawn) -func deferred_spawn(): +func spawn(): if multiplayer.is_server(): var node = item.instantiate() add_sibling(node,true) node.global_position = global_position - queue_free() diff --git a/scripts/multiplayer/lobby.gd b/scripts/multiplayer/lobby.gd index 5b926e6..da93c49 100644 --- a/scripts/multiplayer/lobby.gd +++ b/scripts/multiplayer/lobby.gd @@ -9,10 +9,15 @@ signal lobby_joined signal lobby_closed signal update_teams_state +var in_lobby: bool = false + var attack_team: Array[int] = [] var defence_team: Array[int] = [] var specators_team: Array[int] = [] +var win_score = 13 +var half_rounds = 12 + func _ready() -> void: multiplayer.peer_disconnected.connect(player_left) multiplayer.server_disconnected.connect(server_disconnected) @@ -36,6 +41,7 @@ func host() -> void: multiplayer.multiplayer_peer = peer lobby_created.emit() specators_team.append(multiplayer.get_unique_id()) + in_lobby = true func join(ip: String) -> Error: var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() @@ -44,6 +50,7 @@ func join(ip: String) -> Error: return res multiplayer.multiplayer_peer = peer lobby_joined.emit() + in_lobby = true return Error.OK func leave() -> void: @@ -52,6 +59,7 @@ func leave() -> void: defence_team.clear() specators_team.clear() lobby_closed.emit() + in_lobby = false func add_and_sync_peer(id: int) -> void: if multiplayer.is_server() == false: @@ -100,3 +108,16 @@ func team_switch_notification(id: int, team: int) -> void: @rpc("authority","call_local","reliable") func start_game() -> void: get_tree().change_scene_to_file("res://levels/prototype_scene.tscn") + if multiplayer.is_server(): + await get_tree().scene_changed + Session.start_session() + +func get_team() -> Session.TEAMS: + var id = multiplayer.get_unique_id() + if attack_team.has(id): + return Session.TEAMS.ATTACK + if defence_team.has(id): + return Session.TEAMS.DEFENCE + if specators_team.has(id): + return Session.TEAMS.SPECTATE + return Session.TEAMS.UNASSIGNED diff --git a/scripts/multiplayer/own_visibility_toggle.gd b/scripts/multiplayer/own_visibility_toggle.gd index e721e0a..b2c51dd 100644 --- a/scripts/multiplayer/own_visibility_toggle.gd +++ b/scripts/multiplayer/own_visibility_toggle.gd @@ -4,3 +4,6 @@ extends Node func _ready() -> void: get_parent().visible = (get_multiplayer_authority() != multiplayer.get_unique_id()) == visible_for_others + +func reverse() -> void: + get_parent().visible = not get_parent().visible diff --git a/scripts/multiplayer/session.gd b/scripts/multiplayer/session.gd index e70a97b..4d776fb 100644 --- a/scripts/multiplayer/session.gd +++ b/scripts/multiplayer/session.gd @@ -6,15 +6,186 @@ enum TEAMS { SPECTATE, UNASSIGNED } + +enum ROUND_STATES { + NOT_SET = 0, + BUY = 1, + ROUND = 2, + AFTER_ROUND = 3, + AFTER_PLANT = 4, + AFTER_SESSION = 5, +} + const ATTACK_LAYER: int = 0b10000 const DEFENCE_LAYER: int = 0b100000 +signal round_started +signal round_state_changed(state: int) + var player_nodes: Dictionary[int,Player] = {} +var object_containers: Array[ObjectContainer] var dynamic_objects_spawner: MultiplayerSpawner var plants: Array[PlantSite] var plant_deadzones: Dictionary[StringName, Area3D] +var current_round: int = 0 +var attacker_score: int = 0 +var defender_score: int = 0 +var attackers_alive: int = 0 +var defenders_alive: int = 0 + +var bomb_timer: Timer +var round_timer: Timer +var buy_timer: Timer + +var round_state: ROUND_STATES +var session_started: bool = false + +var reference_round_time: float + +func _ready() -> void: + if multiplayer.is_server() == false: + return + + bomb_timer = Timer.new() + bomb_timer.wait_time = 45.0 + bomb_timer.one_shot = true + bomb_timer.timeout.connect(end_round.bind(TEAMS.ATTACK)) + + round_timer = Timer.new() + round_timer.wait_time = 150 + round_timer.one_shot = true + round_timer.timeout.connect(end_round.bind(TEAMS.DEFENCE)) + + buy_timer = Timer.new() + buy_timer.wait_time = 15 + buy_timer.one_shot = true + buy_timer.timeout.connect(begin_main_stage) + + add_child(bomb_timer) + add_child(round_timer) + add_child(buy_timer) + +func _process(_delta: float) -> void: + if multiplayer.is_server() == false or not session_started: + return + match round_state: + ROUND_STATES.BUY: + reference_round_time = buy_timer.time_left + ROUND_STATES.ROUND: + reference_round_time = round_timer.time_left + ROUND_STATES.AFTER_PLANT: + reference_round_time = bomb_timer.time_left + _: + reference_round_time = 0 + update_clock.rpc(reference_round_time) + +@rpc("authority","call_remote","unreliable") +func update_clock(time: float): + reference_round_time = time + +@rpc("any_peer","call_remote","reliable") +func start_session() -> void: + if not is_server_request(): + return + if multiplayer.is_server(): + start_session.rpc() + + current_round = 0 + attacker_score = 0 + defender_score = 0 + session_started = true + + start_round() + +@rpc("any_peer","call_remote","reliable") +func end_session() -> void: + if not is_server_request(): + return + if multiplayer.is_server(): + end_session.rpc() + + bomb_timer.stop() + round_timer.stop() + buy_timer.stop() + object_containers.clear() + + session_started = false + +@rpc("any_peer","call_remote","reliable") +func start_round() -> void: + if not is_server_request(): + return + if multiplayer.is_server(): + buy_timer.start() + start_round.rpc() + for container in object_containers: + container.despawn() + attackers_alive = 0 + defenders_alive = 0 + + current_round += 1 + + round_started.emit.call_deferred() + round_state = ROUND_STATES.BUY + round_state_changed.emit.call_deferred(round_state) + +@rpc("any_peer","call_remote","reliable") +func end_round(win_team: int) -> void: + if not is_server_request(): + return + if multiplayer.is_server(): + get_tree().create_timer(5).timeout.connect(start_round) + end_round.rpc(win_team) + + if win_team == TEAMS.DEFENCE: + defender_score += 1 + elif win_team == TEAMS.ATTACK: + attacker_score += 1 + + round_state = ROUND_STATES.AFTER_ROUND + round_state_changed.emit(round_state) + +@rpc("any_peer","call_remote","reliable") +func begin_main_stage() -> void: + if not is_server_request(): + return + if multiplayer.is_server(): + round_timer.start() + begin_main_stage.rpc() + + round_state = ROUND_STATES.ROUND + round_state_changed.emit(round_state) + +@rpc("any_peer","call_remote","reliable") +func begin_bomb_stage() -> void: + if not is_server_request(): + return + if multiplayer.is_server(): + bomb_timer.start() + round_timer.stop() + begin_bomb_stage.rpc() + + round_state = ROUND_STATES.AFTER_PLANT + round_state_changed.emit(round_state) + +@rpc("any_peer","call_local","reliable") +func add_dead(team: int): + if multiplayer.is_server() == false: + return + if team == TEAMS.ATTACK: + attackers_alive -= 1 + if attackers_alive == 0 and round_state != ROUND_STATES.AFTER_ROUND: + end_round(TEAMS.DEFENCE) + if team == TEAMS.DEFENCE: + defenders_alive -= 1 + if defenders_alive == 0 and round_state != ROUND_STATES.AFTER_ROUND: + end_round(TEAMS.ATTACK) + +func is_server_request() -> bool: + return multiplayer.is_server() or multiplayer.get_remote_sender_id() == 1 + ## Spawns dynamic object at game scene [br] ## Dictionary keys: [br] ## (Required) scene - path/uuid to scene [br] diff --git a/scripts/multiplayer/team_spawner.gd b/scripts/multiplayer/team_spawner.gd index 2aaf6d1..e38e87a 100644 --- a/scripts/multiplayer/team_spawner.gd +++ b/scripts/multiplayer/team_spawner.gd @@ -7,6 +7,14 @@ func _ready() -> void: if not multiplayer.is_server(): queue_free() return + Session.round_started.connect(spawn) + +func _exit_tree() -> void: + if not multiplayer.is_server(): + return + Session.round_started.disconnect(spawn) + +func spawn(): match team: Session.TEAMS.ATTACK: for attacker in Lobby.attack_team: @@ -23,6 +31,10 @@ func spawn_player(id: int) -> void: var inst: Player = player.instantiate() Session.player_nodes[id] = inst inst.name = str(id) + if team == Session.TEAMS.DEFENCE: + Session.defenders_alive += 1 + elif team == Session.TEAMS.ATTACK: + Session.attackers_alive += 1 deferred_setup.bind(inst,team).call_deferred() @@ -34,7 +46,7 @@ func spawn_spectator(id: int) -> void: deferred_setup.bind(inst,Session.TEAMS.SPECTATE).call_deferred() func deferred_setup(what: Node3D, new_team: Session.TEAMS): - get_parent().add_child(what) + get_parent().add_child(what,true) var distance = randf_range(0,spawn_radius) var angle = randf_range(0,TAU) var new_position = global_position + Vector3.RIGHT.rotated(Vector3.UP,angle) * distance diff --git a/scripts/object_container.gd b/scripts/object_container.gd new file mode 100644 index 0000000..66f18ee --- /dev/null +++ b/scripts/object_container.gd @@ -0,0 +1,16 @@ +extends Node + +class_name ObjectContainer + +@export var exlusion_list: Array[Node] + +func _ready() -> void: + if not multiplayer.is_server(): return + Session.object_containers.append(self) + +func despawn(): + if not multiplayer.is_server(): return + for child in get_children(): + if exlusion_list.has(child): + continue + child.queue_free() diff --git a/scripts/object_container.gd.uid b/scripts/object_container.gd.uid new file mode 100644 index 0000000..4da5b07 --- /dev/null +++ b/scripts/object_container.gd.uid @@ -0,0 +1 @@ +uid://3i00rp8urth7 diff --git a/scripts/player/dead_player_spectator.gd b/scripts/player/dead_player_spectator.gd new file mode 100644 index 0000000..eee9dea --- /dev/null +++ b/scripts/player/dead_player_spectator.gd @@ -0,0 +1,36 @@ +extends Camera3D + +@export var SENSITIVITY = 0.02 +@export var SPEED = 10.0 + +var active: bool + +func _ready() -> void: + if not is_multiplayer_authority(): + return + +func set_active() -> void: + if not is_multiplayer_authority(): + return + active = true + current = true + +func _process(delta: float) -> void: + if active == false or not is_multiplayer_authority(): + return + var xz_plane = Input.get_vector("plr_strafe_l","plr_strafe_r","plr_forward","plr_back") + var y = Input.get_axis("spc_down","spc_up") + + var direction = Vector3(xz_plane.x,y,xz_plane.y) + global_position += global_basis * direction * SPEED * delta + +func rotate_camera(x,y) -> void: + rotate_y(x) + rotation.x = clamp(rotation.x + y,-PI/2,PI/2) + orthonormalize() + +func _input(event: InputEvent) -> void: + if active == false or not is_multiplayer_authority(): + return + if event is InputEventMouseMotion: + rotate_camera(-event.relative.x * SENSITIVITY,-event.relative.y * SENSITIVITY) diff --git a/scripts/player/dead_player_spectator.gd.uid b/scripts/player/dead_player_spectator.gd.uid new file mode 100644 index 0000000..bbe18e2 --- /dev/null +++ b/scripts/player/dead_player_spectator.gd.uid @@ -0,0 +1 @@ +uid://bl8gfrrc512q2 diff --git a/scripts/player/player.gd b/scripts/player/player.gd index 28ec14c..109162b 100644 --- a/scripts/player/player.gd +++ b/scripts/player/player.gd @@ -7,6 +7,7 @@ class_name Player signal spawned signal health_changed(to: int) +signal died const MAX_HP = 100 @@ -23,8 +24,6 @@ const MAX_HP = 100 get: return hp -var TEMP_start_pos - func _enter_tree() -> void: set_multiplayer_authority(str(name).to_int()) @@ -37,9 +36,8 @@ func _physics_process(_delta: float) -> void: func die() -> void: if (not is_multiplayer_authority()): return - - global_position = TEMP_start_pos - hp = MAX_HP + Session.add_dead.rpc(team) + died.emit() @rpc("any_peer","call_local","reliable") func kill_request() -> void: @@ -51,7 +49,6 @@ func kill_request() -> void: @rpc("any_peer","call_local","reliable") func set_after_spawn(start_position: Vector3,new_team: int): global_position = start_position - TEMP_start_pos = global_position team = new_team as Session.TEAMS spawned.emit() diff --git a/scripts/player/player_camera.gd b/scripts/player/player_camera.gd index 0544fbd..3d4d1e8 100644 --- a/scripts/player/player_camera.gd +++ b/scripts/player/player_camera.gd @@ -8,6 +8,7 @@ class_name PlayerCamera var vertical_compensation : float var compensation_tween: Tween var compensate: bool = false +var disable: bool = false var compensation_speed: float @export var compensation_time: float = 1.0 @export var compensation_delay: float = 0.5 @@ -20,6 +21,7 @@ func _ready() -> void: current = true func _process(delta: float) -> void: + if disable: return if compensate: if abs(vertical_compensation) <= 0.001: vertical_compensation = 0 @@ -28,7 +30,7 @@ func _process(delta: float) -> void: rotate_camera(0,compensation_speed * delta) func _input(event: InputEvent) -> void: - if not is_multiplayer_authority(): + if not is_multiplayer_authority() or disable: return if event is InputEventMouseMotion: rotate_camera(-event.relative.x * SENSITIVITY,-event.relative.y * SENSITIVITY) diff --git a/scripts/player/player_movement.gd b/scripts/player/player_movement.gd new file mode 100644 index 0000000..7183722 --- /dev/null +++ b/scripts/player/player_movement.gd @@ -0,0 +1,21 @@ +extends Node + +class_name PlayerMovement + +@export var player: Player + +func process_movement(max_speed: float,acceleration: float,deceleration: float,delta: float) -> void: + if is_multiplayer_authority() == false: + return + if Session.round_state == Session.ROUND_STATES.BUY: + player.velocity.x = 0 + player.velocity.z = 0 + return + var input_dir := Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward") + var direction := (player.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() + if direction: + player.velocity.x = clamp(player.velocity.x + direction.x * acceleration * delta,-max_speed*abs(direction.x),max_speed*abs(direction.x)) + player.velocity.z = clamp(player.velocity.z + direction.z * acceleration * delta,-max_speed*abs(direction.z),max_speed*abs(direction.z)) + else: + player.velocity.x = move_toward(player.velocity.x, 0, deceleration*delta) + player.velocity.z = move_toward(player.velocity.z, 0, deceleration*delta) diff --git a/scripts/player/player_movement.gd.uid b/scripts/player/player_movement.gd.uid new file mode 100644 index 0000000..1a05ad8 --- /dev/null +++ b/scripts/player/player_movement.gd.uid @@ -0,0 +1 @@ +uid://bs4y647h5rdfr diff --git a/scripts/player/spectator.gd b/scripts/player/spectator.gd index 59d14c1..8ec85b3 100644 --- a/scripts/player/spectator.gd +++ b/scripts/player/spectator.gd @@ -14,6 +14,8 @@ func _ready() -> void: current = true func _process(delta: float) -> void: + if not is_multiplayer_authority(): + return var xz_plane = Input.get_vector("plr_strafe_l","plr_strafe_r","plr_forward","plr_back") var y = Input.get_axis("spc_down","spc_up") @@ -26,6 +28,8 @@ func rotate_camera(x,y) -> void: orthonormalize() func _input(event: InputEvent) -> void: + if not is_multiplayer_authority(): + return if event is InputEventMouseMotion: rotate_camera(-event.relative.x * SENSITIVITY,-event.relative.y * SENSITIVITY) diff --git a/scripts/player/states/crouching.gd b/scripts/player/states/crouching.gd index 2ff7c33..9bdff3f 100644 --- a/scripts/player/states/crouching.gd +++ b/scripts/player/states/crouching.gd @@ -7,6 +7,7 @@ extends State @export var toggle: bool = false @export var stand_up_area: Area3D @export var player: Player +@export var player_movement: PlayerMovement @export var animation_player: AnimationPlayer @export var crouch_time: float = 0.1 @export var weapon_system: WeaponSystem @@ -28,15 +29,7 @@ func physics_update(delta: float) -> void: transition.emit("Fall") return - var input_dir := Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward") - var direction := (player.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() - var modified_max_speed = max_speed * weapon_system.get_speed_modifier() - if direction: - player.velocity.x = clamp(player.velocity.x + direction.x * acceleration * delta,-modified_max_speed*abs(direction.x),modified_max_speed*abs(direction.x)) - player.velocity.z = clamp(player.velocity.z + direction.z * acceleration * delta,-modified_max_speed*abs(direction.z),modified_max_speed*abs(direction.z)) - else: - player.velocity.x = move_toward(player.velocity.x, 0, deceleration*delta) - player.velocity.z = move_toward(player.velocity.z, 0, deceleration*delta) + player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta) func state_input(event: InputEvent) -> void: if (toggle == true and event.is_action_pressed("plr_crouch")) or (toggle == false and event.is_action_released("plr_crouch")): diff --git a/scripts/player/states/death.gd b/scripts/player/states/death.gd new file mode 100644 index 0000000..68a4a57 --- /dev/null +++ b/scripts/player/states/death.gd @@ -0,0 +1,12 @@ +extends State + +@export var animation_player: AnimationPlayer + +func on_death() -> void: + transition.emit("Death") + +func enter() -> void: + animation_player.play("die") + +func exit() -> void: + pass diff --git a/scripts/player/states/death.gd.uid b/scripts/player/states/death.gd.uid new file mode 100644 index 0000000..8670416 --- /dev/null +++ b/scripts/player/states/death.gd.uid @@ -0,0 +1 @@ +uid://tb140f8fweug diff --git a/scripts/player/states/falling.gd b/scripts/player/states/falling.gd index 16fefd0..209cfbe 100644 --- a/scripts/player/states/falling.gd +++ b/scripts/player/states/falling.gd @@ -1,6 +1,7 @@ extends State @export var player: Player +@export var player_movement: PlayerMovement @export var max_speed: float = 5.0 @export var acceleration: float @export var weapon_system: WeaponSystem @@ -20,11 +21,4 @@ func physics_update(delta: float) -> void: player.velocity += player.get_gravity() * delta - var input_dir := Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward") - var direction := (player.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() - var modified_max_speed = max_speed * weapon_system.get_speed_modifier() - if direction: - if abs(player.velocity.x + direction.x * acceleration * delta) < abs(modified_max_speed * direction.x): - player.velocity.x += direction.x * acceleration * delta - if abs(player.velocity.z + direction.z * acceleration * delta) < abs(modified_max_speed * direction.z): - player.velocity.z += direction.z * acceleration * delta + player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,0,delta) diff --git a/scripts/player/states/standing.gd b/scripts/player/states/standing.gd index 7190923..6d95cfa 100644 --- a/scripts/player/states/standing.gd +++ b/scripts/player/states/standing.gd @@ -5,6 +5,7 @@ extends State @export var deceleration: float = 200.0 @export var JUMP_VELOCITY: float = 4.5 @export var player: Player +@export var player_movement: PlayerMovement @export var weapon_system: WeaponSystem func enter() -> void: @@ -17,7 +18,7 @@ func physics_update(delta: float) -> void: if not is_multiplayer_authority(): return if Input.is_action_just_pressed("plr_jump") and player.is_on_floor(): - player.velocity.y = JUMP_VELOCITY + player.velocity.y = JUMP_VELOCITY * sign(weapon_system.get_speed_modifier()) transition.emit("Fall") return @@ -25,15 +26,7 @@ func physics_update(delta: float) -> void: transition.emit("Fall") return - var input_dir := Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward") - var direction := (player.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() - var modified_max_speed = max_speed * weapon_system.get_speed_modifier() - if direction: - player.velocity.x = clamp(player.velocity.x + direction.x * acceleration * delta,-modified_max_speed*abs(direction.x),modified_max_speed*abs(direction.x)) - player.velocity.z = clamp(player.velocity.z + direction.z * acceleration * delta,-modified_max_speed*abs(direction.z),modified_max_speed*abs(direction.z)) - else: - player.velocity.x = move_toward(player.velocity.x, 0, deceleration*delta) - player.velocity.z = move_toward(player.velocity.z, 0, deceleration*delta) + player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta) func state_input(event: InputEvent) -> void: if event.is_action_pressed("plr_crouch"): diff --git a/scripts/player/states/walk.gd b/scripts/player/states/walk.gd index 9dc8f5b..579e7d1 100644 --- a/scripts/player/states/walk.gd +++ b/scripts/player/states/walk.gd @@ -5,6 +5,7 @@ extends State @export var deceleration: float = 100.0 @export var JUMP_VELOCITY: float = 4.5 @export var player: Player +@export var player_movement: PlayerMovement @export var weapon_system: WeaponSystem func enter() -> void: @@ -25,15 +26,7 @@ func physics_update(delta: float) -> void: transition.emit("Fall") return - var input_dir := Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward") - var direction := (player.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() - var modified_max_speed = max_speed * weapon_system.get_speed_modifier() - if direction: - player.velocity.x = clamp(player.velocity.x + direction.x * acceleration * delta,-modified_max_speed*abs(direction.x),modified_max_speed*abs(direction.x)) - player.velocity.z = clamp(player.velocity.z + direction.z * acceleration * delta,-modified_max_speed*abs(direction.z),modified_max_speed*abs(direction.z)) - else: - player.velocity.x = move_toward(player.velocity.x, 0, deceleration*delta) - player.velocity.z = move_toward(player.velocity.z, 0, deceleration*delta) + player_movement.process_movement(max_speed * weapon_system.get_speed_modifier(),acceleration,deceleration,delta) func state_input(event: InputEvent) -> void: if event.is_action_released("plr_walk"): diff --git a/scripts/weapon_system/bomb/active_bomb.gd b/scripts/weapon_system/bomb/active_bomb.gd index 12b8d7e..d926420 100644 --- a/scripts/weapon_system/bomb/active_bomb.gd +++ b/scripts/weapon_system/bomb/active_bomb.gd @@ -4,7 +4,8 @@ var plant: StringName func _ready() -> void: if multiplayer.is_server(): - $Timer.timeout.connect(on_timeout) + Session.bomb_timer.timeout.connect(on_timeout) + Session.begin_bomb_stage() func on_timeout(): if multiplayer.is_server() == false: diff --git a/scripts/weapon_system/bomb/bomb_main_state.gd b/scripts/weapon_system/bomb/bomb_main_state.gd index 5aac64e..2ab006c 100644 --- a/scripts/weapon_system/bomb/bomb_main_state.gd +++ b/scripts/weapon_system/bomb/bomb_main_state.gd @@ -12,6 +12,8 @@ func exit(): machine.speed_modifier = 1.0 func on_animation_finished(animation: StringName): + if is_multiplayer_authority() == false: + return if animation == machine.animation_prefix + "plant": Session.spawn({"scene": active_bomb, "position": machine.player_camera.get_parent().global_position,"plant": Session.get_site().name}) @@ -20,5 +22,7 @@ func on_animation_finished(animation: StringName): return_to_previous.emit() func state_input(event: InputEvent) -> void: + if is_multiplayer_authority() == false: + return if event.is_action_released("plr_bomb"): transition.emit("Idle") diff --git a/scripts/weapon_system/weapon_system.gd b/scripts/weapon_system/weapon_system.gd index ba8774f..e17819f 100644 --- a/scripts/weapon_system/weapon_system.gd +++ b/scripts/weapon_system/weapon_system.gd @@ -8,6 +8,7 @@ class_name WeaponSystem var current_state: WeaponSubStateMachine var last_slot: StringName +var disabled: bool var slots: Dictionary[StringName,WeaponSubStateMachine] = { "primary": null, @@ -151,18 +152,21 @@ func check_for_empty() -> void: func on_ammo_updated() -> void: ammo_updated.emit(current_state.ammo,current_state.remaining_ammo) +func disable() -> void: + disabled = true + func _process(delta: float) -> void: - if current_state == null: + if current_state == null or disabled: return current_state.update(delta) func _physics_process(delta: float) -> void: - if current_state == null: + if current_state == null or disabled: return current_state.physics_update(delta) func _input(event: InputEvent) -> void: - if is_multiplayer_authority() == false: return + if is_multiplayer_authority() == false or disabled or Session.round_state == Session.ROUND_STATES.BUY: return if current_state != null: current_state.state_input(event) diff --git a/textures/prototype_256x256.svg b/textures/prototype_256x256.svg index 0e08cf3..16c9da8 100644 --- a/textures/prototype_256x256.svg +++ b/textures/prototype_256x256.svg @@ -9,6 +9,9 @@ id="svg1" inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)" sodipodi:docname="prototype_256x256.svg" + inkscape:export-filename="prototype_yellow_256x256.png" + inkscape:export-xdpi="96.000008" + inkscape:export-ydpi="96.000008" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" @@ -25,14 +28,14 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="2" - inkscape:cx="185.25" - inkscape:cy="135.25" + inkscape:cx="67.75" + inkscape:cy="128.75" inkscape:window-width="1890" inkscape:window-height="1012" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:current-layer="g19"> + inkscape:current-layer="layer1">