This commit is contained in:
lunatic 2022-08-09 04:29:12 +07:00
commit 27b41f1efa
29 changed files with 922 additions and 284 deletions

View File

@ -1,46 +1,98 @@
#include <pch.h> #include <pch.h>
#include "Settings.h" #include "Settings.h"
#include <cheat-base/render/gui-util.h>
#include <cheat-base/render/renderer.h>
#include <cheat-base/cheat/CheatManagerBase.h> #include <cheat-base/cheat/CheatManagerBase.h>
#include <cheat-base/render/renderer.h>
#include <cheat-base/render/gui-util.h>
#include <misc/cpp/imgui_stdlib.h>
#include <cheat-base/util.h>
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_MenuKey, "Show Cheat Menu Key", "General", Hotkey(VK_F1)),
NF(f_HotkeysEnabled, "Hotkeys Enabled", "General", true), 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_StatusMove, "Move Status Window", "General::StatusWindow", true),
NF(f_StatusShow, "Show 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_InfoMove, "Move Info Window", "General::InfoWindow", true),
NF(f_InfoShow, "Show 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_FpsMove, "Move FPS Indicator", "General::FPS", false),
NF(f_FpsShow, "Show FPS Indicator", "General::FPS", true), 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_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_ConsoleLogging, "Console Logging", "General::Logging", true),
NF(f_FastExitEnable, "Fast Exit", "General::FastExit", false), 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<float>(f_FontSize)); renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed); 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 }; bool inited = false;
return info; 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() void Settings::DrawMain()
{ {
@ -51,13 +103,7 @@ namespace cheat::feature
"Key to toggle main menu visibility. Cannot be empty.\n"\ "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."); "If you forget this key, you can see or set it in your config file.");
ConfigWidget(f_HotkeysEnabled, "Enable hotkeys."); 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<float>(f_FontSize));
}
ConfigWidget(f_ShowStyleEditor, "Show interface style editor window.");
}
ImGui::EndGroupPanel(); ImGui::EndGroupPanel();
ImGui::BeginGroupPanel("Logging"); ImGui::BeginGroupPanel("Logging");
@ -103,7 +149,7 @@ namespace cheat::feature
ImGui::BeginGroupPanel("Show Notifications"); ImGui::BeginGroupPanel("Show Notifications");
{ {
ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed."); 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(); ImGui::EndGroupPanel();
@ -111,7 +157,7 @@ namespace cheat::feature
{ {
ConfigWidget("Enabled", ConfigWidget("Enabled",
f_FastExitEnable, f_FastExitEnable,
"Enable Fast Exit.\n" "Enable Fast Exit.\n"
); );
if (!f_FastExitEnable) if (!f_FastExitEnable)
ImGui::BeginDisabled(); ImGui::BeginDisabled();
@ -123,13 +169,54 @@ namespace cheat::feature
ImGui::EndDisabled(); ImGui::EndDisabled();
} }
ImGui::EndGroupPanel(); 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<float>(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() Settings& Settings::GetInstance()
{ {
static Settings instance; static Settings instance;
return instance; return instance;
} }
void Settings::OnExitKeyPressed() void Settings::OnExitKeyPressed()
{ {
@ -139,4 +226,3 @@ namespace cheat::feature
ExitProcess(0); ExitProcess(0);
} }
} }

View File

@ -2,26 +2,24 @@
#include <cheat-base/cheat/Feature.h> #include <cheat-base/cheat/Feature.h>
#include <cheat-base/config/config.h> #include <cheat-base/config/config.h>
namespace cheat::feature namespace cheat::feature
{ {
class Settings : public Feature class Settings : public Feature
{ {
public: public:
config::Field<Hotkey> f_MenuKey; config::Field<Hotkey> f_MenuKey;
config::Field<bool> f_HotkeysEnabled; config::Field<bool> f_HotkeysEnabled;
config::Field<int> f_FontSize;
config::Field<bool> f_ShowStyleEditor;
config::Field<bool> f_StatusMove; config::Field<bool> f_StatusMove;
config::Field<bool> f_StatusShow; config::Field<bool> f_StatusShow;
config::Field<bool> f_InfoMove; config::Field<bool> f_InfoMove;
config::Field<bool> f_InfoShow; config::Field<bool> f_InfoShow;
config::Field<bool> f_FpsShow; config::Field<bool> f_FpsShow;
config::Field<bool> f_FpsMove; config::Field<bool> f_FpsMove;
config::Field<bool> f_NotificationsShow; config::Field<bool> f_NotificationsShow;
config::Field<int> f_NotificationsDelay; config::Field<int> f_NotificationsDelay;
@ -31,11 +29,20 @@ namespace cheat::feature
config::Field<bool> f_FastExitEnable; config::Field<bool> f_FastExitEnable;
config::Field<Hotkey> f_HotkeyExit; config::Field<Hotkey> f_HotkeyExit;
config::Field<int> f_FontSize;
config::Field<bool> f_ShowStyleEditor;
std::filesystem::path themesDir;
config::Field<std::string> f_DefaultTheme;
static Settings& GetInstance(); static Settings& GetInstance();
const FeatureGUIInfo& GetGUIInfo() const override; const FeatureGUIInfo& GetGUIInfo() const override;
void DrawMain() override; void DrawMain() override;
void Init();
void Colors_Export(std::string name);
void Colors_Import(std::string name);
private: private:
void OnExitKeyPressed(); void OnExitKeyPressed();

View File

@ -12,6 +12,7 @@
#include <cheat-base/render/backend/dx12-hook.h> #include <cheat-base/render/backend/dx12-hook.h>
#include <cheat-base/ResourceLoader.h> #include <cheat-base/ResourceLoader.h>
#include <cheat-base/cheat/misc/Settings.h>
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 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 constexpr int _fontsCount = _fontSizeMax / _fontSizeStep;
static std::array<ImFont*, _fontsCount> _fonts; static std::array<ImFont*, _fontsCount> _fonts;
static Data _customFontData {}; static Data _customFontData{};
static WNDPROC OriginalWndProcHandler; static WNDPROC OriginalWndProcHandler;
static ID3D11RenderTargetView* mainRenderTargetView; static ID3D11RenderTargetView* mainRenderTargetView;
static void OnRenderDX11(ID3D11DeviceContext* pContext); static void OnRenderDX11(ID3D11DeviceContext* pContext);
static void OnInitializeDX11(HWND window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain* pChain); static void OnInitializeDX11(HWND window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain* pChain);
static void OnPreRenderDX12(); static void OnPreRenderDX12();
static void OnPostRenderDX12(ID3D12GraphicsCommandList* commandList); static void OnPostRenderDX12(ID3D12GraphicsCommandList* commandList);
static void OnInitializeDX12(HWND window, ID3D12Device* pDevice, UINT buffersCounts, ID3D12DescriptorHeap* pDescriptorHeapImGuiRender); static void OnInitializeDX12(HWND window, ID3D12Device* pDevice, UINT buffersCounts, ID3D12DescriptorHeap* pDescriptorHeapImGuiRender);
@ -106,7 +107,7 @@ namespace renderer
return io.FontDefault; return io.FontDefault;
} }
int fontSizeInt = static_cast<int>(fontSize); int fontSizeInt = static_cast<int>(fontSize);
int fontIndex = fontSizeInt / _fontSizeStep + int fontIndex = fontSizeInt / _fontSizeStep +
(fontSizeInt % _fontSizeStep > (_fontSizeStep / 2) ? 1 : 0) - 1; (fontSizeInt % _fontSizeStep > (_fontSizeStep / 2) ? 1 : 0) - 1;
fontIndex = std::clamp(fontIndex, 0, _fontsCount - 1); fontIndex = std::clamp(fontIndex, 0, _fontsCount - 1);
return _fonts[fontIndex]; return _fonts[fontIndex];
@ -122,7 +123,7 @@ namespace renderer
int fontSizeInt = static_cast<int>(fontSize); int fontSizeInt = static_cast<int>(fontSize);
int fontIndex = fontSizeInt / _fontSizeStep; int fontIndex = fontSizeInt / _fontSizeStep;
int fontAligned = fontIndex * _fontSizeStep + int fontAligned = fontIndex * _fontSizeStep +
((fontSizeInt % _fontSizeStep) > _fontSizeStep / 2 ? _fontSizeStep : 0); ((fontSizeInt % _fontSizeStep) > _fontSizeStep / 2 ? _fontSizeStep : 0);
fontAligned = std::clamp(fontAligned, _fontSizeStep, _fontSizeMax); fontAligned = std::clamp(fontAligned, _fontSizeStep, _fontSizeMax);
@ -138,7 +139,7 @@ namespace renderer
{ {
return _globalFontSize; return _globalFontSize;
} }
static void LoadCustomFont() static void LoadCustomFont()
{ {
if (_customFontData.data == nullptr) if (_customFontData.data == nullptr)
@ -195,7 +196,7 @@ namespace renderer
reinterpret_cast<LONG_PTR>(hWndProc))); reinterpret_cast<LONG_PTR>(hWndProc)));
ImGui_ImplWin32_Init(window); ImGui_ImplWin32_Init(window);
ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM, ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM,
pDescriptorHeapImGuiRender, pDescriptorHeapImGuiRender,
pDescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(), pDescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(),
pDescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart()); pDescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart());
@ -253,6 +254,9 @@ namespace renderer
pContext->OMSetRenderTargets(1, &mainRenderTargetView, nullptr); pContext->OMSetRenderTargets(1, &mainRenderTargetView, nullptr);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); 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) static LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

