96 lines
2.5 KiB
GDScript
96 lines
2.5 KiB
GDScript
class_name FlyAbility extends RunnerAbility
|
|
|
|
const LIFT_SCALE: float = 10000.0
|
|
const TILT_LIFT_SCALE: float = 13.0
|
|
const MAX_BACKWARD_IMPETUS: float = 0.5
|
|
|
|
@export var tilt: float = 0.375
|
|
@export var thrust: float = 0.5
|
|
@export var lift: float = 1.0
|
|
|
|
var saved_gravity_scale: float = -1.0
|
|
var saved_deceleration: float = -1.0
|
|
var saved_speed_cap: float = -1.0
|
|
|
|
func begin(runner: Runner) -> void:
|
|
if runner.floor_normal.is_zero_approx():
|
|
saved_gravity_scale = runner.gravity_scale
|
|
saved_deceleration = runner.run_deceleration
|
|
saved_speed_cap = runner.top_run_speed
|
|
runner.gravity_scale /= 4.0
|
|
runner.run_deceleration = 0.0
|
|
runner.top_run_speed = INF
|
|
else:
|
|
runner.change_state(&'jump')
|
|
|
|
func integrate_forces(
|
|
runner: Runner,
|
|
body_state: PhysicsDirectBodyState3D
|
|
) -> void:
|
|
if not runner.floor_normal.is_zero_approx():
|
|
runner.change_state(&'fall')
|
|
elif not runner.wall_normal.is_zero_approx():
|
|
runner.change_state(&'wall_slide')
|
|
else:
|
|
body_state.linear_velocity -= (
|
|
impetus_multiplier *
|
|
runner.impetus.project(runner.basis.z) *
|
|
runner.run_acceleration *
|
|
body_state.step
|
|
)
|
|
var speed_factor = (
|
|
body_state.linear_velocity.slide(
|
|
Vector3.UP
|
|
).length() /
|
|
saved_speed_cap
|
|
)
|
|
var local_impetus := runner.impetus*runner.basis
|
|
var real_tilt: float = local_impetus.z*tilt/(
|
|
1.0 + lift*TILT_LIFT_SCALE*(speed_factor**2.0)
|
|
)
|
|
if real_tilt < 0.0:
|
|
runner.up_normal = runner.up_normal.lerp(
|
|
Vector3.UP - runner.basis.z, -real_tilt
|
|
).normalized()
|
|
else:
|
|
runner.up_normal = runner.up_normal.lerp(
|
|
Vector3.UP + runner.basis.z, real_tilt
|
|
).normalized()
|
|
body_state.linear_velocity = (
|
|
body_state.linear_velocity.slide(Vector3.UP)
|
|
)
|
|
body_state.linear_velocity += (
|
|
runner.basis.z *
|
|
thrust *
|
|
runner.run_acceleration *
|
|
max(local_impetus.z, -MAX_BACKWARD_IMPETUS) *
|
|
body_state.step
|
|
)
|
|
body_state.linear_velocity -= (
|
|
Vector3.UP *
|
|
lift*LIFT_SCALE *
|
|
real_tilt *
|
|
(speed_factor**2.0) *
|
|
body_state.step
|
|
)
|
|
|
|
func orientation(runner: Runner) -> Vector3:
|
|
return runner.linear_velocity
|
|
|
|
func animation_speed(runner: Runner) -> float:
|
|
return 1.0 + runner.linear_velocity.length()/10.0
|
|
|
|
func end(runner: Runner) -> void:
|
|
if saved_gravity_scale > 0.0:
|
|
runner.gravity_scale = saved_gravity_scale
|
|
saved_gravity_scale = -1.0
|
|
if saved_deceleration > 0.0:
|
|
runner.run_deceleration = saved_deceleration
|
|
saved_deceleration = -1.0
|
|
if saved_speed_cap > 0.0:
|
|
runner.top_run_speed = saved_speed_cap
|
|
saved_speed_cap = -1.0
|
|
|
|
func on_repeated_input(runner: Runner) -> void:
|
|
runner.change_state(&'fall')
|