class_name ProjectileBase extends Area2D signal on_hit(projectile, target) signal on_spawned(projectile) signal on_destroyed(projectile) @export var speed: float = 500.0 @export var damage: float = 10.0 @export var lifetime: float = 5.0 @export var direction: Vector2 = Vector2.RIGHT @export var target_position: Vector2 @export var is_friendly: bool = true # Modifier-related properties var pierce_count: int = 0 var has_explosive_impact: bool = true var explosion_projectile_count: int = 2 var explosion_projectile_damage_mult: float = 0.5 var explosion_projectile_speed: float = 300.0 var explosion_spread_angle: float = 360.0 # Full circle by default # References var source_weapon: RangedWeapon # Reference to the weapon that fired this var lifetime_timer: Timer # Add a variable to track the entity that triggered the explosion var ignore_target = null func _on_body_entered(body): # Check if this is a body we should ignore if body == ignore_target: return if body.is_in_group("enemies") and is_friendly: Log.pr("Hit enemy: ", body.name) # Deal damage to enemy if body.has_method("take_damage"): body.take_damage(damage) # Emit signal for modifiers to react to emit_signal("on_hit", self, body) # Handle piercing if pierce_count > 0: pierce_count -= 1 else: # Handle explosive impact if has_explosive_impact: # Store the target that triggered the explosion ignore_target = body _trigger_explosion() # Destroy the projectile destroy() func _trigger_explosion(): # Create the explosion VFX # var explosion = preload("res://scenes/explosion_effect.tscn").instantiate() # explosion.global_position = global_position # get_tree().root.add_child(explosion) # Spawn the additional projectiles if explosion_projectile_count > 0: _spawn_explosion_projectiles() func _spawn_explosion_projectiles(): for i in range(explosion_projectile_count): # Create a new projectile var new_proj = duplicate() new_proj.global_position = global_position # Calculate new direction based on spread var random_angle = randf_range(0, 2 * PI) var new_dir = Vector2.RIGHT.rotated(random_angle) # Set properties for the new projectile new_proj.direction = new_dir new_proj.damage = damage * explosion_projectile_damage_mult new_proj.speed = explosion_projectile_speed # Clear explosive properties so we don't get infinite loops new_proj.has_explosive_impact = true new_proj.explosion_projectile_count = 1 # Pass the ignore_target to the new projectiles new_proj.ignore_target = ignore_target # Add to scene tree get_tree().root.call_deferred("add_child", new_proj) func destroy(): emit_signal("on_destroyed", self) queue_free() func _on_lifetime_timeout(): destroy()