diff --git a/soh/soh/Enhancements/Cheats/EasyESS.cpp b/soh/soh/Enhancements/Cheats/EasyESS.cpp new file mode 100644 index 00000000000..9f338b9336c --- /dev/null +++ b/soh/soh/Enhancements/Cheats/EasyESS.cpp @@ -0,0 +1,43 @@ +#include +#include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include + +extern "C" { + extern PlayState* gPlayState; + #include "macros.h" +} + +#define CVAR_EASY_ESS_NAME CVAR_CHEAT("EasyESS") +#define CVAR_EASY_ESS_DEFAULT 0 +#define CVAR_EASY_ESS_VALUE CVarGetInteger(CVAR_EASY_ESS_NAME, CVAR_EASY_ESS_DEFAULT) + +void OnGameStateMainStartEasyESS() { + if (!GameInteractor::IsSaveLoaded(true)) { + return; + } + + Player* player = GET_PLAYER(gPlayState); + Input* input = &gPlayState->state.input[0]; + + if (player != nullptr && CHECK_BTN_ANY(input->cur.button, BTN_CUSTOM_MODIFIER1)) { + const int essValue = 18; + int x = input->cur.stick_x; + int y = input->cur.stick_y; + int magSq = x * x + y * y; + if (magSq > essValue * essValue) { + float mag = sqrtf(static_cast(magSq)); + input->cur.stick_x = static_cast((x / mag) * essValue); + input->cur.stick_y = static_cast((y / mag) * essValue); + input->rel.stick_x = input->cur.stick_x; + input->rel.stick_y = input->cur.stick_y; + } + } +} + +void RegisterEasyESS() { + COND_HOOK(OnGameStateMainStart, CVAR_EASY_ESS_VALUE, OnGameStateMainStartEasyESS); +} + +static RegisterShipInitFunc initFunc(RegisterEasyESS, { CVAR_EASY_ESS_NAME }); diff --git a/soh/soh/Enhancements/controls/InputViewer.cpp b/soh/soh/Enhancements/controls/InputViewer.cpp index c5855884131..19624620c2a 100644 --- a/soh/soh/Enhancements/controls/InputViewer.cpp +++ b/soh/soh/Enhancements/controls/InputViewer.cpp @@ -350,6 +350,18 @@ void InputViewer::DrawElement() { const bool analogStickIsInDeadzone = !pads[0].stick_x && !pads[0].stick_y; const bool rightStickIsInDeadzone = !pads[0].right_stick_x && !pads[0].right_stick_y; + const int essValue = 18; + int stickX = pads[0].stick_x; + int stickY = pads[0].stick_y; + if ((pads[0].button & BTN_CUSTOM_MODIFIER1) && CVarGetInteger(CVAR_CHEAT("EasyESS"), 0)) { + int magSq = stickX * stickX + stickY * stickY; + if (magSq > essValue * essValue) { + float mag = sqrtf(static_cast(magSq)); + stickX = static_cast((stickX / mag) * essValue); + stickY = static_cast((stickY / mag) * essValue); + } + } + // Analog Stick const int analogOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), STICK_MODE_ALWAYS_SHOWN); @@ -369,8 +381,8 @@ void InputViewer::DrawElement() { (analogStickMode == STICK_MODE_HIDDEN_IN_DEADZONE && !analogStickIsInDeadzone)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos( - ImVec2(aPos.x + maxStickDistance * ((float)(pads[0].stick_x) / MAX_AXIS_RANGE) * scale, - aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale)); + ImVec2(aPos.x + maxStickDistance * ((float)(stickX) / MAX_AXIS_RANGE) * scale, + aPos.y - maxStickDistance * ((float)(stickY) / MAX_AXIS_RANGE) * scale)); ImGui::Image( std::dynamic_pointer_cast(Ship::Context::GetRawInstance()->GetWindow()->GetGui()) ->GetTextureByName("Analog-Stick"), @@ -415,7 +427,7 @@ void InputViewer::DrawElement() { ImGui::PushFont(ImGui::GetFont()); // Calculate polar R coordinate from X and Y angles, squared to avoid sqrt - const int32_t rSquared = pads[0].stick_x * pads[0].stick_x + pads[0].stick_y * pads[0].stick_y; + const int32_t rSquared = stickX * stickX + stickY * stickY; // ESS range const int range1Min = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Min"), 8); @@ -442,7 +454,7 @@ void InputViewer::DrawElement() { } // Render text - ImGui::Text("X: %-3d Y: %-3d", pads[0].stick_x, pads[0].stick_y); + ImGui::Text("X: %-3d Y: %-3d", stickX, stickY); // Restore original color ImGui::PopStyleColor(); // Restore original font scale diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index c8c52897cc7..5fdf2b88877 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1816,6 +1816,9 @@ void SohMenu::AddMenuEnhancements() { AddWidget(path, "Easy QPA", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_CHEAT("EasyQPA")) .Options(CheckboxOptions().Tooltip("Gives you the glitched damage value of the quick put away glitch.")); + AddWidget(path, "Easy ESS", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_CHEAT("EasyESS")) + .Options(CheckboxOptions().Tooltip("Force ESS position while holding M1.")); AddWidget(path, "Clear Cutscene Pointer", WIDGET_BUTTON) .Callback([](WidgetInfo& info) { GameInteractor::RawAction::ClearCutscenePointer(); }) .Options(ButtonOptions()