56 lines
1.7 KiB
GDScript
56 lines
1.7 KiB
GDScript
extends Node3D
|
|
## Visible, dodgeable Alien Grunt projectile. Swept ray prevents tunnelling.
|
|
const SPEED := 8.0
|
|
const LIFETIME := 3.0
|
|
var direction := Vector3.FORWARD
|
|
var damage := 8.0
|
|
var shooter: CharacterBody3D
|
|
var player: CharacterBody3D
|
|
var age := 0.0
|
|
var spent := false
|
|
|
|
func _ready() -> void:
|
|
add_to_group("boss_projectiles")
|
|
var model: Node3D = preload("res://assets/boss/hornet_textured.scn").instantiate()
|
|
add_child(model)
|
|
for area in model.find_children("*", "Area3D", true, false):
|
|
area.collision_layer = 0
|
|
area.collision_mask = 0
|
|
var anim := model.get_node_or_null("AnimationPlayer") as AnimationPlayer
|
|
if anim != null:
|
|
# The exported native scene already marks idle as looping.
|
|
anim.play("idle")
|
|
var mesh := SphereMesh.new()
|
|
mesh.radius = 0.055
|
|
mesh.height = 0.11
|
|
var glow := StandardMaterial3D.new()
|
|
glow.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
|
glow.albedo_color = Color(1, 0.7, 0.1)
|
|
mesh.material = glow
|
|
var marker := MeshInstance3D.new()
|
|
marker.mesh = mesh
|
|
marker.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
|
add_child(marker)
|
|
if direction.length_squared() > 0:
|
|
look_at(global_position + direction)
|
|
|
|
func _physics_process(dt: float) -> void:
|
|
if spent:
|
|
return
|
|
age += dt
|
|
if age >= LIFETIME or not is_instance_valid(shooter) or shooter.dead \
|
|
or not is_instance_valid(player) or player.hp <= 0:
|
|
queue_free()
|
|
return
|
|
var next := global_position + direction * SPEED * dt
|
|
var query := PhysicsRayQueryParameters3D.create(global_position, next, 1 | 2)
|
|
query.exclude = [shooter.get_rid()]
|
|
var hit := get_world_3d().direct_space_state.intersect_ray(query)
|
|
if not hit.is_empty():
|
|
spent = true
|
|
if hit.collider == player:
|
|
player.take_damage(damage)
|
|
queue_free()
|
|
else:
|
|
global_position = next
|