VBify Crawl Speed Enhancement and Add Exlcude Glitch-Aiding Crawlspace Option (#5465)

* add menu option

* VBify + add conditions

* oops wrong func

* clean up includes + casting

* move z_player externed functions

* better name

* correct menu text

* one last name final final

* maintain glitch-aiding selection
This commit is contained in:
Eric Hoey 2025-05-06 20:00:33 -04:00 committed by GitHub
commit 6a93625f5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 170 additions and 63 deletions

View file

@ -1044,6 +1044,7 @@ VecSph* OLib_Vec3fToVecSph(VecSph* dest, Vec3f* vec);
VecSph* OLib_Vec3fToVecSphGeo(VecSph* arg0, Vec3f* arg1);
VecSph* OLib_Vec3fDiffToVecSphGeo(VecSph* arg0, Vec3f* a, Vec3f* b);
Vec3f* OLib_Vec3fDiffRad(Vec3f* dest, Vec3f* a, Vec3f* b);
void OnePointCutscene_SetCsCamPoints(Camera* camera, s16 actionParameters, s16 initTimer, CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints);
s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s16 camIdx);
s16 OnePointCutscene_EndCutscene(PlayState* play, s16 camIdx);
s32 OnePointCutscene_Attention(PlayState* play, Actor* actor);
@ -1102,6 +1103,7 @@ void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx);
s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input);
u8 PlayerGrounded(Player* player);
void Player_SetBootData(PlayState* play, Player* player);
void Player_StartAnimMovement(PlayState* play, Player* player, s32 flags);
s32 Player_InBlockingCsMode(PlayState* play, Player* player);
s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction);
s32 Player_InCsMode(PlayState* play);

View file

