136 lines
4.0 KiB
GDScript3
136 lines
4.0 KiB
GDScript3
|
class_name RunnerController extends RunnerObserver
|
||
|
|
||
|
const BASE_ZOOM_SPEED: float = 0.125
|
||
|
const MOUSE_WHEEL_BIAS: float = 8.0
|
||
|
const MAX_VERTICAL_ALIGNMENT: float = 0.75
|
||
|
const LOOK_IMPETUS_LERP_WEIGHT: float = 0.125
|
||
|
|
||
|
var control_enabled: bool
|
||
|
|
||
|
var look_impetus := Vector3.ZERO
|
||
|
var look_impetus_target := Vector3.ZERO
|
||
|
|
||
|
func _ready() -> void:
|
||
|
super()
|
||
|
control_enabled = true
|
||
|
|
||
|
func switch_runner(whom: Runner, distance: float = DEFAULT_DISTANCE) -> void:
|
||
|
if runner:
|
||
|
runner.remove_from_group(&'player')
|
||
|
super(whom, distance)
|
||
|
if runner:
|
||
|
runner.add_to_group(&'player')
|
||
|
|
||
|
func _would_be_responsive_if_current() -> bool:
|
||
|
return runner and control_enabled and not target_override
|
||
|
|
||
|
func _is_responsive() -> bool:
|
||
|
return current and _would_be_responsive_if_current()
|
||
|
|
||
|
func _unhandled_input(event: InputEvent) -> void:
|
||
|
if _is_responsive():
|
||
|
var iemm := event as InputEventMouseMotion
|
||
|
var iemb := event as InputEventMouseButton
|
||
|
if iemm and Options.mouselook:
|
||
|
var dy: float = iemm.relative.y
|
||
|
if Options.invert_mouselook:
|
||
|
dy = -dy
|
||
|
var align: float = maintain_direction.dot(up_normal)
|
||
|
if (
|
||
|
(dy > 0.0 and align < -MAX_VERTICAL_ALIGNMENT) or
|
||
|
(dy < 0.0 and align > MAX_VERTICAL_ALIGNMENT/2.0)
|
||
|
):
|
||
|
dy = 0.0
|
||
|
var dx: float = iemm.relative.x
|
||
|
look_impetus_target += (
|
||
|
basis.y*dy - basis.x*dx
|
||
|
).limit_length()*Options.mouse_sensitivity*(
|
||
|
maintain_distance/FX.DEFAULT_CAMERA_DISTANCE
|
||
|
)
|
||
|
if iemb and Options.mouselook:
|
||
|
match iemb.button_index:
|
||
|
MOUSE_BUTTON_WHEEL_UP:
|
||
|
maintain_distance = max(
|
||
|
maintain_distance - (
|
||
|
BASE_ZOOM_SPEED *
|
||
|
MOUSE_WHEEL_BIAS *
|
||
|
Options.mouse_wheel_sensitivity
|
||
|
)*(
|
||
|
-1.0 if Options.invert_mouse_wheel
|
||
|
else 1.0
|
||
|
),
|
||
|
0.0
|
||
|
)
|
||
|
MOUSE_BUTTON_WHEEL_DOWN:
|
||
|
maintain_distance = max(
|
||
|
maintain_distance + (
|
||
|
BASE_ZOOM_SPEED *
|
||
|
MOUSE_WHEEL_BIAS *
|
||
|
Options.mouse_wheel_sensitivity
|
||
|
)*(
|
||
|
-1.0 if Options.invert_mouse_wheel
|
||
|
else 1.0
|
||
|
),
|
||
|
0.0
|
||
|
)
|
||
|
_: pass
|
||
|
if event.is_action_released(&'pause'):
|
||
|
UI.Call(load("res://ui/OptionsMenu/OptionsMenu.tscn"))
|
||
|
get_viewport().set_input_as_handled()
|
||
|
elif runner.state != &'knockback' and runner.state != &'taunt':
|
||
|
if event.is_action_pressed(&'jump'):
|
||
|
runner.jump()
|
||
|
get_viewport().set_input_as_handled()
|
||
|
elif event.is_action_released(&'jump'):
|
||
|
runner.cancel_jump()
|
||
|
get_viewport().set_input_as_handled()
|
||
|
elif event.is_action_pressed(&'ability'):
|
||
|
runner.do_ability()
|
||
|
get_viewport().set_input_as_handled()
|
||
|
|
||
|
func _accept_analog_input() -> void:
|
||
|
if _is_responsive():
|
||
|
var dy: float = Input.get_axis(&'look_down', &'look_up')
|
||
|
if Options.invert_right_stick:
|
||
|
dy = -dy
|
||
|
var align: float = maintain_direction.dot(up_normal)
|
||
|
if (
|
||
|
(dy > 0.0 and align < -MAX_VERTICAL_ALIGNMENT) or
|
||
|
(dy < 0.0 and align > MAX_VERTICAL_ALIGNMENT/2.0)
|
||
|
):
|
||
|
dy = 0.0
|
||
|
var dx: float = Input.get_axis(&'look_left', &'look_right')
|
||
|
look_impetus_target += (
|
||
|
basis.y*dy - basis.x*dx
|
||
|
).limit_length()*Options.right_stick_sensitivity*(
|
||
|
maintain_distance/FX.DEFAULT_CAMERA_DISTANCE
|
||
|
)
|
||
|
look_impetus = look_impetus.lerp(
|
||
|
look_impetus_target, LOOK_IMPETUS_LERP_WEIGHT
|
||
|
)
|
||
|
_try_go(global_position + look_impetus)
|
||
|
if Input.is_action_pressed(&'zoom_in'):
|
||
|
maintain_distance = max(maintain_distance - BASE_ZOOM_SPEED, 0.0)
|
||
|
if Input.is_action_pressed(&'zoom_out'):
|
||
|
maintain_distance += BASE_ZOOM_SPEED
|
||
|
if runner.state != &'knockback' and runner.state != &'taunt':
|
||
|
var raw_impetus := Vector3(
|
||
|
Input.get_axis(&'move_left', &'move_right'),
|
||
|
0.0,
|
||
|
Input.get_axis(&'move_forward', &'move_back')
|
||
|
).limit_length()
|
||
|
if not raw_impetus.is_zero_approx():
|
||
|
runner.impetus = (
|
||
|
(basis*raw_impetus).slide(runner.up_normal).normalized()
|
||
|
)*raw_impetus.length()
|
||
|
look_impetus_target = Vector3.ZERO
|
||
|
|
||
|
func _update_mouselook_requested() -> void:
|
||
|
if current:
|
||
|
Options.mouselook_requested = _would_be_responsive_if_current()
|
||
|
|
||
|
func _physics_process(delta: float) -> void:
|
||
|
_update_mouselook_requested()
|
||
|
_accept_analog_input()
|
||
|
super(delta)
|