Compare commits

...

5 Commits

Author SHA1 Message Date
1393338839 Add buffs to replay data as well 2026-07-29 22:36:41 +03:00
e763db9108 Add buffs at player spawn 2026-07-29 22:36:41 +03:00
a71bc513ac Make spawn protection work 2026-07-29 22:36:41 +03:00
6a2d8564d5 Add buffs, add spawnprotection buff effect 2026-07-29 22:36:41 +03:00
bfddd3129f Add shield effects 2026-07-29 22:36:41 +03:00
14 changed files with 456 additions and 24 deletions

View File

@ -2,15 +2,23 @@
[ext_resource type="PackedScene" uid="uid://bod6b3befmyt5" path="res://scenes/player/soldier_m.tscn" id="1_jd651"]
[ext_resource type="PackedScene" uid="uid://cl66unms2gim0" path="res://scenes/player/effects.tscn" id="2_ywmwa"]
[ext_resource type="Shader" uid="uid://datt1r440base" path="res://shaders/vignette.tres" id="3_7awel"]
[ext_resource type="PackedScene" uid="uid://c1gs6cqek1qlq" path="res://scenes/ui/hud.tscn" id="5_cv68x"]
[ext_resource type="Texture2D" uid="uid://bdfqu6p74pfwe" path="res://raw_assets/crosshair/Crosshair 1.png" id="6_7awel"]
[ext_resource type="AudioStream" uid="uid://bfg31e3s4jv8c" path="res://raw_assets/sfx/Hit.mp3" id="7_dguuj"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "effects", "dead_cam_target", "respawn_label", "camera_origin", "weapon_node", "hud", "hit_sound")]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_dguuj"]
shader = ExtResource("3_7awel")
shader_parameter/Color = Color(1, 0, 0, 1)
shader_parameter/RimDistance = 0.7
shader_parameter/FloatParameter = 3.0
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "vignette", "soldier_mesh", "collider", "effects", "dead_cam_target", "respawn_label", "camera_origin", "weapon_node", "hud", "hit_sound")]
look_sensitivity = 1.5
camera = NodePath("camera_3d")
vignette = NodePath("vignette")
move_speed = 7.0
soldier_mesh = NodePath("soldier_m")
collider = NodePath("collision_shape_3d2")
@ -49,6 +57,14 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.16157162, 1.4223524, 0)
[node name="dead_camera_target" type="Node3D" parent="." unique_id=559969559]
transform = Transform3D(1, 0, 0, 0, 0.9069022, 0.4213412, 0, -0.4213412, 0.9069022, 0, 2.3258846, 1.5254744)
[node name="vignette" type="ColorRect" parent="." unique_id=1797767615]
material = SubResource("ShaderMaterial_dguuj")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="crosshair" type="TextureRect" parent="." unique_id=1329977849]
modulate = Color(1, 1, 1, 0.5058824)
anchors_preset = 8

View File

