sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

mario_actions_airborne.c (65719B)


      1 #include <PR/ultratypes.h>
      2 
      3 #include "sm64.h"
      4 #include "area.h"
      5 #include "audio/external.h"
      6 #include "camera.h"
      7 #include "engine/graph_node.h"
      8 #include "engine/math_util.h"
      9 #include "game_init.h"
     10 #include "interaction.h"
     11 #include "level_update.h"
     12 #include "mario.h"
     13 #include "mario_step.h"
     14 #include "save_file.h"
     15 #include "rumble_init.h"
     16 
     17 void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) {
     18     s32 animFrame = m->marioObj->header.gfx.animInfo.animFrame;
     19     if (animFrame == frame1 || animFrame == frame2 || animFrame == frame3) {
     20         play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
     21     }
     22 }
     23 
     24 void play_far_fall_sound(struct MarioState *m) {
     25     u32 action = m->action;
     26     if (!(action & ACT_FLAG_INVULNERABLE) && action != ACT_TWIRLING && action != ACT_FLYING
     27         && !(m->flags & MARIO_UNKNOWN_18)) {
     28         if (m->peakHeight - m->pos[1] > 1150.0f) {
     29             play_sound(SOUND_MARIO_WAAAOOOW, m->marioObj->header.gfx.cameraToObject);
     30             m->flags |= MARIO_UNKNOWN_18;
     31         }
     32     }
     33 }
     34 
     35 #ifndef VERSION_JP
     36 void play_knockback_sound(struct MarioState *m) {
     37     if (m->actionArg == 0 && (m->forwardVel <= -28.0f || m->forwardVel >= 28.0f)) {
     38         play_sound_if_no_flag(m, SOUND_MARIO_DOH, MARIO_MARIO_SOUND_PLAYED);
     39     } else {
     40         play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
     41     }
     42 }
     43 #endif
     44 
     45 s32 lava_boost_on_wall(struct MarioState *m) {
     46     m->faceAngle[1] = atan2s(m->wall->normal.z, m->wall->normal.x);
     47 
     48     if (m->forwardVel < 24.0f) {
     49         m->forwardVel = 24.0f;
     50     }
     51 
     52     if (!(m->flags & MARIO_METAL_CAP)) {
     53         m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18;
     54     }
     55 
     56     play_sound(SOUND_MARIO_ON_FIRE, m->marioObj->header.gfx.cameraToObject);
     57     update_mario_sound_and_camera(m);
     58     return drop_and_set_mario_action(m, ACT_LAVA_BOOST, 1);
     59 }
     60 
     61 s32 check_fall_damage(struct MarioState *m, u32 hardFallAction) {
     62     f32 fallHeight;
     63     f32 damageHeight;
     64 
     65     fallHeight = m->peakHeight - m->pos[1];
     66 
     67 #pragma GCC diagnostic push
     68 #if defined(__clang__)
     69 #pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
     70 #elif defined(__GNUC__)
     71 #pragma GCC diagnostic ignored "-Wtype-limits"
     72 #endif
     73 
     74     //! Never true
     75     if (m->actionState == ACT_GROUND_POUND) {
     76         damageHeight = 600.0f;
     77     } else {
     78         damageHeight = 1150.0f;
     79     }
     80 
     81 #pragma GCC diagnostic pop
     82 
     83     if (m->action != ACT_TWIRLING && m->floor->type != SURFACE_BURNING) {
     84         if (m->vel[1] < -55.0f) {
     85             if (fallHeight > 3000.0f) {
     86                 m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 16 : 24;
     87 #if ENABLE_RUMBLE
     88                 queue_rumble_data(5, 80);
     89 #endif
     90                 set_camera_shake_from_hit(SHAKE_FALL_DAMAGE);
     91                 play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject);
     92                 return drop_and_set_mario_action(m, hardFallAction, 4);
     93             } else if (fallHeight > damageHeight && !mario_floor_is_slippery(m)) {
     94                 m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 8 : 12;
     95                 m->squishTimer = 30;
     96 #if ENABLE_RUMBLE
     97                 queue_rumble_data(5, 80);
     98 #endif
     99                 set_camera_shake_from_hit(SHAKE_FALL_DAMAGE);
    100                 play_sound(SOUND_MARIO_ATTACKED, m->marioObj->header.gfx.cameraToObject);
    101             }
    102         }
    103     }
    104 
    105     return FALSE;
    106 }
    107 
    108 s32 check_kick_or_dive_in_air(struct MarioState *m) {
    109     if (m->input & INPUT_B_PRESSED) {
    110         return set_mario_action(m, m->forwardVel > 28.0f ? ACT_DIVE : ACT_JUMP_KICK, 0);
    111     }
    112     return FALSE;
    113 }
    114 
    115 s32 should_get_stuck_in_ground(struct MarioState *m) {
    116     u32 terrainType = m->area->terrainType & TERRAIN_MASK;
    117     struct Surface *floor = m->floor;
    118     s32 flags = floor->flags;
    119     s32 type = floor->type;
    120 
    121     if (floor != NULL && (terrainType == TERRAIN_SNOW || terrainType == TERRAIN_SAND)
    122         && type != SURFACE_BURNING && SURFACE_IS_NOT_HARD(type)) {
    123         if (!(flags & 0x01) && m->peakHeight - m->pos[1] > 1000.0f && floor->normal.y >= 0.8660254f) {
    124             return TRUE;
    125         }
    126     }
    127 
    128     return FALSE;
    129 }
    130 
    131 s32 check_fall_damage_or_get_stuck(struct MarioState *m, u32 hardFallAction) {
    132     if (should_get_stuck_in_ground(m)) {
    133 #ifdef VERSION_JP
    134         play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
    135 #else
    136         play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
    137 #endif
    138         m->particleFlags |= PARTICLE_MIST_CIRCLE;
    139         drop_and_set_mario_action(m, ACT_FEET_STUCK_IN_GROUND, 0);
    140 #if ENABLE_RUMBLE
    141         queue_rumble_data(5, 80);
    142 #endif
    143         return TRUE;
    144     }
    145 
    146     return check_fall_damage(m, hardFallAction);
    147 }
    148 
    149 s32 check_horizontal_wind(struct MarioState *m) {
    150     struct Surface *floor;
    151     f32 speed;
    152     s16 pushAngle;
    153 
    154     floor = m->floor;
    155 
    156     if (floor->type == SURFACE_HORIZONTAL_WIND) {
    157         pushAngle = floor->force << 8;
    158 
    159         m->slideVelX += 1.2f * sins(pushAngle);
    160         m->slideVelZ += 1.2f * coss(pushAngle);
    161 
    162         speed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
    163 
    164         if (speed > 48.0f) {
    165             m->slideVelX = m->slideVelX * 48.0f / speed;
    166             m->slideVelZ = m->slideVelZ * 48.0f / speed;
    167             speed = 32.0f; //! This was meant to be 48?
    168         } else if (speed > 32.0f) {
    169             speed = 32.0f;
    170         }
    171 
    172         m->vel[0] = m->slideVelX;
    173         m->vel[2] = m->slideVelZ;
    174         m->slideYaw = atan2s(m->slideVelZ, m->slideVelX);
    175         m->forwardVel = speed * coss(m->faceAngle[1] - m->slideYaw);
    176 
    177 #ifdef VERSION_JP
    178         play_sound(SOUND_ENV_WIND2, m->marioObj->header.gfx.cameraToObject);
    179 #endif
    180         return TRUE;
    181     }
    182 
    183     return FALSE;
    184 }
    185 
    186 void update_air_with_turn(struct MarioState *m) {
    187     f32 dragThreshold;
    188     s16 intendedDYaw;
    189     f32 intendedMag;
    190 
    191     if (!check_horizontal_wind(m)) {
    192         dragThreshold = m->action == ACT_LONG_JUMP ? 48.0f : 32.0f;
    193         m->forwardVel = approach_f32(m->forwardVel, 0.0f, 0.35f, 0.35f);
    194 
    195         if (m->input & INPUT_NONZERO_ANALOG) {
    196             intendedDYaw = m->intendedYaw - m->faceAngle[1];
    197             intendedMag = m->intendedMag / 32.0f;
    198 
    199             m->forwardVel += 1.5f * coss(intendedDYaw) * intendedMag;
    200             m->faceAngle[1] += 512.0f * sins(intendedDYaw) * intendedMag;
    201         }
    202 
    203         //! Uncapped air speed. Net positive when moving forward.
    204         if (m->forwardVel > dragThreshold) {
    205             m->forwardVel -= 1.0f;
    206         }
    207         if (m->forwardVel < -16.0f) {
    208             m->forwardVel += 2.0f;
    209         }
    210 
    211         m->vel[0] = m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
    212         m->vel[2] = m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
    213     }
    214 }
    215 
    216 void update_air_without_turn(struct MarioState *m) {
    217     f32 sidewaysSpeed = 0.0f;
    218     f32 dragThreshold;
    219     s16 intendedDYaw;
    220     f32 intendedMag;
    221 
    222     if (!check_horizontal_wind(m)) {
    223         dragThreshold = m->action == ACT_LONG_JUMP ? 48.0f : 32.0f;
    224         m->forwardVel = approach_f32(m->forwardVel, 0.0f, 0.35f, 0.35f);
    225 
    226         if (m->input & INPUT_NONZERO_ANALOG) {
    227             intendedDYaw = m->intendedYaw - m->faceAngle[1];
    228             intendedMag = m->intendedMag / 32.0f;
    229 
    230             m->forwardVel += intendedMag * coss(intendedDYaw) * 1.5f;
    231             sidewaysSpeed = intendedMag * sins(intendedDYaw) * 10.0f;
    232         }
    233 
    234         //! Uncapped air speed. Net positive when moving forward.
    235         if (m->forwardVel > dragThreshold) {
    236             m->forwardVel -= 1.0f;
    237         }
    238         if (m->forwardVel < -16.0f) {
    239             m->forwardVel += 2.0f;
    240         }
    241 
    242         m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
    243         m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
    244 
    245         m->slideVelX += sidewaysSpeed * sins(m->faceAngle[1] + 0x4000);
    246         m->slideVelZ += sidewaysSpeed * coss(m->faceAngle[1] + 0x4000);
    247 
    248         m->vel[0] = m->slideVelX;
    249         m->vel[2] = m->slideVelZ;
    250     }
    251 }
    252 
    253 void update_lava_boost_or_twirling(struct MarioState *m) {
    254     s16 intendedDYaw;
    255     f32 intendedMag;
    256 
    257     if (m->input & INPUT_NONZERO_ANALOG) {
    258         intendedDYaw = m->intendedYaw - m->faceAngle[1];
    259         intendedMag = m->intendedMag / 32.0f;
    260 
    261         m->forwardVel += coss(intendedDYaw) * intendedMag;
    262         m->faceAngle[1] += sins(intendedDYaw) * intendedMag * 1024.0f;
    263 
    264         if (m->forwardVel < 0.0f) {
    265             m->faceAngle[1] += 0x8000;
    266             m->forwardVel *= -1.0f;
    267         }
    268 
    269         if (m->forwardVel > 32.0f) {
    270             m->forwardVel -= 2.0f;
    271         }
    272     }
    273 
    274     m->vel[0] = m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
    275     m->vel[2] = m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
    276 }
    277 
    278 void update_flying_yaw(struct MarioState *m) {
    279     s16 targetYawVel = -(s16)(m->controller->stickX * (m->forwardVel / 4.0f));
    280 
    281     if (targetYawVel > 0) {
    282         if (m->angleVel[1] < 0) {
    283             m->angleVel[1] += 0x40;
    284             if (m->angleVel[1] > 0x10) {
    285                 m->angleVel[1] = 0x10;
    286             }
    287         } else {
    288             m->angleVel[1] = approach_s32(m->angleVel[1], targetYawVel, 0x10, 0x20);
    289         }
    290     } else if (targetYawVel < 0) {
    291         if (m->angleVel[1] > 0) {
    292             m->angleVel[1] -= 0x40;
    293             if (m->angleVel[1] < -0x10) {
    294                 m->angleVel[1] = -0x10;
    295             }
    296         } else {
    297             m->angleVel[1] = approach_s32(m->angleVel[1], targetYawVel, 0x20, 0x10);
    298         }
    299     } else {
    300         m->angleVel[1] = approach_s32(m->angleVel[1], 0, 0x40, 0x40);
    301     }
    302 
    303     m->faceAngle[1] += m->angleVel[1];
    304     m->faceAngle[2] = 20 * -m->angleVel[1];
    305 }
    306 
    307 void update_flying_pitch(struct MarioState *m) {
    308     s16 targetPitchVel = -(s16)(m->controller->stickY * (m->forwardVel / 5.0f));
    309 
    310     if (targetPitchVel > 0) {
    311         if (m->angleVel[0] < 0) {
    312             m->angleVel[0] += 0x40;
    313             if (m->angleVel[0] > 0x20) {
    314                 m->angleVel[0] = 0x20;
    315             }
    316         } else {
    317             m->angleVel[0] = approach_s32(m->angleVel[0], targetPitchVel, 0x20, 0x40);
    318         }
    319     } else if (targetPitchVel < 0) {
    320         if (m->angleVel[0] > 0) {
    321             m->angleVel[0] -= 0x40;
    322             if (m->angleVel[0] < -0x20) {
    323                 m->angleVel[0] = -0x20;
    324             }
    325         } else {
    326             m->angleVel[0] = approach_s32(m->angleVel[0], targetPitchVel, 0x40, 0x20);
    327         }
    328     } else {
    329         m->angleVel[0] = approach_s32(m->angleVel[0], 0, 0x40, 0x40);
    330     }
    331 }
    332 
    333 void update_flying(struct MarioState *m) {
    334     UNUSED u8 filler[4];
    335 
    336     update_flying_pitch(m);
    337     update_flying_yaw(m);
    338 
    339     m->forwardVel -= 2.0f * ((f32) m->faceAngle[0] / 0x4000) + 0.1f;
    340     m->forwardVel -= 0.5f * (1.0f - coss(m->angleVel[1]));
    341 
    342     if (m->forwardVel < 0.0f) {
    343         m->forwardVel = 0.0f;
    344     }
    345 
    346     if (m->forwardVel > 16.0f) {
    347         m->faceAngle[0] += (m->forwardVel - 32.0f) * 6.0f;
    348     } else if (m->forwardVel > 4.0f) {
    349         m->faceAngle[0] += (m->forwardVel - 32.0f) * 10.0f;
    350     } else {
    351         m->faceAngle[0] -= 0x400;
    352     }
    353 
    354     m->faceAngle[0] += m->angleVel[0];
    355 
    356     if (m->faceAngle[0] > 0x2AAA) {
    357         m->faceAngle[0] = 0x2AAA;
    358     }
    359     if (m->faceAngle[0] < -0x2AAA) {
    360         m->faceAngle[0] = -0x2AAA;
    361     }
    362 
    363     m->vel[0] = m->forwardVel * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
    364     m->vel[1] = m->forwardVel * sins(m->faceAngle[0]);
    365     m->vel[2] = m->forwardVel * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
    366 
    367     m->slideVelX = m->vel[0];
    368     m->slideVelZ = m->vel[2];
    369 }
    370 
    371 u32 common_air_action_step(struct MarioState *m, u32 landAction, s32 animation, u32 stepArg) {
    372     u32 stepResult;
    373 
    374     update_air_without_turn(m);
    375 
    376     stepResult = perform_air_step(m, stepArg);
    377     switch (stepResult) {
    378         case AIR_STEP_NONE:
    379             set_mario_animation(m, animation);
    380             break;
    381 
    382         case AIR_STEP_LANDED:
    383             if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
    384                 set_mario_action(m, landAction, 0);
    385             }
    386             break;
    387 
    388         case AIR_STEP_HIT_WALL:
    389             set_mario_animation(m, animation);
    390 
    391             if (m->forwardVel > 16.0f) {
    392 #if ENABLE_RUMBLE
    393                 queue_rumble_data(5, 40);
    394 #endif
    395                 mario_bonk_reflection(m, FALSE);
    396                 m->faceAngle[1] += 0x8000;
    397 
    398                 if (m->wall != NULL) {
    399                     set_mario_action(m, ACT_AIR_HIT_WALL, 0);
    400                 } else {
    401                     if (m->vel[1] > 0.0f) {
    402                         m->vel[1] = 0.0f;
    403                     }
    404 
    405                     //! Hands-free holding. Bonking while no wall is referenced
    406                     // sets Mario's action to a non-holding action without
    407                     // dropping the object, causing the hands-free holding
    408                     // glitch. This can be achieved using an exposed ceiling,
    409                     // out of bounds, grazing the bottom of a wall while
    410                     // falling such that the final quarter step does not find a
    411                     // wall collision, or by rising into the top of a wall such
    412                     // that the final quarter step detects a ledge, but you are
    413                     // not able to ledge grab it.
    414                     if (m->forwardVel >= 38.0f) {
    415                         m->particleFlags |= PARTICLE_VERTICAL_STAR;
    416                         set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
    417                     } else {
    418                         if (m->forwardVel > 8.0f) {
    419                             mario_set_forward_vel(m, -8.0f);
    420                         }
    421                         return set_mario_action(m, ACT_SOFT_BONK, 0);
    422                     }
    423                 }
    424             } else {
    425                 mario_set_forward_vel(m, 0.0f);
    426             }
    427             break;
    428 
    429         case AIR_STEP_GRABBED_LEDGE:
    430             set_mario_animation(m, MARIO_ANIM_IDLE_ON_LEDGE);
    431             drop_and_set_mario_action(m, ACT_LEDGE_GRAB, 0);
    432             break;
    433 
    434         case AIR_STEP_GRABBED_CEILING:
    435             set_mario_action(m, ACT_START_HANGING, 0);
    436             break;
    437 
    438         case AIR_STEP_HIT_LAVA_WALL:
    439             lava_boost_on_wall(m);
    440             break;
    441     }
    442 
    443     return stepResult;
    444 }
    445 
    446 s32 act_jump(struct MarioState *m) {
    447     if (check_kick_or_dive_in_air(m)) {
    448         return TRUE;
    449     }
    450 
    451     if (m->input & INPUT_Z_PRESSED) {
    452         return set_mario_action(m, ACT_GROUND_POUND, 0);
    453     }
    454 
    455     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
    456     common_air_action_step(m, ACT_JUMP_LAND, MARIO_ANIM_SINGLE_JUMP,
    457                            AIR_STEP_CHECK_LEDGE_GRAB | AIR_STEP_CHECK_HANG);
    458     return FALSE;
    459 }
    460 
    461 s32 act_double_jump(struct MarioState *m) {
    462     s32 animation = (m->vel[1] >= 0.0f)
    463         ? MARIO_ANIM_DOUBLE_JUMP_RISE
    464         : MARIO_ANIM_DOUBLE_JUMP_FALL;
    465 
    466     if (check_kick_or_dive_in_air(m)) {
    467         return TRUE;
    468     }
    469 
    470     if (m->input & INPUT_Z_PRESSED) {
    471         return set_mario_action(m, ACT_GROUND_POUND, 0);
    472     }
    473 
    474     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_HOOHOO);
    475     common_air_action_step(m, ACT_DOUBLE_JUMP_LAND, animation,
    476                            AIR_STEP_CHECK_LEDGE_GRAB | AIR_STEP_CHECK_HANG);
    477     return FALSE;
    478 }
    479 
    480 s32 act_triple_jump(struct MarioState *m) {
    481     if (gSpecialTripleJump) {
    482         return set_mario_action(m, ACT_SPECIAL_TRIPLE_JUMP, 0);
    483     }
    484 
    485     if (m->input & INPUT_B_PRESSED) {
    486         return set_mario_action(m, ACT_DIVE, 0);
    487     }
    488 
    489     if (m->input & INPUT_Z_PRESSED) {
    490         return set_mario_action(m, ACT_GROUND_POUND, 0);
    491     }
    492 
    493 #ifndef VERSION_JP
    494     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
    495 #else
    496     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
    497 #endif
    498 
    499     common_air_action_step(m, ACT_TRIPLE_JUMP_LAND, MARIO_ANIM_TRIPLE_JUMP, 0);
    500 #if ENABLE_RUMBLE
    501     if (m->action == ACT_TRIPLE_JUMP_LAND) {
    502         queue_rumble_data(5, 40);
    503     }
    504 #endif
    505     play_flip_sounds(m, 2, 8, 20);
    506     return FALSE;
    507 }
    508 
    509 s32 act_backflip(struct MarioState *m) {
    510     if (m->input & INPUT_Z_PRESSED) {
    511         return set_mario_action(m, ACT_GROUND_POUND, 0);
    512     }
    513 
    514     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAH_WAH_HOO);
    515     common_air_action_step(m, ACT_BACKFLIP_LAND, MARIO_ANIM_BACKFLIP, 0);
    516 #if ENABLE_RUMBLE
    517     if (m->action == ACT_BACKFLIP_LAND) {
    518         queue_rumble_data(5, 40);
    519     }
    520 #endif
    521     play_flip_sounds(m, 2, 3, 17);
    522     return FALSE;
    523 }
    524 
    525 s32 act_freefall(struct MarioState *m) {
    526     s32 animation;
    527 
    528     if (m->input & INPUT_B_PRESSED) {
    529         return set_mario_action(m, ACT_DIVE, 0);
    530     }
    531 
    532     if (m->input & INPUT_Z_PRESSED) {
    533         return set_mario_action(m, ACT_GROUND_POUND, 0);
    534     }
    535 
    536     switch (m->actionArg) {
    537         case 0:
    538             animation = MARIO_ANIM_GENERAL_FALL;
    539             break;
    540         case 1:
    541             animation = MARIO_ANIM_FALL_FROM_SLIDE;
    542             break;
    543         case 2:
    544             animation = MARIO_ANIM_FALL_FROM_SLIDE_KICK;
    545             break;
    546     }
    547 
    548     common_air_action_step(m, ACT_FREEFALL_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB);
    549     return FALSE;
    550 }
    551 
    552 s32 act_hold_jump(struct MarioState *m) {
    553     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
    554         return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
    555     }
    556 
    557     if ((m->input & INPUT_B_PRESSED) && !(m->heldObj->oInteractionSubtype & INT_SUBTYPE_HOLDABLE_NPC)) {
    558         return set_mario_action(m, ACT_AIR_THROW, 0);
    559     }
    560 
    561     if (m->input & INPUT_Z_PRESSED) {
    562         return drop_and_set_mario_action(m, ACT_GROUND_POUND, 0);
    563     }
    564 
    565     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
    566     common_air_action_step(m, ACT_HOLD_JUMP_LAND, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ,
    567                            AIR_STEP_CHECK_LEDGE_GRAB);
    568     return FALSE;
    569 }
    570 
    571 s32 act_hold_freefall(struct MarioState *m) {
    572     s32 animation;
    573     if (m->actionArg == 0) {
    574         animation = MARIO_ANIM_FALL_WITH_LIGHT_OBJ;
    575     } else {
    576         animation = MARIO_ANIM_FALL_FROM_SLIDING_WITH_LIGHT_OBJ;
    577     }
    578 
    579     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
    580         return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
    581     }
    582 
    583     if ((m->input & INPUT_B_PRESSED) && !(m->heldObj->oInteractionSubtype & INT_SUBTYPE_HOLDABLE_NPC)) {
    584         return set_mario_action(m, ACT_AIR_THROW, 0);
    585     }
    586 
    587     if (m->input & INPUT_Z_PRESSED) {
    588         return drop_and_set_mario_action(m, ACT_GROUND_POUND, 0);
    589     }
    590 
    591     common_air_action_step(m, ACT_HOLD_FREEFALL_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB);
    592     return FALSE;
    593 }
    594 
    595 s32 act_side_flip(struct MarioState *m) {
    596     if (m->input & INPUT_B_PRESSED) {
    597         return set_mario_action(m, ACT_DIVE, 0);
    598     }
    599 
    600     if (m->input & INPUT_Z_PRESSED) {
    601         return set_mario_action(m, ACT_GROUND_POUND, 0);
    602     }
    603 
    604     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
    605 
    606     if (common_air_action_step(m, ACT_SIDE_FLIP_LAND, MARIO_ANIM_SLIDEFLIP, AIR_STEP_CHECK_LEDGE_GRAB)
    607         != AIR_STEP_GRABBED_LEDGE) {
    608         m->marioObj->header.gfx.angle[1] += 0x8000;
    609     }
    610 
    611     // This must be one line to match on -O2
    612     // clang-format off
    613     if (m->marioObj->header.gfx.animInfo.animFrame == 6) play_sound(SOUND_ACTION_SIDE_FLIP_UNK, m->marioObj->header.gfx.cameraToObject);
    614     // clang-format on
    615     return FALSE;
    616 }
    617 
    618 s32 act_wall_kick_air(struct MarioState *m) {
    619     if (m->input & INPUT_B_PRESSED) {
    620         return set_mario_action(m, ACT_DIVE, 0);
    621     }
    622 
    623     if (m->input & INPUT_Z_PRESSED) {
    624         return set_mario_action(m, ACT_GROUND_POUND, 0);
    625     }
    626 
    627     play_mario_jump_sound(m);
    628     common_air_action_step(m, ACT_JUMP_LAND, MARIO_ANIM_SLIDEJUMP, AIR_STEP_CHECK_LEDGE_GRAB);
    629     return FALSE;
    630 }
    631 
    632 s32 act_long_jump(struct MarioState *m) {
    633     s32 animation;
    634     if (!m->marioObj->oMarioLongJumpIsSlow) {
    635         animation = MARIO_ANIM_FAST_LONGJUMP;
    636     } else {
    637         animation = MARIO_ANIM_SLOW_LONGJUMP;
    638     }
    639 
    640     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
    641 
    642     if (m->floor->type == SURFACE_VERTICAL_WIND && m->actionState == 0) {
    643         play_sound(SOUND_MARIO_HERE_WE_GO, m->marioObj->header.gfx.cameraToObject);
    644         m->actionState = 1;
    645     }
    646 
    647     common_air_action_step(m, ACT_LONG_JUMP_LAND, animation, AIR_STEP_CHECK_LEDGE_GRAB);
    648 #if ENABLE_RUMBLE
    649     if (m->action == ACT_LONG_JUMP_LAND) {
    650         queue_rumble_data(5, 40);
    651     }
    652 #endif
    653     return FALSE;
    654 }
    655 
    656 s32 act_riding_shell_air(struct MarioState *m) {
    657     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
    658     set_mario_animation(m, MARIO_ANIM_JUMP_RIDING_SHELL);
    659 
    660     update_air_without_turn(m);
    661 
    662     switch (perform_air_step(m, 0)) {
    663         case AIR_STEP_LANDED:
    664             set_mario_action(m, ACT_RIDING_SHELL_GROUND, 1);
    665             break;
    666 
    667         case AIR_STEP_HIT_WALL:
    668             mario_set_forward_vel(m, 0.0f);
    669             break;
    670 
    671         case AIR_STEP_HIT_LAVA_WALL:
    672             lava_boost_on_wall(m);
    673             break;
    674     }
    675 
    676     m->marioObj->header.gfx.pos[1] += 42.0f;
    677     return FALSE;
    678 }
    679 
    680 s32 act_twirling(struct MarioState *m) {
    681     s16 startTwirlYaw = m->twirlYaw;
    682     s16 yawVelTarget;
    683 
    684     if (m->input & INPUT_A_DOWN) {
    685         yawVelTarget = 0x2000;
    686     } else {
    687         yawVelTarget = 0x1800;
    688     }
    689 
    690     m->angleVel[1] = approach_s32(m->angleVel[1], yawVelTarget, 0x200, 0x200);
    691     m->twirlYaw += m->angleVel[1];
    692 
    693     set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_START_TWIRL : MARIO_ANIM_TWIRL);
    694     if (is_anim_past_end(m)) {
    695         m->actionArg = 1;
    696     }
    697 
    698     if (startTwirlYaw > m->twirlYaw) {
    699         play_sound(SOUND_ACTION_TWIRL, m->marioObj->header.gfx.cameraToObject);
    700     }
    701 
    702     update_lava_boost_or_twirling(m);
    703 
    704     switch (perform_air_step(m, 0)) {
    705         case AIR_STEP_LANDED:
    706             set_mario_action(m, ACT_TWIRL_LAND, 0);
    707             break;
    708 
    709         case AIR_STEP_HIT_WALL:
    710             mario_bonk_reflection(m, FALSE);
    711             break;
    712 
    713         case AIR_STEP_HIT_LAVA_WALL:
    714             lava_boost_on_wall(m);
    715             break;
    716     }
    717 
    718     m->marioObj->header.gfx.angle[1] += m->twirlYaw;
    719 #if ENABLE_RUMBLE
    720     reset_rumble_timers();
    721 #endif
    722     return FALSE;
    723 }
    724 
    725 s32 act_dive(struct MarioState *m) {
    726     if (m->actionArg == 0) {
    727         play_mario_sound(m, SOUND_ACTION_THROW, SOUND_MARIO_HOOHOO);
    728     } else {
    729         play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
    730     }
    731 
    732     set_mario_animation(m, MARIO_ANIM_DIVE);
    733     if (mario_check_object_grab(m)) {
    734         mario_grab_used_object(m);
    735         m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ;
    736         if (m->action != ACT_DIVE) {
    737             return TRUE;
    738         }
    739     }
    740 
    741     update_air_without_turn(m);
    742 
    743     switch (perform_air_step(m, 0)) {
    744         case AIR_STEP_NONE:
    745             if (m->vel[1] < 0.0f && m->faceAngle[0] > -0x2AAA) {
    746                 m->faceAngle[0] -= 0x200;
    747                 if (m->faceAngle[0] < -0x2AAA) {
    748                     m->faceAngle[0] = -0x2AAA;
    749                 }
    750             }
    751             m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
    752             break;
    753 
    754         case AIR_STEP_LANDED:
    755             if (should_get_stuck_in_ground(m) && m->faceAngle[0] == -0x2AAA) {
    756 #if ENABLE_RUMBLE
    757                 queue_rumble_data(5, 80);
    758 #endif
    759 #ifdef VERSION_JP
    760                 play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
    761 #else
    762                 play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
    763 #endif
    764                 m->particleFlags |= PARTICLE_MIST_CIRCLE;
    765                 drop_and_set_mario_action(m, ACT_HEAD_STUCK_IN_GROUND, 0);
    766             } else if (!check_fall_damage(m, ACT_HARD_FORWARD_GROUND_KB)) {
    767                 if (m->heldObj == NULL) {
    768                     set_mario_action(m, ACT_DIVE_SLIDE, 0);
    769                 } else {
    770                     set_mario_action(m, ACT_DIVE_PICKING_UP, 0);
    771                 }
    772             }
    773             m->faceAngle[0] = 0;
    774             break;
    775 
    776         case AIR_STEP_HIT_WALL:
    777             mario_bonk_reflection(m, TRUE);
    778             m->faceAngle[0] = 0;
    779 
    780             if (m->vel[1] > 0.0f) {
    781                 m->vel[1] = 0.0f;
    782             }
    783 
    784             m->particleFlags |= PARTICLE_VERTICAL_STAR;
    785             drop_and_set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
    786             break;
    787 
    788         case AIR_STEP_HIT_LAVA_WALL:
    789             lava_boost_on_wall(m);
    790             break;
    791     }
    792 
    793     return FALSE;
    794 }
    795 
    796 s32 act_air_throw(struct MarioState *m) {
    797     if (++(m->actionTimer) == 4) {
    798         mario_throw_held_object(m);
    799     }
    800 
    801     play_sound_if_no_flag(m, SOUND_MARIO_WAH2, MARIO_MARIO_SOUND_PLAYED);
    802     set_mario_animation(m, MARIO_ANIM_THROW_LIGHT_OBJECT);
    803     update_air_without_turn(m);
    804 
    805     switch (perform_air_step(m, 0)) {
    806         case AIR_STEP_LANDED:
    807             if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
    808                 m->action = ACT_AIR_THROW_LAND;
    809             }
    810             break;
    811 
    812         case AIR_STEP_HIT_WALL:
    813             mario_set_forward_vel(m, 0.0f);
    814             break;
    815 
    816         case AIR_STEP_HIT_LAVA_WALL:
    817             lava_boost_on_wall(m);
    818             break;
    819     }
    820 
    821     return FALSE;
    822 }
    823 
    824 s32 act_water_jump(struct MarioState *m) {
    825     if (m->forwardVel < 15.0f) {
    826         mario_set_forward_vel(m, 15.0f);
    827     }
    828 
    829     play_mario_sound(m, SOUND_ACTION_UNKNOWN432, 0);
    830     set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP);
    831 
    832     switch (perform_air_step(m, AIR_STEP_CHECK_LEDGE_GRAB)) {
    833         case AIR_STEP_LANDED:
    834             set_mario_action(m, ACT_JUMP_LAND, 0);
    835             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
    836             break;
    837 
    838         case AIR_STEP_HIT_WALL:
    839             mario_set_forward_vel(m, 15.0f);
    840             break;
    841 
    842         case AIR_STEP_GRABBED_LEDGE:
    843 #ifndef VERSION_JP
    844             set_mario_animation(m, MARIO_ANIM_IDLE_ON_LEDGE);
    845 #endif
    846             set_mario_action(m, ACT_LEDGE_GRAB, 0);
    847             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
    848             break;
    849 
    850         case AIR_STEP_HIT_LAVA_WALL:
    851             lava_boost_on_wall(m);
    852             break;
    853     }
    854 
    855     return FALSE;
    856 }
    857 
    858 s32 act_hold_water_jump(struct MarioState *m) {
    859     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
    860         return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
    861     }
    862 
    863     if (m->forwardVel < 15.0f) {
    864         mario_set_forward_vel(m, 15.0f);
    865     }
    866 
    867     play_mario_sound(m, SOUND_ACTION_UNKNOWN432, 0);
    868     set_mario_animation(m, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ);
    869 
    870     switch (perform_air_step(m, 0)) {
    871         case AIR_STEP_LANDED:
    872             set_mario_action(m, ACT_HOLD_JUMP_LAND, 0);
    873             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
    874             break;
    875 
    876         case AIR_STEP_HIT_WALL:
    877             mario_set_forward_vel(m, 15.0f);
    878             break;
    879 
    880         case AIR_STEP_HIT_LAVA_WALL:
    881             lava_boost_on_wall(m);
    882             break;
    883     }
    884 
    885     return FALSE;
    886 }
    887 
    888 s32 act_steep_jump(struct MarioState *m) {
    889     if (m->input & INPUT_B_PRESSED) {
    890         return set_mario_action(m, ACT_DIVE, 0);
    891     }
    892 
    893     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
    894     mario_set_forward_vel(m, 0.98f * m->forwardVel);
    895 
    896     switch (perform_air_step(m, 0)) {
    897         case AIR_STEP_LANDED:
    898             if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
    899                 m->faceAngle[0] = 0;
    900                 set_mario_action(m, m->forwardVel < 0.0f ? ACT_BEGIN_SLIDING : ACT_JUMP_LAND, 0);
    901             }
    902             break;
    903 
    904         case AIR_STEP_HIT_WALL:
    905             mario_set_forward_vel(m, 0.0f);
    906             break;
    907 
    908         case AIR_STEP_HIT_LAVA_WALL:
    909             lava_boost_on_wall(m);
    910             break;
    911     }
    912 
    913     set_mario_animation(m, MARIO_ANIM_SINGLE_JUMP);
    914     m->marioObj->header.gfx.angle[1] = m->marioObj->oMarioSteepJumpYaw;
    915     return FALSE;
    916 }
    917 
    918 s32 act_ground_pound(struct MarioState *m) {
    919     u32 stepResult;
    920     f32 yOffset;
    921 
    922     play_sound_if_no_flag(m, SOUND_ACTION_THROW, MARIO_ACTION_SOUND_PLAYED);
    923 
    924     if (m->actionState == 0) {
    925         if (m->actionTimer < 10) {
    926             yOffset = 20 - 2 * m->actionTimer;
    927             if (m->pos[1] + yOffset + 160.0f < m->ceilHeight) {
    928                 m->pos[1] += yOffset;
    929                 m->peakHeight = m->pos[1];
    930                 vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
    931             }
    932         }
    933 
    934         m->vel[1] = -50.0f;
    935         mario_set_forward_vel(m, 0.0f);
    936 
    937         set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_START_GROUND_POUND
    938                                                  : MARIO_ANIM_TRIPLE_JUMP_GROUND_POUND);
    939         if (m->actionTimer == 0) {
    940             play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
    941         }
    942 
    943         m->actionTimer++;
    944         if (m->actionTimer >= m->marioObj->header.gfx.animInfo.curAnim->loopEnd + 4) {
    945             play_sound(SOUND_MARIO_GROUND_POUND_WAH, m->marioObj->header.gfx.cameraToObject);
    946             m->actionState = 1;
    947         }
    948     } else {
    949         set_mario_animation(m, MARIO_ANIM_GROUND_POUND);
    950 
    951         stepResult = perform_air_step(m, 0);
    952         if (stepResult == AIR_STEP_LANDED) {
    953             if (should_get_stuck_in_ground(m)) {
    954 #if ENABLE_RUMBLE
    955                 queue_rumble_data(5, 80);
    956 #endif
    957 #ifdef VERSION_JP
    958                 play_sound(SOUND_MARIO_OOOF, m->marioObj->header.gfx.cameraToObject);
    959 #else
    960                 play_sound(SOUND_MARIO_OOOF2, m->marioObj->header.gfx.cameraToObject);
    961 #endif
    962                 m->particleFlags |= PARTICLE_MIST_CIRCLE;
    963                 set_mario_action(m, ACT_BUTT_STUCK_IN_GROUND, 0);
    964             } else {
    965                 play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_HEAVY_LANDING);
    966                 if (!check_fall_damage(m, ACT_HARD_BACKWARD_GROUND_KB)) {
    967                     m->particleFlags |= PARTICLE_MIST_CIRCLE | PARTICLE_HORIZONTAL_STAR;
    968                     set_mario_action(m, ACT_GROUND_POUND_LAND, 0);
    969                 }
    970             }
    971             set_camera_shake_from_hit(SHAKE_GROUND_POUND);
    972         } else if (stepResult == AIR_STEP_HIT_WALL) {
    973             mario_set_forward_vel(m, -16.0f);
    974             if (m->vel[1] > 0.0f) {
    975                 m->vel[1] = 0.0f;
    976             }
    977 
    978             m->particleFlags |= PARTICLE_VERTICAL_STAR;
    979             set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
    980         }
    981     }
    982 
    983     return FALSE;
    984 }
    985 
    986 s32 act_burning_jump(struct MarioState *m) {
    987     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, m->actionArg == 0 ? 0 : -1);
    988     mario_set_forward_vel(m, m->forwardVel);
    989 
    990     if (perform_air_step(m, 0) == AIR_STEP_LANDED) {
    991         play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
    992         set_mario_action(m, ACT_BURNING_GROUND, 0);
    993     }
    994 
    995     set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_SINGLE_JUMP : MARIO_ANIM_FIRE_LAVA_BURN);
    996     m->particleFlags |= PARTICLE_FIRE;
    997     play_sound(SOUND_MOVING_LAVA_BURN, m->marioObj->header.gfx.cameraToObject);
    998 
    999     m->marioObj->oMarioBurnTimer += 3;
   1000 
   1001     m->health -= 10;
   1002     if (m->health < 0x100) {
   1003         m->health = 0xFF;
   1004     }
   1005 #if ENABLE_RUMBLE
   1006     reset_rumble_timers();
   1007 #endif
   1008     return FALSE;
   1009 }
   1010 
   1011 s32 act_burning_fall(struct MarioState *m) {
   1012     mario_set_forward_vel(m, m->forwardVel);
   1013 
   1014     if (perform_air_step(m, 0) == AIR_STEP_LANDED) {
   1015         play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1016         set_mario_action(m, ACT_BURNING_GROUND, 0);
   1017     }
   1018 
   1019     set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
   1020     m->particleFlags |= PARTICLE_FIRE;
   1021     m->marioObj->oMarioBurnTimer += 3;
   1022 
   1023     m->health -= 10;
   1024     if (m->health < 0x100) {
   1025         m->health = 0xFF;
   1026     }
   1027 #if ENABLE_RUMBLE
   1028     reset_rumble_timers();
   1029 #endif
   1030     return FALSE;
   1031 }
   1032 
   1033 s32 act_crazy_box_bounce(struct MarioState *m) {
   1034     f32 minSpeed;
   1035 
   1036     if (m->actionTimer == 0) {
   1037         switch (m->actionArg) {
   1038             case 0:
   1039                 m->vel[1] = 45.0f;
   1040                 minSpeed = 32.0f;
   1041                 break;
   1042 
   1043             case 1:
   1044                 m->vel[1] = 60.0f;
   1045                 minSpeed = 36.0f;
   1046                 break;
   1047 
   1048             case 2:
   1049                 m->vel[1] = 100.0f;
   1050                 minSpeed = 48.0f;
   1051                 break;
   1052         }
   1053 
   1054         play_sound(minSpeed < 40.0f ? SOUND_GENERAL_BOING1 : SOUND_GENERAL_BOING2,
   1055                    m->marioObj->header.gfx.cameraToObject);
   1056 
   1057         if (m->forwardVel < minSpeed) {
   1058             mario_set_forward_vel(m, minSpeed);
   1059         }
   1060 
   1061         m->actionTimer = 1;
   1062     }
   1063 
   1064     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
   1065     set_mario_animation(m, MARIO_ANIM_DIVE);
   1066 
   1067     update_air_without_turn(m);
   1068 
   1069     switch (perform_air_step(m, 0)) {
   1070         case AIR_STEP_LANDED:
   1071             if (m->actionArg < 2) {
   1072                 set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, m->actionArg + 1);
   1073             } else {
   1074                 m->heldObj->oInteractStatus = INT_STATUS_STOP_RIDING;
   1075                 m->heldObj = NULL;
   1076                 set_mario_action(m, ACT_STOMACH_SLIDE, 0);
   1077             }
   1078 #if ENABLE_RUMBLE
   1079             queue_rumble_data(5, 80);
   1080 #endif
   1081             m->particleFlags |= PARTICLE_MIST_CIRCLE;
   1082             break;
   1083 
   1084         case AIR_STEP_HIT_WALL:
   1085             mario_bonk_reflection(m, FALSE);
   1086             break;
   1087 
   1088         case AIR_STEP_HIT_LAVA_WALL:
   1089             lava_boost_on_wall(m);
   1090             break;
   1091     }
   1092 
   1093     m->marioObj->header.gfx.angle[0] = atan2s(m->forwardVel, -m->vel[1]);
   1094     return FALSE;
   1095 }
   1096 
   1097 u32 common_air_knockback_step(struct MarioState *m, u32 landAction, u32 hardFallAction, s32 animation,
   1098                               f32 speed) {
   1099     u32 stepResult;
   1100 
   1101     mario_set_forward_vel(m, speed);
   1102 
   1103     stepResult = perform_air_step(m, 0);
   1104     switch (stepResult) {
   1105         case AIR_STEP_NONE:
   1106             set_mario_animation(m, animation);
   1107             break;
   1108 
   1109         case AIR_STEP_LANDED:
   1110 #if ENABLE_RUMBLE
   1111             if (m->action != ACT_SOFT_BONK) {
   1112                 queue_rumble_data(5, 40);
   1113             }
   1114 #endif
   1115             if (!check_fall_damage_or_get_stuck(m, hardFallAction)) {
   1116 #ifndef VERSION_JP
   1117                 if (m->action == ACT_THROWN_FORWARD || m->action == ACT_THROWN_BACKWARD) {
   1118                     set_mario_action(m, landAction, m->hurtCounter);
   1119                 } else {
   1120                     set_mario_action(m, landAction, m->actionArg);
   1121                 }
   1122 #else
   1123                 set_mario_action(m, landAction, m->actionArg);
   1124 #endif
   1125             }
   1126             break;
   1127 
   1128         case AIR_STEP_HIT_WALL:
   1129             set_mario_animation(m, MARIO_ANIM_BACKWARD_AIR_KB);
   1130             mario_bonk_reflection(m, FALSE);
   1131 
   1132             if (m->vel[1] > 0.0f) {
   1133                 m->vel[1] = 0.0f;
   1134             }
   1135 
   1136             mario_set_forward_vel(m, -speed);
   1137             break;
   1138 
   1139         case AIR_STEP_HIT_LAVA_WALL:
   1140             lava_boost_on_wall(m);
   1141             break;
   1142     }
   1143 
   1144     return stepResult;
   1145 }
   1146 
   1147 s32 check_wall_kick(struct MarioState *m) {
   1148     if ((m->input & INPUT_A_PRESSED) && m->wallKickTimer != 0 && m->prevAction == ACT_AIR_HIT_WALL) {
   1149         m->faceAngle[1] += 0x8000;
   1150         return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
   1151     }
   1152 
   1153     return FALSE;
   1154 }
   1155 
   1156 s32 act_backward_air_kb(struct MarioState *m) {
   1157     if (check_wall_kick(m)) {
   1158         return TRUE;
   1159     }
   1160 
   1161 #ifndef VERSION_JP
   1162     play_knockback_sound(m);
   1163 #else
   1164     play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
   1165 #endif
   1166     common_air_knockback_step(m, ACT_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB, 0x0002, -16.0f);
   1167     return FALSE;
   1168 }
   1169 
   1170 s32 act_forward_air_kb(struct MarioState *m) {
   1171     if (check_wall_kick(m)) {
   1172         return TRUE;
   1173     }
   1174 
   1175 #ifndef VERSION_JP
   1176     play_knockback_sound(m);
   1177 #else
   1178     play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
   1179 #endif
   1180     common_air_knockback_step(m, ACT_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB, 0x002D, 16.0f);
   1181     return FALSE;
   1182 }
   1183 
   1184 s32 act_hard_backward_air_kb(struct MarioState *m) {
   1185 #ifndef VERSION_JP
   1186     play_knockback_sound(m);
   1187 #else
   1188     play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
   1189 #endif
   1190     common_air_knockback_step(m, ACT_HARD_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB, 0x0002,
   1191                               -16.0f);
   1192     return FALSE;
   1193 }
   1194 
   1195 s32 act_hard_forward_air_kb(struct MarioState *m) {
   1196 #ifndef VERSION_JP
   1197     play_knockback_sound(m);
   1198 #else
   1199     play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
   1200 #endif
   1201     common_air_knockback_step(m, ACT_HARD_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB, 0x002D, 16.0f);
   1202     return FALSE;
   1203 }
   1204 
   1205 s32 act_thrown_backward(struct MarioState *m) {
   1206     u32 landAction;
   1207     if (m->actionArg != 0) {
   1208         landAction = ACT_HARD_BACKWARD_GROUND_KB;
   1209     } else {
   1210         landAction = ACT_BACKWARD_GROUND_KB;
   1211     }
   1212 
   1213     play_sound_if_no_flag(m, SOUND_MARIO_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED);
   1214 
   1215     common_air_knockback_step(m, landAction, ACT_HARD_BACKWARD_GROUND_KB, 0x0002, m->forwardVel);
   1216 
   1217     m->forwardVel *= 0.98f;
   1218     return FALSE;
   1219 }
   1220 
   1221 s32 act_thrown_forward(struct MarioState *m) {
   1222     s16 pitch;
   1223 
   1224     u32 landAction;
   1225     if (m->actionArg != 0) {
   1226         landAction = ACT_HARD_FORWARD_GROUND_KB;
   1227     } else {
   1228         landAction = ACT_FORWARD_GROUND_KB;
   1229     }
   1230 
   1231     play_sound_if_no_flag(m, SOUND_MARIO_WAAAOOOW, MARIO_MARIO_SOUND_PLAYED);
   1232 
   1233     if (common_air_knockback_step(m, landAction, ACT_HARD_FORWARD_GROUND_KB, 0x002D, m->forwardVel)
   1234         == AIR_STEP_NONE) {
   1235         pitch = atan2s(m->forwardVel, -m->vel[1]);
   1236         if (pitch > 0x1800) {
   1237             pitch = 0x1800;
   1238         }
   1239 
   1240         m->marioObj->header.gfx.angle[0] = pitch + 0x1800;
   1241     }
   1242 
   1243     m->forwardVel *= 0.98f;
   1244     return FALSE;
   1245 }
   1246 
   1247 s32 act_soft_bonk(struct MarioState *m) {
   1248     if (check_wall_kick(m)) {
   1249         return TRUE;
   1250     }
   1251 
   1252 #ifndef VERSION_JP
   1253     play_knockback_sound(m);
   1254 #else
   1255     play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
   1256 #endif
   1257 
   1258     common_air_knockback_step(m, ACT_FREEFALL_LAND, ACT_HARD_BACKWARD_GROUND_KB, 0x0056, m->forwardVel);
   1259     return FALSE;
   1260 }
   1261 
   1262 s32 act_getting_blown(struct MarioState *m) {
   1263     if (m->actionState == 0) {
   1264         if (m->forwardVel > -60.0f) {
   1265             m->forwardVel -= 6.0f;
   1266         } else {
   1267             m->actionState = 1;
   1268         }
   1269     } else {
   1270         if (m->forwardVel < -16.0f) {
   1271             m->forwardVel += 0.8f;
   1272         }
   1273 
   1274         if (m->vel[1] < 0.0f && m->gettingBlownGravity < 4.0f) {
   1275             m->gettingBlownGravity += 0.05f;
   1276         }
   1277     }
   1278 
   1279     if (++(m->actionTimer) == 20) {
   1280         mario_blow_off_cap(m, 50.0f);
   1281     }
   1282 
   1283     mario_set_forward_vel(m, m->forwardVel);
   1284 #ifdef VERSION_JP
   1285     play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
   1286 #endif
   1287     set_mario_animation(m, MARIO_ANIM_BACKWARD_AIR_KB);
   1288 
   1289     switch (perform_air_step(m, 0)) {
   1290         case AIR_STEP_LANDED:
   1291             set_mario_action(m, ACT_HARD_BACKWARD_AIR_KB, 0);
   1292             break;
   1293 
   1294         case AIR_STEP_HIT_WALL:
   1295             set_mario_animation(m, MARIO_ANIM_AIR_FORWARD_KB);
   1296             mario_bonk_reflection(m, FALSE);
   1297 
   1298             if (m->vel[1] > 0.0f) {
   1299                 m->vel[1] = 0.0f;
   1300             }
   1301 
   1302             mario_set_forward_vel(m, -m->forwardVel);
   1303             break;
   1304     }
   1305 
   1306     return FALSE;
   1307 }
   1308 
   1309 s32 act_air_hit_wall(struct MarioState *m) {
   1310     if (m->heldObj != NULL) {
   1311         mario_drop_held_object(m);
   1312     }
   1313 
   1314     if (++(m->actionTimer) <= 2) {
   1315         if (m->input & INPUT_A_PRESSED) {
   1316             m->vel[1] = 52.0f;
   1317             m->faceAngle[1] += 0x8000;
   1318             return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
   1319         }
   1320     } else if (m->forwardVel >= 38.0f) {
   1321         m->wallKickTimer = 5;
   1322         if (m->vel[1] > 0.0f) {
   1323             m->vel[1] = 0.0f;
   1324         }
   1325 
   1326         m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1327         return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
   1328     } else {
   1329         m->wallKickTimer = 5;
   1330         if (m->vel[1] > 0.0f) {
   1331             m->vel[1] = 0.0f;
   1332         }
   1333 
   1334         if (m->forwardVel > 8.0f) {
   1335             mario_set_forward_vel(m, -8.0f);
   1336         }
   1337         return set_mario_action(m, ACT_SOFT_BONK, 0);
   1338     }
   1339 
   1340 #ifdef AVOID_UB
   1341     return
   1342 #endif
   1343     set_mario_animation(m, MARIO_ANIM_START_WALLKICK);
   1344 
   1345     //! Missing return statement. The returned value is the result of the call
   1346     // to set_mario_animation. In practice, this value is nonzero.
   1347     // This results in this action "cancelling" into itself. It is supposed to
   1348     // execute on two frames, but instead it executes twice on the same frame.
   1349     // This results in firsties only being possible for a single frame, instead
   1350     // of two.
   1351 }
   1352 
   1353 s32 act_forward_rollout(struct MarioState *m) {
   1354     if (m->actionState == 0) {
   1355         m->vel[1] = 30.0f;
   1356         m->actionState = 1;
   1357     }
   1358 
   1359     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
   1360 
   1361     update_air_without_turn(m);
   1362 
   1363     switch (perform_air_step(m, 0)) {
   1364         case AIR_STEP_NONE:
   1365             if (m->actionState == 1) {
   1366                 if (set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING) == 4) {
   1367                     play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
   1368                 }
   1369             } else {
   1370                 set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
   1371             }
   1372             break;
   1373 
   1374         case AIR_STEP_LANDED:
   1375             set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
   1376             play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1377             break;
   1378 
   1379         case AIR_STEP_HIT_WALL:
   1380             mario_set_forward_vel(m, 0.0f);
   1381             break;
   1382 
   1383         case AIR_STEP_HIT_LAVA_WALL:
   1384             lava_boost_on_wall(m);
   1385             break;
   1386     }
   1387 
   1388     if (m->actionState == 1 && is_anim_past_end(m)) {
   1389         m->actionState = 2;
   1390     }
   1391     return FALSE;
   1392 }
   1393 
   1394 s32 act_backward_rollout(struct MarioState *m) {
   1395     if (m->actionState == 0) {
   1396         m->vel[1] = 30.0f;
   1397         m->actionState = 1;
   1398     }
   1399 
   1400     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, 0);
   1401 
   1402     update_air_without_turn(m);
   1403 
   1404     switch (perform_air_step(m, 0)) {
   1405         case AIR_STEP_NONE:
   1406             if (m->actionState == 1) {
   1407                 if (set_mario_animation(m, MARIO_ANIM_BACKWARD_SPINNING) == 4) {
   1408                     play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
   1409                 }
   1410             } else {
   1411                 set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
   1412             }
   1413             break;
   1414 
   1415         case AIR_STEP_LANDED:
   1416             set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
   1417             play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1418             break;
   1419 
   1420         case AIR_STEP_HIT_WALL:
   1421             mario_set_forward_vel(m, 0.0f);
   1422             break;
   1423 
   1424         case AIR_STEP_HIT_LAVA_WALL:
   1425             lava_boost_on_wall(m);
   1426             break;
   1427     }
   1428 
   1429     if (m->actionState == 1 && m->marioObj->header.gfx.animInfo.animFrame == 2) {
   1430         m->actionState = 2;
   1431     }
   1432     return FALSE;
   1433 }
   1434 
   1435 s32 act_butt_slide_air(struct MarioState *m) {
   1436     if (++(m->actionTimer) > 30 && m->pos[1] - m->floorHeight > 500.0f) {
   1437         return set_mario_action(m, ACT_FREEFALL, 1);
   1438     }
   1439 
   1440     update_air_with_turn(m);
   1441 
   1442     switch (perform_air_step(m, 0)) {
   1443         case AIR_STEP_LANDED:
   1444             if (m->actionState == 0 && m->vel[1] < 0.0f && m->floor->normal.y >= 0.9848077f) {
   1445                 m->vel[1] = -m->vel[1] / 2.0f;
   1446                 m->actionState = 1;
   1447             } else {
   1448                 set_mario_action(m, ACT_BUTT_SLIDE, 0);
   1449             }
   1450             play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1451             break;
   1452 
   1453         case AIR_STEP_HIT_WALL:
   1454             if (m->vel[1] > 0.0f) {
   1455                 m->vel[1] = 0.0f;
   1456             }
   1457             m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1458             set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
   1459             break;
   1460 
   1461         case AIR_STEP_HIT_LAVA_WALL:
   1462             lava_boost_on_wall(m);
   1463             break;
   1464     }
   1465 
   1466     set_mario_animation(m, MARIO_ANIM_SLIDE);
   1467     return FALSE;
   1468 }
   1469 
   1470 s32 act_hold_butt_slide_air(struct MarioState *m) {
   1471     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
   1472         return drop_and_set_mario_action(m, ACT_HOLD_FREEFALL, 1);
   1473     }
   1474 
   1475     if (++m->actionTimer > 30 && m->pos[1] - m->floorHeight > 500.0f) {
   1476         return set_mario_action(m, ACT_HOLD_FREEFALL, 1);
   1477     }
   1478 
   1479     update_air_with_turn(m);
   1480 
   1481     switch (perform_air_step(m, 0)) {
   1482         case AIR_STEP_LANDED:
   1483             if (m->actionState == 0 && m->vel[1] < 0.0f && m->floor->normal.y >= 0.9848077f) {
   1484                 m->vel[1] = -m->vel[1] / 2.0f;
   1485                 m->actionState = 1;
   1486             } else {
   1487                 set_mario_action(m, ACT_HOLD_BUTT_SLIDE, 0);
   1488             }
   1489             play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1490             break;
   1491 
   1492         case AIR_STEP_HIT_WALL:
   1493             if (m->vel[1] > 0.0f) {
   1494                 m->vel[1] = 0.0f;
   1495             }
   1496 
   1497             mario_drop_held_object(m);
   1498             m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1499             set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
   1500             break;
   1501 
   1502         case AIR_STEP_HIT_LAVA_WALL:
   1503             lava_boost_on_wall(m);
   1504             break;
   1505     }
   1506 
   1507     set_mario_animation(m, MARIO_ANIM_SLIDING_ON_BOTTOM_WITH_LIGHT_OBJ);
   1508     return FALSE;
   1509 }
   1510 
   1511 s32 act_lava_boost(struct MarioState *m) {
   1512 #if ENABLE_RUMBLE
   1513     if (!(m->flags & MARIO_MARIO_SOUND_PLAYED)) {
   1514 #endif
   1515         play_sound_if_no_flag(m, SOUND_MARIO_ON_FIRE, MARIO_MARIO_SOUND_PLAYED);
   1516 #if ENABLE_RUMBLE
   1517         queue_rumble_data(5, 80);
   1518     }
   1519 #endif
   1520 
   1521     if (!(m->input & INPUT_NONZERO_ANALOG)) {
   1522         m->forwardVel = approach_f32(m->forwardVel, 0.0f, 0.35f, 0.35f);
   1523     }
   1524 
   1525     update_lava_boost_or_twirling(m);
   1526 
   1527     switch (perform_air_step(m, 0)) {
   1528         case AIR_STEP_LANDED:
   1529             if (m->floor->type == SURFACE_BURNING) {
   1530                 m->actionState = 0;
   1531                 if (!(m->flags & MARIO_METAL_CAP)) {
   1532                     m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18;
   1533                 }
   1534                 m->vel[1] = 84.0f;
   1535                 play_sound(SOUND_MARIO_ON_FIRE, m->marioObj->header.gfx.cameraToObject);
   1536 #if ENABLE_RUMBLE
   1537                 queue_rumble_data(5, 80);
   1538 #endif
   1539             } else {
   1540                 play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
   1541                 if (m->actionState < 2 && m->vel[1] < 0.0f) {
   1542                     m->vel[1] = -m->vel[1] * 0.4f;
   1543                     mario_set_forward_vel(m, m->forwardVel * 0.5f);
   1544                     m->actionState++;
   1545                 } else {
   1546                     set_mario_action(m, ACT_LAVA_BOOST_LAND, 0);
   1547                 }
   1548             }
   1549             break;
   1550 
   1551         case AIR_STEP_HIT_WALL:
   1552             mario_bonk_reflection(m, FALSE);
   1553             break;
   1554 
   1555         case AIR_STEP_HIT_LAVA_WALL:
   1556             lava_boost_on_wall(m);
   1557             break;
   1558     }
   1559 
   1560     set_mario_animation(m, MARIO_ANIM_FIRE_LAVA_BURN);
   1561     if ((m->area->terrainType & TERRAIN_MASK) != TERRAIN_SNOW && !(m->flags & MARIO_METAL_CAP)
   1562         && m->vel[1] > 0.0f) {
   1563         m->particleFlags |= PARTICLE_FIRE;
   1564         if (m->actionState == 0) {
   1565             play_sound(SOUND_MOVING_LAVA_BURN, m->marioObj->header.gfx.cameraToObject);
   1566         }
   1567     }
   1568 
   1569     if (m->health < 0x100) {
   1570         level_trigger_warp(m, WARP_OP_DEATH);
   1571     }
   1572 
   1573     m->marioBodyState->eyeState = MARIO_EYES_DEAD;
   1574 #if ENABLE_RUMBLE
   1575     reset_rumble_timers();
   1576 #endif
   1577     return FALSE;
   1578 }
   1579 
   1580 s32 act_slide_kick(struct MarioState *m) {
   1581     if (m->actionState == 0 && m->actionTimer == 0) {
   1582         play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_HOOHOO);
   1583         set_mario_animation(m, MARIO_ANIM_SLIDE_KICK);
   1584     }
   1585 
   1586     if (++(m->actionTimer) > 30 && m->pos[1] - m->floorHeight > 500.0f) {
   1587         return set_mario_action(m, ACT_FREEFALL, 2);
   1588     }
   1589 
   1590     update_air_without_turn(m);
   1591 
   1592     switch (perform_air_step(m, 0)) {
   1593         case AIR_STEP_NONE:
   1594             if (m->actionState == 0) {
   1595                 m->marioObj->header.gfx.angle[0] = atan2s(m->forwardVel, -m->vel[1]);
   1596                 if (m->marioObj->header.gfx.angle[0] > 0x1800) {
   1597                     m->marioObj->header.gfx.angle[0] = 0x1800;
   1598                 }
   1599             }
   1600             break;
   1601 
   1602         case AIR_STEP_LANDED:
   1603             if (m->actionState == 0 && m->vel[1] < 0.0f) {
   1604                 m->vel[1] = -m->vel[1] / 2.0f;
   1605                 m->actionState = 1;
   1606                 m->actionTimer = 0;
   1607             } else {
   1608                 set_mario_action(m, ACT_SLIDE_KICK_SLIDE, 0);
   1609             }
   1610             play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1611             break;
   1612 
   1613         case AIR_STEP_HIT_WALL:
   1614             if (m->vel[1] > 0.0f) {
   1615                 m->vel[1] = 0.0f;
   1616             }
   1617 
   1618             m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1619 
   1620             set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
   1621             break;
   1622 
   1623         case AIR_STEP_HIT_LAVA_WALL:
   1624             lava_boost_on_wall(m);
   1625             break;
   1626     }
   1627 
   1628     return FALSE;
   1629 }
   1630 
   1631 s32 act_jump_kick(struct MarioState *m) {
   1632     s32 animFrame;
   1633 
   1634     if (m->actionState == 0) {
   1635         play_sound_if_no_flag(m, SOUND_MARIO_PUNCH_HOO, MARIO_ACTION_SOUND_PLAYED);
   1636         m->marioObj->header.gfx.animInfo.animID = -1;
   1637         set_mario_animation(m, MARIO_ANIM_AIR_KICK);
   1638         m->actionState = 1;
   1639     }
   1640 
   1641     animFrame = m->marioObj->header.gfx.animInfo.animFrame;
   1642     if (animFrame == 0) {
   1643         m->marioBodyState->punchState = (2 << 6) | 6;
   1644     }
   1645     if (animFrame >= 0 && animFrame < 8) {
   1646         m->flags |= MARIO_KICKING;
   1647     }
   1648 
   1649     update_air_without_turn(m);
   1650 
   1651     switch (perform_air_step(m, 0)) {
   1652         case AIR_STEP_LANDED:
   1653             if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
   1654                 set_mario_action(m, ACT_FREEFALL_LAND, 0);
   1655             }
   1656             break;
   1657 
   1658         case AIR_STEP_HIT_WALL:
   1659             mario_set_forward_vel(m, 0.0f);
   1660             break;
   1661     }
   1662 
   1663     return FALSE;
   1664 }
   1665 
   1666 s32 act_shot_from_cannon(struct MarioState *m) {
   1667     if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
   1668         m->statusForCamera->cameraEvent = CAM_EVENT_SHOT_FROM_CANNON;
   1669     }
   1670 
   1671     mario_set_forward_vel(m, m->forwardVel);
   1672 
   1673     play_sound_if_no_flag(m, SOUND_MARIO_YAHOO, MARIO_MARIO_SOUND_PLAYED);
   1674 
   1675     switch (perform_air_step(m, 0)) {
   1676         case AIR_STEP_NONE:
   1677             set_mario_animation(m, MARIO_ANIM_AIRBORNE_ON_STOMACH);
   1678             m->faceAngle[0] = atan2s(m->forwardVel, m->vel[1]);
   1679             m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
   1680             break;
   1681 
   1682         case AIR_STEP_LANDED:
   1683             set_mario_action(m, ACT_DIVE_SLIDE, 0);
   1684             m->faceAngle[0] = 0;
   1685             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
   1686 #if ENABLE_RUMBLE
   1687             queue_rumble_data(5, 80);
   1688 #endif
   1689             break;
   1690 
   1691         case AIR_STEP_HIT_WALL:
   1692             mario_set_forward_vel(m, -16.0f);
   1693 
   1694             m->faceAngle[0] = 0;
   1695             if (m->vel[1] > 0.0f) {
   1696                 m->vel[1] = 0.0f;
   1697             }
   1698 
   1699             m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1700             set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
   1701             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
   1702             break;
   1703 
   1704         case AIR_STEP_HIT_LAVA_WALL:
   1705             lava_boost_on_wall(m);
   1706             break;
   1707     }
   1708 
   1709     if ((m->flags & MARIO_WING_CAP) && m->vel[1] < 0.0f) {
   1710         set_mario_action(m, ACT_FLYING, 0);
   1711     }
   1712 
   1713     if ((m->forwardVel -= 0.05) < 10.0f) {
   1714         mario_set_forward_vel(m, 10.0f);
   1715     }
   1716 
   1717     if (m->vel[1] > 0.0f) {
   1718         m->particleFlags |= PARTICLE_DUST;
   1719     }
   1720 #if ENABLE_RUMBLE
   1721     reset_rumble_timers();
   1722 #endif
   1723     return FALSE;
   1724 }
   1725 
   1726 s32 act_flying(struct MarioState *m) {
   1727     s16 startPitch = m->faceAngle[0];
   1728 
   1729     if (m->input & INPUT_Z_PRESSED) {
   1730         if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) {
   1731             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
   1732         }
   1733         return set_mario_action(m, ACT_GROUND_POUND, 1);
   1734     }
   1735 
   1736     if (!(m->flags & MARIO_WING_CAP)) {
   1737         if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) {
   1738             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
   1739         }
   1740         return set_mario_action(m, ACT_FREEFALL, 0);
   1741     }
   1742 
   1743     if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
   1744         set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
   1745     }
   1746 
   1747     if (m->actionState == 0) {
   1748         if (m->actionArg == 0) {
   1749             set_mario_animation(m, MARIO_ANIM_FLY_FROM_CANNON);
   1750         } else {
   1751             set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP);
   1752             if (m->marioObj->header.gfx.animInfo.animFrame == 1) {
   1753                 play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
   1754             }
   1755         }
   1756 
   1757         if (is_anim_at_end(m)) {
   1758             if (m->actionArg == 2) {
   1759                 load_level_init_text(0);
   1760                 m->actionArg = 1;
   1761             }
   1762 
   1763             set_mario_animation(m, MARIO_ANIM_WING_CAP_FLY);
   1764             m->actionState = 1;
   1765         }
   1766     }
   1767 
   1768     update_flying(m);
   1769 
   1770     switch (perform_air_step(m, 0)) {
   1771         case AIR_STEP_NONE:
   1772             m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
   1773             m->marioObj->header.gfx.angle[2] = m->faceAngle[2];
   1774             m->actionTimer = 0;
   1775             break;
   1776 
   1777         case AIR_STEP_LANDED:
   1778             set_mario_action(m, ACT_DIVE_SLIDE, 0);
   1779 
   1780             set_mario_animation(m, MARIO_ANIM_DIVE);
   1781             set_anim_to_frame(m, 7);
   1782 
   1783             m->faceAngle[0] = 0;
   1784             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
   1785 #if ENABLE_RUMBLE
   1786             queue_rumble_data(5, 60);
   1787 #endif
   1788             break;
   1789 
   1790         case AIR_STEP_HIT_WALL:
   1791             if (m->wall != NULL) {
   1792                 mario_set_forward_vel(m, -16.0f);
   1793                 m->faceAngle[0] = 0;
   1794 
   1795                 if (m->vel[1] > 0.0f) {
   1796                     m->vel[1] = 0.0f;
   1797                 }
   1798 
   1799                 play_sound((m->flags & MARIO_METAL_CAP) ? SOUND_ACTION_METAL_BONK
   1800                                                         : SOUND_ACTION_BONK,
   1801                            m->marioObj->header.gfx.cameraToObject);
   1802 
   1803                 m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1804                 set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
   1805                 set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
   1806             } else {
   1807                 if (m->actionTimer++ == 0) {
   1808                     play_sound(SOUND_ACTION_HIT, m->marioObj->header.gfx.cameraToObject);
   1809                 }
   1810 
   1811                 if (m->actionTimer == 30) {
   1812                     m->actionTimer = 0;
   1813                 }
   1814 
   1815                 m->faceAngle[0] -= 0x200;
   1816                 if (m->faceAngle[0] < -0x2AAA) {
   1817                     m->faceAngle[0] = -0x2AAA;
   1818                 }
   1819 
   1820                 m->marioObj->header.gfx.angle[0] = -m->faceAngle[0];
   1821                 m->marioObj->header.gfx.angle[2] = m->faceAngle[2];
   1822             }
   1823             break;
   1824 
   1825         case AIR_STEP_HIT_LAVA_WALL:
   1826             lava_boost_on_wall(m);
   1827             break;
   1828     }
   1829 
   1830     if (m->faceAngle[0] > 0x800 && m->forwardVel >= 48.0f) {
   1831         m->particleFlags |= PARTICLE_DUST;
   1832     }
   1833 
   1834     if (startPitch <= 0 && m->faceAngle[0] > 0 && m->forwardVel >= 48.0f) {
   1835         play_sound(SOUND_ACTION_FLYING_FAST, m->marioObj->header.gfx.cameraToObject);
   1836 #ifndef VERSION_JP
   1837         play_sound(SOUND_MARIO_YAHOO_WAHA_YIPPEE + ((gAudioRandom % 5) << 16),
   1838                    m->marioObj->header.gfx.cameraToObject);
   1839 #endif
   1840 #if ENABLE_RUMBLE
   1841         queue_rumble_data(50, 40);
   1842 #endif
   1843     }
   1844 
   1845     play_sound(SOUND_MOVING_FLYING, m->marioObj->header.gfx.cameraToObject);
   1846     adjust_sound_for_speed(m);
   1847     return FALSE;
   1848 }
   1849 
   1850 s32 act_riding_hoot(struct MarioState *m) {
   1851     if (!(m->input & INPUT_A_DOWN) || (m->marioObj->oInteractStatus & INT_STATUS_MARIO_UNK7)) {
   1852         m->usedObj->oInteractStatus = 0;
   1853         m->usedObj->oHootMarioReleaseTime = gGlobalTimer;
   1854 
   1855         play_sound_if_no_flag(m, SOUND_MARIO_UH, MARIO_MARIO_SOUND_PLAYED);
   1856 #if ENABLE_RUMBLE
   1857         queue_rumble_data(4, 40);
   1858 #endif
   1859         return set_mario_action(m, ACT_FREEFALL, 0);
   1860     }
   1861 
   1862     m->pos[0] = m->usedObj->oPosX;
   1863     m->pos[1] = m->usedObj->oPosY - 92.5f;
   1864     m->pos[2] = m->usedObj->oPosZ;
   1865 
   1866     m->faceAngle[1] = 0x4000 - m->usedObj->oMoveAngleYaw;
   1867 
   1868     if (m->actionState == 0) {
   1869         set_mario_animation(m, MARIO_ANIM_HANG_ON_CEILING);
   1870         if (is_anim_at_end(m)) {
   1871             set_mario_animation(m, MARIO_ANIM_HANG_ON_OWL);
   1872             m->actionState = 1;
   1873         }
   1874     }
   1875 
   1876     vec3f_set(m->vel, 0.0f, 0.0f, 0.0f);
   1877     vec3f_set(m->marioObj->header.gfx.pos, m->pos[0], m->pos[1], m->pos[2]);
   1878     vec3s_set(m->marioObj->header.gfx.angle, 0, 0x4000 - m->faceAngle[1], 0);
   1879     return FALSE;
   1880 }
   1881 
   1882 s32 act_flying_triple_jump(struct MarioState *m) {
   1883 #ifndef VERSION_JP
   1884     if (m->input & (INPUT_B_PRESSED | INPUT_Z_PRESSED)) {
   1885         if (m->area->camera->mode == CAMERA_MODE_BEHIND_MARIO) {
   1886             set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
   1887         }
   1888         if (m->input & INPUT_B_PRESSED) {
   1889             return set_mario_action(m, ACT_DIVE, 0);
   1890         } else {
   1891             return set_mario_action(m, ACT_GROUND_POUND, 0);
   1892         }
   1893     }
   1894 #else
   1895     if (m->input & INPUT_B_PRESSED) {
   1896         return set_mario_action(m, ACT_DIVE, 0);
   1897     }
   1898 
   1899     if (m->input & INPUT_Z_PRESSED) {
   1900         return set_mario_action(m, ACT_GROUND_POUND, 0);
   1901     }
   1902 #endif
   1903 
   1904     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
   1905     if (m->actionState == 0) {
   1906         set_mario_animation(m, MARIO_ANIM_TRIPLE_JUMP_FLY);
   1907 
   1908         if (m->marioObj->header.gfx.animInfo.animFrame == 7) {
   1909             play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
   1910         }
   1911 
   1912         if (is_anim_past_end(m)) {
   1913             set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING);
   1914 #if ENABLE_RUMBLE
   1915             queue_rumble_data(8, 80);
   1916 #endif
   1917             m->actionState = 1;
   1918         }
   1919     }
   1920 
   1921     if (m->actionState == 1 && m->marioObj->header.gfx.animInfo.animFrame == 1) {
   1922         play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
   1923     }
   1924 
   1925     if (m->vel[1] < 4.0f) {
   1926         if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
   1927             set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
   1928         }
   1929 
   1930         if (m->forwardVel < 32.0f) {
   1931             mario_set_forward_vel(m, 32.0f);
   1932         }
   1933 
   1934         set_mario_action(m, ACT_FLYING, 1);
   1935     }
   1936 
   1937     if (m->actionTimer++ == 10 && m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
   1938         set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
   1939     }
   1940 
   1941     update_air_without_turn(m);
   1942 
   1943     switch (perform_air_step(m, 0)) {
   1944         case AIR_STEP_LANDED:
   1945             if (!check_fall_damage_or_get_stuck(m, ACT_HARD_BACKWARD_GROUND_KB)) {
   1946                 set_mario_action(m, ACT_DOUBLE_JUMP_LAND, 0);
   1947             }
   1948             break;
   1949 
   1950         case AIR_STEP_HIT_WALL:
   1951             mario_bonk_reflection(m, FALSE);
   1952             break;
   1953 
   1954         case AIR_STEP_HIT_LAVA_WALL:
   1955             lava_boost_on_wall(m);
   1956             break;
   1957     }
   1958 
   1959     return FALSE;
   1960 }
   1961 
   1962 s32 act_top_of_pole_jump(struct MarioState *m) {
   1963     play_mario_jump_sound(m);
   1964     common_air_action_step(m, ACT_FREEFALL_LAND, MARIO_ANIM_HANDSTAND_JUMP, AIR_STEP_CHECK_LEDGE_GRAB);
   1965     return FALSE;
   1966 }
   1967 
   1968 s32 act_vertical_wind(struct MarioState *m) {
   1969     s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
   1970     f32 intendedMag = m->intendedMag / 32.0f;
   1971 
   1972     play_sound_if_no_flag(m, SOUND_MARIO_HERE_WE_GO, MARIO_MARIO_SOUND_PLAYED);
   1973     if (m->actionState == 0) {
   1974         set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP);
   1975         if (m->marioObj->header.gfx.animInfo.animFrame == 1) {
   1976             play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
   1977 #if ENABLE_RUMBLE
   1978             queue_rumble_data(8, 80);
   1979 #endif
   1980         }
   1981 
   1982         if (is_anim_past_end(m)) {
   1983             m->actionState = 1;
   1984         }
   1985     } else {
   1986         set_mario_animation(m, MARIO_ANIM_AIRBORNE_ON_STOMACH);
   1987     }
   1988 
   1989     update_air_without_turn(m);
   1990 
   1991     switch (perform_air_step(m, 0)) {
   1992         case AIR_STEP_LANDED:
   1993             set_mario_action(m, ACT_DIVE_SLIDE, 0);
   1994             break;
   1995 
   1996         case AIR_STEP_HIT_WALL:
   1997             mario_set_forward_vel(m, -16.0f);
   1998             break;
   1999     }
   2000 
   2001     m->marioObj->header.gfx.angle[0] = (s16)(6144.0f * intendedMag * coss(intendedDYaw));
   2002     m->marioObj->header.gfx.angle[2] = (s16)(-4096.0f * intendedMag * sins(intendedDYaw));
   2003     return FALSE;
   2004 }
   2005 
   2006 s32 act_special_triple_jump(struct MarioState *m) {
   2007     if (m->input & INPUT_B_PRESSED) {
   2008         return set_mario_action(m, ACT_DIVE, 0);
   2009     }
   2010 
   2011     if (m->input & INPUT_Z_PRESSED) {
   2012         return set_mario_action(m, ACT_GROUND_POUND, 0);
   2013     }
   2014 
   2015     play_mario_sound(m, SOUND_ACTION_TERRAIN_JUMP, SOUND_MARIO_YAHOO);
   2016 
   2017     update_air_without_turn(m);
   2018 
   2019     switch (perform_air_step(m, 0)) {
   2020         case AIR_STEP_LANDED:
   2021             if (m->actionState++ == 0) {
   2022                 m->vel[1] = 42.0f;
   2023             } else {
   2024                 set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
   2025             }
   2026             play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   2027             break;
   2028 
   2029         case AIR_STEP_HIT_WALL:
   2030             mario_bonk_reflection(m, TRUE);
   2031             break;
   2032     }
   2033 
   2034     if (m->actionState == 0 || m->vel[1] > 0.0f) {
   2035         if (set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING) == 0) {
   2036             play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
   2037         }
   2038     } else {
   2039         set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
   2040     }
   2041 
   2042     m->particleFlags |= PARTICLE_SPARKLES;
   2043     return FALSE;
   2044 }
   2045 
   2046 s32 check_common_airborne_cancels(struct MarioState *m) {
   2047     if (m->pos[1] < m->waterLevel - 100) {
   2048         return set_water_plunge_action(m);
   2049     }
   2050 
   2051     if (m->input & INPUT_SQUISHED) {
   2052         return drop_and_set_mario_action(m, ACT_SQUISHED, 0);
   2053     }
   2054 
   2055     if (m->floor->type == SURFACE_VERTICAL_WIND && (m->action & ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)) {
   2056         return drop_and_set_mario_action(m, ACT_VERTICAL_WIND, 0);
   2057     }
   2058 
   2059     m->quicksandDepth = 0.0f;
   2060     return FALSE;
   2061 }
   2062 
   2063 s32 mario_execute_airborne_action(struct MarioState *m) {
   2064     u32 cancel;
   2065 
   2066     if (check_common_airborne_cancels(m)) {
   2067         return TRUE;
   2068     }
   2069 
   2070     play_far_fall_sound(m);
   2071 
   2072     /* clang-format off */
   2073     switch (m->action) {
   2074         case ACT_JUMP:                 cancel = act_jump(m);                 break;
   2075         case ACT_DOUBLE_JUMP:          cancel = act_double_jump(m);          break;
   2076         case ACT_FREEFALL:             cancel = act_freefall(m);             break;
   2077         case ACT_HOLD_JUMP:            cancel = act_hold_jump(m);            break;
   2078         case ACT_HOLD_FREEFALL:        cancel = act_hold_freefall(m);        break;
   2079         case ACT_SIDE_FLIP:            cancel = act_side_flip(m);            break;
   2080         case ACT_WALL_KICK_AIR:        cancel = act_wall_kick_air(m);        break;
   2081         case ACT_TWIRLING:             cancel = act_twirling(m);             break;
   2082         case ACT_WATER_JUMP:           cancel = act_water_jump(m);           break;
   2083         case ACT_HOLD_WATER_JUMP:      cancel = act_hold_water_jump(m);      break;
   2084         case ACT_STEEP_JUMP:           cancel = act_steep_jump(m);           break;
   2085         case ACT_BURNING_JUMP:         cancel = act_burning_jump(m);         break;
   2086         case ACT_BURNING_FALL:         cancel = act_burning_fall(m);         break;
   2087         case ACT_TRIPLE_JUMP:          cancel = act_triple_jump(m);          break;
   2088         case ACT_BACKFLIP:             cancel = act_backflip(m);             break;
   2089         case ACT_LONG_JUMP:            cancel = act_long_jump(m);            break;
   2090         case ACT_RIDING_SHELL_JUMP:
   2091         case ACT_RIDING_SHELL_FALL:    cancel = act_riding_shell_air(m);     break;
   2092         case ACT_DIVE:                 cancel = act_dive(m);                 break;
   2093         case ACT_AIR_THROW:            cancel = act_air_throw(m);            break;
   2094         case ACT_BACKWARD_AIR_KB:      cancel = act_backward_air_kb(m);      break;
   2095         case ACT_FORWARD_AIR_KB:       cancel = act_forward_air_kb(m);       break;
   2096         case ACT_HARD_FORWARD_AIR_KB:  cancel = act_hard_forward_air_kb(m);  break;
   2097         case ACT_HARD_BACKWARD_AIR_KB: cancel = act_hard_backward_air_kb(m); break;
   2098         case ACT_SOFT_BONK:            cancel = act_soft_bonk(m);            break;
   2099         case ACT_AIR_HIT_WALL:         cancel = act_air_hit_wall(m);         break;
   2100         case ACT_FORWARD_ROLLOUT:      cancel = act_forward_rollout(m);      break;
   2101         case ACT_SHOT_FROM_CANNON:     cancel = act_shot_from_cannon(m);     break;
   2102         case ACT_BUTT_SLIDE_AIR:       cancel = act_butt_slide_air(m);       break;
   2103         case ACT_HOLD_BUTT_SLIDE_AIR:  cancel = act_hold_butt_slide_air(m);  break;
   2104         case ACT_LAVA_BOOST:           cancel = act_lava_boost(m);           break;
   2105         case ACT_GETTING_BLOWN:        cancel = act_getting_blown(m);        break;
   2106         case ACT_BACKWARD_ROLLOUT:     cancel = act_backward_rollout(m);     break;
   2107         case ACT_CRAZY_BOX_BOUNCE:     cancel = act_crazy_box_bounce(m);     break;
   2108         case ACT_SPECIAL_TRIPLE_JUMP:  cancel = act_special_triple_jump(m);  break;
   2109         case ACT_GROUND_POUND:         cancel = act_ground_pound(m);         break;
   2110         case ACT_THROWN_FORWARD:       cancel = act_thrown_forward(m);       break;
   2111         case ACT_THROWN_BACKWARD:      cancel = act_thrown_backward(m);      break;
   2112         case ACT_FLYING_TRIPLE_JUMP:   cancel = act_flying_triple_jump(m);   break;
   2113         case ACT_SLIDE_KICK:           cancel = act_slide_kick(m);           break;
   2114         case ACT_JUMP_KICK:            cancel = act_jump_kick(m);            break;
   2115         case ACT_FLYING:               cancel = act_flying(m);               break;
   2116         case ACT_RIDING_HOOT:          cancel = act_riding_hoot(m);          break;
   2117         case ACT_TOP_OF_POLE_JUMP:     cancel = act_top_of_pole_jump(m);     break;
   2118         case ACT_VERTICAL_WIND:        cancel = act_vertical_wind(m);        break;
   2119     }
   2120     /* clang-format on */
   2121 
   2122     return cancel;
   2123 }