extends PlayerState class_name DodgeState @export var dodge_speed_curve : Curve #optionnel : controle le "falloff" de vitesse pendant la roulade (1.0 = pleine vitesse, 0.0 = arret). Laisser vide pour une vitesse constante. var dodge_dir : Vector2 = Vector2.ZERO var dodge_timer : float = 0.0 var dodge_duration_ref : float = 0.0 func on_enter() -> void: AimReticle.hide_instance() #pas de reticule pendant la roulade (si la visee est maintenue, elle reprend apres) verifications() func verifications() -> void: player.floor_snap_length = 1.0 player.is_dodging = true player.dodge_cooldown = player.dodge_cooldown_ref #roule dans la direction actuelle de l'input, ou dans la derniere direction connue si aucune touche n'est tenue (comportement Arceus) dodge_dir = player.move_dir if player.move_dir != Vector2.ZERO else player.last_input_dir if dodge_dir == Vector2.ZERO: dodge_dir = Vector2.DOWN #direction par defaut si le perso n'a encore jamais bouge dodge_dir = dodge_dir.normalized() dodge_timer = player.dodge_duration dodge_duration_ref = player.dodge_duration #oriente immediatement le modele dans la direction de la roulade, verrouillee pour toute sa duree player.visual_root.rotation.y = -dodge_dir.orthogonal().angle() func exit() -> void: player.is_dodging = false func physics_update(delta : float) -> void: applies() player.gravity_apply(delta) move(delta) dodge_timer -= delta if dodge_timer <= 0.0: end_dodge() func applies() -> void: #si le perso quitte le sol en roulant (ex: roulade vers un bord), on bascule vers InairState comme les autres etats au sol if !player.is_on_floor() and !player.is_on_wall(): if player.velocity.y < 0.0: fall() func move(_delta : float) -> void: if !player.is_on_floor(): return #falloff de vitesse : pleine vitesse par defaut, ou modele par dodge_speed_curve si assignee var ratio : float = 1.0 if dodge_speed_curve: ratio = dodge_speed_curve.sample(1.0 - (dodge_timer / dodge_duration_ref)) player.velocity.x = dodge_dir.x * player.dodge_speed * ratio player.velocity.z = dodge_dir.y * player.dodge_speed * ratio func end_dodge() -> void: #a la fin de la roulade, retour a l'etat approprie (la posture accroupie est conservee : Idle / Walk la reappliquent) if !player.is_on_floor(): fall() else: if input.aim_held(): player.aim_targeting.begin_aim() #visee enfoncee pendant la roulade (sans effet si la visee est deja active) request_ground_state(player.move_dir != Vector2.ZERO)