frame-of-mind/src/logic-scenes/player_controller/player_controller.gd

220 lines
7.7 KiB
GDScript3
Raw Normal View History

2023-03-06 14:06:36 +00:00
extends RigidBody3D
var has_stage: bool = false:
2024-09-15 09:30:31 +00:00
set(on_stage):
print("%s player controller take stage" % "True: " if on_stage else "false")
2024-09-15 09:30:31 +00:00
if has_stage != on_stage:
if on_stage:
has_stage = true
if is_inside_tree():
camera.make_current()
get_viewport().gui_release_focus()
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
var jitter_tween: Tween = create_tween()
jitter_tween.tween_property(self, "jitter_strength", 1, 1)
if has_entered: emit_signal("ui_exited")
elif has_stage:
camera.current = true
jitter_strength = 1
else:
if is_inside_tree() and has_stage:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
var jitter_tween: Tween = create_tween()
jitter_tween.tween_property(self, "jitter_strength", 0, 0.5)
if has_entered: emit_signal("ui_exited")
else:
jitter_strength = 0
has_stage = false
print("player controller %s take stage" % "did" if has_stage else "didn't")
2024-09-15 09:30:31 +00:00
sleeping = has_stage
2025-02-06 18:15:39 +00:00
@export var mouse_sensitivity: Vector2 = Vector2(6, 5)
2023-03-06 14:06:36 +00:00
@export_range (0, 10) var max_speed: float = 3
@export_range (0, 10) var max_acceleration: float = 5
@export_range (0, 20) var damp: float = 10
@export_range (0.1, 1) var mouse_jerk:float = 0.5
@export_range (10, 100) var gamepad_response = 50
@export_range (50, 500) var mouse_jerk_rejection = 200
@export var max_angle:float = 75
@export var camera_jitter_speed:float = 3
@export var angular_jitter:Vector3 = Vector3(0.1, 0, 0.05)
@export var angular_jitter_speed:Vector3 = Vector3(2, 1, 1)
@export var location_jitter:Vector3 = Vector3(0.05, 0.05, 0.05)
@export var location_jitter_speed:Vector3 = Vector3(2, 0.3, 1)
var jitter_strength: float = 0
2023-03-06 14:06:36 +00:00
var loc_noise_spot: Vector3 = Vector3.ZERO
var rot_noise_spot: Vector3 = Vector3.ZERO
var rotation_speed: Vector2 = Vector2.ZERO
var current_mouse_rotation: Vector2 = Vector2.ZERO
2025-02-06 18:15:39 +00:00
2023-03-06 14:06:36 +00:00
var noise: Noise = FastNoiseLite.new()
var crouched:bool = false
var on_crouch_cooldown:bool = false
2023-03-06 14:06:36 +00:00
@onready var yaw:Node3D = $Yaw
@onready var pitch:Node3D = $Yaw/Pitch
@onready var mount:Node3D = $Yaw/Pitch/Mount
@onready var camera:Camera3D = $Yaw/Pitch/Mount/Camera3D
@onready var focus_ray: RayCast3D = $Yaw/Pitch/Mount/Camera3D/RayCast3D
2023-03-06 14:06:36 +00:00
2025-02-06 18:15:39 +00:00
var zoomed:bool = false:
2024-09-15 09:30:31 +00:00
set(zoom):
if zoomed != zoom:
if zoom:
var zoom_tween = create_tween()
zoom_tween.tween_property(camera, "fov", camera.fov*0.5, 0.5)
else:
var zoom_tween = create_tween()
2025-02-06 18:15:39 +00:00
zoom_tween.tween_property(camera, "fov", camera.fov*2.0, 0.5)
2024-09-15 09:30:31 +00:00
zoomed = zoom
signal ui_entered
var has_entered:bool = false
signal ui_exited
2023-03-06 14:06:36 +00:00
func _ready():
2024-09-15 09:30:31 +00:00
_handle_jitter(0)
2025-02-06 18:15:39 +00:00
2024-09-15 09:30:31 +00:00
2023-07-11 08:57:19 +00:00
func _process(_delta):
2024-09-15 09:30:31 +00:00
if focus_ray.get_collider() != null and not has_entered:
emit_signal("ui_entered")
has_entered = true
focus_ray.get_collider().reveal()
if has_stage:
if has_entered:
if focus_ray.get_collider() == null:
emit_signal("ui_exited")
has_entered = false
if Input.is_action_just_pressed("ui_accept"):
State.pass_stage_to(focus_ray.get_collider())
else:
if Input.is_action_just_pressed("zoom_in_controller"):
zoomed = true
elif Input.is_action_just_released("zoom_in_controller"):
zoomed = false
2023-03-06 14:06:36 +00:00
func _physics_process(delta:float):
2024-09-15 09:30:31 +00:00
if has_stage:
_handle_movement(delta)
_handle_rotation(delta)
if jitter_strength > 0 and not State.reduce_motion: _handle_jitter(delta)
2023-03-06 14:06:36 +00:00
func _handle_movement(delta:float):
2024-09-15 09:30:31 +00:00
var input:Vector2 = Vector2(Input.get_action_strength("player_right") - Input.get_action_strength("player_left"),
Input.get_action_strength("player_backwards")*0.8 - Input.get_action_strength("player_forwards"))
if input.length()>1:
input = input.normalized()
var direction: Vector3 = Vector3(input.x, 0, input.y)
direction = yaw.global_transform.basis.x * direction.x + transform.basis.y * direction.y + yaw.global_transform.basis.z * direction.z
if linear_velocity.length() > (linear_velocity + (direction*max_speed - linear_velocity)).length():
direction = Vector3.ZERO
else:
direction *= (direction*max_speed - linear_velocity).length()*max_acceleration
linear_damp = damp * max(0.5, 1 - input.length())
apply_central_impulse(direction*delta)
2023-03-06 14:06:36 +00:00
func _handle_rotation(delta:float):
2024-09-15 09:30:31 +00:00
var smoothness = min(3, 60.0/Engine.get_frames_per_second())
var input_speed = Vector2( Input.get_action_strength("look_right")-Input.get_action_strength("look_left"), Input.get_action_strength("look_up")-Input.get_action_strength("look_down")) * gamepad_response
if current_mouse_rotation.length()>0:
input_speed = current_mouse_rotation
current_mouse_rotation = Vector2.ZERO
rotation_speed = rotation_speed * (1-mouse_jerk*smoothness) + input_speed * mouse_jerk * smoothness
if rotation_speed.y > 0 and pitch.rotation_degrees.x < 0:
rotation_speed.y *= 1-pow(pitch.rotation_degrees.x/-max_angle, 4)
elif rotation_speed.y < 0 and pitch.rotation_degrees.x > 0 :
rotation_speed.y *= 1-pow(pitch.rotation_degrees.x/max_angle, 4)
yaw.rotate_y(deg_to_rad(-rotation_speed.x * delta * mouse_sensitivity.x))
pitch.rotate_x(deg_to_rad(-rotation_speed.y * delta * mouse_sensitivity.y))
2023-03-06 14:06:36 +00:00
func _handle_jitter(delta):
2024-09-15 09:30:31 +00:00
loc_noise_spot += Vector3(delta * camera_jitter_speed * location_jitter_speed)
rot_noise_spot += Vector3(delta * camera_jitter_speed * angular_jitter_speed)
pitch.position = Vector3(
noise.get_noise_1d(loc_noise_spot.x),
noise.get_noise_1d(loc_noise_spot.y),
noise.get_noise_1d(loc_noise_spot.z)
) * location_jitter * jitter_strength
if not State.reduce_motion: mount.rotation = Vector3(
noise.get_noise_1d(rot_noise_spot.x),
noise.get_noise_1d(rot_noise_spot.y),
noise.get_noise_1d(rot_noise_spot.z)
) * angular_jitter * jitter_strength
2023-03-06 14:06:36 +00:00
func _handle_mouse_input(event:InputEventMouseMotion):
2024-09-15 09:30:31 +00:00
if event.relative.length() < mouse_jerk_rejection:
current_mouse_rotation = event.relative
2023-03-06 14:06:36 +00:00
func _input(event:InputEvent):
if get_parent().get_parent().dnd: return
if has_stage and Scenes.current_sequence == -1:
2024-09-15 09:30:31 +00:00
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
_handle_mouse_input(event)
get_viewport().set_input_as_handled()
if event is InputEventMouseButton and event.pressed:
if Input.is_action_just_pressed("zoom_in_mouse"):
zoomed = true
elif Input.is_action_just_pressed("zoom_out_mouse"):
zoomed = false
#FIXME remove this if it has been determined that this kind of reveal all is no longer planned.
#else:
#State.free_focus()
#get_tree().call_group("interactables", "reveal")
if event.is_action_pressed("collect_memento_ui") or event.is_action_pressed("option_memento_ui"):
focus_ray.get_collider().handle(event)
get_viewport().set_input_as_handled()
#FIXME this code jeets focxus back to the player, but I think it may be an anti-pattern.
#else:
# if event is InputEventMouseButton:
# if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
# if !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
# State.take_stage(self, true)
# get_tree().call_group("interactables", "collapse")
2023-03-06 14:06:36 +00:00
func play_scene(id: int, _repeat):
2024-09-15 09:30:31 +00:00
if id == Scenes.id.YOUTH_DRAEVEN:
var rotation_tween = create_tween()
2023-07-17 12:16:12 +00:00
func scene_finished(_id, repeat: bool):
2024-09-15 09:30:31 +00:00
if repeat:
State.take_stage(self, true)
func _on_bed_enter(_body):
2024-09-15 09:30:31 +00:00
if not (crouched or on_crouch_cooldown):
$PlayerAnimationPlayer.queue("crouch")
var tween = create_tween()
tween.tween_property(self, "max_speed", max_speed/2, 0.3)
crouched = true
2023-03-06 14:06:36 +00:00
func _on_bed_exit(_body):
2024-09-15 09:30:31 +00:00
if crouched:
crouched = false
$PlayerAnimationPlayer.queue("stand_up")
var tween = create_tween()
tween.tween_property(self, "max_speed", max_speed*2, 1)
on_crouch_cooldown = true
await get_tree().create_timer(1.0).timeout
on_crouch_cooldown = false