This repository has been archived on 2022-01-09. You can view files and clone it, but cannot push or open issues/pull-requests.
liblast/Game/Assets/Weapons/Projectile.gd

123 lines
4.0 KiB
GDScript

extends Node3D
@export var hit_effect_scene : PackedScene
@export var speed : float
var damage : int
var source_position : Vector3
var player
var time := 0.0
#var active := true
@onready var halo = $Halo
@onready var halo_size = halo.mesh.size
@onready var halo_transform = halo.global_transform
@export var halo_color : Color
var ray_previously : bool = false
# 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():
halo.mesh = halo.mesh.duplicate()
var halo_material = halo.mesh.surface_get_material(0).duplicate()
halo.set_surface_override_material(0, halo_material)
#$OmniLight3D/Smoke.emitting = true
func _physics_process(delta):
if $Body.test_move($Body.global_transform, Vector3.FORWARD * speed):
var hit_normal = global_transform.origin - source_position # is this correct?
give_damage(null, global_transform.origin,hit_normal, damage, source_position, Globals.DamageType.EXPLOSION, 100)
terminate()
else:
translate_object_local(Vector3.FORWARD * speed * delta)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
$Rocket.rotate_z(delta * 4)
time += delta
var flicker = sin(time * 125) + sin(time * 180) / 2 + sin(time * 295) / 3
$OmniLight3D.light_energy = 3 + flicker /2
halo.mesh.size = halo_size * 1.5 + Vector2(flicker, flicker) / 8
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 = [$Area3D, get_viewport().get_camera_3d().get_parent().get_parent()]
var ray = space_state.intersect_ray(physics_ray_query_parameters_3d)
#print(ray)
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
if halo.visible:
var fade = 1 - clamp(pow(physics_ray_query_parameters_3d.from.distance_to(physics_ray_query_parameters_3d.to), 1.5) / 800, 0, 1)
#print(fade)
halo.get_surface_override_material(0)["albedo_color"] = halo_color * fade
func give_damage(target: Node, hit_position: Vector3, hit_normal: Vector3, damage: int, source_position: Vector3, type: Globals.DamageType, push: float):
if target:
if target.has_method(&'take_damage'): # we've hit a player or something else - they will handle everything like effects etc.
target.rpc(&'take_damage',get_multiplayer_authority(), hit_position, hit_normal, damage, source_position, type, push)
# 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 = global_transform.origin
#print(impact_vfx.global_transform)
var result = hit_effect.look_at(source_position)
if not result: # if the look_at failed (as it will on floors and ceilings) try another approach:
hit_effect.look_at(source_position, Vector3.LEFT)
hit_effect.rotate(hit_normal, randf_range(0, PI * 2))
rpc(&'terminate') # doesn't work!
#print(impact_vfx.global_transform)
@rpc(any_peer, call_local, reliable) func terminate() -> void: # cleanly end the rocket's life
set_physics_process(false)
halo.hide()
$OmniLight3D.hide()
$Smoke.emitting = false
$Area3D.set_deferred("monitoring",false)
$Rocket.hide()
$AmbientSound.stop()
$Timer2.start()
func _on_Area3D_body_entered(body):
if is_multiplayer_authority(): # only do this on the attacker's local instance of the game
var hit_normal = body.global_transform.origin - global_transform.origin # is this correct?
# direct hit
give_damage(body, global_transform.origin, hit_normal,damage , source_position, Globals.DamageType.EXPLOSION, 100)
terminate()
func _on_Timer_timeout():
queue_free()
func _on_Timer2_timeout():
queue_free()