Wall jump

Version:

1.0

Added on:

09 Nov 2018 18:38

Tags:

Description:
Lets all rabbit players slide down walls and jump off of them, similar to the wall jump mechanics in Hollow Knight.
class PlayerWallJumpProperties {
  uint Stage = 0;
  bool FacingRight;
  int LastSlidingTick = 0;
  bool PressingJumpOneTickAgo = false;
  PlayerWallJumpProperties(){}
}
array<PlayerWallJumpProperties> PlayerWallJumpPropertiesArray(jjLocalPlayerCount);

void onPlayer(jjPLAYER@ play) {
  PlayerWallJumpProperties@ wallJumpProperties = @PlayerWallJumpPropertiesArray[play.localPlayerID];
  const bool pressingJump = play.keyJump;
  if (
    pressingJump &&
    !wallJumpProperties.PressingJumpOneTickAgo &&
    wallJumpProperties.Stage < 2 &&
    (jjGameTicks - wallJumpProperties.LastSlidingTick) < 10 //10 = number of ticks after technically letting go of the wall during which you can still start the jump. Higher numbers are more generous.
  ) {
    wallJumpProperties.Stage = 2;
    jjSample(play.xPos, play.yPos, SOUND::COMMON_JUMP);
    play.ySpeed = play.jumpStrength;
    play.helicopter = 0;
    play.doubleJumpCount = 0;
  } else if (wallJumpProperties.Stage > 1) {
    if (++wallJumpProperties.Stage == 20)
      wallJumpProperties.Stage = 0;
    else {
      play.keyRight = wallJumpProperties.FacingRight;
      play.keyLeft = !wallJumpProperties.FacingRight;
      play.keyJump = true;
      play.helicopter = 0;
    }
  } else {
    const auto anim = play.curAnim - jjAnimSets[play.setID];
    const int xPosToTest = int(play.xPos) + (play.keyRight ? 13 : -13);
    uint16 tileIDToTest;
    if (
      (anim == RABBIT::FALL || anim == RABBIT::HELICOPTER) &&
      (play.keyRight || play.keyLeft) &&
      (jjMaskedPixel(xPosToTest, int(play.yPos)-8) && jjMaskedPixel(xPosToTest, int(play.yPos)+8))
      //put any additional conditions, e.g. events or tiles you can't slide on, here.
    ) {
      play.helicopter = 0;
      wallJumpProperties.Stage = 1;
      wallJumpProperties.FacingRight = play.keyLeft;
      play.ySpeed = 0.25; //modify as desired if you don't like this sliding speed
      play.keyJump = false;
      wallJumpProperties.LastSlidingTick = jjGameTicks;
    } else if (wallJumpProperties.Stage == 1)
      wallJumpProperties.Stage = 0;
  }
  if (play.invisibility = wallJumpProperties.Stage == 1) { //this works for SP, but for MP you'd probably instead want to give everyone SPRITE::INVISIBLE all the time and draw non-local players in an onMain loop.
    if (play.blink == 0 || ((jjRenderFrame >> 2) & 1) == 1) {
      const int vDir = !play.antiGrav ? 1 : -1;
      jjDrawRotatedSprite(play.xPos - play.direction * 3, play.yPos, play.setID, RABBIT::SKID1, jjGameTicks>>4, 256 * play.direction * vDir, -play.direction, vDir, SPRITE::PLAYER, play.playerID);
    }
  }
  wallJumpProperties.PressingJumpOneTickAgo = pressingJump;
}