96 lines
2.4 KiB
GDScript
96 lines
2.4 KiB
GDScript
extends Node3D
|
|
|
|
@export var noise: FastNoiseLite
|
|
|
|
@onready var enemy: PoliceCar = get_parent()
|
|
|
|
const CHARGE_COOLDOWN := 5. # time charger has to wait between charges before being able to charge again
|
|
const CHARGE_COOLUP := 0.5 # time the charger has to see the player before charging
|
|
|
|
const CHARGE_SPEED := 50.
|
|
const HOLD_TIME := 1.
|
|
const CHARGE_TIME := 16. / CHARGE_SPEED
|
|
|
|
var cooldown := 0.
|
|
var coolup := 0.
|
|
|
|
var charge_clock := 0.
|
|
|
|
func _start_charge() -> void:
|
|
charge_clock = 0.
|
|
|
|
enemy.default_movement = false
|
|
enemy.velocity = global_position.direction_to(Player.instance.global_position)
|
|
enemy.velocity *= CHARGE_SPEED
|
|
enemy.set_rotation_to_velocity()
|
|
|
|
func _end_charge() -> void:
|
|
charge_clock = 0.
|
|
cooldown = CHARGE_COOLDOWN
|
|
|
|
enemy.default_movement = true
|
|
enemy.set_collision_mask_value(4, true)
|
|
|
|
%KnockUpArea.monitoring = false
|
|
%Meshes.position = Vector3.ZERO
|
|
|
|
func _not_charging_process(delta: float) -> void:
|
|
cooldown -= delta
|
|
if cooldown > 0.: return
|
|
|
|
var player_pos := Player.instance.global_position
|
|
|
|
if global_position.distance_to(player_pos) > 15.:
|
|
print("too far")
|
|
coolup = 0.
|
|
return
|
|
|
|
var params := PhysicsRayQueryParameters3D.create(
|
|
global_position, player_pos, 4294967295, [enemy]
|
|
)
|
|
var raycast := get_world_3d().direct_space_state.intersect_ray(params)
|
|
|
|
if not raycast.is_empty() and raycast.collider is Player:
|
|
coolup += delta
|
|
if coolup > CHARGE_COOLUP:
|
|
_start_charge()
|
|
else:
|
|
print("raycast failed")
|
|
coolup = 0.
|
|
|
|
func _charging_process(delta: float) -> void:
|
|
charge_clock += delta
|
|
if charge_clock > HOLD_TIME + CHARGE_TIME:
|
|
_end_charge()
|
|
return
|
|
|
|
if charge_clock < HOLD_TIME:
|
|
var x := noise.get_noise_1d(charge_clock * 10000)
|
|
var y := noise.get_noise_1d(-charge_clock * 10000)
|
|
%Meshes.position = Vector3(x, 0, y)
|
|
else:
|
|
%KnockUpArea.monitoring = true
|
|
enemy.set_collision_mask_value(4, false)
|
|
|
|
enemy.move_and_slide()
|
|
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
if enemy.default_movement:
|
|
_not_charging_process(delta)
|
|
else:
|
|
_charging_process(delta)
|
|
|
|
|
|
func _on_knock_up_area_body_entered(body: Node3D) -> void:
|
|
if body is PoliceCar and body != enemy and body.default_movement:
|
|
var e := body as PoliceCar
|
|
|
|
e.stunned = true
|
|
var t := e.create_tween()
|
|
t.set_trans(Tween.TRANS_QUAD)
|
|
t.tween_property(e, "position:y", e.position.y + 7.5, .6).set_ease(Tween.EASE_OUT)
|
|
t.tween_property(e, "position:y", e.position.y, .6).set_ease(Tween.EASE_IN)
|
|
await t.finished
|
|
e.stunned = false
|