55 lines
1.4 KiB
GDScript
55 lines
1.4 KiB
GDScript
class_name AttackAbility extends RunnerAbility
|
|
|
|
const KNOCKBACK_ATTENUATION: float = 0.125
|
|
|
|
@export var power: float = 50.0
|
|
@export var duration: float = 0.5
|
|
@export var slowdown_factor: float = 2.0
|
|
@export var cooldown: float = 0.25
|
|
@export var hit_sound: AudioStream
|
|
|
|
var timer: float = 0.0
|
|
|
|
func begin(runner: Runner) -> void:
|
|
timer = duration
|
|
runner.linear_velocity /= slowdown_factor
|
|
|
|
func integrate_forces(
|
|
runner: Runner,
|
|
body_state: PhysicsDirectBodyState3D
|
|
) -> void:
|
|
if timer <= 0.0:
|
|
runner.change_state(&'run')
|
|
else:
|
|
for i in body_state.get_contact_count():
|
|
var other := (
|
|
body_state.get_contact_collider_object(i) as RigidBody3D
|
|
)
|
|
var other_runner = other as Runner
|
|
if other and not (other is Platform):
|
|
runner.audio_player.stream = hit_sound
|
|
runner.audio_player.play()
|
|
if other_runner:
|
|
if other_runner.state != &'ability':
|
|
other_runner.knockback(
|
|
runner.global_position,
|
|
runner.mass*power*KNOCKBACK_ATTENUATION
|
|
)
|
|
else:
|
|
other.apply_force(
|
|
runner.mass*(
|
|
runner.impetus + runner.up_normal
|
|
).normalized()*power,
|
|
body_state.get_contact_collider_position(i) -
|
|
other.global_position
|
|
)
|
|
|
|
func passive(_runner: Runner, delta: float, _active: bool) -> void:
|
|
timer -= delta
|
|
|
|
func available(_runner: Runner) -> bool:
|
|
return timer < -cooldown
|
|
|
|
func animation_speed(_runner: Runner) -> float:
|
|
return 2.0
|