From d1e9d5af2f373b3d7c02879f51b5315ff64eb43c Mon Sep 17 00:00:00 2001 From: Joey Cato Date: Tue, 12 May 2026 12:56:54 -0700 Subject: [PATCH] Add Fast Roll cheat (#929) * Add roll fast cheat * Corrected case on cheat name * Addressed PR feedback * Fixed whitespace * Renamed cheat to be more consistent with other options --- include/dusk/settings.h | 1 + src/d/actor/d_a_alink.cpp | 30 +++++++++++++++++++++++++++--- src/dusk/imgui/ImGuiMenuGame.cpp | 1 + src/dusk/settings.cpp | 2 ++ src/dusk/ui/settings.cpp | 3 +++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/dusk/settings.h b/include/dusk/settings.h index 59f1daada0..366a9cd82b 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -165,6 +165,7 @@ struct UserSettings { ConfigVar alwaysGreatspin; ConfigVar enableFastIronBoots; ConfigVar canTransformAnywhere; + ConfigVar fastRoll; ConfigVar fastSpinner; ConfigVar freeMagicArmor; diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index 343282e7b1..0e0f0d06c7 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -16114,6 +16114,9 @@ int daAlink_c::procSlideLand() { int daAlink_c::procFrontRollInit() { BOOL is_guard_anime = checkUpperGuardAnime(); +#ifdef TARGET_PC + const f32 fastRollMultiplier = dusk::getSettings().game.fastRoll ? 2.0f : 1.0f; +#endif if (mProcID == PROC_FRONT_ROLL && mDemo.getDemoMode() == daPy_demo_c::DEMO_FRONT_ROLL_e) { return 0; @@ -16129,10 +16132,16 @@ int daAlink_c::procFrontRollInit() { roll_anm_speed = mpHIO->mFrontRoll.m.mRollAnm.mStartFrame; } - setSingleAnime(ANM_FRONT_ROLL, mpHIO->mFrontRoll.m.mRollAnm.mSpeed, roll_anm_speed, + setSingleAnime(ANM_FRONT_ROLL, +#ifdef TARGET_PC + mpHIO->mFrontRoll.m.mRollAnm.mSpeed * fastRollMultiplier, +#else + mpHIO->mFrontRoll.m.mRollAnm.mSpeed, +#endif + roll_anm_speed, mpHIO->mFrontRoll.m.mRollAnm.mEndFrame, mpHIO->mFrontRoll.m.mRollAnm.mInterpolation); - + mNormalSpeed = speedF * mpHIO->mFrontRoll.m.mSpeedRate + mpHIO->mFrontRoll.m.mInitSpeed; f32 max_speed = mpHIO->mFrontRoll.m.mInitSpeed + mpHIO->mMove.m.mMaxSpeed * mpHIO->mFrontRoll.m.mSpeedRate; @@ -16155,6 +16164,10 @@ int daAlink_c::procFrontRollInit() { mNormalSpeed *= mHeavySpeedMultiplier; } +#ifdef TARGET_PC + mNormalSpeed *= fastRollMultiplier; +#endif + current.angle.y = shape_angle.y; voiceStart(Z2SE_AL_V_BACKTEN); mProcVar2.field_0x300c = 0; @@ -16385,6 +16398,9 @@ int daAlink_c::procFrontRollSuccess() { int daAlink_c::procSideRollInit(int param_0) { BOOL is_prev_guardAnm = checkUpperGuardAnime(); +#ifdef TARGET_PC + const f32 fastRollMultiplier = dusk::getSettings().game.fastRoll ? 2.0f : 1.0f; +#endif if (!commonProcInitNotSameProc(PROC_SIDE_ROLL)) { return 0; @@ -16401,7 +16417,12 @@ int daAlink_c::procSideRollInit(int param_0) { current.angle.y = shape_angle.y + -0x4000; } - setSingleAnime(anmID, mpHIO->mGuard.mTurnMove.m.mSideRollAnmSpeed, + setSingleAnime(anmID, +#ifdef TARGET_PC + mpHIO->mGuard.mTurnMove.m.mSideRollAnmSpeed * fastRollMultiplier, +#else + mpHIO->mGuard.mTurnMove.m.mSideRollAnmSpeed, +#endif mpHIO->mGuard.mTurnMove.m.mTurnAnm.mStartFrame, mpHIO->mGuard.mTurnMove.m.mTurnAnm.mEndFrame, mpHIO->mGuard.mTurnMove.m.mTurnAnm.mInterpolation); @@ -16417,6 +16438,9 @@ int daAlink_c::procSideRollInit(int param_0) { } else if (checkHeavyStateOn(TRUE, TRUE)) { mNormalSpeed *= mHeavySpeedMultiplier; } +#ifdef TARGET_PC + mNormalSpeed *= fastRollMultiplier; +#endif setFootEffectProcType(0); field_0x2f9d = 4; diff --git a/src/dusk/imgui/ImGuiMenuGame.cpp b/src/dusk/imgui/ImGuiMenuGame.cpp index 783bbbdeec..43a01483d0 100644 --- a/src/dusk/imgui/ImGuiMenuGame.cpp +++ b/src/dusk/imgui/ImGuiMenuGame.cpp @@ -40,6 +40,7 @@ namespace dusk { getSettings().game.alwaysGreatspin.setValue(false); getSettings().game.enableFastIronBoots.setValue(false); getSettings().game.canTransformAnywhere.setValue(false); + getSettings().game.fastRoll.setValue(false); getSettings().game.fastSpinner.setValue(false); getSettings().game.freeMagicArmor.setValue(false); diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 5944fe701b..888ad2da7f 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -102,6 +102,7 @@ UserSettings g_userSettings = { .alwaysGreatspin {"game.alwaysGreatspin", false}, .enableFastIronBoots {"game.enableFastIronBoots", false}, .canTransformAnywhere {"game.canTransformAnywhere", false}, + .fastRoll {"game.fastRoll", false}, .fastSpinner {"game.fastSpinner", false}, .freeMagicArmor {"game.freeMagicArmor", false}, @@ -188,6 +189,7 @@ void registerSettings() { Register(g_userSettings.game.disableCutscenePillarboxing); Register(g_userSettings.game.enableFastIronBoots); Register(g_userSettings.game.canTransformAnywhere); + Register(g_userSettings.game.fastRoll); Register(g_userSettings.game.freeMagicArmor); Register(g_userSettings.game.restoreWiiGlitches); Register(g_userSettings.game.enableLinkDollRotation); diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index 33b02aa8da..f8eec85a52 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -189,6 +189,7 @@ void reset_for_speedrun_mode() { getSettings().game.alwaysGreatspin.setValue(false); getSettings().game.enableFastIronBoots.setValue(false); getSettings().game.canTransformAnywhere.setValue(false); + getSettings().game.fastRoll.setValue(false); getSettings().game.fastSpinner.setValue(false); getSettings().game.freeMagicArmor.setValue(false); @@ -1084,6 +1085,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { "Speeds up movement while wearing the Iron Boots."); addCheat("Can Transform Anywhere", getSettings().game.canTransformAnywhere, "Allows transforming even if NPCs are looking."); + addCheat("Fast Roll", getSettings().game.fastRoll, + "Makes Link's roll animation and movement twice as fast."); addCheat("Fast Spinner", getSettings().game.fastSpinner, "Speeds up Spinner movement while holding R."); addCheat("Free Magic Armor", getSettings().game.freeMagicArmor,