Abstract class for Jumping logic.
    public override void OnEnable() {
      base.OnEnable();

      defaultJump = new JumpVariableHeight(character, jumpProperties);

      _graceJumpFrames = UpdateManager.GetFrameCount (jumpProperties.graceJumpTime);
      input.onActionUp += OnActionUp;
      input.onActionDown += OnActionDown;
    }
 /// <summary>
 /// Try to jump
 /// </summary>
 public void Jump(Jump j) {
   jumping = true;
   customJump = true; // enable StartJump
   currentJump = j;
 }
    /// <summary>
    /// Listen input and Select the current Jump
    ///
    /// Other actions (with higher priority) can trigger Jumps
    /// using Jump(), and the next Frame CharacterActionJump
    /// willl take control!
    /// </summary>
    public override int WantsToUpdate(float delta) {
      /* DEBUG
      text = string.Format("jumpHeld: {0}\nonGround: {1}\njumping: {2}\njumpStopped: {3}\nCondition: {4}\n" +
      "maxJumpVelocity: {5}\nminJumpVelocity: {6}\nhangFrames: {7}\napexFrames: {8}\nticks: {9}",
        jumpHeld,
        pc2d.IsOnGround(_graceJumpFrames),
        jumping,
        jumpStopped,
        jumpStopped || (
          jumpHeld && (
            pc2d.IsOnGround(_graceJumpFrames) || jumping
          )
        ),

        jump.maxJumpVelocity,
        jump.minJumpVelocity,
        jump.hangFrames,
        jump.apexFrames,
        jump.ticks
      );
      */

      if (forceJump) {
        return priority;
      }

      // while on a liquid player can be onGround, so it can jump...
      // disable it
      if (character.IsOnState(States.Liquid)) {
        return 0;
      }

      if (jumpHeld) {
        if (pc2d.IsOnGround(_graceJumpFrames) && !jumping) {
          currentJump = defaultJump;
          return priority;
        }
        if (jumping) {
          return priority;
        }
      }

      // jump stopped? run one last time to reset
      if (jumpStopped) {
        return priority;
      }

      return 0;
    }
 /// <summary>
 /// Force Character to Jump!
 ///
 /// User must be sure of what they are doing... this doesn't check anything
 /// </summary>
 public void ForceJump(Jump j) {
   Jump(j);
   forceJump = true;
 }