Flying: Difference between revisions

4,503 bytes added ,  19 December 2023
fix misinformation
(Created page with "{{Action_infobox |title= Flying |image= |official name= |hex= 0x10880899 |flags= air, diving, attacking, swimming/flying |group= Airborne |id= 0x099 |into= Airborner cancels:...")
 
(fix misinformation)
 
(9 intermediate revisions by the same user not shown)
Line 7: Line 7:
|group= Airborne
|group= Airborne
|id= 0x099
|id= 0x099
|into= Airborner cancels: [[Water Plunge]], [[Squished]], [[Vertical Wind]] (theoretically), (Technically, because of the flying triple jump code): [[Double Jump Land]], [[Lava Boost]] (theoretically),, non cancel: [[Backwards Air Kb]], [[Lava Boost]] (again) (theoretically)
|into= Airborner cancels: [[Water Plunge]], [[Squished]], [[Vertical Wind]] (theoretically), (Technically, because of the flying triple jump code): [[Double Jump Land]], [[Lava Boost]] (theoretically), non cancel: [[Ground Pound]], [[Freefall]], [[Dive Slide]], [[Backwards Air Kb]], [[Lava Boost]] (again) (theoretically)
|out of= [[Shot From Cannon]], [[Flying Triple Jump]], when spawning in some levels like [[Tower of the Wing Cap]]
|out of= [[Shot From Cannon]], [[Flying Triple Jump]], when spawning in some levels like [[Tower of the Wing Cap]]
|animation= 0x5B fly from cannon, 0xCF forwards spinning flip, 0x29 wing cap fly
|animation= 0x5B fly from cannon, 0xCF forwards spinning flip, 0x29 wing cap fly
|related=
|related=
}}
}}
Flying is an action that can occurs when Mario triple jumps or does a cannon shot while wearing the [[wing cap]].
Flying is an action that can occurs when Mario triple jumps or does a cannon shot while wearing the [[wing cap]].
== Entering flying ==
== Entering flying ==
* [[Shot From Cannon|Cannon shot]]: when y vel < 0 (and Mario does not cancel) ('''Action argument: 0''')
* [[Shot From Cannon|Cannon shot]]: when y vel < 0 (and Mario does not cancel) ('''Action argument: 0''')


Line 22: Line 19:


