2025-08-31 21:26:02 +02:00
|
|
|
extends CharacterBody3D
|
|
|
|
|
class_name Projectile
|
|
|
|
|
|
2025-08-31 23:07:55 +02:00
|
|
|
const TARGET_ENEMY : int = 1 ## Flag to target enemy
|
|
|
|
|
const TARGET_ALLY : int = 2 ## Flag to target ally
|
2025-08-31 21:26:02 +02:00
|
|
|
|
|
|
|
|
const MINIMUN_AREA : float = .1
|
|
|
|
|
|
2025-08-31 23:07:55 +02:00
|
|
|
var speed : int = 20
|
|
|
|
|
var isAOE : bool = false
|
|
|
|
|
var allowedTargets : int = TARGET_ENEMY
|
2025-08-31 21:26:02 +02:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
2025-08-31 23:07:55 +02:00
|
|
|
func onBodyExitedDamageArea(body: Node3D) -> void:
|
2025-08-31 21:26:02 +02:00
|
|
|
if body is Enemy:
|
|
|
|
|
enemiesInRange.erase(body)
|
|
|
|
|
if body is Tower:
|
|
|
|
|
allyInRange.erase(body)
|
|
|
|
|
|
|
|
|
|
|
2025-08-31 23:07:55 +02:00
|
|
|
func onBodyCollideWithProjectile(body: Node3D) -> void:
|
2025-08-31 21:26:02 +02:00
|
|
|
if body == target:
|
|
|
|
|
resolveDamages()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func targetable(body: Node3D) -> bool:
|
|
|
|
|
if body is Enemy:
|
2025-08-31 23:07:55 +02:00
|
|
|
return TARGET_ENEMY & allowedTargets
|
2025-08-31 21:26:02 +02:00
|
|
|
if body is Tower:
|
2025-08-31 23:07:55 +02:00
|
|
|
return TARGET_ALLY & allowedTargets
|
2025-08-31 21:26:02 +02:00
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func resolveDamages() -> void:
|
|
|
|
|
for enemy in enemiesInRange:
|
|
|
|
|
enemy.take_damage(damage)
|
|
|
|
|
queue_free()
|
2025-08-31 23:07:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|