From cf7e6d13ef31deb5938bc55ff972ef22518881c1 Mon Sep 17 00:00:00 2001 From: Ruslan Ignatov Date: Sun, 16 Nov 2025 23:18:45 +0300 Subject: [PATCH] Added splash damage --- game/entities/other/blast.gd | 40 +++++++++++++++++++ game/entities/other/blast.gd.uid | 1 + game/entities/other/blast.tscn | 8 ++++ game/entities/weapons/abstract_projectile.gd | 26 +++++++----- game/entities/weapons/blast_projectile.gd | 22 ++++++++++ game/entities/weapons/blast_projectile.tscn | 5 ++- .../weapons/cannon/cannon_projectile.gd | 2 +- .../weapons/cannon/cannon_projectile.tscn | 20 ++++++---- .../entities/weapons/direct_hit_projectile.gd | 8 ++++ .../weapons/gatling/gatling_projectile.gd | 2 +- .../weapons/laser/laser_projectile.gd | 2 +- .../weapons/launcher/launcher_projectile.gd | 2 +- .../weapons/launcher/launcher_projectile.tscn | 20 ++++++---- .../weapons/minelayer/minelayer_projectile.gd | 2 +- .../minelayer/minelayer_projectile.tscn | 22 ++++++---- .../weapons/plasma/plasma_projectile.gd | 2 +- .../weapons/railgun/railgun_projectile.gd | 2 +- .../weapons/shrapnel/shrapnel_projectile.gd | 2 +- .../weapons/tesla/tesla_projectile.gd | 2 +- 19 files changed, 147 insertions(+), 43 deletions(-) create mode 100644 game/entities/other/blast.gd create mode 100644 game/entities/other/blast.gd.uid create mode 100644 game/entities/other/blast.tscn diff --git a/game/entities/other/blast.gd b/game/entities/other/blast.gd new file mode 100644 index 0000000..f356f40 --- /dev/null +++ b/game/entities/other/blast.gd @@ -0,0 +1,40 @@ +class_name Blast +extends Area2D + + +@export var damage : AbstractDamage +@export var shape : CircleShape2D + + +const FALLOFF_FACTOR = 3 + + +@onready var collision : CollisionShape2D = $CollisionShape2D + + +func _ready() -> void: + if collision and shape: + collision.shape = shape + + +func get_damage_to(body: Node2D) -> AbstractDamage: + var distance := _get_distance_to(body) + var damage_dub := damage.duplicate() + + var factor := _get_damage_factor(distance) + damage_dub.value = damage_dub.value * factor + + return damage_dub + + +func _get_distance_to(body: Node2D) -> float: + return global_position.distance_to(body.global_position) + + +func _get_damage_factor(distance: float) -> float: + if not shape: return 0.0 + + var coef := distance / shape.radius + if coef > 1: + return 0.0 + return 1 - coef * coef * coef diff --git a/game/entities/other/blast.gd.uid b/game/entities/other/blast.gd.uid new file mode 100644 index 0000000..b1f3c32 --- /dev/null +++ b/game/entities/other/blast.gd.uid @@ -0,0 +1 @@ +uid://clt20ebs6shkm diff --git a/game/entities/other/blast.tscn b/game/entities/other/blast.tscn new file mode 100644 index 0000000..895c55f --- /dev/null +++ b/game/entities/other/blast.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=3 uid="uid://pfvs7wqrnn08"] + +[ext_resource type="Script" uid="uid://clt20ebs6shkm" path="res://game/entities/other/blast.gd" id="1_2fpxy"] + +[node name="Blast" type="Area2D"] +script = ExtResource("1_2fpxy") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] diff --git a/game/entities/weapons/abstract_projectile.gd b/game/entities/weapons/abstract_projectile.gd index 35c4082..47a0d9c 100644 --- a/game/entities/weapons/abstract_projectile.gd +++ b/game/entities/weapons/abstract_projectile.gd @@ -8,7 +8,6 @@ const PLAYER_PROJECTILE_LAYER = 8 const ENEMY_PROJECTILE_LAYER = 16 -@export var damage : AbstractDamage @export_range(0, 1000) var speed : int = 0 @@ -44,19 +43,23 @@ func _physics_process(delta: float) -> void: func _apply_collision_mask() -> void: + _apply_collision_mask_to_area(self) + + +func _apply_collision_mask_to_area(area: Area2D) -> void: if collide_players: - collision_layer |= ENEMY_PROJECTILE_LAYER - collision_mask |= PLAYER_LAYER + area.collision_layer |= ENEMY_PROJECTILE_LAYER + area.collision_mask |= PLAYER_LAYER else: - collision_layer &= ~ENEMY_PROJECTILE_LAYER - collision_mask &= ~PLAYER_LAYER + area.collision_layer &= ~ENEMY_PROJECTILE_LAYER + area.collision_mask &= ~PLAYER_LAYER if collide_enemies: - collision_layer |= PLAYER_PROJECTILE_LAYER - collision_mask |= ENEMY_LAYER + area.collision_layer |= PLAYER_PROJECTILE_LAYER + area.collision_mask |= ENEMY_LAYER else: - collision_layer &= ~PLAYER_PROJECTILE_LAYER - collision_mask &= ~ENEMY_LAYER + area.collision_layer &= ~PLAYER_PROJECTILE_LAYER + area.collision_mask &= ~ENEMY_LAYER func _update_collision_rotation(velocity: Vector2) -> void: @@ -67,11 +70,12 @@ func _on_screen_exited() -> void: queue_free() -func _on_body_entered(body: Node2D) -> void: +func _try_to_damage(body: Node2D, damage: AbstractDamage) -> bool: var health_component : Health = body.find_child("Health") if health_component and health_component.has_method("apply_damage"): health_component.apply_damage(damage) - _process_hit_for_projectile(body) + return true + return false func _process_hit_for_projectile(_collided_body: Node2D) -> void: diff --git a/game/entities/weapons/blast_projectile.gd b/game/entities/weapons/blast_projectile.gd index daa3047..0986a16 100644 --- a/game/entities/weapons/blast_projectile.gd +++ b/game/entities/weapons/blast_projectile.gd @@ -1,2 +1,24 @@ class_name BlastProjectile extends AbstractProjectile + + +@onready var blast : Blast = $Blast + + +func _on_body_entered(body: Node2D) -> void: + var damaged := false + var overlapping_bodies := blast.get_overlapping_bodies() + for overlapping_body in overlapping_bodies: + var damage := blast.get_damage_to(overlapping_body) + if _try_to_damage(overlapping_body, damage): + damaged = true + + if damaged: + _process_hit_for_projectile(body) + + +func _apply_collision_mask() -> void: + super._apply_collision_mask() + + if blast: + _apply_collision_mask_to_area(blast) diff --git a/game/entities/weapons/blast_projectile.tscn b/game/entities/weapons/blast_projectile.tscn index 9c586ab..f2da00d 100644 --- a/game/entities/weapons/blast_projectile.tscn +++ b/game/entities/weapons/blast_projectile.tscn @@ -1,7 +1,10 @@ -[gd_scene load_steps=3 format=3 uid="uid://betr5ry5tc75e"] +[gd_scene load_steps=4 format=3 uid="uid://betr5ry5tc75e"] [ext_resource type="PackedScene" uid="uid://ybkqaynvpcjm" path="res://game/entities/weapons/abstract_projectile.tscn" id="1_pd7f6"] [ext_resource type="Script" uid="uid://bg8yrenh7x03b" path="res://game/entities/weapons/blast_projectile.gd" id="2_5vx6r"] +[ext_resource type="PackedScene" uid="uid://pfvs7wqrnn08" path="res://game/entities/other/blast.tscn" id="3_r3k86"] [node name="BlastProjectile" instance=ExtResource("1_pd7f6")] script = ExtResource("2_5vx6r") + +[node name="Blast" parent="." index="2" instance=ExtResource("3_r3k86")] diff --git a/game/entities/weapons/cannon/cannon_projectile.gd b/game/entities/weapons/cannon/cannon_projectile.gd index 3591c15..86a4890 100644 --- a/game/entities/weapons/cannon/cannon_projectile.gd +++ b/game/entities/weapons/cannon/cannon_projectile.gd @@ -1,2 +1,2 @@ class_name CannonProjectile -extends AbstractProjectile +extends BlastProjectile diff --git a/game/entities/weapons/cannon/cannon_projectile.tscn b/game/entities/weapons/cannon/cannon_projectile.tscn index 6be46db..ac16047 100644 --- a/game/entities/weapons/cannon/cannon_projectile.tscn +++ b/game/entities/weapons/cannon/cannon_projectile.tscn @@ -1,15 +1,10 @@ -[gd_scene load_steps=8 format=3 uid="uid://cgi7wd84kjnyw"] +[gd_scene load_steps=9 format=3 uid="uid://cgi7wd84kjnyw"] [ext_resource type="PackedScene" uid="uid://betr5ry5tc75e" path="res://game/entities/weapons/blast_projectile.tscn" id="1_20qwt"] [ext_resource type="Script" uid="uid://dfdh0o88as054" path="res://game/entities/weapons/cannon/cannon_projectile.gd" id="2_x3axw"] [ext_resource type="Script" uid="uid://dftb7hg5f06b5" path="res://game/health_system/damage/explosion_damage.gd" id="3_lb11p"] [ext_resource type="Texture2D" uid="uid://oj86smpsipw4" path="res://images/projectiles.png" id="4_bb01p"] -[sub_resource type="Resource" id="Resource_bb01p"] -script = ExtResource("3_lb11p") -value = 50 -metadata/_custom_type_script = "uid://dftb7hg5f06b5" - [sub_resource type="AtlasTexture" id="AtlasTexture_ugryq"] atlas = ExtResource("4_bb01p") region = Rect2(32, 16, 16, 16) @@ -17,11 +12,18 @@ region = Rect2(32, 16, 16, 16) [sub_resource type="CircleShape2D" id="CircleShape2D_lb11p"] radius = 2.0 +[sub_resource type="Resource" id="Resource_ugryq"] +script = ExtResource("3_lb11p") +value = 50 +metadata/_custom_type_script = "uid://dftb7hg5f06b5" + +[sub_resource type="CircleShape2D" id="CircleShape2D_bb01p"] +radius = 80.0 + [node name="CannonProjectile" instance=ExtResource("1_20qwt")] collision_layer = 0 collision_mask = 0 script = ExtResource("2_x3axw") -damage = SubResource("Resource_bb01p") speed = 600 [node name="Sprite2D" type="Sprite2D" parent="." index="0"] @@ -29,3 +31,7 @@ texture = SubResource("AtlasTexture_ugryq") [node name="CollisionShape2D" parent="." index="1"] shape = SubResource("CircleShape2D_lb11p") + +[node name="Blast" parent="." index="3"] +damage = SubResource("Resource_ugryq") +shape = SubResource("CircleShape2D_bb01p") diff --git a/game/entities/weapons/direct_hit_projectile.gd b/game/entities/weapons/direct_hit_projectile.gd index ed499bb..9c09d4f 100644 --- a/game/entities/weapons/direct_hit_projectile.gd +++ b/game/entities/weapons/direct_hit_projectile.gd @@ -1,2 +1,10 @@ class_name DirectHitProjectile extends AbstractProjectile + + +@export var damage : AbstractDamage + + +func _on_body_entered(body: Node2D) -> void: + if _try_to_damage(body, damage): + _process_hit_for_projectile(body) diff --git a/game/entities/weapons/gatling/gatling_projectile.gd b/game/entities/weapons/gatling/gatling_projectile.gd index 2e296dd..58f4a72 100644 --- a/game/entities/weapons/gatling/gatling_projectile.gd +++ b/game/entities/weapons/gatling/gatling_projectile.gd @@ -1,2 +1,2 @@ class_name GatlingProjectile -extends AbstractProjectile +extends DirectHitProjectile diff --git a/game/entities/weapons/laser/laser_projectile.gd b/game/entities/weapons/laser/laser_projectile.gd index 63ca052..4440e79 100644 --- a/game/entities/weapons/laser/laser_projectile.gd +++ b/game/entities/weapons/laser/laser_projectile.gd @@ -1,2 +1,2 @@ class_name LaserProjectile -extends AbstractProjectile +extends DirectHitProjectile diff --git a/game/entities/weapons/launcher/launcher_projectile.gd b/game/entities/weapons/launcher/launcher_projectile.gd index 34abdef..e44b56d 100644 --- a/game/entities/weapons/launcher/launcher_projectile.gd +++ b/game/entities/weapons/launcher/launcher_projectile.gd @@ -1,5 +1,5 @@ class_name LauncherProjectile -extends AbstractProjectile +extends BlastProjectile @export_range(0, 360) var rotation_speed: int diff --git a/game/entities/weapons/launcher/launcher_projectile.tscn b/game/entities/weapons/launcher/launcher_projectile.tscn index 6da9f7d..f80b2e0 100644 --- a/game/entities/weapons/launcher/launcher_projectile.tscn +++ b/game/entities/weapons/launcher/launcher_projectile.tscn @@ -1,15 +1,10 @@ -[gd_scene load_steps=15 format=3 uid="uid://dukgbg13ujkv2"] +[gd_scene load_steps=16 format=3 uid="uid://dukgbg13ujkv2"] [ext_resource type="PackedScene" uid="uid://betr5ry5tc75e" path="res://game/entities/weapons/blast_projectile.tscn" id="1_0mcat"] [ext_resource type="Script" uid="uid://dkvur5bdwg3sr" path="res://game/entities/weapons/launcher/launcher_projectile.gd" id="2_6hdsf"] [ext_resource type="Script" uid="uid://dftb7hg5f06b5" path="res://game/health_system/damage/explosion_damage.gd" id="3_ycnsk"] [ext_resource type="Texture2D" uid="uid://oj86smpsipw4" path="res://images/projectiles.png" id="4_kxgpk"] -[sub_resource type="Resource" id="Resource_kxgpk"] -script = ExtResource("3_ycnsk") -value = 24 -metadata/_custom_type_script = "uid://dftb7hg5f06b5" - [sub_resource type="AtlasTexture" id="AtlasTexture_kxgpk"] atlas = ExtResource("4_kxgpk") region = Rect2(0, 32, 16, 16) @@ -46,12 +41,19 @@ region = Rect2(48, 48, 16, 16) radius = 1.0 height = 6.0 +[sub_resource type="Resource" id="Resource_kos01"] +script = ExtResource("3_ycnsk") +value = 24 +metadata/_custom_type_script = "uid://dftb7hg5f06b5" + +[sub_resource type="CircleShape2D" id="CircleShape2D_kxgpk"] +radius = 16.0 + [node name="LauncherProjectile" instance=ExtResource("1_0mcat")] collision_layer = 0 collision_mask = 0 script = ExtResource("2_6hdsf") rotation_speed = 90 -damage = SubResource("Resource_kxgpk") speed = 300 [node name="Sprite2D_E" type="Sprite2D" parent="." index="0"] @@ -80,3 +82,7 @@ texture = SubResource("AtlasTexture_dl8vu") [node name="CollisionShape2D" parent="." index="8"] shape = SubResource("CapsuleShape2D_6hdsf") + +[node name="Blast" parent="." index="10"] +damage = SubResource("Resource_kos01") +shape = SubResource("CircleShape2D_kxgpk") diff --git a/game/entities/weapons/minelayer/minelayer_projectile.gd b/game/entities/weapons/minelayer/minelayer_projectile.gd index 26fc708..f3055cb 100644 --- a/game/entities/weapons/minelayer/minelayer_projectile.gd +++ b/game/entities/weapons/minelayer/minelayer_projectile.gd @@ -1,5 +1,5 @@ class_name MinelayerProjectile -extends AbstractProjectile +extends BlastProjectile @export var deceleration : int diff --git a/game/entities/weapons/minelayer/minelayer_projectile.tscn b/game/entities/weapons/minelayer/minelayer_projectile.tscn index 6cee9a5..1b7b553 100644 --- a/game/entities/weapons/minelayer/minelayer_projectile.tscn +++ b/game/entities/weapons/minelayer/minelayer_projectile.tscn @@ -1,15 +1,10 @@ -[gd_scene load_steps=8 format=3 uid="uid://4mkklqt1g14f"] +[gd_scene load_steps=9 format=3 uid="uid://4mkklqt1g14f"] [ext_resource type="PackedScene" uid="uid://betr5ry5tc75e" path="res://game/entities/weapons/blast_projectile.tscn" id="1_ufc4r"] [ext_resource type="Script" uid="uid://76swcukelnii" path="res://game/entities/weapons/minelayer/minelayer_projectile.gd" id="2_hwwfa"] [ext_resource type="Script" uid="uid://dftb7hg5f06b5" path="res://game/health_system/damage/explosion_damage.gd" id="3_hll7s"] [ext_resource type="Texture2D" uid="uid://oj86smpsipw4" path="res://images/projectiles.png" id="4_px1i2"] -[sub_resource type="Resource" id="Resource_px1i2"] -script = ExtResource("3_hll7s") -value = 100 -metadata/_custom_type_script = "uid://dftb7hg5f06b5" - [sub_resource type="AtlasTexture" id="AtlasTexture_ckqco"] atlas = ExtResource("4_px1i2") region = Rect2(0, 16, 16, 16) @@ -17,12 +12,19 @@ region = Rect2(0, 16, 16, 16) [sub_resource type="CircleShape2D" id="CircleShape2D_ufc4r"] radius = 7.0 +[sub_resource type="Resource" id="Resource_ckqco"] +script = ExtResource("3_hll7s") +value = 100 +metadata/_custom_type_script = "uid://dftb7hg5f06b5" + +[sub_resource type="CircleShape2D" id="CircleShape2D_px1i2"] +radius = 48.0 + [node name="MinelayerProjectile" instance=ExtResource("1_ufc4r")] collision_layer = 0 collision_mask = 0 script = ExtResource("2_hwwfa") deceleration = 100 -damage = SubResource("Resource_px1i2") speed = 200 [node name="Sprite2D" type="Sprite2D" parent="." index="0"] @@ -31,7 +33,11 @@ texture = SubResource("AtlasTexture_ckqco") [node name="CollisionShape2D" parent="." index="1"] shape = SubResource("CircleShape2D_ufc4r") -[node name="LivetimeTimer" type="Timer" parent="." index="3"] +[node name="Blast" parent="." index="3"] +damage = SubResource("Resource_ckqco") +shape = SubResource("CircleShape2D_px1i2") + +[node name="LivetimeTimer" type="Timer" parent="." index="4"] wait_time = 60.0 one_shot = true autostart = true diff --git a/game/entities/weapons/plasma/plasma_projectile.gd b/game/entities/weapons/plasma/plasma_projectile.gd index dd08fdc..66e9e25 100644 --- a/game/entities/weapons/plasma/plasma_projectile.gd +++ b/game/entities/weapons/plasma/plasma_projectile.gd @@ -1,2 +1,2 @@ class_name PlasmaProjectile -extends AbstractProjectile +extends DirectHitProjectile diff --git a/game/entities/weapons/railgun/railgun_projectile.gd b/game/entities/weapons/railgun/railgun_projectile.gd index 9eecaac..db3a704 100644 --- a/game/entities/weapons/railgun/railgun_projectile.gd +++ b/game/entities/weapons/railgun/railgun_projectile.gd @@ -1,5 +1,5 @@ class_name RailgunProjectile -extends AbstractProjectile +extends DirectHitProjectile @export_range(1, 10) var piercing: int = 1 diff --git a/game/entities/weapons/shrapnel/shrapnel_projectile.gd b/game/entities/weapons/shrapnel/shrapnel_projectile.gd index 695ecfd..04c5c61 100644 --- a/game/entities/weapons/shrapnel/shrapnel_projectile.gd +++ b/game/entities/weapons/shrapnel/shrapnel_projectile.gd @@ -1,5 +1,5 @@ class_name ShrapnelProjectile -extends AbstractProjectile +extends DirectHitProjectile @export var max_distance : int diff --git a/game/entities/weapons/tesla/tesla_projectile.gd b/game/entities/weapons/tesla/tesla_projectile.gd index 594b5c8..9fab2ea 100644 --- a/game/entities/weapons/tesla/tesla_projectile.gd +++ b/game/entities/weapons/tesla/tesla_projectile.gd @@ -1,5 +1,5 @@ class_name TeslaProjectile -extends AbstractProjectile +extends DirectHitProjectile @export_range(0.01, 0.5) var jink_min_delay: float = 0.01