91 lines
3.0 KiB
GDScript
91 lines
3.0 KiB
GDScript
extends Node3D
|
|
|
|
@export var hit_effect_scene : PackedScene
|
|
@export var speed : float
|
|
@export var damage : int
|
|
|
|
var source_position : Vector3
|
|
|
|
var noise = OpenSimplexNoise.new()
|
|
var time := 0.0
|
|
|
|
@onready var halo = $OmniLight3D/Halo
|
|
@onready var halo_transform = halo.global_transform
|
|
|
|
var ray_previously : bool
|
|
|
|
# Declare member variables here. Examples:
|
|
# var a = 2
|
|
# var b = "text"
|
|
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready():
|
|
#$OmniLight3D/Smoke.emitting = true
|
|
|
|
noise.octaves = 2
|
|
noise.persistence = 0.8
|
|
noise.period = 16
|
|
noise.seed = randi()
|
|
|
|
func _physics_process(delta):
|
|
#constant_linear_velocity = Vector3(1, 0, 0)
|
|
translate_object_local(Vector3.FORWARD * speed * delta)
|
|
|
|
# move_and_collide(global_transform.basis.x * Vector3.FORWARD * speed)
|
|
|
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
func _process(delta):
|
|
time += delta
|
|
|
|
var flicker = sin(time * 225) + sin(time * 240) / 2 + sin(time * 295) / 3
|
|
|
|
$OmniLight3D.light_energy = 3 + flicker /2
|
|
halo.mesh.size = Vector2.ONE * 2 + Vector2(flicker, flicker) / 16
|
|
|
|
var space_state = get_world_3d().direct_space_state
|
|
var physics_ray_query_parameters_3d = PhysicsRayQueryParameters3D.new()
|
|
physics_ray_query_parameters_3d.from = halo.global_transform.origin
|
|
physics_ray_query_parameters_3d.to = get_viewport().get_camera_3d().global_transform.origin
|
|
physics_ray_query_parameters_3d.exclude = [self]
|
|
var ray = space_state.intersect_ray(physics_ray_query_parameters_3d)
|
|
|
|
if ray.size() > 0 and not ray_previously:
|
|
halo.hide()
|
|
elif not ray.size() > 0 and ray_previously:
|
|
halo.show()
|
|
|
|
if ray.size() > 0:
|
|
ray_previously = true
|
|
else:
|
|
ray_previously = false
|
|
|
|
|
|
|
|
func give_damage(target: Node, hit_position: Vector3, hit_normal: Vector3, damage: int, source_position: Vector3, type: Globals.DamageType, push: float):
|
|
if target.has_method(&'take_damage'): # we've hit a player or something else - the ywill handle everything like effects etc.
|
|
target.rpc(&'take_damage', get_multiplayer_authority(), hit_position, hit_normal, damage, source_position, type, push)
|
|
else:
|
|
# TODO take data from the material of the target and spawn an appropriate hit effect
|
|
var hit_effect : Node = hit_effect_scene.instantiate()
|
|
get_tree().root.add_child(hit_effect)
|
|
|
|
hit_effect.global_transform.origin = hit_position
|
|
#print(impact_vfx.global_transform)
|
|
var result = hit_effect.look_at(hit_position + hit_normal)
|
|
|
|
if not result: # if the look_at failed (as it will on floors and ceilings) try another approach:
|
|
hit_effect.look_at(hit_position + hit_normal, Vector3.LEFT)
|
|
|
|
hit_effect.rotate(hit_normal, randf_range(0, PI * 2))
|
|
|
|
#print(impact_vfx.global_transform)
|
|
|
|
func _on_Area3D_body_entered(body):
|
|
var hit_normal = body.global_transform.origin - global_transform.origin # is this correct?
|
|
give_damage(body, global_transform.origin, hit_normal,damage, source_position, Globals.DamageType.EXPLOSION, 100)
|
|
queue_free()
|
|
|
|
func _on_Timer_timeout():
|
|
queue_free()
|