@ -5,8 +5,9 @@
[ext_resource type="PackedScene" uid="uid://ci8r4lgijtalh" path="res://scenes/player/ball_weapon.tscn" id="2_jbny0"]
[ext_resource type="PackedScene" uid="uid://deyfeiqyi0wmj" path="res://scenes/player/shotgun.tscn" id="2_kknoo"]
[ext_resource type="Texture2D" uid="uid://cbvxh8xp8ilac" path="res://assets/Soldier.png" id="5_hjbn3"]
[ext_resource type="Shader" uid="uid://canvckfs02odw" path="res://shaders/bubble_shader.tres" id="6_3lfhi"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3lfhi"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_hjbn3"]
resource_local_to_scene = true
albedo_texture = ExtResource("5_hjbn3")
texture_filter = 0
@ -51,7 +52,17 @@ nodes/Movement/node = SubResource("AnimationNodeBlendSpace2D_tt88r")
nodes/Movement/position = Vector2(350, 90)
node_connections = [&"output", 0, &"Movement"]
[node name="soldier_m" type="SoldierMesh" unique_id=281995630 node_paths=PackedStringArray("hand_attachment", "animation_tree", "skeleton", "mesh", "look_at", "hand_remover")]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_tt88r"]
render_priority = 0
shader = ExtResource("6_3lfhi")
shader_parameter/BubbleColor = Color(1, 1, 1, 1)
[sub_resource type="CapsuleMesh" id="CapsuleMesh_1cgct"]
material = SubResource("ShaderMaterial_tt88r")
radius = 1.3764648
height = 4.480774
[node name="soldier_m" type="SoldierMesh" unique_id=281995630 node_paths=PackedStringArray("hand_attachment", "animation_tree", "skeleton", "mesh", "look_at", "hand_remover", "bubble")]
hand_attachment = NodePath("bone_attachment_3d/hand")
animation_tree = NodePath("animation_tree")
skeleton = NodePath("SoldierM/Soldier/Skeleton3D")
@ -61,16 +72,17 @@ shotgun = ExtResource("2_kknoo")
ball = ExtResource("2_jbny0")
look_at = NodePath("look_at_root")
hand_remover = NodePath("SoldierM/Soldier/Skeleton3D/player_hand_remover")
bubble = NodePath("bubble")
[node name="SoldierM" parent="." unique_id=1868587353 instance=ExtResource("1_sxefq")]
[node name="Skeleton3D" parent="SoldierM/Soldier" parent_id_path=PackedInt32Array(1868587353, 1101404322) index="0" unique_id=1074852808]
bones/0/position = Vector3(0, 0, 0.00071418716)
bones/1/position = Vector3(0, 0, -0.007)
bones/1/rotation = Quaternion(0.707061, 0, 0, 0.70715255)
bones/1/rotation = Quaternion(0.6949507, 0, 0, 0.71905756)
bones/1/scale = Vector3(1, 1, 1)
bones/2/position = Vector3(0.002, 3.469447e-18, -1.4901118e-10)
bones/2/rotation = Quaternion(0.9515771, 2.0946482e-08, 2.3652152e-08, -0.30741027)
bones/2/rotation = Quaternion(0.9462384, 2.1343759e-08, 2.3294275e-08, -0.32347023)
bones/2/scale = Vector3(1, 1, 1)
bones/3/position = Vector3(0, 0.0069999984, 5.169879e-25)
bones/3/scale = Vector3(1, 0.99999994, 1)
@ -78,7 +90,7 @@ bones/4/position = Vector3(-2.39752e-11, 0.010049875, -1.4156722e-10)
bones/4/rotation = Quaternion(0.73982674, -2.6881349e-08, 7.0005948e-09, 0.67279744)
bones/4/scale = Vector3(1, 0.99999994, 0.99999994)
bones/6/position = Vector3(-0.002, 3.469447e-18, -1.4901205e-10)
bones/6/rotation = Quaternion(0.99906224, 1.784155e-08, 1.8973411e-08, 0.043298792)
bones/6/rotation = Quaternion(0.99965084, 1.8159357e-08, 1.8669468e-08, 0.026424171)
bones/6/scale = Vector3(1, 1, 1)
bones/7/position = Vector3(0, 0.0069999984, -5.169879e-25)
bones/7/rotation = Quaternion(-0.21973656, 4.264305e-08, 9.604991e-09, 0.9755593)
@ -87,33 +99,33 @@ bones/8/position = Vector3(-2.3975525e-11, 0.010049875, -4.6138777e-11)
bones/8/rotation = Quaternion(0.86758894, -7.867721e-09, 3.036851e-08, 0.4972821)
bones/8/scale = Vector3(1, 0.99999994, 0.99999994)
bones/10/position = Vector3(0, 0.009, 0)
bones/10/rotation = Quaternion(-0.17217702, -0.13130672, 0.022171758, 0.9760237)
bones/10/rotation = Quaternion(-0.15553917, -0.13165307, 0.019935569, 0.9788144)
bones/10/scale = Vector3(1, 1, 1)
bones/11/position = Vector3(6.8186457e-17, 0.008, 0.001)
bones/11/rotation = Quaternion(5.6336947e-05, 1.1336415e-07, -1.5418686e-05, 1)
bones/11/rotation = Quaternion(0.054136645, 0.00010869091, -0.014815048, 0.9984237)
bones/11/scale = Vector3(1, 1, 1)
bones/12/position = Vector3(-2.2285185e-16, 0.0035, 0.0015000002)
bones/12/rotation = Quaternion(-0.70710677, 0, 0, 0.70710677)
bones/12/scale = Vector3(1, 1, 1)
bones/14/position = Vector3(0.005, 0.005, -1.7336413e-21)
bones/14/rotation = Quaternion(0.8812731, 0.032443736, 0.4378821, -0.17482696)
bones/14/rotation = Quaternion(0.8939152, 0.033332374, 0.4326297, -0.11241125)
bones/14/scale = Vector3(1, 0.99999994, 1)
bones/15/position = Vector3(-1.3005262e-15, 0.0050000004, -6.938894e-18)
bones/15/rotation = Quaternion(1.0136929e-08, -7.095393e-09, 0.9187736, 0.3947851)
bones/15/rotation = Quaternion(1.0339061e-08, -6.7974764e-09, 0.92987007, 0.36788812)
bones/15/scale = Vector3(1, 1, 1)
bones/16/position = Vector3(7.632945e-11, 0.007071071, 6.938894e-18)
bones/16/rotation = Quaternion(0.029925434, -0.03646163, -0.18585494, 0.98144436)
bones/16/rotation = Quaternion(0.007951379, -0.09016584, -0.1849911, 0.97856295)
bones/16/scale = Vector3(0.99999994, 0.9999999, 1)
bones/18/position = Vector3(-0.005, 0.005, -1.7303326e-21)
bones/18/rotation = Quaternion(0.64453954, 0.21452981, -0.0943058, -0.72777206)
bones/18/rotation = Quaternion(0.6557931, 0.17115685, -0.12843657, -0.7239786)
bones/18/scale = Vector3(1, 0.99999994, 1)
bones/19/position = Vector3(-1.3005262e-15, 0.0050000004, -6.938894e-18)
bones/19/rotation = Quaternion(-1.7099223e-08, -3.7721332e-08, -0.15766992, 0.98749197)
bones/19/rotation = Quaternion(-2.1018757e-08, -3.568606e-08, -0.26192647, 0.9650879)
bones/19/scale = Vector3(1, 1, 1)
bones/20/position = Vector3(-2.2286711e-10, 0.007071072, 0)
bones/20/rotation = Quaternion(-0.14211333, -0.45638156, -0.17767368, 0.8602045)
bones/20/rotation = Quaternion(-0.114065535, -0.47033018, -0.13636212, 0.86439806)
bones/20/scale = Vector3(1, 0.9999999, 1)
bones/22/position = Vector3(0.012581623, -0.0085772155, 0.0021672463)
bones/22/position = Vector3(0.011173905, -0.0085772155, 0.0025524832)
bones/22/rotation = Quaternion(3.090862e-08, 0.70710677, 0.70710677, 3.090862e-08)
bones/22/scale = Vector3(1, 1, 1)
bones/24/position = Vector3(-0.011000002, 0.0050000013, 0.0070000007)
@ -133,7 +145,7 @@ bones/36/position = Vector3(-0.002, -0.00568604, -0.02264523)
bones/36/rotation = Quaternion(0, 0, 0, 1)
[node name="Soldier_Male_Mesh" parent="SoldierM/Soldier/Skeleton3D" index="0" unique_id=1117347105]
surface_material_override/0 = SubResource("StandardMaterial3D_3lfhi")
surface_material_override/0 = SubResource("StandardMaterial3D_hjbn3")
[node name="look_at_modifier_3d" type="LookAtModifier3D" parent="SoldierM/Soldier/Skeleton3D" index="1" unique_id=1054155740]
target_node = NodePath("../../../../look_at_root/look_at")
@ -168,7 +180,7 @@ origin_external_node = NodePath("../../../../look_at_root")
transform = Transform3D(1, -2.2737368e-13, 0, 2.2737368e-13, 1, 0, -1.3552527e-20, 0, 1, 0, 0, 0)
[node name="bone_attachment_3d" type="BoneAttachment3D" parent="." unique_id=1964353847]
transform = Transform3D(-31.442406, 3.474139, -94.86467, -87.30682, 38.17428, 30.335432, 37.26781, 92.36152, -8.969748, -0.47997, 3.3490868, 0.74448436)
transform = Transform3D(-34.789017, 3.8380542, -93.674934, -83.87692, 43.364418, 32.92697, 41.885357, 90.026634, -11.866832, -0.4724244, 3.3871224, 0.74117285)
bone_name = "HAND.R_end"
bone_idx = 17
use_external_skeleton = true
@ -189,4 +201,8 @@ transform = Transform3D(1, 0, 0, 0, 1.0000001, 0, 0, 0, 1.0000001, 0, 3.7622375,
[node name="look_at" type="Node3D" parent="look_at_root" unique_id=1308525699]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.698)
[node name="bubble" type="MeshInstance3D" parent="." unique_id=2033209152]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.0816538, 0)
mesh = SubResource("CapsuleMesh_1cgct")
[editable path="SoldierM"]

