From 5517c28ad0a85508a1dd60daecc7b1954e0bf599 Mon Sep 17 00:00:00 2001 From: Grinch_ Date: Mon, 22 Jan 2024 23:46:47 +0600 Subject: [PATCH] Add random remap feature --- .gitignore | 1 + src/dllmain.cpp | 6 +++ src/extender.h | 25 +++++++++ src/features/common/randomizer.cpp | 3 +- src/features/common/randomremap.cpp | 78 +++++++++++++++++++++++++++++ src/features/common/randomremap.h | 21 ++++++++ src/features/weapon/bloodremap.cpp | 6 +-- src/features/weapon/bloodremap.h | 10 ++-- src/features/weapon/bodystate.h | 2 +- 9 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 src/extender.h create mode 100644 src/features/common/randomremap.cpp create mode 100644 src/features/common/randomremap.h diff --git a/.gitignore b/.gitignore index 64be3aa..deaa259 100644 --- a/.gitignore +++ b/.gitignore @@ -245,3 +245,4 @@ build/obj/Win32/Release/ModelExtras.tlog/link.command.1.tlog build/obj/Win32/Release/ModelExtras.tlog/link.read.1.tlog build/obj/Win32/Release/ModelExtras.tlog/link.write.1.tlog build/obj/Win32/Release/ModelExtras.tlog/ModelExtras.lastbuildstate +build/obj/Win32/Debug/randomremap.obj diff --git a/src/dllmain.cpp b/src/dllmain.cpp index f06871a..efced97 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -7,6 +7,7 @@ #include "features/weapon/bodystate.h" #include "features/weapon/bloodremap.h" #include "features/common/randomizer.h" +#include "features/common/randomremap.h" #include "soundsystem.h" static ThiscallEvent , PRIORITY_BEFORE, ArgPickN, void(CPed*)> weaponRenderEvent; @@ -30,12 +31,14 @@ static void ProcessNodesRecursive(RwFrame * frame, void* pEntity, eNodeEntityTyp GearLever.Process(frame, pVeh); GearSound.Process(frame, pVeh); Randomizer.Process(frame, static_cast(pVeh), type); + RandomRemap.Process(frame, static_cast(pVeh), type); } else if (type == eNodeEntityType::Weapon) { CWeapon *pWep = static_cast(pEntity); BodyState.Process(frame, pWep); BodyState.ProcessZen(frame, pWep); BloodRemap.Process(frame, pWep); Randomizer.Process(frame, static_cast(pWep), type); + RandomRemap.Process(frame, static_cast(pWep), type); } else if (type == eNodeEntityType::Object) { /* @@ -44,6 +47,9 @@ static void ProcessNodesRecursive(RwFrame * frame, void* pEntity, eNodeEntityTyp CWeapon *pWep = static_cast(pEntity); BodyState.Process(frame, pWep); BodyState.ProcessZen(frame, pWep); + } else if (type == eNodeEntityType::Ped) { + Randomizer.Process(frame, pEntity, type); + RandomRemap.Process(frame, pEntity, type); } } // LicensePlate.Process(frame, pVeh); diff --git a/src/extender.h b/src/extender.h new file mode 100644 index 0000000..1976344 --- /dev/null +++ b/src/extender.h @@ -0,0 +1,25 @@ +#pragma once +#include "pch.h" +#include +#include + +template +class Extender { + private: + inline static std::vector> data{}; + + public: + Extender(const Extender&) = delete; + Extender() {} + + Y& Get(T ptr) { + for (auto it = data.begin(); it < data.end(); ++it) { + if (it->first == ptr) { + return it->second; + } + } + + data.push_back({ ptr, Y(ptr) }); + return data.back().second; + } +}; \ No newline at end of file diff --git a/src/features/common/randomizer.cpp b/src/features/common/randomizer.cpp index 7a68422..49e5514 100644 --- a/src/features/common/randomizer.cpp +++ b/src/features/common/randomizer.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "randomizer.h" +#define NODE_ID "x_randomizer" RandomizerFeature Randomizer; @@ -17,7 +18,7 @@ void RandomizerFeature::Initialize(RwFrame* pFrame) { void RandomizerFeature::Process(RwFrame* frame, void* ptr, eNodeEntityType type) { std::string name = GetFrameNodeName(frame); - if (name.find("x_randomizer") != std::string::npos) { + if (name.find(NODE_ID) != std::string::npos) { if (std::find(frameStore.begin(), frameStore.end(), frame) == frameStore.end()) { Initialize(frame); frameStore.push_back(frame); diff --git a/src/features/common/randomremap.cpp b/src/features/common/randomremap.cpp new file mode 100644 index 0000000..6c73dbc --- /dev/null +++ b/src/features/common/randomremap.cpp @@ -0,0 +1,78 @@ +#include "pch.h" +#include "randomremap.h" +#include +#include +#include +#define MAX_REMAPS 32 +#define NODE_ID "x_ranmap" + +RandomRemapFeature RandomRemap; + +struct RemapData { + bool m_bInit; + unsigned int rand; + std::vector m_pTextures; +}; + +void RandomRemapFeature::Process(RwFrame* frame, void* ptr, eNodeEntityType type) { + FrameData &data = xFrame.Get(frame); + + if (data.m_bInit) { + return; + } + + std::string name = GetFrameNodeName(frame); + if (name.find(NODE_ID) != std::string::npos) { + std::string str = Util::GetRegexVal(name, NODE_ID"_(.*)", ""); + + RpClump *pClump; + RemapData remapData; + + CBaseModelInfo *pModelInfo = nullptr; + if (type == eNodeEntityType::Weapon) { + CWeaponInfo* pWeaponInfo = CWeaponInfo::GetWeaponInfo(reinterpret_cast(ptr)->m_eWeaponType, + FindPlayerPed()->GetWeaponSkill(reinterpret_cast(ptr)->m_eWeaponType)); + if (pWeaponInfo){ + pModelInfo = CModelInfo::GetModelInfo(pWeaponInfo->m_nModelId1); + } + } else { + pModelInfo = CModelInfo::GetModelInfo(reinterpret_cast(ptr)->m_nModelIndex); + } + + + if (pModelInfo) { + pClump = pModelInfo->m_pRwClump; + + TxdDef pedTxd = CTxdStore::ms_pTxdPool->m_pObjects[pModelInfo->m_nTxdIndex]; + RwTexDictionary *pedTxdDic = pedTxd.m_pRwDictionary; + if (pedTxdDic) { + RwTexture *ptr = RwTexDictionaryFindHashNamedTexture(pedTxdDic, CKeyGen::GetUppercaseKey(str.c_str())); + remapData.m_pTextures.push_back(ptr); + for (int i = 1; i != MAX_REMAPS; i++) { + RwTexture *ptr = RwTexDictionaryFindHashNamedTexture(pedTxdDic, + CKeyGen::GetUppercaseKey((str + "_" + std::to_string(i)).c_str())); + + if (ptr) { + remapData.m_pTextures.push_back(ptr); + } + } + } + } + + remapData.rand = Random(0u, remapData.m_pTextures.size()-1); + RpClumpForAllAtomics(pClump, [](RpAtomic *atomic, void *data) { + if (atomic->geometry) { + RpGeometryForAllMaterials(atomic->geometry, [](RpMaterial *material, void *data) { + RemapData *pData = reinterpret_cast(data); + if (material->texture == pData->m_pTextures[0]) { + material->texture = pData->m_pTextures[pData->rand]; + } + return material; + }, data); + } + return atomic; + }, &remapData); + + data.m_bInit = true; + } +} \ No newline at end of file diff --git a/src/features/common/randomremap.h b/src/features/common/randomremap.h new file mode 100644 index 0000000..b0fbb92 --- /dev/null +++ b/src/features/common/randomremap.h @@ -0,0 +1,21 @@ +#pragma once +#include "plugin.h" +#include "../../interface/ifeature.hpp" +#include "../../extender.h" + +class RandomRemapFeature : public IFeature { +private: + struct FrameData { + bool m_bInit = false; + FrameData(RwFrame*) {} + ~FrameData() {} + }; + Extender xFrame; + +public: + RandomRemapFeature () {}; + + void Process(RwFrame* frame, void* ptr, eNodeEntityType type); +}; + +extern RandomRemapFeature RandomRemap; \ No newline at end of file diff --git a/src/features/weapon/bloodremap.cpp b/src/features/weapon/bloodremap.cpp index 8e7772d..0c47c3f 100644 --- a/src/features/weapon/bloodremap.cpp +++ b/src/features/weapon/bloodremap.cpp @@ -9,7 +9,7 @@ BloodRemapFeature BloodRemap; void BloodRemapFeature::Initialize(RwFrame* pFrame, CWeapon* pWeapon) { - WepData &data = xData.Get(pWeapon); + FrameData &data = xData.Get(pWeapon); std::string name = GetFrameNodeName(pFrame); std::string str = Util::GetRegexVal(name, "x_remap_(.*)", ""); @@ -40,7 +40,7 @@ void BloodRemapFeature::Initialize(RwFrame* pFrame, CWeapon* pWeapon) { } void BloodRemapFeature::Process(RwFrame* frame, CWeapon *pWeapon) { - WepData &data = xData.Get(pWeapon); + FrameData &data = xData.Get(pWeapon); std::string name = GetFrameNodeName(frame); data.m_CurNode = name; if (name.find("x_remap") != std::string::npos) { @@ -75,7 +75,7 @@ void BloodRemapFeature::Process(RwFrame* frame, CWeapon *pWeapon) { RpClumpForAllAtomics(pWeaponModelInfo->m_pRwClump, [](RpAtomic *atomic, void *data) { if (atomic->geometry) { RpGeometryForAllMaterials(atomic->geometry, [](RpMaterial *material, void *data) { - WepData *pData = reinterpret_cast(data); + FrameData *pData = reinterpret_cast(data); if (material->texture == pData->m_Textures[pData->m_CurNode].m_pFrames[0]) { material->texture = pData->m_Textures[pData->m_CurNode].m_pFrames[pData->m_Textures[pData->m_CurNode].m_nCurRemap]; } diff --git a/src/features/weapon/bloodremap.h b/src/features/weapon/bloodremap.h index fe97422..f5c6861 100644 --- a/src/features/weapon/bloodremap.h +++ b/src/features/weapon/bloodremap.h @@ -1,7 +1,7 @@ #pragma once #include "plugin.h" #include "../../interface/ifeature.hpp" -#include "../../weaponextender.h" +#include "../../weaponExtender.h" #include struct TextureData { @@ -11,17 +11,17 @@ struct TextureData { std::vector m_pFrames; }; -struct WepData { +struct FrameData { std::string m_CurNode = ""; CPed* m_pLastKilledEntity = nullptr; std::map m_Textures; - WepData(CWeapon*) {} - ~WepData() {} + FrameData(CWeapon*) {} + ~FrameData() {} }; class BloodRemapFeature : public IFeature { - WeaponExtender xData; + WeaponExtender xData; public: void Initialize(RwFrame* frame, CWeapon* pWeapon); void Process(RwFrame* frame, CWeapon *pWeapon); diff --git a/src/features/weapon/bodystate.h b/src/features/weapon/bodystate.h index 06c4197..68094c8 100644 --- a/src/features/weapon/bodystate.h +++ b/src/features/weapon/bodystate.h @@ -1,7 +1,7 @@ #pragma once #include "plugin.h" #include "../../interface/ifeature.hpp" -#include "../../weaponextender.h" +#include "../../weaponExtender.h" #include enum class eBodyState {