View File

@ -21,6 +21,7 @@
<ClInclude Include="src\user\cheat\misc\sniffer\pipe\PipeClient.h" /> <ClInclude Include="src\user\cheat\misc\sniffer\pipe\PipeClient.h" />
<ClInclude Include="src\user\cheat\misc\sniffer\pipe\PipeIO.h" /> <ClInclude Include="src\user\cheat\misc\sniffer\pipe\PipeIO.h" />
<ClInclude Include="src\user\cheat\player\AutoRun.h" /> <ClInclude Include="src\user\cheat\player\AutoRun.h" />
<ClInclude Include="src\user\cheat\visuals\AnimationChanger.h" />
<ClInclude Include="src\user\cheat\visuals\TextureChanger.h" /> <ClInclude Include="src\user\cheat\visuals\TextureChanger.h" />
<ClInclude Include="src\user\cheat\visuals\FreeCamera.h" /> <ClInclude Include="src\user\cheat\visuals\FreeCamera.h" />
<ClInclude Include="src\user\cheat\world\AutoSeelie.h" /> <ClInclude Include="src\user\cheat\world\AutoSeelie.h" />
@ -113,6 +114,7 @@
<ClCompile Include="src\user\cheat\misc\sniffer\pipe\PipeClient.cpp" /> <ClCompile Include="src\user\cheat\misc\sniffer\pipe\PipeClient.cpp" />
<ClCompile Include="src\user\cheat\misc\sniffer\pipe\PipeIO.cpp" /> <ClCompile Include="src\user\cheat\misc\sniffer\pipe\PipeIO.cpp" />
<ClCompile Include="src\user\cheat\player\AutoRun.cpp" /> <ClCompile Include="src\user\cheat\player\AutoRun.cpp" />
<ClCompile Include="src\user\cheat\visuals\AnimationChanger.cpp" />
<ClCompile Include="src\user\cheat\visuals\TextureChanger.cpp" /> <ClCompile Include="src\user\cheat\visuals\TextureChanger.cpp" />
<ClCompile Include="src\user\cheat\visuals\FreeCamera.cpp" /> <ClCompile Include="src\user\cheat\visuals\FreeCamera.cpp" />
<ClCompile Include="src\user\cheat\world\AutoSeelie.cpp" /> <ClCompile Include="src\user\cheat\world\AutoSeelie.cpp" />
@ -219,6 +221,7 @@
<Image Include="res\iconsHD\Andrius.png" /> <Image Include="res\iconsHD\Andrius.png" />
<Image Include="res\iconsHD\Azhdaha.png" /> <Image Include="res\iconsHD\Azhdaha.png" />
<Image Include="res\iconsHD\Boar.png" /> <Image Include="res\iconsHD\Boar.png" />
<Image Include="res\iconsHD\BookPage.png" />
<Image Include="res\iconsHD\Cat.png" /> <Image Include="res\iconsHD\Cat.png" />
<Image Include="res\iconsHD\Cicin.png" /> <Image Include="res\iconsHD\Cicin.png" />
<Image Include="res\iconsHD\Crane.png" /> <Image Include="res\iconsHD\Crane.png" />
@ -557,6 +560,7 @@
<Image Include="res\icons\Andrius.png" /> <Image Include="res\icons\Andrius.png" />
<Image Include="res\icons\Azhdaha.png" /> <Image Include="res\icons\Azhdaha.png" />
<Image Include="res\icons\Boar.png" /> <Image Include="res\icons\Boar.png" />
<Image Include="res\icons\BookPage.png" />
<Image Include="res\icons\Cat.png" /> <Image Include="res\icons\Cat.png" />
<Image Include="res\icons\Cicin.png" /> <Image Include="res\icons\Cicin.png" />
<Image Include="res\icons\Crane.png" /> <Image Include="res\icons\Crane.png" />
@ -1010,7 +1014,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch-il2cpp.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch-il2cpp.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>$(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/</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(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/</AdditionalIncludeDirectories>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>

View File

@ -252,6 +252,9 @@
<ClInclude Include="src\user\cheat\world\CustomWeather.h"> <ClInclude Include="src\user\cheat\world\CustomWeather.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\user\cheat\visuals\AnimationChanger.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Font Include="res\Ruda-Bold.ttf" /> <Font Include="res\Ruda-Bold.ttf" />
@ -462,6 +465,9 @@
<ClCompile Include="src\user\cheat\world\CustomWeather.cpp"> <ClCompile Include="src\user\cheat\world\CustomWeather.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\user\cheat\visuals\AnimationChanger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="res\res.rc"> <ResourceCompile Include="res\res.rc">
@ -2508,5 +2514,11 @@
<Image Include="res\icons\Spincrocodile.png"> <Image Include="res\icons\Spincrocodile.png">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</Image> </Image>
<Image Include="res\iconsHD\BookPage.png">
<Filter>Resource Files</Filter>
</Image>
<Image Include="res\icons\BookPage.png">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup> </ItemGroup>
</Project> </Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -25,21 +25,21 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// TEXTINCLUDE // TEXTINCLUDE
// //
1 TEXTINCLUDE 1 TEXTINCLUDE
BEGIN BEGIN
"resource.h\0" "resource.h\0"
END END
2 TEXTINCLUDE 2 TEXTINCLUDE
BEGIN BEGIN
"#include ""winres.h""\r\n" "#include ""winres.h""\r\n"
"\0" "\0"
END END
3 TEXTINCLUDE 3 TEXTINCLUDE
BEGIN BEGIN
"\r\n" "\r\n"
"\0" "\0"
END END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED
@ -140,6 +140,8 @@ HDBOAR PNG "iconsHD\\Boar.png"
HDBOOK PNG "iconsHD\\Book.png" HDBOOK PNG "iconsHD\\Book.png"
HDBOOKPAGE PNG "iconsHD\\BookPage.png"
HDBOOTWEASEL PNG "iconsHD\\BootWeasel.png" HDBOOTWEASEL PNG "iconsHD\\BootWeasel.png"
HDBRIGHTCROWNPIGEON PNG "iconsHD\\BrightcrownPigeon.png" HDBRIGHTCROWNPIGEON PNG "iconsHD\\BrightcrownPigeon.png"
@ -316,6 +318,8 @@ HDGEOGRANUM PNG "iconsHD\\Geogranum.png"
HDGEOHYPOSTASIS PNG "iconsHD\\GeoHypostasis.png" HDGEOHYPOSTASIS PNG "iconsHD\\GeoHypostasis.png"
HDGEOPUZZLE PNG "iconsHD\\MiniPuzzle.png"
HDGEOSIGIL PNG "iconsHD\\GeoSigil.png" HDGEOSIGIL PNG "iconsHD\\GeoSigil.png"
HDGEOVISHAP PNG "iconsHD\\Geovishap.png" HDGEOVISHAP PNG "iconsHD\\Geovishap.png"
@ -626,7 +630,7 @@ HDSHOGUN PNG "iconsHD\\Shogun.png"
HDSHOGUNATEINFANTRY PNG "iconsHD\\ShogunateInfantry.png" HDSHOGUNATEINFANTRY PNG "iconsHD\\ShogunateInfantry.png"
HDSHRINEOFDEPTH PNG "iconsHD\\ShrineOfDepth.png" HDSHRINEOFDEPTH PNG "iconsHD\\Mondstadt.png"
HDSIGNORA PNG "iconsHD\\Signora.png" HDSIGNORA PNG "iconsHD\\Signora.png"
@ -850,6 +854,8 @@ BOAR PNG "icons\\Boar.png"
BOOK PNG "icons\\Book.png" BOOK PNG "icons\\Book.png"
BOOKPAGE PNG "icons\\BookPage.png"
BOOTWEASEL PNG "icons\\BootWeasel.png" BOOTWEASEL PNG "icons\\BootWeasel.png"
BRIGHTCROWNPIGEON PNG "icons\\BrightcrownPigeon.png" BRIGHTCROWNPIGEON PNG "icons\\BrightcrownPigeon.png"
@ -1026,6 +1032,8 @@ GEOGRANUM PNG "icons\\Geogranum.png"
GEOHYPOSTASIS PNG "icons\\GeoHypostasis.png" GEOHYPOSTASIS PNG "icons\\GeoHypostasis.png"
GEOPUZZLE PNG "icons\\MiniPuzzle.png"
GEOSIGIL PNG "icons\\GeoSigil.png" GEOSIGIL PNG "icons\\GeoSigil.png"
GEOVISHAP PNG "icons\\Geovishap.png" GEOVISHAP PNG "icons\\Geovishap.png"

View File

@ -56,6 +56,7 @@ DO_APP_FUNC(0x02DB4680, void, MoleMole_ActorAbilityPlugin_AddDynamicFloatWithRan
// Rapid fire // Rapid fire
DO_APP_FUNC(0x017B1D50, void, MoleMole_LCBaseCombat_DoHitEntity, (LCBaseCombat* __this, uint32_t targetID, AttackResult* attackResult, bool ignoreCheckCanBeHitInMP, MethodInfo* method)); DO_APP_FUNC(0x017B1D50, void, MoleMole_LCBaseCombat_DoHitEntity, (LCBaseCombat* __this, uint32_t targetID, AttackResult* attackResult, bool ignoreCheckCanBeHitInMP, MethodInfo* method));
DO_APP_FUNC(0x019DDF40, void, MoleMole_Formula_CalcAttackResult, (CombatProperty* attackCombatProperty, CombatProperty* defenseCombatProperty, AttackResult* attackResult, BaseEntity* attackerEntity, BaseEntity* attackeeEntity, MethodInfo* method)); DO_APP_FUNC(0x019DDF40, void, MoleMole_Formula_CalcAttackResult, (CombatProperty* attackCombatProperty, CombatProperty* defenseCombatProperty, AttackResult* attackResult, BaseEntity* attackerEntity, BaseEntity* attackeeEntity, MethodInfo* method));
DO_APP_FUNC(0x0106D020, void, MoleMole_VCAnimatorEvent_HandleProcessItem, (MoleMole_VCAnimatorEvent* __this, MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem* processItem, AnimatorStateInfo processStateInfo, MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method));
// World cheats // World cheats
@ -344,6 +345,9 @@ DO_APP_FUNC(0x057E9D10, int32_t, Camera_get_pixelHeight, (Camera* __this, Method
DO_APP_FUNC(0x0579EB70, int32_t, Screen_get_width, (MethodInfo* method)); DO_APP_FUNC(0x0579EB70, int32_t, Screen_get_width, (MethodInfo* method));
DO_APP_FUNC(0x0579EB00, int32_t, Screen_get_height, (MethodInfo* method)); DO_APP_FUNC(0x0579EB00, int32_t, Screen_get_height, (MethodInfo* method));
DO_APP_FUNC(0x05822EE0, void, Animator_Play, (Animator* __this, String* stateName, int32_t layer, float normalizedTime, MethodInfo* method));
DO_APP_FUNC(0x05823060, void, Animator_Rebind, (Animator* __this, MethodInfo* method));
DO_APP_FUNC(0x058235C0, float, Animator_get_speed, (Animator* __this, MethodInfo* method));
DO_APP_FUNC(0x058236F0, void, Animator_set_speed, (Animator* __this, float value, MethodInfo* method)); DO_APP_FUNC(0x058236F0, void, Animator_set_speed, (Animator* __this, float value, MethodInfo* method));
DO_APP_FUNC(0x058AE2D0, bool, Behaviour_get_isActiveAndEnabled, (Behaviour* __this, MethodInfo* method)); DO_APP_FUNC(0x058AE2D0, bool, Behaviour_get_isActiveAndEnabled, (Behaviour* __this, MethodInfo* method));

View File

@ -11998,6 +11998,61 @@ namespace app {
struct MoleMole_ActorAbilityPlugin__Fields fields; struct MoleMole_ActorAbilityPlugin__Fields fields;
}; };
struct MoleMole_VCAnimatorEvent__Fields {
struct VCBase__Fields _;
struct Animator* _animator;
struct Action_1_MoleMole_AnimatorParameterEntry_* onUserInputControllerChanged;
struct Action_4_Int32_UnityEngine_AnimatorStateInfo_UnityEngine_AnimatorStateInfo_MoleMole_AnimatorStateChangeExtra_* onAnimatorStateTransitionFinish;
struct Dictionary_2_System_Int32_Dictionary_2_System_Int32_List_1_System_Int32_* _activeAnimatorEventPatterns;
struct Dictionary_2_System_Int32_System_Int32_* _filterOldPattern2newPattern;
struct Action_2_Int32_Single_* processNormalizedTimeActions;
struct Queue_1_MoleMole_CompensateDiffInfo_* authorityEventQueue;
struct Queue_1_MoleMole_CompensateDiffInfo_* remoteEventQueue;
struct MoleMole_VCMoveData* _moveData;
struct MoleMole_VCSyncAnimator* _vcSyncAnimator;
int32_t MAX_ALLOW_COMPENSATE_TIME;
struct List_1_System_Int32_* _layerIndexes;
struct Dictionary_2_System_Int32_MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorLayerItem_* _layerItems;
};
struct MoleMole_VCAnimatorEvent {
struct MoleMole_VCAnimatorEvent__Class* klass;
MonitorData* monitor;
struct MoleMole_VCAnimatorEvent__Fields fields;
};
struct AnimatorStateInfo {
int32_t m_Name;
int32_t m_Path;
int32_t m_FullPath;
float m_NormalizedTime;
float m_Length;
float m_Speed;
float m_SpeedMultiplier;
int32_t m_Tag;
int32_t m_Loop;
};
struct __declspec(align(8)) MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem__Fields {
struct List_1_System_Int32_* patterns;
struct AnimatorStateInfo stateInfo;
float lastTime;
};
struct MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem {
struct MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem__Class* klass;
MonitorData* monitor;
struct MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem__Fields fields;
};
enum class MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum : int32_t {
NormalTrigger = 0x00000000,
ForceTriggerOnEnter = 0x00000001,
ForceTriggerOnExitImediately = 0x00000002,
ForceTriggerOnExitTransition = 0x00000003,
ForceTriggerOnExitTransitionFinish = 0x00000004,
};
#if !defined(_GHIDRA_) && !defined(_IDA_) #if !defined(_GHIDRA_) && !defined(_IDA_)
} }
#endif #endif

View File

@ -55,6 +55,7 @@
#include <cheat/visuals/EnablePeeking.h> #include <cheat/visuals/EnablePeeking.h>
#include <cheat/visuals/TextureChanger.h> #include <cheat/visuals/TextureChanger.h>
#include <cheat/visuals/FreeCamera.h> #include <cheat/visuals/FreeCamera.h>
#include <cheat/visuals/AnimationChanger.h>
#include "GenshinCM.h" #include "GenshinCM.h"
@ -122,7 +123,8 @@ namespace cheat
FEAT_INST(Browser), FEAT_INST(Browser),
FEAT_INST(EnablePeeking), FEAT_INST(EnablePeeking),
FEAT_INST(TextureChanger), FEAT_INST(TextureChanger),
FEAT_INST(FreeCamera) FEAT_INST(FreeCamera),
FEAT_INST(AnimationChanger)
}); });
#undef FEAT_INST #undef FEAT_INST