@ -0,0 +1,110 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "global.h"
extern "C" {
#include "functions.h"
#include "objects/gameplay_keep/gameplay_keep.h"
extern PlayState* gPlayState;
}
#define CVAR_CRAWL_SPEED_NAME CVAR_ENHANCEMENT("CrawlSpeed")
#define CVAR_CRAWL_SPEED_DEFAULT 1
#define CVAR_CRAWL_SPEED_VALUE CVarGetInteger(CVAR_CRAWL_SPEED_NAME, CVAR_CRAWL_SPEED_DEFAULT)
#define CVAR_GLITCH_AIDING_NAME CVAR_ENHANCEMENT("GlitchAidingCrawlspaces")
#define CVAR_GLITCH_AIDING_DEFAULT 0
#define CVAR_GLITCH_AIDING_VALUE CVarGetInteger(CVAR_GLITCH_AIDING_NAME, CVAR_GLITCH_AIDING_DEFAULT)
extern "C" void ExitCrawlspace(Player* player, PlayState* play) {
LinkAnimationHeader* animExit = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_end;
LinkAnimationHeader* animEnter = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_start;
if (player->linearVelocity > 0.0f) {
// Leaving a crawlspace forwards
player->actor.shape.rot.y = player->actor.wallYaw + 0x8000;
LinkAnimation_Change(play, &player->skelAnime, animExit, ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(animExit), ANIMMODE_ONCE, 0.0f);
Player_StartAnimMovement(play, player, 0x9D);
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
} else {
// Leaving a crawlspace backwards
player->actor.shape.rot.y = player->actor.wallYaw;
LinkAnimation_Change(play, &player->skelAnime, animEnter, -1.0f * ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f),
Animation_GetLastFrame(animEnter), 0.0f, ANIMMODE_ONCE, 0.0f);
Player_StartAnimMovement(play, player, 0x9D);
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
}
}
extern "C" void ExitCrawlspaceCS(PlayState* play, Camera* csCam, int16_t actionParameters, int16_t initTimer,
CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints) {
s16 camCrawlTemp = CVAR_CRAWL_SPEED_VALUE;
s16 camCrawlTimer = initTimer / camCrawlTemp;
OnePointCutscene_SetCsCamPoints(csCam, actionParameters | 0x1000, camCrawlTimer, atPoints, eyePoints);
}
extern "C" void EnterCrawlspace(Player* player, PlayState* play) {
LinkAnimationHeader* anim = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_start;
LinkAnimation_Change(play, &player->skelAnime, anim, ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(anim), ANIMMODE_ONCE, 0.0f);
}
extern "C" void IncreaseCrawlSpeed(Player* player, PlayState* play) {
Input* sControlInput = &play->state.input[0];
player->linearVelocity = sControlInput->rel.stick_y * 0.03f * CVAR_CRAWL_SPEED_VALUE;
}
void CrawlSpeed_Register() {
bool shouldRegister = CVAR_CRAWL_SPEED_VALUE > 1;
COND_VB_SHOULD(VB_CRAWL_SPEED_EXIT, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
bool excludeWellBackroom = (player->actor.world.pos.x > 950.0f) && (player->actor.world.pos.x < 1025.0f) &&
(player->actor.world.pos.z > -1510.0f) && (player->actor.world.pos.z < -1490.0f) &&
gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL;
bool excludeGlitchAiding = CVAR_GLITCH_AIDING_VALUE;
if (excludeGlitchAiding && excludeWellBackroom) {
*should = true;
} else {
ExitCrawlspace(player, gPlayState);
*should = false;
}
});
COND_VB_SHOULD(VB_CRAWL_SPEED_EXIT_CS, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
Camera* csCam = va_arg(args, Camera*);
s16 csId = va_arg(args, s16);
s16 actionParameters = va_arg(args, s16);
s16 initTimer = va_arg(args, s16);
CutsceneCameraPoint* atPoints = va_arg(args, CutsceneCameraPoint*);
CutsceneCameraPoint* eyePoints = va_arg(args, CutsceneCameraPoint*);
bool excludeWellBackroom = (player->actor.world.pos.x > 950.0f) && (player->actor.world.pos.x < 1025.0f) &&
(player->actor.world.pos.z > -1510.0f) && (player->actor.world.pos.z < -1490.0f) &&
gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL;
bool excludeGlitchAiding = CVAR_GLITCH_AIDING_VALUE;
if (excludeGlitchAiding && excludeWellBackroom) {
*should = true;
} else {
ExitCrawlspaceCS(gPlayState, csCam, actionParameters, initTimer, atPoints, eyePoints);
*should = false;
}
});
COND_VB_SHOULD(VB_CRAWL_SPEED_ENTER, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
EnterCrawlspace(player, gPlayState);
*should = false;
});
COND_VB_SHOULD(VB_CRAWL_SPEED_INCREASE, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
IncreaseCrawlSpeed(player, gPlayState);
*should = false;
});
}
static RegisterShipInitFunc initSpeed(CrawlSpeed_Register, { CVAR_CRAWL_SPEED_NAME });

View file

