Randoloot/scripts/game/enemy_plasma_projectile.gd
2026-10-16 22:04:36 +02:00

57 lines
1.9 KiB
GDScript

extends Area2D
const DAMAGE_POPUP_SCENE := preload("res://scenes/game/damage_popup.tscn")
const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn")
var direction := Vector2.UP
var projectile_speed := 300.0
var damage := 8.0
var max_range := 1000.0
var _distance_travelled := 0.0
var _impact_handled := false
func _ready() -> void:
body_entered.connect(_on_body_entered)
func configure(start_position: Vector2, travel_direction: Vector2, projectile_damage: float) -> void:
global_position = start_position
direction = travel_direction.normalized()
damage = projectile_damage
rotation = direction.angle()
func _physics_process(delta: float) -> void:
var step := projectile_speed * delta
var next_position := global_position + direction * step
var query := PhysicsRayQueryParameters2D.create(global_position, next_position, collision_mask, [get_rid()])
var hit := get_world_2d().direct_space_state.intersect_ray(query)
if not hit.is_empty():
global_position = hit["position"]
_hit_target(hit.get("collider"))
return
global_position = next_position
_distance_travelled += step
if _distance_travelled >= max_range:
queue_free()
func _draw() -> void:
draw_circle(Vector2.ZERO, 6.0, Color(1.0, 0.24, 0.32, 0.98))
draw_circle(Vector2.ZERO, 3.0, Color(1.0, 0.82, 0.7, 1.0))
func _on_body_entered(body: Node2D) -> void:
_hit_target(body)
func _hit_target(target: Variant) -> void:
if _impact_handled:
return
_impact_handled = true
var effect := IMPACT_EFFECT_SCENE.instantiate() as Node2D
effect.global_position = global_position
get_parent().add_child(effect)
effect.call("configure", false, Color(1.0, 0.32, 0.38))
if target is Node and target.has_method("take_damage") and not target.is_in_group("asteroids"):
if target is CharacterBody2D:
target.call("take_damage", damage, false, DamageTypes.Type.ENERGY)
else:
target.call("take_damage", damage)
queue_free()