diff --git a/game/player/states/aim_state.gd b/game/player/states/aim_state.gd index 4563567..ab6145a 100644 --- a/game/player/states/aim_state.gd +++ b/game/player/states/aim_state.gd @@ -10,6 +10,7 @@ var play_char : CharacterBody3D @export var switch_target_action : StringName = &"player_aim_switch_target" @export var unlock_action : StringName = &"player_aim_unlock" @export var throw_action : StringName = &"player_throw" #RT / clic gauche (cree automatiquement s'il n'existe pas) +@export var cancel_action : StringName = &"player_throw_cancel" #annule la charge d'un lancer (cree par ThrowState) @export_group("Targeting") @export var throw_range : float = 20.0 @@ -27,6 +28,7 @@ var auto_lock_blocked : bool = false #true apres un deverrouillage manuel, tant var dodging_from_aim : bool = false #true quand on quitte Aim pour rouler, pour ne pas relacher la cible verrouillee var came_from_crouch : bool = false #true si Aim a ete declenche depuis CrouchState, pour y retourner en sortant var keep_aim_on_exit : bool = false #true quand on part vers ThrowState : camera et verrouillage restent en place +var charging_throw : bool = false #true quand on arrive depuis ThrowState en pleine charge : RT est encore maintenue func _ready() -> void: if InputMap.has_action(throw_action): return @@ -54,6 +56,7 @@ func verifications() -> void: play_char.cam_holder.cam_aimed = true func exit() -> void: + charging_throw = false if keep_aim_on_exit: keep_aim_on_exit = false return @@ -86,12 +89,22 @@ func input_management() -> bool: return true if !Input.is_action_pressed(aim_action): + if charging_throw and Input.is_action_pressed(throw_action) and can_throw(): + transitioned.emit(self, "ThrowState") #visee relachee en pleine charge : on reprend la charge hors visee + return true if came_from_crouch: transitioned.emit(self, "CrouchState") else: transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState") return true + if charging_throw: + if Input.is_action_just_pressed(cancel_action): + charging_throw = false #lancer annule, on reste en visee + elif !Input.is_action_pressed(throw_action): + charging_throw = false + if start_throw(true): return true #RT relachee : le lancer part avec la cible verrouillee + if Input.is_action_just_pressed(throw_action): #si le pokemon selectionne est deja dehors, un nouvel appui le rappelle au lieu de relancer var selected : PokemonInstance = GameData.get_selected_pokemon() @@ -108,10 +121,15 @@ func input_management() -> bool: switch_target() return false -func start_throw() -> bool: +func can_throw() -> bool: if GameData.get_selected_pokemon() == null: return false #personne a envoyer - if !play_char.state_machine.states.has("throwstate"): return false #pas de node ThrowState dans la StateMachine + return play_char.state_machine.states.has("throwstate") #sinon : pas de node ThrowState dans la StateMachine + +func start_throw(released : bool = false) -> bool: + if !can_throw(): return false keep_aim_on_exit = true + var throw : Node = play_char.state_machine.states["throwstate"] + throw.resume_released = released #true : on saute la charge, le windup demarre directement transitioned.emit(self, "ThrowState") return true diff --git a/game/player/states/throw_state.gd b/game/player/states/throw_state.gd index 790777b..b215c57 100644 --- a/game/player/states/throw_state.gd +++ b/game/player/states/throw_state.gd @@ -39,6 +39,7 @@ var _pokemon : PokemonInstance = null var _target : Variant = null #AimTarget verrouille au moment du relachement var _free_aim_point : Vector3 = Vector3.ZERO var _came_from_crouch : bool = false #true si le lancer vient du crouch (directement, ou via Aim declenche depuis le crouch) +var resume_released : bool = false #mis a true par AimState : RT a ete relachee pendant la visee, le lancer demarre directement en windup func _ready() -> void: _ensure_action(throw_action, func(): @@ -85,6 +86,10 @@ func enter(play_char_ref : CharacterBody3D) -> void: play_char.floor_snap_length = 1.0 #play_char.godot_plush_skin.set_state("throw") + + if resume_released: + resume_released = false + release() #fige la cible verrouillee / le point vise et lance le windup func exit() -> void: #retour a la visee : on garde tout tel quel ; sinon on libere camera et verrouillage (comme AimState) @@ -116,6 +121,10 @@ func physics_update(delta : float) -> void: finish() #annule avant que la balle parte return + if _thrown and Input.is_action_just_pressed(aim_action): + finish() #balle partie : on coupe la recuperation, finish() bascule en AimState + return + _elapsed += delta if !_thrown and _elapsed >= windup_time: throw_ball() @@ -135,12 +144,25 @@ func charge(delta : float) -> void: finish() #annule : rien n'est lance return + if Input.is_action_just_pressed(aim_action): + enter_aim_while_charging() + return + if !Input.is_action_pressed(throw_action): release() return move_while_charging(delta) update_reticle() + +func enter_aim_while_charging() -> void: + #on passe en visee sans perdre la charge : AimState se charge de relancer le lancer au relachement de RT + var aim : Node = play_char.state_machine.states.get("aimstate") + if aim == null: return + aim.came_from_crouch = _came_from_crouch + aim.charging_throw = true + _keep_aim = true + transitioned.emit(self, "AimState") func release() -> void: #RT relachee : on fige la cible et le point vise, puis le windup demarre