From 62c19c0f64705215f02da068618d5cdee28ad4a1 Mon Sep 17 00:00:00 2001 From: Olivia!! Date: Thu, 28 May 2026 08:25:45 +0200 Subject: [PATCH] Adds a new cheat that let you transform from the start of the game. (#1241) * Adds a new cheat that let you transform from the start of the game. * Preserves transformation when passing loadzones similar to having shadow crystal * standards compliance * code compliance with decomp --- include/dusk/settings.h | 1 + src/d/actor/d_a_alink_dusk.cpp | 6 +++--- src/d/actor/d_a_midna.cpp | 16 ++++++++++------ src/d/d_com_inf_game.cpp | 6 +++++- src/dusk/settings.cpp | 2 ++ src/dusk/ui/settings.cpp | 2 ++ 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/include/dusk/settings.h b/include/dusk/settings.h index f48f5862ca..e36f0b9f24 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -230,6 +230,7 @@ struct UserSettings { ConfigVar fastSpinner; ConfigVar freeMagicArmor; ConfigVar invincibleEnemies; + ConfigVar transformWithoutShadowCrystal; // Technical ConfigVar restoreWiiGlitches; diff --git a/src/d/actor/d_a_alink_dusk.cpp b/src/d/actor/d_a_alink_dusk.cpp index 8c1d415ae0..ef14eadd9f 100644 --- a/src/d/actor/d_a_alink_dusk.cpp +++ b/src/d/actor/d_a_alink_dusk.cpp @@ -72,7 +72,7 @@ void daAlink_c::handleQuickTransform() { } // Check to see if Link has the ability to transform. - if (!dComIfGs_isEventBit(dSv_event_flag_c::M_077)) { + if (!dComIfGs_isEventBit(dSv_event_flag_c::M_077) && !dusk::getSettings().game.transformWithoutShadowCrystal) { return; } @@ -102,7 +102,7 @@ void daAlink_c::handleQuickTransform() { } // Ensure that the Z Button is not dimmed - if (meterDrawPtr->getButtonZAlpha() != 1.f) { + if (meterDrawPtr->getButtonZAlpha() != 1.f && !dusk::getSettings().game.transformWithoutShadowCrystal) { Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0); return; } @@ -122,7 +122,7 @@ void daAlink_c::handleQuickTransform() { bool canTransform = false; if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY) && !checkMagneBootsOn()) { - if (checkMidnaRide()) { + if (checkMidnaRide() || dusk::getSettings().game.transformWithoutShadowCrystal) { if ((checkWolf() && (checkModeFlg(MODE_UNK_1000) || dComIfGp_checkPlayerStatus0(0, 0x10))) || (!checkWolf() && diff --git a/src/d/actor/d_a_midna.cpp b/src/d/actor/d_a_midna.cpp index 3082fc6a71..b33229e08c 100644 --- a/src/d/actor/d_a_midna.cpp +++ b/src/d/actor/d_a_midna.cpp @@ -3106,14 +3106,18 @@ void daMidna_c::setMidnaNoDrawFlg() { BOOL daMidna_c::checkMetamorphoseEnableBase() { BOOL tmp; - if (!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) || - /* dSv_event_flag_c::M_077 - Main Event - Get shadow crystal (can now transform) */ - !dComIfGs_isEventBit(0xD04) || #if TARGET_PC - (fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp) && - !dusk::getSettings().game.canTransformAnywhere) + if (((!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) || + /* dSv_event_flag_c::M_077 - Main Event - Get shadow crystal (can now transform) */ + !dComIfGs_isEventBit(0xD04)) && + !dusk::getSettings().game.transformWithoutShadowCrystal) || + (fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp) && + !dusk::getSettings().game.canTransformAnywhere) #else - fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp) + if (!daAlink_getAlinkActorClass()->checkMidnaRide() || (g_env_light.mEvilInitialized & 0x80) || + /* dSv_event_flag_c::M_077 - Main Event - Get shadow crystal (can now transform) */ + !dComIfGs_isEventBit(0xD04) || + fopAcIt_Judge((fopAcIt_JudgeFunc)daMidna_searchNpc, &tmp) #endif ) { diff --git a/src/d/d_com_inf_game.cpp b/src/d/d_com_inf_game.cpp index 93fc15ca8f..3e881e63f8 100644 --- a/src/d/d_com_inf_game.cpp +++ b/src/d/d_com_inf_game.cpp @@ -2843,7 +2843,11 @@ BOOL dComIfGs_Wolf_Change_Check() { BOOL is_wolf = false; // Transforming Unlocked - if (dComIfGs_isEventBit(0x0D04)) { + if (dComIfGs_isEventBit(0x0D04) +#if TARGET_PC + || dusk::getSettings().game.transformWithoutShadowCrystal +#endif + ) { is_wolf = dComIfGs_getTransformStatus(); } else if (dComIfGs_isTransformLV(0) && !dComIfGs_isDarkClearLV(0)) { is_wolf = true; diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 3bea017e2c..cc8d54a517 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -123,6 +123,7 @@ UserSettings g_userSettings = { .fastSpinner {"game.fastSpinner", false}, .freeMagicArmor {"game.freeMagicArmor", false}, .invincibleEnemies {"game.invincibleEnemies", false}, + .transformWithoutShadowCrystal {"game.transformWithoutShadowCrystal", false}, // Technical .restoreWiiGlitches {"game.restoreWiiGlitches", false}, @@ -208,6 +209,7 @@ void registerSettings() { // Game Register(g_userSettings.game.language); Register(g_userSettings.game.enableQuickTransform); + Register(g_userSettings.game.transformWithoutShadowCrystal); Register(g_userSettings.game.hideTvSettingsScreen); Register(g_userSettings.game.biggerWallets); Register(g_userSettings.game.noReturnRupees); diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index a164de0089..42b0fa65e5 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -1288,6 +1288,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { "Lets the magic armor work without consuming rupees."); addCheat("Invincible Enemies", getSettings().game.invincibleEnemies, "Prevents enemies from taking damage."); + addCheat("Transform without Shadow Crystal", getSettings().game.transformWithoutShadowCrystal, + "Allows Link to transform without the Shadow Crystal (Only using Quick Transform.)"); }); add_tab("Interface", [this](Rml::Element* content) {