Player getting extra knockback when holding direction while on ladder

Godot Version

v4.7.2.stable.official [ed1daf0bf]

Question

What the title says. When I’m on a ladder and I get hit by something while holding right or left, I get kicked back much further than I normally would.

Relevant player code:

func _physics_process(delta: float) -> void:
	if OS.is_debug_build():
		debug_print()
	
	if allow_input:
		input_vector = get_input_vector()
	
	position.x = round(position.x)
	position.y = round(position.y)
	
	if is_affected_by_gravity:
		if velocity.y < 0:
			velocity.y += GRAVITY * delta
		else:
			velocity.y += GRAVITY * delta * fall_gravity_multiplier
	
	if input_vector.x == 0:
		if is_on_floor():
			velocity.x = lerp(velocity.x, 0.0, ground_friction)
		else:
			velocity.x = lerp(velocity.x, 0.0, air_friction)
	
	if flip_sprite_in_movement_direction:
		if input_vector.x > 0:
			$Sprite.flip_h = false
		elif input_vector.x < 0:
			$Sprite.flip_h = true
	
	if !$Sprite.flip_h:
		$AttackBox.position.x = hitbox_pos
		$NpcDetectionRay.position.x = raycast_pos
		$NpcDetectionRay.target_position = raycast_length
	else:
		$AttackBox.position.x = -hitbox_pos
		$NpcDetectionRay.position.x = -raycast_pos
		$NpcDetectionRay.target_position = -raycast_length
	
	var camera_node: ShakingCamera = GameWindow.ingame_cam
	if camera_node and movement_mode != MovementModes.GLITCH:
		position.x = clamp(position.x, camera_node.limit_left, camera_node.limit_right)
	
	match movement_mode:
		MovementModes.REGULAR_MOVEMENT:
			state_move(delta)
		MovementModes.HURT:
			state_hurt()
		MovementModes.DEAD:
			state_dead()
		MovementModes.LADDER:
			state_ladder()
		MovementModes.GLITCH:
			state_glitch()
	
	move_and_slide()
	
	velocity.x = round(velocity.x)
	velocity.y = round(velocity.y)
	
	if is_on_floor():
		rotation = move_toward(rotation, get_floor_normal().angle() + PI / 2, 0.05)
		
		jumped = false
		coyote_timer = COYOTE_TIME
		
	else:
		rotation = move_toward(rotation, 0, 0.05)
		
		if coyote_timer > 0:
			coyote_timer -= delta
		
		if jump_buffer_timer > 0:
			jump_buffer_timer -= delta
	
	if ladder_buffer_timer > 0:
		ladder_buffer_timer -= delta
	
	if (!$RaycastLeft.is_colliding() or !$RaycastRight.is_colliding()
			or $SemisolidDetector.has_overlapping_bodies()):
		$CollisionRect.disabled = false
		$CollisionPoly.disabled = true
	else:
		$CollisionRect.disabled = true
		$CollisionPoly.disabled = false
	
	if looking_around and look_timer > 0:
		look_timer -= delta
	
	if look_timer < LOOK_WAIT_TIME and movement_mode != MovementModes.REGULAR_MOVEMENT:
		looking_around = false


func take_damage(area: Hitbox = null, damage := 1, knockback := true,
		ignore_iframes := false) -> void:
	if (movement_mode == MovementModes.DEAD
			or movement_mode == MovementModes.GLITCH
			or !$InvincibilityTimer.is_stopped() and !ignore_iframes):
		return
	
	allow_input = false
	
	if movement_mode == MovementModes.LADDER:
		is_affected_by_gravity = true
		set_collision_mask_value(7, true)
	
	PlayerStats.health -= damage
	
	velocity.y = -KNOCKBACK_SPEED
	
	if knockback:
	
		flip_sprite_in_movement_direction = false
		
		if area and !area.ignore_direction:
			if (sign(velocity.x) != sign(area.velocity.x)
					and !(abs(velocity.x) <= MIN_X_VEL_DISCARDED)):
				velocity.x = 0
			else:
				velocity.x = KNOCKBACK_SPEED * sign(area.velocity.x)
			
			if movement_mode == MovementModes.LADDER:
				if area.velocity.x > 0:
					$Sprite.flip_h = true
				else:
					$Sprite.flip_h = false
			
		else:
			if abs(velocity.x) >= MIN_X_VEL_DISCARDED:
				velocity.x = 0
			elif !$Sprite.flip_h:
				velocity.x = -KNOCKBACK_SPEED
			else:
				velocity.x = KNOCKBACK_SPEED
	
	else:
		flip_sprite_in_movement_direction = true
	
	movement_mode = MovementModes.HURT
	
	$Hitbox/HitboxCollision.set_deferred("disabled", true)
	$InteractBox/InteractCollision.set_deferred("disabled", true)
	$HurtInputLockTimer.start()
	if !$InvincibilityTimer.is_stopped():
		$InvincibilityTimer.stop()
		$InvincibilityTimer.timeout.emit()
	$InvincibilityTimer.start()
	_blink_hurt()


func state_hurt() -> void:
	anim_state.travel("hurt")
	await $HurtInputLockTimer.timeout
	if PlayerStats.health > 0:
		$InteractBox/InteractCollision.set_deferred("disabled", false)
		allow_input = true
		flip_sprite_in_movement_direction = true
		$BlinkTimer.start()
		if movement_mode != MovementModes.GLITCH:
			movement_mode = MovementModes.REGULAR_MOVEMENT
	else:
		die()
		$InvincibilityTimer.timeout.emit()

Nullify input_vector in take_damage().