PneumaticPlaything/Scripts/Player/Player.gd
Persephone Bubblegum-Holiday a9efa66b09 dynamic menu and menu music
2025-08-18 21:51:12 -07:00

188 lines
6.5 KiB
GDScript

class_name Player extends CharacterBody3D
@export var current_map: String
var startPosition: Vector3
var SPEED_BASE: float = 2
var SPEED_CROUCHED: float = 1
var SPEED_RUNNING: float = 4
var SPEED_CROUCH_RUN: float = 2
var JUMP_HEIGHT_BASE: float = 0.6
var JUMP_HEIGHT_CROUCHED: float = 0.2
var JUMP_HEIGHT_RUNNING: float = 0.8
var JUMP_HEIGHT_CROUCH_RUN: float = 0.4
var speed: float = SPEED_BASE # m/s
var acceleration: float = 100 # m/s^2
var jump_height: float = JUMP_HEIGHT_BASE # m
var camera_sens: float = 3
var interact: bool = true
var jumping: bool = false
var crouched: bool = false
var running: bool = false
var mouse_captured: bool = false
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
var move_dir: Vector2 # Input direction for movement
var look_dir: Vector2 # Input direction for look/aim
var walk_vel: Vector3 # Walking velocity
var grav_vel: Vector3 # Gravity velocity
var jump_vel: Vector3 # Jumping velocity
@onready var camera: Camera3D = $Camera
func _ready() -> void:
capture_mouse()
if ($Camera.fov != GlobalVariables.FOV):
$Camera.fov = GlobalVariables.FOV
startPosition = self.position
func _unhandled_input(event: InputEvent) -> void:
if (interact):
if event is InputEventMouseMotion:
look_dir = event.relative * 0.001
if mouse_captured: _rotate_camera(GlobalVariables.mouse_sens)
if event.is_action_pressed(&"fullscreen"):
if (!DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN):
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
elif event.is_action_pressed(&"freeroam_open_menu"):
if (!interact):
interact = true
capture_mouse()
$InGameMenu.visible = false
else:
interact = false
release_mouse()
$InGameMenu.visible = true
$InGameMenu/Buttons/ReturnButton.grab_focus()
pass
elif event.is_action_pressed(&"freeroam_debug_menu"):
$DebugMenu.visible = !$DebugMenu.visible
elif event.is_action_pressed(&"freeroam_respawn"):
self.position = startPosition
elif event.is_action_pressed(&"freeroam_flashlight_zoom_in"):
if ($Camera/Flashlight.visible):
if ($Camera/Flashlight.spot_angle > 2):
$Camera/Flashlight.spot_angle -= 2
$FlashlightSizeSFX.pitch_scale = sqrt($Camera/Flashlight.spot_angle)-0.5
$FlashlightSizeSFX.play()
elif event.is_action_pressed(&"freeroam_flashlight_zoom_out"):
if ($Camera/Flashlight.visible):
if ($Camera/Flashlight.spot_angle < 88):
$Camera/Flashlight.spot_angle += 2
$FlashlightSizeSFX.pitch_scale = sqrt($Camera/Flashlight.spot_angle)-0.5
$FlashlightSizeSFX.play()
elif event.is_action_pressed(&"freeroam_flashlight_zoom_reset"):
if ($Camera/Flashlight.visible):
$Camera/Flashlight.spot_angle = 30
$FlashlightSizeSFX.pitch_scale = sqrt($Camera/Flashlight.spot_angle)-0.5
$FlashlightSizeSFX.play()
elif event.is_action_pressed(&"freeroam_camera_zoom_in"):
if ($Camera.fov > 2):
$Camera.fov -= 2
camera_sens = maxf(camera_sens - 0.1, 0.1)
elif event.is_action_pressed(&"freeroam_camera_zoom_out"):
if ($Camera.fov < 178):
$Camera.fov += 2
camera_sens = minf(camera_sens + 0.1, 3)
elif event.is_action_pressed(&"freeroam_camera_zoom_reset"):
$Camera.fov = GlobalVariables.FOV
camera_sens = 3
func _physics_process(delta: float) -> void:
if (interact):
if Input.is_action_just_pressed(&"freeroam_jump"): jumping = true
elif Input.is_action_just_pressed(&"freeroam_crouch"):
$CShape.shape.height = 1.0
$Camera.position.y = 1.0
if (running):
speed = SPEED_CROUCH_RUN
jump_height = JUMP_HEIGHT_CROUCH_RUN
else:
speed = SPEED_CROUCHED
jump_height = JUMP_HEIGHT_CROUCHED
crouched = true
elif Input.is_action_just_released(&"freeroam_crouch"):
$CShape.shape.height = 1.8
$Camera.position.y = 1.7
if (running):
speed = SPEED_RUNNING
jump_height = JUMP_HEIGHT_RUNNING
else:
speed = SPEED_BASE
jump_height = JUMP_HEIGHT_BASE
crouched = false
elif Input.is_action_just_pressed(&"freeroam_run"):
if (crouched):
speed = SPEED_CROUCH_RUN
jump_height = JUMP_HEIGHT_CROUCH_RUN
else:
speed = SPEED_RUNNING
jump_height = JUMP_HEIGHT_RUNNING
running = true
elif Input.is_action_just_released(&"freeroam_run"):
if (crouched):
speed = SPEED_CROUCHED
jump_height = JUMP_HEIGHT_CROUCHED
else:
speed = SPEED_BASE
jump_height = JUMP_HEIGHT_BASE
running = false
elif Input.is_action_just_pressed(&"freeroam_toggle_flashlight"):
$Camera/Flashlight.visible = !$Camera/Flashlight.visible
if ($Camera/Flashlight.visible): $FlashlightOnSFX.play()
else: $FlashlightOffSFX.play()
if mouse_captured: _handle_joypad_camera_rotation(delta, GlobalVariables.mouse_sens)
velocity = _walk(delta) + _gravity(delta) + _jump(delta)
move_and_slide()
if (self.position.y < -20):
jump_vel = Vector3(0, 50, 0)
$BoingSFX.play()
func capture_mouse() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
mouse_captured = true
func release_mouse() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
mouse_captured = false
func _rotate_camera(sens_mod: float = 1.0) -> void:
camera.rotation.y -= look_dir.x * camera_sens * sens_mod
camera.rotation.x = clamp(camera.rotation.x - look_dir.y * camera_sens * sens_mod, -1.5, 1.5)
func _handle_joypad_camera_rotation(delta: float, sens_mod: float = 1.0) -> void:
var joypad_dir: Vector2 = Input.get_vector(&"freeroam_look_left", &"freeroam_look_right", &"freeroam_look_up", &"freeroam_look_down")
if joypad_dir.length() > 0:
look_dir += joypad_dir * delta
_rotate_camera(sens_mod)
look_dir = Vector2.ZERO
func _walk(delta: float) -> Vector3:
move_dir = Input.get_vector(&"freeroam_move_left", &"freeroam_move_right", &"freeroam_move_forward", &"freeroam_move_backward")
var _forward: Vector3 = camera.global_transform.basis * Vector3(move_dir.x, 0, move_dir.y)
var walk_dir: Vector3 = Vector3(_forward.x, 0, _forward.z).normalized()
walk_vel = walk_vel.move_toward(walk_dir * speed * move_dir.length(), acceleration * delta)
return walk_vel
func _gravity(delta: float) -> Vector3:
grav_vel = Vector3.ZERO if is_on_floor() else grav_vel.move_toward(Vector3(0, velocity.y - gravity, 0), gravity * delta)
return grav_vel
func _jump(delta: float) -> Vector3:
if jumping:
if is_on_floor(): jump_vel = Vector3(0, sqrt(4 * jump_height * gravity), 0)
jumping = false
return jump_vel
jump_vel = Vector3.ZERO if is_on_floor() or is_on_ceiling_only() else jump_vel.move_toward(Vector3.ZERO, gravity * delta)
return jump_vel