Tales-of-PKMN/game/player/states/dodge_state.gd

77 lines
2.6 KiB
GDScript

extends State
class_name DodgeState
var state_name : String = "Dodge"
var play_char : CharacterBody3D
@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 enter(play_char_ref : CharacterBody3D) -> void:
play_char = play_char_ref
verifications()
func verifications() -> void:
play_char.floor_snap_length = 1.0
play_char.is_dodging = true
play_char.dodge_cooldown = play_char.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 = play_char.move_dir if play_char.move_dir != Vector2.ZERO else play_char.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 = play_char.dodge_duration
dodge_duration_ref = play_char.dodge_duration
#oriente immediatement le modele dans la direction de la roulade, verrouillee pour toute sa duree
play_char.visual_root.rotation.y = -dodge_dir.orthogonal().angle()
func exit() -> void:
play_char.is_dodging = false
func physics_update(delta : float) -> void:
applies()
play_char.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 !play_char.is_on_floor() and !play_char.is_on_wall():
if play_char.velocity.y < 0.0:
transitioned.emit(self, "InairState")
func move(_delta : float) -> void:
if !play_char.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))
play_char.velocity.x = dodge_dir.x * play_char.dodge_speed * ratio
play_char.velocity.z = dodge_dir.y * play_char.dodge_speed * ratio
func end_dodge() -> void:
#a la fin de la roulade, retour a l'etat approprie
if !play_char.is_on_floor():
transitioned.emit(self, "InairState")
elif Input.is_action_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState") #le joueur a garde la visee enfoncee pendant la roulade
elif play_char.move_dir:
transitioned.emit(self, play_char.walk_or_run)
else:
transitioned.emit(self, "IdleState")