diff --git a/components/explosive_damage_component.gd b/components/explosive_damage_component.gd index 1d26827..99433ad 100644 --- a/components/explosive_damage_component.gd +++ b/components/explosive_damage_component.gd @@ -27,6 +27,6 @@ func _physics_process(_delta : float) -> void: for area in get_overlapping_areas(): if area is HealthComponent and is_multiplayer_authority(): - area.damage.rpc(damage, damage_dealer.player_id) + (area as HealthComponent).damage.rpc(damage, damage_dealer.player_id, damage_dealer.team_id) set_physics_process(false) diff --git a/components/flag_carry_component.gd b/components/flag_carry_component.gd index 021ac9c..d9f6e49 100644 --- a/components/flag_carry_component.gd +++ b/components/flag_carry_component.gd @@ -38,13 +38,13 @@ func _grab(flag : Flag) -> void: _carried_flag = flag show() -func _release(inherited_velocity : Vector3, throw_speed : float) -> void: +func _release(inherited_velocity : Vector3, throw_speed : float, dropper : Player) -> void: if _is_carrying(): - _carried_flag.drop() + _carried_flag.drop(dropper) _carried_flag.rotation_degrees.x = 0.0 _carried_flag.linear_velocity = inherited_velocity + (global_basis.z * throw_speed) # Throw the flag from some distance in front of the player to avoid regrabbing mid-air - _carried_flag.global_position = _carried_flag.global_position + (global_basis.z * 1.5) + _carried_flag.global_position = carrier.global_position + (global_basis.z * 1.7) _carried_flag = null hide() @@ -55,8 +55,8 @@ func _sensor_on_body_entered(collider : Flag) -> void: if collider is Flag: _grab(collider) -func drop() -> void: - _release(Vector3.ZERO, 0.0) +func drop(dropper : Player) -> void: + _release(Vector3.ZERO, 0.0, dropper) -func throw(inherited_velocity : Vector3) -> void: - _release(inherited_velocity, max_throw_speed) +func throw(inherited_velocity : Vector3, dropper : Player) -> void: + _release(inherited_velocity, max_throw_speed, dropper) diff --git a/components/health_component.gd b/components/health_component.gd index e6d047e..750b51a 100644 --- a/components/health_component.gd +++ b/components/health_component.gd @@ -19,6 +19,7 @@ class_name HealthComponent extends Area3D set(value): health = value health_changed.emit(value) +@export var _player : Player signal health_zeroed(killer_id : int) signal health_changed(value : float) @@ -26,13 +27,16 @@ signal health_changed(value : float) func _ready() -> void: heal_full() -@rpc("call_local") -func damage(amount : float, damage_dealer_id : int) -> void: +@rpc("call_local", "reliable") +func damage(amount : float, damage_dealer_id : int, damage_dealer_team_id : int) -> void: + if damage_dealer_team_id == _player.team_id: + return + health = clampf(health - amount, 0.0, max_health) if health == 0.0: health_zeroed.emit(damage_dealer_id) -@rpc("call_local") +@rpc("call_local", "reliable") func _heal(amount : float) -> void: health = clampf(health + amount, 0.0, max_health) diff --git a/entities/flag/flag.gd b/entities/flag/flag.gd index 4f86225..b6767f6 100644 --- a/entities/flag/flag.gd +++ b/entities/flag/flag.gd @@ -6,7 +6,7 @@ enum FlagState { FLAG_STATE_ON_STAND, FLAG_STATE_DROPPED, FLAG_STATE_TAKEN } signal grabbed(grabber : Player) signal regrabbed -signal dropped +signal dropped(dropper : Player) var last_carrier : Player = null @onready var _mesh : Node = $Smoothing/Mesh @@ -24,9 +24,9 @@ func grab(grabber : Player) -> void: else: regrabbed.emit() -func drop() -> void: +func drop(dropper : Player) -> void: if flag_state == FlagState.FLAG_STATE_TAKEN: _mesh.show() flag_state = FlagState.FLAG_STATE_DROPPED - dropped.emit() + dropped.emit(dropper) diff --git a/entities/player/assets/jetpackfx/Particle01.png b/entities/player/assets/jetpackfx/Particle01.png new file mode 100644 index 0000000..74e9e8c Binary files /dev/null and b/entities/player/assets/jetpackfx/Particle01.png differ diff --git a/entities/player/assets/jetpackfx/Particle01.png.import b/entities/player/assets/jetpackfx/Particle01.png.import new file mode 100644 index 0000000..edbb4dd --- /dev/null +++ b/entities/player/assets/jetpackfx/Particle01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmf12llra7aq5" +path.s3tc="res://.godot/imported/Particle01.png-789728e4e363d58f11747b3cf3c5d5a3.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://entities/player/assets/jetpackfx/Particle01.png" +dest_files=["res://.godot/imported/Particle01.png-789728e4e363d58f11747b3cf3c5d5a3.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/entities/player/assets/jetpackfx/smoke_01.png b/entities/player/assets/jetpackfx/smoke_01.png new file mode 100644 index 0000000..1cd418e Binary files /dev/null and b/entities/player/assets/jetpackfx/smoke_01.png differ diff --git a/entities/player/assets/jetpackfx/smoke_01.png.import b/entities/player/assets/jetpackfx/smoke_01.png.import new file mode 100644 index 0000000..f895109 --- /dev/null +++ b/entities/player/assets/jetpackfx/smoke_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ct1v5iadtpadm" +path.s3tc="res://.godot/imported/smoke_01.png-5c3d69bc74b2f317eac64d37cd67aed3.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://entities/player/assets/jetpackfx/smoke_01.png" +dest_files=["res://.godot/imported/smoke_01.png-5c3d69bc74b2f317eac64d37cd67aed3.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/entities/player/assets/jetpackfx/smoke_02.png b/entities/player/assets/jetpackfx/smoke_02.png new file mode 100644 index 0000000..d866368 Binary files /dev/null and b/entities/player/assets/jetpackfx/smoke_02.png differ diff --git a/entities/player/assets/jetpackfx/smoke_02.png.import b/entities/player/assets/jetpackfx/smoke_02.png.import new file mode 100644 index 0000000..b9e266f --- /dev/null +++ b/entities/player/assets/jetpackfx/smoke_02.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://doxo4vfn0bjlp" +path.s3tc="res://.godot/imported/smoke_02.png-a5343a97ff1cefeebcd82e41218739ca.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://entities/player/assets/jetpackfx/smoke_02.png" +dest_files=["res://.godot/imported/smoke_02.png-a5343a97ff1cefeebcd82e41218739ca.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/entities/player/assets/jetpackfx/smoke_05.png b/entities/player/assets/jetpackfx/smoke_05.png new file mode 100644 index 0000000..0ac46dc Binary files /dev/null and b/entities/player/assets/jetpackfx/smoke_05.png differ diff --git a/entities/player/assets/jetpackfx/smoke_05.png.import b/entities/player/assets/jetpackfx/smoke_05.png.import new file mode 100644 index 0000000..482ef49 --- /dev/null +++ b/entities/player/assets/jetpackfx/smoke_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dg8jhudb2pp5" +path="res://.godot/imported/smoke_05.png-0e09dd48bb034f353433668dafb91bd9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://entities/player/assets/jetpackfx/smoke_05.png" +dest_files=["res://.godot/imported/smoke_05.png-0e09dd48bb034f353433668dafb91bd9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/entities/player/assets/jetpackfx/smoke_06.png b/entities/player/assets/jetpackfx/smoke_06.png new file mode 100644 index 0000000..300c5fa Binary files /dev/null and b/entities/player/assets/jetpackfx/smoke_06.png differ diff --git a/entities/player/assets/jetpackfx/smoke_06.png.import b/entities/player/assets/jetpackfx/smoke_06.png.import new file mode 100644 index 0000000..34260f4 --- /dev/null +++ b/entities/player/assets/jetpackfx/smoke_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bj3byo4v71rub" +path="res://.godot/imported/smoke_06.png-551015dc27729e05438bc76194d0b9c3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://entities/player/assets/jetpackfx/smoke_06.png" +dest_files=["res://.godot/imported/smoke_06.png-551015dc27729e05438bc76194d0b9c3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/entities/player/player.gd b/entities/player/player.gd index f6935cb..113e7ef 100644 --- a/entities/player/player.gd +++ b/entities/player/player.gd @@ -39,6 +39,7 @@ enum PlayerState { PLAYER_ALIVE, PLAYER_DEAD } set(id): player_id = id $PlayerInput.set_multiplayer_authority(id) +@export var team_id : int = 1 @export var nickname : String @onready var input : PlayerInput = $PlayerInput @@ -53,6 +54,7 @@ enum PlayerState { PLAYER_ALIVE, PLAYER_DEAD } @onready var spring_arm_height : float = $Smoothing/SpringArm3D.position.y @onready var _original_weapon_transform : Transform3D = weapon.transform @onready var tp_player : Vanguard = $Smoothing/ThirdPerson/PlayerMesh +@onready var jetpack_particles : Array = $Smoothing/ThirdPerson/PlayerMesh/JetpackFX.get_children() signal died(player : Player, killer_id : int) signal energy_changed(energy : float) @@ -111,7 +113,7 @@ func _jump() -> void: _jumping = true func _throw_flag() -> void: - flag_carry_component.throw(linear_velocity) + flag_carry_component.throw(linear_velocity, self) func is_on_floor() -> bool: if shape_cast.is_colliding(): @@ -134,6 +136,7 @@ func _handle_jetpack(direction : Vector3) -> void: var up_vector : Vector3 = Vector3.UP * jetpack_vertical_force * jetpack_force_factor var side_vector : Vector3 = direction * jetpack_horizontal_force * jetpack_force_factor apply_force(up_vector + side_vector) + display_jetpack_particles() func _update_jetpack_energy(delta : float) -> void: if input.jetting: @@ -225,12 +228,13 @@ func _is_player_dead() -> bool: return player_state != PlayerState.PLAYER_ALIVE func die(killer_id : int) -> void: - flag_carry_component.drop() + flag_carry_component.drop(self) player_state = PlayerState.PLAYER_DEAD if _is_pawn(): animation_player.play("death") died.emit(self, killer_id) +@rpc("call_local", "reliable") func respawn(location : Vector3) -> void: animation_player.stop() player_state = PlayerState.PLAYER_ALIVE @@ -240,4 +244,8 @@ func respawn(location : Vector3) -> void: func _exit_tree() -> void: player_state = PlayerState.PLAYER_DEAD - flag_carry_component.drop() + flag_carry_component.drop(self) + +func display_jetpack_particles() -> void: + for particle: GPUParticles3D in jetpack_particles: + particle.emitting = true diff --git a/entities/player/player.tscn b/entities/player/player.tscn index 10ff523..f53ba92 100644 --- a/entities/player/player.tscn +++ b/entities/player/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=19 format=3 uid="uid://cbhx1xme0sb7k"] +[gd_scene load_steps=41 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"] @@ -11,6 +11,9 @@ [ext_resource type="PackedScene" uid="uid://2t8ql8pkxv6c" path="res://components/flag_carry_component.tscn" id="7_e7s1a"] [ext_resource type="PackedScene" uid="uid://d3l7fvbdg6m5g" path="res://entities/flag/assets/flag.glb" id="9_fce2y"] [ext_resource type="Script" path="res://addons/smoothing/smoothing.gd" id="11_k330l"] +[ext_resource type="Texture2D" uid="uid://ct1v5iadtpadm" path="res://entities/player/assets/jetpackfx/smoke_01.png" id="12_ypuho"] +[ext_resource type="Texture2D" uid="uid://doxo4vfn0bjlp" path="res://entities/player/assets/jetpackfx/smoke_02.png" id="13_wvbf0"] +[ext_resource type="Texture2D" uid="uid://dmf12llra7aq5" path="res://entities/player/assets/jetpackfx/Particle01.png" id="14_vughy"] [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_clur0"] resource_local_to_scene = true @@ -74,6 +77,9 @@ properties/4/replication_mode = 2 properties/5/path = NodePath(".:nickname") properties/5/spawn = true properties/5/replication_mode = 2 +properties/6/path = NodePath(".:team_id") +properties/6/spawn = true +properties/6/replication_mode = 2 [sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_5j4ew"] properties/0/path = NodePath(".:direction") @@ -89,6 +95,114 @@ properties/3/path = NodePath(".:skiing") properties/3/spawn = false properties/3/replication_mode = 2 +[sub_resource type="Gradient" id="Gradient_3u0pn"] +offsets = PackedFloat32Array(0, 0.872727) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_wjoiw"] +gradient = SubResource("Gradient_3u0pn") + +[sub_resource type="Curve" id="Curve_pmb0n"] +max_value = 2.0 +_data = [Vector2(0, 0.197802), 0.0, 0.0, 0, 0, Vector2(1, 2), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="CurveTexture" id="CurveTexture_cj8ky"] +curve = SubResource("Curve_pmb0n") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_v556h"] +emission_shape = 1 +emission_sphere_radius = 0.1 +angle_min = -381.7 +angle_max = 381.7 +gravity = Vector3(0, -5, 0) +tangential_accel_min = -5.0 +tangential_accel_max = 5.0 +scale_curve = SubResource("CurveTexture_cj8ky") +color_ramp = SubResource("GradientTexture1D_wjoiw") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_27esd"] +transparency = 1 +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("12_ypuho") +billboard_mode = 1 +billboard_keep_scale = true + +[sub_resource type="QuadMesh" id="QuadMesh_hegkl"] +material = SubResource("StandardMaterial3D_27esd") + +[sub_resource type="Gradient" id="Gradient_f4nyt"] +offsets = PackedFloat32Array(0, 0.972727) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_ovx5q"] +gradient = SubResource("Gradient_f4nyt") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_l8e6j"] +emission_shape = 1 +emission_sphere_radius = 0.1 +angle_min = -381.7 +angle_max = 381.7 +gravity = Vector3(0, -5, 0) +tangential_accel_min = -5.0 +tangential_accel_max = 5.0 +scale_curve = SubResource("CurveTexture_cj8ky") +color_ramp = SubResource("GradientTexture1D_ovx5q") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bknuu"] +transparency = 1 +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("13_wvbf0") +billboard_mode = 1 +billboard_keep_scale = true +grow_amount = 1.506 + +[sub_resource type="QuadMesh" id="QuadMesh_aeure"] +material = SubResource("StandardMaterial3D_bknuu") + +[sub_resource type="Gradient" id="Gradient_t1nsw"] +offsets = PackedFloat32Array(0, 0.627273, 0.927273) +colors = PackedColorArray(1, 0.858824, 0.0784314, 1, 1, 0, 0, 1, 1, 0, 0, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_x0y0j"] +gradient = SubResource("Gradient_t1nsw") + +[sub_resource type="Curve" id="Curve_fkrx7"] +max_value = 2.0 +_data = [Vector2(0, 0.197802), 0.0, 0.0, 0, 0, Vector2(0.594203, 0.395604), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_frkde"] +curve = SubResource("Curve_fkrx7") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_q1vdw"] +emission_shape = 1 +emission_sphere_radius = 0.05 +angle_min = -381.7 +angle_max = 381.7 +gravity = Vector3(0, -5, 0) +tangential_accel_min = -5.0 +tangential_accel_max = 5.0 +scale_curve = SubResource("CurveTexture_frkde") +color_ramp = SubResource("GradientTexture1D_x0y0j") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_2jwv2"] +transparency = 1 +blend_mode = 1 +cull_mode = 2 +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("14_vughy") +emission_enabled = true +emission = Color(1, 0.823529, 0.701961, 1) +billboard_mode = 3 +billboard_keep_scale = true +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false + +[sub_resource type="QuadMesh" id="QuadMesh_uc7ts"] +material = SubResource("StandardMaterial3D_2jwv2") + [node name="Player" type="RigidBody3D" node_paths=PackedStringArray("iff")] collision_mask = 2147483649 axis_lock_angular_x = true @@ -126,7 +240,8 @@ shape = ExtResource("2_vjqny") [node name="HUD" parent="." instance=ExtResource("3_ccety")] -[node name="HealthComponent" parent="." instance=ExtResource("5_t6i6e")] +[node name="HealthComponent" parent="." node_paths=PackedStringArray("_player") instance=ExtResource("5_t6i6e")] +_player = NodePath("..") [node name="CollisionShape3D" type="CollisionShape3D" parent="HealthComponent"] shape = ExtResource("2_vjqny") @@ -185,6 +300,33 @@ transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, -0.602515, 0) transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0) spine_ik_target_attachment = NodePath("../../SpringArm3D/SpineIKTarget") +[node name="JetpackFX" type="Node3D" parent="Smoothing/ThirdPerson/PlayerMesh"] +transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0.187666, 0.238235, -0.147731) + +[node name="Smoke1" type="GPUParticles3D" parent="Smoothing/ThirdPerson/PlayerMesh/JetpackFX"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.150648, 0) +emitting = false +lifetime = 0.5 +one_shot = true +process_material = SubResource("ParticleProcessMaterial_v556h") +draw_pass_1 = SubResource("QuadMesh_hegkl") + +[node name="Smoke2" type="GPUParticles3D" parent="Smoothing/ThirdPerson/PlayerMesh/JetpackFX"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.108846, 0) +emitting = false +lifetime = 0.5 +one_shot = true +process_material = SubResource("ParticleProcessMaterial_l8e6j") +draw_pass_1 = SubResource("QuadMesh_aeure") + +[node name="Fire1" type="GPUParticles3D" parent="Smoothing/ThirdPerson/PlayerMesh/JetpackFX"] +emitting = false +amount = 16 +lifetime = 0.3 +one_shot = true +process_material = SubResource("ParticleProcessMaterial_q1vdw") +draw_pass_1 = SubResource("QuadMesh_uc7ts") + [node name="IFFAttachment" type="Marker3D" parent="Smoothing/ThirdPerson"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.27457, 0) diff --git a/entities/weapons/space_gun/projectile.gd b/entities/weapons/space_gun/projectile.gd index afd64fa..cdd0209 100644 --- a/entities/weapons/space_gun/projectile.gd +++ b/entities/weapons/space_gun/projectile.gd @@ -18,9 +18,11 @@ class_name Projectile extends Node3D @export var EXPLOSION : PackedScene @export var speed : float = 78.4 # m/s @export var lifespan : float = 5.0 # in seconds +@export var _time_to_trail_enable : float = 0.05 # in seconds @onready var shape_cast : ShapeCast3D = $ShapeCast3D @onready var game : Node3D = get_tree().get_current_scene() +@onready var projectile_trail : Trail3D = $Smoothing/ProjectileTrail var velocity : Vector3 = Vector3.ZERO var shooter : Player @@ -32,6 +34,13 @@ func _ready() -> void: lifespan_timer.autostart = true lifespan_timer.timeout.connect(self_destruct) add_child(lifespan_timer) + projectile_trail._trail_enabled = false + var trail_enable_timer : Timer = Timer.new() + trail_enable_timer.wait_time = _time_to_trail_enable + trail_enable_timer.one_shot = true + trail_enable_timer.autostart = true + trail_enable_timer.timeout.connect(_enable_trail) + add_child(trail_enable_timer) func self_destruct() -> void: explode(position) @@ -50,3 +59,6 @@ func _physics_process(delta : float) -> void: if shape_cast.is_colliding(): var contact_point : Vector3 = shape_cast.collision_result[0].point explode(contact_point) + +func _enable_trail() -> void: + projectile_trail._trail_enabled = true diff --git a/entities/weapons/space_gun/projectile.tscn b/entities/weapons/space_gun/projectile.tscn index 87037d4..52f7c21 100644 --- a/entities/weapons/space_gun/projectile.tscn +++ b/entities/weapons/space_gun/projectile.tscn @@ -1,9 +1,18 @@ -[gd_scene load_steps=7 format=3 uid="uid://dn1tcakam5egs"] +[gd_scene load_steps=8 format=3 uid="uid://dn1tcakam5egs"] [ext_resource type="Script" path="res://entities/weapons/space_gun/projectile.gd" id="1_4j1dp"] [ext_resource type="PackedScene" uid="uid://8atq41j7wd55" path="res://entities/weapons/space_gun/projectile_explosion.tscn" id="2_llml6"] +[ext_resource type="Script" path="res://addons/smoothing/smoothing.gd" id="3_dmi64"] [ext_resource type="Script" path="res://entities/weapons/space_gun/projectile_trail.gd" id="3_ygqbh"] +[sub_resource type="SphereShape3D" id="SphereShape3D_umtte"] +radius = 0.15 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o6j55"] +albedo_color = Color(0, 0.498039, 0.854902, 1) +emission_enabled = true +emission = Color(0.482353, 0.65098, 1, 1) + [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4a265"] transparency = 1 blend_mode = 1 @@ -11,33 +20,10 @@ cull_mode = 2 shading_mode = 0 vertex_color_use_as_albedo = true -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o6j55"] -albedo_color = Color(0, 0.498039, 0.854902, 1) -emission_enabled = true -emission = Color(0.482353, 0.65098, 1, 1) - -[sub_resource type="SphereShape3D" id="SphereShape3D_umtte"] -radius = 0.15 - [node name="Projectile" type="Node3D"] script = ExtResource("1_4j1dp") EXPLOSION = ExtResource("2_llml6") -[node name="ProjectileTrail" type="MeshInstance3D" parent="."] -material_override = SubResource("StandardMaterial3D_4a265") -script = ExtResource("3_ygqbh") -_start_width = 0.15 -_lifespan = 0.25 -_start_color = Color(0, 0.498039, 0.854902, 1) -_end_color = Color(1, 1, 1, 0) - -[node name="Mesh" type="CSGSphere3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 0.2, 0, 0, 0, 1, 0, 0, 0) -radius = 0.15 -radial_segments = 24 -rings = 8 -material = SubResource("StandardMaterial3D_o6j55") - [node name="ShapeCast3D" type="ShapeCast3D" parent="."] transform = Transform3D(1, 0, 0, 0, 0.2, 0, 0, 0, 1, 0, 0, 0) shape = SubResource("SphereShape3D_umtte") @@ -46,3 +32,23 @@ margin = 0.1 max_results = 1 collision_mask = 2147483649 debug_shape_custom_color = Color(1, 0, 0, 1) + +[node name="Smoothing" type="Node3D" parent="."] +script = ExtResource("3_dmi64") +target = NodePath("..") + +[node name="Mesh" type="CSGSphere3D" parent="Smoothing"] +transform = Transform3D(1, 0, 0, 0, 0.2, 0, 0, 0, 1, 0, 0, 0) +radius = 0.15 +radial_segments = 24 +rings = 8 +material = SubResource("StandardMaterial3D_o6j55") + +[node name="ProjectileTrail" type="MeshInstance3D" parent="Smoothing"] +material_override = SubResource("StandardMaterial3D_4a265") +skeleton = NodePath("../..") +script = ExtResource("3_ygqbh") +_start_width = 0.15 +_lifespan = 0.25 +_start_color = Color(0, 0.498039, 0.854902, 1) +_end_color = Color(1, 1, 1, 0) diff --git a/main.tscn b/main.tscn index 95844c6..8690f7c 100644 --- a/main.tscn +++ b/main.tscn @@ -17,6 +17,7 @@ script/source = "class_name Game extends Node3D @onready var maps : Array[PackedScene] = _maps_resource.get_items() +# current mode, when the value is set to null we're in the main menu var mode : Node: set(new_mode): # clean up previous mode @@ -40,16 +41,13 @@ func _ready() -> void: DisplayServer.window_set_mode(Settings.get_value(\"video\", \"window_mode\")) func _unhandled_input(event : InputEvent) -> void: - # escape key pressed if event.is_action_pressed(\"exit\"): # reset game mode mode = null - # check for debug build + # make it easier to exit the game during development if OS.is_debug_build(): - # exit with success get_tree().quit(0) else: - # show boot menu $BootMenu.show() # switch window mode @@ -73,7 +71,7 @@ func _start_demo() -> void: func _start_server(port : int, nickname : String) -> void: mode = MULTIPLAYER.instantiate() mode.start_server({ - \"port\": port, + \"port\": port, \"nickname\": nickname, \"map\": maps[clamp($BootMenu/Multiplayer.map_selector.selected, 0, len(maps))] }) diff --git a/modes/multiplayer.gd b/modes/multiplayer.gd index 9f077f7..9350cde 100644 --- a/modes/multiplayer.gd +++ b/modes/multiplayer.gd @@ -29,6 +29,9 @@ var _map_manager : Map var _flag : Flag var _flag_carrier_scoring_timer : Timer = Timer.new() +var team_chasers : Team +var team_rabbit : Team + signal connected_to_server signal connection_failed @@ -36,6 +39,10 @@ func _ready() -> void: _flag_carrier_scoring_timer.wait_time = 10.0 _flag_carrier_scoring_timer.timeout.connect(_on_flag_carrier_scoring_timer_timeout) add_child(_flag_carrier_scoring_timer) + team_chasers = Team.new() + team_chasers.team_id = 0 + team_rabbit = Team.new() + team_rabbit.team_id = 1 func start_server(config : Dictionary) -> void: # Check if required parameters are missing @@ -49,7 +56,7 @@ func start_server(config : Dictionary) -> void: peer.create_server(config["port"], MAX_CLIENTS) multiplayer.multiplayer_peer = peer multiplayer.peer_disconnected.connect(remove_player) - + _load_map.call_deferred(config["map"], config["nickname"]) func join_server(host : String, port : int, nickname : String) -> void: @@ -79,12 +86,13 @@ func _on_player_died(player : Player, killer_id : int) -> void: func respawn_player(player : Player) -> void: var spawn_location : Vector3 = _map_manager.get_player_spawn().position - player.respawn(spawn_location) + player.respawn.rpc(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.team_id = team_chasers.team_id player.nickname = nickname player.global_position = _map_manager.get_player_spawn().position players.add_child(player) @@ -122,10 +130,12 @@ func _join_match(nickname : String) -> void: add_player(multiplayer.get_remote_sender_id(), nickname) func _on_flag_grabbed(grabber : Player) -> void: + grabber.team_id = team_rabbit.team_id scoreboard.add_score_to_player(grabber, 10) _flag_carrier_scoring_timer.start() -func _on_flag_dropped() -> void: +func _on_flag_dropped(dropper : Player) -> void: + dropper.team_id = team_chasers.team_id _flag_carrier_scoring_timer.stop() func _on_flag_carrier_scoring_timer_timeout() -> void: diff --git a/modes/team.gd b/modes/team.gd new file mode 100644 index 0000000..2bcfc84 --- /dev/null +++ b/modes/team.gd @@ -0,0 +1,3 @@ +class_name Team extends Object + +var team_id : int diff --git a/tests/test_health_component.gd b/tests/test_health_component.gd index 2ce83bd..0f89077 100644 --- a/tests/test_health_component.gd +++ b/tests/test_health_component.gd @@ -31,15 +31,15 @@ func test_that_it_has_max_health_when_ready() -> void: func test_that_it_takes_damage() -> void: var damage_amount : float = 10 - _subject.damage(damage_amount, -1) + _subject.damage(damage_amount, -1, 0) assert_eq(_subject.health, TEST_MAX_HEALTH - damage_amount) func test_that_it_emits_health_changed_after_damage() -> void: - _subject.damage(1, -1) + _subject.damage(1, -1, 0) assert_signal_emitted(_subject, 'health_changed') func test_that_it_emits_health_zeroed() -> void: - _subject.damage(TEST_MAX_HEALTH, -1) + _subject.damage(TEST_MAX_HEALTH, -1, 0) assert_signal_emitted_with_parameters(_subject, 'health_zeroed', [-1]) func test_that_it_heals_fully() -> void: