diff --git a/cheat-base/src/cheat-base/cheat/misc/Settings.cpp b/cheat-base/src/cheat-base/cheat/misc/Settings.cpp index 371650d..fff9213 100644 --- a/cheat-base/src/cheat-base/cheat/misc/Settings.cpp +++ b/cheat-base/src/cheat-base/cheat/misc/Settings.cpp @@ -1,46 +1,98 @@ #include #include "Settings.h" -#include -#include #include +#include +#include +#include +#include -namespace cheat::feature +#include "shlwapi.h" +#pragma comment(lib, "shlwapi.lib") + +namespace cheat::feature { - Settings::Settings() : Feature(), + Settings::Settings() : Feature(), NF(f_MenuKey, "Show Cheat Menu Key", "General", Hotkey(VK_F1)), NF(f_HotkeysEnabled, "Hotkeys Enabled", "General", true), - NF(f_FontSize, "Font size", "General", 16.0f), - NF(f_ShowStyleEditor, "Show Style Editor", "General", false), - + NF(f_StatusMove, "Move Status Window", "General::StatusWindow", true), NF(f_StatusShow, "Show Status Window", "General::StatusWindow", true), - - NF(f_InfoMove, "Move Info Window", "General::InfoWindow", true), - NF(f_InfoShow, "Show Info Window", "General::InfoWindow", true), - + + NF(f_InfoMove, "Move Info Window", "General::InfoWindow", true), + NF(f_InfoShow, "Show Info Window", "General::InfoWindow", true), + NF(f_FpsMove, "Move FPS Indicator", "General::FPS", false), NF(f_FpsShow, "Show FPS Indicator", "General::FPS", true), - NF(f_NotificationsShow, "Show Notifications", "General::Notify", true), + NF(f_NotificationsShow, "Show Notifications", "General::Notify", true), NF(f_NotificationsDelay, "Notifications Delay", "General::Notify", 500), - - NF(f_FileLogging, "File Logging", "General::Logging", false), + + NF(f_FileLogging, "File Logging", "General::Logging", false), NF(f_ConsoleLogging, "Console Logging", "General::Logging", true), NF(f_FastExitEnable, "Fast Exit", "General::FastExit", false), - NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12)) + NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12)), - { + NF(f_FontSize, "Font Size", "General", 16.0f), + NF(f_ShowStyleEditor, "Show Colors Customization", "General", false), + NFS(f_DefaultTheme, "Theme", "General::Colors", "Default"), + themesDir(util::GetCurrentPath() / "themes") + + { renderer::SetGlobalFontSize(static_cast(f_FontSize)); f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed); - } + if (!std::filesystem::exists(themesDir)) + std::filesystem::create_directory(themesDir); - const FeatureGUIInfo& Settings::GetGUIInfo() const - { - static const FeatureGUIInfo info{ "", "Settings", false }; - return info; - } + } + + bool inited = false; + void Settings::Init() { + if (this->f_DefaultTheme.value() != "Default" && !inited) + { + LOG_INFO("Loading theme: %s", themesDir / (f_DefaultTheme.value() + ".json").c_str()); + if (!std::filesystem::exists(themesDir / (f_DefaultTheme.value() + ".json"))) + f_DefaultTheme = "Default"; + else Colors_Import(f_DefaultTheme.value()); + inited = true; + } + } + + const FeatureGUIInfo& Settings::GetGUIInfo() const + { + static const FeatureGUIInfo info{ "", "Settings", false }; + return info; + } + + void Settings::Colors_Export(std::string name) + { + ImGuiStyle& style = ImGui::GetStyle(); + auto colors = style.Colors; + + nlohmann::json json; + for (int i = 0; i < ImGuiCol_COUNT; i++) + json[ImGui::GetStyleColorName((ImGuiCol)i)] = { colors[i].x, colors[i].y, colors[i].z, colors[i].w }; + std::ofstream file(themesDir / (name + ".json")); + file << std::setw(4) << json << std::endl; + } + + void Settings::Colors_Import(std::string name) + { + ImGuiStyle& style = ImGui::GetStyle(); + auto colors = style.Colors; + nlohmann::json json; + std::ifstream file(themesDir / (name + ".json")); + file >> json; + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + auto color = json[ImGui::GetStyleColorName((ImGuiCol)i)]; + colors[i].x = color[0]; + colors[i].y = color[1]; + colors[i].z = color[2]; + colors[i].w = color[3]; + } + } void Settings::DrawMain() { @@ -51,13 +103,7 @@ namespace cheat::feature "Key to toggle main menu visibility. Cannot be empty.\n"\ "If you forget this key, you can see or set it in your config file."); ConfigWidget(f_HotkeysEnabled, "Enable hotkeys."); - if (ConfigWidget(f_FontSize, 1, 8, 64, "Font size for cheat interface.")) - { - f_FontSize = std::clamp(f_FontSize.value(), 8, 64); - renderer::SetGlobalFontSize(static_cast(f_FontSize)); - } - ConfigWidget(f_ShowStyleEditor, "Show interface style editor window."); - } + } ImGui::EndGroupPanel(); ImGui::BeginGroupPanel("Logging"); @@ -103,7 +149,7 @@ namespace cheat::feature ImGui::BeginGroupPanel("Show Notifications"); { ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed."); - ConfigWidget(f_NotificationsDelay, 1,1,10000, "Delay in milliseconds between notifications."); + ConfigWidget(f_NotificationsDelay, 1, 1, 10000, "Delay in milliseconds between notifications."); } ImGui::EndGroupPanel(); @@ -111,7 +157,7 @@ namespace cheat::feature { ConfigWidget("Enabled", f_FastExitEnable, - "Enable Fast Exit.\n" + "Enable Fast Exit.\n" ); if (!f_FastExitEnable) ImGui::BeginDisabled(); @@ -123,13 +169,54 @@ namespace cheat::feature ImGui::EndDisabled(); } ImGui::EndGroupPanel(); + + ImGui::BeginGroupPanel("Interface Customization"); + { + if (ConfigWidget(f_FontSize, 1, 8, 64, "Adjust interface font size.")) + { + f_FontSize = std::clamp(f_FontSize.value(), 8, 64); + renderer::SetGlobalFontSize(static_cast(f_FontSize)); + } + ImGui::Spacing(); + + ConfigWidget(f_ShowStyleEditor, "Show colors customization window."); + ImGui::Spacing(); + + ImGui::Text("Save Customized Color"); + static std::string nameBuffer_; + ImGui::InputText("Color Name", &nameBuffer_); + if (ImGui::Button("Save")) + Colors_Export(nameBuffer_); + ImGui::SameLine(); + + if (std::filesystem::exists(themesDir / (nameBuffer_ + ".json"))) + { + if (this->f_DefaultTheme.value() != nameBuffer_) + { + if (ImGui::Button("Set as default")) + { + f_DefaultTheme = nameBuffer_; + } + ImGui::SameLine(); + if (ImGui::Button("Load")) + { + Colors_Import(nameBuffer_); + } + } + } + else + { + ImGui::Text("Color does not exist."); + } + } + ImGui::EndGroupPanel(); } - Settings& Settings::GetInstance() - { - static Settings instance; - return instance; - } + Settings& Settings::GetInstance() + { + static Settings instance; + return instance; + } void Settings::OnExitKeyPressed() { @@ -139,4 +226,3 @@ namespace cheat::feature ExitProcess(0); } } - diff --git a/cheat-base/src/cheat-base/cheat/misc/Settings.h b/cheat-base/src/cheat-base/cheat/misc/Settings.h index 710866b..7605b43 100644 --- a/cheat-base/src/cheat-base/cheat/misc/Settings.h +++ b/cheat-base/src/cheat-base/cheat/misc/Settings.h @@ -2,26 +2,24 @@ #include #include -namespace cheat::feature +namespace cheat::feature { class Settings : public Feature - { + { public: config::Field f_MenuKey; config::Field f_HotkeysEnabled; - config::Field f_FontSize; - config::Field f_ShowStyleEditor; config::Field f_StatusMove; config::Field f_StatusShow; config::Field f_InfoMove; config::Field f_InfoShow; - + config::Field f_FpsShow; config::Field f_FpsMove; - + config::Field f_NotificationsShow; config::Field f_NotificationsDelay; @@ -31,11 +29,20 @@ namespace cheat::feature config::Field f_FastExitEnable; config::Field f_HotkeyExit; + config::Field f_FontSize; + config::Field f_ShowStyleEditor; + std::filesystem::path themesDir; + config::Field f_DefaultTheme; + + static Settings& GetInstance(); const FeatureGUIInfo& GetGUIInfo() const override; void DrawMain() override; - + void Init(); + void Colors_Export(std::string name); + void Colors_Import(std::string name); + private: void OnExitKeyPressed(); diff --git a/cheat-base/src/cheat-base/render/renderer.cpp b/cheat-base/src/cheat-base/render/renderer.cpp index 4246b06..4242c65 100644 --- a/cheat-base/src/cheat-base/render/renderer.cpp +++ b/cheat-base/src/cheat-base/render/renderer.cpp @@ -12,6 +12,7 @@ #include #include +#include extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); @@ -33,14 +34,14 @@ namespace renderer static constexpr int _fontsCount = _fontSizeMax / _fontSizeStep; static std::array _fonts; - static Data _customFontData {}; + static Data _customFontData{}; static WNDPROC OriginalWndProcHandler; static ID3D11RenderTargetView* mainRenderTargetView; static void OnRenderDX11(ID3D11DeviceContext* pContext); static void OnInitializeDX11(HWND window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain* pChain); - + static void OnPreRenderDX12(); static void OnPostRenderDX12(ID3D12GraphicsCommandList* commandList); static void OnInitializeDX12(HWND window, ID3D12Device* pDevice, UINT buffersCounts, ID3D12DescriptorHeap* pDescriptorHeapImGuiRender); @@ -106,7 +107,7 @@ namespace renderer return io.FontDefault; } int fontSizeInt = static_cast(fontSize); - int fontIndex = fontSizeInt / _fontSizeStep + + int fontIndex = fontSizeInt / _fontSizeStep + (fontSizeInt % _fontSizeStep > (_fontSizeStep / 2) ? 1 : 0) - 1; fontIndex = std::clamp(fontIndex, 0, _fontsCount - 1); return _fonts[fontIndex]; @@ -122,7 +123,7 @@ namespace renderer int fontSizeInt = static_cast(fontSize); int fontIndex = fontSizeInt / _fontSizeStep; - int fontAligned = fontIndex * _fontSizeStep + + int fontAligned = fontIndex * _fontSizeStep + ((fontSizeInt % _fontSizeStep) > _fontSizeStep / 2 ? _fontSizeStep : 0); fontAligned = std::clamp(fontAligned, _fontSizeStep, _fontSizeMax); @@ -138,7 +139,7 @@ namespace renderer { return _globalFontSize; } - + static void LoadCustomFont() { if (_customFontData.data == nullptr) @@ -195,7 +196,7 @@ namespace renderer reinterpret_cast(hWndProc))); ImGui_ImplWin32_Init(window); - ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM, + ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM, pDescriptorHeapImGuiRender, pDescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(), pDescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart()); @@ -253,6 +254,9 @@ namespace renderer pContext->OMSetRenderTargets(1, &mainRenderTargetView, nullptr); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + auto& themes = cheat::feature::Settings::GetInstance(); + themes.Init(); } static LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) diff --git a/cheat-library/cheat-library.vcxproj b/cheat-library/cheat-library.vcxproj index af6ba65..12cc502 100644 --- a/cheat-library/cheat-library.vcxproj +++ b/cheat-library/cheat-library.vcxproj @@ -21,6 +21,7 @@ + @@ -113,6 +114,7 @@ + @@ -219,6 +221,7 @@ + @@ -557,6 +560,7 @@ + @@ -1010,7 +1014,7 @@ true Use pch-il2cpp.h - stdcpp17 + stdcpp20 $(ProjectDir)src/appdata;$(ProjectDir)src/framework;$(ProjectDir)res/;$(ProjectDir)src/user;$(SolutionDir)cheat-base/src/;$(SolutionDir)cheat-base/vendor/imgui/;$(SolutionDir)cheat-base/vendor/json/single_include/;$(SolutionDir)cheat-base/vendor/magic_enum/include/;$(SolutionDir)cheat-base/vendor/fmt/include/;$(SolutionDir)cheat-base/vendor/imgui-notify-v2/;$(SolutionDir)cheat-base/vendor/simpleIni/;$(SolutionDir)cheat-base/vendor/imgui-notify-v2/;$(SolutionDir)cheat-base/vendor/detours/ MaxSpeed true diff --git a/cheat-library/cheat-library.vcxproj.filters b/cheat-library/cheat-library.vcxproj.filters index 7392f94..c949b36 100644 --- a/cheat-library/cheat-library.vcxproj.filters +++ b/cheat-library/cheat-library.vcxproj.filters @@ -252,6 +252,9 @@ Header Files + + Header Files + @@ -462,6 +465,9 @@ Source Files + + Source Files + @@ -2508,5 +2514,11 @@ Resource Files + + Resource Files + + + Resource Files + \ No newline at end of file diff --git a/cheat-library/res/icons/BookPage.png b/cheat-library/res/icons/BookPage.png new file mode 100644 index 0000000..c504ebe Binary files /dev/null and b/cheat-library/res/icons/BookPage.png differ diff --git a/cheat-library/res/iconsHD/BookPage.png b/cheat-library/res/iconsHD/BookPage.png new file mode 100644 index 0000000..d13b14f Binary files /dev/null and b/cheat-library/res/iconsHD/BookPage.png differ diff --git a/cheat-library/res/res.rc b/cheat-library/res/res.rc index 3b9e066..923ed0e 100644 --- a/cheat-library/res/res.rc +++ b/cheat-library/res/res.rc @@ -25,21 +25,21 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN - "resource.h\0" +"resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN - "#include ""winres.h""\r\n" - "\0" +"#include ""winres.h""\r\n" +"\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN - "\r\n" - "\0" +"\r\n" +"\0" END #endif // APSTUDIO_INVOKED @@ -140,6 +140,8 @@ HDBOAR PNG "iconsHD\\Boar.png" HDBOOK PNG "iconsHD\\Book.png" +HDBOOKPAGE PNG "iconsHD\\BookPage.png" + HDBOOTWEASEL PNG "iconsHD\\BootWeasel.png" HDBRIGHTCROWNPIGEON PNG "iconsHD\\BrightcrownPigeon.png" @@ -316,6 +318,8 @@ HDGEOGRANUM PNG "iconsHD\\Geogranum.png" HDGEOHYPOSTASIS PNG "iconsHD\\GeoHypostasis.png" +HDGEOPUZZLE PNG "iconsHD\\MiniPuzzle.png" + HDGEOSIGIL PNG "iconsHD\\GeoSigil.png" HDGEOVISHAP PNG "iconsHD\\Geovishap.png" @@ -626,7 +630,7 @@ HDSHOGUN PNG "iconsHD\\Shogun.png" HDSHOGUNATEINFANTRY PNG "iconsHD\\ShogunateInfantry.png" -HDSHRINEOFDEPTH PNG "iconsHD\\ShrineOfDepth.png" +HDSHRINEOFDEPTH PNG "iconsHD\\Mondstadt.png" HDSIGNORA PNG "iconsHD\\Signora.png" @@ -850,6 +854,8 @@ BOAR PNG "icons\\Boar.png" BOOK PNG "icons\\Book.png" +BOOKPAGE PNG "icons\\BookPage.png" + BOOTWEASEL PNG "icons\\BootWeasel.png" BRIGHTCROWNPIGEON PNG "icons\\BrightcrownPigeon.png" @@ -1026,6 +1032,8 @@ GEOGRANUM PNG "icons\\Geogranum.png" GEOHYPOSTASIS PNG "icons\\GeoHypostasis.png" +GEOPUZZLE PNG "icons\\MiniPuzzle.png" + GEOSIGIL PNG "icons\\GeoSigil.png" GEOVISHAP PNG "icons\\Geovishap.png" diff --git a/cheat-library/src/user/cheat/cheat.cpp b/cheat-library/src/user/cheat/cheat.cpp index 5093d7f..1dbdcae 100644 --- a/cheat-library/src/user/cheat/cheat.cpp +++ b/cheat-library/src/user/cheat/cheat.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include "GenshinCM.h" @@ -122,7 +123,8 @@ namespace cheat FEAT_INST(Browser), FEAT_INST(EnablePeeking), FEAT_INST(TextureChanger), - FEAT_INST(FreeCamera) + FEAT_INST(FreeCamera), + FEAT_INST(AnimationChanger) }); #undef FEAT_INST diff --git a/cheat-library/src/user/cheat/esp/ESP.cpp b/cheat-library/src/user/cheat/esp/ESP.cpp index 98a8d30..43d5d0b 100644 --- a/cheat-library/src/user/cheat/esp/ESP.cpp +++ b/cheat-library/src/user/cheat/esp/ESP.cpp @@ -21,17 +21,17 @@ namespace cheat::feature ESP::ESP() : Feature(), NF(f_Enabled, "ESP", "ESP", false), - NF(f_DrawBoxMode, "Draw Mode", "ESP", DrawMode::Box), + NF(f_DrawBoxMode, "Draw Mode", "ESP", DrawMode::Box), NF(f_DrawTracerMode, "Tracer Mode", "ESP", DrawTracerMode::Line), - NF(f_Fill, "Fill Box/Rectangle/Arrows", "ESP", false), - NF(f_FillTransparency, "Fill Transparency", "ESP", 0.5f), + NF(f_Fill, "Fill Box/Rectangle/Arrows", "ESP", false), + NF(f_FillTransparency, "Fill Transparency", "ESP", 0.5f), NF(f_ArrowRadius, "Arrow Radius", "ESP", 100.0f), NF(f_OutlineThickness, "Outline Thickness", "ESP", 1.0f), NF(f_TracerSize, "Tracer Size", "ESP", 1.0f), NF(f_MiddleScreenTracer, "Middle Screen Tracer", "ESP", false), - NF(f_DrawDistance, "Draw Distance", "ESP", false), - NF(f_DrawName, "Draw Name", "ESP", false), + NF(f_DrawDistance, "Draw Distance", "ESP", false), + NF(f_DrawName, "Draw Name", "ESP", false), NF(f_FontSize, "Font Size", "ESP", 12.0f), NF(f_FontOutline, "Font outline", "ESP", true), @@ -69,7 +69,7 @@ namespace cheat::feature ConfigWidget(f_DrawBoxMode, "Select the mode of box drawing."); ConfigWidget(f_DrawTracerMode, "Select the mode of tracer drawing."); - + ConfigWidget(f_Fill); ConfigWidget(f_FillTransparency, 0.01f, 0.0f, 1.0f, "Transparency of filled part."); ConfigWidget(f_MiddleScreenTracer, "Draw tracer from middle part of the screen."); @@ -84,7 +84,7 @@ namespace cheat::feature } ImGui::EndGroupPanel(); } - + ImGui::Spacing(); ConfigWidget(f_DrawName, "Draw name of object."); ConfigWidget(f_DrawDistance, "Draw distance of object."); @@ -189,55 +189,55 @@ namespace cheat::feature //switch statement to determine how we will get name switch (count) { - case 3: + case 3: + { + j = 0; // j is the number of spaces before the name starts + pos1 = 0; + pos2 = 0; + for (int i = 0; i < name.length(); i++) { - j = 0; // j is the number of spaces before the name starts - pos1 = 0; - pos2 = 0; - for (int i = 0; i < name.length(); i++) + if (name[i] == '_') { - if (name[i] == '_') + j++; + if (j == 3) { - j++; - if (j == 3) - { - pos1 = i; - } - + pos1 = i; } - if (name[i] == '(') + + } + if (name[i] == '(') + { + pos2 = i; + break; + } + } + name = name.substr(pos1, pos2 - pos1); + } + case 4: + { + j = 0; // j is the number of spaces before the name starts + pos1 = 0; + pos2 = 0; + for (int i = 0; i < name.length(); i++) + { + if (name[i] == '_') + { + j++; + if (j == 3) + { + pos1 = i; + } + if (j == 4) { pos2 = i; break; } } - name = name.substr(pos1, pos2 - pos1); } - case 4: - { - j = 0; // j is the number of spaces before the name starts - pos1 = 0; - pos2 = 0; - for (int i = 0; i < name.length(); i++) - { - if (name[i] == '_') - { - j++; - if (j == 3) - { - pos1 = i; - } - if (j == 4) - { - pos2 = i; - break; - } - } - } - name = name.substr(pos1 + 1, pos2 - pos1 - 1); - } - default: - break; + name = name.substr(pos1 + 1, pos2 - pos1 - 1); + } + default: + break; } return; } @@ -574,12 +574,16 @@ namespace cheat::feature ADD_FILTER_FIELD(collection, WoodenCrate); ADD_FILTER_FIELD(collection, GeoSigil); + // Regular Chests ADD_FILTER_FIELD(chest, CommonChest); ADD_FILTER_FIELD(chest, ExquisiteChest); ADD_FILTER_FIELD(chest, PreciousChest); ADD_FILTER_FIELD(chest, LuxuriousChest); ADD_FILTER_FIELD(chest, RemarkableChest); + // Other Chests + ADD_FILTER_FIELD(chest, BuriedChest); ADD_FILTER_FIELD(chest, SearchPoint); + ADD_FILTER_FIELD(featured, Anemoculus); ADD_FILTER_FIELD(featured, CrimsonAgate); diff --git a/cheat-library/src/user/cheat/game/filters.cpp b/cheat-library/src/user/cheat/game/filters.cpp index 0827961..3c23e4f 100644 --- a/cheat-library/src/user/cheat/game/filters.cpp +++ b/cheat-library/src/user/cheat/game/filters.cpp @@ -32,6 +32,7 @@ namespace cheat::game::filters ChestFilter SFrozen = ChestFilter(Chest::ChestState::Frozen); ChestFilter SBramble = ChestFilter(Chest::ChestState::Bramble); ChestFilter STrap = ChestFilter(Chest::ChestState::Trap); + SimpleFilter BuriedChest = { EntityType__Enum_1::Field, "_WorldArea_Operator" }; } namespace equipment @@ -111,7 +112,7 @@ namespace cheat::game::filters SimpleFilter WeaselThief = { EntityType__Enum_1::Monster, "Thoarder_Weasel" }; SimpleFilter Kitsune = { EntityType__Enum_1::EnvAnimal, "Vulpes" }; SimpleFilter BakeDanuki = { EntityType__Enum_1::Monster, "Inu_Tanuki" }; - SimpleFilter Meat = { EntityType__Enum_1::GatherObject , { "_Food_BirdMeat", "_Food_Meat", "_Fishmeat" }}; + SimpleFilter Meat = { EntityType__Enum_1::GatherObject , { "_Food_BirdMeat", "_Food_Meat", "_Fishmeat" } }; } namespace mineral @@ -131,7 +132,7 @@ namespace cheat::game::filters SimpleFilter DunlinsTooth = { EntityType__Enum_1::GatherObject, "_DunlinsTooth" }; SimpleFilter AmethystLumpDrop = { EntityType__Enum_1::GatherObject, "_Thundercrystaldrop" }; - SimpleFilter CrystalChunkDrop = { EntityType__Enum_1::GatherObject,"_Drop_Crystal"}; + SimpleFilter CrystalChunkDrop = { EntityType__Enum_1::GatherObject,"_Drop_Crystal" }; SimpleFilter ElectroCrystalDrop = { EntityType__Enum_1::GatherObject, "_Drop_Ore_ElectricRock" }; SimpleFilter IronChunkDrop = { EntityType__Enum_1::GatherObject, "_Drop_Stone" }; SimpleFilter NoctilucousJadeDrop = { EntityType__Enum_1::GatherObject,"_NightBerth" }; @@ -161,7 +162,7 @@ namespace cheat::game::filters SimpleFilter RuinGrader = { EntityType__Enum_1::Monster, "_Konungmathr" }; SimpleFilter RuinSentinel = { EntityType__Enum_1::Monster, "_Apparatus_Enigma" }; SimpleFilter Samachurl = { EntityType__Enum_1::Monster, "_Shaman" }; - SimpleFilter ShadowyHusk = { EntityType__Enum_1::Monster, "ForlornVessel_Strong" }; + SimpleFilter ShadowyHusk = { EntityType__Enum_1::Monster, "ForlornVessel_Strong" }; SimpleFilter Slime = { EntityType__Enum_1::Monster, "_Slime" }; SimpleFilter FloatingFungus = { EntityType__Enum_1::Monster, "Fungus_Un_" }; SimpleFilter StretchyFungus = { EntityType__Enum_1::Monster, "Fungus_Deux_" }; @@ -221,7 +222,7 @@ namespace cheat::game::filters SimpleFilter JadeplumeTerrorshroom = { EntityType__Enum_1::Monster, "Fungus_Raptor" }; SimpleFilter RishbolandTiger = { EntityType__Enum_1::Monster, "_Megamoth_" }; SimpleFilter ShaggySumpterBeast = { EntityType__Enum_1::Monster, "_Panther" }; - SimpleFilter Spincrocodile = { EntityType__Enum_1::Monster, "_Gator" }; + SimpleFilter Spincrocodile = { EntityType__Enum_1::Monster, "_Gator" }; SimpleFilter SentryTurrets = { EntityType__Enum_1::Field, "SentryTurrets_" }; } @@ -285,7 +286,7 @@ namespace cheat::game::filters SimpleFilter AncientRime = { EntityType__Enum_1::Gadget, "_IceSolidBulk" }; SimpleFilter BakeDanuki = { EntityType__Enum_1::Monster, "Animal_Inu_Tanuki_" }; SimpleFilter BloattyFloatty = { EntityType__Enum_1::Field, "_Flower_PongPongTree_" }; - WhitelistFilter CubeDevices = { {EntityType__Enum_1::Gadget, EntityType__Enum_1::Platform }, {"_ElecStone", "_ElecSwitch" }}; + WhitelistFilter CubeDevices = { {EntityType__Enum_1::Gadget, EntityType__Enum_1::Platform }, {"_ElecStone", "_ElecSwitch" } }; SimpleFilter EightStoneTablets = { EntityType__Enum_1::Gadget, "_HistoryBoard" }; SimpleFilter ElectricConduction = { EntityType__Enum_1::Gear, "_ElectricPowerSource" }; SimpleFilter RelayStone = { EntityType__Enum_1::Worktop, "_ElectricTransfer_" }; @@ -346,6 +347,13 @@ namespace cheat::game::filters mineral::Starsilver, mineral::WhiteIronChunk }; + SimpleFilter PlantDestroy = { + //plant::SakuraBloom, + plant::DandelionSeed, + plant::MistFlowerCorolla, + plant::FlamingFlowerStamen + }; + WhitelistFilter Doodads = { EntityType__Enum_1::Gadget, { @@ -518,15 +526,15 @@ namespace cheat::game::filters monster::Whopperflower }; SimpleFilter MonsterEquips = { EntityType__Enum_1::MonsterEquip }; - BlacklistFilter Living = { - {EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster}, - { - // Environmental mobs - "Cat", "DogPrick", "Vulpues", "Inu_Tanuki", - // Overworld bosses - "Ningyo", "Regisvine", "Hypostasis", "Planelurker", "Nithhoggr" - } - }; + BlacklistFilter Living = { + {EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster}, + { + // Environmental mobs + "Cat", "DogPrick", "Vulpues", "Inu_Tanuki", + // Overworld bosses + "Ningyo", "Regisvine", "Hypostasis", "Planelurker", "Nithhoggr" + } + }; SimpleFilter OrganicTargets = { Monsters, Animals }; // Solael: Please don't mess around with this filter. //m0nkrel: We can choose the entities we need ourselves so as not to magnetize cats, dogs, etc. //AdvancedFilter Animals = { {EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster }, {"Crane", "Tit", "Boar", "Squirrel", "Fox", "Pigeon", "Wigeon", "Falcon" ,"Marten" } }; diff --git a/cheat-library/src/user/cheat/game/filters.h b/cheat-library/src/user/cheat/game/filters.h index 8a9f2a2..2edd84f 100644 --- a/cheat-library/src/user/cheat/game/filters.h +++ b/cheat-library/src/user/cheat/game/filters.h @@ -32,6 +32,8 @@ namespace cheat::game::filters extern ChestFilter SFrozen; extern ChestFilter SBramble; extern ChestFilter STrap; + + extern SimpleFilter BuriedChest; } namespace equipment @@ -220,7 +222,7 @@ namespace cheat::game::filters extern SimpleFilter Beisht; extern SimpleFilter RishbolandTiger; extern SimpleFilter ShaggySumpterBeast; - extern SimpleFilter Spincrocodile; + extern SimpleFilter Spincrocodile; extern SimpleFilter SentryTurrets; } @@ -325,6 +327,7 @@ namespace cheat::game::filters extern SimpleFilter Oculies; extern SimpleFilter Chests; extern SimpleFilter Ores; + extern SimpleFilter PlantDestroy; extern WhitelistFilter Doodads; extern SimpleFilter Animals; extern SimpleFilter AnimalDrop; diff --git a/cheat-library/src/user/cheat/imap/InteractiveMap.cpp b/cheat-library/src/user/cheat/imap/InteractiveMap.cpp index e338c8f..0c6a973 100644 --- a/cheat-library/src/user/cheat/imap/InteractiveMap.cpp +++ b/cheat-library/src/user/cheat/imap/InteractiveMap.cpp @@ -563,13 +563,13 @@ namespace cheat::feature std::lock_guard _userDataLock(m_UserDataMutex); LOG_WARNING("Complete point at %.0f.", game::EntityManager::instance().avatar()->distance(pointData->levelPosition)); - if (m_CompletedPoints.count(pointData) > 0) + if (std::find_if(m_CompletedPoints.begin(), m_CompletedPoints.end(), [=](PointData* data) { return pointData->id == data->id; }) != std::end(m_CompletedPoints)) return; pointData->completed = true; pointData->completeTimestamp = util::GetCurrentTimeMillisec(); m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount++; - m_CompletedPoints.insert(pointData); + m_CompletedPoints.push_back(pointData); SaveCompletedPoints(); } @@ -578,13 +578,14 @@ namespace cheat::feature { std::lock_guard _userDataLock(m_UserDataMutex); - if (m_CompletedPoints.count(pointData) == 0) + auto pointDataIterator = std::find_if(m_CompletedPoints.begin(), m_CompletedPoints.end(), [=](PointData* data) { return pointData->id == data->id; }); + if (pointDataIterator == m_CompletedPoints.end()) return; pointData->completed = false; pointData->completeTimestamp = 0; m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--; - m_CompletedPoints.erase(pointData); + m_CompletedPoints.erase(pointDataIterator); SaveCompletedPoints(); } @@ -595,11 +596,12 @@ namespace cheat::feature if (m_CompletedPoints.empty()) return; - PointData* pointData = *m_CompletedPoints.begin(); + auto pointDataIterator = --m_CompletedPoints.end(); + PointData* pointData = *pointDataIterator; pointData->completed = false; pointData->completeTimestamp = 0; m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--; - m_CompletedPoints.erase(pointData); + m_CompletedPoints.erase(pointDataIterator); SaveCompletedPoints(); } @@ -916,7 +918,7 @@ namespace cheat::feature } auto& point = points[pointID]; - if (m_CompletedPoints.count(&point) > 0) + if (std::find_if(m_CompletedPoints.begin(), m_CompletedPoints.end(), [=](PointData* data) { return point.id == data->id; }) != std::end(m_CompletedPoints)) { LOG_WARNING("Completed point %u duplicate.", pointID); return; @@ -926,7 +928,7 @@ namespace cheat::feature point.completeTimestamp = data["complete_timestamp"]; labelData->completedCount++; - m_CompletedPoints.insert(&point); + m_CompletedPoints.push_back(&point); } void InteractiveMap::LoadFixedPointData(LabelData* labelData, const nlohmann::json& data) @@ -1026,6 +1028,7 @@ namespace cheat::feature void InteractiveMap::LoadCompletedPoints() { LoadUserData(f_CompletedPointsJson, &InteractiveMap::LoadCompletedPointData); + ReorderCompletedPointDataByTimestamp(); } void InteractiveMap::SaveCompletedPoints() @@ -1040,6 +1043,11 @@ namespace cheat::feature m_CompletedPoints.clear(); } + void InteractiveMap::ReorderCompletedPointDataByTimestamp() + { + m_CompletedPoints.sort([](PointData* a, PointData* b) { return a->completeTimestamp < b->completeTimestamp; }); + } + void InteractiveMap::LoadCustomPoints() { LoadUserData(f_CustomPointsJson, &InteractiveMap::LoadCustomPointData); diff --git a/cheat-library/src/user/cheat/imap/InteractiveMap.h b/cheat-library/src/user/cheat/imap/InteractiveMap.h index 51b2f44..47b7cfa 100644 --- a/cheat-library/src/user/cheat/imap/InteractiveMap.h +++ b/cheat-library/src/user/cheat/imap/InteractiveMap.h @@ -146,7 +146,7 @@ namespace cheat::feature std::unordered_set m_CustomPoints; std::unordered_set m_FixedPoints; - std::unordered_set m_CompletedPoints; + std::list m_CompletedPoints; std::mutex m_PointMutex; // PointData* m_SelectedPoint; @@ -182,6 +182,7 @@ namespace cheat::feature void LoadCompletedPointData(LabelData* labelData, const nlohmann::json& data); void SaveCompletedPointData(nlohmann::json& jObject, PointData* point); bool ResetCompletedPointData(LabelData* label, PointData* point); + void ReorderCompletedPointDataByTimestamp(); void LoadCustomPointData(LabelData* labelData, const nlohmann::json& data); void SaveCustomPointData(nlohmann::json& jObject, PointData* point); diff --git a/cheat-library/src/user/cheat/misc/Debug.cpp b/cheat-library/src/user/cheat/misc/Debug.cpp index 0699dc3..e30396c 100644 --- a/cheat-library/src/user/cheat/misc/Debug.cpp +++ b/cheat-library/src/user/cheat/misc/Debug.cpp @@ -203,7 +203,8 @@ namespace cheat::feature for (auto entity : entities) { auto entityPos = entity->absolutePosition(); std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}"; - auto entityDetails = fmt::format(baseString, + auto entityDetails = fmt::format( + fmt::runtime(baseString), fmt::ptr(entity), entity->runtimeID(), entity->name().c_str(), @@ -222,7 +223,8 @@ namespace cheat::feature std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}"; if (csvFriendly && includeHeaders) baseString = headerString.append(baseString); - auto entityDetails = fmt::format(baseString, + auto entityDetails = fmt::format( + fmt::runtime(baseString), fmt::ptr(entity), entity->runtimeID(), entity->name().c_str(), diff --git a/cheat-library/src/user/cheat/player/RapidFire.cpp b/cheat-library/src/user/cheat/player/RapidFire.cpp index bcad5ee..f4bf3a2 100644 --- a/cheat-library/src/user/cheat/player/RapidFire.cpp +++ b/cheat-library/src/user/cheat/player/RapidFire.cpp @@ -6,41 +6,46 @@ #include #include -namespace cheat::feature +namespace cheat::feature { static void LCBaseCombat_DoHitEntity_Hook(app::LCBaseCombat* __this, uint32_t targetID, app::AttackResult* attackResult, bool ignoreCheckCanBeHitInMP, MethodInfo* method); + static void VCAnimatorEvent_HandleProcessItem_Hook(app::MoleMole_VCAnimatorEvent* __this, + app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem* processItem, + app::AnimatorStateInfo processStateInfo, app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method); - RapidFire::RapidFire() : Feature(), - NF(f_Enabled, "Attack Multiplier", "RapidFire", false), - NF(f_MultiHit, "Multi-hit", "RapidFire", false), - NF(f_Multiplier, "Hit Multiplier", "RapidFire", 2), - NF(f_OnePunch, "One Punch Mode", "RapidFire", false), - NF(f_Randomize, "Randomize", "RapidFire", false), - NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1), - NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3), - NF(f_MultiTarget, "Multi-target", "RapidFire", false), - NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f) - { + RapidFire::RapidFire() : Feature(), + NF(f_Enabled, "Attack Multiplier", "RapidFire", false), + NF(f_MultiHit, "Multi-hit", "RapidFire", false), + NF(f_Multiplier, "Hit Multiplier", "RapidFire", 2), + NF(f_OnePunch, "One Punch Mode", "RapidFire", false), + NF(f_Randomize, "Randomize", "RapidFire", false), + NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1), + NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3), + NF(f_MultiTarget, "Multi-target", "RapidFire", false), + NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f), + NF(f_MultiAnimation, "Multi-animation", "RapidFire", false) + { HookManager::install(app::MoleMole_LCBaseCombat_DoHitEntity, LCBaseCombat_DoHitEntity_Hook); - } + HookManager::install(app::MoleMole_VCAnimatorEvent_HandleProcessItem, VCAnimatorEvent_HandleProcessItem_Hook); + } - const FeatureGUIInfo& RapidFire::GetGUIInfo() const - { - static const FeatureGUIInfo info{ "Attack Effects", "Player", true }; - return info; - } + const FeatureGUIInfo& RapidFire::GetGUIInfo() const + { + static const FeatureGUIInfo info{ "Attack Effects", "Player", true }; + return info; + } - void RapidFire::DrawMain() - { + void RapidFire::DrawMain() + { ConfigWidget("Enabled", f_Enabled, "Enables attack multipliers. Need to choose a mode to work."); ImGui::SameLine(); ImGui::TextColored(ImColor(255, 165, 0, 255), "Choose any or both modes below."); ConfigWidget("Multi-hit Mode", f_MultiHit, "Enables multi-hit.\n" \ - "Multiplies your attack count.\n" \ - "This is not well tested, and can be detected by anticheat.\n" \ - "Not recommended to be used with main accounts or used with high values.\n" \ + "Multiplies your attack count.\n" \ + "This is not well tested, and can be detected by anticheat.\n" \ + "Not recommended to be used with main accounts or used with high values.\n" \ "Known issues with certain multi-hit attacks, e.g. Xiao E, Ayaka CA, etc."); ImGui::Indent(); @@ -73,20 +78,23 @@ namespace cheat::feature "If multi-hit is off and there are still multiple numbers on a single target, check the Entity Manager in the Debug section to see if there are invisible entities.\n" \ "This can cause EXTREME lag and quick bans if used with multi-hit. You are warned." ); - + ImGui::Indent(); ConfigWidget("Radius (m)", f_MultiTargetRadius, 0.1f, 5.0f, 50.0f, "Radius to check for valid targets."); ImGui::Unindent(); - } - bool RapidFire::NeedStatusDraw() const -{ - return f_Enabled && (f_MultiHit || f_MultiTarget); - } + ConfigWidget("Multi-animation", f_MultiAnimation, "Enables multi-animation attacks.\n" \ + "Do keep in mind that the character's audio will also be spammed."); + } - void RapidFire::DrawStatus() - { - if (f_MultiHit) + bool RapidFire::NeedStatusDraw() const + { + return f_Enabled && (f_MultiHit || f_MultiTarget || f_MultiAnimation); + } + + void RapidFire::DrawStatus() + { + if (f_MultiHit) { if (f_Randomize) ImGui::Text("Multi-Hit Random[%d|%d]", f_minMultiplier.value(), f_maxMultiplier.value()); @@ -97,20 +105,23 @@ namespace cheat::feature } if (f_MultiTarget) ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value()); - } - RapidFire& RapidFire::GetInstance() - { - static RapidFire instance; - return instance; - } + if (f_MultiAnimation) + ImGui::Text("Multi-Animation"); + } + + RapidFire& RapidFire::GetInstance() + { + static RapidFire instance; + return instance; + } int RapidFire::CalcCountToKill(float attackDamage, uint32_t targetID) { if (attackDamage == 0) return f_Multiplier; - + auto& manager = game::EntityManager::instance(); auto targetEntity = manager.entity(targetID); if (targetEntity == nullptr) @@ -165,10 +176,10 @@ namespace cheat::feature entity = game::Entity(app::MoleMole_GadgetEntity_GetOwnerEntity(reinterpret_cast(entity.raw()), nullptr)); if (entity.runtimeID() == avatarID) return true; - } + } return false; - + } bool IsAttackByAvatar(game::Entity& attacker) @@ -183,6 +194,20 @@ namespace cheat::feature return attackerID == avatarID || IsAvatarOwner(attacker); } + bool IsConfigByAvatar(game::Entity& attacker) + { + if (attacker.raw() == nullptr) + return false; + + auto& manager = game::EntityManager::instance(); + auto avatarID = manager.avatar()->raw()->fields._configID_k__BackingField; + auto attackerID = attacker.raw()->fields._configID_k__BackingField; + // Taiga#5555: IDs can be found in ConfigAbility_Avatar_*.json or GadgetExcelConfigData.json + bool bulletID = attackerID >= 40000160 && attackerID <= 41069999; + + return avatarID == attackerID || bulletID; + } + bool IsValidByFilter(game::Entity* entity) { if (game::filters::combined::OrganicTargets.IsValid(entity) || @@ -192,7 +217,7 @@ namespace cheat::feature game::filters::puzzle::LargeRockPile.IsValid(entity) || game::filters::puzzle::SmallRockPile.IsValid(entity)) return true; - return false; + return false; } // Raises when any entity do hit event. @@ -203,7 +228,7 @@ namespace cheat::feature { auto attacker = game::Entity(__this->fields._._._entity); RapidFire& rapidFire = RapidFire::GetInstance(); - if (!IsAttackByAvatar(attacker) || !rapidFire.f_Enabled) + if (!IsConfigByAvatar(attacker) || !IsAttackByAvatar(attacker) || !rapidFire.f_Enabled) return CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method); auto& manager = game::EntityManager::instance(); @@ -242,9 +267,25 @@ namespace cheat::feature if (rapidFire.f_MultiHit) { int attackCount = rapidFire.GetAttackCount(__this, entity->runtimeID(), attackResult); for (int i = 0; i < attackCount; i++) - CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, method); - } else CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, method); + app::MoleMole_LCBaseCombat_FireBeingHitEvent(__this, entity->runtimeID(), attackResult, method); + } + else app::MoleMole_LCBaseCombat_FireBeingHitEvent(__this, entity->runtimeID(), attackResult, method); } + + CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method); + } + + static void VCAnimatorEvent_HandleProcessItem_Hook(app::MoleMole_VCAnimatorEvent* __this, + app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem* processItem, + app::AnimatorStateInfo processStateInfo, app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method) + { + auto attacker = game::Entity(__this->fields._._._entity); + RapidFire& rapidFire = RapidFire::GetInstance(); + + if (rapidFire.f_MultiAnimation && IsAttackByAvatar(attacker)) + processItem->fields.lastTime = 0; + + CALL_ORIGIN(VCAnimatorEvent_HandleProcessItem_Hook, __this, processItem, processStateInfo, mode, method); } } diff --git a/cheat-library/src/user/cheat/player/RapidFire.h b/cheat-library/src/user/cheat/player/RapidFire.h index 940741c..7d9d26f 100644 --- a/cheat-library/src/user/cheat/player/RapidFire.h +++ b/cheat-library/src/user/cheat/player/RapidFire.h @@ -19,6 +19,7 @@ namespace cheat::feature config::Field f_maxMultiplier; config::Field> f_MultiTarget; config::Field f_MultiTargetRadius; + config::Field> f_MultiAnimation; static RapidFire& GetInstance(); diff --git a/cheat-library/src/user/cheat/teleport/CustomTeleports.cpp b/cheat-library/src/user/cheat/teleport/CustomTeleports.cpp index 8e6738f..e3d9984 100644 --- a/cheat-library/src/user/cheat/teleport/CustomTeleports.cpp +++ b/cheat-library/src/user/cheat/teleport/CustomTeleports.cpp @@ -17,10 +17,11 @@ namespace cheat::feature { CustomTeleports::CustomTeleports() : Feature(), - NF(f_DebugMode, "Debug Mode", "CustomTeleports", false), // Soon to be added NF(f_Enabled, "Custom Teleport", "CustomTeleports", false), NF(f_Next, "Teleport Next", "CustomTeleports", Hotkey(VK_OEM_6)), NF(f_Previous, "Teleport Previous", "CustomTeleports", Hotkey(VK_OEM_4)), + NF(f_Interpolate, "Custom Teleport", "CustomTeleports", false), + NF(f_Speed, "Interpolation Speed", "CustomTeleports", 10.0f), dir(util::GetCurrentPath() / "teleports") { f_Next.value().PressedEvent += MY_METHOD_HANDLER(CustomTeleports::OnNext); @@ -122,6 +123,42 @@ namespace cheat::feature return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2) + pow(a.z - b.z, 2)); } + void CustomTeleports::TeleportTo(app::Vector3 position, bool interpolate) + { + auto &manager = game::EntityManager::instance(); + auto avatar = manager.avatar(); + if (avatar->moveComponent() == nullptr) + { + LOG_ERROR("Avatar has no move component, Is scene loaded?"); + return; + } + if (interpolate) + { + float speed = this->f_Speed; + auto avatarPos = manager.avatar()->absolutePosition(); + auto endPos = position; + std::thread interpolate([avatarPos, endPos, &manager, speed]() + { + float t = 0.0f; + app::Vector3 zero = {0,0,0}; + auto newPos = zero; + while (t < 1.0f) { + newPos = app::Vector3_Lerp(avatarPos, endPos, t, nullptr); + manager.avatar()->setAbsolutePosition(newPos); + t += speed / 100.0f; + Sleep(10); + } }); + interpolate.detach(); + } + else + { + if (PositionDistance(position, app::ActorUtils_GetAvatarPos(nullptr)) > 60.0f) + MapTeleport::GetInstance().TeleportTo(position); + else + manager.avatar()->setAbsolutePosition(position); + } + } + void CustomTeleports::OnTeleportKeyPressed(bool next) { if (!f_Enabled || selectedIndex < 0) @@ -138,13 +175,14 @@ namespace cheat::feature else { std::vector list(checkedIndices.begin(), checkedIndices.end()); - if (selectedIndex == list.back() ? next : selectedIndex == list.front()) + if (next ? selectedIndex == list.back() : selectedIndex == list.front()) return; + auto index = std::distance(list.begin(), std::find(list.begin(), list.end(), selectedIndex)); - position = Teleports.at(list.at(index + (next ? 1 : -1))).position; selectedIndex = list.at(index + (next ? 1 : -1)); + position = Teleports.at(selectedIndex).position; } - mapTeleport.TeleportTo(position); + TeleportTo(position, this->f_Interpolate); UpdateIndexName(); } @@ -157,38 +195,28 @@ namespace cheat::feature OnTeleportKeyPressed(true); } + void itr(std::regex exp, std::string name, std::string s) + { + std::sregex_iterator itr(name.begin(), name.end(), exp); + while (itr != std::sregex_iterator()) + { + for (unsigned i = 0; i < itr->size(); i++) + s.append((*itr)[i]); + itr++; + } + } void CustomTeleports::UpdateIndexName() { - std::string name(selectedIndex == -1 || checkedIndices.empty() ? "" : Teleports.at(selectedIndex).name); - // abbreviate teleport names that are too long + std::string name(selectedIndex == -1 || checkedIndices.empty() ? "" : Teleports.at(selectedIndex).name); if (name.length() > 15) { std::string shortened; std::regex numsExp("[\\d]+"); std::regex firstCharsExp("\\b[A-Za-z]"); - - std::sregex_iterator wordItr(name.begin(), name.end(), firstCharsExp); - while (wordItr != std::sregex_iterator()) - { - for (unsigned i = 0; i < wordItr->size(); i++) - { - shortened.append((*wordItr)[i]); - } - wordItr++; - } - - std::sregex_iterator numItr(name.begin(), name.end(), numsExp); - while (numItr != std::sregex_iterator()) - { - for (unsigned i = 0; i < numItr->size(); i++) - { - shortened.append(" "); - shortened.append((*numItr)[i]); - } - numItr++; - } + itr(firstCharsExp, name, shortened); + itr(numsExp, name, shortened); name = shortened; } selectedIndexName = name; @@ -249,7 +277,9 @@ namespace cheat::feature "3. You can now press Next or Previous Hotkey to Teleport through the Checklist\n" "Initially it will teleport the player to the selection made\n" "Note: Double click or click the arrow to open teleport details"); - ImGui::SameLine(); + ConfigWidget("Enable Interpolation", f_Interpolate, "Enable interpolation between teleports when using keybinds"); + ConfigWidget("Interpolation Speed", f_Speed, 0.1f, 0.1f, 99.0f, + "Interpolation speed.\n recommended setting below or equal to 0.1."); if (ImGui::Button("Delete Checked")) { @@ -281,8 +311,8 @@ namespace cheat::feature { std::sort(Teleports.begin(), Teleports.end(), [](const auto &a, const auto &b) { return StrCmpLogicalW(std::wstring(a.name.begin(), a.name.end()).c_str(), std::wstring(b.name.begin(), b.name.end()).c_str()) < 0; }); - bool allChecked = checkedIndices.size() == Teleports.size() && !Teleports.empty(); - bool allSearchChecked = checkedIndices.size() == searchIndices.size() && !searchIndices.empty(); + bool allSearchChecked = std::includes(checkedIndices.begin(), checkedIndices.end(), searchIndices.begin(), searchIndices.end()) && !searchIndices.empty(); + bool allChecked = (checkedIndices.size() == Teleports.size() && !Teleports.empty()) || allSearchChecked; ImGui::Checkbox("All", &allChecked); if (ImGui::IsItemClicked()) { @@ -316,11 +346,10 @@ namespace cheat::feature maxNameLength = Teleport.name.length(); ImGui::BeginTable("Teleports", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_NoSavedSettings); ImGui::TableSetupColumn("#", ImGuiTableColumnFlags_WidthFixed, 20); - ImGui::TableSetupColumn("Commands", ImGuiTableColumnFlags_WidthFixed, 100); + ImGui::TableSetupColumn("Commands", ImGuiTableColumnFlags_WidthFixed, 130); ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, maxNameLength * 8 + 10); ImGui::TableSetupColumn("Position"); ImGui::TableHeadersRow(); - ImGuiTreeNodeFlags nodeFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; for (const auto &[name, position, description] : Teleports) { @@ -332,12 +361,13 @@ namespace cheat::feature bool checked = std::any_of(checkedIndices.begin(), checkedIndices.end(), [&index](const auto &i) { return i == index; }); bool selected = index == selectedIndex; + std::string stringIndex = std::to_string(index); ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("%d", index); ImGui::TableNextColumn(); - ImGui::Checkbox(("##Index" + std::to_string(index)).c_str(), &checked); + ImGui::Checkbox(("##Index" + stringIndex).c_str(), &checked); if (ImGui::IsItemClicked(0)) { if (checked) @@ -352,37 +382,29 @@ namespace cheat::feature } ImGui::SameLine(); - if (ImGui::Button(("TP##Button" + std::to_string(index)).c_str())) + if (ImGui::Button(("TP##Button" + stringIndex).c_str())) { - auto &manager = game::EntityManager::instance(); - auto avatar = manager.avatar(); - if (avatar->moveComponent() == nullptr) - { - LOG_ERROR("Avatar has no move component, Is scene loaded?"); - return; - } - if (PositionDistance(position, app::ActorUtils_GetAvatarPos(nullptr)) > 60.0f) - MapTeleport::GetInstance().TeleportTo(position); - else - manager.avatar()->setAbsolutePosition(position); + TeleportTo(position, false); } ImGui::SameLine(); - if (ImGui::Button(("Select##Button" + std::to_string(index)).c_str())) + if (ImGui::Button(("Lerp##Button" + stringIndex).c_str())) + { + TeleportTo(position, true); + } + ImGui::SameLine(); + + if (ImGui::Button(("Select##Button" + stringIndex).c_str())) { selectedIndex = index; selectedByClick = true; UpdateIndexName(); } - ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, selected ? IM_COL32(40, 90, 175, 255) : IM_COL32(255, 255, 255, 255)); - - if (selected) - nodeFlags |= ImGuiTreeNodeFlags_Selected; - ImGui::PopStyleColor(); ImGui::TableNextColumn(); + ImGui::PushStyleColor(ImGuiCol_Text, selected ? IM_COL32(40, 90, 175, 255) : ImGui::ColorConvertFloat4ToU32(ImGui::GetStyle().Colors[ImGuiCol_Text])); ImGui::Text("%s", name.c_str()); + ImGui::PopStyleColor(); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); diff --git a/cheat-library/src/user/cheat/teleport/CustomTeleports.h b/cheat-library/src/user/cheat/teleport/CustomTeleports.h index e1fd414..6b2de3c 100644 --- a/cheat-library/src/user/cheat/teleport/CustomTeleports.h +++ b/cheat-library/src/user/cheat/teleport/CustomTeleports.h @@ -25,8 +25,9 @@ namespace cheat::feature class CustomTeleports : public Feature { public: - config::Field> f_DebugMode; config::Field> f_Enabled; + config::Field> f_Interpolate; + config::Field f_Speed; config::Field f_Next; config::Field f_Previous; static CustomTeleports& GetInstance(); @@ -55,6 +56,7 @@ namespace cheat::feature std::string selectedName; std::string selectedIndexName; CustomTeleports(); + void TeleportTo(app::Vector3 position, bool interpolate); void OnTeleportKeyPressed(bool next); void OnPrevious(); void OnNext(); diff --git a/cheat-library/src/user/cheat/visuals/AnimationChanger.cpp b/cheat-library/src/user/cheat/visuals/AnimationChanger.cpp new file mode 100644 index 0000000..37f36e0 --- /dev/null +++ b/cheat-library/src/user/cheat/visuals/AnimationChanger.cpp @@ -0,0 +1,301 @@ +#include "pch-il2cpp.h" +#include "AnimationChanger.h" + +#include +#include +#include +#include + +namespace cheat::feature +{ + static std::string animations[] = { + // All characters + "SlipFaceWall", + "SlipBackWall", + "DropDown", + "JumpOffWall", + "Jump", + "JumpForRun", + "JumpForWalk", + "Fly", + "FlyStart", + "JumpForSprint", + "SwimIdle", + "SwimMove", + "SwimDash", + "ClimbMove1", + "ClimbIdle", + "ClimbJump", + "ClimbMove0", + "FallToGroundRun", + "FallOnGroundLit", + "FallOnGround", + "FallToGroundRunHard", + "FallToGroundSprint", + "Walk", + "Run", + "Standby", + "RunToIdle", + "RunToWalk", + "WalkToIdle", + "WalkToRun", + "Sprint", + "SprintToIdle", + "SprintToRun", + "ClimbDownToGround", + "SprintBS", + "ShowUp", + "CrouchToStandby", + "CrouchIdle", + "CrouchRoll", + "CrouchMove", + "SkiffNormal", + "Upstairs", + "JumpUpWallForStandby", + "JumpUpWallReady", + "Standby2ClimbA", + "SwimJump", + "SwimJumpDrop", + "SwimJumpToWater", + "Standby2ClimbB", + "CrouchDrop", + "TurnDir", + "StandbyWeapon", + "StandbyPutaway", + "StandbyPutawayOver", + "Icespine_Out", + "Icespine", + "LiquidStrike_MoveStandby", + "LiquidStrike_AS", + "LiquidStrike_BS", + "LiquidStrike_BS1", + "LiquidStrike_Move", + "LiquidStrike_Strike", + "LiquidStrike_FatalStandby", + "LiquidStrike_FatalMove", + "LiquidStrike_AS_OnWater", + "LiquidStrike_BS_0", + "FrozenWindmill", + "FrozenWindmill_AS", + "Attack03", + "Attack04", + "Attack05", + "Attack01", + "Attack02", + "ExtraAttack", + "ExtraAttack_AS", + "FallingAnthem_Loop", + "FallingAnthem_AS_2", + "FallingAnthem_BS_1", + "FallingAnthem_BS_2", + "FallingAnthem_AS_1", + "FallingAnthem_Loop_Low", + "SitBDown", + "SitBLoop", + "SitBUp", + "SitDown", + "SitLoop", + "SitUp", + "StandbyShow_01", + "StandbyShow_02", + "StandbyVoice", + "Think01BS", + "Think01Loop", + "Think01AS", + "Akimbo02BS", + "Akimbo02Loop", + "Akimbo02AS", + "ChannelBS", + "ChannelLoop", + "ChannelAS", + "PlayMusic_Lyre_AS", + "PlayMusic_Lyre_BS", + "PlayMusic_Lyre_Loop", + "PlayMusic_Qin_BS", + "PlayMusic_Qin_AS", + "PlayMusic_Qin_Loop", + "ActivitySkill_ElectricCoreFly", + "Hit_H", + "Hit_L", + "Hit_Throw", + "Hit_Throw_Ground", + "Hit_ThrowAir", + "Struggle", + "NormalDie", + "SwimDie", + "HitGroundDie", + "FallDie_AS", + "FallDie", + // Main Character only + "UziExplode_AS", + "UziExplode_BS", + "UziExplode_Charge_01", + "UziExplode_Strike_02", + "UziExplode_Charge_02", + "UziExplode_Strike_01", + "UziExplode_BS_1", + "WindBreathe_AS", + "WindBreathe", + "Hogyoku_AS", + "Hogyoku_BS", + "Hogyoku", + "Hogyoku_Charge", + "Hogyoku_Charge_AS", + "Hogyoku_Charge_2", + "RockTide_AS", + "RockTide", + "CrouchThrowBS", + "CrouchThrowLoop", + "CrouchThrowAS", + "FindCatThrowBS", + "FindCatThrowLoop", + "FindCatThrowAS", + "Player_Electric_ElementalArt", + "Player_Electric_ElementalArt_AS", + "Player_Electric_ElementalBurst", + "Player_Electric_ElementalBurst_AS", + "PutHand01BS", + "PutHand01Loop", + "PutHand01AS", + "Akimbo01BS", + "Backrake01BS", + "Forerake01BS", + "StrikeChest01BS", + "Akimbo01Loop", + "Akimbo01AS", + "Backrake01Loop", + "Backrake01AS", + "Forerake01Loop", + "Forerake01AS", + "StrikeChest01Loop", + "StrikeChest01AS", + "HoldHead01BS", + "HoldHead01Loop", + "HoldHead01AS", + "Clap01", + "Turn01_90LBS", + "Turn01_90RBS", + "Turn01_90LAS", + "Turn01_90RAS", + "Alert01BS", + "Alert01Loop", + "Alert01AS", + "Fishing01_BS", + "Fishing01Loop", + "Fishing01AS", + "Think01_BS", + "Think01_Loop", + "Think01_AS", + "Channel01BS", + "Channel01Loop", + "Channel01AS", + "Fishing_Battle_BS", + "Fishing_Cast_AS", + "Fishing_Cast_BS", + "Fishing_Cast_Loop", + "Fishing_Choose", + "Fishing_Choose_Loop", + "Fishing_End", + "Fishing_Pull_01", + "Fishing_Pull_02", + "Fishing_Wait", + "Fishing_Pull_Fail", + "Bartender_MixingStandby", + "Bartender_MixingStart", + "Bartender_MixingToPour", + "Bartender_Pour", + "Bartender_PourFinish", + "Bartender_PourStandby", + "Bartender_AddLoop", + "Bartender_PrepareStart", + "Bartender_Standby", + "Bartender_AddStandby", + "Bartender_PrepareToStandby", + "Bartender_StandbyFinish", + "Blocking_BS", + "Blocking_Loop", + "Blocking_Back", + "Blocking_Bounce", + "Blocking_Hit", + "Blocking_AS" + }; + + AnimationChanger::AnimationChanger() : Feature(), + NF(f_Enabled, "Animation Changer", "Visuals::AnimationChanger", false), + NF(f_Animation, "Animation", "Visuals::AnimationChanger", "ExtraAttack"), + NF(f_ApplyKey, "Apply Animation", "Visuals::AnimationChanger", Hotkey('Y')), + NF(f_ResetKey, "Reset Animation", "Visuals::AnimationChanger", Hotkey('R')) + { + events::GameUpdateEvent += MY_METHOD_HANDLER(AnimationChanger::OnGameUpdate); + } + + const FeatureGUIInfo& AnimationChanger::GetGUIInfo() const + { + static const FeatureGUIInfo info{ "AnimationChanger", "Visuals", false }; + return info; + } + + void AnimationChanger::DrawMain() + { + ImGui::BeginGroupPanel("Animation Changer"); + { + ConfigWidget(f_Enabled, "Changes active character's animation.\nNot all animations work for every character except Main Character."); + if (f_Enabled) + { + if (ImGui::BeginCombo("Animations", f_Animation.value().c_str())) + { + for (auto &animation : animations) + { + bool is_selected = (f_Animation.value().c_str() == animation); + if (ImGui::Selectable(animation.c_str(), is_selected)) + f_Animation.value() = animation; + + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + ConfigWidget("Apply Key", f_ApplyKey, true); + ConfigWidget("Reset Key", f_ResetKey, true); + } + } + ImGui::EndGroupPanel(); + } + + bool AnimationChanger::NeedStatusDraw() const + { + return f_Enabled; + } + + void AnimationChanger::DrawStatus() + { + ImGui::Text("AnimationChanger"); + } + + AnimationChanger& AnimationChanger::GetInstance() + { + static AnimationChanger instance; + return instance; + } + + void AnimationChanger::OnGameUpdate() + { + if (!f_Enabled) + return; + + // Taiga#5555: Maybe need to add separate option to change delay value if user feels like it's too fast or slow. + UPDATE_DELAY(400); + + auto& manager = game::EntityManager::instance(); + auto avatar = manager.avatar(); + if (avatar->animator() == nullptr) + return; + + if (f_ApplyKey.value().IsPressed()) + app::Animator_Play(avatar->animator(), string_to_il2cppi(f_Animation.value().c_str()), 0, 0, nullptr); + + if (f_ResetKey.value().IsPressed()) + app::Animator_Rebind(avatar->animator(), nullptr); + } +} diff --git a/cheat-library/src/user/cheat/visuals/AnimationChanger.h b/cheat-library/src/user/cheat/visuals/AnimationChanger.h new file mode 100644 index 0000000..b8f9d0c --- /dev/null +++ b/cheat-library/src/user/cheat/visuals/AnimationChanger.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include + +namespace cheat::feature +{ + + class AnimationChanger : public Feature + { + public: + config::Field> f_Enabled; + config::Field f_Animation; + config::Field f_ApplyKey; + config::Field f_ResetKey; + + const FeatureGUIInfo& GetGUIInfo() const override; + void DrawMain() override; + virtual bool NeedStatusDraw() const override; + void DrawStatus() override; + static AnimationChanger& GetInstance(); + void OnGameUpdate(); + + private: + AnimationChanger(); + }; +} + diff --git a/cheat-library/src/user/cheat/world/AutoCook.cpp b/cheat-library/src/user/cheat/world/AutoCook.cpp index 12cab44..653fd39 100644 --- a/cheat-library/src/user/cheat/world/AutoCook.cpp +++ b/cheat-library/src/user/cheat/world/AutoCook.cpp @@ -14,7 +14,9 @@ namespace cheat::feature app::Component_1* Profirency = nullptr; } - static void PlayerModule_RequestPlayerCook(app::MoleMole_PlayerModule* __this, uint32_t recipeId, uint32_t avatarId, uint32_t qteQuality, uint32_t count, MethodInfo* method); + static std::map qualities{ {"Suspicious", 1}, {"Normal", 2}, {"Delicious", 3} }; + + static void PlayerModule_RequestPlayerCook(app::MoleMole_PlayerModule* __this, uint32_t recipeId, uint32_t avatarId, uint32_t qteQuality, uint32_t count, MethodInfo* method); static void PlayerModule_OnPlayerCookRsp(app::MoleMole_PlayerModule* __this, app::PlayerCookRsp* rsp, MethodInfo* method); static void CookingQtePageContext_UpdateProficiency(app::CookingQtePageContext* __this, MethodInfo* method); @@ -22,7 +24,7 @@ namespace cheat::feature NF(f_Enabled, "Standart Cooking", "AutoCook", false), NF(f_FastProficiency, "Fast Proficiency", "AutoCook", false), NF(f_CountField, "Count Item", "AutoCook", 1), - NF(f_QualityField, "Quality", "AutoCook", 1) + NF(f_QualityField, "Quality", "AutoCook", "Normal") { HookManager::install(app::MoleMole_PlayerModule_RequestPlayerCook, PlayerModule_RequestPlayerCook); HookManager::install(app::MoleMole_PlayerModule_OnPlayerCookRsp, PlayerModule_OnPlayerCookRsp); @@ -38,12 +40,24 @@ namespace cheat::feature void AutoCook::DrawMain() { ConfigWidget(f_Enabled, "Fast Cooking if the recipe has fast cooking open. \n" \ - "If fast cooking is closed, you in addition need to turn on Fast Proficiency."); + "If fast cooking is closed, you in addition need to turn on Fast Proficiency."); ConfigWidget(f_FastProficiency, "Quickly prepare an unstudied recipe to the maximum possible."); ConfigWidget("Count Item", f_CountField, 1, 1, 100, "How much to cook at a time.\n" \ "(For standard mode only.)"); - ConfigWidget("Quality Cooking", f_QualityField, 1, 1, 3, "Quality of the cook."); + if (ImGui::BeginCombo("Cooking Quality", f_QualityField.value().c_str())) + { + for (auto& [qualityName, quality] : qualities) + { + bool is_selected = (f_QualityField.value().c_str() == qualityName); + if (ImGui::Selectable(qualityName.c_str(), is_selected)) + f_QualityField.value() = qualityName; + + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } } bool AutoCook::NeedStatusDraw() const @@ -53,7 +67,10 @@ namespace cheat::feature void AutoCook::DrawStatus() { - ImGui::Text("Auto Cooking [%s]", f_FastProficiency ? "Proficiency" : "Standart"); + if (f_FastProficiency) + ImGui::Text("Auto Cooking [Proficiency]"); + else + ImGui::Text("Auto Cooking [Standart, %s]", f_QualityField.value().c_str()); } AutoCook& AutoCook::GetInstance() @@ -82,9 +99,14 @@ namespace cheat::feature if (autoCook.f_Enabled || autoCook.f_FastProficiency) { autoCook.CookFoodMaxNum = app::MoleMole_Config_CookRecipeExcelConfig_CheckCookFoodMaxNum(recipeId, nullptr); - qteQuality = autoCook.f_QualityField; - if (!autoCook.f_FastProficiency && autoCook.f_Enabled){ + // To prevent possible crashes + if (!qualities.count(autoCook.f_QualityField.value())) + autoCook.f_QualityField.value() = "Normal"; + + qteQuality = qualities.find(autoCook.f_QualityField.value())->second; + + if (!autoCook.f_FastProficiency && autoCook.f_Enabled) { count = autoCook.f_CountField; if (autoCook.f_CountField > autoCook.CookFoodMaxNum) count = autoCook.CookFoodMaxNum; @@ -99,7 +121,7 @@ namespace cheat::feature auto RectTransform = app::GameObject_GetComponentByName(GameObject::Profirency, string_to_il2cppi("RectTransform"), nullptr); auto TransformChild = app::Transform_GetChild(reinterpret_cast(RectTransform), 0, nullptr); auto TextComponent = app::Component_1_GetComponent_1(reinterpret_cast(TransformChild), string_to_il2cppi("Text"), nullptr); - + if (TextComponent != nullptr) { auto Text_str = app::Text_get_text(reinterpret_cast(TextComponent), nullptr); auto ProficiencyStr = il2cppi_to_string(Text_str).erase(0, il2cppi_to_string(Text_str).find_first_of(" .")); @@ -127,7 +149,11 @@ namespace cheat::feature AutoCook& autoCook = AutoCook::GetInstance(); if (autoCook.f_Enabled || autoCook.f_FastProficiency) { - rsp->fields.qteQuality_ = autoCook.f_QualityField; + // To prevent possible crashes + if (!qualities.count(autoCook.f_QualityField.value())) + autoCook.f_QualityField.value() = "Normal"; + + rsp->fields.qteQuality_ = qualities.find(autoCook.f_QualityField.value())->second; rsp->fields.cookCount_ = autoCook.f_CountField; if (autoCook.f_FastProficiency) rsp->fields.cookCount_ = 1; @@ -137,7 +163,7 @@ namespace cheat::feature return CALL_ORIGIN(PlayerModule_OnPlayerCookRsp, __this, rsp, method); } - + static void CookingQtePageContext_UpdateProficiency(app::CookingQtePageContext* __this, MethodInfo* method) { AutoCook& autoCook = AutoCook::GetInstance(); if (autoCook.f_Enabled || autoCook.f_FastProficiency) diff --git a/cheat-library/src/user/cheat/world/AutoCook.h b/cheat-library/src/user/cheat/world/AutoCook.h index 1efaa6c..de11afb 100644 --- a/cheat-library/src/user/cheat/world/AutoCook.h +++ b/cheat-library/src/user/cheat/world/AutoCook.h @@ -12,10 +12,10 @@ namespace cheat::feature config::Field> f_FastProficiency; config::Field f_CountField; - config::Field f_QualityField; + config::Field f_QualityField; int CookFoodMaxNum; // Maximum quantity at a time - int CookCount; + int CookCount; static AutoCook& GetInstance(); @@ -26,7 +26,7 @@ namespace cheat::feature void DrawStatus() override; private: - + AutoCook(); }; } diff --git a/cheat-library/src/user/cheat/world/AutoDestroy.cpp b/cheat-library/src/user/cheat/world/AutoDestroy.cpp index 65d26a3..3f873e2 100644 --- a/cheat-library/src/user/cheat/world/AutoDestroy.cpp +++ b/cheat-library/src/user/cheat/world/AutoDestroy.cpp @@ -9,31 +9,32 @@ #include #include -namespace cheat::feature +namespace cheat::feature { static void LCAbilityElement_ReduceModifierDurability_Hook(app::LCAbilityElement* __this, int32_t modifierDurabilityIndex, float reduceDurability, app::Nullable_1_Single_ deltaTime, MethodInfo* method); - AutoDestroy::AutoDestroy() : Feature(), - NF(f_Enabled, "Auto Destroy", "AutoDestroy", false), - NF(f_DestroyOres, "Destroy Ores", "AutoDestroy", false), - NF(f_DestroyShields, "Destroy Shields", "AutoDestroy", false), - NF(f_DestroyDoodads, "Destroy Doodads", "AutoDestroy", false), - NF(f_Range, "Range", "AutoDestroy", 10.0f) - { + AutoDestroy::AutoDestroy() : Feature(), + NF(f_Enabled, "Auto Destroy", "AutoDestroy", false), + NF(f_DestroyOres, "Destroy Ores", "AutoDestroy", false), + NF(f_DestroyShields, "Destroy Shields", "AutoDestroy", false), + NF(f_DestroyDoodads, "Destroy Doodads", "AutoDestroy", false), + NF(f_DestroyPlants, "Destroy Plants", "AutoDestroy", false), + NF(f_Range, "Range", "AutoDestroy", 10.0f) + { HookManager::install(app::MoleMole_LCAbilityElement_ReduceModifierDurability, LCAbilityElement_ReduceModifierDurability_Hook); } - const FeatureGUIInfo& AutoDestroy::GetGUIInfo() const - { - static const FeatureGUIInfo info { "Auto Destroy Objects", "World", true }; - return info; - } + const FeatureGUIInfo& AutoDestroy::GetGUIInfo() const + { + static const FeatureGUIInfo info{ "Auto Destroy Objects", "World", true }; + return info; + } - void AutoDestroy::DrawMain() - { + void AutoDestroy::DrawMain() + { ImGui::TextColored(ImColor(255, 165, 0, 255), "Note. This feature is not fully tested detection-wise.\n" "Not recommended for main accounts or used with high values."); - + ConfigWidget("Enabled", f_Enabled, "Instantly destroys non-living objects within range."); ImGui::Indent(); ConfigWidget("Ores", f_DestroyOres, "Ores and variants, e.g. electro crystals, marrows, etc."); @@ -43,30 +44,32 @@ namespace cheat::feature ConfigWidget("Doodads", f_DestroyDoodads, "Barrels, boxes, vases, etc."); ImGui::SameLine(); ImGui::TextColored(ImColor(255, 165, 0, 255), "Extremely risky!"); + ConfigWidget("Plants", f_DestroyPlants, "Dandelion Seeds, Sakura Bloom, etc."); ImGui::Unindent(); ConfigWidget("Range (m)", f_Range, 0.1f, 1.0f, 15.0f); - } + } - bool AutoDestroy::NeedStatusDraw() const + bool AutoDestroy::NeedStatusDraw() const { - return f_Enabled; - } + return f_Enabled; + } - void AutoDestroy::DrawStatus() - { - ImGui::Text("Destroy [%.01fm%s%s%s%s]", + void AutoDestroy::DrawStatus() + { + ImGui::Text("Destroy [%.01fm%s%s%s%s%s]", f_Range.value(), - f_DestroyOres || f_DestroyShields || f_DestroyDoodads ? "|" : "", + f_DestroyOres || f_DestroyShields || f_DestroyDoodads || f_DestroyPlants ? "|" : "", f_DestroyOres ? "O" : "", f_DestroyShields ? "S" : "", - f_DestroyDoodads ? "D" : ""); - } + f_DestroyDoodads ? "D" : "", + f_DestroyPlants ? "P" : ""); + } - AutoDestroy& AutoDestroy::GetInstance() - { - static AutoDestroy instance; - return instance; - } + AutoDestroy& AutoDestroy::GetInstance() + { + static AutoDestroy instance; + return instance; + } // Thanks to @RyujinZX // Every ore has ability element component @@ -79,17 +82,17 @@ namespace cheat::feature auto& manager = game::EntityManager::instance(); auto& autoDestroy = AutoDestroy::GetInstance(); auto entity = __this->fields._._._entity; - if (autoDestroy.f_Enabled && + if (autoDestroy.f_Enabled && autoDestroy.f_Range > manager.avatar()->distance(entity) && ( - (autoDestroy.f_DestroyOres && game::filters::combined::Ores.IsValid(manager.entity(entity))) || - (autoDestroy.f_DestroyDoodads && game::filters::combined::Doodads.IsValid(manager.entity(entity))) || + (autoDestroy.f_DestroyOres && game::filters::combined::Ores.IsValid(manager.entity(entity))) || + (autoDestroy.f_DestroyDoodads && (game::filters::combined::Doodads.IsValid(manager.entity(entity)) || game::filters::chest::SBramble.IsValid(manager.entity(entity)))) || (autoDestroy.f_DestroyShields && !game::filters::combined::MonsterBosses.IsValid(manager.entity(entity)) && ( - game::filters::combined::MonsterShielded.IsValid(manager.entity(entity)) || // For shields attached to monsters, e.g. abyss mage shields. - game::filters::combined::MonsterEquips.IsValid(manager.entity(entity)) // For shields/weapons equipped by monsters, e.g. rock shield. - )) + game::filters::combined::MonsterShielded.IsValid(manager.entity(entity)) || // For shields attached to monsters, e.g. abyss mage shields. + game::filters::combined::MonsterEquips.IsValid(manager.entity(entity)))) || // For shields/weapons equipped by monsters, e.g. rock shield. + (autoDestroy.f_DestroyPlants && game::filters::combined::PlantDestroy.IsValid(manager.entity(entity))) // For plants e.g dandelion seeds. + ) ) - ) { // This value always above any ore durability reduceDurability = 1000; diff --git a/cheat-library/src/user/cheat/world/AutoDestroy.h b/cheat-library/src/user/cheat/world/AutoDestroy.h index 14e0985..d4c47a0 100644 --- a/cheat-library/src/user/cheat/world/AutoDestroy.h +++ b/cheat-library/src/user/cheat/world/AutoDestroy.h @@ -12,6 +12,7 @@ namespace cheat::feature config::Field> f_DestroyOres; config::Field> f_DestroyShields; config::Field> f_DestroyDoodads; + config::Field> f_DestroyPlants; config::Field f_Range; static AutoDestroy& GetInstance(); diff --git a/cheat-library/src/user/cheat/world/FreezeEnemies.cpp b/cheat-library/src/user/cheat/world/FreezeEnemies.cpp index a9d8bed..183b4d1 100644 --- a/cheat-library/src/user/cheat/world/FreezeEnemies.cpp +++ b/cheat-library/src/user/cheat/world/FreezeEnemies.cpp @@ -47,6 +47,7 @@ namespace cheat::feature void FreezeEnemies::OnGameUpdate() { auto& manager = game::EntityManager::instance(); + static bool change = false; for (const auto& monster : manager.entities(game::filters::combined::Monsters)) { @@ -61,11 +62,16 @@ namespace cheat::feature //LOG_DEBUG("%s", magic_enum::enum_name(constraints).data()); app::Rigidbody_set_constraints(rigidBody, app::RigidbodyConstraints__Enum::FreezeAll, nullptr); app::Animator_set_speed(animator, 0.f, nullptr); + change = false; } else { app::Rigidbody_set_constraints(rigidBody, app::RigidbodyConstraints__Enum::FreezeRotation, nullptr); - app::Animator_set_speed(animator, 1.f, nullptr); + if (!change) + { + app::Animator_set_speed(animator, 1.f, nullptr); + change = true; + } } } } diff --git a/injector/injector.vcxproj b/injector/injector.vcxproj index 836096f..7bf85d8 100644 --- a/injector/injector.vcxproj +++ b/injector/injector.vcxproj @@ -127,7 +127,7 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - stdcpp17 + stdcpp20 $(ProjectDir)include/;$(SolutionDir)cheat-base/src;$(SolutionDir)cheat-base/vendor/simpleIni/ stdc17