TowerDefense/Projectiles/Projectile.gd
2025-08-31 23:07:55 +02:00

72 lines
1.7 KiB
GDScript

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