From eabe566aca1b7d08acf8d1994b46155a7687f10b Mon Sep 17 00:00:00 2001 From: Varylios Date: Mon, 15 Sep 2025 19:45:59 +0200 Subject: [PATCH] fix(projectile): Bug when projectile was already in next target hitbox --- Projectiles/Draft/projectile_pierre.gd | 2 +- Projectiles/Projectile.gd | 37 ++++++++++++++------- Projectiles/Scenes/projectile-Victoria.tscn | 2 +- Projectiles/projectile.tscn | 1 + 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Projectiles/Draft/projectile_pierre.gd b/Projectiles/Draft/projectile_pierre.gd index 7dcf613..986cb4b 100644 --- a/Projectiles/Draft/projectile_pierre.gd +++ b/Projectiles/Draft/projectile_pierre.gd @@ -1,6 +1,6 @@ extends Sprite3D -var impact : GPUParticles3D = preload("res://Towers/Projectiles/ImpactPierre.tscn").instantiate() +var impact : GPUParticles3D = preload("res://Projectiles/Draft/ImpactPierre.tscn").instantiate() func _ready() -> void: $SFXCreate.play() diff --git a/Projectiles/Projectile.gd b/Projectiles/Projectile.gd index 8d84a73..3d88299 100644 --- a/Projectiles/Projectile.gd +++ b/Projectiles/Projectile.gd @@ -27,6 +27,7 @@ var amount : float var target : PhysicsBody3D var vectorTarget : Vector3 var bodiesInRange : Array[Node3D] +var collidingBodies : Array[Node3D] var affectedTarget : Array[Node3D] @@ -36,8 +37,10 @@ func _physics_process(_delta: float) -> void: maxTargets = 0 # Ensure queue free in next if if shouldQueueFree(): - queue_free() - return + return queue_free() + + if not collidingBodies.is_empty() && collidingBodies.has(target): + return onBodyCollideWithProjectile(target) var globalPos : Vector3 = vectorTarget if vectorTarget else target.global_position if target: @@ -67,6 +70,9 @@ func onBodyEnteredDamageArea(body: Node3D) -> void: func onBodyCollideWithProjectile(body: Node3D) -> void: + if not collidingBodies.has(body): + collidingBodies.push_back(body) + if mode != MODE.LOCATION && (body == target || type == TYPE.PIERCING) && targetable(body): addBodyInRange(body, true) resolveContact() @@ -75,12 +81,14 @@ func onBodyCollideWithProjectile(body: Node3D) -> void: func addBodyInRange(body: Node3D, pushFront: bool = false) -> void: var idx : int = bodiesInRange.find(body) - if pushFront: - if idx != -1: - bodiesInRange.remove_at(idx) + if idx == -1: + if pushFront: + bodiesInRange.push_front(body) + else: + bodiesInRange.push_back(body) + elif pushFront && idx != 0: + bodiesInRange.remove_at(idx) bodiesInRange.push_front(body) - elif idx == -1: - bodiesInRange.push_back(body) func targetable(body: Node3D) -> bool: @@ -95,16 +103,17 @@ func resolveContact() -> void: match type: TYPE.AOE: - for _body in bodiesInRange: - if is_instance_valid(_body): - resolveEffect(_body) + for bodyInRange in bodiesInRange: + if is_instance_valid(bodyInRange): + resolveEffect(bodyInRange, false) TYPE.BOUNCING: target = null if bodiesInRange.is_empty() else bodiesInRange[0] -func resolveEffect(body : Node3D) -> void: - bodiesInRange.erase(body) +func resolveEffect(body : Node3D, erase : bool = true) -> void: + if erase: + bodiesInRange.erase(body) if affectedTarget.has(body) || body is GameTile: return @@ -121,6 +130,10 @@ func removeTarget(body: Node3D) -> void: bodiesInRange.erase(body) +func removeCollidingBody(body: Node3D) -> void: + collidingBodies.erase(body) + + func shoot(_target: Node3D, globalPos: Vector3) -> void: target = _target diff --git a/Projectiles/Scenes/projectile-Victoria.tscn b/Projectiles/Scenes/projectile-Victoria.tscn index 4ff674b..78bf3d2 100644 --- a/Projectiles/Scenes/projectile-Victoria.tscn +++ b/Projectiles/Scenes/projectile-Victoria.tscn @@ -16,5 +16,5 @@ collision_mask = 2 [node name="DamageArea" parent="." index="3"] collision_mask = 2 -[node name="Node" type="CollisionShape3D" parent="DamageArea" index="0"] +[node name="BoucingRange" type="CollisionShape3D" parent="DamageArea" index="0"] shape = SubResource("SphereShape3D_k24mn") diff --git a/Projectiles/projectile.tscn b/Projectiles/projectile.tscn index ce80754..3d0bee3 100644 --- a/Projectiles/projectile.tscn +++ b/Projectiles/projectile.tscn @@ -35,5 +35,6 @@ collision_layer = 0 collision_mask = 0 [connection signal="body_entered" from="HitBox" to="." method="onBodyCollideWithProjectile" flags=3] +[connection signal="body_exited" from="HitBox" to="." method="removeCollidingBody"] [connection signal="body_entered" from="DamageArea" to="." method="onBodyEnteredDamageArea"] [connection signal="body_exited" from="DamageArea" to="." method="removeTarget"]