61 lines
2.2 KiB
GDScript
61 lines
2.2 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)
|
|
var exclusions: Array[RID] = [get_rid()]
|
|
hit = preload("res://scripts/game/shield_intersections.gd").intercept(hit,global_position,next_position,collision_mask,exclusions,get_tree())
|
|
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))
|
|
effect.call("configure_contact",DamageTypes.Type.ENERGY,direction)
|
|
if target is Node and target.has_method("take_damage") and not target.is_in_group("asteroids"):
|
|
preload("res://scripts/game/combat_vfx.gd").mark_hit(target,global_position,direction)
|
|
if target is CharacterBody2D:
|
|
target.call("take_damage", damage, false, DamageTypes.Type.ENERGY)
|
|
else:
|
|
target.call("take_damage", damage)
|
|
queue_free()
|