grunk/src/player/player.gd

130 lines
3.3 KiB
GDScript3
Raw Normal View History

2025-02-28 15:20:52 -07:00
class_name Player extends CharacterBody3D
2025-03-09 16:40:19 -06:00
const FOCUS_SPEED := 30.0
2025-02-28 15:20:52 -07:00
const RUN_SPEED := 80.0
const SPRINT_SPEED := 160.0
2025-03-01 14:40:02 -07:00
const AIR_SPEED := 10.0
2025-03-28 16:16:43 -06:00
2025-02-28 15:20:52 -07:00
const JUMP_FORCE := 4.5
2025-03-28 16:16:43 -06:00
2025-02-28 15:20:52 -07:00
const GROUND_FRICTION := 0.3
const AIR_FRICTION := 0.03
2025-03-21 12:07:05 -06:00
@export var inventory: Dictionary[Item, int] = {}
2025-02-28 15:20:52 -07:00
var gravity: Vector3 = (
ProjectSettings.get_setting("physics/3d/default_gravity")
* ProjectSettings.get_setting("physics/3d/default_gravity_vector")
)
2025-03-05 14:46:13 -07:00
var selected_interactive: Interactive
2025-03-05 16:11:03 -07:00
var firing := false
2025-03-05 14:46:13 -07:00
2025-03-20 22:45:19 -06:00
@onready var hud: PlayerHUD = %PlayerHUD
2025-03-05 14:46:13 -07:00
2025-03-05 16:11:03 -07:00
@onready var camera_pivot: CameraController = %CameraPivot
2025-03-05 14:46:13 -07:00
@onready var interact_ray: RayCast3D = %InteractRay
2025-03-01 14:40:02 -07:00
2025-03-12 12:19:09 -06:00
@onready var tool_mount: ToolMount = %ToolMount
@onready var point_spray: PointSpray = %PointSpray
@onready var wide_spray: WideSpray = %WideSpray
2025-03-13 10:29:25 -06:00
@onready var toothbrush: Tool = %Toothbrush
2025-03-12 12:19:09 -06:00
2025-03-20 22:45:19 -06:00
## Global static access to player singleton
static var instance: Player
func _ready() -> void:
instance = self
2025-02-28 15:20:52 -07:00
func get_speed() -> float:
if is_on_floor():
2025-03-07 12:18:30 -07:00
if firing:
return FOCUS_SPEED
2025-03-09 16:40:19 -06:00
if Input.is_action_pressed("sprint"):
2025-02-28 15:20:52 -07:00
return SPRINT_SPEED
return RUN_SPEED
return AIR_SPEED
func get_friction() -> float:
if is_on_floor():
return GROUND_FRICTION
return AIR_FRICTION
2025-03-12 12:19:09 -06:00
func get_tool() -> Tool:
return tool_mount.get_active()
2025-03-01 14:40:02 -07:00
2025-03-21 12:07:05 -06:00
## Add the given item to the player's inventory.
func add_item(item: Item, amount: int = 1) -> void:
inventory[item] = inventory.get(item, 0) + amount
## Remove the given item from the player's inventory.
func remove_item(item: Item, amount: int = 1) -> void:
inventory[item] = inventory.get(item, 0) - amount
if inventory[item] <= 0:
inventory.erase(item)
2025-02-28 15:20:52 -07:00
func _physics_process(delta: float) -> void:
2025-03-05 15:35:49 -07:00
# Will be null if no valid interactor is selected.
var interactive: Interactive = interact_ray.get_collider() as Interactive
2025-03-20 22:45:19 -06:00
hud.select_interactive(interactive)
2025-03-21 12:07:05 -06:00
if interactive:
interactive.select()
2025-03-05 15:35:49 -07:00
2025-03-12 12:19:09 -06:00
# World interaction
2025-03-05 15:35:49 -07:00
if interactive and Input.is_action_just_pressed("interact"):
interactive.activate()
2025-03-05 14:46:13 -07:00
2025-03-12 12:19:09 -06:00
# Tool selection
if Input.is_action_just_pressed("select_next_tool"):
tool_mount.set_active_relative(1)
elif Input.is_action_just_pressed("select_prev_tool"):
tool_mount.set_active_relative(-1)
elif Input.is_action_just_pressed("select_point_spray"):
tool_mount.set_active(point_spray)
elif Input.is_action_just_pressed("select_wide_spray"):
tool_mount.set_active(wide_spray)
2025-03-13 10:29:25 -06:00
elif Input.is_action_just_pressed("select_brush"):
tool_mount.set_active(toothbrush)
2025-03-12 12:19:09 -06:00
# Tool use
2025-03-01 14:40:02 -07:00
if Input.is_action_pressed("fire"):
get_tool().fire()
2025-03-05 16:11:03 -07:00
firing = true
2025-03-01 14:40:02 -07:00
else:
get_tool().idle()
2025-03-05 16:11:03 -07:00
firing = false
2025-03-01 14:40:02 -07:00
if Input.is_action_just_pressed("switch_mode"):
get_tool().switch_mode()
2025-02-28 15:20:52 -07:00
# Gravity
if not is_on_floor():
velocity += gravity * delta
# Input movement
var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
var direction := (
(camera_pivot.global_basis * Vector3(input_dir.x, 0, input_dir.y) * Vector3(1, 0, 1))
. normalized()
)
var movement := direction * get_speed() * delta
velocity.x += movement.x
velocity.z += movement.z
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_FORCE
# Friction
var friction := get_friction()
velocity.x = lerpf(velocity.x, 0, friction)
velocity.z = lerpf(velocity.z, 0, friction)
move_and_slide()