mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 17:37:53 +08:00
- working VarManagerBase for player variables too
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
#include <EGSDK\Engine\VarManagerBase.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
#include <EGSDK\GamePH\PlayerVariables.h>
|
||||
#include <EGSDK\Vec4.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
@ -22,14 +23,19 @@ namespace EGSDK::Engine {
|
||||
std::unordered_map<std::string, uint64_t> VarManagerBase<VarMapType, VarType>::varOwnerMap{};
|
||||
#endif
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarType* VarManagerBase<VarMapType, VarType>::GetVar(const std::string& name) {
|
||||
return vars.Find(name);
|
||||
}
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::IsVarManagedByBool(const std::string& name) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
return prevBoolValueMap.find(name) != prevBoolValueMap.end() && prevBoolValueMap[name];
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::DoesVarHaveCustomValue(const std::string& name) {
|
||||
return !customVars.none_of(cVar->GetName());
|
||||
return !customVars.none_of(name);
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::AreAnyVarsPresent() {
|
||||
@ -54,4 +60,5 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
|
||||
template EGameSDK_API class VarManagerBase<CVarMap, CVar>;
|
||||
template EGameSDK_API class VarManagerBase<GamePH::PlayerVarMap, GamePH::PlayerVar>;
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
#include <EGSDK\Engine\VarMapBase.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
#include <EGSDK\GamePH\PlayerVariables.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);
|
||||
std::lock_guard lock(mutex);
|
||||
const std::string& name = var->GetName();
|
||||
auto [it, inserted] = vars.try_emplace(name, std::move(var));
|
||||
if (inserted)
|
||||
@ -13,35 +14,35 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
template <typename VarType>
|
||||
bool VarMapBase<VarType>::empty() const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard 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);
|
||||
std::lock_guard 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);
|
||||
std::lock_guard lock(mutex);
|
||||
vars.reserve(count);
|
||||
}
|
||||
template <typename VarType>
|
||||
size_t VarMapBase<VarType>::size() {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
return vars.size();
|
||||
}
|
||||
|
||||
template <typename VarType>
|
||||
VarType* VarMapBase<VarType>::Find(const std::string& name) const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard 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);
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = vars.find(name);
|
||||
if (it == vars.end())
|
||||
return;
|
||||
@ -54,4 +55,5 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
|
||||
template EGameSDK_API class VarMapBase<CVar>;
|
||||
template EGameSDK_API class VarMapBase<GamePH::PlayerVar>;
|
||||
}
|
@ -5,9 +5,12 @@
|
||||
#include <unordered_map>
|
||||
#include <intrin.h>
|
||||
#include <variant>
|
||||
#include <optional>
|
||||
#include <EGSDK\Exports.h>
|
||||
#include <EGSDK\Vec3.h>
|
||||
#include <EGSDK\Vec4.h>
|
||||
#include <EGSDK\Utils\Values.h>
|
||||
#include <EGSDK\Engine\VarBase.h>
|
||||
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
|
||||
@ -22,35 +25,71 @@ namespace EGSDK::Engine {
|
||||
static VarMapType defaultVars;
|
||||
|
||||
template <typename T>
|
||||
static T* GetVarValue(const std::string& name) {
|
||||
static std::optional<T> GetVarValue(const std::string& name) {
|
||||
StaticAssertValueType;
|
||||
auto var = vars.Find(name);
|
||||
return var ? std::get_if<T>(&var->GetValue()) : nullptr;
|
||||
if (!var)
|
||||
return std::nullopt;
|
||||
auto value = var->GetValue();
|
||||
auto variantValue = std::get_if<T>(&value);
|
||||
return variantValue ? std::optional<T>(*variantValue) : std::nullopt;
|
||||
}
|
||||
template <typename T>
|
||||
static T* GetVarValue(VarType* var) {
|
||||
static std::optional<T> GetVarValue(VarType* var) {
|
||||
StaticAssertValueType;
|
||||
return var ? std::get_if<T>(&var->GetValue()) : nullptr;
|
||||
if (!var)
|
||||
return std::nullopt;
|
||||
auto value = var->GetValue();
|
||||
auto variantValue = std::get_if<T>(&value);
|
||||
return variantValue ? std::optional<T>(*variantValue) : std::nullopt;
|
||||
}
|
||||
template <typename T>
|
||||
static T* GetVarValueFromMap(const std::string& name, const VarMapType& map) {
|
||||
static std::optional<T> GetVarValueFromMap(const std::string& name, const VarMapType& map) {
|
||||
StaticAssertValueType;
|
||||
auto var = map.Find(name);
|
||||
return var ? std::get_if<T>(&var->GetValue()) : nullptr;
|
||||
return GetVarValue<T>(var);
|
||||
}
|
||||
|
||||
static VarType* GetVar(const std::string& name);
|
||||
|
||||
template <typename T>
|
||||
static void ChangeVar(const std::string& name, T value) {
|
||||
StaticAssertValueType;
|
||||
auto var = vars.Find(name);
|
||||
if (var)
|
||||
var->SetValue(value);
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
ChangeVar<T>(var, value);
|
||||
}
|
||||
template <typename T>
|
||||
static void ChangeVar(VarType* var, T value) {
|
||||
StaticAssertValueType;
|
||||
if (var)
|
||||
var->SetValue(value);
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
switch (var->GetType()) {
|
||||
case Engine::VarType::Float:
|
||||
ChangeVar<float>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Int:
|
||||
ChangeVar<int>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Bool:
|
||||
ChangeVar<bool>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
var->SetValue(value);
|
||||
}
|
||||
template <typename T>
|
||||
static void ChangeVarFromMap(const std::string& name, T value, const VarMapType& map) {
|
||||
StaticAssertValueType;
|
||||
auto var = map.Find(name);
|
||||
ChangeVar<T>(var, value);
|
||||
}
|
||||
template <typename T>
|
||||
static void ChangeVarFromList(const std::string& name, T value) {
|
||||
@ -72,6 +111,21 @@ namespace EGSDK::Engine {
|
||||
auto customVar = customVars.Find(var->GetName());
|
||||
auto defVar = defaultVars.Find(var->GetName());
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
switch (var->GetType()) {
|
||||
case Engine::VarType::Float:
|
||||
ChangeVarFromList<float>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Int:
|
||||
ChangeVarFromList<int>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Bool:
|
||||
ChangeVarFromList<bool>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!customVar)
|
||||
customVar = customVars.try_emplace(std::make_unique<VarType>(var->GetName(), var->GetType())).get();
|
||||
if (!defVar) {
|
||||
@ -89,7 +143,7 @@ namespace EGSDK::Engine {
|
||||
static void ManageVarByBool(const std::string& name, T valueIfTrue, T valueIfFalse, bool boolVal, bool usePreviousVal = true) {
|
||||
uint64_t caller = reinterpret_cast<uint64_t>(_ReturnAddress());
|
||||
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
auto ownerIt = varOwnerMap.find(name);
|
||||
if (ownerIt != varOwnerMap.end() && ownerIt->second != caller)
|
||||
@ -125,7 +179,7 @@ namespace EGSDK::Engine {
|
||||
static bool AreAllCustomVarsManagedByBool();
|
||||
|
||||
template <typename T>
|
||||
static void RestoreVariableToDefault(VarType* var) {
|
||||
static void RestoreVariableToDefault(VarType* var, bool eraseFromMaps = true) {
|
||||
if (IsVarManagedByBool(var->GetName()))
|
||||
return;
|
||||
|
||||
@ -135,8 +189,26 @@ namespace EGSDK::Engine {
|
||||
|
||||
ChangeVar(var->GetName(), *defValue);
|
||||
|
||||
defaultVars.Erase(var->GetName());
|
||||
customVars.Erase(var->GetName());
|
||||
if (eraseFromMaps) {
|
||||
defaultVars.Erase(var->GetName());
|
||||
customVars.Erase(var->GetName());
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
static void RestoreVariableToDefaultFromMap(VarType* var, VarMapType& map, bool eraseFromMaps = true) {
|
||||
if (IsVarManagedByBool(var->GetName()))
|
||||
return;
|
||||
|
||||
auto defValue = GetVarValueFromMap<T>(var->GetName(), map);
|
||||
if (!defValue)
|
||||
return;
|
||||
|
||||
ChangeVar(var->GetName(), *defValue);
|
||||
|
||||
if (eraseFromMaps) {
|
||||
map.Erase(var->GetName());
|
||||
customVars.Erase(var->GetName());
|
||||
}
|
||||
}
|
||||
private:
|
||||
static std::unordered_map<std::string, std::any> prevVarValueMap;
|
||||
|
@ -31,7 +31,7 @@ namespace EGSDK::Engine {
|
||||
|
||||
template <typename Callable, typename... Args>
|
||||
void ForEach(Callable&& func, Args&&... args) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
for (const auto& name : varsOrdered)
|
||||
func(vars.at(name), std::forward<Args>(args)...);
|
||||
}
|
||||
|
@ -1,134 +1,59 @@
|
||||
#pragma once
|
||||
#include <any>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <EGSDK\ClassHelpers.h>
|
||||
#include <EGSDK\Utils\Values.h>
|
||||
#include <EGSDK\Engine\VarBase.h>
|
||||
#include <EGSDK\Engine\VarMapBase.h>
|
||||
#include <EGSDK\Engine\VarManagerBase.h>
|
||||
|
||||
namespace EGSDK::GamePH {
|
||||
enum EGameSDK_API PlayerVarType {
|
||||
NONE = 0,
|
||||
String,
|
||||
Float,
|
||||
Bool
|
||||
};
|
||||
|
||||
class EGameSDK_API PlayerVariable {
|
||||
public:
|
||||
PlayerVariable(const std::string& name);
|
||||
|
||||
const char* GetName();
|
||||
void SetName(const std::string& newName);
|
||||
|
||||
PlayerVarType GetType();
|
||||
void SetType(PlayerVarType newType);
|
||||
private:
|
||||
static std::unordered_map<PlayerVariable*, std::string> playerVarNames;
|
||||
static std::unordered_map<PlayerVariable*, PlayerVarType> playerVarTypes;
|
||||
static std::mutex mutex;
|
||||
};
|
||||
|
||||
class EGameSDK_API StringPlayerVariable : public PlayerVariable {
|
||||
class EGameSDK_API PlayerVar : public Engine::VarBase {
|
||||
public:
|
||||
union {
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x8, const char*> value; // remove 0x2 bit to access ptr
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x10, const char*> defaultValue; // remove 0x2 bit to access ptr
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x8, const char*> strValue;
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x8, float> floatValue;
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x8, bool> boolValue;
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x10, const char*> defaultStrValue; // remove 0x2 bit to access ptr
|
||||
EGSDK::ClassHelpers::StaticBuffer<0xC, float> defaultFloatValue;
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x9, bool> defaultBoolValue;
|
||||
};
|
||||
explicit PlayerVar(const std::string& name);
|
||||
explicit PlayerVar(const std::string& name, Engine::VarType type);
|
||||
|
||||
Engine::VarValueType GetValue();
|
||||
Engine::VarValueType GetDefaultValue();
|
||||
void SetValue(const Engine::VarValueType& value);
|
||||
};
|
||||
|
||||
class EGameSDK_API StringPlayerVariable : public PlayerVar {
|
||||
public:
|
||||
explicit StringPlayerVariable(const std::string& name);
|
||||
|
||||
const char* GetValue();
|
||||
const char* GetDefaultValue();
|
||||
void SetValues(const std::string& value);
|
||||
};
|
||||
class EGameSDK_API FloatPlayerVariable : public PlayerVariable {
|
||||
class EGameSDK_API FloatPlayerVariable : public PlayerVar {
|
||||
public:
|
||||
union {
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x8, float> value;
|
||||
EGSDK::ClassHelpers::StaticBuffer<0xC, float> defaultValue;
|
||||
};
|
||||
explicit FloatPlayerVariable(const std::string& name);
|
||||
|
||||
float GetValue();
|
||||
float GetDefaultValue();
|
||||
void SetValues(float value);
|
||||
};
|
||||
class EGameSDK_API BoolPlayerVariable : public PlayerVariable {
|
||||
class EGameSDK_API BoolPlayerVariable : public PlayerVar {
|
||||
public:
|
||||
union {
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x8, bool> value;
|
||||
EGSDK::ClassHelpers::StaticBuffer<0x9, bool> defaultValue;
|
||||
};
|
||||
explicit BoolPlayerVariable(const std::string& name);
|
||||
|
||||
bool GetValue();
|
||||
bool GetDefaultValue();
|
||||
void SetValues(bool value);
|
||||
};
|
||||
|
||||
class EGameSDK_API PlayerVarMap {
|
||||
class EGameSDK_API PlayerVarMap : public Engine::VarMapBase<PlayerVar> {
|
||||
public:
|
||||
PlayerVarMap() = default;
|
||||
PlayerVarMap(const PlayerVarMap&) = delete;
|
||||
PlayerVarMap& operator=(const PlayerVarMap&) = delete;
|
||||
|
||||
PlayerVarMap(PlayerVarMap&&) noexcept = default;
|
||||
PlayerVarMap& operator=(PlayerVarMap&&) noexcept = default;
|
||||
|
||||
std::unique_ptr<PlayerVariable>& try_emplace(std::unique_ptr<PlayerVariable> playerVar);
|
||||
bool empty();
|
||||
bool none_of(const std::string& name);
|
||||
void reserve(size_t count);
|
||||
size_t size();
|
||||
|
||||
std::unique_ptr<PlayerVariable>* FindPtr(const std::string& name);
|
||||
PlayerVariable* Find(const std::string& name);
|
||||
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 : playerVarsOrder)
|
||||
func(playerVars.at(name), std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
std::unordered_map<std::string, std::unique_ptr<PlayerVariable>> playerVars{};
|
||||
std::vector<std::string> playerVarsOrder{};
|
||||
mutable std::mutex mutex{};
|
||||
using Engine::VarMapBase<PlayerVar>::Find;
|
||||
using Engine::VarMapBase<PlayerVar>::none_of;
|
||||
using Engine::VarMapBase<PlayerVar>::empty;
|
||||
};
|
||||
|
||||
class EGameSDK_API PlayerVariables {
|
||||
class EGameSDK_API PlayerVariables : public Engine::VarManagerBase<PlayerVarMap, PlayerVar> {
|
||||
public:
|
||||
static PlayerVarMap playerVars;
|
||||
static PlayerVarMap customPlayerVars;
|
||||
static PlayerVarMap defaultPlayerVars;
|
||||
static PlayerVarMap customDefaultPlayerVars;
|
||||
static PlayerVarMap customDefaultVars;
|
||||
static std::atomic<bool> gotPlayerVars;
|
||||
|
||||
#ifdef EGameSDK_EXPORTS
|
||||
static std::unordered_map<std::string, std::any> prevPlayerVarValueMap;
|
||||
static std::unordered_map<std::string, bool> prevBoolValueMap;
|
||||
static std::unordered_map<std::string, uint64_t> playerVarOwnerMap;
|
||||
|
||||
static void GetPlayerVars();
|
||||
static bool SortPlayerVars();
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
static T GetPlayerVarValue(const std::string& name);
|
||||
template <typename T>
|
||||
static void ChangePlayerVar(const std::string& name, const T value, PlayerVariable* playerVar = nullptr);
|
||||
template <typename T>
|
||||
static void ChangePlayerVarFromList(const std::string& name, const T value, PlayerVariable* playerVar = nullptr);
|
||||
|
||||
template <typename T>
|
||||
static void ManagePlayerVarByBool(const std::string& name, const T valueIfTrue, const T valueIfFalse, bool boolVal, bool usePreviousVal = true);
|
||||
static bool IsPlayerVarManagedByBool(const std::string& name);
|
||||
|
||||
static PlayerVariables* Get();
|
||||
private:
|
||||
static std::mutex mutex;
|
||||
};
|
||||
}
|
@ -6,7 +6,7 @@ namespace EGSDK::Engine {
|
||||
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);
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = varValues.find(this);
|
||||
if (it == varValues.end()) {
|
||||
switch (GetType()) {
|
||||
@ -70,7 +70,7 @@ namespace EGSDK::Engine {
|
||||
}, value);
|
||||
}
|
||||
void CVar::AddValuePtr(uint64_t* ptr) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
varValues[this].valuePtrs.push_back(ptr);
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
|
||||
std::unique_ptr<CVar>& CVarMap::try_emplace(std::unique_ptr<CVar> cVar) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
const std::string& name = cVar->GetName();
|
||||
auto [it, inserted] = vars.try_emplace(name, std::move(cVar));
|
||||
if (inserted) {
|
||||
@ -99,17 +99,17 @@ namespace EGSDK::Engine {
|
||||
return it->second;
|
||||
}
|
||||
bool CVarMap::none_of(uint32_t valueOffset) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
return varsByValueOffset.find(valueOffset) == varsByValueOffset.end();
|
||||
}
|
||||
|
||||
CVar* CVarMap::Find(uint32_t valueOffset) const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard 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);
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = vars.find(name);
|
||||
if (it == vars.end())
|
||||
return;
|
||||
|
@ -6,42 +6,42 @@ namespace EGSDK::Engine {
|
||||
std::recursive_mutex VarBase::mutex{};
|
||||
|
||||
VarBase::VarBase(const std::string& name) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
varNames[this] = name;
|
||||
varTypes[this] = VarType::NONE;
|
||||
}
|
||||
VarBase::VarBase(const std::string& name, VarType type) {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
varNames[this] = name;
|
||||
varTypes[this] = type;
|
||||
}
|
||||
VarBase::~VarBase() {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard lock(mutex);
|
||||
varNames.erase(this);
|
||||
varTypes.erase(this);
|
||||
}
|
||||
|
||||
const char* VarBase::GetName() const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard 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);
|
||||
std::lock_guard lock(mutex);
|
||||
varNames[this] = newName;
|
||||
}
|
||||
|
||||
VarType VarBase::GetType() const {
|
||||
std::lock_guard<decltype(mutex)> lock(mutex);
|
||||
std::lock_guard 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);
|
||||
std::lock_guard lock(mutex);
|
||||
varTypes[this] = newType;
|
||||
}
|
||||
}
|
@ -12,135 +12,70 @@ namespace EGSDK::GamePH {
|
||||
static constexpr int FLOAT_SIZE_OFFSET = 3;
|
||||
static constexpr int BOOL_SIZE_OFFSET = 2;
|
||||
|
||||
std::unordered_map<PlayerVariable*, std::string> PlayerVariable::playerVarNames{};
|
||||
std::unordered_map<PlayerVariable*, PlayerVarType> PlayerVariable::playerVarTypes{};
|
||||
std::mutex PlayerVariable::mutex{};
|
||||
PlayerVar::PlayerVar(const std::string& name) : VarBase(name) {}
|
||||
PlayerVar::PlayerVar(const std::string& name, Engine::VarType type) : Engine::VarBase(name, type) {}
|
||||
Engine::VarValueType PlayerVar::GetValue() {
|
||||
std::lock_guard lock(mutex);
|
||||
switch (GetType()) {
|
||||
case Engine::VarType::String:
|
||||
return reinterpret_cast<const char*>(reinterpret_cast<uint64_t>(this->strValue.data) & 0x1FFFFFFFFFFFFFFF);
|
||||
case Engine::VarType::Float:
|
||||
return this->floatValue;
|
||||
case Engine::VarType::Bool:
|
||||
return this->boolValue;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
Engine::VarValueType PlayerVar::GetDefaultValue() {
|
||||
std::lock_guard lock(mutex);
|
||||
switch (GetType()) {
|
||||
case Engine::VarType::String:
|
||||
return reinterpret_cast<const char*>(reinterpret_cast<uint64_t>(this->defaultStrValue.data) & 0x1FFFFFFFFFFFFFFF);
|
||||
case Engine::VarType::Float:
|
||||
return this->defaultFloatValue;
|
||||
case Engine::VarType::Bool:
|
||||
return this->defaultBoolValue;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
void PlayerVar::SetValue(const Engine::VarValueType& value) {
|
||||
std::lock_guard lock(mutex);
|
||||
std::visit([&](auto&& val) {
|
||||
using T = std::decay_t<decltype(val)>;
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
uint64_t firstByte = (reinterpret_cast<uint64_t>(this->strValue.data) >> 56) & 0xFF;
|
||||
uint64_t newValueAddr = reinterpret_cast<uint64_t>(val.c_str());
|
||||
if (firstByte != 0x0)
|
||||
newValueAddr |= (firstByte << 56);
|
||||
|
||||
PlayerVariable::PlayerVariable(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
playerVarNames[this] = name;
|
||||
playerVarTypes[this] = PlayerVarType::NONE;
|
||||
}
|
||||
const char* PlayerVariable::GetName() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = playerVarNames.find(this);
|
||||
if (it != playerVarNames.end())
|
||||
return it->second.c_str();
|
||||
return nullptr;
|
||||
}
|
||||
void PlayerVariable::SetName(const std::string& newName) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
playerVarNames[this] = newName;
|
||||
}
|
||||
PlayerVarType PlayerVariable::GetType() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = playerVarTypes.find(this);
|
||||
if (it != playerVarTypes.end())
|
||||
return it->second;
|
||||
return PlayerVarType::NONE;
|
||||
}
|
||||
void PlayerVariable::SetType(PlayerVarType newType) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
playerVarTypes[this] = newType;
|
||||
this->strValue = val.c_str();
|
||||
this->defaultStrValue = val.c_str();
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
this->floatValue = val;
|
||||
this->defaultFloatValue = val;
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
this->boolValue = val;
|
||||
this->defaultBoolValue = val;
|
||||
}
|
||||
}, value);
|
||||
}
|
||||
|
||||
StringPlayerVariable::StringPlayerVariable(const std::string& name) : PlayerVariable(name) {
|
||||
SetType(PlayerVarType::String);
|
||||
StringPlayerVariable::StringPlayerVariable(const std::string& name) : PlayerVar(name) {
|
||||
SetType(Engine::VarType::String);
|
||||
}
|
||||
const char* StringPlayerVariable::GetValue() {
|
||||
return reinterpret_cast<const char*>(reinterpret_cast<uint64_t>(this->value.data) & 0x1FFFFFFFFFFFFFFF);
|
||||
FloatPlayerVariable::FloatPlayerVariable(const std::string& name) : PlayerVar(name) {
|
||||
SetType(Engine::VarType::Float);
|
||||
}
|
||||
const char* StringPlayerVariable::GetDefaultValue() {
|
||||
return reinterpret_cast<const char*>(reinterpret_cast<uint64_t>(this->defaultValue.data) & 0x1FFFFFFFFFFFFFFF);
|
||||
}
|
||||
void StringPlayerVariable::SetValues(const std::string& value) {
|
||||
uint64_t firstuint8_t = (reinterpret_cast<uint64_t>(this->value.data) >> 56) & 0xFF;
|
||||
uint64_t newValueAddr = reinterpret_cast<uint64_t>(value.c_str());
|
||||
if (firstuint8_t != 0x0)
|
||||
newValueAddr |= (firstuint8_t << 56);
|
||||
|
||||
this->value = reinterpret_cast<const char*>(newValueAddr);
|
||||
this->defaultValue = reinterpret_cast<const char*>(newValueAddr);
|
||||
}
|
||||
FloatPlayerVariable::FloatPlayerVariable(const std::string& name) : PlayerVariable(name) {
|
||||
SetType(PlayerVarType::Float);
|
||||
}
|
||||
float FloatPlayerVariable::GetValue() {
|
||||
return this->value.data;
|
||||
}
|
||||
float FloatPlayerVariable::GetDefaultValue() {
|
||||
return this->defaultValue.data;
|
||||
}
|
||||
void FloatPlayerVariable::SetValues(float value) {
|
||||
this->value = value;
|
||||
this->defaultValue = value;
|
||||
}
|
||||
BoolPlayerVariable::BoolPlayerVariable(const std::string& name) : PlayerVariable(name) {
|
||||
SetType(PlayerVarType::Bool);
|
||||
}
|
||||
bool BoolPlayerVariable::GetValue() {
|
||||
return this->value.data;
|
||||
}
|
||||
bool BoolPlayerVariable::GetDefaultValue() {
|
||||
return this->defaultValue.data;
|
||||
}
|
||||
void BoolPlayerVariable::SetValues(bool value) {
|
||||
this->value = value;
|
||||
this->defaultValue = value;
|
||||
BoolPlayerVariable::BoolPlayerVariable(const std::string& name) : PlayerVar(name) {
|
||||
SetType(Engine::VarType::Bool);
|
||||
}
|
||||
|
||||
std::unique_ptr<PlayerVariable>& PlayerVarMap::try_emplace(std::unique_ptr<PlayerVariable> playerVar) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
const std::string& name = playerVar->GetName();
|
||||
auto [it, inserted] = playerVars.try_emplace(name, std::move(playerVar));
|
||||
if (inserted)
|
||||
playerVarsOrder.emplace_back(name);
|
||||
return it->second;
|
||||
}
|
||||
bool PlayerVarMap::empty() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return playerVars.empty();
|
||||
}
|
||||
bool PlayerVarMap::none_of(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return playerVars.find(name) == playerVars.end();
|
||||
}
|
||||
void PlayerVarMap::reserve(size_t count) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
playerVars.reserve(count);
|
||||
}
|
||||
size_t PlayerVarMap::size() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return playerVars.size();
|
||||
}
|
||||
|
||||
std::unique_ptr<PlayerVariable>* PlayerVarMap::FindPtr(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = playerVars.find(name);
|
||||
return it == playerVars.end() ? nullptr : &it->second;
|
||||
}
|
||||
PlayerVariable* PlayerVarMap::Find(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto it = playerVars.find(name);
|
||||
return it == playerVars.end() ? nullptr : it->second.get();
|
||||
}
|
||||
bool PlayerVarMap::Erase(const std::string& name) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return playerVars.erase(name) > 0;
|
||||
}
|
||||
|
||||
PlayerVarMap PlayerVariables::playerVars{};
|
||||
PlayerVarMap PlayerVariables::customPlayerVars{};
|
||||
PlayerVarMap PlayerVariables::defaultPlayerVars{};
|
||||
PlayerVarMap PlayerVariables::customDefaultPlayerVars{};
|
||||
PlayerVarMap PlayerVariables::customDefaultVars{};
|
||||
std::atomic<bool> PlayerVariables::gotPlayerVars = false;
|
||||
std::mutex PlayerVariables::mutex{};
|
||||
static bool sortedPlayerVars = false;
|
||||
|
||||
std::unordered_map<std::string, std::any> PlayerVariables::prevPlayerVarValueMap{};
|
||||
std::unordered_map<std::string, bool> PlayerVariables::prevBoolValueMap{};
|
||||
std::unordered_map<std::string, uint64_t> PlayerVariables::playerVarOwnerMap{};
|
||||
|
||||
#pragma region Player Variables Processing
|
||||
template <typename T>
|
||||
static void updateDefaultVar(PlayerVarMap& defaultVars, const std::string& name, T value, T defaultValue) {
|
||||
@ -151,15 +86,13 @@ namespace EGSDK::GamePH {
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
auto stringPlayerVar = std::make_unique<StringPlayerVariable>(name);
|
||||
defaultVars.try_emplace(std::move(stringPlayerVar));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, float>) {
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
auto floatPlayerVar = std::make_unique<FloatPlayerVariable>(name);
|
||||
floatPlayerVar->SetValues(value);
|
||||
floatPlayerVar->SetValue(value);
|
||||
defaultVars.try_emplace(std::move(floatPlayerVar));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, bool>) {
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
auto boolPlayerVar = std::make_unique<BoolPlayerVariable>(name);
|
||||
boolPlayerVar->SetValues(value);
|
||||
boolPlayerVar->SetValue(value);
|
||||
defaultVars.try_emplace(std::move(boolPlayerVar));
|
||||
}
|
||||
} else {
|
||||
@ -168,14 +101,14 @@ namespace EGSDK::GamePH {
|
||||
return;
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
auto floatPlayerVar = reinterpret_cast<FloatPlayerVariable*>(playerVar);
|
||||
floatPlayerVar->SetValues(value);
|
||||
floatPlayerVar->SetValue(value);
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
auto boolPlayerVar = reinterpret_cast<BoolPlayerVariable*>(playerVar);
|
||||
boolPlayerVar->SetValues(value);
|
||||
boolPlayerVar->SetValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void processPlayerVar(uint64_t*(*playerVarsGetter)(), std::unique_ptr<PlayerVariable>& playerVarPtr) {
|
||||
static void processPlayerVar(uint64_t*(*playerVarsGetter)(), std::unique_ptr<PlayerVar>& playerVarPtr) {
|
||||
static int offset = 0;
|
||||
int offsetDif = 0;
|
||||
while (true) {
|
||||
@ -190,10 +123,10 @@ namespace EGSDK::GamePH {
|
||||
}
|
||||
|
||||
std::string varName = playerVarPtr->GetName();
|
||||
PlayerVarType varType = playerVarPtr->GetType();
|
||||
Engine::VarType varType = playerVarPtr->GetType();
|
||||
|
||||
switch (playerVarPtr->GetType()) {
|
||||
case PlayerVarType::String:
|
||||
case Engine::VarType::String:
|
||||
{
|
||||
if (vTableName != "StringPlayerVariable")
|
||||
return;
|
||||
@ -207,7 +140,7 @@ namespace EGSDK::GamePH {
|
||||
offset += STRING_SIZE_OFFSET;
|
||||
return;
|
||||
}
|
||||
case PlayerVarType::Float:
|
||||
case Engine::VarType::Float:
|
||||
{
|
||||
if (vTableName != "FloatPlayerVariable")
|
||||
return;
|
||||
@ -216,12 +149,12 @@ namespace EGSDK::GamePH {
|
||||
playerVarPtr.reset(floatPlayerVar);
|
||||
playerVarPtr->SetName(varName);
|
||||
playerVarPtr->SetType(varType);
|
||||
updateDefaultVar(PlayerVariables::customDefaultPlayerVars, varName, floatPlayerVar->value.data, floatPlayerVar->defaultValue.data);
|
||||
updateDefaultVar(PlayerVariables::customDefaultVars, varName, floatPlayerVar->floatValue.data, floatPlayerVar->defaultFloatValue.data);
|
||||
|
||||
offset += FLOAT_SIZE_OFFSET;
|
||||
return;
|
||||
}
|
||||
case PlayerVarType::Bool:
|
||||
case Engine::VarType::Bool:
|
||||
{
|
||||
if (vTableName != "BoolPlayerVariable")
|
||||
return;
|
||||
@ -230,7 +163,7 @@ namespace EGSDK::GamePH {
|
||||
playerVarPtr.reset(boolPlayerVar);
|
||||
playerVarPtr->SetName(varName);
|
||||
playerVarPtr->SetType(varType);
|
||||
updateDefaultVar(PlayerVariables::customDefaultPlayerVars, varName, boolPlayerVar->value.data, boolPlayerVar->defaultValue.data);
|
||||
updateDefaultVar(PlayerVariables::customDefaultVars, varName, boolPlayerVar->boolValue.data, boolPlayerVar->defaultBoolValue.data);
|
||||
|
||||
offset += BOOL_SIZE_OFFSET;
|
||||
return;
|
||||
@ -241,7 +174,7 @@ namespace EGSDK::GamePH {
|
||||
}
|
||||
}
|
||||
}
|
||||
static void processPlayerVarSafe(std::unique_ptr<PlayerVariable>& playerVarPtr, uint64_t*(*playerVarsGetter)()) {
|
||||
static void processPlayerVarSafe(std::unique_ptr<PlayerVar>& playerVarPtr, uint64_t*(*playerVarsGetter)()) {
|
||||
__try {
|
||||
processPlayerVar(playerVarsGetter, playerVarPtr);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
@ -257,26 +190,24 @@ namespace EGSDK::GamePH {
|
||||
if (!Get())
|
||||
return;
|
||||
|
||||
customPlayerVars.reserve(playerVars.size());
|
||||
defaultPlayerVars.reserve(playerVars.size());
|
||||
customDefaultPlayerVars.reserve(playerVars.size());
|
||||
prevPlayerVarValueMap.reserve(playerVars.size());
|
||||
prevBoolValueMap.reserve(playerVars.size());
|
||||
customVars.reserve(vars.size());
|
||||
defaultVars.reserve(vars.size());
|
||||
customDefaultVars.reserve(vars.size());
|
||||
|
||||
playerVars.ForEach(processPlayerVarSafe, reinterpret_cast<uint64_t*(*)()>(&Get));
|
||||
vars.ForEach(processPlayerVarSafe, reinterpret_cast<uint64_t*(*)()>(&Get));
|
||||
gotPlayerVars = true;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Player Variables Sorting
|
||||
struct VarTypeFieldMeta {
|
||||
PlayerVarType type;
|
||||
Engine::VarType type;
|
||||
std::string_view className;
|
||||
};
|
||||
const std::vector<VarTypeFieldMeta> varTypeFields = {
|
||||
{ PlayerVarType::String, "constds::FieldsCollection<PlayerVariables>::TypedFieldMeta<StringPlayerVariable>" },
|
||||
{ PlayerVarType::Float, "constds::FieldsCollection<PlayerVariables>::TypedFieldMeta<FloatPlayerVariable>" },
|
||||
{ PlayerVarType::Bool, "constds::FieldsCollection<PlayerVariables>::TypedFieldMeta<BoolPlayerVariable>" }
|
||||
{ Engine::VarType::String, "constds::FieldsCollection<PlayerVariables>::TypedFieldMeta<StringPlayerVariable>" },
|
||||
{ Engine::VarType::Float, "constds::FieldsCollection<PlayerVariables>::TypedFieldMeta<FloatPlayerVariable>" },
|
||||
{ Engine::VarType::Bool, "constds::FieldsCollection<PlayerVariables>::TypedFieldMeta<BoolPlayerVariable>" }
|
||||
};
|
||||
|
||||
static bool isRetInstruction(uint8_t* address) {
|
||||
@ -318,10 +249,10 @@ namespace EGSDK::GamePH {
|
||||
|
||||
return playerVarName;
|
||||
}
|
||||
static PlayerVarType getPlayerVarType(uint8_t*& funcAddress, uint64_t startOfFunc) {
|
||||
PlayerVarType playerVarType = PlayerVarType::NONE;
|
||||
static Engine::VarType getPlayerVarType(uint8_t*& funcAddress, uint64_t startOfFunc) {
|
||||
Engine::VarType varType = Engine::VarType::NONE;
|
||||
|
||||
while (!playerVarType && !isRetInstruction(funcAddress) && isBelowFuncSizeLimit(funcAddress, startOfFunc, MAX_FUNC_SIZE)) {
|
||||
while (varType == Engine::VarType::NONE && !isRetInstruction(funcAddress) && isBelowFuncSizeLimit(funcAddress, startOfFunc, MAX_FUNC_SIZE)) {
|
||||
// call LoadPlayerXVariable
|
||||
if (!isCallInstruction(funcAddress)) {
|
||||
funcAddress++;
|
||||
@ -350,16 +281,16 @@ namespace EGSDK::GamePH {
|
||||
continue;
|
||||
}
|
||||
|
||||
playerVarType = varTypeIt->type;
|
||||
varType = varTypeIt->type;
|
||||
break;
|
||||
}
|
||||
|
||||
// if it's still NONE after seeing the function doesnt reference any of the variables, break so the loop stops
|
||||
if (playerVarType == PlayerVarType::NONE)
|
||||
if (varType == Engine::VarType::NONE)
|
||||
break;
|
||||
}
|
||||
|
||||
return playerVarType;
|
||||
return varType;
|
||||
}
|
||||
|
||||
bool PlayerVariables::SortPlayerVars() {
|
||||
@ -385,20 +316,20 @@ namespace EGSDK::GamePH {
|
||||
if (!playerVarName)
|
||||
continue;
|
||||
|
||||
PlayerVarType playerVarType = getPlayerVarType(funcAddress, startOfFunc);
|
||||
Engine::VarType playerVarType = getPlayerVarType(funcAddress, startOfFunc);
|
||||
switch (playerVarType) {
|
||||
case PlayerVarType::String:
|
||||
playerVars.try_emplace(std::make_unique<StringPlayerVariable>(playerVarName));
|
||||
break;
|
||||
case PlayerVarType::Float:
|
||||
playerVars.try_emplace(std::make_unique<FloatPlayerVariable>(playerVarName));
|
||||
break;
|
||||
case PlayerVarType::Bool:
|
||||
playerVars.try_emplace(std::make_unique<BoolPlayerVariable>(playerVarName));
|
||||
break;
|
||||
default:
|
||||
//playerVars.try_emplace(std::make_unique<PlayerVariable>(playerVarName));
|
||||
break;
|
||||
case Engine::VarType::String:
|
||||
vars.try_emplace(std::make_unique<StringPlayerVariable>(playerVarName));
|
||||
break;
|
||||
case Engine::VarType::Float:
|
||||
vars.try_emplace(std::make_unique<FloatPlayerVariable>(playerVarName));
|
||||
break;
|
||||
case Engine::VarType::Bool:
|
||||
vars.try_emplace(std::make_unique<BoolPlayerVariable>(playerVarName));
|
||||
break;
|
||||
default:
|
||||
//vars.try_emplace(std::make_unique<PlayerVar>(playerVarName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,177 +338,6 @@ namespace EGSDK::GamePH {
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
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;
|
||||
}
|
||||
template <typename T>
|
||||
T PlayerVariables::GetPlayerVarValue(const std::string& name) {
|
||||
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 (!gotPlayerVars)
|
||||
return getDefaultValue<T>();
|
||||
|
||||
auto playerVar = playerVars.Find(name);
|
||||
if (!playerVar)
|
||||
return getDefaultValue<T>();
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>)
|
||||
return reinterpret_cast<StringPlayerVariable*>(playerVar)->value.data;
|
||||
else if constexpr (std::is_same_v<T, float>)
|
||||
return reinterpret_cast<FloatPlayerVariable*>(playerVar)->value.data;
|
||||
else if constexpr (std::is_same_v<T, bool>)
|
||||
return reinterpret_cast<BoolPlayerVariable*>(playerVar)->value.data;
|
||||
}
|
||||
template <typename T>
|
||||
void PlayerVariables::ChangePlayerVar(const std::string& name, const T value, PlayerVariable* playerVar) {
|
||||
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 (!gotPlayerVars)
|
||||
return;
|
||||
|
||||
if (!playerVar)
|
||||
playerVar = playerVars.Find(name);
|
||||
if (!playerVar)
|
||||
return;
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
switch (playerVar->GetType()) {
|
||||
case PlayerVarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case PlayerVarType::Float:
|
||||
ChangePlayerVar<float>(name, std::stof(Utils::Values::to_string(value)), playerVar);
|
||||
break;
|
||||
case PlayerVarType::Bool:
|
||||
ChangePlayerVar<bool>(name, std::stof(Utils::Values::to_string(value)), playerVar);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
if (playerVar->GetType() == PlayerVarType::Float)
|
||||
reinterpret_cast<FloatPlayerVariable*>(playerVar)->SetValues(value);
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
if (playerVar->GetType() == PlayerVarType::Bool)
|
||||
reinterpret_cast<BoolPlayerVariable*>(playerVar)->SetValues(value);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void PlayerVariables::ChangePlayerVarFromList(const std::string& name, const T value, PlayerVariable* playerVar) {
|
||||
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 (!gotPlayerVars)
|
||||
return;
|
||||
|
||||
if (!playerVar)
|
||||
playerVar = playerVars.Find(name);
|
||||
if (!playerVar)
|
||||
return;
|
||||
|
||||
auto customPlayerVar = customPlayerVars.Find(name);
|
||||
auto defPlayerVar = defaultPlayerVars.Find(name);
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
switch (playerVar->GetType()) {
|
||||
case PlayerVarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case PlayerVarType::Float:
|
||||
ChangePlayerVarFromList<float>(name, std::stof(Utils::Values::to_string(value)), playerVar);
|
||||
break;
|
||||
case PlayerVarType::Bool:
|
||||
ChangePlayerVarFromList<bool>(name, std::stof(Utils::Values::to_string(value)), playerVar);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
if (playerVar->GetType() != PlayerVarType::Float)
|
||||
return;
|
||||
if (!customPlayerVar)
|
||||
customPlayerVar = customPlayerVars.try_emplace(std::make_unique<FloatPlayerVariable>(name)).get();
|
||||
if (!defPlayerVar) {
|
||||
defPlayerVar = defaultPlayerVars.try_emplace(std::make_unique<FloatPlayerVariable>(name)).get();
|
||||
reinterpret_cast<FloatPlayerVariable*>(defPlayerVar)->SetValues(reinterpret_cast<FloatPlayerVariable*>(playerVar)->value);
|
||||
}
|
||||
|
||||
reinterpret_cast<FloatPlayerVariable*>(playerVar)->SetValues(value);
|
||||
reinterpret_cast<FloatPlayerVariable*>(customPlayerVar)->SetValues(value);
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
if (playerVar->GetType() != PlayerVarType::Bool)
|
||||
return;
|
||||
if (!customPlayerVar)
|
||||
customPlayerVar = customPlayerVars.try_emplace(std::make_unique<BoolPlayerVariable>(name)).get();
|
||||
if (!defPlayerVar) {
|
||||
defPlayerVar = defaultPlayerVars.try_emplace(std::make_unique<BoolPlayerVariable>(name)).get();
|
||||
reinterpret_cast<BoolPlayerVariable*>(defPlayerVar)->SetValues(reinterpret_cast<BoolPlayerVariable*>(playerVar)->value);
|
||||
}
|
||||
|
||||
reinterpret_cast<BoolPlayerVariable*>(playerVar)->SetValues(value);
|
||||
reinterpret_cast<BoolPlayerVariable*>(customPlayerVar)->SetValues(value);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PlayerVariables::ManagePlayerVarByBool(const std::string& name, const T valueIfTrue, const T valueIfFalse, bool boolVal, bool usePreviousVal) {
|
||||
if (!gotPlayerVars)
|
||||
return;
|
||||
|
||||
uint64_t caller = reinterpret_cast<uint64_t>(_ReturnAddress());
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
auto ownerIt = playerVarOwnerMap.find(name);
|
||||
if (ownerIt != playerVarOwnerMap.end() && ownerIt->second != caller)
|
||||
return;
|
||||
if (!boolVal && prevBoolValueMap.find(name) == prevBoolValueMap.end())
|
||||
return;
|
||||
|
||||
bool& prevBoolValue = prevBoolValueMap[name];
|
||||
auto& prevValueAny = prevPlayerVarValueMap[name];
|
||||
|
||||
if (boolVal) {
|
||||
if (!prevBoolValue)
|
||||
prevPlayerVarValueMap[name] = GetPlayerVarValue<T>(name);
|
||||
|
||||
ChangePlayerVar(name, valueIfTrue);
|
||||
prevBoolValue = true;
|
||||
playerVarOwnerMap[name] = caller;
|
||||
} else if (prevBoolValue) {
|
||||
ChangePlayerVar(name, usePreviousVal ? std::any_cast<T>(prevValueAny) : valueIfFalse);
|
||||
prevPlayerVarValueMap.erase(name);
|
||||
prevBoolValueMap.erase(name);
|
||||
playerVarOwnerMap.erase(name);
|
||||
}
|
||||
}
|
||||
bool PlayerVariables::IsPlayerVarManagedByBool(const std::string& name) {
|
||||
if (!gotPlayerVars)
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return prevBoolValueMap.find(name) != prevBoolValueMap.end() && prevBoolValueMap[name];
|
||||
}
|
||||
|
||||
template EGameSDK_API std::string PlayerVariables::GetPlayerVarValue<std::string>(const std::string& name);
|
||||
template EGameSDK_API float PlayerVariables::GetPlayerVarValue<float>(const std::string& name);
|
||||
template EGameSDK_API bool PlayerVariables::GetPlayerVarValue<bool>(const std::string& name);
|
||||
template EGameSDK_API void PlayerVariables::ChangePlayerVar<std::string>(const std::string& name, const std::string value, PlayerVariable* playerVar);
|
||||
template EGameSDK_API void PlayerVariables::ChangePlayerVar<float>(const std::string& name, const float value, PlayerVariable* playerVar);
|
||||
template EGameSDK_API void PlayerVariables::ChangePlayerVar<bool>(const std::string& name, const bool value, PlayerVariable* playerVar);
|
||||
template EGameSDK_API void PlayerVariables::ChangePlayerVarFromList<std::string>(const std::string& name, const std::string value, PlayerVariable* playerVar);
|
||||
template EGameSDK_API void PlayerVariables::ChangePlayerVarFromList<float>(const std::string& name, const float value, PlayerVariable* playerVar);
|
||||
template EGameSDK_API void PlayerVariables::ChangePlayerVarFromList<bool>(const std::string& name, const bool value, PlayerVariable* playerVar);
|
||||
|
||||
template EGameSDK_API void PlayerVariables::ManagePlayerVarByBool<std::string>(const std::string& name, const std::string valueIfTrue, const std::string valueIfFalse, bool boolVal, bool usePreviousVal);
|
||||
template EGameSDK_API void PlayerVariables::ManagePlayerVarByBool<float>(const std::string& name, const float valueIfTrue, const float valueIfFalse, bool boolVal, bool usePreviousVal);
|
||||
template EGameSDK_API void PlayerVariables::ManagePlayerVarByBool<bool>(const std::string& name, const bool valueIfTrue, const bool valueIfFalse, bool boolVal, bool usePreviousVal);
|
||||
|
||||
static PlayerVariables* GetOffset_PlayerVariables() {
|
||||
PlayerState* playerState = PlayerState::Get();
|
||||
return playerState ? playerState->playerVariables : nullptr;
|
||||
|
@ -235,7 +235,7 @@ namespace EGT::Menu {
|
||||
if (!EGSDK::GamePH::PlayerVariables::gotPlayerVars)
|
||||
return;
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("CameraDefaultFOVReduction", 0.0f, baseSafezoneFOVReduction, disableSafezoneFOVReduction.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("CameraDefaultFOVReduction", 0.0f, baseSafezoneFOVReduction, disableSafezoneFOVReduction.GetValue(), true);
|
||||
|
||||
static float prevLensDistortion = lensDistortion;
|
||||
static bool lensDistortionJustEnabled = false;
|
||||
@ -251,8 +251,8 @@ namespace EGT::Menu {
|
||||
lensDistortionJustEnabled = false;
|
||||
}
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVar("FOVCorrection", goProMode.GetValue() ? (altLensDistortion / 100.0f) : (lensDistortion / 100.0f));
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("SprintHeadCorrectionFactor", 0.0f, baseSprintHeadCorrectionFactor, goProMode.GetValue() ? goProMode.GetValue() : disableHeadCorrection.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVar("FOVCorrection", goProMode.GetValue() ? (altLensDistortion / 100.0f) : (lensDistortion / 100.0f));
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("SprintHeadCorrectionFactor", 0.0f, baseSprintHeadCorrectionFactor, goProMode.GetValue() ? goProMode.GetValue() : disableHeadCorrection.GetValue(), true);
|
||||
}
|
||||
static void UpdateDisabledOptions() {
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
|
@ -36,9 +36,6 @@ namespace EGT::Menu {
|
||||
return lowerKey.find(lowerFilter) != std::string::npos;
|
||||
}
|
||||
static void RestoreVariableToDefault(const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
if (EGSDK::Engine::CVars::IsVarManagedByBool(cVarPtr->GetName()))
|
||||
return;
|
||||
|
||||
auto cVar = cVarPtr.get();
|
||||
|
||||
ImGui_impl::DeferredActions::Add([cVar]() {
|
||||
@ -128,7 +125,7 @@ namespace EGT::Menu {
|
||||
if (ImGui::CollapsingHeader("Renderer CVars list", ImGuiTreeNodeFlags_None)) {
|
||||
ImGui::Indent();
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::Engine::CVars::AreAnyCustomVarsPresent() || !EGSDK::Engine::CVars::AreAllCustomVarsManagedByBool());
|
||||
ImGui::BeginDisabled(!EGSDK::Engine::CVars::AreAnyCustomVarsPresent() || EGSDK::Engine::CVars::AreAllCustomVarsManagedByBool());
|
||||
if (ImGui::Button("Restore variables to default"))
|
||||
RestoreVariablesToDefault();
|
||||
ImGui::EndDisabled();
|
||||
|
@ -49,7 +49,7 @@ namespace EGT::Menu {
|
||||
|
||||
static bool debugEnabled = false;
|
||||
static bool restoreVarsToSavedVarsEnabled = false;
|
||||
static char playerVarsSearchFilter[64];
|
||||
static char varsSearchFilter[64];
|
||||
|
||||
#pragma region Player Variables
|
||||
static std::string getParamName(const std::string& str) {
|
||||
@ -90,37 +90,48 @@ namespace EGT::Menu {
|
||||
if (!playerVariables.GetValue())
|
||||
return;
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::customPlayerVars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVariable>& customPlayerVarPtr) {
|
||||
if (EGSDK::GamePH::PlayerVariables::IsPlayerVarManagedByBool(customPlayerVarPtr->GetName()))
|
||||
EGSDK::GamePH::PlayerVariables::customVars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& customPlayerVarPtr) {
|
||||
auto customPlayerVar = customPlayerVarPtr.get();
|
||||
if (EGSDK::GamePH::PlayerVariables::IsVarManagedByBool(customPlayerVar->GetName()))
|
||||
return;
|
||||
|
||||
switch (customPlayerVarPtr->GetType()) {
|
||||
case EGSDK::GamePH::PlayerVarType::String:
|
||||
|
||||
switch (customPlayerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::GamePH::PlayerVarType::Float:
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(customPlayerVarPtr->GetName(), reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(customPlayerVarPtr.get())->value.data);
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto customVarValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(customPlayerVar);
|
||||
if (!customVarValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVar(customPlayerVar->GetName(), *customVarValue);
|
||||
break;
|
||||
case EGSDK::GamePH::PlayerVarType::Bool:
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(customPlayerVarPtr->GetName(), reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(customPlayerVarPtr.get())->value.data);
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto customVarValue = EGSDK::GamePH::PlayerVariables::GetVarValue<bool>(customPlayerVar);
|
||||
if (!customVarValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVar(customPlayerVar->GetName(), *customVarValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
static void PlayerVarsUpdate() {
|
||||
static void varsUpdate() {
|
||||
if (!EGSDK::GamePH::PlayerVariables::gotPlayerVars)
|
||||
return;
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("NightRunnerItemForced", true, false, nightrunnerMode.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("NightRunnerFurySmashEnabled", true, false, nightrunnerMode.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("NightRunnerFuryGroundPoundEnabled", true, false, nightrunnerMode.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("AntizinDrainBlocked", true, false, unlimitedImmunity.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("InfiniteStamina", true, false, unlimitedStamina.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("UvFlashlightEnergyDrainFactor", 0.0f, 1.0f, unlimitedItems.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("DamageMulAll", 99999.0f, 0.0f, oneHitKill.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("InVisibleToEnemies", true, false, invisibleToEnemies.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("LeftHandDisabled", true, false, oneHandedMode.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("NightRunnerItemForced", true, false, nightrunnerMode.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("NightRunnerFurySmashEnabled", true, false, nightrunnerMode.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("NightRunnerFuryGroundPoundEnabled", true, false, nightrunnerMode.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("AntizinDrainBlocked", true, false, unlimitedImmunity.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("InfiniteStamina", true, false, unlimitedStamina.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("UvFlashlightEnergyDrainFactor", 0.0f, 1.0f, unlimitedItems.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("DamageMulAll", 99999.0f, 0.0f, oneHitKill.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("InVisibleToEnemies", true, false, invisibleToEnemies.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("LeftHandDisabled", true, false, oneHandedMode.GetValue());
|
||||
}
|
||||
|
||||
static void SaveVariablesToSCR() {
|
||||
@ -129,9 +140,9 @@ namespace EGT::Menu {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tempPlayerVarsSCR = g_PlayerVariablesSCRFile;
|
||||
std::string tempvarsSCR = g_PlayerVariablesSCRFile;
|
||||
|
||||
std::istringstream iss(tempPlayerVarsSCR);
|
||||
std::istringstream iss(tempvarsSCR);
|
||||
std::string line{};
|
||||
while (std::getline(iss, line)) {
|
||||
const std::string origLine = line;
|
||||
@ -139,23 +150,33 @@ namespace EGT::Menu {
|
||||
if (name.empty())
|
||||
continue;
|
||||
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::playerVars.Find(name);
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVar(name);
|
||||
if (!playerVar)
|
||||
continue;
|
||||
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::GamePH::PlayerVarType::String:
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::GamePH::PlayerVarType::Float:
|
||||
replaceParamValue(line, std::to_string(reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(playerVar)->value));
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
if (!varValue)
|
||||
return;
|
||||
replaceParamValue(line, std::to_string(*varValue));
|
||||
break;
|
||||
case EGSDK::GamePH::PlayerVarType::Bool:
|
||||
replaceParamValue(line, reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(playerVar) ? "true" : "false");
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
if (!varValue)
|
||||
return;
|
||||
replaceParamValue(line, *varValue ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
EGSDK::Utils::Values::str_replace(tempPlayerVarsSCR, origLine, line);
|
||||
EGSDK::Utils::Values::str_replace(tempvarsSCR, origLine, line);
|
||||
}
|
||||
|
||||
std::ofstream outFile(saveSCRPath + "\\player_variables.scr", std::ios::binary);
|
||||
@ -163,7 +184,7 @@ namespace EGT::Menu {
|
||||
ImGui::OpenPopup("Failed saving player variables.");
|
||||
return;
|
||||
}
|
||||
outFile << tempPlayerVarsSCR;
|
||||
outFile << tempvarsSCR;
|
||||
outFile.close();
|
||||
ImGui::OpenPopup("Saved player variables!");
|
||||
}
|
||||
@ -188,61 +209,61 @@ namespace EGT::Menu {
|
||||
if (value.empty())
|
||||
continue;
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(name, value);
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVar(name, value);
|
||||
}
|
||||
file.close();
|
||||
ImGui::OpenPopup("Loaded player variables!");
|
||||
}
|
||||
|
||||
static void RestoreVariableToDefault(const std::string& name) {
|
||||
ImGui_impl::DeferredActions::Add([name]() {
|
||||
auto& defVars = restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars : EGSDK::GamePH::PlayerVariables::defaultPlayerVars;
|
||||
auto defPlayerVar = defVars.Find(name);
|
||||
if (!defPlayerVar)
|
||||
return;
|
||||
static void RestoreVariableToDefault(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = playerVarPtr.get();
|
||||
|
||||
switch (defPlayerVar->GetType()) {
|
||||
case EGSDK::GamePH::PlayerVarType::String:
|
||||
ImGui_impl::DeferredActions::Add([playerVar]() {
|
||||
auto& defVars = restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::customDefaultVars : EGSDK::GamePH::PlayerVariables::defaultVars;
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::GamePH::PlayerVarType::Float:
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(name, reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defPlayerVar)->value.data);
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
EGSDK::GamePH::PlayerVariables::RestoreVariableToDefaultFromMap<float>(playerVar, defVars, !restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
case EGSDK::GamePH::PlayerVarType::Bool:
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVar(name, reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defPlayerVar)->value.data);
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
EGSDK::GamePH::PlayerVariables::RestoreVariableToDefaultFromMap<bool>(playerVar, defVars, !restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!restoreVarsToSavedVarsEnabled) {
|
||||
defVars.Erase(name);
|
||||
EGSDK::GamePH::PlayerVariables::customPlayerVars.Erase(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
static void RestoreVariablesToDefault() {
|
||||
(restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::playerVars : EGSDK::GamePH::PlayerVariables::customPlayerVars).ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr) {
|
||||
RestoreVariableToDefault(playerVarPtr->GetName());
|
||||
(restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::vars : EGSDK::GamePH::PlayerVariables::customVars).ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
RestoreVariableToDefault(playerVarPtr);
|
||||
});
|
||||
|
||||
ImGui::OpenPopup("Restored player variables!");
|
||||
}
|
||||
static void SaveVariablesAsDefault() {
|
||||
EGSDK::GamePH::PlayerVariables::playerVars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr) {
|
||||
EGSDK::GamePH::PlayerVariables::vars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = playerVarPtr.get();
|
||||
auto defCustomPlayerVar = EGSDK::GamePH::PlayerVariables::customDefaultPlayerVars.Find(playerVar->GetName());
|
||||
if (!defCustomPlayerVar)
|
||||
return;
|
||||
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::GamePH::PlayerVarType::String:
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::GamePH::PlayerVarType::Float:
|
||||
reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(defCustomPlayerVar)->value = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(playerVar)->value;
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
if (!varValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromMap(playerVar->GetName(), *varValue, EGSDK::GamePH::PlayerVariables::customDefaultVars);
|
||||
break;
|
||||
case EGSDK::GamePH::PlayerVarType::Bool:
|
||||
reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(defCustomPlayerVar)->value = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(playerVar)->value;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<bool>(playerVar);
|
||||
if (!varValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromMap(playerVar->GetName(), *varValue, EGSDK::GamePH::PlayerVariables::customDefaultVars);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -250,8 +271,8 @@ namespace EGT::Menu {
|
||||
ImGui::OpenPopup("Saved current player variables!");
|
||||
}
|
||||
|
||||
static bool ShouldDisplayVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr, const std::string& searchFilter) {
|
||||
if (playerVarPtr->GetType() == EGSDK::GamePH::PlayerVarType::String || playerVarPtr->GetType() == EGSDK::GamePH::PlayerVarType::NONE) // TO IMPLEMENT
|
||||
static bool ShouldDisplayVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr, const std::string& searchFilter) {
|
||||
if (playerVarPtr->GetType() == EGSDK::Engine::VarType::String || playerVarPtr->GetType() == EGSDK::Engine::VarType::NONE) // TO IMPLEMENT
|
||||
return false;
|
||||
if (searchFilter.empty())
|
||||
return true;
|
||||
@ -261,7 +282,7 @@ namespace EGT::Menu {
|
||||
std::string lowerKey = EGSDK::Utils::Values::to_lower(playerVarPtr->GetName());
|
||||
return lowerKey.find(lowerFilter) != std::string::npos;
|
||||
}
|
||||
static void RenderDebugInfo(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr) {
|
||||
static void RenderDebugInfo(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
const float maxInputTextWidth = ImGui::CalcTextSize("0x0000000000000000").x;
|
||||
std::string labelID = "##DebugAddrInputText" + std::string(playerVarPtr->GetName());
|
||||
DWORD64 finalVarValueAddr = reinterpret_cast<DWORD64>(playerVarPtr.get()) + 0x8; // 0x8 is PlayerVariable->value
|
||||
@ -280,25 +301,31 @@ namespace EGT::Menu {
|
||||
ImGui::InputText(labelID.c_str(), const_cast<char*>(addrString.c_str()), strlen(addrString.c_str()), ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
static void RenderPlayerVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr) {
|
||||
static void RenderPlayerVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = playerVarPtr.get();
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::IsPlayerVarManagedByBool(playerVarPtr->GetName()));
|
||||
switch (playerVarPtr->GetType()) {
|
||||
case EGSDK::GamePH::PlayerVarType::String:
|
||||
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::IsVarManagedByBool(playerVar->GetName()));
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::GamePH::PlayerVarType::Float:
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
float newValue = reinterpret_cast<EGSDK::GamePH::FloatPlayerVariable*>(playerVar)->value;
|
||||
auto value = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat(playerVar->GetName(), &newValue))
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVarFromList(playerVar->GetName(), newValue, playerVar);
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromList(playerVar, newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::GamePH::PlayerVarType::Bool:
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
bool newValue = reinterpret_cast<EGSDK::GamePH::BoolPlayerVariable*>(playerVar)->value;
|
||||
auto value = EGSDK::GamePH::PlayerVariables::GetVarValue<bool>(playerVar);
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::Checkbox(playerVar->GetName(), &newValue))
|
||||
EGSDK::GamePH::PlayerVariables::ChangePlayerVarFromList(playerVar->GetName(), newValue, playerVar);
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromList(playerVar, newValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -309,9 +336,9 @@ namespace EGT::Menu {
|
||||
ImGui::SameLine();
|
||||
std::string restoreBtnName = "Restore##" + std::string(playerVarPtr->GetName());
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::customPlayerVars.none_of(playerVarPtr->GetName()) || EGSDK::GamePH::PlayerVariables::IsPlayerVarManagedByBool(playerVarPtr->GetName()));
|
||||
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::DoesVarHaveCustomValue(playerVar->GetName()) || EGSDK::GamePH::PlayerVariables::IsVarManagedByBool(playerVar->GetName()));
|
||||
if (ImGui::Button(restoreBtnName.c_str(), "Restores player variable to default"))
|
||||
RestoreVariableToDefault(playerVarPtr->GetName());
|
||||
RestoreVariableToDefault(playerVarPtr);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (debugEnabled)
|
||||
@ -334,7 +361,7 @@ namespace EGT::Menu {
|
||||
ImGui::Checkbox("Restore variables to saved variables", &restoreVarsToSavedVarsEnabled, "Sets whether or not \"Restore variables to default\" should restore variables to the ones saved by \"Save current variables as default\"");
|
||||
ImGui::Checkbox("Debug Mode", &debugEnabled, "Shows text boxes alongside player variables, which will show the address in memory of each variable");
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::customPlayerVars.empty());
|
||||
ImGui::BeginDisabled(!EGSDK::GamePH::PlayerVariables::AreAnyCustomVarsPresent() || EGSDK::GamePH::PlayerVariables::AreAllCustomVarsManagedByBool());
|
||||
if (ImGui::Button("Restore variables to default"))
|
||||
RestoreVariablesToDefault();
|
||||
ImGui::EndDisabled();
|
||||
@ -343,10 +370,10 @@ namespace EGT::Menu {
|
||||
SaveVariablesAsDefault();
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::InputTextWithHint("##PlayerVariablesSearch", "Search variables", playerVarsSearchFilter, 64);
|
||||
ImGui::InputTextWithHint("##PlayerVariablesSearch", "Search variables", varsSearchFilter, 64);
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::playerVars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVariable>& playerVarPtr) {
|
||||
if (ShouldDisplayVariable(playerVarPtr, playerVarsSearchFilter))
|
||||
EGSDK::GamePH::PlayerVariables::vars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
if (ShouldDisplayVariable(playerVarPtr, varsSearchFilter))
|
||||
RenderPlayerVariable(playerVarPtr);
|
||||
});
|
||||
|
||||
@ -521,7 +548,7 @@ namespace EGT::Menu {
|
||||
PlayerImmunityUpdate();
|
||||
PlayerRestrictionsUpdate();
|
||||
|
||||
PlayerVarsUpdate();
|
||||
varsUpdate();
|
||||
PlayerVarListValuesUpdate();
|
||||
|
||||
HandleToggles();
|
||||
@ -581,7 +608,7 @@ namespace EGT::Menu {
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Player Variables");
|
||||
ImGui::Checkbox("Enabled##PlayerVars", &playerVariables, "Shows the list of player variables");
|
||||
ImGui::Checkbox("Enabled##vars", &playerVariables, "Shows the list of player variables");
|
||||
HandlePlayerVariablesList();
|
||||
HandlePlayerVariablesDialogs();
|
||||
}
|
||||
|
@ -25,39 +25,39 @@ namespace EGT::Menu {
|
||||
if (!EGSDK::GamePH::PlayerVariables::gotPlayerVars)
|
||||
return;
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("MeleeWpnDurabilityMulReduce", 0.0f, baseWeaponDurabilityMul, unlimitedDurability.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("MeleeWpnDurabilityMulReduce", 0.0f, baseWeaponDurabilityMul, unlimitedDurability.GetValue(), true);
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsPistolInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRevolverInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRifleInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsShotgunInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsSMGInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("InfiniteArrows", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsPistolInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRevolverInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRifleInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsShotgunInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsSMGInfiniteAmmo", true, false, unlimitedAmmo.GetValue());
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("InfiniteArrows", true, false, unlimitedAmmo.GetValue());
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("BulletAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsMoveAccuracyReduce", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsPistolAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRevolverAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRifleAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsShotgunAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsCrossbowAccuracyFactor", 0.0f, baseBowAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsHarpoonAccuracyFactor", 0.0f, baseBowAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("BowAccuracyFactor", 0.0f, baseBowAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("BowMaxThrowFactor", 99999.0f, 1.0f, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("BowSlowMoAccuracyMul", 0.0f, 0.25f, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("BulletAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsMoveAccuracyReduce", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsPistolAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRevolverAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRifleAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsShotgunAccuracyFactor", 0.0f, baseWeaponAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsCrossbowAccuracyFactor", 0.0f, baseBowAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsHarpoonAccuracyFactor", 0.0f, baseBowAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("BowAccuracyFactor", 0.0f, baseBowAccuracyMul, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("BowMaxThrowFactor", 99999.0f, 1.0f, noSpread.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("BowSlowMoAccuracyMul", 0.0f, 0.25f, noSpread.GetValue(), true);
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("BulletRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsPistolRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRevolverRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRifleRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsShotgunRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("BulletRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsPistolRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRevolverRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRifleRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsShotgunRecoilFactor", 0.0f, baseWeaponRecoilMul, noRecoil.GetValue(), true);
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("BulletReloadSpeed", 1000.0f, 0.0f, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsPistolReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRevolverReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsRifleReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("FirearmsShotgunReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("BowPutArrowDuration", 0.0f, 0.137f, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("BulletReloadSpeed", 1000.0f, 0.0f, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsPistolReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRevolverReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsRifleReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("FirearmsShotgunReloadTimeMul", 1000.0f, baseWeaponReloadMul, instantReload.GetValue(), true);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("BowPutArrowDuration", 0.0f, 0.137f, instantReload.GetValue(), true);
|
||||
}
|
||||
static void UpdateWeaponDurability(bool updateSlider) {
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
|
@ -159,7 +159,7 @@ namespace EGT::Menu {
|
||||
ImGui::SeparatorText("Time##World");
|
||||
ImGui::BeginDisabled(!iLevel || !iLevel->IsLoaded() || !dayNightCycle || !timeWeatherSystem);
|
||||
bool timeSlider = ImGui::SliderFloat("Time", &time, 0.01f, 24.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp);
|
||||
EGSDK::GamePH::PlayerVariables::ManagePlayerVarByBool("AntizinDrainBlocked", true, false, timeSlider);
|
||||
EGSDK::GamePH::PlayerVariables::ManageVarByBool("AntizinDrainBlocked", true, false, timeSlider);
|
||||
if (timeSlider) {
|
||||
requestedTimeWeatherInterpolation = true;
|
||||
timeBeforeFreeze = time;
|
||||
|
Reference in New Issue
Block a user