class_name Player extends Unit @export var mouse_sensitivity := 0.006 @export var rotation_speed := 24.0 @export var joypad_sensitivity := 0.1 var attacks := ["1h_slice_diagonal", "1h_slice_horizontal", "1h_attack_chop"] var footsteps := [ "res://resources/audio/footstep_grass_000.ogg", "res://resources/audio/footstep_grass_001.ogg", "res://resources/audio/footstep_grass_002.ogg", "res://resources/audio/footstep_grass_003.ogg", "res://resources/audio/footstep_grass_004.ogg" ] @onready var spring_arm := $SpringArm3D var gold := 0: get: return gold set(value): gold = value gold_changed.emit(gold) signal gold_changed(current_gold) signal player_loaded() func _ready() -> void: health = maximum_health stamina = maximum_stamina #state_changed.connect(_on_state_changed) player_loaded.emit() #func _on_state_changed(_old_state: States, new_state: States) -> void: #print("Player changed state from " + str(old_state) + " to " + str(new_state)) #match new_state: #States.blocking: #print("Player is blocking!") #States.dead: func _physics_process(delta: float) -> void: velocity.y += -gravity * delta get_move_input(delta) move_and_slide() if velocity.length() > 1.0: model.rotation.y = lerp_angle(model.rotation.y, spring_arm.rotation.y, rotation_speed * delta) func player_game_over(): GameManager.game_over() queue_free() func _input(event: InputEvent) -> void: #move camera via mouse if event is InputEventMouseMotion: spring_arm.rotation.x -= event.relative.y * mouse_sensitivity spring_arm.rotation_degrees.x = clamp(spring_arm.rotation_degrees.x, -90.0, 30.0) spring_arm.rotation.y -= event.relative.x * mouse_sensitivity #move camera via joypad if event is InputEventJoypadMotion: if event.axis == JOY_AXIS_RIGHT_X: spring_arm.rotation.y -= event.axis_value * joypad_sensitivity elif event.axis == JOY_AXIS_RIGHT_Y: spring_arm.rotation.x -= event.axis_value * joypad_sensitivity spring_arm.rotation_degrees.x = clamp(spring_arm.rotation_degrees.x, -90.0, 30.0) #attack if event.is_action_pressed("attack"): if enough_stamina_available(attack_cost): use_stamina(attack_cost) if state == States.blocking: anim_state.travel("Block_Attack") else: anim_state.travel(attacks.pick_random()) #block if Input.is_action_pressed("block"): state = States.blocking if Input.is_action_just_released("block"): state = States.idle anim_tree.set("parameters/conditions/blocking", state == States.blocking) anim_tree.set("parameters/conditions/not_blocking", state != States.blocking) #jump if is_on_floor() and Input.is_action_just_pressed("jump"): if enough_stamina_available(jump_cost): use_stamina(jump_cost) velocity.y = jump_speed state = States.jumping anim_tree.set("parameters/conditions/grounded", false) # We just hit the floor after being in the air if is_on_floor() and not last_floor: if (state != States.idle ): state = States.idle anim_tree.set("parameters/conditions/grounded", true) # We're in the air, but we didn't jump if not is_on_floor() and state != States.jumping: anim_state.travel("Jump_Idle") anim_tree.set("parameters/conditions/grounded", false) anim_tree.set("parameters/conditions/jumping", state == States.jumping) last_floor = is_on_floor() #Menue if event.is_action_pressed("Menue"): get_tree().quit() func get_move_input(delta: float) -> void: var vy = velocity.y velocity.y = 0 var input = Input.get_vector("left", "right", "forward", "back") var dir = Vector3(input.x, 0, input.y).rotated(Vector3.UP, spring_arm.rotation.y) if state == States.blocking: dir = Vector3.ZERO # TODO: Walk while blocking velocity = lerp(velocity, dir * speed, acceleration * delta) var vl = velocity * model.transform.basis anim_tree.set("parameters/IWR/blend_position", Vector2(vl.x, -vl.z) / speed) velocity.y = vy