extends CharacterBody2D @export_range(10, 1000, 10, "or_greater") var speed = 300.0 @export_range(0, 0.2, 0.001, "or_greater") var acceleration = 0.5 @export_group("Airborne") @export_range(0, 1000, 10, "or_greater") var jump_velocity = 400.0 @export_range(0, 10, 0.1, "or_greater") var gravity_modifier = 1 @onready var hitting: Timer = $Hitting @onready var hitbox: Area2D = $Hitbox @onready var armor: AnimatedSprite2D = $Armor @onready var sword: AnimatedSprite2D = $Sword @onready var damageable: Damageable = $Damageable @onready var shield: AnimatedSprite2D = $Shield @onready var base: AnimatedSprite2D = $Base var current_sprite: AnimatedSprite2D var is_in_cutscene = false # back to true on build var current_animation = "idle" var is_hitting = false var has_shield = false var has_sword = false var has_armor = false @onready var steps_player: AudioStreamPlayer = $StepsPlayer @onready var gearup_armor: AudioStreamPlayer = $GearupArmor @onready var gearup_sword: AudioStreamPlayer = $GearupSword @onready var gearup_shield: AudioStreamPlayer = $GearupShield @onready var sword_hit: AudioStreamPlayer = $SwordHit @onready var got_hit_audio: AudioStreamPlayer = $GotHitAudio func play_anim(): current_sprite.play(current_animation) func play_anim_run(): current_animation = "run" current_sprite.play("run") func play_anim_idle(): current_animation = "idle" current_sprite.play("idle") func play_anim_jump(): current_animation = "walk" current_sprite.play("walk") func play_anim_dance(): current_animation = "dance" current_sprite.play("dance") func set_in_cutscene(): is_in_cutscene = true play_anim_idle() func set_in_play(): is_in_cutscene = false func look_left(): current_sprite.flip_h = true func look_right(): current_sprite.flip_h = false func _ready() -> void: current_sprite = base func _physics_process(delta: float) -> void: if is_in_cutscene: velocity.x = move_toward(velocity.x, 0, speed) move_and_slide() return play_anim() if is_hitting: current_animation = "hit" velocity.x = move_toward(velocity.x, 0, speed) move_and_slide() return if not is_on_floor(): velocity += get_gravity() * delta * gravity_modifier var direction := Input.get_axis("move_left", "move_right") if(has_shield and not has_sword and direction == 0): damageable.set_active(false) else: damageable.set_active(true) if direction > 0 and is_on_floor(): look_right() if direction < 0 and is_on_floor(): look_left() if not is_on_floor(): current_animation = "got_hit" else: if velocity.x != 0: play_anim_run() else: play_anim_idle() if is_on_floor(): if direction: var smoothed_speed = speed * smoothstep(0, 1, acceleration) velocity.x += direction * smoothed_speed velocity.x = clampf(velocity.x, -speed, speed) else: velocity.x = move_toward(velocity.x, 0, speed) if Input.is_action_just_pressed("hit") and has_sword: hit() move_and_slide() func hit(): is_hitting = true sword_hit.play() hitting.start() hitbox.monitoring = true func _on_hitting_timeout() -> void: is_hitting = false hitbox.monitoring = false damageable.set_active(true) func _on_dialogue_manager_dialogue_ended() -> void: set_in_play() func _on_trigger_dialogue_body_entered(body: Node2D) -> void: set_in_cutscene() func _on_start_dancing() -> void: play_anim_dance() func _on_npc_shield_dialogue_dialogue_ended() -> void: set_in_play() current_sprite.visible = false current_sprite = shield current_sprite.play("idle") current_sprite.visible = true has_shield = true gearup_shield.play() func _on_red_hood_sword_dialogue_dialogue_ended() -> void: set_in_play() current_sprite.visible = false current_sprite = sword current_sprite.play("idle") current_sprite.visible = true has_sword = true gearup_sword.play() func _on_put_on_armor() -> void: gearup_armor.play() current_sprite.visible = false current_sprite = armor current_sprite.play("power_up") current_sprite.visible = true has_armor = true func _on_final_armor_dialogue_ended() -> void: set_in_play() current_sprite.play("idle") func _on_trigger_final_dialogue_body_entered(body: Node2D) -> void: set_in_cutscene() func _on_step_sound_interval_timeout() -> void: if velocity.x == 0: return if not is_on_floor(): return steps_player.play() func _on_damageable_got_hit() -> void: got_hit_audio.play()