* Spawning in, e.g, [[Tower of the Wing Cap]]: ('''Action argument: 2''')
* Spawning in, e.g, [[Tower of the Wing Cap]]: ('''Action argument: 2''')
== Behavior ==
== Behavior ==
As with all airborne actions, a variety of "cancels" are checked prior to actually performing any airborne action. See [[Jump#Airborne cancels]].
As with all airborne actions, a variety of "cancels" are checked prior to actually performing any airborne action. See [[Jump#Airborne cancels]].


Then:<ref>https://github.com/n64decomp/sm64/blob/66018e9f3caaa67399218971d61366cb3f7ba7d7/src/game/mario_actions_airborne.c#L1726</ref>
# If Z is pressed
# If Z is pressed
## If Mario's camera mode is CAMERA_MODE_BEHIND_MARIO, set_camera_mode to m->area->camera->defMode
## If Mario's camera mode is CAMERA_MODE_BEHIND_MARIO, set_camera_mode to m->area->camera->defMode
Line 33: Line 29:
## If Mario's camera mode is CAMERA_MODE_BEHIND_MARIO, set_camera_mode to m->area->camera->defMode
## If Mario's camera mode is CAMERA_MODE_BEHIND_MARIO, set_camera_mode to m->area->camera->defMode
## [[Freefall]]
## [[Freefall]]
# If Mario's camera mode is ''not'' CAMERA_MODE_BEHIND_MARIO, set_camera_mode to CAMERA_MODE_BEHIND_MARIO
# <span style="color:gray;">If Mario's camera mode is ''not'' CAMERA_MODE_BEHIND_MARIO,</span> set_camera_mode to CAMERA_MODE_BEHIND_MARIO
# If the action state is 0
# If the action state is 0
## If the action argument is 0 (was shot from cannon), set Mario's animation to MARIO_ANIM_FLY_FROM_CANNON, else set Mario's animation to MARIO_ANIM_FORWARD_SPINNING_FLIP
## If the action argument is 0 (was shot from cannon), set Mario's animation to MARIO_ANIM_FLY_FROM_CANNON, else set Mario's animation to MARIO_ANIM_FORWARD_SPINNING_FLIP
Line 41: Line 37:
### Set action state to 1
### Set action state to 1
# Call '''<code>update_flying</code>'''
# Call '''<code>update_flying</code>'''
# switch [[Movement_steps#Perform_Air_Step]]:
# switch [[Movement_steps#Perform_Air_Step]]: (Note: if there are no floor/wall/ceiling/oob interactions this just '''adds vel[0,1,2] to pos[0,1,2]'''.)
## air step none:
#* air step none:
### Update graphics (camera) angle to be behind Mario
#*# Update graphics (camera) angle to be behind Mario
### Set action timer to 0
#*# Set action timer to 0
## air step land:
#* air step land:
### Set action to [[Dive Slide]]
#*# Set action to [[Dive Slide]]
### Set animation to MARIO_ANIM_DIVE
#*# Set animation to MARIO_ANIM_DIVE
### Set animation frame to 7
#*# Set animation frame to 7
### Set facing angle (x) to 0
#*# Set facing angle (x) to 0
### Set camera mode to m->area->camera->defMode
#*# Set camera mode to m->area->camera->defMode
## air step hit wall:
#* air step hit wall:
### '''todo'''
#*#'''todo'''
### if wall is not null, stuff, [[Backwards Air Kb]]
#*# if wall is not null, stuff, [[Backwards Air Kb]]
### else, stuff (but no knockback, this is probably out of bounds)
#*# else, stuff (but no knockback, this is probably out of bounds)
## air step hit lava wall:
#* air step hit lava wall:
### stop holding, stop riding, [[Lava Boost]]
#*# stop holding, stop riding, [[Lava Boost]]
# finally, play the flying sound (adjust sound for speed)
# finally, play the flying sound (adjust sound for speed)
Notice that there is no code handling air steps for ledge grabbing or hanging on a ceiling, so such transitions are impossible.
===update_flying===
Casually, tilt the joystick left to move left, right to move right, up to move down, down to move up.


I am too lazy to describe the exact details of <code>update_flying</code>, so here is the code
I am too lazy to describe the exact details of <code>update_flying</code>, so here is the code
<syntaxhighlight lang="c">
void update_flying(struct MarioState *m) {
    UNUSED u8 filler[4];
    update_flying_pitch(m);
    update_flying_yaw(m);
    m->forwardVel -= 2.0f * ((f32) m->faceAngle[0] / 0x4000) + 0.1f;
    m->forwardVel -= 0.5f * (1.0f - coss(m->angleVel[1]));
    if (m->forwardVel < 0.0f) {
        m->forwardVel = 0.0f;
    }
    if (m->forwardVel > 16.0f) {
        m->faceAngle[0] += (m->forwardVel - 32.0f) * 6.0f;
    } else if (m->forwardVel > 4.0f) {
        m->faceAngle[0] += (m->forwardVel - 32.0f) * 10.0f;
    } else {
        m->faceAngle[0] -= 0x400;
    }
    m->faceAngle[0] += m->angleVel[0];
    if (m->faceAngle[0] > 0x2AAA) {
        m->faceAngle[0] = 0x2AAA;
    }
    if (m->faceAngle[0] < -0x2AAA) {
        m->faceAngle[0] = -0x2AAA;
    }
    m->vel[0] = m->forwardVel * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
    m->vel[1] = m->forwardVel * sins(m->faceAngle[0]);
    m->vel[2] = m->forwardVel * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);


    m->slideVelX = m->vel[0];
    m->slideVelZ = m->vel[2];
}
</syntaxhighlight>
'''Key takeaways''':
* Pitching to move up happens faster with higher forward velocity.
** The difference between 4 and 5 speed, and 16 and 17 speed is especially large.
* At the same time, forward velocity is based on pitch. (But it is also based on:)
** There is a base 0.1 forwardVel speed loss
** There is anywhere from 0 to 0.5 further speed loss - more speed is lost the higher the yaw velocity is (ie '''the more Mario turns''').
* Pitch has a minimum and maximum and cannot overflow with standard speeds.
* '''More below the tables'''
* '''TODO:''' I heard moving down then up can be faster then just the direct line. Explain big picture movements, what happens in a practical example.
{| class="wikitable"
|+forwardVel's affect on pitch
|'''<=4'''
|5
|6
|7
|8
|9
|10
|11
|12
|13
|14
|15
|'''16'''
|17
|18
|19
|...
|31
|32
|33
|-
|  -1024
| -270
| -260
| -250
| -240
| -230
| -220
| -210
| -200
| -190
| -180
| -170
| -160
| -90
| -84
| -76
|...
| -6
|0
|6
|}
*'''TODO:''' I heard moving down then up can be faster then just the direct line. Explain big picture movements, what happens in a practical example.
Although I posted the code instead of the detailed psuedocode, here's some less detailed psuedocode anyways:
Although I was too lazy, I typed a less detailed pseudocode anyways:
# Joystick inputs affect (pitch,yaw) velocity.
# Yaw velocity affects yaw, roll, and forward velocity.
# Pitch affects forward velocity.
# Forward velocity becomes at least 0
# Forward velocity affects pitch (see above table)
# Pitch velocity affects pitch.
# Pitch is clamped to be inside [-0x2AAA, 0x2AAA]
# x,y,z velocity is more or less directly exactly correspondent to forward velocity, pitch, and yaw.
# xz sliding velocity updated to correspond
<hr>
Here are some tables summarizing the <code>approach_s32</code>, <code>update_flying_pitch</code>, and <code>update_flying_yaw</code> functions.
{| class="wikitable"
|+
update_flying_pitch (target vel = -(stickX * (forwardVel / 5)))
!
!joystick is down (move up)
!joystick is up (move down)
!joystick is neutral
|-
|negative pitch velocity
|add 64 vel, cap at 32
| approach (at most 64 up or 32 down)
|approach 0 (by at most 64)
|-
|positive pitch velocity
| approach (at most 32 up or 64 down)
|subtract 64 vel, cap at -32
|approach 0 (by at most 64)
|-
|zero pitch velocity
| approach (at most 32 up or 64 down)
| approach (at most 64 up or 32 down)
| approach 0 (by at most 64)
|}
{| class="wikitable"
|+update_flying_yaw (target vel = -(stickY * (forwardVel / 4)))
!
!joystick is left
!joystick is right
!joystick is neutral
|-
|negative yaw velocity
| add 64 vel, cap at 16
|approach (at most 32 up or 16 down)
|approach 0 (by at most 64)
|-
|positive yaw velocity
| approach (at most 16 up or 32 down)
| subtract 64 vel, cap at -16
|approach 0 (by at most 64)
|-
|zero yaw velocity
|approach (at most 16 up or 32 down)
|approach (at most 32 up or 16 down)
|approach 0 (by at most 64)
|}
'''Key takeaways''':
# Many joystick positions are equivalent.
# One cannot change velocity by more than 64 (ignoring the effects of speed)
# Holding joystick x=0 or y=0 will approach the corresponding 0 by at most 64.
#* In contrast, holding the opposite direction changes the angle by 32 (yaw) or 64 (pitch), unconditionally
#* In further contrast, holding less of the same direction changes the angle by 32 (yaw) or 64 (pitch)
#* In even furthest contrast, holding more of the same direction changes the angle by 16 (yaw) or 32 (pitch)
#* So it might be faster to say, modify pitch:as such: -56 to -4 to 60 instead of -56 to 8 to 40. Notice the slightly under zero instead of slightly over zero.
After that, update_flying_yaw does:
#Add yaw velocity to yaw
# Set roll to yaw times negative twenty (-20)
'''Note that turning left = positive yaw''' (up = positive pitch).<ref>https://youtu.be/TQt8MCsniQI</ref>
*
<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
/**
/**
Line 137: Line 303:
         m->angleVel[0] = approach_s32(m->angleVel[0], 0, 0x40, 0x40);
         m->angleVel[0] = approach_s32(m->angleVel[0], 0, 0x40, 0x40);
     }
     }
}
void update_flying(struct MarioState *m) {
    UNUSED u8 filler[4];
    update_flying_pitch(m);
    update_flying_yaw(m);
    m->forwardVel -= 2.0f * ((f32) m->faceAngle[0] / 0x4000) + 0.1f;
    m->forwardVel -= 0.5f * (1.0f - coss(m->angleVel[1]));
    if (m->forwardVel < 0.0f) {
        m->forwardVel = 0.0f;
    }
    if (m->forwardVel > 16.0f) {
        m->faceAngle[0] += (m->forwardVel - 32.0f) * 6.0f;
    } else if (m->forwardVel > 4.0f) {
        m->faceAngle[0] += (m->forwardVel - 32.0f) * 10.0f;
    } else {
        m->faceAngle[0] -= 0x400;
    }
    m->faceAngle[0] += m->angleVel[0];
    if (m->faceAngle[0] > 0x2AAA) {
        m->faceAngle[0] = 0x2AAA;
    }
    if (m->faceAngle[0] < -0x2AAA) {
        m->faceAngle[0] = -0x2AAA;
    }
    m->vel[0] = m->forwardVel * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
    m->vel[1] = m->forwardVel * sins(m->faceAngle[0]);
    m->vel[2] = m->forwardVel * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
    m->slideVelX = m->vel[0];
    m->slideVelZ = m->vel[2];
}
}
</syntaxhighlight>
</syntaxhighlight>
 
==References==
 
<references />
{{Actions}}
{{Actions}}
192

edits