mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 17:37:53 +08:00
backup of new VarManagerBase for variable managing such as PlayerVariables or CVars
This commit is contained in:
@ -30,9 +30,10 @@
|
||||
<ClCompile Include="src\Engine\IBaseCamera.cpp" />
|
||||
<ClCompile Include="src\Engine\IControlObject.cpp" />
|
||||
<ClCompile Include="src\Engine\IPhysicsCharacter.cpp" />
|
||||
<ClCompile Include="src\Engine\RendererCVars.cpp" />
|
||||
<ClCompile Include="src\Engine\CVars.cpp" />
|
||||
<ClCompile Include="src\Engine\CVideoSettings.cpp" />
|
||||
<ClCompile Include="src\Engine\Engine_Misc.cpp" />
|
||||
<ClCompile Include="src\Engine\VarBase.cpp" />
|
||||
<ClCompile Include="src\GamePH\CoPlayerRestrictions.cpp" />
|
||||
<ClCompile Include="src\GamePH\DayNightCycle.cpp" />
|
||||
<ClCompile Include="src\GamePH\FreeCamera.cpp" />
|
||||
@ -65,6 +66,8 @@
|
||||
<ClCompile Include="src\Vec3.cpp" />
|
||||
<ClCompile Include="src\Vec4.cpp" />
|
||||
<ClCompile Include="SteamAPI.cpp" />
|
||||
<ClCompile Include="VarManagerBase.cpp" />
|
||||
<ClCompile Include="VarMapBase.cpp" />
|
||||
<ClCompile Include="WinMemory.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -86,9 +89,12 @@
|
||||
<ClInclude Include="include\EGSDK\Engine\IControlObject.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\IGSObject.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\IPhysicsCharacter.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\RendererCVars.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\CVars.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\CVideoSettings.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\Engine_Misc.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\VarBase.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\VarManagerBase.h" />
|
||||
<ClInclude Include="include\EGSDK\Engine\VarMapBase.h" />
|
||||
<ClInclude Include="include\EGSDK\Exports.h" />
|
||||
<ClInclude Include="include\EGSDK\GamePH\CameraFPPDI.h" />
|
||||
<ClInclude Include="include\EGSDK\GamePH\CoBaseCameraProxy.h" />
|
||||
@ -170,6 +176,7 @@
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>EGameSDK</TargetName>
|
||||
@ -210,7 +217,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalDependencies>DbgHelp.lib;Version.lib;libMinHook-x64-v141-mdd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OptimizeReferences>
|
||||
@ -246,7 +253,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>deps\MinHook\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>DbgHelp.lib;Version.lib;libMinHook-x64-v141-mdd.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
|
@ -142,7 +142,7 @@
|
||||
<ClCompile Include="Offsets.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Engine\RendererCVars.cpp">
|
||||
<ClCompile Include="src\Engine\CVars.cpp">
|
||||
<Filter>src\Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WinMemory.cpp">
|
||||
@ -166,6 +166,15 @@
|
||||
<ClCompile Include="src\Vec2.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VarMapBase.cpp">
|
||||
<Filter>src\Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VarManagerBase.cpp">
|
||||
<Filter>src\Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Engine\VarBase.cpp">
|
||||
<Filter>src\Engine</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="include">
|
||||
@ -365,7 +374,7 @@
|
||||
<ClInclude Include="include\EGSDK\Core\SteamAPI.h">
|
||||
<Filter>include\Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\EGSDK\Engine\RendererCVars.h">
|
||||
<ClInclude Include="include\EGSDK\Engine\CVars.h">
|
||||
<Filter>include\Engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\EGSDK\Utils\WinMemory.h">
|
||||
@ -401,5 +410,14 @@
|
||||
<ClInclude Include="include\EGSDK\Vec2.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\EGSDK\Engine\VarMapBase.h">
|
||||
<Filter>include\Engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\EGSDK\Engine\VarManagerBase.h">
|
||||
<Filter>include\Engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\EGSDK\Engine\VarBase.h">
|
||||
<Filter>include\Engine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
104
EGameSDK/VarManagerBase.cpp
Normal file
104
EGameSDK/VarManagerBase.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include <EGSDK\Vec4.h>
|
||||
#include <EGSDK\Engine\VarManagerBase.h>
|
||||
#include <EGSDK\Engine\VarMapBase.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
#define StaticAssertValueType static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, float> || std::is_same_v<T, int> || std::is_same_v<T, Vec3> || std::is_same_v<T, Vec4> || std::is_same_v<T, bool>, "Invalid type: value must be string, float, int, Vec3, Vec4 or bool")
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarMapType VarManagerBase<VarMapType, VarType>::vars;
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarMapType VarManagerBase<VarMapType, VarType>::customVars;
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarMapType VarManagerBase<VarMapType, VarType>::defaultVars;
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
template <typename T>
|
||||
T* VarManagerBase<VarMapType, VarType>::GetVarValue(const std::string& name) {
|
||||
StaticAssertValueType;
|
||||
auto var = vars.Find(name);
|
||||
return var ? std::get_if<T>(&var->GetValue()) : nullptr;
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
template <typename T>
|
||||
T* VarManagerBase<VarMapType, VarType>::GetVarValue(VarType* var) {
|
||||
StaticAssertValueType;
|
||||
return var ? std::get_if<T>(&var->GetValue()) : nullptr;
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
template <typename T>
|
||||
T* VarManagerBase<VarMapType, VarType>::GetVarValueFromMap(const std::string& name, const VarMapType& map) {
|
||||
StaticAssertValueType;
|
||||
auto var = map.Find(name);
|
||||
return var ? std::get_if<T>(&var->GetValue()) : nullptr;
|
||||
}
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
template <typename T>
|
||||
void VarManagerBase<VarMapType, VarType>::ChangeVar(const std::string& name, T value) {
|
||||
StaticAssertValueType;
|
||||
auto var = vars.Find(name);
|
||||
if (var)
|
||||
var->SetValue(value);
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
template <typename T>
|
||||
void VarManagerBase<VarMapType, VarType>::ChangeVar(VarType* var, T value) {
|
||||
StaticAssertValueType;
|
||||
if (var)
|
||||
var->SetValue(value);
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
template <typename T>
|
||||
void VarManagerBase<VarMapType, VarType>::ChangeVarFromList(const std::string& name, T value) {
|
||||
StaticAssertValueType;
|
||||
|
||||
auto var = vars.Find(name);
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
ChangeVarFromList<T>(var, value);
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
template <typename T>
|
||||
void VarManagerBase<VarMapType, VarType>::ChangeVarFromList(VarType* var, T value) {
|
||||
StaticAssertValueType;
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
auto customVar = customVars.Find(var->GetName());
|
||||
auto defVar = defaultVars.Find(var->GetName());
|
||||
|
||||
if (!customVar)
|
||||
customVar = customVars.try_emplace(std::make_unique<VarType>(var->GetName(), var->GetType())).get();
|
||||
if (!defVar) {
|
||||
defVar = defaultVars.try_emplace(std::make_unique<VarType>(var->GetName(), var->GetType())).get();
|
||||
if (auto varValue = GetVarValue<T>(var); defVar && varValue)
|
||||
defVar->SetValue(*varValue);
|
||||
}
|
||||
|
||||
if (customVar)
|
||||
customVar->SetValue(value);
|
||||
var->SetValue(value);
|
||||
}
|
||||
|
||||
template EGameSDK_API class VarManagerBase<CVarMap, CVar>;
|
||||
|
||||
template EGameSDK_API float* VarManagerBase<CVarMap, CVar>::GetVarValue<float>(const std::string&);
|
||||
template EGameSDK_API float* VarManagerBase<CVarMap, CVar>::GetVarValue<float>(CVar*);
|
||||
template EGameSDK_API int* VarManagerBase<CVarMap, CVar>::GetVarValue<int>(const std::string&);
|
||||
template EGameSDK_API int* VarManagerBase<CVarMap, CVar>::GetVarValue<int>(CVar*);
|
||||
template EGameSDK_API float* VarManagerBase<CVarMap, CVar>::GetVarValueFromMap<float>(const std::string&, const CVarMap& map);
|
||||
template EGameSDK_API int* VarManagerBase<CVarMap, CVar>::GetVarValueFromMap<int>(const std::string&, const CVarMap& map);
|
||||
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVar<float>(const std::string&, float);
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVar<float>(CVar*, float);
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVar<int>(const std::string&, int);
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVar<int>(CVar*, int);
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVarFromList<float>(const std::string&, float);
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVarFromList<float>(CVar*, float);
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVarFromList<int>(const std::string&, int);
|
||||
template EGameSDK_API void VarManagerBase<CVarMap, CVar>::ChangeVarFromList<int>(CVar*, int);
|
||||
}
|
57
EGameSDK/VarMapBase.cpp
Normal file
57
EGameSDK/VarMapBase.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include <EGSDK\Engine\VarMapBase.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
template <typename VarType>
|
||||
std::unique_ptr<VarType>& VarMapBase<VarType>::try_emplace(std::unique_ptr<VarType> var) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
const std::string& name = var->GetName();
|
||||
auto [it, inserted] = vars.try_emplace(name, std::move(var));
|
||||
if (inserted)
|
||||
varsOrdered.emplace_back(name);
|
||||
return it->second;
|
||||
}
|
||||
template <typename VarType>
|
||||
bool VarMapBase<VarType>::empty() const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
return vars.empty();
|
||||
}
|
||||
template <typename VarType>
|
||||
bool VarMapBase<VarType>::none_of(const std::string& name) const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
return vars.find(name) == vars.end();
|
||||
}
|
||||
template <typename VarType>
|
||||
void VarMapBase<VarType>::reserve(size_t count) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
vars.reserve(count);
|
||||
}
|
||||
template <typename VarType>
|
||||
size_t VarMapBase<VarType>::size() {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
return vars.size();
|
||||
}
|
||||
|
||||
template <typename VarType>
|
||||
VarType* VarMapBase<VarType>::Find(const std::string& name) const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
auto it = vars.find(name);
|
||||
return (it != vars.end()) ? it->second.get() : nullptr;
|
||||
}
|
||||
|
||||
template <typename VarType>
|
||||
void VarMapBase<VarType>::Erase(const std::string& name) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
auto it = vars.find(name);
|
||||
if (it == vars.end())
|
||||
return;
|
||||
|
||||
auto orderIt = std::find(varsOrdered.begin(), varsOrdered.end(), name);
|
||||
if (orderIt != varsOrdered.end())
|
||||
varsOrdered.erase(orderIt);
|
||||
|
||||
vars.erase(it);
|
||||
}
|
||||
|
||||
template EGameSDK_API class VarMapBase<CVar>;
|
||||
}
|
@ -13,7 +13,6 @@
|
||||
#endif
|
||||
|
||||
namespace EGSDK {
|
||||
static constexpr uint32_t GAME_VER_COMPAT = 12001;
|
||||
static constexpr std::array<uint32_t, 2> SUPPORTED_GAME_VERSIONS = { 11200, 12001 };
|
||||
|
||||
namespace Core {
|
||||
@ -31,6 +30,8 @@ namespace EGSDK {
|
||||
#endif
|
||||
|
||||
extern EGameSDK_API std::string GetSDKStoragePath();
|
||||
extern EGameSDK_API std::string GetSupportedGameVersionsStr();
|
||||
extern EGameSDK_API bool IsGameVerCompatible();
|
||||
|
||||
#ifdef EGameSDK_EXPORTS
|
||||
extern void OnPostUpdate();
|
||||
|
54
EGameSDK/include/EGSDK/Engine/CVars.h
Normal file
54
EGameSDK/include/EGSDK/Engine/CVars.h
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
#include <EGSDK\ClassHelpers.h>
|
||||
#include <EGSDK\Engine\VarBase.h>
|
||||
#include <EGSDK\Engine\VarMapBase.h>
|
||||
#include <EGSDK\Engine\VarManagerBase.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
class EGameSDK_API CVar : public VarBase {
|
||||
public:
|
||||
union {
|
||||
ClassHelpers::StaticBuffer<0x50, uint32_t> valueOffset;
|
||||
};
|
||||
|
||||
explicit CVar(const std::string& name);
|
||||
explicit CVar(const std::string& name, VarType type);
|
||||
|
||||
VarValueType& GetValue();
|
||||
void SetValue(const VarValueType& value);
|
||||
void AddValuePtr(uint64_t* ptr);
|
||||
private:
|
||||
struct VarValue {
|
||||
VarValueType value;
|
||||
std::vector<uint64_t*> valuePtrs;
|
||||
};
|
||||
static std::unordered_map<const CVar*, VarValue> varValues;
|
||||
};
|
||||
|
||||
class EGameSDK_API FloatCVar : public CVar {
|
||||
public:
|
||||
explicit FloatCVar(const std::string& name);
|
||||
};
|
||||
class EGameSDK_API IntCVar : public CVar {
|
||||
public:
|
||||
explicit IntCVar(const std::string& name);
|
||||
};
|
||||
|
||||
class EGameSDK_API CVarMap : public VarMapBase<CVar> {
|
||||
public:
|
||||
using VarMapBase<CVar>::Find;
|
||||
using VarMapBase<CVar>::none_of;
|
||||
|
||||
bool none_of(uint32_t valueOffset);
|
||||
|
||||
CVar* Find(uint32_t valueOffset) const;
|
||||
|
||||
std::unique_ptr<CVar>& try_emplace(std::unique_ptr<CVar> var) override;
|
||||
|
||||
void Erase(const std::string& name) override;
|
||||
private:
|
||||
std::unordered_map<uint32_t, CVar*> varsByValueOffset;
|
||||
};
|
||||
|
||||
class EGameSDK_API CVars : public VarManagerBase<CVarMap, CVar> {};
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
#pragma once
|
||||
#include <any>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <EGSDK\ClassHelpers.h>
|
||||
#include <EGSDK\Utils\Values.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
enum EGameSDK_API RendererCVarType {
|
||||
NONE = 0,
|
||||
Float
|
||||
};
|
||||
|
||||
class EGameSDK_API RendererCVar {
|
||||
public:
|
||||
RendererCVar(const std::string& name);
|
||||
RendererCVar(const std::string& name, DWORD64 address);
|
||||
|
||||
const char* GetName();
|
||||
void SetName(const std::string& name);
|
||||
|
||||
RendererCVarType GetType();
|
||||
void SetType(RendererCVarType type);
|
||||
|
||||
DWORD64 GetAddress();
|
||||
void SetAddress(DWORD64 address);
|
||||
private:
|
||||
std::string name{};
|
||||
RendererCVarType type = RendererCVarType::NONE;
|
||||
DWORD64 address = 0;
|
||||
};
|
||||
|
||||
class EGameSDK_API FloatRendererCVar : public RendererCVar {
|
||||
public:
|
||||
explicit FloatRendererCVar(const std::string& name);
|
||||
explicit FloatRendererCVar(const std::string& name, DWORD64 address);
|
||||
|
||||
float GetValue();
|
||||
void SetValue(float value);
|
||||
private:
|
||||
float value = -404.0f;
|
||||
};
|
||||
|
||||
class EGameSDK_API RendererCVarMap {
|
||||
public:
|
||||
RendererCVarMap() = default;
|
||||
RendererCVarMap(const RendererCVarMap&) = delete;
|
||||
RendererCVarMap& operator=(const RendererCVarMap&) = delete;
|
||||
|
||||
RendererCVarMap(RendererCVarMap&&) noexcept = default;
|
||||
RendererCVarMap& operator=(RendererCVarMap&&) noexcept = default;
|
||||
|
||||
std::unique_ptr<RendererCVar>& try_emplace(std::unique_ptr<RendererCVar> rendererCVar);
|
||||
bool empty();
|
||||
bool none_of(const std::string& name);
|
||||
bool none_of(DWORD64 address);
|
||||
|
||||
std::unique_ptr<RendererCVar>* FindPtr(const std::string& name);
|
||||
RendererCVar* Find(const std::string& name);
|
||||
RendererCVar* Find(DWORD64 address);
|
||||
bool Erase(const std::string& name);
|
||||
|
||||
template <typename Callable, typename... Args>
|
||||
void ForEach(Callable&& func, Args&&... args) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
for (const auto& name : _order)
|
||||
func(_rendererCVars.at(name), std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
std::unordered_map<std::string, std::unique_ptr<RendererCVar>> _rendererCVars{};
|
||||
std::unordered_map<DWORD64, RendererCVar*> _rendererCVarsByAddress{};
|
||||
std::vector<std::string> _order{};
|
||||
mutable std::mutex mutex{};
|
||||
};
|
||||
|
||||
class EGameSDK_API RendererCVars {
|
||||
public:
|
||||
static RendererCVarMap rendererCVars;
|
||||
static RendererCVarMap customRendererCVars;
|
||||
static RendererCVarMap defaultRendererCVars;
|
||||
|
||||
static float GetRendererCVarValue(const std::string& name);
|
||||
static void ChangeRendererCVar(const std::string& name, float value, RendererCVar* rendererCVar = nullptr);
|
||||
static void ChangeRendererCVarFromList(const std::string& name, float value, RendererCVar* rendererCVar = nullptr);
|
||||
};
|
||||
}
|
40
EGameSDK/include/EGSDK/Engine/VarBase.h
Normal file
40
EGameSDK/include/EGSDK/Engine/VarBase.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <variant>
|
||||
#include <EGSDK\Exports.h>
|
||||
#include <EGSDK\Vec3.h>
|
||||
#include <EGSDK\Vec4.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
EGameSDK_API enum class VarType {
|
||||
NONE = 0,
|
||||
String,
|
||||
Float,
|
||||
Int,
|
||||
Vec3,
|
||||
Vec4,
|
||||
Bool
|
||||
};
|
||||
|
||||
using VarValueType = std::variant<std::string, float, int, Vec3, Vec4, bool>;
|
||||
|
||||
class EGameSDK_API VarBase {
|
||||
public:
|
||||
VarBase(const std::string& name);
|
||||
VarBase(const std::string& name, VarType type);
|
||||
~VarBase();
|
||||
|
||||
const char* GetName() const;
|
||||
void SetName(const std::string& name);
|
||||
|
||||
VarType GetType() const;
|
||||
void SetType(VarType type);
|
||||
protected:
|
||||
static std::recursive_mutex mutex;
|
||||
private:
|
||||
static std::unordered_map<const VarBase*, std::string> varNames;
|
||||
static std::unordered_map<const VarBase*, VarType> varTypes;
|
||||
};
|
||||
}
|
29
EGameSDK/include/EGSDK/Engine/VarManagerBase.h
Normal file
29
EGameSDK/include/EGSDK/Engine/VarManagerBase.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <EGSDK\Exports.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
template <typename VarMapType, typename VarType>
|
||||
class EGameSDK_API VarManagerBase {
|
||||
public:
|
||||
static VarMapType vars;
|
||||
static VarMapType customVars;
|
||||
static VarMapType defaultVars;
|
||||
|
||||
template <typename T>
|
||||
static T* GetVarValue(const std::string& name);
|
||||
template <typename T>
|
||||
static T* GetVarValue(VarType* var);
|
||||
template <typename T>
|
||||
static T* GetVarValueFromMap(const std::string& name, const VarMapType& map);
|
||||
|
||||
template <typename T>
|
||||
static void ChangeVar(const std::string& name, T value);
|
||||
template <typename T>
|
||||
static void ChangeVar(VarType* var, T value);
|
||||
template <typename T>
|
||||
static void ChangeVarFromList(const std::string& name, T value);
|
||||
template <typename T>
|
||||
static void ChangeVarFromList(VarType* var, T value);
|
||||
};
|
||||
}
|
43
EGameSDK/include/EGSDK/Engine/VarMapBase.h
Normal file
43
EGameSDK/include/EGSDK/Engine/VarMapBase.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <EGSDK\Exports.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
template <typename VarType>
|
||||
class EGameSDK_API VarMapBase {
|
||||
public:
|
||||
VarMapBase() = default;
|
||||
VarMapBase(const VarMapBase&) = delete;
|
||||
VarMapBase& operator=(const VarMapBase&) = delete;
|
||||
VarMapBase(VarMapBase&&) noexcept = default;
|
||||
VarMapBase& operator=(VarMapBase&&) noexcept = default;
|
||||
|
||||
virtual ~VarMapBase() = default;
|
||||
|
||||
virtual std::unique_ptr<VarType>& try_emplace(std::unique_ptr<VarType> var);
|
||||
bool empty() const;
|
||||
bool none_of(const std::string& name) const;
|
||||
void reserve(size_t count);
|
||||
size_t size();
|
||||
|
||||
VarType* Find(const std::string& name) const;
|
||||
|
||||
virtual void Erase(const std::string& name);
|
||||
|
||||
template <typename Callable, typename... Args>
|
||||
void ForEach(Callable&& func, Args&&... args) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
for (const auto& name : varsOrdered)
|
||||
func(vars.at(name), std::forward<Args>(args)...);
|
||||
}
|
||||
protected:
|
||||
std::unordered_map<std::string, std::unique_ptr<VarType>> vars{};
|
||||
std::vector<std::string> varsOrdered{};
|
||||
mutable std::recursive_mutex mutex{};
|
||||
};
|
||||
}
|
@ -102,7 +102,11 @@ namespace EGSDK {
|
||||
AddDynamicPattern(DisablePlayerRestrictionsSubFunc, "gamedll_ph_x64_rwdi.dll", void*)
|
||||
AddDynamicPattern(HandlePlayerRestrictions, "gamedll_ph_x64_rwdi.dll", void*) // sub func of m_EnableRestrictions sub funcs and m_DisableRestrictions sub funcs
|
||||
AddPattern(SetIsInCoSafeZone, "gamedll_ph_x64_rwdi.dll", "E8 [?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0 74 ?? E8 ?? ?? ?? ?? 48 8B C8 E8 ?? ?? ?? ?? 48 8B 5C 24 ?? 48 83 C4", Utils::SigScan::PatternType::RelativePointer, void*)
|
||||
AddPattern(UpdateCVarFloat, "engine_x64_rwdi.dll", "40 53 48 83 EC ?? 8B 51 ?? 49 8B D8 48 8B 4C 24 ?? 41 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0 48 8D 0D ?? ?? ?? ?? 48 0F 45 C8 8B 01 89 03 48 83 C4 ?? 5B C3 CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC ?? 8B 51 ?? 49 8B D8 48 8B 4C 24 ?? 41 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0 48 8D 0D ?? ?? ?? ?? 48 0F 45 C8 F2 0F 10 01", Utils::SigScan::PatternType::Address, void*)
|
||||
AddPattern(LoadScriptedVarInt, "engine_x64_rwdi.dll", "48 89 5C 24 ?? 55 57 41 54 41 56 41 57 48 83 EC ?? 45 0F B6 11 45 33 E4 4D 8B F1 4D 8B F8 48 8B FA 48 8B E9 49 8B D9 45 8B DC 45 84 D2 74 ?? 90 45 0F B6 C2 48 8D 5B ?? 41 80 EA ?? 41 80 FA ?? 44 0F B6 13 41 8D 40 ?? 0F B6 C8 41 0F 47 C8 45 6B DB ?? 0F BE C9 44 03 D9 45 84 D2 75 ?? 0F B6 47 ?? 41 8B D4 84 C0 75 ?? 44 8B 47 ?? EB ?? FE C8 44 0F B6 C0 41 83 E8 ?? 48 89 B4 24 ?? ?? ?? ?? 78 ?? 4C 8B 17 48 B8 ?? ?? ?? ?? ?? ?? ?? ?? 4C 23 D0 41 8D 0C 10 D1 F9 48 63 C1 49 8D 34 C2 49 8B 04 C2 44 39 58 ?? 74 ?? 8D 41 ?? 41 0F 42 C0 44 8B C0 8D 41 ?? 0F 42 D0 41 3B D0 7E ?? B9 ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 8B F8 48 85 C0 0F 84 ?? ?? ?? ?? 4C 89 60 ?? 4C 89 60 ?? 4C 89 60 ?? 66 44 89 60 ?? 44 88 60 ?? 48 8D 05 ?? ?? ?? ?? 48 89 07 48 8D 05 ?? ?? ?? ?? 48 89 47 ?? E9 ?? ?? ?? ?? 48 85 F6 74 ?? F6 40 ?? ?? 0F 85 ?? ?? ?? ?? B9 ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 8B F8 85 C0 0F 84 ?? ?? ?? ?? BA ?? ?? ?? ?? 48 8D 8C 24 ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 BE ?? ?? ?? ?? ?? ?? ?? ?? 48 8D 1D ?? ?? ?? ?? B9 ?? ?? ?? ?? 48 8B 10", Utils::SigScan::PatternType::Address, void*)
|
||||
AddPattern(GetCVarT, "engine_x64_rwdi.dll", "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC ?? 44 0F B6 12 33 F6 41 8B E9", Utils::SigScan::PatternType::Address, void*)
|
||||
AddPattern(GetCVarValue, "engine_x64_rwdi.dll", "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B 05 ?? ?? ?? ?? 48 8B D9 41 8B F0 8B FA", Utils::SigScan::PatternType::Address, void*)
|
||||
AddPattern(UpdateFrameScript, "engine_x64_rwdi.dll", "48 81 C1 ?? ?? ?? ?? 4C 8D 05 ?? ?? ?? ?? E9 ?? ?? ?? ?? CC CC CC CC CC CC CC CC CC CC CC CC CC 48 81 C1 ?? ?? ?? ?? 4C 8D 05 ?? ?? ?? ?? E9 ?? ?? ?? ?? CC CC CC CC CC CC CC CC CC CC CC CC CC 48 81 C1", Utils::SigScan::PatternType::Address, void*)
|
||||
AddPattern(GetListOfCVarValues, "engine_x64_rwdi.dll", "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B 05 ?? ?? ?? ?? 48 8B F9 48 8B 08 8B 49 ?? FF 15 ?? ?? ?? ?? 48 8B CF 48 8B F0 E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 8B 09 48 8B 1A FF 15 ?? ?? ?? ?? FF C8 48 8B 54 C3 ?? 80 BA ?? ?? ?? ?? ?? 75 ?? 83 FE ?? 75 ?? 48 8D 47 ?? 48 8B 5C 24 ?? 48 8B 74 24 ?? 48 83 C4 ?? 5F C3 48 8B 5C 24 ?? 48 8D 4F ?? 85 F6 48 8D 47 ?? 48 8B 74 24 ?? 48 0F 44 C1 48 83 C4 ?? 5F C3 0F 57 C0", Utils::SigScan::PatternType::Address, void*)
|
||||
AddPattern(HandleTimeWeatherInterpolationOnDemandTextureIsLoaded, "engine_x64_rwdi.dll", "40 84 ED 0F 84 ?? ?? ?? ?? 0F B6 4E", Utils::SigScan::PatternType::Address, void*)
|
||||
private:
|
||||
static void AddOffsets(DWORD gameVer, const std::unordered_map<std::string, DWORD>& offsets);
|
||||
|
@ -160,6 +160,9 @@ namespace EGSDK::Utils {
|
||||
auto ExecuteOriginal(Args... args) {
|
||||
return pOriginal(args...);
|
||||
}
|
||||
auto ExecuteDetour(Args... args) {
|
||||
return pDetour(args...);
|
||||
}
|
||||
|
||||
void RegisterCallback(CallbackType callback) {
|
||||
callbacks.push_back(callback);
|
||||
@ -225,6 +228,9 @@ namespace EGSDK::Utils {
|
||||
auto ExecuteOriginal(Args... args) {
|
||||
return pOriginal(args...);
|
||||
}
|
||||
auto ExecuteDetour(Args... args) {
|
||||
return pDetour(args...);
|
||||
}
|
||||
|
||||
void RegisterCallback(CallbackType callback) {
|
||||
callbacks.push_back(callback);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <spdlog\sinks\rotating_file_sink.h>
|
||||
#include <DbgHelp.h>
|
||||
#include <thread>
|
||||
#include <ranges>
|
||||
|
||||
namespace EGSDK::Core {
|
||||
std::vector<spdlog::sink_ptr> spdlogSinks{};
|
||||
@ -51,6 +52,19 @@ namespace EGSDK::Core {
|
||||
}
|
||||
return localAppDataDir += "\\EGameSDK";
|
||||
}
|
||||
std::string GetSupportedGameVersionsStr() {
|
||||
std::ostringstream oss{};
|
||||
|
||||
for (const auto& version : SUPPORTED_GAME_VERSIONS) {
|
||||
if (&version != &SUPPORTED_GAME_VERSIONS.front())
|
||||
oss << ", ";
|
||||
oss << "v" << EGSDK::GamePH::GameVerToStr(version);
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
bool IsGameVerCompatible() {
|
||||
return std::ranges::contains(SUPPORTED_GAME_VERSIONS, gameVer);
|
||||
}
|
||||
|
||||
void OnPostUpdate() {
|
||||
GamePH::PlayerVariables::GetPlayerVars();
|
||||
@ -91,9 +105,9 @@ namespace EGSDK::Core {
|
||||
#endif
|
||||
static void GameVersionCheck() {
|
||||
try {
|
||||
SPDLOG_INFO("EGSDK supported game versions: {}", GetSupportedGameVersionsStr());
|
||||
SPDLOG_DEBUG("Attempting to get current game version");
|
||||
gameVer = GamePH::GetCurrentGameVersion();
|
||||
SPDLOG_DEBUG("Got game version: {}", gameVer);
|
||||
} catch (const std::exception& e) {
|
||||
std::string errorMsg = "Failed to get game version, EXCEPTION: " + std::string(e.what()) + "\n\nThis shouldn't happen! Contact developer.";
|
||||
SPDLOG_ERROR(errorMsg);
|
||||
@ -103,11 +117,8 @@ namespace EGSDK::Core {
|
||||
|
||||
SPDLOG_INFO("Got game version: v{}", GamePH::GameVerToStr(gameVer));
|
||||
SPDLOG_DEBUG("Comparing game version with compatible versions");
|
||||
if (std::find(SUPPORTED_GAME_VERSIONS.begin(), SUPPORTED_GAME_VERSIONS.end(), Core::gameVer) == SUPPORTED_GAME_VERSIONS.end()) {
|
||||
std::string warningMsg = "Unsupported game version v" + GamePH::GameVerToStr(gameVer) + ".\n\nPlease note that your game version has not been officially tested with this version of EGameSDK, therefore expect bugs, glitches or other mods to completely stop working.\n\nThe following game versions are officially supported: ";
|
||||
for (const auto& version : SUPPORTED_GAME_VERSIONS)
|
||||
warningMsg += "- v" + GamePH::GameVerToStr(version) + "\n";
|
||||
|
||||
if (!IsGameVerCompatible()) {
|
||||
std::string warningMsg = "Unsupported game version v" + GamePH::GameVerToStr(gameVer) + ".\n\nPlease note that your game version has not been officially tested with this version of EGameSDK, therefore expect bugs, glitches or other mods to completely stop working.\n\nThe following game versions are officially supported: " + GetSupportedGameVersionsStr();
|
||||
SPDLOG_WARN(warningMsg);
|
||||
std::thread([warningMsg]() {
|
||||
MessageBox(nullptr, warningMsg.c_str(), "EGameSDK unsupported game version", MB_ICONWARNING | MB_OK | MB_SETFOREGROUND);
|
||||
|
111
EGameSDK/src/Engine/CVars.cpp
Normal file
111
EGameSDK/src/Engine/CVars.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include <algorithm>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
std::unordered_map<const CVar*, CVar::VarValue> CVar::varValues;
|
||||
CVar::CVar(const std::string& name) : VarBase(name) {}
|
||||
CVar::CVar(const std::string& name, VarType type) : VarBase(name, type) {}
|
||||
VarValueType& CVar::GetValue() {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
auto it = varValues.find(this);
|
||||
switch (GetType()) {
|
||||
case VarType::Float:
|
||||
if (it == varValues.end())
|
||||
return varValues[this].value = 0.0f;
|
||||
if (!it->second.valuePtrs.size())
|
||||
return it->second.value;
|
||||
if (!it->second.valuePtrs[0])
|
||||
return it->second.value;
|
||||
|
||||
it->second.value = *reinterpret_cast<float*>(it->second.valuePtrs[0]);
|
||||
return it->second.value;
|
||||
case VarType::Int:
|
||||
if (it == varValues.end())
|
||||
return varValues[this].value = 0;
|
||||
if (!it->second.valuePtrs.size())
|
||||
return it->second.value;
|
||||
if (!it->second.valuePtrs[0])
|
||||
return it->second.value;
|
||||
|
||||
it->second.value = *reinterpret_cast<int*>(it->second.valuePtrs[0]);
|
||||
return it->second.value;
|
||||
default:
|
||||
if (it == varValues.end())
|
||||
return varValues[this].value = 0;
|
||||
return it->second.value;
|
||||
}
|
||||
}
|
||||
void CVar::SetValue(const VarValueType& value) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
switch (GetType()) {
|
||||
case VarType::Float:
|
||||
{
|
||||
if (auto floatVal = std::get_if<float>(&value)) {
|
||||
for (const auto& ptr : varValues[this].valuePtrs) {
|
||||
if (ptr)
|
||||
*reinterpret_cast<float*>(ptr) = *floatVal;
|
||||
}
|
||||
varValues[this].value = *floatVal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VarType::Int:
|
||||
{
|
||||
if (auto intVal = std::get_if<int>(&value)) {
|
||||
for (const auto& ptr : varValues[this].valuePtrs) {
|
||||
if (ptr)
|
||||
*reinterpret_cast<int*>(ptr) = *intVal;
|
||||
}
|
||||
varValues[this].value = *intVal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CVar::AddValuePtr(uint64_t* ptr) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
varValues[this].valuePtrs.push_back(ptr);
|
||||
}
|
||||
|
||||
FloatCVar::FloatCVar(const std::string& name) : CVar(name) {
|
||||
SetType(VarType::Float);
|
||||
}
|
||||
IntCVar::IntCVar(const std::string& name) : CVar(name) {
|
||||
SetType(VarType::Int);
|
||||
}
|
||||
|
||||
std::unique_ptr<CVar>& CVarMap::try_emplace(std::unique_ptr<CVar> cVar) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
const std::string& name = cVar->GetName();
|
||||
auto [it, inserted] = vars.try_emplace(name, std::move(cVar));
|
||||
if (inserted) {
|
||||
varsOrdered.emplace_back(name);
|
||||
if (uint32_t valueOffset = it->second->valueOffset.data; valueOffset || valueOffset != 0xCDCDCDCD)
|
||||
varsByValueOffset[valueOffset] = it->second.get();
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
bool CVarMap::none_of(uint32_t valueOffset) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
return varsByValueOffset.find(valueOffset) == varsByValueOffset.end();
|
||||
}
|
||||
|
||||
CVar* CVarMap::Find(uint32_t valueOffset) const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
auto it = varsByValueOffset.find(valueOffset);
|
||||
return it == varsByValueOffset.end() ? nullptr : it->second;
|
||||
}
|
||||
void CVarMap::Erase(const std::string& name) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
auto it = vars.find(name);
|
||||
if (it == vars.end())
|
||||
return;
|
||||
|
||||
auto orderIt = std::find(varsOrdered.begin(), varsOrdered.end(), name);
|
||||
if (orderIt != varsOrdered.end())
|
||||
varsOrdered.erase(orderIt);
|
||||
|
||||
varsByValueOffset.erase(it->second->valueOffset.data);
|
||||
vars.erase(it);
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <spdlog\spdlog.h>
|
||||
#include <EGSDK\Offsets.h>
|
||||
#include <EGSDK\Utils\Time.h>
|
||||
#include <EGSDK\Engine\RendererCVars.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
RendererCVar::RendererCVar(const std::string& name) {
|
||||
this->name = name;
|
||||
this->type = RendererCVarType::NONE;
|
||||
}
|
||||
RendererCVar::RendererCVar(const std::string& name, DWORD64 address) {
|
||||
this->name = name;
|
||||
this->type = RendererCVarType::NONE;
|
||||
this->address = address;
|
||||
}
|
||||
const char* RendererCVar::GetName() {
|
||||
return name.c_str();
|
||||
}
|
||||
void RendererCVar::SetName(const std::string& name) {
|
||||
this->name = name;
|
||||
}
|
||||
RendererCVarType RendererCVar::GetType() {
|
||||
return type;
|
||||
}
|
||||
void RendererCVar::SetType(RendererCVarType type) {
|
||||
this->type = type;
|
||||
}
|
||||
DWORD64 RendererCVar::GetAddress() {
|
||||
return address;
|
||||
}
|
||||
void RendererCVar::SetAddress(DWORD64 address) {
|
||||
this->address = address;
|
||||
}
|
||||
|
||||
FloatRendererCVar::FloatRendererCVar(const std::string& name) : RendererCVar(name) {
|
||||
SetType(RendererCVarType::Float);
|
||||
}
|
||||
FloatRendererCVar::FloatRendererCVar(const std::string& name, DWORD64 address) : RendererCVar(name, address) {
|
||||
SetType(RendererCVarType::Float);
|
||||
}
|
||||
float FloatRendererCVar::GetValue() {
|
||||
return value;
|
||||
}
|
||||
void FloatRendererCVar::SetValue(float value) {
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
std::unique_ptr<RendererCVar>& RendererCVarMap::try_emplace(std::unique_ptr<RendererCVar> rendererCVar) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
const std::string& name = rendererCVar->GetName();
|
||||
auto [it, inserted] = _rendererCVars.try_emplace(name, std::move(rendererCVar));
|
||||
if (inserted) {
|
||||
_order.emplace_back(name);
|
||||
_rendererCVarsByAddress[it->second->GetAddress()] = it->second.get();
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
bool RendererCVarMap::empty() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return _rendererCVars.empty();
|
||||
}
|
||||
bool RendererCVarMap::none_of(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return _rendererCVars.find(name) == _rendererCVars.end();
|
||||
}
|
||||
bool RendererCVarMap::none_of(DWORD64 address) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return _rendererCVarsByAddress.find(address) == _rendererCVarsByAddress.end();
|
||||
}
|
||||
|
||||
std::unique_ptr<RendererCVar>* RendererCVarMap::FindPtr(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = _rendererCVars.find(name);
|
||||
return it == _rendererCVars.end() ? nullptr : &it->second;
|
||||
}
|
||||
RendererCVar* RendererCVarMap::Find(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = _rendererCVars.find(name);
|
||||
return it == _rendererCVars.end() ? nullptr : it->second.get();
|
||||
}
|
||||
RendererCVar* RendererCVarMap::Find(DWORD64 address) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = _rendererCVarsByAddress.find(address);
|
||||
return it == _rendererCVarsByAddress.end() ? nullptr : it->second;
|
||||
}
|
||||
bool RendererCVarMap::Erase(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = _rendererCVars.find(name);
|
||||
if (it != _rendererCVars.end())
|
||||
return _rendererCVarsByAddress.erase(it->second->GetAddress()) > 0 && _rendererCVars.erase(name) > 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
RendererCVarMap RendererCVars::rendererCVars{};
|
||||
RendererCVarMap RendererCVars::customRendererCVars{};
|
||||
RendererCVarMap RendererCVars::defaultRendererCVars{};
|
||||
|
||||
template <typename T>
|
||||
static T getDefaultValue() {
|
||||
static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, float> || std::is_same_v<T, bool>, "Invalid type: value must be string, float or bool");
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>)
|
||||
return {};
|
||||
else if constexpr (std::is_same_v<T, float>)
|
||||
return -404.0f;
|
||||
else if constexpr (std::is_same_v<T, bool>)
|
||||
return false;
|
||||
}
|
||||
float RendererCVars::GetRendererCVarValue(const std::string& name) {
|
||||
auto rendererCVar = rendererCVars.Find(name);
|
||||
if (!rendererCVar)
|
||||
return getDefaultValue<float>();
|
||||
|
||||
return reinterpret_cast<FloatRendererCVar*>(rendererCVar)->GetValue();
|
||||
}
|
||||
void RendererCVars::ChangeRendererCVar(const std::string& name, float value, RendererCVar* rendererCVar) {
|
||||
if (!rendererCVar)
|
||||
rendererCVar = rendererCVars.Find(name);
|
||||
if (!rendererCVar)
|
||||
return;
|
||||
|
||||
if (rendererCVar->GetType() == RendererCVarType::Float)
|
||||
reinterpret_cast<FloatRendererCVar*>(rendererCVar)->SetValue(value);
|
||||
}
|
||||
void RendererCVars::ChangeRendererCVarFromList(const std::string& name, float value, RendererCVar* rendererCVar) {
|
||||
if (!rendererCVar)
|
||||
rendererCVar = rendererCVars.Find(name);
|
||||
if (!rendererCVar)
|
||||
return;
|
||||
|
||||
auto customRendererCVar = customRendererCVars.Find(name);
|
||||
auto defRendererCVar = defaultRendererCVars.Find(name);
|
||||
|
||||
if (rendererCVar->GetType() != RendererCVarType::Float)
|
||||
return;
|
||||
if (!customRendererCVar)
|
||||
customRendererCVar = customRendererCVars.try_emplace(std::make_unique<FloatRendererCVar>(name, rendererCVar->GetAddress())).get();
|
||||
if (!defRendererCVar) {
|
||||
defRendererCVar = defaultRendererCVars.try_emplace(std::make_unique<FloatRendererCVar>(name)).get();
|
||||
reinterpret_cast<FloatRendererCVar*>(defRendererCVar)->SetValue(reinterpret_cast<FloatRendererCVar*>(rendererCVar)->GetValue());
|
||||
}
|
||||
|
||||
reinterpret_cast<FloatRendererCVar*>(rendererCVar)->SetValue(value);
|
||||
reinterpret_cast<FloatRendererCVar*>(customRendererCVar)->SetValue(value);
|
||||
}
|
||||
}
|
47
EGameSDK/src/Engine/VarBase.cpp
Normal file
47
EGameSDK/src/Engine/VarBase.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <EGSDK\Engine\VarBase.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
std::unordered_map<const VarBase*, std::string> VarBase::varNames{};
|
||||
std::unordered_map<const VarBase*, VarType> VarBase::varTypes{};
|
||||
std::recursive_mutex VarBase::mutex{};
|
||||
|
||||
VarBase::VarBase(const std::string& name) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
varNames[this] = name;
|
||||
varTypes[this] = VarType::NONE;
|
||||
}
|
||||
VarBase::VarBase(const std::string& name, VarType type) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
varNames[this] = name;
|
||||
varTypes[this] = type;
|
||||
}
|
||||
VarBase::~VarBase() {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
varNames.erase(this);
|
||||
varTypes.erase(this);
|
||||
}
|
||||
|
||||
const char* VarBase::GetName() const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
auto it = varNames.find(this);
|
||||
if (it != varNames.end())
|
||||
return it->second.c_str();
|
||||
return nullptr;
|
||||
}
|
||||
void VarBase::SetName(const std::string& newName) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
varNames[this] = newName;
|
||||
}
|
||||
|
||||
VarType VarBase::GetType() const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
auto it = varTypes.find(this);
|
||||
if (it != varTypes.end())
|
||||
return it->second;
|
||||
return VarType::NONE;
|
||||
}
|
||||
void VarBase::SetType(VarType newType) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
varTypes[this] = newType;
|
||||
}
|
||||
}
|
1
EGameSDK/src/Engine/VarManagerBase.cpp
Normal file
1
EGameSDK/src/Engine/VarManagerBase.cpp
Normal file
@ -0,0 +1 @@
|
||||
|
1
EGameSDK/src/Engine/VarMapBase.cpp
Normal file
1
EGameSDK/src/Engine/VarMapBase.cpp
Normal file
@ -0,0 +1 @@
|
||||
|
@ -108,6 +108,7 @@
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>EGameTools</TargetName>
|
||||
@ -147,7 +148,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalDependencies>DbgHelp.lib;Version.lib;EGameSDK.lib;libMinHook-x64-v141-mdd.lib;freetype-mdd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OptimizeReferences>
|
||||
@ -187,7 +188,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>..\EGameSDK\deps\MinHook\lib;deps\freetype\lib;..\$(PlatformShortName)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>DbgHelp.lib;Version.lib;EGameSDK.lib;libMinHook-x64-v141-mdd.lib;freetype-md.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <ImGui\imgui_internal.h>
|
||||
#include <EGSDK\Utils\Time.h>
|
||||
#include <EGSDK\Utils\Values.h>
|
||||
#include <EGSDK\Core\Core.h>
|
||||
|
||||
namespace ImGui {
|
||||
bool isAnyHotkeyBtnClicked = false;
|
||||
@ -13,10 +14,10 @@ namespace ImGui {
|
||||
VKey::VKey(std::string_view name, int code) : name(name), code(code) {}
|
||||
|
||||
#pragma region Option
|
||||
Option::Option() {
|
||||
Option::Option(bool value) : value(value), previousValue(value) {
|
||||
GetInstances()->insert(this);
|
||||
};
|
||||
Option::Option(bool value) : value(value) {
|
||||
Option::Option(bool value, std::initializer_list<uint32_t> unsupportedGameVers) : value(value), previousValue(value), unsupportedGameVers(unsupportedGameVers) {
|
||||
GetInstances()->insert(this);
|
||||
};
|
||||
Option::~Option() {
|
||||
@ -33,6 +34,7 @@ namespace ImGui {
|
||||
bool Option::GetChangesAreDisabled() const {
|
||||
return changesAreDisabled;
|
||||
}
|
||||
|
||||
void Option::Toggle() {
|
||||
previousValue = value;
|
||||
value = !value;
|
||||
@ -63,6 +65,11 @@ namespace ImGui {
|
||||
bool Option::HasChangedTo(bool toValue) const {
|
||||
return previousValue != value && value == toValue;
|
||||
}
|
||||
|
||||
uint32_t Option::IsUnsupportedGameVer() const {
|
||||
auto it = unsupportedGameVers.find(EGSDK::Core::gameVer);
|
||||
return it != unsupportedGameVers.end() ? EGSDK::Core::gameVer : 0;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region KeyBindOption
|
||||
@ -70,7 +77,7 @@ namespace ImGui {
|
||||
bool KeyBindOption::scrolledMouseWheelUp = false;
|
||||
bool KeyBindOption::scrolledMouseWheelDown = false;
|
||||
|
||||
KeyBindOption::KeyBindOption(int keyCode, bool isToggleableOption) : keyCode(keyCode), isToggleableOption(isToggleableOption) {
|
||||
KeyBindOption::KeyBindOption(bool value, int keyCode, bool isToggleableOption, std::initializer_list<uint32_t> unsupportedGameVers) : keyCode(keyCode), isToggleableOption(isToggleableOption), Option(value, unsupportedGameVers) {
|
||||
GetInstances()->insert(this);
|
||||
};
|
||||
KeyBindOption::~KeyBindOption() {
|
||||
@ -452,29 +459,21 @@ namespace ImGui {
|
||||
});
|
||||
#pragma endregion
|
||||
|
||||
static void HotkeyDebugInfo(const std::string_view& label) {
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGui::Text("Hotkey Label: %s", label.data());
|
||||
ImGui::Text("CurrentItemFlags: 0x%X", g.CurrentItemFlags);
|
||||
ImGui::Text("DisabledStackSize: %d", g.DisabledStackSize);
|
||||
ImGui::Text("ItemFlagsStack Size: %d", (int)g.ItemFlagsStack.size());
|
||||
for (size_t i = 0; i < g.ItemFlagsStack.size(); ++i) {
|
||||
ImGui::Text(" Stack[%d]: 0x%X", (int)i, g.ItemFlagsStack[i]);
|
||||
}
|
||||
}
|
||||
void Hotkey(const std::string_view& label, KeyBindOption* key) {
|
||||
if (key->IsUnsupportedGameVer())
|
||||
ImGui::BeginDisabled(key->IsUnsupportedGameVer());
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
bool wasDisabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
||||
|
||||
//HotkeyDebugInfo(label);
|
||||
|
||||
if (wasDisabled)
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGuiItemFlags backupFlags = g.CurrentItemFlags;
|
||||
g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled;
|
||||
float backupAlpha = g.Style.Alpha;
|
||||
g.Style.Alpha = backupAlpha / g.Style.DisabledAlpha;
|
||||
|
||||
if (wasDisabled && !key->IsUnsupportedGameVer()) {
|
||||
ImGui::EndDisabled();
|
||||
g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled;
|
||||
g.Style.Alpha = backupAlpha / g.Style.DisabledAlpha;
|
||||
}
|
||||
|
||||
const ImGuiID id = GetID(label.data());
|
||||
PushID(label.data());
|
||||
@ -516,12 +515,13 @@ namespace ImGui {
|
||||
|
||||
PopID();
|
||||
|
||||
g.CurrentItemFlags = backupFlags;
|
||||
g.Style.Alpha = backupAlpha;
|
||||
|
||||
if (wasDisabled)
|
||||
if (wasDisabled && !key->IsUnsupportedGameVer()) {
|
||||
g.CurrentItemFlags = backupFlags;
|
||||
g.Style.Alpha = backupAlpha;
|
||||
ImGui::BeginDisabled(true);
|
||||
}
|
||||
|
||||
//HotkeyDebugInfo(label);
|
||||
if (key->IsUnsupportedGameVer())
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
}
|
@ -30,15 +30,16 @@ namespace ImGui {
|
||||
|
||||
class Option {
|
||||
public:
|
||||
Option();
|
||||
bool value = false;
|
||||
|
||||
Option(bool value);
|
||||
Option(bool value, std::initializer_list<uint32_t> unsupportedGameVers);
|
||||
~Option();
|
||||
static std::set<Option*>* GetInstances();
|
||||
|
||||
bool value = false;
|
||||
|
||||
void SetChangesAreDisabled(bool newValue);
|
||||
bool GetChangesAreDisabled() const;
|
||||
|
||||
void Toggle();
|
||||
void Set(bool newValue);
|
||||
void SetBothValues(bool newValue);
|
||||
@ -48,9 +49,12 @@ namespace ImGui {
|
||||
bool GetPrevValue() const;
|
||||
bool HasChanged() const;
|
||||
bool HasChangedTo(bool toValue) const;
|
||||
|
||||
uint32_t IsUnsupportedGameVer() const;
|
||||
private:
|
||||
bool changesAreDisabled = false;
|
||||
bool previousValue = false;
|
||||
std::set<uint32_t> unsupportedGameVers{};
|
||||
};
|
||||
class KeyBindOption : public Option {
|
||||
public:
|
||||
@ -58,7 +62,7 @@ namespace ImGui {
|
||||
static bool scrolledMouseWheelUp;
|
||||
static bool scrolledMouseWheelDown;
|
||||
|
||||
KeyBindOption(int keyCode, bool isToggleableOption = true);
|
||||
KeyBindOption(bool value, int keyCode, bool isToggleableOption = true, std::initializer_list<uint32_t> unsupportedGameVers = {});
|
||||
~KeyBindOption();
|
||||
static std::set<KeyBindOption*>* GetInstances();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <ImGui\imgui_hotkey.h>
|
||||
#include <ImGui\imgui_internal.h>
|
||||
|
||||
#include <EGSDK\GamePH\GamePH_Misc.h>
|
||||
namespace ImGui {
|
||||
static ImGuiStyle defImGuiStyle{};
|
||||
static size_t tabIndex = 1;
|
||||
@ -69,9 +69,13 @@ namespace ImGui {
|
||||
return checkbox;
|
||||
}
|
||||
bool Checkbox(const char* label, Option* v) {
|
||||
ImGui::BeginDisabled(v->IsUnsupportedGameVer());
|
||||
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
if (window->SkipItems) {
|
||||
ImGui::EndDisabled();
|
||||
return false;
|
||||
}
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
@ -84,6 +88,7 @@ namespace ImGui {
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id)) {
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (v->GetValue() ? ImGuiItemStatusFlags_Checked : 0));
|
||||
ImGui::EndDisabled();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -116,17 +121,20 @@ namespace ImGui {
|
||||
RenderText(label_pos, label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (v->GetValue() ? ImGuiItemStatusFlags_Checked : 0));
|
||||
ImGui::EndDisabled();
|
||||
return pressed;
|
||||
}
|
||||
bool Checkbox(const char* label, Option* v, const char* tooltip) {
|
||||
bool checkbox = Checkbox(label, v);
|
||||
SetItemTooltip(tooltip);
|
||||
|
||||
std::string finalTooltip = v->IsUnsupportedGameVer() ? "Option is disabled because it does not support v" + EGSDK::GamePH::GameVerToStr(v->IsUnsupportedGameVer()) : tooltip ? tooltip : "";
|
||||
if (!finalTooltip.empty())
|
||||
SetItemTooltip(finalTooltip.c_str());
|
||||
|
||||
return checkbox;
|
||||
}
|
||||
bool CheckboxHotkey(const char* label, KeyBindOption* v, const char* tooltip) {
|
||||
const bool checkbox = Checkbox(label, v);
|
||||
if (tooltip)
|
||||
SetItemTooltip(tooltip);
|
||||
bool checkbox = Checkbox(label, v, tooltip);
|
||||
Hotkey(std::string(label + std::string("##ToggleKey")), v);
|
||||
return checkbox;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
namespace EGT {
|
||||
constexpr const char* MOD_VERSION_STR = "v1.3.0";
|
||||
constexpr unsigned long MOD_VERSION = 10300;
|
||||
constexpr unsigned long GAME_VER_COMPAT = 12001;
|
||||
|
||||
namespace Core {
|
||||
extern void OpenIOBuffer();
|
||||
|
@ -275,15 +275,6 @@ namespace EGT::Core {
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
static void GameVersionCheck() {
|
||||
SPDLOG_INFO("Game version: v{}", EGSDK::GamePH::GameVerToStr(EGSDK::Core::gameVer));
|
||||
SPDLOG_DEBUG("Comparing game version with compatible version");
|
||||
if (EGSDK::Core::gameVer != GAME_VER_COMPAT) {
|
||||
SPDLOG_WARN("Game version is not compatible with mod");
|
||||
SPDLOG_ERROR("Please note that your game version has not been officially tested with this mod, therefore expect bugs, glitches or the mod to completely stop working. If so, please {}", EGSDK::Core::gameVer > GAME_VER_COMPAT ? "wait for a new patch." : "upgrade your game version to one that the mod supports.");
|
||||
} else
|
||||
SPDLOG_DEBUG("Game version is compatible with mod");
|
||||
}
|
||||
DWORD64 WINAPI MainThread(HMODULE hModule) {
|
||||
EGSDK::GamePH::Hooks::OnPostUpdateHook.RegisterCallback(OnPostUpdate);
|
||||
|
||||
@ -291,9 +282,6 @@ namespace EGT::Core {
|
||||
SetUnhandledExceptionFilter(CrashHandler);
|
||||
#endif
|
||||
|
||||
SPDLOG_INFO("Running game version checks");
|
||||
GameVersionCheck();
|
||||
|
||||
SPDLOG_INFO("Initializing config");
|
||||
Config::InitConfig();
|
||||
threads.emplace_back(Config::ConfigLoop);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <EGSDK\Utils\Time.h>
|
||||
#include <EGSDK\Utils\WinMemory.h>
|
||||
#include <EGSDK\GamePH\LevelDI.h>
|
||||
#include <EGSDK\Engine\RendererCVars.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
#include <EGSDK\Engine\CBaseCamera.h>
|
||||
#include <EGSDK\Engine\Engine_Misc.h>
|
||||
#include <EGSDK\GamePH\FreeCamera.h>
|
||||
@ -269,20 +269,71 @@ namespace EGT::Engine {
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UpdateVarFloat
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(uint64_t, uint64_t, float*, uint64_t, uint64_t), uint64_t, uint64_t, float*, uint64_t, uint64_t> UpdateCVarFloatHook{ "UpdateCVarFloat", &EGSDK::OffsetManager::Get_UpdateCVarFloat, [](uint64_t a1, uint64_t a2, float* varValue, uint64_t a4, uint64_t a5) -> void {
|
||||
UpdateCVarFloatHook.ExecuteOriginal(a1, a2, varValue, a4, a5);
|
||||
const char* name = reinterpret_cast<const char*>(a1 - 0x60);
|
||||
#pragma region GetCVarT
|
||||
EGSDK::Utils::Hook::MHook<void*, EGSDK::Engine::CVar*(*)(uint64_t, const char*, uint64_t, int), uint64_t, const char*, uint64_t, int> GetCVarTHook{ "GetCVarT", &EGSDK::OffsetManager::Get_GetCVarT, [](uint64_t pEvent, const char* name, uint64_t eventType, int someFlag) -> EGSDK::Engine::CVar* {
|
||||
EGSDK::Engine::CVar* cVarPtr = GetCVarTHook.ExecuteOriginal(pEvent, name, eventType, someFlag);
|
||||
if (!cVarPtr)
|
||||
return cVarPtr;
|
||||
if (EGSDK::Engine::CVars::vars.Find(name))
|
||||
return cVarPtr;
|
||||
|
||||
auto floatRendererCVar = reinterpret_cast<EGSDK::Engine::FloatRendererCVar*>(EGSDK::Engine::RendererCVars::rendererCVars.Find(a1));
|
||||
if (!floatRendererCVar)
|
||||
floatRendererCVar = reinterpret_cast<EGSDK::Engine::FloatRendererCVar*>(EGSDK::Engine::RendererCVars::rendererCVars.try_emplace(std::make_unique<EGSDK::Engine::FloatRendererCVar>(name, a1)).get());
|
||||
switch (eventType - pEvent) {
|
||||
case 0x1A8:
|
||||
{
|
||||
cVarPtr->SetName(name);
|
||||
cVarPtr->SetType(EGSDK::Engine::VarType::Float);
|
||||
EGSDK::Engine::CVars::vars.try_emplace(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
|
||||
break;
|
||||
}
|
||||
case 0x198:
|
||||
{
|
||||
cVarPtr->SetName(name);
|
||||
cVarPtr->SetType(EGSDK::Engine::VarType::Int);
|
||||
EGSDK::Engine::CVars::vars.try_emplace(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auto customFloatRendererCVar = reinterpret_cast<EGSDK::Engine::FloatRendererCVar*>(EGSDK::Engine::RendererCVars::customRendererCVars.Find(a1));
|
||||
if (customFloatRendererCVar)
|
||||
*varValue = customFloatRendererCVar->GetValue();
|
||||
else if (floatRendererCVar)
|
||||
floatRendererCVar->SetValue(*varValue);
|
||||
return cVarPtr;
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
#pragma region GetCVarValue
|
||||
static std::unordered_map<uint32_t, uint64_t*> cVarValuePtrs;
|
||||
static EGSDK::Utils::Hook::MHook<void*, uint64_t*(*)(uint64_t, uint32_t, int), uint64_t, uint32_t, int> GetCVarValueHook{ "GetCVarValue", &EGSDK::OffsetManager::Get_GetCVarValue, [](uint64_t a1, uint32_t valueOffset, int a3) -> uint64_t* {
|
||||
uint64_t* varValuePtr = GetCVarValueHook.ExecuteOriginal(a1, valueOffset, a3);
|
||||
if (!varValuePtr)
|
||||
return varValuePtr;
|
||||
|
||||
EGSDK::Engine::CVar* cVar = EGSDK::Engine::CVars::vars.Find(valueOffset);
|
||||
if (!cVar)
|
||||
return varValuePtr;
|
||||
cVar->AddValuePtr(varValuePtr);
|
||||
|
||||
EGSDK::Engine::CVar* customCVar = EGSDK::Engine::CVars::customVars.Find(cVar->GetName());
|
||||
if (!customCVar)
|
||||
return varValuePtr;
|
||||
|
||||
switch (cVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<float>(customCVar);
|
||||
if (value)
|
||||
cVar->SetValue(*value);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<int>(customCVar);
|
||||
if (value)
|
||||
cVar->SetValue(*value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return varValuePtr;
|
||||
} };
|
||||
#pragma endregion
|
||||
|
||||
|
@ -108,7 +108,7 @@ namespace EGT::GamePH {
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ShowTPPModelFunc3
|
||||
ImGui::Option wannaUseTPPModel{};
|
||||
ImGui::Option wannaUseTPPModel{ false };
|
||||
static bool prevUseTPPModel;
|
||||
|
||||
static EGSDK::Utils::Hook::MHook<void*, void(*)(uint64_t, bool), uint64_t, bool> ShowTPPModelFunc3Hook{ "ShowTPPModelFunc3", &EGSDK::OffsetManager::Get_ShowTPPModelFunc3, [](uint64_t tppFunc2Addr, bool showTPPModel) -> void {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <Windows.h>
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <Windows.h>
|
||||
#include <dinput.h>
|
||||
#include <spdlog\spdlog.h>
|
||||
#include <ImGui\imgui_hotkey.h>
|
||||
|
@ -21,18 +21,18 @@ namespace EGT::Menu {
|
||||
EGSDK::Vec3 cameraOffset{};
|
||||
float firstPersonFOV = baseFOV;
|
||||
float originalFirstPersonFOVAfterZoomIn = firstPersonFOV;
|
||||
ImGui::KeyBindOption firstPersonZoomIn{ 'Q' , false };
|
||||
ImGui::KeyBindOption firstPersonZoomIn{ false, 'Q', false };
|
||||
static bool isZoomingIn = false;
|
||||
|
||||
ImGui::Option photoMode{ false };
|
||||
|
||||
ImGui::KeyBindOption freeCam{ VK_F3 };
|
||||
ImGui::KeyBindOption freeCam{ false, VK_F3 };
|
||||
float freeCamFOV = baseFOV;
|
||||
float freeCamSpeed = 2.0f;
|
||||
ImGui::KeyBindOption teleportPlayerToCamera{ VK_F4 };
|
||||
ImGui::KeyBindOption teleportPlayerToCamera{ false, VK_F4 };
|
||||
|
||||
ImGui::KeyBindOption thirdPersonCamera{ VK_F1 };
|
||||
ImGui::KeyBindOption tpUseTPPModel{ VK_F2 };
|
||||
ImGui::KeyBindOption thirdPersonCamera{ false, VK_F1 };
|
||||
ImGui::KeyBindOption tpUseTPPModel{ false, VK_F2 };
|
||||
float thirdPersonFOV = baseFOV;
|
||||
float thirdPersonDistanceBehindPlayer = 2.0f;
|
||||
float thirdPersonHeightAbovePlayer = 1.3f;
|
||||
@ -40,10 +40,10 @@ namespace EGT::Menu {
|
||||
|
||||
float lensDistortion = 20.0f;
|
||||
static float altLensDistortion = lensDistortion;
|
||||
ImGui::KeyBindOption goProMode{ VK_NONE };
|
||||
ImGui::KeyBindOption disableSafezoneFOVReduction{ VK_NONE };
|
||||
ImGui::KeyBindOption disablePhotoModeLimits{ VK_NONE };
|
||||
ImGui::KeyBindOption disableHeadCorrection{ VK_NONE };
|
||||
ImGui::KeyBindOption goProMode{ false, VK_NONE };
|
||||
ImGui::KeyBindOption disableSafezoneFOVReduction{ false, VK_NONE };
|
||||
ImGui::KeyBindOption disablePhotoModeLimits{ false, VK_NONE };
|
||||
ImGui::KeyBindOption disableHeadCorrection{ false, VK_NONE };
|
||||
|
||||
static void CalculateBaseFOV() {
|
||||
if (!EGSDK::Utils::Values::are_samef(baseFOV, 0.0f))
|
||||
|
@ -61,14 +61,12 @@ namespace EGT::Menu {
|
||||
ImGui::TextCentered(thankYou.c_str());
|
||||
ImGui::Spacing(ImVec2(0.0f, 5.0f));
|
||||
|
||||
const std::string gameCompat = "This version of the mod is compatible with game version v" + EGSDK::GamePH::GameVerToStr(GAME_VER_COMPAT) + ".";
|
||||
const std::string gameCompat = "This version of the mod is compatible with game versions: " + EGSDK::Core::GetSupportedGameVersionsStr() + ".";
|
||||
ImGui::TextCentered(gameCompat.c_str());
|
||||
const std::string gameVer = "The game version you are currently running is v" + EGSDK::GamePH::GameVerToStr(EGSDK::Core::gameVer) + ".";
|
||||
ImGui::TextCentered(gameVer.c_str());
|
||||
if (EGSDK::Core::gameVer != GAME_VER_COMPAT) {
|
||||
const std::string gameNotCompat = "Please note that your game version has not been officially tested with this mod, therefore expect bugs, glitches or the mod to completely stop working. If so, please " + std::string(EGSDK::Core::gameVer > GAME_VER_COMPAT ? "wait for a new patch." : "upgrade your game version to one that the mod supports.");
|
||||
ImGui::TextCenteredColored(gameNotCompat.c_str(), IM_COL32(200, 0, 0, 255));
|
||||
}
|
||||
if (!EGSDK::Core::IsGameVerCompatible())
|
||||
ImGui::TextCenteredColored("Please note that your game version has not been officially tested with this mod, therefore expect bugs, glitches or the mod to completely stop working. If so, please upgrade or downgrade your game version to one that the mod supports.", IM_COL32(200, 0, 0, 255));
|
||||
ImGui::Spacing(ImVec2(0.0f, 5.0f));
|
||||
ImGui::TextCentered("I will not bore you with what this mod is about, so let's get right to teaching you how to use it!");
|
||||
|
||||
|
@ -19,7 +19,7 @@ namespace EGT::Menu {
|
||||
static constexpr ImVec2 defMaxWndSize = ImVec2(900.0f, 725.0f);
|
||||
static ImVec2 maxWndSize = defMaxWndSize;
|
||||
|
||||
ImGui::KeyBindOption menuToggle{ VK_F5 };
|
||||
ImGui::KeyBindOption menuToggle{ false, VK_F5 };
|
||||
float opacity = 99.0f;
|
||||
float scale = 1.0f;
|
||||
|
||||
@ -41,7 +41,7 @@ namespace EGT::Menu {
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowWidth() / 2.0f) - (EGTLogoSize.x / 2.0f));
|
||||
ImGui::Image(EGTLogoTexture, EGTLogoSize);
|
||||
|
||||
const float footerHeight = ImGui::GetFrameHeightWithSpacing() * 3.0f + (EGSDK::Core::gameVer != GAME_VER_COMPAT ? (ImGui::CalcTextSize("").y * 2.0f) + GImGui->Style.FramePadding.y + GImGui->Style.ItemSpacing.y : 0.0f) + GImGui->Style.WindowPadding.y * 2.0f + GImGui->Style.FramePadding.y * 2.0f;
|
||||
const float footerHeight = ImGui::GetFrameHeightWithSpacing() * 3.0f + (!EGSDK::Core::IsGameVerCompatible() ? (ImGui::CalcTextSize("").y * 2.0f) + GImGui->Style.FramePadding.y + GImGui->Style.ItemSpacing.y : 0.0f) + GImGui->Style.WindowPadding.y * 2.0f + GImGui->Style.FramePadding.y * 2.0f;
|
||||
const float remainingHeight = ImGui::GetContentRegionAvail().y - footerHeight;
|
||||
|
||||
if (ImGui::BeginTabBar("##MainTabBar")) {
|
||||
@ -51,7 +51,7 @@ namespace EGT::Menu {
|
||||
ImGui::SpanNextTabAcrossWidth(childWidth, MenuTab::GetInstances()->size());
|
||||
if (ImGui::BeginTabItem(tab.second->tabName.data())) {
|
||||
ImGui::SetNextWindowBgAlpha(static_cast<float>(opacity) / 100.0f);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(std::fmax(minWndSize.x - GImGui->Style.WindowPadding.x * 2.0f, ImGui::CalcTextSize(EGSDK::Core::gameVer > GAME_VER_COMPAT ? "Please wait for a new mod update." : "Upgrade your game version to one that the mod supports.").x), remainingHeight), ImVec2(maxWndSize.x - GImGui->Style.WindowPadding.x * 2.0f, remainingHeight));
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(EGSDK::Core::IsGameVerCompatible() ? minWndSize.x - GImGui->Style.WindowPadding.x * 2.0f : std::fmax(minWndSize.x - GImGui->Style.WindowPadding.x * 2.0f, ImGui::CalcTextSize(std::string("Compatible game versions: %s" + EGSDK::Core::GetSupportedGameVersionsStr()).c_str()).x), remainingHeight), ImVec2(maxWndSize.x - GImGui->Style.WindowPadding.x * 2.0f, remainingHeight));
|
||||
|
||||
ImGui::BeginDisabled(!EGSDK::GamePH::Hooks::didOnPostUpdateHookExecute);
|
||||
if (ImGui::BeginChild("##TabChild", ImVec2(0.0f, 0.0f), ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_Border)) {
|
||||
@ -70,9 +70,9 @@ namespace EGT::Menu {
|
||||
ImGui::Hotkey("Menu Toggle Key", &menuToggle);
|
||||
ImGui::SliderFloat("Menu Opacity", &opacity, 0.0f, 100.0f, "%.1f%%", ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::SliderFloat("Menu Scale", &scale, 1.0f, 2.5f, "%.1f%%", ImGuiSliderFlags_AlwaysClamp);
|
||||
if (EGSDK::Core::gameVer != GAME_VER_COMPAT) {
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(IM_COL32(200, 0, 0, 255)), "Incompatible game version detected!");
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(IM_COL32(200, 0, 0, 255)), "Compatible game version: v%s", EGSDK::GamePH::GameVerToStr(GAME_VER_COMPAT).c_str());
|
||||
if (!EGSDK::Core::IsGameVerCompatible()) {
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(IM_COL32(200, 0, 0, 255)), "Incompatible game version (v%s) detected!", EGSDK::GamePH::GameVerToStr(EGSDK::Core::gameVer).c_str());
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(IM_COL32(200, 0, 0, 255)), "Compatible game versions: %s", EGSDK::Core::GetSupportedGameVersionsStr().c_str());
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <ImGui\imgui_hotkey.h>
|
||||
#include <ImGui\imguiex.h>
|
||||
#include <EGSDK\Utils\Hook.h>
|
||||
#include <EGSDK\Engine\RendererCVars.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
#include <EGSDK\GamePH\GameDI_PH.h>
|
||||
#include <EGSDK\GamePH\LevelDI.h>
|
||||
#include <EGT\ImGui_impl\DeferredActions.h>
|
||||
@ -10,8 +10,8 @@
|
||||
|
||||
namespace EGT::Menu {
|
||||
namespace Misc {
|
||||
ImGui::KeyBindOption disableGamePauseWhileAFK{ VK_NONE };
|
||||
ImGui::KeyBindOption disableHUD{ VK_F8 };
|
||||
ImGui::KeyBindOption disableGamePauseWhileAFK{ false, VK_NONE };
|
||||
ImGui::KeyBindOption disableHUD{ false, VK_F8 };
|
||||
ImGui::Option disableSavegameCRCCheck{ false };
|
||||
ImGui::Option disableDataPAKsCRCCheck{ false };
|
||||
ImGui::Option increaseDataPAKsLimit{ false };
|
||||
@ -23,57 +23,105 @@ namespace EGT::Menu {
|
||||
disableHUD.SetChangesAreDisabled(!iLevel || !iLevel->IsLoaded());
|
||||
}
|
||||
|
||||
static bool ShouldDisplayVariable(const std::unique_ptr<EGSDK::Engine::RendererCVar>& rendererCVarPtr, const std::string& searchFilter) {
|
||||
if (rendererCVarPtr->GetType() == EGSDK::Engine::RendererCVarType::NONE)
|
||||
return false;
|
||||
if (EGSDK::Utils::Values::are_samef(reinterpret_cast<EGSDK::Engine::FloatRendererCVar*>(rendererCVarPtr.get())->GetValue(), -404.0f))
|
||||
static bool ShouldDisplayVariable(const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr, const std::string& searchFilter) {
|
||||
if (cVarPtr->GetType() == EGSDK::Engine::VarType::NONE)
|
||||
return false;
|
||||
if (searchFilter.empty())
|
||||
return true;
|
||||
|
||||
// Convert searchFilter and variable name to lowercase
|
||||
std::string lowerFilter = EGSDK::Utils::Values::to_lower(searchFilter);
|
||||
std::string lowerKey = EGSDK::Utils::Values::to_lower(rendererCVarPtr->GetName());
|
||||
std::string lowerKey = EGSDK::Utils::Values::to_lower(cVarPtr->GetName());
|
||||
return lowerKey.find(lowerFilter) != std::string::npos;
|
||||
}
|
||||
static void RestoreVariableToDefault(const std::string& name) {
|
||||
ImGui_impl::DeferredActions::Add([name]() {
|
||||
auto defRendererCVar = EGSDK::Engine::RendererCVars::defaultRendererCVars.Find(name);
|
||||
if (!defRendererCVar)
|
||||
return;
|
||||
static void RestoreVariableToDefault(const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
auto cVar = cVarPtr.get();
|
||||
|
||||
EGSDK::Engine::RendererCVars::ChangeRendererCVar(name, reinterpret_cast<EGSDK::Engine::FloatRendererCVar*>(defRendererCVar)->GetValue());
|
||||
ImGui_impl::DeferredActions::Add([cVar]() {
|
||||
switch (cVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto defValue = EGSDK::Engine::CVars::GetVarValueFromMap<float>(cVar->GetName(), EGSDK::Engine::CVars::defaultVars);
|
||||
if (!defValue)
|
||||
return;
|
||||
|
||||
EGSDK::Engine::RendererCVars::defaultRendererCVars.Erase(name);
|
||||
EGSDK::Engine::RendererCVars::customRendererCVars.Erase(name);
|
||||
EGSDK::Engine::CVars::ChangeVar(cVar->GetName(), *defValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
{
|
||||
auto defValue = EGSDK::Engine::CVars::GetVarValueFromMap<int>(cVar->GetName(), EGSDK::Engine::CVars::defaultVars);
|
||||
if (!defValue)
|
||||
return;
|
||||
|
||||
EGSDK::Engine::CVars::ChangeVar(cVar->GetName(), *defValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EGSDK::Engine::CVars::defaultVars.Erase(cVar->GetName());
|
||||
EGSDK::Engine::CVars::customVars.Erase(cVar->GetName());
|
||||
});
|
||||
}
|
||||
static void RenderRendererCVar(const std::unique_ptr<EGSDK::Engine::RendererCVar>& rendererCVarPtr) {
|
||||
auto rendererCVar = rendererCVarPtr.get();
|
||||
static void RestoreVariablesToDefault() {
|
||||
EGSDK::Engine::CVars::customVars.ForEach([](const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
RestoreVariableToDefault(cVarPtr);
|
||||
});
|
||||
}
|
||||
static void RenderRendererCVar(const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
auto cVar = cVarPtr.get();
|
||||
|
||||
float newValue = reinterpret_cast<EGSDK::Engine::FloatRendererCVar*>(rendererCVar)->GetValue();
|
||||
if (ImGui::InputFloat(rendererCVar->GetName(), &newValue))
|
||||
EGSDK::Engine::RendererCVars::ChangeRendererCVarFromList(rendererCVar->GetName(), newValue, rendererCVar);
|
||||
switch (cVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<float>(cVar);
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat(cVar->GetName(), &newValue))
|
||||
EGSDK::Engine::CVars::ChangeVarFromList(cVar, newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<int>(cVar);
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputInt(cVar->GetName(), &newValue))
|
||||
EGSDK::Engine::CVars::ChangeVarFromList(cVar, newValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
std::string restoreBtnName = "Restore##" + std::string(rendererCVarPtr->GetName());
|
||||
std::string restoreBtnName = "Restore##" + std::string(cVar->GetName());
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::Engine::RendererCVars::customRendererCVars.none_of(rendererCVarPtr->GetName()));
|
||||
ImGui::BeginDisabled(EGSDK::Engine::CVars::customVars.none_of(cVar->GetName()));
|
||||
if (ImGui::Button(restoreBtnName.c_str(), "Restores renderer cvar to default"))
|
||||
RestoreVariableToDefault(rendererCVarPtr->GetName());
|
||||
RestoreVariableToDefault(cVarPtr);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
static void HandleRendererCVarsList() {
|
||||
ImGui::BeginDisabled(EGSDK::Engine::RendererCVars::rendererCVars.empty());
|
||||
ImGui::BeginDisabled(EGSDK::Engine::CVars::vars.empty());
|
||||
if (ImGui::CollapsingHeader("Renderer CVars list", ImGuiTreeNodeFlags_None)) {
|
||||
ImGui::Indent();
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::Engine::CVars::customVars.empty());
|
||||
if (ImGui::Button("Restore variables to default"))
|
||||
RestoreVariablesToDefault();
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::InputTextWithHint("##RendererCVarsSearch", "Search variables", rendererCVarsSearchFilter, 64);
|
||||
|
||||
EGSDK::Engine::RendererCVars::rendererCVars.ForEach([](std::unique_ptr<EGSDK::Engine::RendererCVar>& rendererCVarPtr) {
|
||||
if (ShouldDisplayVariable(rendererCVarPtr, rendererCVarsSearchFilter))
|
||||
RenderRendererCVar(rendererCVarPtr);
|
||||
EGSDK::Engine::CVars::vars.ForEach([](std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
if (ShouldDisplayVariable(cVarPtr, rendererCVarsSearchFilter))
|
||||
RenderRendererCVar(cVarPtr);
|
||||
});
|
||||
|
||||
ImGui::Unindent();
|
||||
|
@ -30,18 +30,18 @@ namespace EGT::Menu {
|
||||
float playerImmunity = 80.0f;
|
||||
float playerMaxImmunity = 80.0f;
|
||||
int oldWorldMoney = 0;
|
||||
ImGui::KeyBindOption godMode{ VK_F6 };
|
||||
ImGui::KeyBindOption freezePlayer{ VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedImmunity{ VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedStamina{ VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedItems{ VK_NONE };
|
||||
ImGui::KeyBindOption oneHitKill{ VK_NONE };
|
||||
ImGui::KeyBindOption invisibleToEnemies{ VK_NONE };
|
||||
ImGui::KeyBindOption disableOutOfBoundsTimer{ VK_NONE };
|
||||
ImGui::KeyBindOption nightrunnerMode{ VK_F7 };
|
||||
ImGui::KeyBindOption oneHandedMode{ VK_NONE };
|
||||
ImGui::KeyBindOption disableSafezoneRestrictions{ VK_NONE };
|
||||
ImGui::KeyBindOption disableAirControl{ VK_NONE };
|
||||
ImGui::KeyBindOption godMode{ false, VK_F6 };
|
||||
ImGui::KeyBindOption freezePlayer{ false, VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedImmunity{ false, VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedStamina{ false, VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedItems{ false, VK_NONE };
|
||||
ImGui::KeyBindOption oneHitKill{ false, VK_NONE, true, { 11200 } };
|
||||
ImGui::KeyBindOption invisibleToEnemies{ false, VK_NONE };
|
||||
ImGui::KeyBindOption disableOutOfBoundsTimer{ false, VK_NONE };
|
||||
ImGui::KeyBindOption nightrunnerMode{ false, VK_F7 };
|
||||
ImGui::KeyBindOption oneHandedMode{ false, VK_NONE };
|
||||
ImGui::KeyBindOption disableSafezoneRestrictions{ false, VK_NONE };
|
||||
ImGui::KeyBindOption disableAirControl{ false, VK_NONE };
|
||||
ImGui::Option playerVariables{ false };
|
||||
|
||||
std::string saveSCRPath{};
|
||||
@ -559,7 +559,9 @@ namespace EGT::Menu {
|
||||
ImGui::CheckboxHotkey("Unlimited Stamina", &unlimitedStamina, "Stops stamina from draining");
|
||||
ImGui::CheckboxHotkey("Unlimited Items", &unlimitedItems, "Stops the game from lowering the amount of items such as consumables / throwables when using them, alongside other inventory items such as ammo, lockpicks and other items;\nWARNING: This will not stop the item from getting removed from your inventory if you drop the entire amount\nCurrently, if the amount of item is 1, it will still drop from your inventory unfortunately");
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::CheckboxHotkey("One-Hit Kill", &oneHitKill, "Makes the player one-hit kill EVERYTHING and EVERYONE RAWRRR");
|
||||
|
||||
ImGui::CheckboxHotkey("Invisible to Enemies", &invisibleToEnemies, "Makes the player invisible to the enemies");
|
||||
ImGui::SameLine();
|
||||
ImGui::CheckboxHotkey("Disable Out of Bounds Timer", &disableOutOfBoundsTimer, "Disables the timer that runs when out of map bounds or mission bounds");
|
||||
|
@ -24,9 +24,9 @@ namespace EGT::Menu {
|
||||
bool justTeleportedToWaypoint = false;
|
||||
static EGSDK::Vec3 teleportCoords{};
|
||||
|
||||
ImGui::KeyBindOption teleportToSelectedLocation{ VK_F9 };
|
||||
ImGui::KeyBindOption teleportToCoords{ VK_NONE };
|
||||
ImGui::KeyBindOption teleportToWaypoint{ VK_F10 };
|
||||
ImGui::KeyBindOption teleportToSelectedLocation{ false, VK_F9 };
|
||||
ImGui::KeyBindOption teleportToCoords{ false, VK_NONE };
|
||||
ImGui::KeyBindOption teleportToWaypoint{ false, VK_F10 };
|
||||
|
||||
void UpdateTeleportLocationVisualNames() {
|
||||
savedTeleportLocationNames.clear();
|
||||
|
@ -9,11 +9,11 @@
|
||||
namespace EGT::Menu {
|
||||
namespace Weapon {
|
||||
float currentWeaponDurability = 0.0f;
|
||||
ImGui::KeyBindOption unlimitedDurability{ VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedAmmo{ VK_NONE };
|
||||
ImGui::KeyBindOption noSpread{ VK_NONE };
|
||||
ImGui::KeyBindOption noRecoil{ VK_NONE };
|
||||
ImGui::KeyBindOption instantReload{ VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedDurability{ false, VK_NONE };
|
||||
ImGui::KeyBindOption unlimitedAmmo{ false, VK_NONE };
|
||||
ImGui::KeyBindOption noSpread{ false, VK_NONE };
|
||||
ImGui::KeyBindOption noRecoil{ false, VK_NONE };
|
||||
ImGui::KeyBindOption instantReload{ false, VK_NONE };
|
||||
|
||||
static constexpr float baseWeaponDurabilityMul = 1.0f;
|
||||
static constexpr float baseWeaponAccuracyMul = 1.0f;
|
||||
|
@ -18,8 +18,8 @@ namespace EGT::Menu {
|
||||
static bool isModifyingGameSpeed = false;
|
||||
static float actualGameSpeed = gameSpeed;
|
||||
static float gameSpeedBeforeSlowMo = gameSpeed;
|
||||
ImGui::KeyBindOption freezeTime{ VK_NONE };
|
||||
ImGui::KeyBindOption slowMotion{ '4' };
|
||||
ImGui::KeyBindOption freezeTime{ false, VK_NONE };
|
||||
ImGui::KeyBindOption slowMotion{ false, '4' };
|
||||
float slowMotionSpeed = 0.4f;
|
||||
static float slowMotionSpeedLerp = gameSpeed;
|
||||
float slowMotionTransitionTime = 1.0f;
|
||||
|
Reference in New Issue
Block a user