View File

@ -21,17 +21,17 @@ namespace cheat::feature
ESP::ESP() : Feature(), ESP::ESP() : Feature(),
NF(f_Enabled, "ESP", "ESP", false), 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_DrawTracerMode, "Tracer Mode", "ESP", DrawTracerMode::Line),
NF(f_Fill, "Fill Box/Rectangle/Arrows", "ESP", false), NF(f_Fill, "Fill Box/Rectangle/Arrows", "ESP", false),
NF(f_FillTransparency, "Fill Transparency", "ESP", 0.5f), NF(f_FillTransparency, "Fill Transparency", "ESP", 0.5f),
NF(f_ArrowRadius, "Arrow Radius", "ESP", 100.0f), NF(f_ArrowRadius, "Arrow Radius", "ESP", 100.0f),
NF(f_OutlineThickness, "Outline Thickness", "ESP", 1.0f), NF(f_OutlineThickness, "Outline Thickness", "ESP", 1.0f),
NF(f_TracerSize, "Tracer Size", "ESP", 1.0f), NF(f_TracerSize, "Tracer Size", "ESP", 1.0f),
NF(f_MiddleScreenTracer, "Middle Screen Tracer", "ESP", false), NF(f_MiddleScreenTracer, "Middle Screen Tracer", "ESP", false),
NF(f_DrawDistance, "Draw Distance", "ESP", false), NF(f_DrawDistance, "Draw Distance", "ESP", false),
NF(f_DrawName, "Draw Name", "ESP", false), NF(f_DrawName, "Draw Name", "ESP", false),
NF(f_FontSize, "Font Size", "ESP", 12.0f), NF(f_FontSize, "Font Size", "ESP", 12.0f),
NF(f_FontOutline, "Font outline", "ESP", true), 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_DrawBoxMode, "Select the mode of box drawing.");
ConfigWidget(f_DrawTracerMode, "Select the mode of tracer drawing."); ConfigWidget(f_DrawTracerMode, "Select the mode of tracer drawing.");
ConfigWidget(f_Fill); ConfigWidget(f_Fill);
ConfigWidget(f_FillTransparency, 0.01f, 0.0f, 1.0f, "Transparency of filled part."); ConfigWidget(f_FillTransparency, 0.01f, 0.0f, 1.0f, "Transparency of filled part.");
ConfigWidget(f_MiddleScreenTracer, "Draw tracer from middle part of the screen."); ConfigWidget(f_MiddleScreenTracer, "Draw tracer from middle part of the screen.");
@ -84,7 +84,7 @@ namespace cheat::feature
} }
ImGui::EndGroupPanel(); ImGui::EndGroupPanel();
} }
ImGui::Spacing(); ImGui::Spacing();
ConfigWidget(f_DrawName, "Draw name of object."); ConfigWidget(f_DrawName, "Draw name of object.");
ConfigWidget(f_DrawDistance, "Draw distance 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 statement to determine how we will get name
switch (count) 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 if (name[i] == '_')
pos1 = 0;
pos2 = 0;
for (int i = 0; i < name.length(); i++)
{ {
if (name[i] == '_') j++;
if (j == 3)
{ {
j++; pos1 = i;
if (j == 3)
{
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; pos2 = i;
break; break;
} }
} }
name = name.substr(pos1, pos2 - pos1);
} }
case 4: name = name.substr(pos1 + 1, pos2 - pos1 - 1);
{ }
j = 0; // j is the number of spaces before the name starts default:
pos1 = 0; break;
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;
} }
return; return;
} }
@ -574,12 +574,16 @@ namespace cheat::feature
ADD_FILTER_FIELD(collection, WoodenCrate); ADD_FILTER_FIELD(collection, WoodenCrate);
ADD_FILTER_FIELD(collection, GeoSigil); ADD_FILTER_FIELD(collection, GeoSigil);
// Regular Chests
ADD_FILTER_FIELD(chest, CommonChest); ADD_FILTER_FIELD(chest, CommonChest);
ADD_FILTER_FIELD(chest, ExquisiteChest); ADD_FILTER_FIELD(chest, ExquisiteChest);
ADD_FILTER_FIELD(chest, PreciousChest); ADD_FILTER_FIELD(chest, PreciousChest);
ADD_FILTER_FIELD(chest, LuxuriousChest); ADD_FILTER_FIELD(chest, LuxuriousChest);
ADD_FILTER_FIELD(chest, RemarkableChest); ADD_FILTER_FIELD(chest, RemarkableChest);
// Other Chests
ADD_FILTER_FIELD(chest, BuriedChest);
ADD_FILTER_FIELD(chest, SearchPoint); ADD_FILTER_FIELD(chest, SearchPoint);
ADD_FILTER_FIELD(featured, Anemoculus); ADD_FILTER_FIELD(featured, Anemoculus);
ADD_FILTER_FIELD(featured, CrimsonAgate); ADD_FILTER_FIELD(featured, CrimsonAgate);

