Walking: Difference between revisions

6,590 bytes added ,  12 August 2023
finish todo
m (added begining summary? that best i can word it)
(finish todo)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
The '''walking''' action occurs when Mario is moving only by using the analog stick. {{Action_infobox
{{Action_infobox
|title= Walking
|title= Walking
|image=
|image=
Line 7: Line 7:
|group= Moving
|group= Moving
|id= todo
|id= todo
|into=
|into=common moving cancels: [[Water Plunge]], [[Shockwave Bounce]], [[Squished]], [[Standing Death]], [[Quicksand Death]], non-cancel: [[Begin Sliding]], [[Standing against Wall]], [[Breaking]], [[Decelerating]], (jumps: [[Hold Quicksand Jump Land]], [[Quicksand Jump Land]], [[Steep Jump]], [[Jump]], [[Doube Jump]], [[Flying Triple Jump]], [[Triple Jump]]), [[Dive]], [[Move Punching]], [[Turning Around]], [[Crouch Slide]], [[Freefall]], [[Ledge Climb Down]]
|out of=
|out of=
|animation=
|animation=
|related=
|related=
}}
}}
[[File:Walking.svg|alt=A velocity/time graph of Mario's speed during the first 45 frames (1.5 seconds) of walking|thumb|Mario's speed during the first 45 frames (1.5 seconds) of walking. Note that this depends on the floor's slope (see [[De facto speed]]).]]
The '''walking''' action occurs when Mario is moving only by using the analog stick. It can also occur when exiting water (except if exiting water through a [[water jump]]).
== Common moving cancels ==
All actions in the "moving" group check the following cancels before running any behavior script:
# If Mario's y position is lower than 100 units below the water level, do stuff, [[Water Plunge]]
# If Mario's current action does not have the "invulnerable" flag, and input_stomped, dropheldobject stopridingobject [[Shockwave Bounce]]
# If input_squished, dropheldobject stopridingobject [[Squished]]
# If Mario's current action does not have the "invulnerable" flag, and health < 0x100, dropheldobject stopridingobject [[Standing Death]]
# [[Idle#quicksand death|Potentially cancel into Quicksand Death]] (sinkingSpeed = 0.25)
== Set jump from landing ==
# If quicksand depth > 11, if Mario is holding an object, [[Hold Quicksand Jump Land]] else [[Quicksand Jump Land]]
# If on steep floor, update forwardVelocity and facing direction, [[Steep Jump]]
# Else:
## If double jump timer is 0, or squish timer is not 0, [[Jump]]
## Else if the previous action is:
### [[Jump Land]], [[Freefall Land]], or [[Side Flip Land Stop]]: [[Double Jump]]
### [[Double Jump Land]]; then
#### if has wing cap: [[Flying Triple Jump]]
#### if forward velocity > 20: [[Triple Jump]]
#### [[Jump]]
### else: [[Jump]]
# Set double jump timer to 0
== Behavior ==
When walking<ref>https://github.com/n64decomp/sm64/blob/master/src/game/mario_actions_moving.c#L777</ref>:
When walking<ref>https://github.com/n64decomp/sm64/blob/master/src/game/mario_actions_moving.c#L777</ref>:
# [[File:Walking.svg|alt=A velocity/time graph of Mario's speed during the first 45 frames (1.5 seconds) of walking|thumb|Mario's speed during the first 45 frames (1.5 seconds) of walking.]]mario_drop_held_object
# mario_drop_held_object
# if should_begin_sliding; [[Begin Sliding]]
#if should_begin_sliding; [[Begin Sliding]]
# if INPUT_FIRST_PERSON:
#if INPUT_FIRST_PERSON:
## mario_drop_held_object
##mario_drop_held_object
## if actionState == 1; [[Standing Against Wall]]
## if actionState == 1; [[Standing Against Wall]]
## if forwardVel >= 16 and m->floor->normal.y >= 0.17364818; [[Braking]]
##if forwardVel >= 16 and m->floor->normal.y >= 0.17364818; [[Braking]]
## else; [[Decelerating]]
##else; [[Decelerating]]
# if INPUT_A_PRESSED; (todo; see ref) <ref>https://github.com/n64decomp/sm64/blob/1372ae1bb7cbedc03df366393188f4f05dcfc422/src/game/mario.c#L1018 set_jump_from_landing</ref>
#if INPUT_A_PRESSED; [[#Set jump from landing]]<ref>https://github.com/n64decomp/sm64/blob/1372ae1bb7cbedc03df366393188f4f05dcfc422/src/game/mario.c#L1018 set_jump_from_landing</ref>
# if INPUT_B_PRESSED;
#if INPUT_B_PRESSED;
## if forwardVel >= 29 and stickMag > 48; yVel=20; [[Dive]]
##if forwardVel >= 29 and stickMag > 48; yVel=20; [[Dive]]
## else; [[Move Punching]]
##else; [[Move Punching]]
# if INPUT_UNKNOWN_5 (aka neutral joystick: https://ukikipedia.net/mediawiki/index.php?title=Turning_Around&oldid=17030); (same code as INPUT_FIRST_PERSON)
#if INPUT_UNKNOWN_5 (aka neutral joystick: https://ukikipedia.net/mediawiki/index.php?title=Turning_Around&oldid=17030); (same code as INPUT_FIRST_PERSON)
# if analog_stick_held_back and forwardVel >= 16; [[Turning Around]]
#if analog_stick_held_back and forwardVel >= 16; [[Turning Around]]
# if INPUT_Z_PRESSED; [[Crouch Slide]]
#if INPUT_Z_PRESSED; [[Crouch Slide]]
# more code
#update_walking_speed
# case GROUND_STEP_LEFT_GROUND; [[Freefall]]
#switch (perform_ground_step):
# case GROUND_STEP_HIT_WALL; push_or_sidle_wall
##case GROUND_STEP_LEFT_GROUND; [[Freefall]]
##case GROUND_STEP_NONE: if intendedMag - forwardVel > 16, dust
##case GROUND_STEP_HIT_WALL; push_or_sidle_wall
#check_ledge_climb_down (can transition to [[Ledge Climb Down]])
#tilt_body_walking
Here's what update_walking_speed is for convenience:<syntaxhighlight lang="c">
void update_walking_speed(struct MarioState *m) {
    f32 maxTargetSpeed;
    f32 targetSpeed;
 
    if (m->floor != NULL && m->floor->type == SURFACE_SLOW) {
        maxTargetSpeed = 24.0f;
    } else {
        maxTargetSpeed = 32.0f;
    }
 
    targetSpeed = m->intendedMag < maxTargetSpeed ? m->intendedMag : maxTargetSpeed;
 
    if (m->quicksandDepth > 10.0f) {
        targetSpeed *= 6.25 / m->quicksandDepth;
    }
 
    if (m->forwardVel <= 0.0f) {
        m->forwardVel += 1.1f;
    } else if (m->forwardVel <= targetSpeed) {
        m->forwardVel += 1.1f - m->forwardVel / 43.0f;
    } else if (m->floor->normal.y >= 0.95f) {
        m->forwardVel -= 1.0f;
    }
 
    if (m->forwardVel > 48.0f) {
        m->forwardVel = 48.0f;
    }
 
    m->faceAngle[1] =
        m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
    apply_slope_accel(m);
}
 
/**
* Return the value 'current' after it tries to approach target, going up at
* most 'inc' and going down at most 'dec'.
*/
s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) {
    //! If target is close to the max or min s32, then it's possible to overflow
    // past it without stopping.
 
    if (current < target) {
        current += inc;
        if (current > target) {
            current = target;
        }
    } else {
        current -= dec;
        if (current < target) {
            current = target;
        }
    }
    return current;
}
 
void apply_slope_accel(struct MarioState *m) {
    f32 slopeAccel;
 
    struct Surface *floor = m->floor;
    f32 steepness = sqrtf(floor->normal.x * floor->normal.x + floor->normal.z * floor->normal.z);
 
    UNUSED f32 normalY = floor->normal.y;
    s16 floorDYaw = m->floorAngle - m->faceAngle[1];
 
    if (mario_floor_is_slope(m)) {
        s16 slopeClass = 0;
 
        if (m->action != ACT_SOFT_BACKWARD_GROUND_KB && m->action != ACT_SOFT_FORWARD_GROUND_KB) {
            slopeClass = mario_get_floor_class(m);
        }
 
        switch (slopeClass) {
            case SURFACE_CLASS_VERY_SLIPPERY:
                slopeAccel = 5.3f;
                break;
            case SURFACE_CLASS_SLIPPERY:
                slopeAccel = 2.7f;
                break;
            default:
                slopeAccel = 1.7f;
                break;
            case SURFACE_CLASS_NOT_SLIPPERY:
                slopeAccel = 0.0f;
                break;
        }
 
        if (floorDYaw > -0x4000 && floorDYaw < 0x4000) {
            m->forwardVel += slopeAccel * steepness;
        } else {
            m->forwardVel -= slopeAccel * steepness;
        }
    }
 
    m->slideYaw = m->faceAngle[1];
 
    m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
    m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
 
    m->vel[0] = m->slideVelX;
    m->vel[1] = 0.0f;
    m->vel[2] = m->slideVelZ;
 
    mario_update_moving_sand(m);
    mario_update_windy_ground(m);
}
 
static s16 sMovingSandSpeeds[] = { 12, 8, 4, 0 };
u32 mario_update_moving_sand(struct MarioState *m) {
    struct Surface *floor = m->floor;
    s32 floorType = floor->type;
 
    if (floorType == SURFACE_DEEP_MOVING_QUICKSAND || floorType == SURFACE_SHALLOW_MOVING_QUICKSAND
        || floorType == SURFACE_MOVING_QUICKSAND || floorType == SURFACE_INSTANT_MOVING_QUICKSAND) {
        s16 pushAngle = floor->force << 8;
        f32 pushSpeed = sMovingSandSpeeds[floor->force >> 8];
 
        m->vel[0] += pushSpeed * sins(pushAngle);
        m->vel[2] += pushSpeed * coss(pushAngle);
 
        return TRUE;
    }
 
    return FALSE;
}
 
u32 mario_update_windy_ground(struct MarioState *m) {
    struct Surface *floor = m->floor;
 
    if (floor->type == SURFACE_HORIZONTAL_WIND) {
        f32 pushSpeed;
        s16 pushAngle = floor->force << 8;
 
        if (m->action & ACT_FLAG_MOVING) {
            s16 pushDYaw = m->faceAngle[1] - pushAngle;
 
            pushSpeed = m->forwardVel > 0.0f ? -m->forwardVel * 0.5f : -8.0f;
 
            if (pushDYaw > -0x4000 && pushDYaw < 0x4000) {
                pushSpeed *= -1.0f;
            }
 
            pushSpeed *= coss(pushDYaw);
        } else {
            pushSpeed = 3.2f + (gGlobalTimer % 4);
        }
 
        m->vel[0] += pushSpeed * sins(pushAngle);
        m->vel[2] += pushSpeed * coss(pushAngle);
 
#ifdef VERSION_JP
        play_sound(SOUND_ENV_WIND2, m->marioObj->header.gfx.cameraToObject);
#endif
        return TRUE;
    }
 
    return FALSE;
}
</syntaxhighlight>
==References==
==References==
<references />
<references />
{{actions}}
{{actions}}
188

edits