Merge branch 'master' of https://github.com/lunaticwhat/Akebi-GC
This commit is contained in:
commit
04a1a08d45
@ -1,46 +1,98 @@
|
||||
#include <pch.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/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_HotkeysEnabled, "Hotkeys Enabled", "General", true),
|
||||
NF(f_FontSize, "Font size", "General", 16.0f),
|
||||
NF(f_ShowStyleEditor, "Show Style Editor", "General", false),
|
||||
|
||||
|
||||
NF(f_StatusMove, "Move Status Window", "General::StatusWindow", true),
|
||||
NF(f_StatusShow, "Show Status Window", "General::StatusWindow", true),
|
||||
|
||||
NF(f_InfoMove, "Move Info Window", "General::InfoWindow", true),
|
||||
NF(f_InfoShow, "Show Info Window", "General::InfoWindow", true),
|
||||
|
||||
|
||||
NF(f_InfoMove, "Move Info Window", "General::InfoWindow", true),
|
||||
NF(f_InfoShow, "Show Info Window", "General::InfoWindow", true),
|
||||
|
||||
NF(f_FpsMove, "Move FPS Indicator", "General::FPS", false),
|
||||
NF(f_FpsShow, "Show FPS Indicator", "General::FPS", true),
|
||||
|
||||
NF(f_NotificationsShow, "Show Notifications", "General::Notify", true),
|
||||
NF(f_NotificationsShow, "Show Notifications", "General::Notify", true),
|
||||
NF(f_NotificationsDelay, "Notifications Delay", "General::Notify", 500),
|
||||
|
||||
NF(f_FileLogging, "File Logging", "General::Logging", false),
|
||||
|
||||
NF(f_FileLogging, "File Logging", "General::Logging", false),
|
||||
NF(f_ConsoleLogging, "Console Logging", "General::Logging", true),
|
||||
|
||||
NF(f_FastExitEnable, "Fast Exit", "General::FastExit", false),
|
||||
NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12))
|
||||
NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12)),
|
||||
|
||||
{
|
||||
NF(f_FontSize, "Font Size", "General", 16.0f),
|
||||
NF(f_ShowStyleEditor, "Show Colors Customization", "General", false),
|
||||
NFS(f_DefaultTheme, "Theme", "General::Colors", "Default"),
|
||||
themesDir(util::GetCurrentPath() / "themes")
|
||||
|
||||
{
|
||||
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
|
||||
f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed);
|
||||
}
|
||||
if (!std::filesystem::exists(themesDir))
|
||||
std::filesystem::create_directory(themesDir);
|
||||
|
||||
const FeatureGUIInfo& Settings::GetGUIInfo() const
|
||||
{
|
||||
static const FeatureGUIInfo info{ "", "Settings", false };
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
bool inited = false;
|
||||
void Settings::Init() {
|
||||
if (this->f_DefaultTheme.value() != "Default" && !inited)
|
||||
{
|
||||
LOG_INFO("Loading theme: %s", themesDir / (f_DefaultTheme.value() + ".json").c_str());
|
||||
if (!std::filesystem::exists(themesDir / (f_DefaultTheme.value() + ".json")))
|
||||
f_DefaultTheme = "Default";
|
||||
else Colors_Import(f_DefaultTheme.value());
|
||||
inited = true;
|
||||
}
|
||||
}
|
||||
|
||||
const FeatureGUIInfo& Settings::GetGUIInfo() const
|
||||
{
|
||||
static const FeatureGUIInfo info{ "", "Settings", false };
|
||||
return info;
|
||||
}
|
||||
|
||||
void Settings::Colors_Export(std::string name)
|
||||
{
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
auto colors = style.Colors;
|
||||
|
||||
nlohmann::json json;
|
||||
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
||||
json[ImGui::GetStyleColorName((ImGuiCol)i)] = { colors[i].x, colors[i].y, colors[i].z, colors[i].w };
|
||||
std::ofstream file(themesDir / (name + ".json"));
|
||||
file << std::setw(4) << json << std::endl;
|
||||
}
|
||||
|
||||
void Settings::Colors_Import(std::string name)
|
||||
{
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
auto colors = style.Colors;
|
||||
nlohmann::json json;
|
||||
std::ifstream file(themesDir / (name + ".json"));
|
||||
file >> json;
|
||||
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
||||
{
|
||||
auto color = json[ImGui::GetStyleColorName((ImGuiCol)i)];
|
||||
colors[i].x = color[0];
|
||||
colors[i].y = color[1];
|
||||
colors[i].z = color[2];
|
||||
colors[i].w = color[3];
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::DrawMain()
|
||||
{
|
||||
@ -51,13 +103,7 @@ namespace cheat::feature
|
||||
"Key to toggle main menu visibility. Cannot be empty.\n"\
|
||||
"If you forget this key, you can see or set it in your config file.");
|
||||
ConfigWidget(f_HotkeysEnabled, "Enable hotkeys.");
|
||||
if (ConfigWidget(f_FontSize, 1, 8, 64, "Font size for cheat interface."))
|
||||
{
|
||||
f_FontSize = std::clamp(f_FontSize.value(), 8, 64);
|
||||
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
|
||||
}
|
||||
ConfigWidget(f_ShowStyleEditor, "Show interface style editor window.");
|
||||
}
|
||||
}
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
ImGui::BeginGroupPanel("Logging");
|
||||
@ -103,7 +149,7 @@ namespace cheat::feature
|
||||
ImGui::BeginGroupPanel("Show Notifications");
|
||||
{
|
||||
ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed.");
|
||||
ConfigWidget(f_NotificationsDelay, 1,1,10000, "Delay in milliseconds between notifications.");
|
||||
ConfigWidget(f_NotificationsDelay, 1, 1, 10000, "Delay in milliseconds between notifications.");
|
||||
}
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
@ -111,7 +157,7 @@ namespace cheat::feature
|
||||
{
|
||||
ConfigWidget("Enabled",
|
||||
f_FastExitEnable,
|
||||
"Enable Fast Exit.\n"
|
||||
"Enable Fast Exit.\n"
|
||||
);
|
||||
if (!f_FastExitEnable)
|
||||
ImGui::BeginDisabled();
|
||||
@ -123,13 +169,54 @@ namespace cheat::feature
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
ImGui::BeginGroupPanel("Interface Customization");
|
||||
{
|
||||
if (ConfigWidget(f_FontSize, 1, 8, 64, "Adjust interface font size."))
|
||||
{
|
||||
f_FontSize = std::clamp(f_FontSize.value(), 8, 64);
|
||||
renderer::SetGlobalFontSize(static_cast<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()
|
||||
{
|
||||
static Settings instance;
|
||||
return instance;
|
||||
}
|
||||
Settings& Settings::GetInstance()
|
||||
{
|
||||
static Settings instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Settings::OnExitKeyPressed()
|
||||
{
|
||||
@ -139,4 +226,3 @@ namespace cheat::feature
|
||||
ExitProcess(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,26 +2,24 @@
|
||||
#include <cheat-base/cheat/Feature.h>
|
||||
#include <cheat-base/config/config.h>
|
||||
|
||||
namespace cheat::feature
|
||||
namespace cheat::feature
|
||||
{
|
||||
|
||||
class Settings : public Feature
|
||||
{
|
||||
{
|
||||
public:
|
||||
config::Field<Hotkey> f_MenuKey;
|
||||
config::Field<bool> f_HotkeysEnabled;
|
||||
config::Field<int> f_FontSize;
|
||||
config::Field<bool> f_ShowStyleEditor;
|
||||
|
||||
config::Field<bool> f_StatusMove;
|
||||
config::Field<bool> f_StatusShow;
|
||||
|
||||
config::Field<bool> f_InfoMove;
|
||||
config::Field<bool> f_InfoShow;
|
||||
|
||||
|
||||
config::Field<bool> f_FpsShow;
|
||||
config::Field<bool> f_FpsMove;
|
||||
|
||||
|
||||
config::Field<bool> f_NotificationsShow;
|
||||
config::Field<int> f_NotificationsDelay;
|
||||
|
||||
@ -31,11 +29,20 @@ namespace cheat::feature
|
||||
config::Field<bool> f_FastExitEnable;
|
||||
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();
|
||||
|
||||
const FeatureGUIInfo& GetGUIInfo() const override;
|
||||
void DrawMain() override;
|
||||
|
||||
void Init();
|
||||
void Colors_Export(std::string name);
|
||||
void Colors_Import(std::string name);
|
||||
|
||||
private:
|
||||
|
||||
void OnExitKeyPressed();
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <cheat-base/render/backend/dx12-hook.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);
|
||||
|
||||
@ -33,14 +34,14 @@ namespace renderer
|
||||
static constexpr int _fontsCount = _fontSizeMax / _fontSizeStep;
|
||||
static std::array<ImFont*, _fontsCount> _fonts;
|
||||
|
||||
static Data _customFontData {};
|
||||
static Data _customFontData{};
|
||||
|
||||
static WNDPROC OriginalWndProcHandler;
|
||||
static ID3D11RenderTargetView* mainRenderTargetView;
|
||||
|
||||
static void OnRenderDX11(ID3D11DeviceContext* pContext);
|
||||
static void OnInitializeDX11(HWND window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain* pChain);
|
||||
|
||||
|
||||
static void OnPreRenderDX12();
|
||||
static void OnPostRenderDX12(ID3D12GraphicsCommandList* commandList);
|
||||
static void OnInitializeDX12(HWND window, ID3D12Device* pDevice, UINT buffersCounts, ID3D12DescriptorHeap* pDescriptorHeapImGuiRender);
|
||||
@ -106,7 +107,7 @@ namespace renderer
|
||||
return io.FontDefault;
|
||||
}
|
||||
int fontSizeInt = static_cast<int>(fontSize);
|
||||
int fontIndex = fontSizeInt / _fontSizeStep +
|
||||
int fontIndex = fontSizeInt / _fontSizeStep +
|
||||
(fontSizeInt % _fontSizeStep > (_fontSizeStep / 2) ? 1 : 0) - 1;
|
||||
fontIndex = std::clamp(fontIndex, 0, _fontsCount - 1);
|
||||
return _fonts[fontIndex];
|
||||
@ -122,7 +123,7 @@ namespace renderer
|
||||
|
||||
int fontSizeInt = static_cast<int>(fontSize);
|
||||
int fontIndex = fontSizeInt / _fontSizeStep;
|
||||
int fontAligned = fontIndex * _fontSizeStep +
|
||||
int fontAligned = fontIndex * _fontSizeStep +
|
||||
((fontSizeInt % _fontSizeStep) > _fontSizeStep / 2 ? _fontSizeStep : 0);
|
||||
fontAligned = std::clamp(fontAligned, _fontSizeStep, _fontSizeMax);
|
||||
|
||||
@ -138,7 +139,7 @@ namespace renderer
|
||||
{
|
||||
return _globalFontSize;
|
||||
}
|
||||
|
||||
|
||||
static void LoadCustomFont()
|
||||
{
|
||||
if (_customFontData.data == nullptr)
|
||||
@ -195,7 +196,7 @@ namespace renderer
|
||||
reinterpret_cast<LONG_PTR>(hWndProc)));
|
||||
|
||||
ImGui_ImplWin32_Init(window);
|
||||
ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
pDescriptorHeapImGuiRender,
|
||||
pDescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(),
|
||||
pDescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart());
|
||||
@ -253,6 +254,9 @@ namespace renderer
|
||||
|
||||
pContext->OMSetRenderTargets(1, &mainRenderTargetView, nullptr);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
auto& themes = cheat::feature::Settings::GetInstance();
|
||||
themes.Init();
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
|
@ -21,6 +21,7 @@
|
||||
<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\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\FreeCamera.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\PipeIO.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\FreeCamera.cpp" />
|
||||
<ClCompile Include="src\user\cheat\world\AutoSeelie.cpp" />
|
||||
@ -219,6 +221,7 @@
|
||||
<Image Include="res\iconsHD\Andrius.png" />
|
||||
<Image Include="res\iconsHD\Azhdaha.png" />
|
||||
<Image Include="res\iconsHD\Boar.png" />
|
||||
<Image Include="res\iconsHD\BookPage.png" />
|
||||
<Image Include="res\iconsHD\Cat.png" />
|
||||
<Image Include="res\iconsHD\Cicin.png" />
|
||||
<Image Include="res\iconsHD\Crane.png" />
|
||||
@ -557,6 +560,7 @@
|
||||
<Image Include="res\icons\Andrius.png" />
|
||||
<Image Include="res\icons\Azhdaha.png" />
|
||||
<Image Include="res\icons\Boar.png" />
|
||||
<Image Include="res\icons\BookPage.png" />
|
||||
<Image Include="res\icons\Cat.png" />
|
||||
<Image Include="res\icons\Cicin.png" />
|
||||
<Image Include="res\icons\Crane.png" />
|
||||
@ -1010,7 +1014,7 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<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>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
|
@ -252,6 +252,9 @@
|
||||
<ClInclude Include="src\user\cheat\world\CustomWeather.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\user\cheat\visuals\AnimationChanger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Font Include="res\Ruda-Bold.ttf" />
|
||||
@ -462,6 +465,9 @@
|
||||
<ClCompile Include="src\user\cheat\world\CustomWeather.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\user\cheat\visuals\AnimationChanger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="res\res.rc">
|
||||
@ -2508,5 +2514,11 @@
|
||||
<Image Include="res\icons\Spincrocodile.png">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="res\iconsHD\BookPage.png">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="res\icons\BookPage.png">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
BIN
cheat-library/res/icons/BookPage.png
Normal file
BIN
cheat-library/res/icons/BookPage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
cheat-library/res/iconsHD/BookPage.png
Normal file
BIN
cheat-library/res/iconsHD/BookPage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
@ -25,21 +25,21 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
@ -140,6 +140,8 @@ HDBOAR PNG "iconsHD\\Boar.png"
|
||||
|
||||
HDBOOK PNG "iconsHD\\Book.png"
|
||||
|
||||
HDBOOKPAGE PNG "iconsHD\\BookPage.png"
|
||||
|
||||
HDBOOTWEASEL PNG "iconsHD\\BootWeasel.png"
|
||||
|
||||
HDBRIGHTCROWNPIGEON PNG "iconsHD\\BrightcrownPigeon.png"
|
||||
@ -316,6 +318,8 @@ HDGEOGRANUM PNG "iconsHD\\Geogranum.png"
|
||||
|
||||
HDGEOHYPOSTASIS PNG "iconsHD\\GeoHypostasis.png"
|
||||
|
||||
HDGEOPUZZLE PNG "iconsHD\\MiniPuzzle.png"
|
||||
|
||||
HDGEOSIGIL PNG "iconsHD\\GeoSigil.png"
|
||||
|
||||
HDGEOVISHAP PNG "iconsHD\\Geovishap.png"
|
||||
@ -626,7 +630,7 @@ HDSHOGUN PNG "iconsHD\\Shogun.png"
|
||||
|
||||
HDSHOGUNATEINFANTRY PNG "iconsHD\\ShogunateInfantry.png"
|
||||
|
||||
HDSHRINEOFDEPTH PNG "iconsHD\\ShrineOfDepth.png"
|
||||
HDSHRINEOFDEPTH PNG "iconsHD\\Mondstadt.png"
|
||||
|
||||
HDSIGNORA PNG "iconsHD\\Signora.png"
|
||||
|
||||
@ -850,6 +854,8 @@ BOAR PNG "icons\\Boar.png"
|
||||
|
||||
BOOK PNG "icons\\Book.png"
|
||||
|
||||
BOOKPAGE PNG "icons\\BookPage.png"
|
||||
|
||||
BOOTWEASEL PNG "icons\\BootWeasel.png"
|
||||
|
||||
BRIGHTCROWNPIGEON PNG "icons\\BrightcrownPigeon.png"
|
||||
@ -1026,6 +1032,8 @@ GEOGRANUM PNG "icons\\Geogranum.png"
|
||||
|
||||
GEOHYPOSTASIS PNG "icons\\GeoHypostasis.png"
|
||||
|
||||
GEOPUZZLE PNG "icons\\MiniPuzzle.png"
|
||||
|
||||
GEOSIGIL PNG "icons\\GeoSigil.png"
|
||||
|
||||
GEOVISHAP PNG "icons\\Geovishap.png"
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <cheat/visuals/EnablePeeking.h>
|
||||
#include <cheat/visuals/TextureChanger.h>
|
||||
#include <cheat/visuals/FreeCamera.h>
|
||||
#include <cheat/visuals/AnimationChanger.h>
|
||||
|
||||
#include "GenshinCM.h"
|
||||
|
||||
@ -122,7 +123,8 @@ namespace cheat
|
||||
FEAT_INST(Browser),
|
||||
FEAT_INST(EnablePeeking),
|
||||
FEAT_INST(TextureChanger),
|
||||
FEAT_INST(FreeCamera)
|
||||
FEAT_INST(FreeCamera),
|
||||
FEAT_INST(AnimationChanger)
|
||||
|
||||
});
|
||||
#undef FEAT_INST
|
||||
|
@ -21,17 +21,17 @@ namespace cheat::feature
|
||||
ESP::ESP() : Feature(),
|
||||
NF(f_Enabled, "ESP", "ESP", false),
|
||||
|
||||
NF(f_DrawBoxMode, "Draw Mode", "ESP", DrawMode::Box),
|
||||
NF(f_DrawBoxMode, "Draw Mode", "ESP", DrawMode::Box),
|
||||
NF(f_DrawTracerMode, "Tracer Mode", "ESP", DrawTracerMode::Line),
|
||||
NF(f_Fill, "Fill Box/Rectangle/Arrows", "ESP", false),
|
||||
NF(f_FillTransparency, "Fill Transparency", "ESP", 0.5f),
|
||||
NF(f_Fill, "Fill Box/Rectangle/Arrows", "ESP", false),
|
||||
NF(f_FillTransparency, "Fill Transparency", "ESP", 0.5f),
|
||||
|
||||
NF(f_ArrowRadius, "Arrow Radius", "ESP", 100.0f),
|
||||
NF(f_OutlineThickness, "Outline Thickness", "ESP", 1.0f),
|
||||
NF(f_TracerSize, "Tracer Size", "ESP", 1.0f),
|
||||
NF(f_MiddleScreenTracer, "Middle Screen Tracer", "ESP", false),
|
||||
NF(f_DrawDistance, "Draw Distance", "ESP", false),
|
||||
NF(f_DrawName, "Draw Name", "ESP", false),
|
||||
NF(f_DrawDistance, "Draw Distance", "ESP", false),
|
||||
NF(f_DrawName, "Draw Name", "ESP", false),
|
||||
|
||||
NF(f_FontSize, "Font Size", "ESP", 12.0f),
|
||||
NF(f_FontOutline, "Font outline", "ESP", true),
|
||||
@ -69,7 +69,7 @@ namespace cheat::feature
|
||||
|
||||
ConfigWidget(f_DrawBoxMode, "Select the mode of box drawing.");
|
||||
ConfigWidget(f_DrawTracerMode, "Select the mode of tracer drawing.");
|
||||
|
||||
|
||||
ConfigWidget(f_Fill);
|
||||
ConfigWidget(f_FillTransparency, 0.01f, 0.0f, 1.0f, "Transparency of filled part.");
|
||||
ConfigWidget(f_MiddleScreenTracer, "Draw tracer from middle part of the screen.");
|
||||
@ -84,7 +84,7 @@ namespace cheat::feature
|
||||
}
|
||||
ImGui::EndGroupPanel();
|
||||
}
|
||||
|
||||
|
||||
ImGui::Spacing();
|
||||
ConfigWidget(f_DrawName, "Draw name of object.");
|
||||
ConfigWidget(f_DrawDistance, "Draw distance of object.");
|
||||
@ -189,55 +189,55 @@ namespace cheat::feature
|
||||
//switch statement to determine how we will get name
|
||||
switch (count)
|
||||
{
|
||||
case 3:
|
||||
case 3:
|
||||
{
|
||||
j = 0; // j is the number of spaces before the name starts
|
||||
pos1 = 0;
|
||||
pos2 = 0;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
{
|
||||
j = 0; // j is the number of spaces before the name starts
|
||||
pos1 = 0;
|
||||
pos2 = 0;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
if (name[i] == '_')
|
||||
{
|
||||
if (name[i] == '_')
|
||||
j++;
|
||||
if (j == 3)
|
||||
{
|
||||
j++;
|
||||
if (j == 3)
|
||||
{
|
||||
pos1 = i;
|
||||
}
|
||||
|
||||
pos1 = i;
|
||||
}
|
||||
if (name[i] == '(')
|
||||
|
||||
}
|
||||
if (name[i] == '(')
|
||||
{
|
||||
pos2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
name = name.substr(pos1, pos2 - pos1);
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
j = 0; // j is the number of spaces before the name starts
|
||||
pos1 = 0;
|
||||
pos2 = 0;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
{
|
||||
if (name[i] == '_')
|
||||
{
|
||||
j++;
|
||||
if (j == 3)
|
||||
{
|
||||
pos1 = i;
|
||||
}
|
||||
if (j == 4)
|
||||
{
|
||||
pos2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
name = name.substr(pos1, pos2 - pos1);
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
j = 0; // j is the number of spaces before the name starts
|
||||
pos1 = 0;
|
||||
pos2 = 0;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
{
|
||||
if (name[i] == '_')
|
||||
{
|
||||
j++;
|
||||
if (j == 3)
|
||||
{
|
||||
pos1 = i;
|
||||
}
|
||||
if (j == 4)
|
||||
{
|
||||
pos2 = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
name = name.substr(pos1 + 1, pos2 - pos1 - 1);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
name = name.substr(pos1 + 1, pos2 - pos1 - 1);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -574,12 +574,16 @@ namespace cheat::feature
|
||||
ADD_FILTER_FIELD(collection, WoodenCrate);
|
||||
ADD_FILTER_FIELD(collection, GeoSigil);
|
||||
|
||||
// Regular Chests
|
||||
ADD_FILTER_FIELD(chest, CommonChest);
|
||||
ADD_FILTER_FIELD(chest, ExquisiteChest);
|
||||
ADD_FILTER_FIELD(chest, PreciousChest);
|
||||
ADD_FILTER_FIELD(chest, LuxuriousChest);
|
||||
ADD_FILTER_FIELD(chest, RemarkableChest);
|
||||
// Other Chests
|
||||
ADD_FILTER_FIELD(chest, BuriedChest);
|
||||
ADD_FILTER_FIELD(chest, SearchPoint);
|
||||
|
||||
|
||||
ADD_FILTER_FIELD(featured, Anemoculus);
|
||||
ADD_FILTER_FIELD(featured, CrimsonAgate);
|
||||
|
@ -32,6 +32,7 @@ namespace cheat::game::filters
|
||||
ChestFilter SFrozen = ChestFilter(Chest::ChestState::Frozen);
|
||||
ChestFilter SBramble = ChestFilter(Chest::ChestState::Bramble);
|
||||
ChestFilter STrap = ChestFilter(Chest::ChestState::Trap);
|
||||
SimpleFilter BuriedChest = { EntityType__Enum_1::Field, "_WorldArea_Operator" };
|
||||
}
|
||||
|
||||
namespace equipment
|
||||
@ -111,7 +112,7 @@ namespace cheat::game::filters
|
||||
SimpleFilter WeaselThief = { EntityType__Enum_1::Monster, "Thoarder_Weasel" };
|
||||
SimpleFilter Kitsune = { EntityType__Enum_1::EnvAnimal, "Vulpes" };
|
||||
SimpleFilter BakeDanuki = { EntityType__Enum_1::Monster, "Inu_Tanuki" };
|
||||
SimpleFilter Meat = { EntityType__Enum_1::GatherObject , { "_Food_BirdMeat", "_Food_Meat", "_Fishmeat" }};
|
||||
SimpleFilter Meat = { EntityType__Enum_1::GatherObject , { "_Food_BirdMeat", "_Food_Meat", "_Fishmeat" } };
|
||||
}
|
||||
|
||||
namespace mineral
|
||||
@ -131,7 +132,7 @@ namespace cheat::game::filters
|
||||
SimpleFilter DunlinsTooth = { EntityType__Enum_1::GatherObject, "_DunlinsTooth" };
|
||||
|
||||
SimpleFilter AmethystLumpDrop = { EntityType__Enum_1::GatherObject, "_Thundercrystaldrop" };
|
||||
SimpleFilter CrystalChunkDrop = { EntityType__Enum_1::GatherObject,"_Drop_Crystal"};
|
||||
SimpleFilter CrystalChunkDrop = { EntityType__Enum_1::GatherObject,"_Drop_Crystal" };
|
||||
SimpleFilter ElectroCrystalDrop = { EntityType__Enum_1::GatherObject, "_Drop_Ore_ElectricRock" };
|
||||
SimpleFilter IronChunkDrop = { EntityType__Enum_1::GatherObject, "_Drop_Stone" };
|
||||
SimpleFilter NoctilucousJadeDrop = { EntityType__Enum_1::GatherObject,"_NightBerth" };
|
||||
@ -161,7 +162,7 @@ namespace cheat::game::filters
|
||||
SimpleFilter RuinGrader = { EntityType__Enum_1::Monster, "_Konungmathr" };
|
||||
SimpleFilter RuinSentinel = { EntityType__Enum_1::Monster, "_Apparatus_Enigma" };
|
||||
SimpleFilter Samachurl = { EntityType__Enum_1::Monster, "_Shaman" };
|
||||
SimpleFilter ShadowyHusk = { EntityType__Enum_1::Monster, "ForlornVessel_Strong" };
|
||||
SimpleFilter ShadowyHusk = { EntityType__Enum_1::Monster, "ForlornVessel_Strong" };
|
||||
SimpleFilter Slime = { EntityType__Enum_1::Monster, "_Slime" };
|
||||
SimpleFilter FloatingFungus = { EntityType__Enum_1::Monster, "Fungus_Un_" };
|
||||
SimpleFilter StretchyFungus = { EntityType__Enum_1::Monster, "Fungus_Deux_" };
|
||||
@ -221,7 +222,7 @@ namespace cheat::game::filters
|
||||
SimpleFilter JadeplumeTerrorshroom = { EntityType__Enum_1::Monster, "Fungus_Raptor" };
|
||||
SimpleFilter RishbolandTiger = { EntityType__Enum_1::Monster, "_Megamoth_" };
|
||||
SimpleFilter ShaggySumpterBeast = { EntityType__Enum_1::Monster, "_Panther" };
|
||||
SimpleFilter Spincrocodile = { EntityType__Enum_1::Monster, "_Gator" };
|
||||
SimpleFilter Spincrocodile = { EntityType__Enum_1::Monster, "_Gator" };
|
||||
SimpleFilter SentryTurrets = { EntityType__Enum_1::Field, "SentryTurrets_" };
|
||||
}
|
||||
|
||||
@ -285,7 +286,7 @@ namespace cheat::game::filters
|
||||
SimpleFilter AncientRime = { EntityType__Enum_1::Gadget, "_IceSolidBulk" };
|
||||
SimpleFilter BakeDanuki = { EntityType__Enum_1::Monster, "Animal_Inu_Tanuki_" };
|
||||
SimpleFilter BloattyFloatty = { EntityType__Enum_1::Field, "_Flower_PongPongTree_" };
|
||||
WhitelistFilter CubeDevices = { {EntityType__Enum_1::Gadget, EntityType__Enum_1::Platform }, {"_ElecStone", "_ElecSwitch" }};
|
||||
WhitelistFilter CubeDevices = { {EntityType__Enum_1::Gadget, EntityType__Enum_1::Platform }, {"_ElecStone", "_ElecSwitch" } };
|
||||
SimpleFilter EightStoneTablets = { EntityType__Enum_1::Gadget, "_HistoryBoard" };
|
||||
SimpleFilter ElectricConduction = { EntityType__Enum_1::Gear, "_ElectricPowerSource" };
|
||||
SimpleFilter RelayStone = { EntityType__Enum_1::Worktop, "_ElectricTransfer_" };
|
||||
@ -346,6 +347,13 @@ namespace cheat::game::filters
|
||||
mineral::Starsilver,
|
||||
mineral::WhiteIronChunk
|
||||
};
|
||||
SimpleFilter PlantDestroy = {
|
||||
//plant::SakuraBloom,
|
||||
plant::DandelionSeed,
|
||||
plant::MistFlowerCorolla,
|
||||
plant::FlamingFlowerStamen
|
||||
};
|
||||
|
||||
WhitelistFilter Doodads = {
|
||||
EntityType__Enum_1::Gadget,
|
||||
{
|
||||
@ -518,15 +526,15 @@ namespace cheat::game::filters
|
||||
monster::Whopperflower
|
||||
};
|
||||
SimpleFilter MonsterEquips = { EntityType__Enum_1::MonsterEquip };
|
||||
BlacklistFilter Living = {
|
||||
{EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster},
|
||||
{
|
||||
// Environmental mobs
|
||||
"Cat", "DogPrick", "Vulpues", "Inu_Tanuki",
|
||||
// Overworld bosses
|
||||
"Ningyo", "Regisvine", "Hypostasis", "Planelurker", "Nithhoggr"
|
||||
}
|
||||
};
|
||||
BlacklistFilter Living = {
|
||||
{EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster},
|
||||
{
|
||||
// Environmental mobs
|
||||
"Cat", "DogPrick", "Vulpues", "Inu_Tanuki",
|
||||
// Overworld bosses
|
||||
"Ningyo", "Regisvine", "Hypostasis", "Planelurker", "Nithhoggr"
|
||||
}
|
||||
};
|
||||
SimpleFilter OrganicTargets = { Monsters, Animals }; // Solael: Please don't mess around with this filter.
|
||||
//m0nkrel: We can choose the entities we need ourselves so as not to magnetize cats, dogs, etc.
|
||||
//AdvancedFilter Animals = { {EntityType__Enum_1::EnvAnimal, EntityType__Enum_1::Monster }, {"Crane", "Tit", "Boar", "Squirrel", "Fox", "Pigeon", "Wigeon", "Falcon" ,"Marten" } };
|
||||
|
@ -32,6 +32,8 @@ namespace cheat::game::filters
|
||||
extern ChestFilter SFrozen;
|
||||
extern ChestFilter SBramble;
|
||||
extern ChestFilter STrap;
|
||||
|
||||
extern SimpleFilter BuriedChest;
|
||||
}
|
||||
|
||||
namespace equipment
|
||||
@ -220,7 +222,7 @@ namespace cheat::game::filters
|
||||
extern SimpleFilter Beisht;
|
||||
extern SimpleFilter RishbolandTiger;
|
||||
extern SimpleFilter ShaggySumpterBeast;
|
||||
extern SimpleFilter Spincrocodile;
|
||||
extern SimpleFilter Spincrocodile;
|
||||
extern SimpleFilter SentryTurrets;
|
||||
}
|
||||
|
||||
@ -325,6 +327,7 @@ namespace cheat::game::filters
|
||||
extern SimpleFilter Oculies;
|
||||
extern SimpleFilter Chests;
|
||||
extern SimpleFilter Ores;
|
||||
extern SimpleFilter PlantDestroy;
|
||||
extern WhitelistFilter Doodads;
|
||||
extern SimpleFilter Animals;
|
||||
extern SimpleFilter AnimalDrop;
|
||||
|
@ -563,13 +563,13 @@ namespace cheat::feature
|
||||
std::lock_guard _userDataLock(m_UserDataMutex);
|
||||
LOG_WARNING("Complete point at %.0f.", game::EntityManager::instance().avatar()->distance(pointData->levelPosition));
|
||||
|
||||
if (m_CompletedPoints.count(pointData) > 0)
|
||||
if (std::find_if(m_CompletedPoints.begin(), m_CompletedPoints.end(), [=](PointData* data) { return pointData->id == data->id; }) != std::end(m_CompletedPoints))
|
||||
return;
|
||||
|
||||
pointData->completed = true;
|
||||
pointData->completeTimestamp = util::GetCurrentTimeMillisec();
|
||||
m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount++;
|
||||
m_CompletedPoints.insert(pointData);
|
||||
m_CompletedPoints.push_back(pointData);
|
||||
|
||||
SaveCompletedPoints();
|
||||
}
|
||||
@ -578,13 +578,14 @@ namespace cheat::feature
|
||||
{
|
||||
std::lock_guard _userDataLock(m_UserDataMutex);
|
||||
|
||||
if (m_CompletedPoints.count(pointData) == 0)
|
||||
auto pointDataIterator = std::find_if(m_CompletedPoints.begin(), m_CompletedPoints.end(), [=](PointData* data) { return pointData->id == data->id; });
|
||||
if (pointDataIterator == m_CompletedPoints.end())
|
||||
return;
|
||||
|
||||
pointData->completed = false;
|
||||
pointData->completeTimestamp = 0;
|
||||
m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--;
|
||||
m_CompletedPoints.erase(pointData);
|
||||
m_CompletedPoints.erase(pointDataIterator);
|
||||
|
||||
SaveCompletedPoints();
|
||||
}
|
||||
@ -595,11 +596,12 @@ namespace cheat::feature
|
||||
if (m_CompletedPoints.empty())
|
||||
return;
|
||||
|
||||
PointData* pointData = *m_CompletedPoints.begin();
|
||||
auto pointDataIterator = --m_CompletedPoints.end();
|
||||
PointData* pointData = *pointDataIterator;
|
||||
pointData->completed = false;
|
||||
pointData->completeTimestamp = 0;
|
||||
m_ScenesData[pointData->sceneID].labels[pointData->labelID].completedCount--;
|
||||
m_CompletedPoints.erase(pointData);
|
||||
m_CompletedPoints.erase(pointDataIterator);
|
||||
|
||||
SaveCompletedPoints();
|
||||
}
|
||||
@ -916,7 +918,7 @@ namespace cheat::feature
|
||||
}
|
||||
|
||||
auto& point = points[pointID];
|
||||
if (m_CompletedPoints.count(&point) > 0)
|
||||
if (std::find_if(m_CompletedPoints.begin(), m_CompletedPoints.end(), [=](PointData* data) { return point.id == data->id; }) != std::end(m_CompletedPoints))
|
||||
{
|
||||
LOG_WARNING("Completed point %u duplicate.", pointID);
|
||||
return;
|
||||
@ -926,7 +928,7 @@ namespace cheat::feature
|
||||
point.completeTimestamp = data["complete_timestamp"];
|
||||
labelData->completedCount++;
|
||||
|
||||
m_CompletedPoints.insert(&point);
|
||||
m_CompletedPoints.push_back(&point);
|
||||
}
|
||||
|
||||
void InteractiveMap::LoadFixedPointData(LabelData* labelData, const nlohmann::json& data)
|
||||
@ -1026,6 +1028,7 @@ namespace cheat::feature
|
||||
void InteractiveMap::LoadCompletedPoints()
|
||||
{
|
||||
LoadUserData(f_CompletedPointsJson, &InteractiveMap::LoadCompletedPointData);
|
||||
ReorderCompletedPointDataByTimestamp();
|
||||
}
|
||||
|
||||
void InteractiveMap::SaveCompletedPoints()
|
||||
@ -1040,6 +1043,11 @@ namespace cheat::feature
|
||||
m_CompletedPoints.clear();
|
||||
}
|
||||
|
||||
void InteractiveMap::ReorderCompletedPointDataByTimestamp()
|
||||
{
|
||||
m_CompletedPoints.sort([](PointData* a, PointData* b) { return a->completeTimestamp < b->completeTimestamp; });
|
||||
}
|
||||
|
||||
void InteractiveMap::LoadCustomPoints()
|
||||
{
|
||||
LoadUserData(f_CustomPointsJson, &InteractiveMap::LoadCustomPointData);
|
||||
|
@ -146,7 +146,7 @@ namespace cheat::feature
|
||||
|
||||
std::unordered_set<PointData*> m_CustomPoints;
|
||||
std::unordered_set<PointData*> m_FixedPoints;
|
||||
std::unordered_set<PointData*> m_CompletedPoints;
|
||||
std::list<PointData*> m_CompletedPoints;
|
||||
|
||||
std::mutex m_PointMutex;
|
||||
// PointData* m_SelectedPoint;
|
||||
@ -182,6 +182,7 @@ namespace cheat::feature
|
||||
void LoadCompletedPointData(LabelData* labelData, const nlohmann::json& data);
|
||||
void SaveCompletedPointData(nlohmann::json& jObject, PointData* point);
|
||||
bool ResetCompletedPointData(LabelData* label, PointData* point);
|
||||
void ReorderCompletedPointDataByTimestamp();
|
||||
|
||||
void LoadCustomPointData(LabelData* labelData, const nlohmann::json& data);
|
||||
void SaveCustomPointData(nlohmann::json& jObject, PointData* point);
|
||||
|
@ -203,7 +203,8 @@ namespace cheat::feature
|
||||
for (auto entity : entities) {
|
||||
auto entityPos = entity->absolutePosition();
|
||||
std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}";
|
||||
auto entityDetails = fmt::format(baseString,
|
||||
auto entityDetails = fmt::format(
|
||||
fmt::runtime(baseString),
|
||||
fmt::ptr(entity),
|
||||
entity->runtimeID(),
|
||||
entity->name().c_str(),
|
||||
@ -222,7 +223,8 @@ namespace cheat::feature
|
||||
std::string baseString = csvFriendly ? "{},{},{},{},{},{}" : "{} {} {} x={} y={} z={}";
|
||||
if (csvFriendly && includeHeaders)
|
||||
baseString = headerString.append(baseString);
|
||||
auto entityDetails = fmt::format(baseString,
|
||||
auto entityDetails = fmt::format(
|
||||
fmt::runtime(baseString),
|
||||
fmt::ptr(entity),
|
||||
entity->runtimeID(),
|
||||
entity->name().c_str(),
|
||||
|
@ -6,41 +6,46 @@
|
||||
#include <cheat/game/util.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,
|
||||
bool ignoreCheckCanBeHitInMP, MethodInfo* method);
|
||||
static void VCAnimatorEvent_HandleProcessItem_Hook(app::MoleMole_VCAnimatorEvent* __this,
|
||||
app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem* processItem,
|
||||
app::AnimatorStateInfo processStateInfo, app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method);
|
||||
|
||||
RapidFire::RapidFire() : Feature(),
|
||||
NF(f_Enabled, "Attack Multiplier", "RapidFire", false),
|
||||
NF(f_MultiHit, "Multi-hit", "RapidFire", false),
|
||||
NF(f_Multiplier, "Hit Multiplier", "RapidFire", 2),
|
||||
NF(f_OnePunch, "One Punch Mode", "RapidFire", false),
|
||||
NF(f_Randomize, "Randomize", "RapidFire", false),
|
||||
NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1),
|
||||
NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3),
|
||||
NF(f_MultiTarget, "Multi-target", "RapidFire", false),
|
||||
NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f)
|
||||
{
|
||||
RapidFire::RapidFire() : Feature(),
|
||||
NF(f_Enabled, "Attack Multiplier", "RapidFire", false),
|
||||
NF(f_MultiHit, "Multi-hit", "RapidFire", false),
|
||||
NF(f_Multiplier, "Hit Multiplier", "RapidFire", 2),
|
||||
NF(f_OnePunch, "One Punch Mode", "RapidFire", false),
|
||||
NF(f_Randomize, "Randomize", "RapidFire", false),
|
||||
NF(f_minMultiplier, "Min Multiplier", "RapidFire", 1),
|
||||
NF(f_maxMultiplier, "Max Multiplier", "RapidFire", 3),
|
||||
NF(f_MultiTarget, "Multi-target", "RapidFire", false),
|
||||
NF(f_MultiTargetRadius, "Multi-target Radius", "RapidFire", 20.0f),
|
||||
NF(f_MultiAnimation, "Multi-animation", "RapidFire", false)
|
||||
{
|
||||
HookManager::install(app::MoleMole_LCBaseCombat_DoHitEntity, LCBaseCombat_DoHitEntity_Hook);
|
||||
}
|
||||
HookManager::install(app::MoleMole_VCAnimatorEvent_HandleProcessItem, VCAnimatorEvent_HandleProcessItem_Hook);
|
||||
}
|
||||
|
||||
const FeatureGUIInfo& RapidFire::GetGUIInfo() const
|
||||
{
|
||||
static const FeatureGUIInfo info{ "Attack Effects", "Player", true };
|
||||
return info;
|
||||
}
|
||||
const FeatureGUIInfo& RapidFire::GetGUIInfo() const
|
||||
{
|
||||
static const FeatureGUIInfo info{ "Attack Effects", "Player", true };
|
||||
return info;
|
||||
}
|
||||
|
||||
void RapidFire::DrawMain()
|
||||
{
|
||||
void RapidFire::DrawMain()
|
||||
{
|
||||
ConfigWidget("Enabled", f_Enabled, "Enables attack multipliers. Need to choose a mode to work.");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImColor(255, 165, 0, 255), "Choose any or both modes below.");
|
||||
|
||||
ConfigWidget("Multi-hit Mode", f_MultiHit, "Enables multi-hit.\n" \
|
||||
"Multiplies your attack count.\n" \
|
||||
"This is not well tested, and can be detected by anticheat.\n" \
|
||||
"Not recommended to be used with main accounts or used with high values.\n" \
|
||||
"Multiplies your attack count.\n" \
|
||||
"This is not well tested, and can be detected by anticheat.\n" \
|
||||
"Not recommended to be used with main accounts or used with high values.\n" \
|
||||
"Known issues with certain multi-hit attacks, e.g. Xiao E, Ayaka CA, etc.");
|
||||
|
||||
ImGui::Indent();
|
||||
@ -73,20 +78,23 @@ namespace cheat::feature
|
||||
"If multi-hit is off and there are still multiple numbers on a single target, check the Entity Manager in the Debug section to see if there are invisible entities.\n" \
|
||||
"This can cause EXTREME lag and quick bans if used with multi-hit. You are warned."
|
||||
);
|
||||
|
||||
|
||||
ImGui::Indent();
|
||||
ConfigWidget("Radius (m)", f_MultiTargetRadius, 0.1f, 5.0f, 50.0f, "Radius to check for valid targets.");
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
bool RapidFire::NeedStatusDraw() const
|
||||
{
|
||||
return f_Enabled && (f_MultiHit || f_MultiTarget);
|
||||
}
|
||||
ConfigWidget("Multi-animation", f_MultiAnimation, "Enables multi-animation attacks.\n" \
|
||||
"Do keep in mind that the character's audio will also be spammed.");
|
||||
}
|
||||
|
||||
void RapidFire::DrawStatus()
|
||||
{
|
||||
if (f_MultiHit)
|
||||
bool RapidFire::NeedStatusDraw() const
|
||||
{
|
||||
return f_Enabled && (f_MultiHit || f_MultiTarget || f_MultiAnimation);
|
||||
}
|
||||
|
||||
void RapidFire::DrawStatus()
|
||||
{
|
||||
if (f_MultiHit)
|
||||
{
|
||||
if (f_Randomize)
|
||||
ImGui::Text("Multi-Hit Random[%d|%d]", f_minMultiplier.value(), f_maxMultiplier.value());
|
||||
@ -97,20 +105,23 @@ namespace cheat::feature
|
||||
}
|
||||
if (f_MultiTarget)
|
||||
ImGui::Text("Multi-Target [%.01fm]", f_MultiTargetRadius.value());
|
||||
}
|
||||
|
||||
RapidFire& RapidFire::GetInstance()
|
||||
{
|
||||
static RapidFire instance;
|
||||
return instance;
|
||||
}
|
||||
if (f_MultiAnimation)
|
||||
ImGui::Text("Multi-Animation");
|
||||
}
|
||||
|
||||
RapidFire& RapidFire::GetInstance()
|
||||
{
|
||||
static RapidFire instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
int RapidFire::CalcCountToKill(float attackDamage, uint32_t targetID)
|
||||
{
|
||||
if (attackDamage == 0)
|
||||
return f_Multiplier;
|
||||
|
||||
|
||||
auto& manager = game::EntityManager::instance();
|
||||
auto targetEntity = manager.entity(targetID);
|
||||
if (targetEntity == nullptr)
|
||||
@ -165,10 +176,10 @@ namespace cheat::feature
|
||||
entity = game::Entity(app::MoleMole_GadgetEntity_GetOwnerEntity(reinterpret_cast<app::GadgetEntity*>(entity.raw()), nullptr));
|
||||
if (entity.runtimeID() == avatarID)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool IsAttackByAvatar(game::Entity& attacker)
|
||||
@ -183,6 +194,20 @@ namespace cheat::feature
|
||||
return attackerID == avatarID || IsAvatarOwner(attacker);
|
||||
}
|
||||
|
||||
bool IsConfigByAvatar(game::Entity& attacker)
|
||||
{
|
||||
if (attacker.raw() == nullptr)
|
||||
return false;
|
||||
|
||||
auto& manager = game::EntityManager::instance();
|
||||
auto avatarID = manager.avatar()->raw()->fields._configID_k__BackingField;
|
||||
auto attackerID = attacker.raw()->fields._configID_k__BackingField;
|
||||
// Taiga#5555: IDs can be found in ConfigAbility_Avatar_*.json or GadgetExcelConfigData.json
|
||||
bool bulletID = attackerID >= 40000160 && attackerID <= 41069999;
|
||||
|
||||
return avatarID == attackerID || bulletID;
|
||||
}
|
||||
|
||||
bool IsValidByFilter(game::Entity* entity)
|
||||
{
|
||||
if (game::filters::combined::OrganicTargets.IsValid(entity) ||
|
||||
@ -192,7 +217,7 @@ namespace cheat::feature
|
||||
game::filters::puzzle::LargeRockPile.IsValid(entity) ||
|
||||
game::filters::puzzle::SmallRockPile.IsValid(entity))
|
||||
return true;
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Raises when any entity do hit event.
|
||||
@ -203,7 +228,7 @@ namespace cheat::feature
|
||||
{
|
||||
auto attacker = game::Entity(__this->fields._._._entity);
|
||||
RapidFire& rapidFire = RapidFire::GetInstance();
|
||||
if (!IsAttackByAvatar(attacker) || !rapidFire.f_Enabled)
|
||||
if (!IsConfigByAvatar(attacker) || !IsAttackByAvatar(attacker) || !rapidFire.f_Enabled)
|
||||
return CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method);
|
||||
|
||||
auto& manager = game::EntityManager::instance();
|
||||
@ -242,9 +267,25 @@ namespace cheat::feature
|
||||
if (rapidFire.f_MultiHit) {
|
||||
int attackCount = rapidFire.GetAttackCount(__this, entity->runtimeID(), attackResult);
|
||||
for (int i = 0; i < attackCount; i++)
|
||||
CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, method);
|
||||
} else CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, entity->runtimeID(), attackResult, ignoreCheckCanBeHitInMP, method);
|
||||
app::MoleMole_LCBaseCombat_FireBeingHitEvent(__this, entity->runtimeID(), attackResult, method);
|
||||
}
|
||||
else app::MoleMole_LCBaseCombat_FireBeingHitEvent(__this, entity->runtimeID(), attackResult, method);
|
||||
}
|
||||
|
||||
CALL_ORIGIN(LCBaseCombat_DoHitEntity_Hook, __this, targetID, attackResult, ignoreCheckCanBeHitInMP, method);
|
||||
}
|
||||
|
||||
static void VCAnimatorEvent_HandleProcessItem_Hook(app::MoleMole_VCAnimatorEvent* __this,
|
||||
app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_AnimatorEventPatternProcessItem* processItem,
|
||||
app::AnimatorStateInfo processStateInfo, app::MoleMole_VCAnimatorEvent_MoleMole_VCAnimatorEvent_TriggerMode__Enum mode, MethodInfo* method)
|
||||
{
|
||||
auto attacker = game::Entity(__this->fields._._._entity);
|
||||
RapidFire& rapidFire = RapidFire::GetInstance();
|
||||
|
||||
if (rapidFire.f_MultiAnimation && IsAttackByAvatar(attacker))
|
||||
processItem->fields.lastTime = 0;
|
||||
|
||||
CALL_ORIGIN(VCAnimatorEvent_HandleProcessItem_Hook, __this, processItem, processStateInfo, mode, method);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ namespace cheat::feature
|
||||
config::Field<int> f_maxMultiplier;
|
||||
config::Field<config::Toggle<Hotkey>> f_MultiTarget;
|
||||
config::Field<float> f_MultiTargetRadius;
|
||||
config::Field<config::Toggle<Hotkey>> f_MultiAnimation;
|
||||
|
||||
static RapidFire& GetInstance();
|
||||
|
||||
|
@ -17,10 +17,11 @@
|
||||
namespace cheat::feature
|
||||
{
|
||||
CustomTeleports::CustomTeleports() : Feature(),
|
||||
NF(f_DebugMode, "Debug Mode", "CustomTeleports", false), // Soon to be added
|
||||
NF(f_Enabled, "Custom Teleport", "CustomTeleports", false),
|
||||
NF(f_Next, "Teleport Next", "CustomTeleports", Hotkey(VK_OEM_6)),
|
||||
NF(f_Previous, "Teleport Previous", "CustomTeleports", Hotkey(VK_OEM_4)),
|
||||
NF(f_Interpolate, "Custom Teleport", "CustomTeleports", false),
|
||||
NF(f_Speed, "Interpolation Speed", "CustomTeleports", 10.0f),
|
||||
dir(util::GetCurrentPath() / "teleports")
|
||||
{
|
||||
f_Next.value().PressedEvent += MY_METHOD_HANDLER(CustomTeleports::OnNext);
|
||||
@ -122,6 +123,42 @@ namespace cheat::feature
|
||||
return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2) + pow(a.z - b.z, 2));
|
||||
}
|
||||
|
||||
void CustomTeleports::TeleportTo(app::Vector3 position, bool interpolate)
|
||||
{
|
||||
auto &manager = game::EntityManager::instance();
|
||||
auto avatar = manager.avatar();
|
||||
if (avatar->moveComponent() == nullptr)
|
||||
{
|
||||
LOG_ERROR("Avatar has no move component, Is scene loaded?");
|
||||
return;
|
||||
}
|
||||
if (interpolate)
|
||||
{
|
||||
float speed = this->f_Speed;
|
||||
auto avatarPos = manager.avatar()->absolutePosition();
|
||||
auto endPos = position;
|
||||
std::thread interpolate([avatarPos, endPos, &manager, speed]()
|
||||
{
|
||||
float t = 0.0f;
|
||||
app::Vector3 zero = {0,0,0};
|
||||
auto newPos = zero;
|
||||
while (t < 1.0f) {
|
||||
newPos = app::Vector3_Lerp(avatarPos, endPos, t, nullptr);
|
||||
manager.avatar()->setAbsolutePosition(newPos);
|
||||
t += speed / 100.0f;
|
||||
Sleep(10);
|
||||
} });
|
||||
interpolate.detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PositionDistance(position, app::ActorUtils_GetAvatarPos(nullptr)) > 60.0f)
|
||||
MapTeleport::GetInstance().TeleportTo(position);
|
||||
else
|
||||
manager.avatar()->setAbsolutePosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomTeleports::OnTeleportKeyPressed(bool next)
|
||||
{
|
||||
if (!f_Enabled || selectedIndex < 0)
|
||||
@ -138,13 +175,14 @@ namespace cheat::feature
|
||||
else
|
||||
{
|
||||
std::vector list(checkedIndices.begin(), checkedIndices.end());
|
||||
if (selectedIndex == list.back() ? next : selectedIndex == list.front())
|
||||
if (next ? selectedIndex == list.back() : selectedIndex == list.front())
|
||||
return;
|
||||
|
||||
auto index = std::distance(list.begin(), std::find(list.begin(), list.end(), selectedIndex));
|
||||
position = Teleports.at(list.at(index + (next ? 1 : -1))).position;
|
||||
selectedIndex = list.at(index + (next ? 1 : -1));
|
||||
position = Teleports.at(selectedIndex).position;
|
||||
}
|
||||
mapTeleport.TeleportTo(position);
|
||||
TeleportTo(position, this->f_Interpolate);
|
||||
UpdateIndexName();
|
||||
}
|
||||
|
||||
@ -157,38 +195,28 @@ namespace cheat::feature
|
||||
OnTeleportKeyPressed(true);
|
||||
}
|
||||
|
||||
void itr(std::regex exp, std::string name, std::string s)
|
||||
{
|
||||
std::sregex_iterator itr(name.begin(), name.end(), exp);
|
||||
while (itr != std::sregex_iterator())
|
||||
{
|
||||
for (unsigned i = 0; i < itr->size(); i++)
|
||||
s.append((*itr)[i]);
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
|
||||
void CustomTeleports::UpdateIndexName()
|
||||
{
|
||||
std::string name(selectedIndex == -1 || checkedIndices.empty() ? "" : Teleports.at(selectedIndex).name);
|
||||
|
||||
// abbreviate teleport names that are too long
|
||||
std::string name(selectedIndex == -1 || checkedIndices.empty() ? "" : Teleports.at(selectedIndex).name);
|
||||
if (name.length() > 15)
|
||||
{
|
||||
std::string shortened;
|
||||
std::regex numsExp("[\\d]+");
|
||||
std::regex firstCharsExp("\\b[A-Za-z]");
|
||||
|
||||
std::sregex_iterator wordItr(name.begin(), name.end(), firstCharsExp);
|
||||
while (wordItr != std::sregex_iterator())
|
||||
{
|
||||
for (unsigned i = 0; i < wordItr->size(); i++)
|
||||
{
|
||||
shortened.append((*wordItr)[i]);
|
||||
}
|
||||
wordItr++;
|
||||
}
|
||||
|
||||
std::sregex_iterator numItr(name.begin(), name.end(), numsExp);
|
||||
while (numItr != std::sregex_iterator())
|
||||
{
|
||||
for (unsigned i = 0; i < numItr->size(); i++)
|
||||
{
|
||||
shortened.append(" ");
|
||||
shortened.append((*numItr)[i]);
|
||||
}
|
||||
numItr++;
|
||||
}
|
||||
itr(firstCharsExp, name, shortened);
|
||||
itr(numsExp, name, shortened);
|
||||
name = shortened;
|
||||
}
|
||||
selectedIndexName = name;
|
||||
@ -249,7 +277,9 @@ namespace cheat::feature
|
||||
"3. You can now press Next or Previous Hotkey to Teleport through the Checklist\n"
|
||||
"Initially it will teleport the player to the selection made\n"
|
||||
"Note: Double click or click the arrow to open teleport details");
|
||||
ImGui::SameLine();
|
||||
ConfigWidget("Enable Interpolation", f_Interpolate, "Enable interpolation between teleports when using keybinds");
|
||||
ConfigWidget("Interpolation Speed", f_Speed, 0.1f, 0.1f, 99.0f,
|
||||
"Interpolation speed.\n recommended setting below or equal to 0.1.");
|
||||
|
||||
if (ImGui::Button("Delete Checked"))
|
||||
{
|
||||
@ -281,8 +311,8 @@ namespace cheat::feature
|
||||
{
|
||||
std::sort(Teleports.begin(), Teleports.end(), [](const auto &a, const auto &b)
|
||||
{ return StrCmpLogicalW(std::wstring(a.name.begin(), a.name.end()).c_str(), std::wstring(b.name.begin(), b.name.end()).c_str()) < 0; });
|
||||
bool allChecked = checkedIndices.size() == Teleports.size() && !Teleports.empty();
|
||||
bool allSearchChecked = checkedIndices.size() == searchIndices.size() && !searchIndices.empty();
|
||||
bool allSearchChecked = std::includes(checkedIndices.begin(), checkedIndices.end(), searchIndices.begin(), searchIndices.end()) && !searchIndices.empty();
|
||||
bool allChecked = (checkedIndices.size() == Teleports.size() && !Teleports.empty()) || allSearchChecked;
|
||||
ImGui::Checkbox("All", &allChecked);
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
@ -316,11 +346,10 @@ namespace cheat::feature
|
||||
maxNameLength = Teleport.name.length();
|
||||
ImGui::BeginTable("Teleports", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_NoSavedSettings);
|
||||
ImGui::TableSetupColumn("#", ImGuiTableColumnFlags_WidthFixed, 20);
|
||||
ImGui::TableSetupColumn("Commands", ImGuiTableColumnFlags_WidthFixed, 100);
|
||||
ImGui::TableSetupColumn("Commands", ImGuiTableColumnFlags_WidthFixed, 130);
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, maxNameLength * 8 + 10);
|
||||
ImGui::TableSetupColumn("Position");
|
||||
ImGui::TableHeadersRow();
|
||||
ImGuiTreeNodeFlags nodeFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
|
||||
for (const auto &[name, position, description] : Teleports)
|
||||
{
|
||||
@ -332,12 +361,13 @@ namespace cheat::feature
|
||||
bool checked = std::any_of(checkedIndices.begin(), checkedIndices.end(), [&index](const auto &i)
|
||||
{ return i == index; });
|
||||
bool selected = index == selectedIndex;
|
||||
std::string stringIndex = std::to_string(index);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", index);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(("##Index" + std::to_string(index)).c_str(), &checked);
|
||||
ImGui::Checkbox(("##Index" + stringIndex).c_str(), &checked);
|
||||
if (ImGui::IsItemClicked(0))
|
||||
{
|
||||
if (checked)
|
||||
@ -352,37 +382,29 @@ namespace cheat::feature
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(("TP##Button" + std::to_string(index)).c_str()))
|
||||
if (ImGui::Button(("TP##Button" + stringIndex).c_str()))
|
||||
{
|
||||
auto &manager = game::EntityManager::instance();
|
||||
auto avatar = manager.avatar();
|
||||
if (avatar->moveComponent() == nullptr)
|
||||
{
|
||||
LOG_ERROR("Avatar has no move component, Is scene loaded?");
|
||||
return;
|
||||
}
|
||||
if (PositionDistance(position, app::ActorUtils_GetAvatarPos(nullptr)) > 60.0f)
|
||||
MapTeleport::GetInstance().TeleportTo(position);
|
||||
else
|
||||
manager.avatar()->setAbsolutePosition(position);
|
||||
TeleportTo(position, false);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(("Select##Button" + std::to_string(index)).c_str()))
|
||||
if (ImGui::Button(("Lerp##Button" + stringIndex).c_str()))
|
||||
{
|
||||
TeleportTo(position, true);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button(("Select##Button" + stringIndex).c_str()))
|
||||
{
|
||||
selectedIndex = index;
|
||||
selectedByClick = true;
|
||||
UpdateIndexName();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, selected ? IM_COL32(40, 90, 175, 255) : IM_COL32(255, 255, 255, 255));
|
||||
|
||||
if (selected)
|
||||
nodeFlags |= ImGuiTreeNodeFlags_Selected;
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, selected ? IM_COL32(40, 90, 175, 255) : ImGui::ColorConvertFloat4ToU32(ImGui::GetStyle().Colors[ImGuiCol_Text]));
|
||||
ImGui::Text("%s", name.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
|
@ -25,8 +25,9 @@ namespace cheat::feature
|
||||
class CustomTeleports : public Feature
|
||||
{
|
||||
public:
|
||||
config::Field<config::Toggle<Hotkey>> f_DebugMode;
|
||||
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_Previous;
|
||||
static CustomTeleports& GetInstance();
|
||||
@ -55,6 +56,7 @@ namespace cheat::feature
|
||||
std::string selectedName;
|
||||
std::string selectedIndexName;
|
||||
CustomTeleports();
|
||||
void TeleportTo(app::Vector3 position, bool interpolate);
|
||||
void OnTeleportKeyPressed(bool next);
|
||||
void OnPrevious();
|
||||
void OnNext();
|
||||
|
301
cheat-library/src/user/cheat/visuals/AnimationChanger.cpp
Normal file
301
cheat-library/src/user/cheat/visuals/AnimationChanger.cpp
Normal 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);
|
||||
}
|
||||
}
|
27
cheat-library/src/user/cheat/visuals/AnimationChanger.h
Normal file
27
cheat-library/src/user/cheat/visuals/AnimationChanger.h
Normal 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();
|
||||
};
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ namespace cheat::feature
|
||||
app::Component_1* Profirency = nullptr;
|
||||
}
|
||||
|
||||
static void PlayerModule_RequestPlayerCook(app::MoleMole_PlayerModule* __this, uint32_t recipeId, uint32_t avatarId, uint32_t qteQuality, uint32_t count, MethodInfo* method);
|
||||
static std::map<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 CookingQtePageContext_UpdateProficiency(app::CookingQtePageContext* __this, MethodInfo* method);
|
||||
|
||||
@ -22,7 +24,7 @@ namespace cheat::feature
|
||||
NF(f_Enabled, "Standart Cooking", "AutoCook", false),
|
||||
NF(f_FastProficiency, "Fast Proficiency", "AutoCook", false),
|
||||
NF(f_CountField, "Count Item", "AutoCook", 1),
|
||||
NF(f_QualityField, "Quality", "AutoCook", 1)
|
||||
NF(f_QualityField, "Quality", "AutoCook", "Normal")
|
||||
{
|
||||
HookManager::install(app::MoleMole_PlayerModule_RequestPlayerCook, PlayerModule_RequestPlayerCook);
|
||||
HookManager::install(app::MoleMole_PlayerModule_OnPlayerCookRsp, PlayerModule_OnPlayerCookRsp);
|
||||
@ -38,12 +40,24 @@ namespace cheat::feature
|
||||
void AutoCook::DrawMain()
|
||||
{
|
||||
ConfigWidget(f_Enabled, "Fast Cooking if the recipe has fast cooking open. \n" \
|
||||
"If fast cooking is closed, you in addition need to turn on Fast Proficiency.");
|
||||
"If fast cooking is closed, you in addition need to turn on Fast Proficiency.");
|
||||
ConfigWidget(f_FastProficiency, "Quickly prepare an unstudied recipe to the maximum possible.");
|
||||
ConfigWidget("Count Item", f_CountField, 1, 1, 100,
|
||||
"How much to cook at a time.\n" \
|
||||
"(For standard mode only.)");
|
||||
ConfigWidget("Quality Cooking", f_QualityField, 1, 1, 3, "Quality of the cook.");
|
||||
if (ImGui::BeginCombo("Cooking Quality", f_QualityField.value().c_str()))
|
||||
{
|
||||
for (auto& [qualityName, quality] : qualities)
|
||||
{
|
||||
bool is_selected = (f_QualityField.value().c_str() == qualityName);
|
||||
if (ImGui::Selectable(qualityName.c_str(), is_selected))
|
||||
f_QualityField.value() = qualityName;
|
||||
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
bool AutoCook::NeedStatusDraw() const
|
||||
@ -53,7 +67,10 @@ namespace cheat::feature
|
||||
|
||||
void AutoCook::DrawStatus()
|
||||
{
|
||||
ImGui::Text("Auto Cooking [%s]", f_FastProficiency ? "Proficiency" : "Standart");
|
||||
if (f_FastProficiency)
|
||||
ImGui::Text("Auto Cooking [Proficiency]");
|
||||
else
|
||||
ImGui::Text("Auto Cooking [Standart, %s]", f_QualityField.value().c_str());
|
||||
}
|
||||
|
||||
AutoCook& AutoCook::GetInstance()
|
||||
@ -82,9 +99,14 @@ namespace cheat::feature
|
||||
if (autoCook.f_Enabled || autoCook.f_FastProficiency)
|
||||
{
|
||||
autoCook.CookFoodMaxNum = app::MoleMole_Config_CookRecipeExcelConfig_CheckCookFoodMaxNum(recipeId, nullptr);
|
||||
qteQuality = autoCook.f_QualityField;
|
||||
|
||||
if (!autoCook.f_FastProficiency && autoCook.f_Enabled){
|
||||
// To prevent possible crashes
|
||||
if (!qualities.count(autoCook.f_QualityField.value()))
|
||||
autoCook.f_QualityField.value() = "Normal";
|
||||
|
||||
qteQuality = qualities.find(autoCook.f_QualityField.value())->second;
|
||||
|
||||
if (!autoCook.f_FastProficiency && autoCook.f_Enabled) {
|
||||
count = autoCook.f_CountField;
|
||||
if (autoCook.f_CountField > autoCook.CookFoodMaxNum)
|
||||
count = autoCook.CookFoodMaxNum;
|
||||
@ -99,7 +121,7 @@ namespace cheat::feature
|
||||
auto RectTransform = app::GameObject_GetComponentByName(GameObject::Profirency, string_to_il2cppi("RectTransform"), nullptr);
|
||||
auto TransformChild = app::Transform_GetChild(reinterpret_cast<app::Transform*>(RectTransform), 0, nullptr);
|
||||
auto TextComponent = app::Component_1_GetComponent_1(reinterpret_cast<app::Component_1*>(TransformChild), string_to_il2cppi("Text"), nullptr);
|
||||
|
||||
|
||||
if (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(" ."));
|
||||
@ -127,7 +149,11 @@ namespace cheat::feature
|
||||
AutoCook& autoCook = AutoCook::GetInstance();
|
||||
if (autoCook.f_Enabled || autoCook.f_FastProficiency)
|
||||
{
|
||||
rsp->fields.qteQuality_ = autoCook.f_QualityField;
|
||||
// To prevent possible crashes
|
||||
if (!qualities.count(autoCook.f_QualityField.value()))
|
||||
autoCook.f_QualityField.value() = "Normal";
|
||||
|
||||
rsp->fields.qteQuality_ = qualities.find(autoCook.f_QualityField.value())->second;
|
||||
rsp->fields.cookCount_ = autoCook.f_CountField;
|
||||
if (autoCook.f_FastProficiency)
|
||||
rsp->fields.cookCount_ = 1;
|
||||
@ -137,7 +163,7 @@ namespace cheat::feature
|
||||
|
||||
return CALL_ORIGIN(PlayerModule_OnPlayerCookRsp, __this, rsp, method);
|
||||
}
|
||||
|
||||
|
||||
static void CookingQtePageContext_UpdateProficiency(app::CookingQtePageContext* __this, MethodInfo* method) {
|
||||
AutoCook& autoCook = AutoCook::GetInstance();
|
||||
if (autoCook.f_Enabled || autoCook.f_FastProficiency)
|
||||
|
@ -12,10 +12,10 @@ namespace cheat::feature
|
||||
config::Field<config::Toggle<Hotkey>> f_FastProficiency;
|
||||
|
||||
config::Field<int> f_CountField;
|
||||
config::Field<int> f_QualityField;
|
||||
config::Field<std::string> f_QualityField;
|
||||
|
||||
int CookFoodMaxNum; // Maximum quantity at a time
|
||||
int CookCount;
|
||||
int CookCount;
|
||||
|
||||
static AutoCook& GetInstance();
|
||||
|
||||
@ -26,7 +26,7 @@ namespace cheat::feature
|
||||
void DrawStatus() override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
AutoCook();
|
||||
};
|
||||
}
|
||||
|
@ -9,31 +9,32 @@
|
||||
#include <cheat/game/EntityManager.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);
|
||||
|
||||
AutoDestroy::AutoDestroy() : Feature(),
|
||||
NF(f_Enabled, "Auto Destroy", "AutoDestroy", false),
|
||||
NF(f_DestroyOres, "Destroy Ores", "AutoDestroy", false),
|
||||
NF(f_DestroyShields, "Destroy Shields", "AutoDestroy", false),
|
||||
NF(f_DestroyDoodads, "Destroy Doodads", "AutoDestroy", false),
|
||||
NF(f_Range, "Range", "AutoDestroy", 10.0f)
|
||||
{
|
||||
AutoDestroy::AutoDestroy() : Feature(),
|
||||
NF(f_Enabled, "Auto Destroy", "AutoDestroy", false),
|
||||
NF(f_DestroyOres, "Destroy Ores", "AutoDestroy", false),
|
||||
NF(f_DestroyShields, "Destroy Shields", "AutoDestroy", false),
|
||||
NF(f_DestroyDoodads, "Destroy Doodads", "AutoDestroy", false),
|
||||
NF(f_DestroyPlants, "Destroy Plants", "AutoDestroy", false),
|
||||
NF(f_Range, "Range", "AutoDestroy", 10.0f)
|
||||
{
|
||||
HookManager::install(app::MoleMole_LCAbilityElement_ReduceModifierDurability, LCAbilityElement_ReduceModifierDurability_Hook);
|
||||
}
|
||||
|
||||
const FeatureGUIInfo& AutoDestroy::GetGUIInfo() const
|
||||
{
|
||||
static const FeatureGUIInfo info { "Auto Destroy Objects", "World", true };
|
||||
return info;
|
||||
}
|
||||
const FeatureGUIInfo& AutoDestroy::GetGUIInfo() const
|
||||
{
|
||||
static const FeatureGUIInfo info{ "Auto Destroy Objects", "World", true };
|
||||
return info;
|
||||
}
|
||||
|
||||
void AutoDestroy::DrawMain()
|
||||
{
|
||||
void AutoDestroy::DrawMain()
|
||||
{
|
||||
ImGui::TextColored(ImColor(255, 165, 0, 255), "Note. This feature is not fully tested detection-wise.\n"
|
||||
"Not recommended for main accounts or used with high values.");
|
||||
|
||||
|
||||
ConfigWidget("Enabled", f_Enabled, "Instantly destroys non-living objects within range.");
|
||||
ImGui::Indent();
|
||||
ConfigWidget("Ores", f_DestroyOres, "Ores and variants, e.g. electro crystals, marrows, etc.");
|
||||
@ -43,30 +44,32 @@ namespace cheat::feature
|
||||
ConfigWidget("Doodads", f_DestroyDoodads, "Barrels, boxes, vases, etc.");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImColor(255, 165, 0, 255), "Extremely risky!");
|
||||
ConfigWidget("Plants", f_DestroyPlants, "Dandelion Seeds, Sakura Bloom, etc.");
|
||||
ImGui::Unindent();
|
||||
ConfigWidget("Range (m)", f_Range, 0.1f, 1.0f, 15.0f);
|
||||
}
|
||||
}
|
||||
|
||||
bool AutoDestroy::NeedStatusDraw() const
|
||||
bool AutoDestroy::NeedStatusDraw() const
|
||||
{
|
||||
return f_Enabled;
|
||||
}
|
||||
return f_Enabled;
|
||||
}
|
||||
|
||||
void AutoDestroy::DrawStatus()
|
||||
{
|
||||
ImGui::Text("Destroy [%.01fm%s%s%s%s]",
|
||||
void AutoDestroy::DrawStatus()
|
||||
{
|
||||
ImGui::Text("Destroy [%.01fm%s%s%s%s%s]",
|
||||
f_Range.value(),
|
||||
f_DestroyOres || f_DestroyShields || f_DestroyDoodads ? "|" : "",
|
||||
f_DestroyOres || f_DestroyShields || f_DestroyDoodads || f_DestroyPlants ? "|" : "",
|
||||
f_DestroyOres ? "O" : "",
|
||||
f_DestroyShields ? "S" : "",
|
||||
f_DestroyDoodads ? "D" : "");
|
||||
}
|
||||
f_DestroyDoodads ? "D" : "",
|
||||
f_DestroyPlants ? "P" : "");
|
||||
}
|
||||
|
||||
AutoDestroy& AutoDestroy::GetInstance()
|
||||
{
|
||||
static AutoDestroy instance;
|
||||
return instance;
|
||||
}
|
||||
AutoDestroy& AutoDestroy::GetInstance()
|
||||
{
|
||||
static AutoDestroy instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Thanks to @RyujinZX
|
||||
// Every ore has ability element component
|
||||
@ -79,17 +82,17 @@ namespace cheat::feature
|
||||
auto& manager = game::EntityManager::instance();
|
||||
auto& autoDestroy = AutoDestroy::GetInstance();
|
||||
auto entity = __this->fields._._._entity;
|
||||
if (autoDestroy.f_Enabled &&
|
||||
if (autoDestroy.f_Enabled &&
|
||||
autoDestroy.f_Range > manager.avatar()->distance(entity) &&
|
||||
(
|
||||
(autoDestroy.f_DestroyOres && game::filters::combined::Ores.IsValid(manager.entity(entity))) ||
|
||||
(autoDestroy.f_DestroyDoodads && game::filters::combined::Doodads.IsValid(manager.entity(entity))) ||
|
||||
(autoDestroy.f_DestroyOres && game::filters::combined::Ores.IsValid(manager.entity(entity))) ||
|
||||
(autoDestroy.f_DestroyDoodads && (game::filters::combined::Doodads.IsValid(manager.entity(entity)) || game::filters::chest::SBramble.IsValid(manager.entity(entity)))) ||
|
||||
(autoDestroy.f_DestroyShields && !game::filters::combined::MonsterBosses.IsValid(manager.entity(entity)) && (
|
||||
game::filters::combined::MonsterShielded.IsValid(manager.entity(entity)) || // For shields attached to monsters, e.g. abyss mage shields.
|
||||
game::filters::combined::MonsterEquips.IsValid(manager.entity(entity)) // For shields/weapons equipped by monsters, e.g. rock shield.
|
||||
))
|
||||
game::filters::combined::MonsterShielded.IsValid(manager.entity(entity)) || // For shields attached to monsters, e.g. abyss mage shields.
|
||||
game::filters::combined::MonsterEquips.IsValid(manager.entity(entity)))) || // For shields/weapons equipped by monsters, e.g. rock shield.
|
||||
(autoDestroy.f_DestroyPlants && game::filters::combined::PlantDestroy.IsValid(manager.entity(entity))) // For plants e.g dandelion seeds.
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
// This value always above any ore durability
|
||||
reduceDurability = 1000;
|
||||
|
@ -12,6 +12,7 @@ namespace cheat::feature
|
||||
config::Field<config::Toggle<Hotkey>> f_DestroyOres;
|
||||
config::Field<config::Toggle<Hotkey>> f_DestroyShields;
|
||||
config::Field<config::Toggle<Hotkey>> f_DestroyDoodads;
|
||||
config::Field<config::Toggle<Hotkey>> f_DestroyPlants;
|
||||
config::Field<float> f_Range;
|
||||
|
||||
static AutoDestroy& GetInstance();
|
||||
|
@ -47,6 +47,7 @@ namespace cheat::feature
|
||||
void FreezeEnemies::OnGameUpdate()
|
||||
{
|
||||
auto& manager = game::EntityManager::instance();
|
||||
static bool change = false;
|
||||
|
||||
for (const auto& monster : manager.entities(game::filters::combined::Monsters))
|
||||
{
|
||||
@ -61,11 +62,16 @@ namespace cheat::feature
|
||||
//LOG_DEBUG("%s", magic_enum::enum_name(constraints).data());
|
||||
app::Rigidbody_set_constraints(rigidBody, app::RigidbodyConstraints__Enum::FreezeAll, nullptr);
|
||||
app::Animator_set_speed(animator, 0.f, nullptr);
|
||||
change = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
app::Rigidbody_set_constraints(rigidBody, app::RigidbodyConstraints__Enum::FreezeRotation, nullptr);
|
||||
app::Animator_set_speed(animator, 1.f, nullptr);
|
||||
if (!change)
|
||||
{
|
||||
app::Animator_set_speed(animator, 1.f, nullptr);
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)include/;$(SolutionDir)cheat-base/src;$(SolutionDir)cheat-base/vendor/simpleIni/</AdditionalIncludeDirectories>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
</ClCompile>
|
||||
|
Loading…
Reference in New Issue
Block a user