View File

@ -32,6 +32,7 @@ namespace cheat::game::filters
ChestFilter SFrozen = ChestFilter(Chest::ChestState::Frozen); ChestFilter SFrozen = ChestFilter(Chest::ChestState::Frozen);
ChestFilter SBramble = ChestFilter(Chest::ChestState::Bramble); ChestFilter SBramble = ChestFilter(Chest::ChestState::Bramble);
ChestFilter STrap = ChestFilter(Chest::ChestState::Trap); ChestFilter STrap = ChestFilter(Chest::ChestState::Trap);
SimpleFilter BuriedChest = { EntityType__Enum_1::Field, "_WorldArea_Operator" };
} }
namespace equipment namespace equipment
@ -111,7 +112,7 @@ namespace cheat::game::filters
SimpleFilter WeaselThief = { EntityType__Enum_1::Monster, "Thoarder_Weasel" }; SimpleFilter WeaselThief = { EntityType__Enum_1::Monster, "Thoarder_Weasel" };
SimpleFilter Kitsune = { EntityType__Enum_1::EnvAnimal, "Vulpes" }; SimpleFilter Kitsune = { EntityType__Enum_1::EnvAnimal, "Vulpes" };
SimpleFilter BakeDanuki = { EntityType__Enum_1::Monster, "Inu_Tanuki" }; 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 namespace mineral
@ -131,7 +132,7 @@ namespace cheat::game::filters
SimpleFilter DunlinsTooth = { EntityType__Enum_1::GatherObject, "_DunlinsTooth" }; SimpleFilter DunlinsTooth = { EntityType__Enum_1::GatherObject, "_DunlinsTooth" };
SimpleFilter AmethystLumpDrop = { EntityType__Enum_1::GatherObject, "_Thundercrystaldrop" }; 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 ElectroCrystalDrop = { EntityType__Enum_1::GatherObject, "_Drop_Ore_ElectricRock" };
SimpleFilter IronChunkDrop = { EntityType__Enum_1::GatherObject, "_Drop_Stone" }; SimpleFilter IronChunkDrop = { EntityType__Enum_1::GatherObject, "_Drop_Stone" };
SimpleFilter NoctilucousJadeDrop = { EntityType__Enum_1::GatherObject,"_NightBerth" }; SimpleFilter NoctilucousJadeDrop = { EntityType__Enum_1::GatherObject,"_NightBerth" };
@ -161,7 +162,7 @@ namespace cheat::game::filters
SimpleFilter RuinGrader = { EntityType__Enum_1::Monster, "_Konungmathr" }; SimpleFilter RuinGrader = { EntityType__Enum_1::Monster, "_Konungmathr" };
SimpleFilter RuinSentinel = { EntityType__Enum_1::Monster, "_Apparatus_Enigma" }; SimpleFilter RuinSentinel = { EntityType__Enum_1::Monster, "_Apparatus_Enigma" };
SimpleFilter Samachurl = { EntityType__Enum_1::Monster, "_Shaman" }; 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 Slime = { EntityType__Enum_1::Monster, "_Slime" };
SimpleFilter FloatingFungus = { EntityType__Enum_1::Monster, "Fungus_Un_" }; SimpleFilter FloatingFungus = { EntityType__Enum_1::Monster, "Fungus_Un_" };
SimpleFilter StretchyFungus = { EntityType__Enum_1::Monster, "Fungus_Deux_" }; 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 JadeplumeTerrorshroom = { EntityType__Enum_1::Monster, "Fungus_Raptor" };
SimpleFilter RishbolandTiger = { EntityType__Enum_1::Monster, "_Megamoth_" }; SimpleFilter RishbolandTiger = { EntityType__Enum_1::Monster, "_Megamoth_" };
SimpleFilter ShaggySumpterBeast = { EntityType__Enum_1::Monster, "_Panther" }; 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_" }; SimpleFilter SentryTurrets = { EntityType__Enum_1::Field, "SentryTurrets_" };
} }
@ -285,7 +286,7 @@ namespace cheat::game::filters
SimpleFilter AncientRime = { EntityType__Enum_1::Gadget, "_IceSolidBulk" }; SimpleFilter AncientRime = { EntityType__Enum_1::Gadget, "_IceSolidBulk" };
SimpleFilter BakeDanuki = { EntityType__Enum_1::Monster, "Animal_Inu_Tanuki_" }; SimpleFilter BakeDanuki = { EntityType__Enum_1::Monster, "Animal_Inu_Tanuki_" };
SimpleFilter BloattyFloatty = { EntityType__Enum_1::Field, "_Flower_PongPongTree_" }; 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 EightStoneTablets = { EntityType__Enum_1::Gadget, "_HistoryBoard" };
SimpleFilter ElectricConduction = { EntityType__Enum_1::Gear, "_ElectricPowerSource" }; SimpleFilter ElectricConduction = { EntityType__Enum_1::Gear, "_ElectricPowerSource" };
SimpleFilter RelayStone = { EntityType__Enum_1::Worktop, "_ElectricTransfer_" }; SimpleFilter RelayStone = { EntityType__Enum_1::Worktop, "_ElectricTransfer_" };
@ -346,6 +347,13 @@ namespace cheat::game::filters
mineral::Starsilver, mineral::Starsilver,
mineral::WhiteIronChunk mineral::WhiteIronChunk
}; };
SimpleFilter PlantDestroy = {
//plant::SakuraBloom,
plant::DandelionSeed,
plant::MistFlowerCorolla,
plant::FlamingFlowerStamen
};
WhitelistFilter Doodads = { WhitelistFilter Doodads = {
EntityType__Enum_1::Gadget, EntityType__Enum_1::Gadget,
{ {
@ -518,15 +526,15 @@ namespace cheat::game::filters
monster::Whopperflower monster::Whopperflower
}; };
SimpleFilter MonsterEquips = { EntityType__Enum_1::MonsterEquip }; SimpleFilter MonsterEquips = { EntityType__Enum_1::MonsterEquip };
BlacklistFilter Living = { BlacklistFilter Living = {
{EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster}, {EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster},
{ {
// Environmental mobs // Environmental mobs
"Cat", "DogPrick", "Vulpues", "Inu_Tanuki", "Cat", "DogPrick", "Vulpues", "Inu_Tanuki",
// Overworld bosses // Overworld bosses
"Ningyo", "Regisvine", "Hypostasis", "Planelurker", "Nithhoggr" "Ningyo", "Regisvine", "Hypostasis", "Planelurker", "Nithhoggr"
} }
}; };
SimpleFilter OrganicTargets = { Monsters, Animals }; // Solael: Please don't mess around with this filter. 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. //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" } }; //AdvancedFilter Animals = { {EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster }, {"Crane", "Tit", "Boar", "Squirrel", "Fox", "Pigeon", "Wigeon", "Falcon" ,"Marten" } };

View File

@ -32,6 +32,8 @@ namespace cheat::game::filters
extern ChestFilter SFrozen; extern ChestFilter SFrozen;
extern ChestFilter SBramble; extern ChestFilter SBramble;
extern ChestFilter STrap; extern ChestFilter STrap;
extern SimpleFilter BuriedChest;
} }
namespace equipment namespace equipment
@ -220,7 +222,7 @@ namespace cheat::game::filters
extern SimpleFilter Beisht; extern SimpleFilter Beisht;
extern SimpleFilter RishbolandTiger; extern SimpleFilter RishbolandTiger;
extern SimpleFilter ShaggySumpterBeast; extern SimpleFilter ShaggySumpterBeast;
extern SimpleFilter Spincrocodile; extern SimpleFilter Spincrocodile;
extern SimpleFilter SentryTurrets; extern SimpleFilter SentryTurrets;
} }
@ -325,6 +327,7 @@ namespace cheat::game::filters
extern SimpleFilter Oculies; extern SimpleFilter Oculies;
extern SimpleFilter Chests; extern SimpleFilter Chests;
extern SimpleFilter Ores; extern SimpleFilter Ores;
extern SimpleFilter PlantDestroy;
extern WhitelistFilter Doodads; extern WhitelistFilter Doodads;
extern SimpleFilter Animals; extern SimpleFilter Animals;
extern SimpleFilter AnimalDrop; extern SimpleFilter AnimalDrop;

