47 lines
1.3 KiB
GDScript
47 lines
1.3 KiB
GDScript
@tool
|
|
extends Area2D
|
|
class_name DetectionArea
|
|
|
|
signal enemy_detected(enemy: Enemy)
|
|
|
|
@export var radius: float = 1000:
|
|
set(value):
|
|
radius = value
|
|
if Engine.is_editor_hint():
|
|
update_radii()
|
|
@export var requires_line_of_sight: bool = true
|
|
|
|
enum ActiveState {DISABLED, PREVIEW, ACTIVE}
|
|
@export var active_state: ActiveState = ActiveState.PREVIEW
|
|
|
|
func _ready() -> void:
|
|
update_radii()
|
|
|
|
func update_radii() -> void:
|
|
$CollisionShape2D.shape = $CollisionShape2D.shape.duplicate()
|
|
$CollisionShape2D.shape.radius = radius
|
|
$PointLight2D.texture = $PointLight2D.texture.duplicate()
|
|
$PointLight2D.texture.width = radius * 2
|
|
$PointLight2D.texture.height = radius * 2
|
|
|
|
func _process(delta: float) -> void:
|
|
if Engine.is_editor_hint():
|
|
return
|
|
for body in get_overlapping_bodies():
|
|
if body is Enemy:
|
|
if !body.sighted:
|
|
var sighted: bool = true
|
|
if requires_line_of_sight:
|
|
# perform LOS check
|
|
var params: PhysicsRayQueryParameters2D = PhysicsRayQueryParameters2D.new()
|
|
params.collision_mask = 0b11
|
|
params.from = global_position
|
|
params.to = body.global_position
|
|
var result: Dictionary = get_world_2d().direct_space_state.intersect_ray(params)
|
|
sighted = result.has("collider") and result["collider"] == body
|
|
|
|
if sighted:
|
|
enemy_detected.emit(body)
|
|
body.sighted = true
|
|
|