+extends Node
+class_name PlayerModel
+
+
+@export_group("Movement")
+@export var walk_speed := 8.0
+@export var dash_length := 10.0
+@export var air_speed := 3.0
+@export var acceleration := 30.0
+@export var rotation_speed := 10.0
+@export var idle_timeout := 5.0
+
+var idle_time := 0.0
+var floor_normal := Vector3.ZERO
+var ground_slope_input := 0.0
+
+@onready var _player: Player = $".."
+@onready var _camera: Camera3D = %camera
+
+
+func get_velocity_by_input(input_pkt: InputPacket, delta: float) -> Vector3:
+ var new_velocity: Vector3 = _player.velocity
+
+ if _player.is_on_floor():
+ # Get the XZ input direction based on player's input relative to the camera
+ var forward := _camera.global_basis.z
+ var right := _camera.global_basis.x
+ var move_direction := (
+ forward * input_pkt.movement_direction.y + right * input_pkt.movement_direction.x
+ ).normalized()
+ move_direction.y = 0
+
+ # if we're not stuck, then it's okay to set the velocity
+ floor_normal = _player.get_floor_normal()
+ ground_slope_input = (PI / 2) - new_velocity.angle_to(floor_normal)
+ new_velocity = new_velocity.move_toward(
+ move_direction * (walk_speed + ground_slope_input * walk_speed),
+ acceleration * delta
+ )
+ else:
+ new_velocity += _player.get_gravity() * air_speed * delta
+
+ return new_velocity