road-rage-tank/enemies/charging_car/charger_behavior.gd

98 lines
2.5 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()
enemy.invulnerable = true
func _end_charge() -> void:
charge_clock = 0.
cooldown = CHARGE_COOLDOWN
enemy.default_movement = true
enemy.set_collision_mask_value(4, true)
enemy.invulnerable = false
%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