View File

@ -563,13 +563,13 @@ namespace cheat::feature
std::lock_guard _userDataLock(m_UserDataMutex); std::lock_guard _userDataLock(m_UserDataMutex);
LOG_WARNING("Complete point at %.0f.", game::EntityManager::instance().avatar()->distance(pointData->levelPosition)); 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; return;
pointData->completed = true; pointData->completed = true;
pointData->completeTimestamp = util::GetCurrentTimeMillisec(); pointData->completeTimestamp = util::GetCurrentTimeMillisec();
m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount++; m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount++;
m_CompletedPoints.insert(pointData); m_CompletedPoints.push_back(pointData);
SaveCompletedPoints(); SaveCompletedPoints();
} }
@ -578,13 +578,14 @@ namespace cheat::feature
{ {
std::lock_guard _userDataLock(m_UserDataMutex); 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; return;
pointData->completed = false; pointData->completed = false;
pointData->completeTimestamp = 0; pointData->completeTimestamp = 0;
m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--; m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--;
m_CompletedPoints.erase(pointData); m_CompletedPoints.erase(pointDataIterator);
SaveCompletedPoints(); SaveCompletedPoints();
} }
@ -595,11 +596,12 @@ namespace cheat::feature
if (m_CompletedPoints.empty()) if (m_CompletedPoints.empty())
return; return;
PointData* pointData = *m_CompletedPoints.begin(); auto pointDataIterator = --m_CompletedPoints.end();
PointData* pointData = *pointDataIterator;
pointData->completed = false; pointData->completed = false;
pointData->completeTimestamp = 0; pointData->completeTimestamp = 0;
m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--; m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--;
m_CompletedPoints.erase(pointData); m_CompletedPoints.erase(pointDataIterator);
SaveCompletedPoints(); SaveCompletedPoints();
} }
@ -916,7 +918,7 @@ namespace cheat::feature
} }
auto& point = points[pointID]; 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); LOG_WARNING("Completed point %u duplicate.", pointID);
return; return;
@ -926,7 +928,7 @@ namespace cheat::feature
point.completeTimestamp = data["complete_timestamp"]; point.completeTimestamp = data["complete_timestamp"];
labelData->completedCount++; labelData->completedCount++;
m_CompletedPoints.insert(&point); m_CompletedPoints.push_back(&point);
} }
void InteractiveMap::LoadFixedPointData(LabelData* labelData, const nlohmann::json& data) void InteractiveMap::LoadFixedPointData(LabelData* labelData, const nlohmann::json& data)
@ -1026,6 +1028,7 @@ namespace cheat::feature
void InteractiveMap::LoadCompletedPoints() void InteractiveMap::LoadCompletedPoints()
{ {
LoadUserData(f_CompletedPointsJson, &InteractiveMap::LoadCompletedPointData); LoadUserData(f_CompletedPointsJson, &InteractiveMap::LoadCompletedPointData);
ReorderCompletedPointDataByTimestamp();
} }
void InteractiveMap::SaveCompletedPoints() void InteractiveMap::SaveCompletedPoints()
@ -1040,6 +1043,11 @@ namespace cheat::feature
m_CompletedPoints.clear(); m_CompletedPoints.clear();
} }
void InteractiveMap::ReorderCompletedPointDataByTimestamp()
{
m_CompletedPoints.sort([](PointData* a, PointData* b) { return a->completeTimestamp < b->completeTimestamp; });
}
void InteractiveMap::LoadCustomPoints() void InteractiveMap::LoadCustomPoints()
{ {
LoadUserData(f_CustomPointsJson, &InteractiveMap::LoadCustomPointData); LoadUserData(f_CustomPointsJson, &InteractiveMap::LoadCustomPointData);

View File

@ -146,7 +146,7 @@ namespace cheat::feature
std::unordered_set<PointData*> m_CustomPoints; std::unordered_set<PointData*> m_CustomPoints;
std::unordered_set<PointData*> m_FixedPoints; std::unordered_set<PointData*> m_FixedPoints;
std::unordered_set<PointData*> m_CompletedPoints; std::list<PointData*> m_CompletedPoints;
std::mutex m_PointMutex; std::mutex m_PointMutex;
// PointData* m_SelectedPoint; // PointData* m_SelectedPoint;
@ -182,6 +182,7 @@ namespace cheat::feature
void LoadCompletedPointData(LabelData* labelData, const nlohmann::json& data); void LoadCompletedPointData(LabelData* labelData, const nlohmann::json& data);
void SaveCompletedPointData(nlohmann::json& jObject, PointData* point); void SaveCompletedPointData(nlohmann::json& jObject, PointData* point);
bool ResetCompletedPointData(LabelData* label, PointData* point); bool ResetCompletedPointData(LabelData* label, PointData* point);
void ReorderCompletedPointDataByTimestamp();
void LoadCustomPointData(LabelData* labelData, const nlohmann::json& data); void LoadCustomPointData(LabelData* labelData, const nlohmann::json& data);
void SaveCustomPointData(nlohmann::json& jObject, PointData* point); void SaveCustomPointData(nlohmann::json& jObject, PointData* point);

View File

@ -203,7 +203,8 @@ namespace cheat::feature
for (auto entity : entities) { for (auto entity : entities) {
auto entityPos = entity->absolutePosition(); auto entityPos = entity->absolutePosition();
std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}"; std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}";
auto entityDetails = fmt::format(baseString, auto entityDetails = fmt::format(
fmt::runtime(baseString),
fmt::ptr(entity), fmt::ptr(entity),
entity->runtimeID(), entity->runtimeID(),
entity->name().c_str(), entity->name().c_str(),
@ -222,7 +223,8 @@ namespace cheat::feature
std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}"; std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}";
if (csvFriendly && includeHeaders) if (csvFriendly && includeHeaders)
baseString = headerString.append(baseString); baseString = headerString.append(baseString);
auto entityDetails = fmt::format(baseString, auto entityDetails = fmt::format(
fmt::runtime(baseString),
fmt::ptr(entity), fmt::ptr(entity),
entity->runtimeID(), entity->runtimeID(),
entity->name().c_str(), entity->name().c_str(),

View File

@ -6,41 +6,46 @@
#include <cheat/game/util.h> #include <cheat/game/util.h>
#include <cheat/game/filters.h> #include <cheat/game/filters.h>
namespace cheat::feature namespace cheat::feature
{ {
static void LCBaseCombat_DoHitEntity_Hook(app::LCBaseCombat* __this, uint32_t targetID, app::AttackResult* attackResult, static void LCBaseCombat_DoHitEntity_Hook(app::LCBaseCombat* __this, uint32_t targetID, app::AttackResult* attackResult,
bool ignoreCheckCanBeHitInMP, MethodInfo* method); 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(), RapidFire::RapidFire() : Feature(),
NF(f_Enabled, "Attack Multiplier", "RapidFire", false), NF(f_Enabled, "Attack Multiplier", "RapidFire", false),
NF(f_MultiHit, "Multi-hit", "RapidFire", false), NF(f_MultiHit, "Multi-hit", "RapidFire", false),
NF(f_Multiplier, "Hit Multiplier", "RapidFire", 2), NF(f_Multiplier, "Hit Multiplier", "RapidFire", 2),
NF(f_OnePunch, "One Punch Mode", "RapidFire", false), NF(f_OnePunch, "One Punch Mode", "RapidFire", false),
NF(f_Randomize, "Randomize", "RapidFire", false), NF(f_Randomize, "Randomize", "RapidFire", false),
NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1), NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1),
NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3), NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3),
NF(f_MultiTarget, "Multi-target", "RapidFire", false), NF(f_MultiTarget, "Multi-target", "RapidFire", false),
NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f) 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_LCBaseCombat_DoHitEntity, LCBaseCombat_DoHitEntity_Hook);
} HookManager::install(app::MoleMole_VCAnimatorEvent_HandleProcessItem, VCAnimatorEvent_HandleProcessItem_Hook);
}
const FeatureGUIInfo& RapidFire::GetGUIInfo() const const FeatureGUIInfo& RapidFire::GetGUIInfo() const
{ {
static const FeatureGUIInfo info{ "Attack Effects", "Player", true }; static const FeatureGUIInfo info{ "Attack Effects", "Player", true };
return info; return info;
} }
void RapidFire::DrawMain() void RapidFire::DrawMain()
{ {
ConfigWidget("Enabled", f_Enabled, "Enables attack multipliers. Need to choose a mode to work."); ConfigWidget("Enabled", f_Enabled, "Enables attack multipliers. Need to choose a mode to work.");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextColored(ImColor(255, 165, 0, 255), "Choose any or both modes below."); ImGui::TextColored(ImColor(255, 165, 0, 255), "Choose any or both modes below.");
ConfigWidget("Multi-hit Mode", f_MultiHit, "Enables multi-hit.\n" \ ConfigWidget("Multi-hit Mode", f_MultiHit, "Enables multi-hit.\n" \
"Multiplies your attack count.\n" \ "Multiplies your attack count.\n" \
"This is not well tested, and can be detected by anticheat.\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" \ "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."); "Known issues with certain multi-hit attacks, e.g. Xiao E, Ayaka CA, etc.");
ImGui::Indent(); 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" \ "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." "This can cause EXTREME lag and quick bans if used with multi-hit. You are warned."
); );
ImGui::Indent(); ImGui::Indent();
ConfigWidget("Radius (m)", f_MultiTargetRadius, 0.1f, 5.0f, 50.0f, "Radius to check for valid targets."); ConfigWidget("Radius (m)", f_MultiTargetRadius, 0.1f, 5.0f, 50.0f, "Radius to check for valid targets.");
ImGui::Unindent(); ImGui::Unindent();
}
bool RapidFire::NeedStatusDraw() const ConfigWidget("Multi-animation", f_MultiAnimation, "Enables multi-animation attacks.\n" \
{ "Do keep in mind that the character's audio will also be spammed.");
return f_Enabled && (f_MultiHit || f_MultiTarget); }
}
void RapidFire::DrawStatus() bool RapidFire::NeedStatusDraw() const
{ {
if (f_MultiHit) return f_Enabled && (f_MultiHit || f_MultiTarget || f_MultiAnimation);
}
void RapidFire::DrawStatus()
{
if (f_MultiHit)
{ {
if (f_Randomize) if (f_Randomize)
ImGui::Text("Multi-Hit Random[%d|%d]", f_minMultiplier.value(), f_maxMultiplier.value()); ImGui::Text("Multi-Hit Random[%d|%d]", f_minMultiplier.value(), f_maxMultiplier.value());
@ -97,20 +105,23 @@ namespace cheat::feature
} }
if (f_MultiTarget) if (f_MultiTarget)
ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value()); ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value());
}
RapidFire& RapidFire::GetInstance() if (f_MultiAnimation)
{ ImGui::Text("Multi-Animation");
static RapidFire instance; }
return instance;
} RapidFire& RapidFire::GetInstance()
{
static RapidFire instance;
return instance;
}
int RapidFire::CalcCountToKill(float attackDamage, uint32_t targetID) int RapidFire::CalcCountToKill(float attackDamage, uint32_t targetID)
{ {
if (attackDamage == 0) if (attackDamage == 0)
return f_Multiplier; return f_Multiplier;
auto& manager = game::EntityManager::instance(); auto& manager = game::EntityManager::instance();
auto targetEntity = manager.entity(targetID); auto targetEntity = manager.entity(targetID);
if (targetEntity == nullptr) if (targetEntity == nullptr)
@ -165,10 +176,10 @@ namespace cheat::feature
entity = game::Entity(app::MoleMole_GadgetEntity_GetOwnerEntity(reinterpret_cast<app::GadgetEntity*>(entity.raw()), nullptr)); entity = game::Entity(app::MoleMole_GadgetEntity_GetOwnerEntity(reinterpret_cast<app::GadgetEntity*>(entity.raw()), nullptr));
if (entity.runtimeID() == avatarID) if (entity.runtimeID() == avatarID)
return true; return true;
} }
return false; return false;
} }
bool IsAttackByAvatar(game::Entity& attacker) bool IsAttackByAvatar(game::Entity& attacker)
@ -183,6 +194,20 @@ namespace cheat::feature
return attackerID == avatarID || IsAvatarOwner(attacker); 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) bool IsValidByFilter(game::Entity* entity)
{ {
if (game::filters::combined::OrganicTargets.IsValid(entity) || if (game::filters::combined::OrganicTargets.IsValid(entity) ||
@ -192,7 +217,7 @@ namespace cheat::feature
game::filters::puzzle::LargeRockPile.IsValid(entity) || game::filters::puzzle::LargeRockPile.IsValid(entity) ||
game::filters::puzzle::SmallRockPile.IsValid(entity)) game::filters::puzzle::SmallRockPile.IsValid(entity))
return true; return true;
return false; return false;
} }
// Raises when any entity do hit event. // Raises when any entity do hit event.
@ -203,7 +228,7 @@ namespace cheat::feature
{ {
auto attacker = game::Entity(__this->fields._._._entity); auto attacker = game::Entity(__this->fields._._._entity);
RapidFire& rapidFire = RapidFire::GetInstance(); 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); return CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method);
auto& manager = game::EntityManager::instance(); auto& manager = game::EntityManager::instance();
@ -242,9 +267,25 @@ namespace cheat::feature
if (rapidFire.f_MultiHit) { if (rapidFire.f_MultiHit) {
int attackCount = rapidFire.GetAttackCount(__this, entity->runtimeID(), attackResult); int attackCount = rapidFire.GetAttackCount(__this, entity->runtimeID(), attackResult);
for (int i = 0; i < attackCount; i++) for (int i = 0; i < attackCount; i++)
CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, method); app::MoleMole_LCBaseCombat_FireBeingHitEvent(__this, entity->runtimeID(), attackResult, method);
} else CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, 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);
} }
} }