@ -294,6 +294,43 @@ typedef enum {
// - `*ObjKibako2`
VB_CRATE_SETUP_DRAW,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_CRAWL_SPEED_ENTER,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_CRAWL_SPEED_EXIT,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*Camera`
// - 'int16_t' (csId)
// - 'int16_t' (actionParameters)
// - 'int16_t' (initTimer)
// - 'CutsceneCameraPoint*' (atPoints)
// - 'CutsceneCameraPoint*' (eyePoints)
VB_CRAWL_SPEED_EXIT_CS,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_CRAWL_SPEED_INCREASE,
// #### `result`
// ```c
// !Flags_GetItemGetInf(ITEMGETINF_1C)

View file

@ -382,6 +382,11 @@ void SohMenu::AddMenuEnhancements() {
AddWidget(path, "Crawl Speed %dx", WIDGET_CVAR_SLIDER_INT)
.CVar(CVAR_ENHANCEMENT("CrawlSpeed"))
.Options(IntSliderOptions().Min(1).Max(4).DefaultValue(1).Format("%dx"));
AddWidget(path, "Exclude Glitch-Aiding Crawlspaces", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("GlitchAidingCrawlspaces"))
.PreFunc([](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 0) == 1; })
.Options(CheckboxOptions().Tooltip("Don't increase crawl speed when exiting glitch-useful crawlspaces."
"Currently it is only the BOTW crawlspace to locked door"));
AddWidget(path, "King Zora Speed: %.2fx", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_ENHANCEMENT("MweepSpeed"))
.Options(FloatSliderOptions().Min(0.1f).Max(5.0f).DefaultValue(1.0f).Format("%.2fx"));

View file

@ -71,12 +71,6 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
f32 tempRand;
Unique9OnePointCs* csInfo = ONEPOINT_CS_INFO(csCam);
// #region SOH [Enhancement]
// the default is 90, lower values necessary to prevent camera swing as animation speeds up
s16 camCrawlTemp = CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1);
s16 camCrawlTimer = D_8012042C / camCrawlTemp;
// #endregion
switch (csId) {
case 1020:
if (timer < 20) {
@ -336,26 +330,19 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
case 9601:
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120398);
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_EXIT_CS, true, csCam, csId, D_80120430, D_8012042C, D_80120308,
D_80120398)) {
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120398);
}
break;
case 9602:
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120434);
break;
// #endregion
} else {
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
if (GameInteractor_Should(VB_CRAWL_SPEED_EXIT_CS, true, csCam, csId, D_80120430, D_8012042C, D_80120308,
D_80120434)) {
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120434);
break;
}
break;
case 4175:
csInfo->keyFrames = D_8012147C;
csInfo->keyFrameCnt = 4;

View file

@ -7679,19 +7679,10 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall
this->actor.world.pos.z = zVertex1 + (distToInteractWall * wallPolyNormZ);
func_80832224(this);
this->actor.prevPos = this->actor.world.pos;
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
// increase animation speed when entering a tunnel
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
((CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), ANIMMODE_ONCE,
0.0f);
Player_StartAnimMovement(play, this, 0x9D);
// #endregion
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_ENTER, true)) {
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_start);
Player_StartAnimMovement(play, this, 0x9D);
}
Player_StartAnimMovement(play, this, 0x9D);
return true;
}
}
@ -7773,36 +7764,16 @@ s32 Player_TryLeavingCrawlspace(Player* this, PlayState* play) {
if (ABS(yawToWall) > 0x4000) {
Player_SetupAction(play, this, Player_Action_8084C81C, 0);
if (this->linearVelocity > 0.0f) {
// Leaving a crawlspace forwards
this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_end,
((CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) + 1.0f) / 2.0f), 0.0f,
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_end), ANIMMODE_ONCE,
0.0f);
Player_StartAnimMovement(play, this, 0x9D);
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
// #endregion
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_EXIT, true)) {
if (this->linearVelocity > 0.0f) {
// Leaving a crawlspace forwards
this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_end);
Player_StartAnimMovement(play, this, 0x9D);
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
}
} else {
// Leaving a crawlspace backwards
this->actor.shape.rot.y = this->actor.wallYaw;
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
-1.0f * ((CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) + 1.0f) / 2.0f),
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f,
ANIMMODE_ONCE, 0.0f);
Player_StartAnimMovement(play, this, 0x9D);
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
// #endregion
} else {
// Leaving a crawlspace backwards
this->actor.shape.rot.y = this->actor.wallYaw;
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f,
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f,
ANIMMODE_ONCE, 0.0f);
@ -13587,12 +13558,7 @@ void Player_Action_8084C760(Player* this, PlayState* play) {
// player speed in a tunnel
if (!Player_TryLeavingCrawlspace(this, play)) {
// #region SOH [Enhancement]
if (CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1) > 1) {
this->linearVelocity =
sControlInput->rel.stick_y * 0.03f * CVarGetInteger(CVAR_ENHANCEMENT("CrawlSpeed"), 1);
// #endregion
} else {
if (GameInteractor_Should(VB_CRAWL_SPEED_INCREASE, true)) {
this->linearVelocity = sControlInput->rel.stick_y * 0.03f;
}
}