extends PlayerState class_name GroundedState #base des etats au sol (Idle, Walk, Run). Chaque etat enfant ne decrit que ses differences : # - apply_standing_stats() : vitesse / accel / deccel de l'etat quand on est debout # - on_move() / on_no_move() : ce qui se passe avec / sans direction d'input # - check_locomotion_switch() : bascule Walk <-> Run # - is_falling() : condition pour passer en InairState # #le crouch n'est plus un etat mais une POSTURE (player.is_crouching) : # - elle se bascule ici (toggle_crouch) et survit aux etats Dodge / Throw : plus besoin de "came_from_crouch" # - elle est annulee en courant (RunState) et en quittant le sol (State.fall()) #la visee (AimTargeting) est un mode du meme genre : tant qu'elle est active, deplacement ralenti, pas de saut, et tick() chaque frame. # - accroupi : stats de deplacement accroupi, pas de saut, pas de jump buffer consomme var allows_crouch : bool = true #false : l'appui sur crouch_action est ignore (Run) #---------- cycle de vie ---------- func on_enter() -> void: reset_ground_state() apply_movement_stats() func reset_ground_state() -> void: #remet a zero tout ce qui concerne le saut quand on touche / reste au sol player.floor_snap_length = 1.0 if player.jump_cooldown > 0.0: player.jump_cooldown = -1.0 if player.nb_jumps_in_air_allowed < player.nb_jumps_in_air_allowed_ref: player.nb_jumps_in_air_allowed = player.nb_jumps_in_air_allowed_ref if player.coyote_jump_cooldown < player.coyote_jump_cooldown_ref: player.coyote_jump_cooldown = player.coyote_jump_cooldown_ref if player.has_cut_jump: player.has_cut_jump = false #---------- stats de deplacement ---------- func apply_movement_stats() -> void: if player.is_crouching: apply_crouch_stats() else: apply_standing_stats() func apply_standing_stats() -> void: pass #Walk / Run y copient leurs vitesses sur player ; Idle garde celles de l'etat precedent func apply_crouch_stats() -> void: player.move_speed = player.crouch_speed player.move_accel = player.crouch_accel player.move_deccel = player.crouch_deccel func toggle_crouch() -> void: player.is_crouching = !player.is_crouching apply_movement_stats() #---------- boucle ---------- func physics_update(delta : float) -> void: if try_start_throw(): return if check_ground_transitions(): return player.gravity_apply(delta) if handle_input(): return if player.is_aiming: player.aim_targeting.tick() move(delta) func try_start_throw() -> bool: #RT depuis le sol (debout ou accroupi, visee ou non) lance un pokemon : ce n'est plus la StateMachine qui s'en charge if !input.throw_pressed(): return false if !player.is_on_floor(): return false if GameData.get_selected_pokemon() == null: return false #pokemon selectionne deja dehors : l'appui le rappelle (voir RecallInput), on ne lance pas if PokemonRecall.find_selected_out(get_tree()) != null: return false if !player.state_machine.has_state(States.THROW): return false return request_transition(States.THROW) func check_ground_transitions() -> bool: #etat du sol : on quitte le sol -> InairState ; jump buffer -> JumpState (pas accroupi : le buffer reste en attente) if !player.is_on_floor(): if !player.is_on_wall() and is_falling(): return fall() return false if !player.is_crouching and !player.is_aiming and player.jump_buff_on: player.buffered_jump = true player.jump_buff_on = false return request_transition(States.JUMP) return false func is_falling() -> bool: #accroupi, on quitte le sol sans condition sur la vitesse verticale (comme IdleState, qui le surcharge) return player.is_crouching or player.velocity.y < 0.0 func handle_input() -> bool: #renvoie true si une transition a eu lieu. Priorite : roulade > courir (annule le crouch) > crouch > saut > visee > bascule marche/course if input.wants_dodge() and request_transition(States.DODGE): return true if player.is_crouching and player.is_running() and request_transition(States.RUN): return true if allows_crouch and player.can_crouch and input.crouch_pressed(): toggle_crouch() if !player.is_crouching and !player.is_aiming and input.wants_jump() and request_transition(States.JUMP): return true if input.aim_pressed(): player.aim_targeting.begin_aim() #la visee n'est pas un etat : le deplacement continue, ralenti return check_locomotion_switch() func check_locomotion_switch() -> bool: return false #Walk et Run surchargent func move(delta : float) -> void: player.move_dir = input.read_move_dir() if player.move_dir and player.is_on_floor(): on_move(delta) else: on_no_move(delta) func on_move(delta : float) -> void: if player.is_aiming: accelerate(player.aim_targeting.aim_move_speed, player.aim_targeting.aim_move_accel, delta) else: accelerate(player.move_speed, player.move_accel, delta) func on_no_move(delta : float) -> void: slow_down(delta)