View File

@ -19,6 +19,7 @@ namespace cheat::feature
config::Field<int> f_maxMultiplier; config::Field<int> f_maxMultiplier;
config::Field<config::Toggle<Hotkey>> f_MultiTarget; config::Field<config::Toggle<Hotkey>> f_MultiTarget;
config::Field<float> f_MultiTargetRadius; config::Field<float> f_MultiTargetRadius;
config::Field<config::Toggle<Hotkey>> f_MultiAnimation;
static RapidFire& GetInstance(); static RapidFire& GetInstance();

View File

@ -17,10 +17,11 @@
namespace cheat::feature namespace cheat::feature
{ {
CustomTeleports::CustomTeleports() : Feature(), CustomTeleports::CustomTeleports() : Feature(),
NF(f_DebugMode, "Debug Mode", "CustomTeleports", false), // Soon to be added
NF(f_Enabled, "Custom Teleport", "CustomTeleports", false), NF(f_Enabled, "Custom Teleport", "CustomTeleports", false),
NF(f_Next, "Teleport Next", "CustomTeleports", Hotkey(VK_OEM_6)), NF(f_Next, "Teleport Next", "CustomTeleports", Hotkey(VK_OEM_6)),
NF(f_Previous, "Teleport Previous", "CustomTeleports", Hotkey(VK_OEM_4)), 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") dir(util::GetCurrentPath() / "teleports")
{ {
f_Next.value().PressedEvent += MY_METHOD_HANDLER(CustomTeleports::OnNext); 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)); 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) void CustomTeleports::OnTeleportKeyPressed(bool next)
{ {
if (!f_Enabled || selectedIndex < 0) if (!f_Enabled || selectedIndex < 0)
@ -138,13 +175,14 @@ namespace cheat::feature
else else
{ {
std::vector list(checkedIndices.begin(), checkedIndices.end()); std::vector list(checkedIndices.begin(), checkedIndices.end());
if (selectedIndex == list.back() ? next : selectedIndex == list.front()) if (next ? selectedIndex == list.back() : selectedIndex == list.front())
return; return;
auto index = std::distance(list.begin(), std::find(list.begin(), list.end(), selectedIndex)); 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)); selectedIndex = list.at(index + (next ? 1 : -1));
position = Teleports.at(selectedIndex).position;
} }
mapTeleport.TeleportTo(position); TeleportTo(position, this->f_Interpolate);
UpdateIndexName(); UpdateIndexName();
} }
@ -157,38 +195,28 @@ namespace cheat::feature
OnTeleportKeyPressed(true); 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() void CustomTeleports::UpdateIndexName()
{ {
std::string name(selectedIndex == -1 || checkedIndices.empty() ? "" : Teleports.at(selectedIndex).name);
// abbreviate teleport names that are too long // abbreviate teleport names that are too long
std::string name(selectedIndex == -1 || checkedIndices.empty() ? "" : Teleports.at(selectedIndex).name);
if (name.length() > 15) if (name.length() > 15)
{ {
std::string shortened; std::string shortened;
std::regex numsExp("[\\d]+"); std::regex numsExp("[\\d]+");
std::regex firstCharsExp("\\b[A-Za-z]"); std::regex firstCharsExp("\\b[A-Za-z]");
itr(firstCharsExp, name, shortened);
std::sregex_iterator wordItr(name.begin(), name.end(), firstCharsExp); itr(numsExp, name, shortened);
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++;
}
name = shortened; name = shortened;
} }
selectedIndexName = name; selectedIndexName = name;
@ -249,7 +277,9 @@ namespace cheat::feature
"3. You can now press Next or Previous Hotkey to Teleport through the Checklist\n" "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" "Initially it will teleport the player to the selection made\n"
"Note: Double click or click the arrow to open teleport details"); "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")) if (ImGui::Button("Delete Checked"))
{ {
@ -281,8 +311,8 @@ namespace cheat::feature
{ {
std::sort(Teleports.begin(), Teleports.end(), [](const auto &a, const auto &b) 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; }); { 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 = std::includes(checkedIndices.begin(), checkedIndices.end(), searchIndices.begin(), searchIndices.end()) && !searchIndices.empty();
bool allSearchChecked = checkedIndices.size() == searchIndices.size() && !searchIndices.empty(); bool allChecked = (checkedIndices.size() == Teleports.size() && !Teleports.empty()) || allSearchChecked;
ImGui::Checkbox("All", &allChecked); ImGui::Checkbox("All", &allChecked);
if (ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
{ {
@ -316,11 +346,10 @@ namespace cheat::feature
maxNameLength = Teleport.name.length(); maxNameLength = Teleport.name.length();
ImGui::BeginTable("Teleports", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_NoSavedSettings); ImGui::BeginTable("Teleports", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_NoSavedSettings);
ImGui::TableSetupColumn("#", ImGuiTableColumnFlags_WidthFixed, 20); 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("Name", ImGuiTableColumnFlags_WidthFixed, maxNameLength * 8 + 10);
ImGui::TableSetupColumn("Position"); ImGui::TableSetupColumn("Position");
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
ImGuiTreeNodeFlags nodeFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
for (const auto &[name, position, description] : Teleports) 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) bool checked = std::any_of(checkedIndices.begin(), checkedIndices.end(), [&index](const auto &i)
{ return i == index; }); { return i == index; });
bool selected = index == selectedIndex; bool selected = index == selectedIndex;
std::string stringIndex = std::to_string(index);
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%d", index); ImGui::Text("%d", index);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Checkbox(("##Index" + std::to_string(index)).c_str(), &checked); ImGui::Checkbox(("##Index" + stringIndex).c_str(), &checked);
if (ImGui::IsItemClicked(0)) if (ImGui::IsItemClicked(0))
{ {
if (checked) if (checked)
@ -352,37 +382,29 @@ namespace cheat::feature
} }
ImGui::SameLine(); 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(); TeleportTo(position, false);
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);
} }
ImGui::SameLine(); 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; selectedIndex = index;
selectedByClick = true; selectedByClick = true;
UpdateIndexName(); 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::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::Text("%s", name.c_str());
ImGui::PopStyleColor();
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
ImGui::BeginTooltip(); ImGui::BeginTooltip();

View File

@ -25,8 +25,9 @@ namespace cheat::feature
class CustomTeleports : public Feature class CustomTeleports : public Feature
{ {
public: public:
config::Field<config::Toggle<Hotkey>> f_DebugMode;
config::Field<config::Toggle<Hotkey>> f_Enabled; config::Field<config::Toggle<Hotkey>> f_Enabled;
config::Field<config::Toggle<Hotkey>> f_Interpolate;
config::Field<float> f_Speed;
config::Field<Hotkey> f_Next; config::Field<Hotkey> f_Next;
config::Field<Hotkey> f_Previous; config::Field<Hotkey> f_Previous;
static CustomTeleports& GetInstance(); static CustomTeleports& GetInstance();
@ -55,6 +56,7 @@ namespace cheat::feature
std::string selectedName; std::string selectedName;
std::string selectedIndexName; std::string selectedIndexName;
CustomTeleports(); CustomTeleports();
void TeleportTo(app::Vector3 position, bool interpolate);
void OnTeleportKeyPressed(bool next); void OnTeleportKeyPressed(bool next);
void OnPrevious(); void OnPrevious();
void OnNext(); void OnNext();

View File

@ -0,0 +1,301 @@
#include "pch-il2cpp.h"
#include "AnimationChanger.h"
#include <helpers.h>
#include <cheat/events.h>
#include <misc/cpp/imgui_stdlib.h>
#include <cheat/game/EntityManager.h>
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);
}
}

View File

@ -0,0 +1,27 @@
#pragma once
#include <cheat-base/cheat/Feature.h>
#include <cheat-base/config/config.h>
namespace cheat::feature
{
class AnimationChanger : public Feature
{
public:
config::Field<config::Toggle<Hotkey>> f_Enabled;
config::Field<std::string> f_Animation;
config::Field<Hotkey> f_ApplyKey;
config::Field<Hotkey> 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();
};
}

View File

@ -14,7 +14,9 @@ namespace cheat::feature
app::Component_1* Profirency = nullptr; 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<std::string, int> 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 PlayerModule_OnPlayerCookRsp(app::MoleMole_PlayerModule* __this, app::PlayerCookRsp* rsp, MethodInfo* method);
static void CookingQtePageContext_UpdateProficiency(app::CookingQtePageContext* __this, 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_Enabled, "Standart Cooking", "AutoCook", false),
NF(f_FastProficiency, "Fast Proficiency", "AutoCook", false), NF(f_FastProficiency, "Fast Proficiency", "AutoCook", false),
NF(f_CountField, "Count Item", "AutoCook", 1), 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_RequestPlayerCook, PlayerModule_RequestPlayerCook);
HookManager::install(app::MoleMole_PlayerModule_OnPlayerCookRsp, PlayerModule_OnPlayerCookRsp); HookManager::install(app::MoleMole_PlayerModule_OnPlayerCookRsp, PlayerModule_OnPlayerCookRsp);
@ -38,12 +40,24 @@ namespace cheat::feature
void AutoCook::DrawMain() void AutoCook::DrawMain()
{ {
ConfigWidget(f_Enabled, "Fast Cooking if the recipe has fast cooking open. \n" \ 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(f_FastProficiency, "Quickly prepare an unstudied recipe to the maximum possible.");
ConfigWidget("Count Item", f_CountField, 1, 1, 100, ConfigWidget("Count Item", f_CountField, 1, 1, 100,
"How much to cook at a time.\n" \ "How much to cook at a time.\n" \
"(For standard mode only.)"); "(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 bool AutoCook::NeedStatusDraw() const
@ -53,7 +67,10 @@ namespace cheat::feature
void AutoCook::DrawStatus() 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() AutoCook& AutoCook::GetInstance()
@ -82,9 +99,14 @@ namespace cheat::feature
if (autoCook.f_Enabled || autoCook.f_FastProficiency) if (autoCook.f_Enabled || autoCook.f_FastProficiency)
{ {
autoCook.CookFoodMaxNum = app::MoleMole_Config_CookRecipeExcelConfig_CheckCookFoodMaxNum(recipeId, nullptr); 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; count = autoCook.f_CountField;
if (autoCook.f_CountField > autoCook.CookFoodMaxNum) if (autoCook.f_CountField > autoCook.CookFoodMaxNum)
count = 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 RectTransform = app::GameObject_GetComponentByName(GameObject::Profirency, string_to_il2cppi("RectTransform"), nullptr);
auto TransformChild = app::Transform_GetChild(reinterpret_cast<app::Transform*>(RectTransform), 0, nullptr); auto TransformChild = app::Transform_GetChild(reinterpret_cast<app::Transform*>(RectTransform), 0, nullptr);
auto TextComponent = app::Component_1_GetComponent_1(reinterpret_cast<app::Component_1*>(TransformChild), string_to_il2cppi("Text"), nullptr); auto TextComponent = app::Component_1_GetComponent_1(reinterpret_cast<app::Component_1*>(TransformChild), string_to_il2cppi("Text"), nullptr);
if (TextComponent != nullptr) { if (TextComponent != nullptr) {
auto Text_str = app::Text_get_text(reinterpret_cast<app::Text*>(TextComponent), nullptr); auto Text_str = app::Text_get_text(reinterpret_cast<app::Text*>(TextComponent), nullptr);
auto ProficiencyStr = il2cppi_to_string(Text_str).erase(0, il2cppi_to_string(Text_str).find_first_of(" .")); 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(); AutoCook& autoCook = AutoCook::GetInstance();
if (autoCook.f_Enabled || autoCook.f_FastProficiency) 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; rsp->fields.cookCount_ = autoCook.f_CountField;
if (autoCook.f_FastProficiency) if (autoCook.f_FastProficiency)
rsp->fields.cookCount_ = 1; rsp->fields.cookCount_ = 1;
@ -137,7 +163,7 @@ namespace cheat::feature
return CALL_ORIGIN(PlayerModule_OnPlayerCookRsp, __this, rsp, method); return CALL_ORIGIN(PlayerModule_OnPlayerCookRsp, __this, rsp, method);
} }
static void CookingQtePageContext_UpdateProficiency(app::CookingQtePageContext* __this, MethodInfo* method) { static void CookingQtePageContext_UpdateProficiency(app::CookingQtePageContext* __this, MethodInfo* method) {
AutoCook& autoCook = AutoCook::GetInstance(); AutoCook& autoCook = AutoCook::GetInstance();
if (autoCook.f_Enabled || autoCook.f_FastProficiency) if (autoCook.f_Enabled || autoCook.f_FastProficiency)

View File

@ -12,10 +12,10 @@ namespace cheat::feature
config::Field<config::Toggle<Hotkey>> f_FastProficiency; config::Field<config::Toggle<Hotkey>> f_FastProficiency;
config::Field<int> f_CountField; config::Field<int> f_CountField;
config::Field<int> f_QualityField; config::Field<std::string> f_QualityField;
int CookFoodMaxNum; // Maximum quantity at a time int CookFoodMaxNum; // Maximum quantity at a time
int CookCount; int CookCount;
static AutoCook& GetInstance(); static AutoCook& GetInstance();
@ -26,7 +26,7 @@ namespace cheat::feature
void DrawStatus() override; void DrawStatus() override;
private: private:
AutoCook(); AutoCook();
}; };
} }

View File

@ -9,31 +9,32 @@
#include <cheat/game/EntityManager.h> #include <cheat/game/EntityManager.h>
#include <cheat/game/filters.h> #include <cheat/game/filters.h>
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); static void LCAbilityElement_ReduceModifierDurability_Hook(app::LCAbilityElement* __this, int32_t modifierDurabilityIndex, float reduceDurability, app::Nullable_1_Single_ deltaTime, MethodInfo* method);
AutoDestroy::AutoDestroy() : Feature(), AutoDestroy::AutoDestroy() : Feature(),
NF(f_Enabled, "Auto Destroy", "AutoDestroy", false), NF(f_Enabled, "Auto Destroy", "AutoDestroy", false),
NF(f_DestroyOres, "Destroy Ores", "AutoDestroy", false), NF(f_DestroyOres, "Destroy Ores", "AutoDestroy", false),
NF(f_DestroyShields, "Destroy Shields", "AutoDestroy", false), NF(f_DestroyShields, "Destroy Shields", "AutoDestroy", false),
NF(f_DestroyDoodads, "Destroy Doodads", "AutoDestroy", false), NF(f_DestroyDoodads, "Destroy Doodads", "AutoDestroy", false),
NF(f_Range, "Range", "AutoDestroy", 10.0f) NF(f_DestroyPlants, "Destroy Plants", "AutoDestroy", false),
{ NF(f_Range, "Range", "AutoDestroy", 10.0f)
{
HookManager::install(app::MoleMole_LCAbilityElement_ReduceModifierDurability, LCAbilityElement_ReduceModifierDurability_Hook); HookManager::install(app::MoleMole_LCAbilityElement_ReduceModifierDurability, LCAbilityElement_ReduceModifierDurability_Hook);
} }
const FeatureGUIInfo& AutoDestroy::GetGUIInfo() const const FeatureGUIInfo& AutoDestroy::GetGUIInfo() const
{ {
static const FeatureGUIInfo info { "Auto Destroy Objects", "World", true }; static const FeatureGUIInfo info{ "Auto Destroy Objects", "World", true };
return info; 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" 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."); "Not recommended for main accounts or used with high values.");
ConfigWidget("Enabled", f_Enabled, "Instantly destroys non-living objects within range."); ConfigWidget("Enabled", f_Enabled, "Instantly destroys non-living objects within range.");
ImGui::Indent(); ImGui::Indent();
ConfigWidget("Ores", f_DestroyOres, "Ores and variants, e.g. electro crystals, marrows, etc."); 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."); ConfigWidget("Doodads", f_DestroyDoodads, "Barrels, boxes, vases, etc.");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextColored(ImColor(255, 165, 0, 255), "Extremely risky!"); ImGui::TextColored(ImColor(255, 165, 0, 255), "Extremely risky!");
ConfigWidget("Plants", f_DestroyPlants, "Dandelion Seeds, Sakura Bloom, etc.");
ImGui::Unindent(); ImGui::Unindent();
ConfigWidget("Range (m)", f_Range, 0.1f, 1.0f, 15.0f); 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() void AutoDestroy::DrawStatus()
{ {
ImGui::Text("Destroy [%.01fm%s%s%s%s]", ImGui::Text("Destroy [%.01fm%s%s%s%s%s]",
f_Range.value(), f_Range.value(),
f_DestroyOres || f_DestroyShields || f_DestroyDoodads ? "|" : "", f_DestroyOres || f_DestroyShields || f_DestroyDoodads || f_DestroyPlants ? "|" : "",
f_DestroyOres ? "O" : "", f_DestroyOres ? "O" : "",
f_DestroyShields ? "S" : "", f_DestroyShields ? "S" : "",
f_DestroyDoodads ? "D" : ""); f_DestroyDoodads ? "D" : "",
} f_DestroyPlants ? "P" : "");
}
AutoDestroy& AutoDestroy::GetInstance() AutoDestroy& AutoDestroy::GetInstance()
{ {
static AutoDestroy instance; static AutoDestroy instance;
return instance; return instance;
} }
// Thanks to @RyujinZX // Thanks to @RyujinZX
// Every ore has ability element component // Every ore has ability element component
@ -79,17 +82,17 @@ namespace cheat::feature
auto& manager = game::EntityManager::instance(); auto& manager = game::EntityManager::instance();
auto& autoDestroy = AutoDestroy::GetInstance(); auto& autoDestroy = AutoDestroy::GetInstance();
auto entity = __this->fields._._._entity; auto entity = __this->fields._._._entity;
if (autoDestroy.f_Enabled && if (autoDestroy.f_Enabled &&
autoDestroy.f_Range > manager.avatar()->distance(entity) && autoDestroy.f_Range > manager.avatar()->distance(entity) &&
( (
(autoDestroy.f_DestroyOres && game::filters::combined::Ores.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))) || (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)) && ( (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::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::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 // This value always above any ore durability
reduceDurability = 1000; reduceDurability = 1000;

View File

@ -12,6 +12,7 @@ namespace cheat::feature
config::Field<config::Toggle<Hotkey>> f_DestroyOres; config::Field<config::Toggle<Hotkey>> f_DestroyOres;
config::Field<config::Toggle<Hotkey>> f_DestroyShields; config::Field<config::Toggle<Hotkey>> f_DestroyShields;
config::Field<config::Toggle<Hotkey>> f_DestroyDoodads; config::Field<config::Toggle<Hotkey>> f_DestroyDoodads;
config::Field<config::Toggle<Hotkey>> f_DestroyPlants;
config::Field<float> f_Range; config::Field<float> f_Range;
static AutoDestroy& GetInstance(); static AutoDestroy& GetInstance();

View File

@ -47,6 +47,7 @@ namespace cheat::feature
void FreezeEnemies::OnGameUpdate() void FreezeEnemies::OnGameUpdate()
{ {
auto& manager = game::EntityManager::instance(); auto& manager = game::EntityManager::instance();
static bool change = false;
for (const auto& monster : manager.entities(game::filters::combined::Monsters)) 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()); //LOG_DEBUG("%s", magic_enum::enum_name(constraints).data());
app::Rigidbody_set_constraints(rigidBody, app::RigidbodyConstraints__Enum::FreezeAll, nullptr); app::Rigidbody_set_constraints(rigidBody, app::RigidbodyConstraints__Enum::FreezeAll, nullptr);
app::Animator_set_speed(animator, 0.f, nullptr); app::Animator_set_speed(animator, 0.f, nullptr);
change = false;
} }
else else
{ {
app::Rigidbody_set_constraints(rigidBody, app::RigidbodyConstraints__Enum::FreezeRotation, nullptr); 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;
}
} }
} }
} }

View File

@ -127,7 +127,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>$(ProjectDir)include/;$(SolutionDir)cheat-base/src;$(SolutionDir)cheat-base/vendor/simpleIni/</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)include/;$(SolutionDir)cheat-base/src;$(SolutionDir)cheat-base/vendor/simpleIni/</AdditionalIncludeDirectories>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile> </ClCompile>