extends Node
class_name PlayerModel
+@onready var player: Player = $".."
+@onready var camera: Camera3D = %camera
-@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
+@onready var moves: Dictionary = {
+ "idle": $Idle,
+ "walk": $Walk,
+ "slash": $Slash,
+ "shoot": $Shoot,
+ "dash": $Dash,
+ "fall": $Fall,
+ "fallToRoll": $FallToRoll,
+ "fallToLanding": $FallToLanding
+}
+var current_move: Move
-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
+func _ready() -> void:
+ # assign starting state
+ current_move = moves["idle"]
- 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
+ # assign objects to each move
+ for move in moves.values():
+ move.player = player
+ move.camera = camera
+
+
+func update(input: InputPacket, delta: float):
+ var relevent_move := current_move.should_enter(input)
+ if moves[relevent_move] != current_move:
+ switch_to(relevent_move)
+ current_move.update(input, delta)
+
+
+func switch_to(state: String):
+ player.state = state
+ current_move.on_exit_state()
+ current_move = moves[state]
+ current_move.on_enter_state()