View File

@ -0,0 +1,62 @@
[gd_resource type="VisualShader" format=3 uid="uid://canvckfs02odw"]
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_m0u34"]
default_input_values = [0, 0.0, 1, 0.5]
operator = 2
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_aiwsy"]
operator = 2
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_7h3f8"]
default_input_values = [0, 0.0, 1, 0.5]
[sub_resource type="VisualShaderNodeFresnel" id="VisualShaderNodeFresnel_m0u34"]
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_rsany"]
operator = 2
[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_aiwsy"]
parameter_name = "BubbleColor"
default_value_enabled = true
[sub_resource type="VisualShaderNodeVectorDecompose" id="VisualShaderNodeVectorDecompose_m0u34"]
default_input_values = [0, Quaternion(0, 0, 0, 0)]
op_type = 2
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_rsany"]
operator = 2
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_5614y"]
input_name = "time"
[sub_resource type="VisualShaderNodeFloatFunc" id="VisualShaderNodeFloatFunc_om1j3"]
function = 0
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_6ouiq"]
default_input_values = [0, 0.0, 1, 1.0]
[resource]
nodes/fragment/0/position = Vector2(1150, 120)
nodes/fragment/2/node = SubResource("VisualShaderNodeFresnel_m0u34")
nodes/fragment/2/position = Vector2(-370, 170)
nodes/fragment/3/node = SubResource("VisualShaderNodeVectorOp_rsany")
nodes/fragment/3/position = Vector2(120, 200)
nodes/fragment/4/node = SubResource("VisualShaderNodeColorParameter_aiwsy")
nodes/fragment/4/position = Vector2(-480, 410)
nodes/fragment/5/node = SubResource("VisualShaderNodeVectorDecompose_m0u34")
nodes/fragment/5/position = Vector2(-40, 500)
nodes/fragment/6/node = SubResource("VisualShaderNodeFloatOp_rsany")
nodes/fragment/6/position = Vector2(210, 470)
nodes/fragment/7/node = SubResource("VisualShaderNodeInput_5614y")
nodes/fragment/7/position = Vector2(250, 1250)
nodes/fragment/8/node = SubResource("VisualShaderNodeFloatFunc_om1j3")
nodes/fragment/8/position = Vector2(270, 1130)
nodes/fragment/9/node = SubResource("VisualShaderNodeFloatOp_6ouiq")
nodes/fragment/9/position = Vector2(270, 960)
nodes/fragment/10/node = SubResource("VisualShaderNodeFloatOp_m0u34")
nodes/fragment/10/position = Vector2(270, 790)
nodes/fragment/11/node = SubResource("VisualShaderNodeFloatOp_aiwsy")
nodes/fragment/11/position = Vector2(650, 490)
nodes/fragment/12/node = SubResource("VisualShaderNodeFloatOp_7h3f8")
nodes/fragment/12/position = Vector2(510, 730)
nodes/fragment/connections = PackedInt32Array(2, 0, 3, 0, 3, 0, 0, 0, 4, 0, 5, 0, 4, 0, 3, 1, 2, 0, 6, 0, 5, 3, 6, 1, 7, 0, 8, 0, 8, 0, 9, 0, 9, 0, 10, 0, 6, 0, 11, 0, 11, 0, 0, 1, 10, 0, 12, 0, 12, 0, 11, 1)

152
godot/shaders/vignette.tres Normal file
View File

@ -0,0 +1,152 @@
[gd_resource type="VisualShader" format=3 uid="uid://datt1r440base"]
[sub_resource type="VisualShaderNodeFloatParameter" id="VisualShaderNodeFloatParameter_jyxcy"]
parameter_name = "FloatParameter"
hint = 2
min = 1.0
max = 10.0
step = 0.5
default_value_enabled = true
default_value = 3.0
[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_jyxcy"]
expanded_output_ports = [0]
parameter_name = "Color"
default_value_enabled = true
default_value = Color(1, 0, 0, 1)
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_de6xh"]
operator = 2
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_de6xh"]
input_name = "time"
[sub_resource type="VisualShaderNodeFloatFunc" id="VisualShaderNodeFloatFunc_c4357"]
function = 0
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_fcsw6"]
operator = 2
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_pksew"]
default_input_values = [0, 0.0, 1, 2.0]
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_k2y31"]
default_input_values = [0, 0.0, 1, 0.5]
operator = 2
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_jyxcy"]
input_name = "uv"
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_gbuoh"]
default_input_values = [0, Vector2(0, 0), 1, Vector2(0.5, 0.5)]
op_type = 0
operator = 1
[sub_resource type="VisualShaderNodeVectorFunc" id="VisualShaderNodeVectorFunc_de6xh"]
output_port_for_preview = 0
default_input_values = [0, Vector2(0, 0)]
expanded_output_ports = [0]
op_type = 0
function = 4
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_jyxcy"]
default_input_values = [0, Vector2(0, 0), 1, Vector2(2, 2)]
op_type = 0
operator = 2
[sub_resource type="VisualShaderNodeVectorDistance" id="VisualShaderNodeVectorDistance_jyxcy"]
default_input_values = [0, Vector2(0, 0), 1, Vector2(0, 0)]
op_type = 0
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_jyxcy"]
default_input_values = [0, 0.0, 1, 0.7]
operator = 1
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_gbuoh"]
default_input_values = [0, 0.0, 1, 3.0]
operator = 3
[sub_resource type="VisualShaderNodeFloatParameter" id="VisualShaderNodeFloatParameter_de6xh"]
parameter_name = "RimDistance"
hint = 2
default_value_enabled = true
default_value = 0.7
[sub_resource type="VisualShaderNodeColorConstant" id="VisualShaderNodeColorConstant_jyxcy"]
constant = Color(1, 0, 0, 1)
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_gbuoh"]
input_name = "uv"
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_de6xh"]
default_input_values = [0, Vector2(0, 0), 1, Vector2(0.5, 0.5)]
op_type = 0
operator = 1
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_c4357"]
output_port_for_preview = 0
default_input_values = [0, Vector2(0, 0), 1, Vector2(2, 2)]
op_type = 0
operator = 2
[sub_resource type="VisualShaderNodeVectorFunc" id="VisualShaderNodeVectorFunc_fcsw6"]
output_port_for_preview = 1
default_input_values = [0, Vector2(0, 0)]
expanded_output_ports = [0]
op_type = 0
function = 4
[sub_resource type="VisualShaderNodeVec3Constant" id="VisualShaderNodeVec3Constant_pksew"]
constant = Vector3(1, 0, 0)
[resource]
mode = 1
flags/light_only = false
nodes/vertex/0/position = Vector2(710, 300)
nodes/vertex/2/node = SubResource("VisualShaderNodeColorConstant_jyxcy")
nodes/vertex/2/position = Vector2(-230, 100)
nodes/vertex/3/node = SubResource("VisualShaderNodeInput_gbuoh")
nodes/vertex/3/position = Vector2(-600, 300)
nodes/vertex/4/node = SubResource("VisualShaderNodeVectorOp_de6xh")
nodes/vertex/4/position = Vector2(-280, 440)
nodes/vertex/6/node = SubResource("VisualShaderNodeVectorOp_c4357")
nodes/vertex/6/position = Vector2(-40, 430)
nodes/vertex/7/node = SubResource("VisualShaderNodeVectorFunc_fcsw6")
nodes/vertex/7/position = Vector2(220, 380)
nodes/vertex/8/node = SubResource("VisualShaderNodeVec3Constant_pksew")
nodes/vertex/8/position = Vector2(180, 100)
nodes/vertex/connections = PackedInt32Array(4, 0, 6, 0, 6, 0, 7, 0, 3, 0, 4, 0, 8, 0, 0, 2, 7, 1, 0, 3)
nodes/fragment/0/position = Vector2(2820, 0)
nodes/fragment/2/node = SubResource("VisualShaderNodeInput_jyxcy")
nodes/fragment/2/position = Vector2(-520, 330)
nodes/fragment/3/node = SubResource("VisualShaderNodeVectorOp_gbuoh")
nodes/fragment/3/position = Vector2(-110, 390)
nodes/fragment/4/node = SubResource("VisualShaderNodeVectorFunc_de6xh")
nodes/fragment/4/position = Vector2(190, 380)
nodes/fragment/5/node = SubResource("VisualShaderNodeVectorOp_jyxcy")
nodes/fragment/5/position = Vector2(490, 320)
nodes/fragment/6/node = SubResource("VisualShaderNodeVectorDistance_jyxcy")
nodes/fragment/6/position = Vector2(840, 320)
nodes/fragment/7/node = SubResource("VisualShaderNodeFloatOp_jyxcy")
nodes/fragment/7/position = Vector2(1070, 270)
nodes/fragment/8/node = SubResource("VisualShaderNodeFloatOp_gbuoh")
nodes/fragment/8/position = Vector2(1300, 250)
nodes/fragment/9/node = SubResource("VisualShaderNodeFloatParameter_de6xh")
nodes/fragment/9/position = Vector2(730, 530)
nodes/fragment/10/node = SubResource("VisualShaderNodeFloatParameter_jyxcy")
nodes/fragment/10/position = Vector2(1080, 550)
nodes/fragment/11/node = SubResource("VisualShaderNodeColorParameter_jyxcy")
nodes/fragment/11/position = Vector2(1100, -180)
nodes/fragment/12/node = SubResource("VisualShaderNodeFloatOp_de6xh")
nodes/fragment/12/position = Vector2(2470, 160)
nodes/fragment/13/node = SubResource("VisualShaderNodeInput_de6xh")
nodes/fragment/13/position = Vector2(1480, 740)
nodes/fragment/14/node = SubResource("VisualShaderNodeFloatFunc_c4357")
nodes/fragment/14/position = Vector2(1560, 550)
nodes/fragment/15/node = SubResource("VisualShaderNodeFloatOp_fcsw6")
nodes/fragment/15/position = Vector2(2330, 290)
nodes/fragment/16/node = SubResource("VisualShaderNodeFloatOp_pksew")
nodes/fragment/16/position = Vector2(1870, 460)
nodes/fragment/17/node = SubResource("VisualShaderNodeFloatOp_k2y31")
nodes/fragment/17/position = Vector2(2080, 420)
nodes/fragment/connections = PackedInt32Array(2, 0, 3, 0, 3, 0, 4, 0, 4, 0, 5, 0, 5, 0, 6, 0, 6, 0, 7, 0, 7, 0, 8, 0, 9, 0, 7, 1, 10, 0, 8, 1, 11, 0, 0, 0, 12, 0, 0, 1, 11, 4, 12, 0, 13, 0, 14, 0, 8, 0, 15, 0, 15, 0, 12, 1, 14, 0, 16, 0, 16, 0, 17, 0, 17, 0, 15, 1)

View File

@ -28,8 +28,13 @@ use crate::{
},
pickup::PickupKind,
player::{
DamageSource, IPlayer, NetTransform, ball::Ball, local_player::LocalPlayer,
remote_player::RemotePlayer, telegrenade::Telegrenade, weapon::WeaponType,
DamageSource, IPlayer, NetTransform,
ball::Ball,
buffs::{Buff, BuffKind},
local_player::LocalPlayer,
remote_player::RemotePlayer,
telegrenade::Telegrenade,
weapon::WeaponType,
},
replay::{ReplayEvent, ReplayPlayback, ReplayRecorder},
team_resource::TeamResource,
@ -830,6 +835,11 @@ impl Game {
.spawn_player(id, team, id == self.self_id.unwrap_or(0), None, true);
if let Some(character) = &mut character {
character.dyn_bind_mut().new_buff(Buff {
time_remaining: 5.,
kind: BuffKind::SpawnProtection,
});
if self.current_replay_playback.is_some() {
character.set_visible(false);
}
@ -895,6 +905,11 @@ impl Game {
if let Some(map) = &mut self.current_map {
if let Some(player) = self.players.iter_mut().find(|p| p.id() == id) {
if let Some(mut character) = player.character.clone() {
character.dyn_bind_mut().new_buff(Buff {
time_remaining: 5.,
kind: BuffKind::SpawnProtection,
});
// This is a respawn, delete old character
if let Some(mut recorder) = self.replay_recorder.clone()
&& let Some(state) = player.get_state(player.clone())

View File

@ -2,7 +2,7 @@ use std::{collections::HashMap, f32::consts::PI};
use godot::{classes::RandomNumberGenerator, prelude::*};
use crate::{game::Game, ui::menu_player::MenuPlayer};
use crate::{game::Game, player::menu_player::MenuPlayer};
#[derive(GodotClass)]
#[class(base=Node3D, init)]

71
rust/src/player/buffs.rs Normal file
View File

@ -0,0 +1,71 @@
use godot::{
classes::{CharacterBody3D, class_macros::private::virtuals::ZipReader::Color},
obj::DynGd,
};
use serde::{Deserialize, Serialize};
use crate::player::IPlayer;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Buffs {
buffs: Vec<Buff>,
}
impl Default for Buffs {
fn default() -> Self {
let buffs = Vec::new();
Self { buffs }
}
}
impl Buffs {
pub fn update(&mut self, delta: f64) -> bool {
for buff in &mut self.buffs {
buff.update(delta);
}
let prev_length = self.buffs.len();
self.buffs.retain(|b| b.time_remaining >= 0.);
prev_length != self.buffs.len()
}
pub fn update_effects(self, player: &mut dyn IPlayer) {
let mut new_bubble_color = Color::BLACK.with_alpha(0.);
for buff in &self.buffs {
match buff.kind {
BuffKind::SpawnProtection => new_bubble_color = Color::BLUE,
}
}
player.set_bubble_color(new_bubble_color);
}
pub fn can_take_damage(&self) -> bool {
for buff in &self.buffs {
match buff.kind {
BuffKind::SpawnProtection => return false,
}
}
true
}
pub fn new_buff(&mut self, buff: Buff) {
self.buffs.push(buff);
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Buff {
pub time_remaining: f64,
pub kind: BuffKind,
}
impl Buff {
pub fn update(&mut self, delta: f64) {
self.time_remaining -= delta;
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BuffKind {
SpawnProtection,
}

View File

@ -2,8 +2,8 @@ use std::{f32::consts::PI, ops::Neg};
use godot::{
classes::{
AudioStreamPlayer, Camera3D, CharacterBody3D, CollisionShape3D, ICharacterBody3D, Input,
InputEvent, InputEventMouseMotion, Label, input::MouseMode,
AudioStreamPlayer, Camera3D, CharacterBody3D, CollisionShape3D, ColorRect,
ICharacterBody3D, Input, InputEvent, InputEventMouseMotion, Label, input::MouseMode,
},
obj::WithBaseField,
prelude::*,
@ -24,6 +24,7 @@ use crate::{
pickup::PickupKind,
player::{
DamageSource, DamageSourceSignal, IPlayer, NetTransform, PlayerCommon,
buffs::{Buff, Buffs},
effects::PlayerEffects,
remote_player::RemotePlayer,
shootable::Shootable,
@ -43,6 +44,8 @@ pub struct LocalPlayer {
#[export]
camera: Option<Gd<Camera3D>>,
#[export]
vignette: Option<Gd<ColorRect>>,
#[export]
move_speed: f32,
#[export]
soldier_mesh: Option<Gd<SoldierMesh>>,
@ -94,6 +97,8 @@ pub struct LocalPlayer {
telegrenade_cd_remaining: f64,
telegrenades_allowed: bool,
buffs: Buffs,
base: Base<CharacterBody3D>,
}
@ -357,6 +362,28 @@ impl IPlayer for LocalPlayer {
fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer> {
self.to_gd().into_dyn().upcast()
}
fn set_bubble_color(&mut self, color: Color) {
self.set_vignette_color(color);
}
fn get_buffs(&self) -> &Buffs {
&self.buffs
}
fn get_buffs_mut(&mut self) -> &mut Buffs {
&mut self.buffs
}
fn new_buff(&mut self, buff: Buff) {
self.buffs.new_buff(buff);
self.buffs.clone().update_effects(self);
}
fn set_buffs(&mut self, buffs: Buffs) {
self.buffs = buffs.clone();
buffs.update_effects(self);
}
}
#[godot_api]
@ -411,6 +438,8 @@ impl ICharacterBody3D for LocalPlayer {
}
}
});
self.buffs.clone().update_effects(self);
}
fn process(&mut self, delta: f64) {
@ -521,6 +550,10 @@ impl ICharacterBody3D for LocalPlayer {
};
weapon.set_position(new_weapon_pos);
}
if self.buffs.update(delta) {
self.buffs.clone().update_effects(self);
}
}
fn input(&mut self, event: Gd<InputEvent>) {
@ -782,6 +815,14 @@ impl LocalPlayer {
None
}
}
fn set_vignette_color(&mut self, color: Color) {
if let Some(rect) = &mut self.vignette
&& let Some(mut mat) = rect.get_material()
{
mat.set("shader_parameter/Color", &color.to_variant());
}
}
}
#[godot_dyn]

View File

@ -23,6 +23,8 @@ impl ICharacterBody3D for MenuPlayer {
fn ready(&mut self) {
if let Some(mesh) = &mut self.mesh {
mesh.bind_mut().spawn_raygun();
mesh.bind_mut()
.set_bubble_color(Color::BLACK.with_alpha(0.));
}
}

View File

@ -16,6 +16,7 @@ use crate::{
},
pickup::PickupKind,
player::{
buffs::{Buff, Buffs},
shootable::Shootable,
telegrenade::Telegrenade,
weapon::{BallWeapon, Weapon, WeaponType},
@ -23,8 +24,10 @@ use crate::{
};
pub mod ball;
pub mod buffs;
pub mod effects;
pub mod local_player;
pub mod menu_player;
pub mod player_hand_remover;
pub mod remote_player;
pub mod shootable;
@ -72,6 +75,11 @@ pub trait IPlayer {
fn get_telegrenade(&self) -> Option<Gd<Telegrenade>>;
fn telegrenade_teleport(&mut self, to: Vector3) -> bool;
fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer>;
fn set_bubble_color(&mut self, color: Color);
fn get_buffs(&self) -> &Buffs;
fn get_buffs_mut(&mut self) -> &mut Buffs;
fn new_buff(&mut self, buff: Buff);
fn set_buffs(&mut self, buffs: Buffs);
}
pub trait PlayerCommon {
@ -173,6 +181,10 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
fn can_take_damage(&self, source: &DamageSource) -> bool {
match source {
DamageSource::Player(source_player_id) => {
if !self.get_buffs().can_take_damage() {
return false;
}
if let Some(game) = Game::singleton() {
let (self_team, source_team) = if let Some(self_player) =
game.bind().find_player(self.get_player_id().unwrap_or(0))

View File

@ -13,6 +13,7 @@ use crate::{
pickup::PickupKind,
player::{
DamageSource, DamageSourceSignal, IPlayer, NetTransform, PlayerCommon,
buffs::{Buff, Buffs},
effects::PlayerEffects,
shootable::Shootable,
soldier_mesh::SoldierMesh,
@ -71,6 +72,8 @@ pub struct RemotePlayer {
telegrenade_cd_remaining: f64,
telegrenades_allowed: bool,
buffs: Buffs,
base: Base<CharacterBody3D>,
}
@ -298,6 +301,30 @@ impl IPlayer for RemotePlayer {
fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer> {
self.to_gd().into_dyn().upcast()
}
fn set_bubble_color(&mut self, color: Color) {
if let Some(mesh) = &mut self.soldier_mesh {
mesh.bind_mut().set_bubble_color(color);
}
}
fn get_buffs(&self) -> &Buffs {
&self.buffs
}
fn get_buffs_mut(&mut self) -> &mut Buffs {
&mut self.buffs
}
fn new_buff(&mut self, buff: Buff) {
self.buffs.new_buff(buff);
self.buffs.clone().update_effects(self);
}
fn set_buffs(&mut self, buffs: Buffs) {
self.buffs = buffs.clone();
buffs.update_effects(self);
}
}
#[godot_api]
@ -324,6 +351,8 @@ impl ICharacterBody3D for RemotePlayer {
false
};
});
self.buffs.clone().update_effects(self);
}
fn process(&mut self, delta: f64) {
@ -352,6 +381,10 @@ impl ICharacterBody3D for RemotePlayer {
{
effects.bind_mut().walk();
}
if self.buffs.update(delta) {
self.buffs.clone().update_effects(self);
}
}
fn physics_process(&mut self, delta: f64) {

View File

@ -29,6 +29,8 @@ pub struct SoldierMesh {
look_at: Option<Gd<Node3D>>,
#[export]
pub hand_remover: Option<Gd<PlayerHandRemover>>,
#[export]
pub bubble: Option<Gd<MeshInstance3D>>,
pub current_weapon: Option<DynGd<Node3D, dyn Weapon>>,
@ -116,4 +118,12 @@ impl SoldierMesh {
mat.set("albedo_color", &color.to_variant());
}
}
pub fn set_bubble_color(&mut self, color: Color) {
if let Some(bubble) = &mut self.bubble
&& let Some(mut mat) = bubble.get_active_material(0)
{
mat.set("shader_parameter/BubbleColor", &color.to_variant());
}
}
}

View File

@ -15,7 +15,7 @@ use crate::{
net::{network_manager::BallSync, util::NetVector3},
pickup::{PickupKind, ReplayVisibility},
player::{
DamageSource, IPlayer, NetTransform, ball::Ball, remote_player::RemotePlayer,
DamageSource, IPlayer, NetTransform, ball::Ball, buffs::Buffs, remote_player::RemotePlayer,
telegrenade::Telegrenade, weapon::WeaponType,
},
ui::{hud::Hud, replay_hud::ReplayHud},
@ -389,6 +389,7 @@ impl INode for ReplayPlayback {
.bind_mut()
.set_movement_dir(state.movement_dir.into());
character.bind_mut().set_hp(state.health);
character.bind_mut().set_buffs(state.buffs.clone());
let weapon = character.bind().get_weapon().clone();
if let Some(weapon) = weapon
&& weapon.dyn_bind().get_type() != state.current_weapon
@ -754,6 +755,7 @@ pub struct ReplayPlayerState {
pub kills: u16,
pub deaths: u16,
pub health: i32,
pub buffs: Buffs,
}
impl Player {
@ -772,6 +774,7 @@ impl Player {
kills: player.data.kills,
deaths: player.data.deaths,
health: character.dyn_bind().get_health(),
buffs: character.dyn_bind().get_buffs().clone(),
})
} else {
None

View File

@ -6,7 +6,6 @@ pub mod hud;
pub mod lobby;
pub mod lobby_player_listing;
pub mod main_menu;
pub mod menu_player;
pub mod net_stats;
pub mod player_listing;
pub mod player_listings;