mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 17:37:53 +08:00
merged variables list rendering logic into 1 class
This commit is contained in:
@ -75,6 +75,9 @@ namespace EGSDK::Engine {
|
||||
using Base::GetDefaultVarRef;
|
||||
using Base::GetCustomDefaultVarRef;
|
||||
|
||||
using VarT = CVar;
|
||||
using VarMapT = CVarMap;
|
||||
|
||||
static std::optional<CVarRef> GetVarRef(uint32_t valueOffset);
|
||||
static std::optional<CVarRef> GetCustomVarRef(uint32_t valueOffset);
|
||||
static std::optional<CVarRef> GetDefaultVarRef(uint32_t valueOffset);
|
||||
|
@ -35,8 +35,8 @@ namespace EGSDK::Engine {
|
||||
VarType GetType() const;
|
||||
void SetType(VarType type);
|
||||
protected:
|
||||
static std::mutex writingMutex;
|
||||
static std::shared_mutex readingMutex;
|
||||
static std::mutex writeMutex;
|
||||
static std::shared_mutex readMutex;
|
||||
private:
|
||||
static std::unordered_map<const VarBase*, std::string> varNames;
|
||||
static std::unordered_map<const VarBase*, VarType> varTypes;
|
||||
|
@ -48,8 +48,8 @@ namespace EGSDK::Engine {
|
||||
static std::unordered_map<std::string, std::any> prevVarValueMap;
|
||||
static std::unordered_map<std::string, bool> prevBoolValueMap;
|
||||
static std::unordered_map<std::string, uint64_t> varOwnerMap;
|
||||
static std::mutex writingMutex;
|
||||
static std::shared_mutex readingMutex;
|
||||
static std::mutex writeMutex;
|
||||
static std::shared_mutex readMutex;
|
||||
|
||||
static std::optional<VarRef<VarMapT, VarT>> _GetVarRef(const char* name, VarMapT& map);
|
||||
|
||||
@ -101,7 +101,7 @@ namespace EGSDK::Engine {
|
||||
return;
|
||||
|
||||
uint64_t caller = reinterpret_cast<uint64_t>(returnAddr);
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
|
||||
const char* name = var->GetName();
|
||||
|
||||
@ -133,7 +133,7 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
}
|
||||
template <AllowedVarTypes T>
|
||||
static void _SaveVariableAsDefault(VarRef<VarMapT, VarT>* var) {
|
||||
static void _SaveVarAsDefault(VarRef<VarMapT, VarT>* var) {
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
|
@ -33,14 +33,14 @@ namespace EGSDK::Engine {
|
||||
|
||||
template <typename Callable, typename... Args>
|
||||
void ForEach(Callable&& func, Args&&... args) {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
for (const auto& name : varsOrdered)
|
||||
func(vars.at(name), std::forward<Args>(args)...);
|
||||
}
|
||||
protected:
|
||||
std::unordered_map<std::string, std::unique_ptr<VarT>> vars;
|
||||
std::vector<std::string> varsOrdered;
|
||||
mutable std::mutex writingMutex;
|
||||
mutable std::shared_mutex readingMutex;
|
||||
mutable std::mutex writeMutex;
|
||||
mutable std::shared_mutex readMutex;
|
||||
};
|
||||
}
|
@ -64,8 +64,8 @@ namespace EGSDK::Engine {
|
||||
VarMgrBase::template _ManageByBool<T>(this, valueIfTrue, valueIfFalse, boolVal, usePreviousVal);
|
||||
}
|
||||
template <AllowedVarTypes T>
|
||||
void SaveVariableAsDefault() {
|
||||
VarMgrBase::template _SaveVariableAsDefault<T>(this);
|
||||
void SaveVarAsDefault() {
|
||||
VarMgrBase::template _SaveVarAsDefault<T>(this);
|
||||
}
|
||||
template <AllowedVarTypes T>
|
||||
void RestoreVarToDefault(bool restoreToSavedVars = false) {
|
||||
|
@ -54,6 +54,9 @@ namespace EGSDK::GamePH {
|
||||
using Base::GetDefaultVarRef;
|
||||
using Base::GetCustomDefaultVarRef;
|
||||
|
||||
using VarT = PlayerVar;
|
||||
using VarMapT = PlayerVarMap;
|
||||
|
||||
static std::atomic<bool> gotPlayerVars;
|
||||
|
||||
#ifdef EGameSDK_EXPORTS
|
||||
|
@ -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::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
auto it = varValues.find(this);
|
||||
if (it == varValues.end()) {
|
||||
switch (GetType()) {
|
||||
@ -47,7 +47,7 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
}
|
||||
void CVar::SetValue(const VarValueType& value) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
auto& varData = varValues[this];
|
||||
|
||||
std::visit([&](auto&& val) {
|
||||
@ -70,7 +70,7 @@ namespace EGSDK::Engine {
|
||||
}, value);
|
||||
}
|
||||
void CVar::AddValuePtr(uint64_t* ptr) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
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 lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
const std::string& name = cVar->GetName();
|
||||
auto [it, inserted] = vars.try_emplace(name, std::move(cVar));
|
||||
if (inserted) {
|
||||
@ -99,12 +99,12 @@ namespace EGSDK::Engine {
|
||||
return it->second;
|
||||
}
|
||||
CVar* CVarMap::Find(uint32_t valueOffset) const {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
auto it = varsByValueOffset.find(valueOffset);
|
||||
return it == varsByValueOffset.end() ? nullptr : it->second;
|
||||
}
|
||||
void CVarMap::Erase(const std::string& name) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
auto it = vars.find(name);
|
||||
if (it == vars.end())
|
||||
return;
|
||||
@ -118,7 +118,7 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
|
||||
bool CVarMap::none_of(uint32_t valueOffset) {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
return varsByValueOffset.find(valueOffset) == varsByValueOffset.end();
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
namespace EGSDK::Engine {
|
||||
std::unordered_map<const VarBase*, std::string> VarBase::varNames{};
|
||||
std::unordered_map<const VarBase*, VarType> VarBase::varTypes{};
|
||||
std::mutex VarBase::writingMutex{};
|
||||
std::shared_mutex VarBase::readingMutex{};
|
||||
std::mutex VarBase::writeMutex{};
|
||||
std::shared_mutex VarBase::readMutex{};
|
||||
|
||||
VarBase::VarBase(const std::string& name, VarType type) {
|
||||
SetName(name);
|
||||
@ -16,22 +16,22 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
|
||||
const char* VarBase::GetName() const {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
auto it = varNames.find(this);
|
||||
return it != varNames.end() ? it->second.c_str() : nullptr;
|
||||
}
|
||||
void VarBase::SetName(const std::string& newName) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
varNames[this] = newName;
|
||||
}
|
||||
|
||||
VarType VarBase::GetType() const {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
auto it = varTypes.find(this);
|
||||
return it != varTypes.end() ? it->second : VarType::NONE;
|
||||
}
|
||||
void VarBase::SetType(VarType newType) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
varTypes[this] = newType;
|
||||
}
|
||||
}
|
@ -21,9 +21,9 @@ namespace EGSDK::Engine {
|
||||
std::unordered_map<std::string, uint64_t> VarManagerBase<VarMapT, VarT>::varOwnerMap{};
|
||||
|
||||
template <typename VarMapT, typename VarT>
|
||||
std::mutex VarManagerBase<VarMapT, VarT>::writingMutex{};
|
||||
std::mutex VarManagerBase<VarMapT, VarT>::writeMutex{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
std::shared_mutex VarManagerBase<VarMapT, VarT>::readingMutex{};
|
||||
std::shared_mutex VarManagerBase<VarMapT, VarT>::readMutex{};
|
||||
|
||||
template <typename VarMapT, typename VarT>
|
||||
std::optional<VarRef<VarMapT, VarT>> VarManagerBase<VarMapT, VarT>::GetVarRefFromPtr(VarT* var) {
|
||||
@ -74,7 +74,7 @@ namespace EGSDK::Engine {
|
||||
|
||||
template <typename VarMapT, typename VarT>
|
||||
bool VarManagerBase<VarMapT, VarT>::_IsManagedByBool(const char* name) {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
return (prevBoolValueMap.find(name) != prevBoolValueMap.end()) && prevBoolValueMap[name];
|
||||
}
|
||||
template <typename VarMapT, typename VarT>
|
||||
|
@ -5,11 +5,11 @@
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
template <typename VarT>
|
||||
VarMapBase<VarT>::VarMapBase() : vars(), varsOrdered(), writingMutex(), readingMutex() {}
|
||||
VarMapBase<VarT>::VarMapBase() : vars(), varsOrdered(), writeMutex(), readMutex() {}
|
||||
|
||||
template <typename VarT>
|
||||
std::unique_ptr<VarT>& VarMapBase<VarT>::try_emplace(std::unique_ptr<VarT> var) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
const std::string& name = var->GetName();
|
||||
auto [it, inserted] = vars.try_emplace(name, std::move(var));
|
||||
if (inserted)
|
||||
@ -18,13 +18,13 @@ namespace EGSDK::Engine {
|
||||
}
|
||||
template <typename VarT>
|
||||
VarT* VarMapBase<VarT>::Find(const std::string& name) const {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
auto it = vars.find(name);
|
||||
return (it != vars.end()) ? it->second.get() : nullptr;
|
||||
}
|
||||
template <typename VarT>
|
||||
void VarMapBase<VarT>::Erase(const std::string& name) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
auto it = vars.find(name);
|
||||
if (it == vars.end())
|
||||
return;
|
||||
@ -36,22 +36,22 @@ namespace EGSDK::Engine {
|
||||
|
||||
template <typename VarT>
|
||||
bool VarMapBase<VarT>::empty() const {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
return vars.empty();
|
||||
}
|
||||
template <typename VarT>
|
||||
bool VarMapBase<VarT>::none_of(const std::string& name) const {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
return vars.find(name) == vars.end();
|
||||
}
|
||||
template <typename VarT>
|
||||
size_t VarMapBase<VarT>::size() {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
return vars.size();
|
||||
}
|
||||
template <typename VarT>
|
||||
void VarMapBase<VarT>::reserve(size_t count) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
vars.reserve(count);
|
||||
varsOrdered.reserve(count);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace EGSDK::GamePH {
|
||||
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::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
switch (GetType()) {
|
||||
case Engine::VarType::String:
|
||||
return reinterpret_cast<const char*>(reinterpret_cast<uint64_t>(this->strValue.data) & 0x1FFFFFFFFFFFFFFF);
|
||||
@ -28,7 +28,7 @@ namespace EGSDK::GamePH {
|
||||
}
|
||||
}
|
||||
Engine::VarValueType PlayerVar::GetDefaultValue() {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
switch (GetType()) {
|
||||
case Engine::VarType::String:
|
||||
return reinterpret_cast<const char*>(reinterpret_cast<uint64_t>(this->defaultStrValue.data) & 0x1FFFFFFFFFFFFFFF);
|
||||
@ -41,7 +41,7 @@ namespace EGSDK::GamePH {
|
||||
}
|
||||
}
|
||||
void PlayerVar::SetValue(const Engine::VarValueType& value) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
std::visit([&](auto&& val) {
|
||||
using T = std::decay_t<decltype(val)>;
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
|
@ -40,6 +40,7 @@
|
||||
<ClCompile Include="src\Menu\Misc.cpp" />
|
||||
<ClCompile Include="src\Menu\Player.cpp" />
|
||||
<ClCompile Include="src\Menu\Teleport.cpp" />
|
||||
<ClCompile Include="src\Menu\VarList.cpp" />
|
||||
<ClCompile Include="src\Menu\Weapon.cpp" />
|
||||
<ClCompile Include="src\Menu\World.cpp" />
|
||||
<ClCompile Include="src\Utils\Texture.cpp" />
|
||||
@ -65,6 +66,7 @@
|
||||
<ClInclude Include="include\EGT\Menu\Misc.h" />
|
||||
<ClInclude Include="include\EGT\Menu\Player.h" />
|
||||
<ClInclude Include="include\EGT\Menu\Teleport.h" />
|
||||
<ClInclude Include="include\EGT\Menu\VarList.h" />
|
||||
<ClInclude Include="include\EGT\Menu\Weapon.h" />
|
||||
<ClInclude Include="include\EGT\Menu\World.h" />
|
||||
<ClInclude Include="include\EGT\Utils\Texture.h" />
|
||||
|
@ -165,6 +165,9 @@
|
||||
<ClCompile Include="src\ImGui_impl\DeferredActions.cpp">
|
||||
<Filter>src\ImGui_impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Menu\VarList.cpp">
|
||||
<Filter>src\Menu</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\EGT\Config\Config.h">
|
||||
@ -236,5 +239,8 @@
|
||||
<ClInclude Include="include\EGT\ImGui_impl\NextFrameTask.h">
|
||||
<Filter>include\ImGui_impl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\EGT\Menu\VarList.h">
|
||||
<Filter>include\Menu</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -14,7 +14,7 @@ namespace EGT::ImGui_impl {
|
||||
static void Process();
|
||||
private:
|
||||
static std::vector<std::function<void()>> actions;
|
||||
static std::mutex writingMutex;
|
||||
static std::shared_mutex readingMutex;
|
||||
static std::mutex writeMutex;
|
||||
static std::shared_mutex readMutex;
|
||||
};
|
||||
}
|
@ -18,7 +18,7 @@ namespace EGT::ImGui_impl {
|
||||
};
|
||||
|
||||
static std::vector<TaskEntry> taskQueue;
|
||||
static std::mutex writingMutex;
|
||||
static std::shared_mutex readingMutex;
|
||||
static std::mutex writeMutex;
|
||||
static std::shared_mutex readMutex;
|
||||
};
|
||||
}
|
47
EGameTools/include/EGT/Menu/VarList.h
Normal file
47
EGameTools/include/EGT/Menu/VarList.h
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <shared_mutex>
|
||||
#include <ImGui\imguiex.h>
|
||||
#include <EGSDK\Engine\VarBase.h>
|
||||
#include <EGSDK\Engine\VarMapBase.h>
|
||||
#include <EGSDK\Engine\VarManagerBase.h>
|
||||
#include <EGT\ImGui_impl\DeferredActions.h>
|
||||
|
||||
namespace EGT {
|
||||
namespace Menu {
|
||||
template <typename VarManagerT>
|
||||
class VarList {
|
||||
public:
|
||||
using VarT = typename VarManagerT::VarT;
|
||||
using VarPtr = std::unique_ptr<VarT>;
|
||||
|
||||
VarList(const std::string& title);
|
||||
VarList(const VarList&) = delete;
|
||||
VarList& operator=(const VarList&) = delete;
|
||||
VarList(VarList&&) noexcept = default;
|
||||
VarList& operator=(VarList&&) noexcept = default;
|
||||
|
||||
void Render();
|
||||
private:
|
||||
std::string listTitle{};
|
||||
|
||||
std::vector<VarT*> filteredVars{};
|
||||
bool restoreVarsToSavedVarsEnabled = false;
|
||||
char searchFilter[64] = "";
|
||||
char lastSearchFilter[64] = "";
|
||||
|
||||
void RestoreVarToDefault(VarT* varPtr);
|
||||
void RestoreVarsToDefault();
|
||||
void SaveVarAsDefault(const VarPtr& varPtr);
|
||||
void SaveVarsAsDefault();
|
||||
|
||||
bool ShouldDisplayVar(const VarPtr& varPtr);
|
||||
void UpdateFilteredList();
|
||||
|
||||
void RenderVar(VarT* var);
|
||||
};
|
||||
}
|
||||
}
|
@ -2,26 +2,26 @@
|
||||
|
||||
namespace EGT::ImGui_impl {
|
||||
std::vector<std::function<void()>> DeferredActions::actions{};
|
||||
std::mutex DeferredActions::writingMutex{};
|
||||
std::shared_mutex DeferredActions::readingMutex{};
|
||||
std::mutex DeferredActions::writeMutex{};
|
||||
std::shared_mutex DeferredActions::readMutex{};
|
||||
|
||||
void DeferredActions::Add(const std::function<void()>& action) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
actions.push_back(action);
|
||||
}
|
||||
void DeferredActions::Clear() {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
actions.clear();
|
||||
}
|
||||
|
||||
bool DeferredActions::HasPendingActions() {
|
||||
std::shared_lock lock(readingMutex);
|
||||
std::shared_lock lock(readMutex);
|
||||
return !actions.empty();
|
||||
}
|
||||
void DeferredActions::Process() {
|
||||
std::vector<std::function<void()>> actionsToProcess;
|
||||
{
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
actionsToProcess.swap(actions);
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
namespace EGT::ImGui_impl {
|
||||
std::vector<NextFrameTask::TaskEntry> NextFrameTask::taskQueue;
|
||||
std::mutex NextFrameTask::writingMutex{};
|
||||
std::shared_mutex NextFrameTask::readingMutex{};
|
||||
std::mutex NextFrameTask::writeMutex{};
|
||||
std::shared_mutex NextFrameTask::readMutex{};
|
||||
|
||||
void NextFrameTask::AddTask(const Task& task, int delayFrames) {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
taskQueue.emplace_back(TaskEntry{ delayFrames, task });
|
||||
}
|
||||
void NextFrameTask::ExecuteTasks() {
|
||||
std::lock_guard lock(writingMutex);
|
||||
std::lock_guard lock(writeMutex);
|
||||
for (auto it = taskQueue.begin(); it != taskQueue.end();) {
|
||||
if (it->framesRemaining <= 0) {
|
||||
it->task();
|
||||
|
@ -5,8 +5,9 @@
|
||||
#include <EGSDK\GamePH\GameDI_PH.h>
|
||||
#include <EGSDK\GamePH\LevelDI.h>
|
||||
#include <EGT\ImGui_impl\DeferredActions.h>
|
||||
#include <EGT\Menu\Misc.h>
|
||||
#include <EGT\GamePH\GamePH_Hooks.h>
|
||||
#include <EGT\Menu\Misc.h>
|
||||
#include <EGT\Menu\VarList.h>
|
||||
|
||||
namespace EGT::Menu {
|
||||
namespace Misc {
|
||||
@ -17,132 +18,13 @@ namespace EGT::Menu {
|
||||
ImGui::Option disableDataPAKsCRCCheck{ false };
|
||||
ImGui::Option increaseDataPAKsLimit{ false };
|
||||
|
||||
static char rendererCVarsSearchFilter[64];
|
||||
static VarList<EGSDK::Engine::CVars> cVarsList{ "Renderer CVars List" };
|
||||
|
||||
static void RendererCVarsUpdate() {
|
||||
EGSDK::Engine::CVars::ManageVarByBool("i_pp_taa_on", 0, 1, disableTAA.GetValue());
|
||||
EGSDK::Engine::CVars::ManageVarByBool("i_pp_jitter_on", 0, 1, disableTAA.GetValue());
|
||||
}
|
||||
|
||||
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(cVarPtr->GetName());
|
||||
return lowerKey.find(lowerFilter) != std::string::npos;
|
||||
}
|
||||
static void RestoreVariableToDefault(const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
auto cVar = EGSDK::Engine::CVars::GetVarRefFromPtr(cVarPtr.get());
|
||||
|
||||
ImGui_impl::DeferredActions::Add([cVar]() mutable {
|
||||
switch (cVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
cVar->RestoreVarToDefault<float>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
cVar->RestoreVarToDefault<int>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec3:
|
||||
cVar->RestoreVarToDefault<EGSDK::Vec3>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec4:
|
||||
cVar->RestoreVarToDefault<EGSDK::Vec4>();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
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 = EGSDK::Engine::CVars::GetVarRefFromPtr(cVarPtr.get());
|
||||
|
||||
ImGui::BeginDisabled(cVar->IsManagedByBool());
|
||||
switch (cVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto value = cVar->GetValue<float>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat(cVar->GetName(), &newValue))
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
{
|
||||
auto value = cVar->GetValue<int>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputInt(cVar->GetName(), &newValue))
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Vec3:
|
||||
{
|
||||
auto value = cVar->GetValue<EGSDK::Vec3>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat3(cVar->GetName(), reinterpret_cast<float*>(&newValue)))
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Vec4:
|
||||
{
|
||||
auto value = cVar->GetValue<EGSDK::Vec4>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat4(cVar->GetName(), reinterpret_cast<float*>(&newValue)))
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
std::string restoreBtnName = "Restore##" + std::string(cVar->GetName());
|
||||
|
||||
ImGui::BeginDisabled(!cVar->HasCustomValue() || cVar->IsManagedByBool());
|
||||
if (ImGui::Button(restoreBtnName.c_str(), "Restores renderer cvar to default"))
|
||||
RestoreVariableToDefault(cVarPtr);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
static void HandleRendererCVarsList() {
|
||||
ImGui::BeginDisabled(!EGSDK::Engine::CVars::AreAnyVarsPresent());
|
||||
if (ImGui::CollapsingHeader("Renderer CVars list", ImGuiTreeNodeFlags_None)) {
|
||||
ImGui::Indent();
|
||||
|
||||
ImGui::BeginDisabled(!EGSDK::Engine::CVars::AreAnyCustomVarsPresent() || EGSDK::Engine::CVars::AreAllCustomVarsManagedByBool());
|
||||
if (ImGui::Button("Restore variables to default"))
|
||||
RestoreVariablesToDefault();
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::InputTextWithHint("##RendererCVarsSearch", "Search variables", rendererCVarsSearchFilter, 64);
|
||||
|
||||
EGSDK::Engine::CVars::vars.ForEach([](std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
if (ShouldDisplayVariable(cVarPtr, rendererCVarsSearchFilter))
|
||||
RenderRendererCVar(cVarPtr);
|
||||
});
|
||||
|
||||
ImGui::Unindent();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
static void UpdateDisabledOptions() {
|
||||
auto iLevel = EGSDK::GamePH::LevelDI::Get();
|
||||
disableHUD.SetChangesAreDisabled(!iLevel || !iLevel->IsLoaded());
|
||||
@ -184,7 +66,7 @@ namespace EGT::Menu {
|
||||
ImGui::CheckboxHotkey("Disable TAA", &disableTAA, "Disables the TAA/anti-aliasing (only works if you have upscaling disabled)");
|
||||
|
||||
ImGui::SeparatorText("Scripting##Misc");
|
||||
HandleRendererCVarsList();
|
||||
cVarsList.Render();
|
||||
|
||||
ImGui::SeparatorText("Game Checks##Misc");
|
||||
if (ImGui::Checkbox("Disable Savegame CRC Check *", &disableSavegameCRCCheck, "Stops the game from falsely saying your savegame is corrupt whenever you modify it outside of the game using a save editor"))
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <EGT\Menu\Camera.h>
|
||||
#include <EGT\Menu\Menu.h>
|
||||
#include <EGT\Menu\Player.h>
|
||||
#include <EGT\Menu\VarList.h>
|
||||
|
||||
namespace EGT::Menu {
|
||||
namespace Player {
|
||||
@ -48,8 +49,7 @@ namespace EGT::Menu {
|
||||
std::string loadSCRFilePath{};
|
||||
|
||||
static bool debugEnabled = false;
|
||||
static bool restoreVarsToSavedVarsEnabled = false;
|
||||
static char varsSearchFilter[64];
|
||||
static VarList<EGSDK::GamePH::PlayerVariables> playerVarList{ "Player Variables List" };
|
||||
|
||||
#pragma region Player Variables
|
||||
static std::string getParamName(const std::string& str) {
|
||||
@ -125,7 +125,7 @@ namespace EGT::Menu {
|
||||
}
|
||||
});
|
||||
}
|
||||
static void varsUpdate() {
|
||||
static void ManagePlayerVars() {
|
||||
if (!EGSDK::GamePH::PlayerVariables::gotPlayerVars)
|
||||
return;
|
||||
|
||||
@ -225,67 +225,6 @@ namespace EGT::Menu {
|
||||
ImGui::OpenPopup("Loaded player variables!");
|
||||
}
|
||||
|
||||
static void RestoreVariableToDefault(EGSDK::GamePH::PlayerVar* playerVarPtr) {
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(playerVarPtr->GetName());
|
||||
if (!playerVar)
|
||||
return;
|
||||
|
||||
ImGui_impl::DeferredActions::Add([playerVar]() mutable {
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
playerVar->RestoreVarToDefault<float>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
playerVar->RestoreVarToDefault<bool>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
static void RestoreVariablesToDefault() {
|
||||
(restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::vars : EGSDK::GamePH::PlayerVariables::customVars).ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
RestoreVariableToDefault(playerVarPtr.get());
|
||||
});
|
||||
}
|
||||
static void SaveVariableAsDefault(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRefFromPtr(playerVarPtr.get());
|
||||
if (!playerVar)
|
||||
return;
|
||||
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
playerVar->SaveVariableAsDefault<float>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
playerVar->SaveVariableAsDefault<bool>();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void SaveVariablesAsDefault() {
|
||||
EGSDK::GamePH::PlayerVariables::vars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
SaveVariableAsDefault(playerVarPtr);
|
||||
});
|
||||
ImGui::OpenPopup("Saved current player variables!");
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Convert searchFilter and variable name to lowercase
|
||||
std::string lowerFilter = EGSDK::Utils::Values::to_lower(searchFilter);
|
||||
std::string lowerKey = EGSDK::Utils::Values::to_lower(playerVarPtr->GetName());
|
||||
return lowerKey.find(lowerFilter) != std::string::npos;
|
||||
}
|
||||
static void RenderDebugInfo(EGSDK::GamePH::PlayerVar* playerVarPtr) {
|
||||
const float maxInputTextWidth = ImGui::CalcTextSize("0x0000000000000000").x;
|
||||
std::string labelID = "##DebugAddrInputText" + std::string(playerVarPtr->GetName());
|
||||
@ -305,106 +244,12 @@ 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(EGSDK::GamePH::PlayerVar* playerVarPtr) {
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRefFromPtr(playerVarPtr);
|
||||
if (!playerVar)
|
||||
return;
|
||||
|
||||
ImGui::BeginDisabled(playerVar->IsManagedByBool());
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto value = playerVar->GetValue<float>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat(playerVar->GetName(), &newValue))
|
||||
playerVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto value = playerVar->GetValue<bool>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::Checkbox(playerVar->GetName(), &newValue))
|
||||
playerVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
std::string restoreBtnName = "Restore##" + std::string(playerVarPtr->GetName());
|
||||
|
||||
ImGui::BeginDisabled(!playerVar->HasCustomValue() || playerVar->IsManagedByBool());
|
||||
if (ImGui::Button(restoreBtnName.c_str(), "Restores player variable to default"))
|
||||
RestoreVariableToDefault(playerVarPtr);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (debugEnabled)
|
||||
RenderDebugInfo(playerVarPtr);
|
||||
}
|
||||
static void HandlePlayerVariablesList() {
|
||||
if (!playerVariables.GetValue())
|
||||
return;
|
||||
|
||||
ImGui::BeginDisabled(!EGSDK::GamePH::PlayerVariables::gotPlayerVars);
|
||||
if (ImGui::CollapsingHeader("Player Variables list", ImGuiTreeNodeFlags_None)) {
|
||||
ImGui::Indent();
|
||||
|
||||
if (ImGui::Button("Save variables to file", "Saves current player variables to chosen file inside the file dialog"))
|
||||
ImGuiFileDialog::Instance()->OpenDialog("ChooseSCRPath", "Choose Folder", nullptr, { saveSCRPath.empty() ? "." : saveSCRPath });
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Load variables from file", "Loads player variables from chosen file inside the file dialog")) {
|
||||
std::filesystem::path _loadSCRFilePath = loadSCRFilePath;
|
||||
ImGuiFileDialog::Instance()->OpenDialog("ChooseSCRLoadPath", "Choose File", ".scr", { !_loadSCRFilePath.empty() && std::filesystem::is_directory(_loadSCRFilePath.parent_path()) ? _loadSCRFilePath.parent_path().string() : "." });
|
||||
}
|
||||
|
||||
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::AreAnyCustomVarsPresent() || EGSDK::GamePH::PlayerVariables::AreAllCustomVarsManagedByBool());
|
||||
if (ImGui::Button("Restore variables to default"))
|
||||
RestoreVariablesToDefault();
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save current variables as default", "Saves the current player variables as default for whenever you use \"Restore variables to default\""))
|
||||
SaveVariablesAsDefault();
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::InputTextWithHint("##PlayerVariablesSearch", "Search variables", varsSearchFilter, 64);
|
||||
|
||||
static std::vector<EGSDK::GamePH::PlayerVar*> filteredVars;
|
||||
static char lastSearchFilter[64];
|
||||
|
||||
if (filteredVars.empty() || _strcmpi(varsSearchFilter, lastSearchFilter)) {
|
||||
strcpy_s(lastSearchFilter, varsSearchFilter); // Update last search filter
|
||||
filteredVars.clear();
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::vars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
if (ShouldDisplayVariable(playerVarPtr, varsSearchFilter))
|
||||
filteredVars.push_back(playerVarPtr.get()); // Store raw pointer
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::Text("Total variables: %zu", filteredVars.size()); // Debug info
|
||||
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(filteredVars.size());
|
||||
|
||||
while (clipper.Step()) {
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i)
|
||||
RenderPlayerVariable(filteredVars[i]);
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
}
|
||||
playerVarList.Render();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
static void HandlePlayerVariablesDialogs() {
|
||||
@ -574,7 +419,7 @@ namespace EGT::Menu {
|
||||
PlayerImmunityUpdate();
|
||||
PlayerRestrictionsUpdate();
|
||||
|
||||
varsUpdate();
|
||||
ManagePlayerVars();
|
||||
PlayerVarListValuesUpdate();
|
||||
|
||||
HandleToggles();
|
||||
|
241
EGameTools/src/Menu/VarList.cpp
Normal file
241
EGameTools/src/Menu/VarList.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
#include <EGT\Menu\VarList.h>
|
||||
#include <EGSDK\GamePH\PlayerVariables.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
|
||||
namespace EGT {
|
||||
namespace Menu {
|
||||
template <typename VarManagerT>
|
||||
VarList<VarManagerT>::VarList(const std::string& title) : listTitle(title) {}
|
||||
|
||||
template <typename VarManagerT>
|
||||
void VarList<VarManagerT>::Render() {
|
||||
ImGui::BeginDisabled(!VarManagerT::AreAnyVarsPresent());
|
||||
if (ImGui::CollapsingHeader(listTitle.c_str(), ImGuiTreeNodeFlags_None)) {
|
||||
ImGui::Indent();
|
||||
|
||||
//if (ImGui::Button("Save variables to file", "Saves current player variables to chosen file inside the file dialog"))
|
||||
// ImGuiFileDialog::Instance()->OpenDialog("ChooseSCRPath", "Choose Folder", nullptr, { saveSCRPath.empty() ? "." : saveSCRPath });
|
||||
//ImGui::SameLine();
|
||||
//if (ImGui::Button("Load variables from file", "Loads player variables from chosen file inside the file dialog")) {
|
||||
// std::filesystem::path _loadSCRFilePath = loadSCRFilePath;
|
||||
// ImGuiFileDialog::Instance()->OpenDialog("ChooseSCRLoadPath", "Choose File", ".scr", { !_loadSCRFilePath.empty() && std::filesystem::is_directory(_loadSCRFilePath.parent_path()) ? _loadSCRFilePath.parent_path().string() : "." });
|
||||
//}
|
||||
|
||||
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(!VarManagerT::AreAnyCustomVarsPresent() || VarManagerT::AreAllCustomVarsManagedByBool());
|
||||
if (ImGui::Button("Restore variables to default"))
|
||||
RestoreVarsToDefault();
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save current variables as default", "Saves the current variables as default for whenever you use \"Restore variables to default\""))
|
||||
SaveVarsAsDefault();
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::InputTextWithHint("##SearchFilter", "Search variables...", searchFilter, sizeof(searchFilter));
|
||||
|
||||
UpdateFilteredList();
|
||||
|
||||
ImGui::Text("Total listed variables: %zu", filteredVars.size());
|
||||
|
||||
ImGuiListClipper clipper{};
|
||||
clipper.Begin(filteredVars.size());
|
||||
|
||||
while (clipper.Step()) {
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; ++i)
|
||||
RenderVar(filteredVars[i]);
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
template <typename VarManagerT>
|
||||
void VarList<VarManagerT>::RestoreVarToDefault(VarT* varPtr) {
|
||||
auto var = VarManagerT::GetVarRef(varPtr->GetName());
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
ImGui_impl::DeferredActions::Add([this, var]() mutable {
|
||||
switch (var->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
var->RestoreVarToDefault<float>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
var->RestoreVarToDefault<int>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec3:
|
||||
var->RestoreVarToDefault<EGSDK::Vec3>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec4:
|
||||
var->RestoreVarToDefault<EGSDK::Vec4>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
var->RestoreVarToDefault<bool>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
template <typename VarManagerT>
|
||||
void VarList<VarManagerT>::RestoreVarsToDefault() {
|
||||
(restoreVarsToSavedVarsEnabled ? VarManagerT::vars : VarManagerT::customVars).ForEach([this](VarPtr& varPtr) {
|
||||
RestoreVarToDefault(varPtr.get());
|
||||
});
|
||||
}
|
||||
template <typename VarManagerT>
|
||||
void VarList<VarManagerT>::SaveVarAsDefault(const VarPtr& varPtr) {
|
||||
auto var = VarManagerT::GetVarRefFromPtr(varPtr.get());
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
switch (var->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
var->SaveVarAsDefault<float>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
var->SaveVarAsDefault<int>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec3:
|
||||
var->SaveVarAsDefault<EGSDK::Vec3>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec4:
|
||||
var->SaveVarAsDefault<EGSDK::Vec4>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
var->SaveVarAsDefault<bool>();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
template <typename VarManagerT>
|
||||
void VarList<VarManagerT>::SaveVarsAsDefault() {
|
||||
VarManagerT::vars.ForEach([this](VarPtr& varPtr) {
|
||||
SaveVarAsDefault(varPtr);
|
||||
});
|
||||
//ImGui::OpenPopup("Saved current player variables!");
|
||||
}
|
||||
|
||||
template <typename VarManagerT>
|
||||
bool VarList<VarManagerT>::ShouldDisplayVar(const VarPtr& varPtr) {
|
||||
if (!searchFilter[0])
|
||||
return true;
|
||||
if (varPtr->GetType() == EGSDK::Engine::VarType::NONE)
|
||||
return false;
|
||||
|
||||
// Convert searchFilter and variable name to lowercase
|
||||
std::string lowerFilter = EGSDK::Utils::Values::to_lower(searchFilter);
|
||||
std::string lowerKey = EGSDK::Utils::Values::to_lower(varPtr->GetName());
|
||||
return lowerKey.find(lowerFilter) != std::string::npos;
|
||||
}
|
||||
template <typename VarManagerT>
|
||||
void VarList<VarManagerT>::UpdateFilteredList() {
|
||||
if (filteredVars.empty() || _strcmpi(searchFilter, lastSearchFilter)) {
|
||||
strcpy_s(lastSearchFilter, searchFilter);
|
||||
filteredVars.clear();
|
||||
|
||||
VarManagerT::vars.ForEach([this](VarPtr& varPtr) {
|
||||
if (ShouldDisplayVar(varPtr))
|
||||
filteredVars.push_back(varPtr.get());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VarManagerT>
|
||||
void VarList<VarManagerT>::RenderVar(VarT* varPtr) {
|
||||
auto var = VarManagerT::GetVarRefFromPtr(varPtr);
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
ImGui::BeginDisabled(var->IsManagedByBool());
|
||||
switch (var->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
{
|
||||
static char buffer[256];
|
||||
//std::strncpy(buffer, value->c_str(), sizeof(buffer) - 1);
|
||||
//buffer[sizeof(buffer) - 1] = '\0';
|
||||
|
||||
ImGui::BeginDisabled();
|
||||
if (ImGui::InputText(var->GetName(), buffer, sizeof(buffer)))
|
||||
var->SetValueFromList(std::string(buffer));
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SetItemTooltip("STRING VARIABLES NOT IMPLEMENTED");
|
||||
break; // TO IMPLEMENT
|
||||
}
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto value = var->GetValue<float>();
|
||||
if (!value) return;
|
||||
float newValue = *value;
|
||||
if (ImGui::InputFloat(var->GetName(), &newValue))
|
||||
var->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
{
|
||||
auto value = var->GetValue<int>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputInt(var->GetName(), &newValue))
|
||||
var->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Vec3:
|
||||
{
|
||||
auto value = var->GetValue<EGSDK::Vec3>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat3(var->GetName(), reinterpret_cast<float*>(&newValue)))
|
||||
var->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Vec4:
|
||||
{
|
||||
auto value = var->GetValue<EGSDK::Vec4>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat4(var->GetName(), reinterpret_cast<float*>(&newValue)))
|
||||
var->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto value = var->GetValue<bool>();
|
||||
if (!value) return;
|
||||
bool newValue = *value;
|
||||
if (ImGui::Checkbox(var->GetName(), &newValue))
|
||||
var->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
std::string restoreBtnName = "Restore##" + std::string(var->GetName());
|
||||
|
||||
ImGui::BeginDisabled(!var->HasCustomValue() || var->IsManagedByBool());
|
||||
if (ImGui::Button(restoreBtnName.c_str(), "Restores variable to default"))
|
||||
RestoreVarToDefault(varPtr);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
//if (debugEnabled)
|
||||
// RenderDebugInfo(playerVarPtr);
|
||||
}
|
||||
|
||||
template class VarList<EGSDK::GamePH::PlayerVariables>;
|
||||
template class VarList<EGSDK::Engine::CVars>;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user