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()