extends CharacterBody3D class_name Projectile const TARGET_ENEMY : int = 1 ## Flag to target enemy const TARGET_ALLY : int = 2 ## Flag to target ally const MINIMUN_AREA : float = .1 var speed : int = 20 var isAOE : bool = false var allowedTargets : int = TARGET_ENEMY var target : PhysicsBody3D var damage : int = 1 var enemiesInRange : Array[Enemy] var allyInRange : Array[Tower] func _physics_process(delta: float) -> void: if is_instance_valid(target): velocity = global_position.direction_to(target.global_position) * speed look_at(target.global_position) move_and_slide() else: queue_free() func onBodyEnteredDamageArea(body: Node3D) -> void: if isAOE && targetable(body): if body is Enemy: enemiesInRange.append(body) if body is Tower: allyInRange.append(body) func onBodyExitedDamageArea(body: Node3D) -> void: if body is Enemy: enemiesInRange.erase(body) if body is Tower: allyInRange.erase(body) func onBodyCollideWithProjectile(body: Node3D) -> void: if body == target: resolveDamages() func targetable(body: Node3D) -> bool: if body is Enemy: return TARGET_ENEMY & allowedTargets if body is Tower: return TARGET_ALLY & allowedTargets return false func resolveDamages() -> void: for enemy in enemiesInRange: enemy.take_damage(damage) queue_free() func loadProjectile(resource : ProjectileResource, startPosition: Vector3, _target: PhysicsBody3D) -> void: target = _target enemiesInRange.append(target) global_position = startPosition speed = resource.speed isAOE = resource.isAOE allowedTargets = resource.allowedTargets $Sprite3D.texture = resource.sprite if isAOE && resource.damageArea: $DamageArea/ProjectileArea.shape = resource.damageArea