summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Hoey <121978037+A-Green-Spoon@users.noreply.github.com>2025-05-06 20:00:33 -0400
committerGitHub <noreply@github.com>2025-05-06 17:00:33 -0700
commit6a93625f5cfbaca71262a4fdce1a90d055a282ba (patch)
treeeebf37154e3d9f9f1f3ae30e6795b2f4377502bc
parenta0e49f99607ed6d486925e7ef7d6e9d3e76585be (diff)
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
-rw-r--r--soh/include/functions.h2
-rw-r--r--soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp110
-rw-r--r--soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h37
-rw-r--r--soh/soh/SohGui/SohMenuEnhancements.cpp5
-rw-r--r--soh/src/code/z_onepointdemo.c27
-rw-r--r--soh/src/overlays/actors/ovl_player_actor/z_player.c52
6 files changed, 170 insertions, 63 deletions
diff --git a/soh/include/functions.h b/soh/include/functions.h
index 86e3bf77f..ad615d173 100644
--- a/soh/include/functions.h
+++ b/soh/include/functions.h
@@ -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);
diff --git a/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp b/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp
new file mode 100644
index 000000000..b9f65df04
--- /dev/null
+++ b/soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp
@@ -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 }); \ No newline at end of file
diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
index d57d5029a..0748d913a 100644
--- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
+++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h
@@ -296,6 +296,43 @@ typedef enum {
// #### `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)
// ```
// #### `args`
diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp
index 0b78892d4..82a1d0fae 100644
--- a/soh/soh/SohGui/SohMenuEnhancements.cpp
+++ b/soh/soh/SohGui/SohMenuEnhancements.cpp
@@ -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"));
diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c
index 40f5c1474..c68f1b522 100644
--- a/soh/src/code/z_onepointdemo.c
+++ b/soh/src/code/z_onepointdemo.c
@@ -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;
diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c
index 6638893f5..4da9e0deb 100644
--- a/soh/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c
@@ -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;
}
}