mirror of https://github.com/zeldaret/mm.git
turn in place (#1728)
This commit is contained in:
parent
13c42b487d
commit
694d3b3965
|
@ -1240,7 +1240,7 @@ typedef struct Player {
|
||||||
/* 0xAC8 */ f32 skelAnimeUpperBlendWeight;
|
/* 0xAC8 */ f32 skelAnimeUpperBlendWeight;
|
||||||
/* 0xACC */ s16 unk_ACC;
|
/* 0xACC */ s16 unk_ACC;
|
||||||
/* 0xACE */ s8 unk_ACE;
|
/* 0xACE */ s8 unk_ACE;
|
||||||
/* 0xACF */ u8 putAwayCountdown; // Frames to wait before showing "Put Away" on A
|
/* 0xACF */ u8 putAwayCooldownTimer; // Frames to wait before showing "Put Away" on A
|
||||||
/* 0xAD0 */ f32 speedXZ; // Controls horizontal speed, used for `actor.speed`. Current or target value depending on context.
|
/* 0xAD0 */ f32 speedXZ; // Controls horizontal speed, used for `actor.speed`. Current or target value depending on context.
|
||||||
/* 0xAD4 */ s16 yaw; // General yaw value, used both for world and shape rotation. Current or target value depending on context.
|
/* 0xAD4 */ s16 yaw; // General yaw value, used both for world and shape rotation. Current or target value depending on context.
|
||||||
/* 0xAD6 */ s16 parallelYaw; // yaw in "parallel" mode, Z-Target without an actor lock-on
|
/* 0xAD6 */ s16 parallelYaw; // yaw in "parallel" mode, Z-Target without an actor lock-on
|
||||||
|
@ -1280,7 +1280,7 @@ typedef struct Player {
|
||||||
/* 0xB44 */ f32 unk_B44;
|
/* 0xB44 */ f32 unk_B44;
|
||||||
/* 0xB48 */ f32 unk_B48;
|
/* 0xB48 */ f32 unk_B48;
|
||||||
/* 0xB4C */ s16 unk_B4C;
|
/* 0xB4C */ s16 unk_B4C;
|
||||||
/* 0xB4E */ s16 unk_B4E;
|
/* 0xB4E */ s16 turnRate; // Amount angle is changed every frame when turning in place
|
||||||
/* 0xB50 */ f32 unk_B50;
|
/* 0xB50 */ f32 unk_B50;
|
||||||
/* 0xB54 */ f32 yDistToLedge; // y distance to ground above an interact wall. LEDGE_DIST_MAX if no ground if found
|
/* 0xB54 */ f32 yDistToLedge; // y distance to ground above an interact wall. LEDGE_DIST_MAX if no ground if found
|
||||||
/* 0xB58 */ f32 distToInteractWall; // xyz distance to the interact wall
|
/* 0xB58 */ f32 distToInteractWall; // xyz distance to the interact wall
|
||||||
|
|
|
@ -123,7 +123,7 @@ void Player_Action_6(Player* this, PlayState* play);
|
||||||
void Player_Action_7(Player* this, PlayState* play);
|
void Player_Action_7(Player* this, PlayState* play);
|
||||||
void Player_Action_8(Player* this, PlayState* play);
|
void Player_Action_8(Player* this, PlayState* play);
|
||||||
void Player_Action_9(Player* this, PlayState* play);
|
void Player_Action_9(Player* this, PlayState* play);
|
||||||
void Player_Action_10(Player* this, PlayState* play);
|
void Player_Action_TurnInPlace(Player* this, PlayState* play);
|
||||||
void Player_Action_11(Player* this, PlayState* play);
|
void Player_Action_11(Player* this, PlayState* play);
|
||||||
void Player_Action_12(Player* this, PlayState* play);
|
void Player_Action_12(Player* this, PlayState* play);
|
||||||
void Player_Action_13(Player* this, PlayState* play);
|
void Player_Action_13(Player* this, PlayState* play);
|
||||||
|
@ -5194,7 +5194,7 @@ s8 sActionHandlerList5[] = {
|
||||||
/* 8 */ -PLAYER_ACTION_HANDLER_7,
|
/* 8 */ -PLAYER_ACTION_HANDLER_7,
|
||||||
};
|
};
|
||||||
|
|
||||||
s8 sActionHandlerList6[] = {
|
s8 sActionHandlerListTurnInPlace[] = {
|
||||||
/* 0 */ -PLAYER_ACTION_HANDLER_7,
|
/* 0 */ -PLAYER_ACTION_HANDLER_7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8238,7 +8238,7 @@ s32 Player_ActionHandler_6(Player* this, PlayState* play) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this->putAwayCountdown == 0) && (this->heldItemAction >= PLAYER_IA_SWORD_KOKIRI) &&
|
if ((this->putAwayCooldownTimer == 0) && (this->heldItemAction >= PLAYER_IA_SWORD_KOKIRI) &&
|
||||||
(this->transformation != PLAYER_FORM_FIERCE_DEITY)) {
|
(this->transformation != PLAYER_FORM_FIERCE_DEITY)) {
|
||||||
Player_UseItem(play, this, ITEM_NONE);
|
Player_UseItem(play, this, ITEM_NONE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -8383,8 +8383,8 @@ void func_8083A794(Player* this, PlayState* play) {
|
||||||
Player_SetAction(play, this, func_8082FBE8(this) ? Player_Action_14 : Player_Action_13, 1);
|
Player_SetAction(play, this, func_8082FBE8(this) ? Player_Action_14 : Player_Action_13, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083A844(Player* this, PlayState* play, s16 currentYaw) {
|
void func_8083A844(Player* this, PlayState* play, s16 yaw) {
|
||||||
this->yaw = currentYaw;
|
this->yaw = yaw;
|
||||||
this->actor.shape.rot.y = this->yaw;
|
this->actor.shape.rot.y = this->yaw;
|
||||||
func_8083A794(this, play);
|
func_8083A794(this, play);
|
||||||
}
|
}
|
||||||
|
@ -8560,12 +8560,12 @@ void Player_InitMode_F(PlayState* play, Player* this) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083AECC(Player* this, s16 currentYaw, PlayState* play) {
|
void func_8083AECC(Player* this, s16 yaw, PlayState* play) {
|
||||||
Player_SetAction(play, this, Player_Action_6, 1);
|
Player_SetAction(play, this, Player_Action_6, 1);
|
||||||
PlayerAnimation_CopyJointToMorph(play, &this->skelAnime);
|
PlayerAnimation_CopyJointToMorph(play, &this->skelAnime);
|
||||||
this->unk_B38 = 0.0f;
|
this->unk_B38 = 0.0f;
|
||||||
this->unk_B34 = 0.0f;
|
this->unk_B34 = 0.0f;
|
||||||
this->yaw = currentYaw;
|
this->yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083AF30(Player* this, PlayState* play) {
|
void func_8083AF30(Player* this, PlayState* play) {
|
||||||
|
@ -8573,12 +8573,12 @@ void func_8083AF30(Player* this, PlayState* play) {
|
||||||
Player_Anim_PlayLoopMorph(play, this, D_8085BE84[PLAYER_ANIMGROUP_walk][this->modelAnimType]);
|
Player_Anim_PlayLoopMorph(play, this, D_8085BE84[PLAYER_ANIMGROUP_walk][this->modelAnimType]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083AF8C(Player* this, s16 currentYaw, PlayState* play) {
|
void func_8083AF8C(Player* this, s16 yaw, PlayState* play) {
|
||||||
Player_SetAction(play, this, Player_Action_15, 1);
|
Player_SetAction(play, this, Player_Action_15, 1);
|
||||||
PlayerAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_anchor_back_walk, PLAYER_ANIM_NORMAL_SPEED, 0.0f,
|
PlayerAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_anchor_back_walk, PLAYER_ANIM_NORMAL_SPEED, 0.0f,
|
||||||
Animation_GetLastFrame(&gPlayerAnim_link_anchor_back_walk), ANIMMODE_ONCE, -6.0f);
|
Animation_GetLastFrame(&gPlayerAnim_link_anchor_back_walk), ANIMMODE_ONCE, -6.0f);
|
||||||
this->speedXZ = 8.0f;
|
this->speedXZ = 8.0f;
|
||||||
this->yaw = currentYaw;
|
this->yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083B030(Player* this, PlayState* play) {
|
void func_8083B030(Player* this, PlayState* play) {
|
||||||
|
@ -8592,11 +8592,14 @@ void func_8083B090(Player* this, PlayState* play) {
|
||||||
PlayerAnimation_PlayOnceSetSpeed(play, &this->skelAnime, &gPlayerAnim_link_anchor_back_brake, 6.0f / 3.0f);
|
PlayerAnimation_PlayOnceSetSpeed(play, &this->skelAnime, &gPlayerAnim_link_anchor_back_brake, 6.0f / 3.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083B0E4(PlayState* play, Player* this, s16 currentYaw) {
|
void Player_SetupTurnInPlace(PlayState* play, Player* this, s16 yaw) {
|
||||||
this->yaw = currentYaw;
|
this->yaw = yaw;
|
||||||
Player_SetAction(play, this, Player_Action_10, 1);
|
|
||||||
this->unk_B4E = 1200;
|
Player_SetAction(play, this, Player_Action_TurnInPlace, 1);
|
||||||
this->unk_B4E *= sWaterSpeedFactor;
|
|
||||||
|
this->turnRate = 0x4B0;
|
||||||
|
this->turnRate *= sWaterSpeedFactor; // slow turn rate by half when in water
|
||||||
|
|
||||||
PlayerAnimation_Change(play, &this->skelAnime, D_8085BE84[PLAYER_ANIMGROUP_45_turn][this->modelAnimType],
|
PlayerAnimation_Change(play, &this->skelAnime, D_8085BE84[PLAYER_ANIMGROUP_45_turn][this->modelAnimType],
|
||||||
PLAYER_ANIM_NORMAL_SPEED, 0.0f, 0.0f, ANIMMODE_LOOP, -6.0f);
|
PLAYER_ANIM_NORMAL_SPEED, 0.0f, 0.0f, ANIMMODE_LOOP, -6.0f);
|
||||||
}
|
}
|
||||||
|
@ -8723,11 +8726,11 @@ s32 func_8083B3B4(PlayState* play, Player* this, Input* input) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083B73C(PlayState* play, Player* this, s16 currentYaw) {
|
void func_8083B73C(PlayState* play, Player* this, s16 yaw) {
|
||||||
Player_SetAction(play, this, Player_Action_57, 0);
|
Player_SetAction(play, this, Player_Action_57, 0);
|
||||||
Player_Anim_PlayLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim);
|
Player_Anim_PlayLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim);
|
||||||
this->actor.shape.rot.y = currentYaw;
|
this->actor.shape.rot.y = yaw;
|
||||||
this->yaw = currentYaw;
|
this->yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_8083B798(PlayState* play, Player* this) {
|
void func_8083B798(PlayState* play, Player* this) {
|
||||||
|
@ -8870,7 +8873,7 @@ void func_8083BB4C(PlayState* play, Player* this) {
|
||||||
(((Player_Action_56 != this->actionFunc) && !(this->stateFlags3 & PLAYER_STATE3_8000)) ||
|
(((Player_Action_56 != this->actionFunc) && !(this->stateFlags3 & PLAYER_STATE3_8000)) ||
|
||||||
(this->actor.bgCheckFlags & BGCHECKFLAG_GROUND))) {
|
(this->actor.bgCheckFlags & BGCHECKFLAG_GROUND))) {
|
||||||
if (this->skelAnime.moveFlags == 0) {
|
if (this->skelAnime.moveFlags == 0) {
|
||||||
func_8083B0E4(play, this, this->actor.shape.rot.y);
|
Player_SetupTurnInPlace(play, this, this->actor.shape.rot.y);
|
||||||
}
|
}
|
||||||
func_8083B32C(play, this, this->actor.velocity.y);
|
func_8083B32C(play, this, this->actor.velocity.y);
|
||||||
}
|
}
|
||||||
|
@ -11421,10 +11424,12 @@ void Player_SetDoAction(PlayState* play, Player* this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doActionA != DO_ACTION_PUTAWAY) {
|
if (doActionA != DO_ACTION_PUTAWAY) {
|
||||||
this->putAwayCountdown = 20;
|
this->putAwayCooldownTimer = 20;
|
||||||
} else if (this->putAwayCountdown != 0) {
|
} else if (this->putAwayCooldownTimer != 0) {
|
||||||
|
// Replace the "Put Away" Do Action label with a blank label while
|
||||||
|
// the cooldown timer is counting down
|
||||||
doActionA = DO_ACTION_NONE;
|
doActionA = DO_ACTION_NONE;
|
||||||
this->putAwayCountdown--;
|
this->putAwayCooldownTimer--;
|
||||||
}
|
}
|
||||||
|
|
||||||
Interface_SetAButtonDoAction(play, doActionA);
|
Interface_SetAButtonDoAction(play, doActionA);
|
||||||
|
@ -14157,7 +14162,7 @@ void Player_Action_3(Player* this, PlayState* play) {
|
||||||
s16 temp_v0_2 = yawTarget - this->actor.shape.rot.y;
|
s16 temp_v0_2 = yawTarget - this->actor.shape.rot.y;
|
||||||
|
|
||||||
if (ABS_ALT(temp_v0_2) > 0x320) {
|
if (ABS_ALT(temp_v0_2) > 0x320) {
|
||||||
func_8083B0E4(play, this, yawTarget);
|
Player_SetupTurnInPlace(play, this, yawTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14228,7 +14233,7 @@ void Player_Action_Idle(Player* this, PlayState* play) {
|
||||||
yawDiff = yawTarget - this->actor.shape.rot.y;
|
yawDiff = yawTarget - this->actor.shape.rot.y;
|
||||||
|
|
||||||
if (ABS_ALT(yawDiff) > 0x320) {
|
if (ABS_ALT(yawDiff) > 0x320) {
|
||||||
func_8083B0E4(play, this, yawTarget);
|
Player_SetupTurnInPlace(play, this, yawTarget);
|
||||||
} else {
|
} else {
|
||||||
Math_ScaledStepToS(&this->actor.shape.rot.y, yawTarget, 0x4B0);
|
Math_ScaledStepToS(&this->actor.shape.rot.y, yawTarget, 0x4B0);
|
||||||
this->yaw = this->actor.shape.rot.y;
|
this->yaw = this->actor.shape.rot.y;
|
||||||
|
@ -14455,7 +14460,14 @@ void Player_Action_9(Player* this, PlayState* play) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player_Action_10(Player* this, PlayState* play) {
|
/**
|
||||||
|
* Turn in place until the angle pointed to by the control stick is reached.
|
||||||
|
*
|
||||||
|
* This is the state that the speedrunning community refers to as "ESS" or "ESS Position".
|
||||||
|
* See the bug comment below and https://www.zeldaspeedruns.com/mm/tech/ess-and-hess
|
||||||
|
* for more information.
|
||||||
|
*/
|
||||||
|
void Player_Action_TurnInPlace(Player* this, PlayState* play) {
|
||||||
f32 speedTarget;
|
f32 speedTarget;
|
||||||
s16 yawTarget;
|
s16 yawTarget;
|
||||||
|
|
||||||
|
@ -14469,18 +14481,26 @@ void Player_Action_10(Player* this, PlayState* play) {
|
||||||
|
|
||||||
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_CURVED, play);
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_CURVED, play);
|
||||||
|
|
||||||
|
//! @bug This action does not handle xzSpeed in any capacity.
|
||||||
|
//! Player's current speed value will be maintained the entire time this action is running.
|
||||||
|
//! This is the core bug that allows many different glitches to manifest.
|
||||||
|
//!
|
||||||
|
//! One possible fix is to kill all speed instantly in `Player_SetupTurnInPlace`.
|
||||||
|
//! Another possible fix is to gradually kill speed by calling `Player_DecelerateToZero`
|
||||||
|
//! here, which plenty of other "standing" actions do.
|
||||||
|
|
||||||
if ((this != GET_PLAYER(play)) && (this->focusActor == NULL)) {
|
if ((this != GET_PLAYER(play)) && (this->focusActor == NULL)) {
|
||||||
yawTarget = this->actor.home.rot.y;
|
yawTarget = this->actor.home.rot.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Player_TryActionHandlerList(play, this, sActionHandlerList6, true)) {
|
if (Player_TryActionHandlerList(play, this, sActionHandlerListTurnInPlace, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (speedTarget != 0.0f) {
|
if (speedTarget != 0.0f) {
|
||||||
this->actor.shape.rot.y = yawTarget;
|
this->actor.shape.rot.y = yawTarget;
|
||||||
func_8083A794(this, play);
|
func_8083A794(this, play);
|
||||||
} else if (Math_ScaledStepToS(&this->actor.shape.rot.y, yawTarget, this->unk_B4E)) {
|
} else if (Math_ScaledStepToS(&this->actor.shape.rot.y, yawTarget, this->turnRate)) {
|
||||||
func_80839E74(this, play);
|
func_80839E74(this, play);
|
||||||
}
|
}
|
||||||
this->yaw = this->actor.shape.rot.y;
|
this->yaw = this->actor.shape.rot.y;
|
||||||
|
@ -20841,7 +20861,7 @@ s32 Player_TryCsAction(PlayState* play, Player* this, PlayerCsAction csAction) {
|
||||||
// Specific to Kafei, any negative csAction works
|
// Specific to Kafei, any negative csAction works
|
||||||
if ((this->actor.id == ACTOR_EN_TEST3) && (csAction < 0)) {
|
if ((this->actor.id == ACTOR_EN_TEST3) && (csAction < 0)) {
|
||||||
// PLAYER_CSACTION_NEG1
|
// PLAYER_CSACTION_NEG1
|
||||||
func_8083B0E4(play, this, this->actor.home.rot.y);
|
Player_SetupTurnInPlace(play, this, this->actor.home.rot.y);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4510,7 +4510,7 @@
|
||||||
0x8083AF8C:("func_8083AF8C",),
|
0x8083AF8C:("func_8083AF8C",),
|
||||||
0x8083B030:("func_8083B030",),
|
0x8083B030:("func_8083B030",),
|
||||||
0x8083B090:("func_8083B090",),
|
0x8083B090:("func_8083B090",),
|
||||||
0x8083B0E4:("func_8083B0E4",),
|
0x8083B0E4:("Player_SetupTurnInPlace",),
|
||||||
0x8083B1A0:("func_8083B1A0",),
|
0x8083B1A0:("func_8083B1A0",),
|
||||||
0x8083B23C:("func_8083B23C",),
|
0x8083B23C:("func_8083B23C",),
|
||||||
0x8083B29C:("func_8083B29C",),
|
0x8083B29C:("func_8083B29C",),
|
||||||
|
@ -4671,7 +4671,7 @@
|
||||||
0x8084A794:("Player_Action_7",),
|
0x8084A794:("Player_Action_7",),
|
||||||
0x8084A884:("Player_Action_8",),
|
0x8084A884:("Player_Action_8",),
|
||||||
0x8084A8E8:("Player_Action_9",),
|
0x8084A8E8:("Player_Action_9",),
|
||||||
0x8084AB4C:("Player_Action_10",),
|
0x8084AB4C:("Player_Action_TurnInPlace",),
|
||||||
0x8084AC84:("Player_Action_11",),
|
0x8084AC84:("Player_Action_11",),
|
||||||
0x8084AEEC:("Player_Action_12",),
|
0x8084AEEC:("Player_Action_12",),
|
||||||
0x8084AF9C:("Player_Action_13",),
|
0x8084AF9C:("Player_Action_13",),
|
||||||
|
|
|
@ -4854,7 +4854,7 @@
|
||||||
0x8085CFF8:("sActionHandlerList3","UNK_TYPE1","",0x1),
|
0x8085CFF8:("sActionHandlerList3","UNK_TYPE1","",0x1),
|
||||||
0x8085D004:("sActionHandlerList4","UNK_TYPE1","",0x1),
|
0x8085D004:("sActionHandlerList4","UNK_TYPE1","",0x1),
|
||||||
0x8085D00C:("sActionHandlerList5","UNK_TYPE1","",0x1),
|
0x8085D00C:("sActionHandlerList5","UNK_TYPE1","",0x1),
|
||||||
0x8085D018:("sActionHandlerList6","UNK_TYPE1","",0x1),
|
0x8085D018:("sActionHandlerListTurnInPlace","UNK_TYPE1","",0x1),
|
||||||
0x8085D01C:("sActionHandlerListIdle","UNK_TYPE1","",0x1),
|
0x8085D01C:("sActionHandlerListIdle","UNK_TYPE1","",0x1),
|
||||||
0x8085D028:("sActionHandlerList8","UNK_TYPE1","",0x1),
|
0x8085D028:("sActionHandlerList8","UNK_TYPE1","",0x1),
|
||||||
0x8085D034:("sActionHandlerList9","UNK_TYPE1","",0x1),
|
0x8085D034:("sActionHandlerList9","UNK_TYPE1","",0x1),
|
||||||
|
|
Loading…
Reference in New Issue