From ab55acb7a215ab08ec4aca66d07d776acf28381b Mon Sep 17 00:00:00 2001 From: DK22Pac Date: Fri, 17 Nov 2017 22:33:12 +0200 Subject: [PATCH] Fixed 0x679FA8 crash Improved Gunflashes module --- project_files/imfx.vcxproj | 12 +-- source/BloodSpots.cpp | 4 +- source/Explosions.cpp | 4 +- source/Gunflashes.cpp | 178 ++++++++++++++++++++----------------- source/Gunflashes.h | 22 +++-- source/imfx.cpp | 36 ++++---- source/imfx.h | 2 + 7 files changed, 145 insertions(+), 113 deletions(-) diff --git a/project_files/imfx.vcxproj b/project_files/imfx.vcxproj index d36ea97..b60f7da 100644 --- a/project_files/imfx.vcxproj +++ b/project_files/imfx.vcxproj @@ -85,7 +85,7 @@ .asi D:/Games/Grand Theft Auto - San Andreas/scripts/ - imfx_d + imfx ..\output\obj\$(Configuration)\ @@ -99,15 +99,15 @@ _USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions) - D:/Projects/plugin-sdk/output\lib\plugin_sa\Debug\;%(AdditionalLibraryDirectories) - plugin_d.lib;%(AdditionalDependencies) + D:/Projects/plugin-sdk/output\lib;%(AdditionalLibraryDirectories) + paths_d.lib;plugin_d.lib;%(AdditionalDependencies) Default Debug Windows ..\output\obj\Debug\DEBUG.def - ..\custom_build\gendef\gendef.pl ..\output\obj\Debug Win32 + ..\custom_build\gendef\gendef.pl D:\Projects\imfx\output\obj\Debug Win32 Generating .def file (gendef) @@ -131,8 +131,8 @@ true false UseLinkTimeCodeGeneration - D:/Projects/plugin-sdk/output\lib\plugin_sa\Release\;%(AdditionalLibraryDirectories) - plugin.lib;%(AdditionalDependencies) + D:/Projects/plugin-sdk/output\lib;%(AdditionalLibraryDirectories) + paths_d.lib;plugin.lib;%(AdditionalDependencies) Windows ..\output\obj\Release\RELEASE.def diff --git a/source/BloodSpots.cpp b/source/BloodSpots.cpp index f0ffa33..048e473 100644 --- a/source/BloodSpots.cpp +++ b/source/BloodSpots.cpp @@ -45,7 +45,7 @@ void BloodSpots::Setup() { patch::SetPointer(0x630E32, m_pBloodPool); patch::SetPointer(0x630E74, m_pBloodPool); patch::SetPointer(0x679ED0, m_pBloodPool); - patch::SetPointer(0x679FAA, m_pBloodPool); + patch::SetPointer(0x679FA9, m_pBloodPool); patch::SetPointer(0x707B0B, m_pBloodPool); } @@ -96,7 +96,7 @@ void BloodSpots::DoFootStepShadow(unsigned char type, RwTexture* texture, CVecto if (m_pPedForFootStep) { unsigned int texNum = m_bLeftFootStep ? 0 : 1; if (m_pPedForFootStep->m_wModelIndex == MODEL_NULL && m_pPedForFootStep->m_pPlayerData) { - unsigned int key = m_pPedForFootStep->m_pPlayerData->m_pClothes->m_adwTextureKeys[3]; + unsigned int key = m_pPedForFootStep->m_pPlayerData->m_pPedClothesDesc->m_adwTextureKeys[3]; if (!key || key == CKeyGen::GetUppercaseKey("FOOT")) myTexture = m_pBloodFootStep4[texNum]; else if(key == CKeyGen::GetUppercaseKey("SANDAL") || key == CKeyGen::GetUppercaseKey("SANDALSOCK")) diff --git a/source/Explosions.cpp b/source/Explosions.cpp index 7be52ba..b4bc414 100644 --- a/source/Explosions.cpp +++ b/source/Explosions.cpp @@ -55,8 +55,8 @@ FxSystem_c *__fastcall Explosions::MyCreateExplosionFx(CExplosion *explosion, in else if (bDetonatorExplosion && ExplosionFxNames[IMFX_EXPLOSION_DETONATOR][0]) { return g_fxMan.CreateFxSystem(ExplosionFxNames[IMFX_EXPLOSION_DETONATOR], point, mat, flag); } - else if (explosion->m_Type < IMFX_NUM_DEFAULT_EXPLOSION_TYPES && ExplosionFxNames[explosion->m_Type][0]) { - return g_fxMan.CreateFxSystem(ExplosionFxNames[explosion->m_Type], point, mat, flag); + else if (explosion->m_nType < IMFX_NUM_DEFAULT_EXPLOSION_TYPES && ExplosionFxNames[explosion->m_nType][0]) { + return g_fxMan.CreateFxSystem(ExplosionFxNames[explosion->m_nType], point, mat, flag); } return g_fxMan.CreateFxSystem(name, point, mat, flag); } \ No newline at end of file diff --git a/source/Gunflashes.cpp b/source/Gunflashes.cpp index 3937ba2..709ced9 100644 --- a/source/Gunflashes.cpp +++ b/source/Gunflashes.cpp @@ -12,31 +12,34 @@ using namespace plugin; +RwMatrix Gunflashes::matrixAry[20]; +unsigned int Gunflashes::matrixCounter = 0; +PedExtendedData Gunflashes::pedExt; std::vector Gunflashes::gunflashInfos; -RwMatrix Gunflashes::mLocalParticleMatrix; -bool Gunflashes::bLocalParticleMatrixCopied = false; -bool Gunflashes::bLeftHand; +bool Gunflashes::bLeftHand = false; +bool Gunflashes::bVehicleGunflash = false; + +Gunflashes::PedExtension::PedExtension(CPed *) { + Reset(); +} + +void Gunflashes::PedExtension::Reset() { + bLeftHandGunflashThisFrame = false; + bRightHandGunflashThisFrame = false; + bInVehicle = false; +} void Gunflashes::Setup() { patch::Nop(0x73306D, 9); // Remove default gunflashes patch::Nop(0x7330FF, 9); // Remove default gunflashes patch::SetUShort(0x5DF425, 0xE990); // Remove default gunflashes patch::SetUChar(0x741353, 0); // Add gunflash for cuntgun - if (!IMFX::bSampGame) { - patch::SetUShort(0x53C1F0, 0xC483); // add esp, 8 - patch::SetUChar(0x53C1F2, 8); - patch::Nop(0x53C1F3, 2); - patch::RedirectCall(0x742299, DoDriveByGunflash); - } + patch::RedirectCall(0x742299, DoDriveByGunflash); patch::RedirectJump(0x4A0DE0, MyTriggerGunflash); patch::SetPointer(0x86D744, MyProcessUseGunTask); ReadSettings(); } -void Gunflashes::UpdateAfterPreRender() { - g_fx.Update(TheCamera.m_pRwCamera, CTimer::ms_fTimeStep * 0.02f); -} - void Gunflashes::ReadSettings() { std::ifstream settingsFile(PLUGIN_PATH("imfx\\gunflash.dat")); if (settingsFile.is_open()) { @@ -54,8 +57,17 @@ void Gunflashes::ReadSettings() { } } +void Gunflashes::ProcessPerFrame() { + matrixCounter = 0; + for (int i = 0; i < CPools::ms_pPedPool->m_nSize; i++) { + CPed *ped = CPools::ms_pPedPool->GetAt(i); + if (ped) + pedExt.Get(ped).Reset(); + } +} + bool __fastcall Gunflashes::MyProcessUseGunTask(CTaskSimpleUseGun *task, int, CPed *ped) { - if (task->m_pWeaponInfo == CWeaponInfo::GetWeaponInfo(ped->m_aWeapons[ped->m_nActiveWeaponSlot].m_Type, ped->GetWeaponSkill())) { + if (task->m_pWeaponInfo == CWeaponInfo::GetWeaponInfo(ped->m_aWeapons[ped->m_nActiveWeaponSlot].m_nType, ped->GetWeaponSkill())) { if (task->m_nFlags.bRightHand) { bLeftHand = false; CallMethod<0x61EB10>(task, ped, false); @@ -70,89 +82,93 @@ bool __fastcall Gunflashes::MyProcessUseGunTask(CTaskSimpleUseGun *task, int, CP return 0; } -void Gunflashes::GetMatrixForLocalParticleBefore(FxPrimBP_c *primBP, RwMatrix *out) { - if (primBP->m_apTextures[0] && !_strnicmp(primBP->m_apTextures[0]->name, "gunflash", 7)) { - memcpy(&mLocalParticleMatrix, out, sizeof(RwMatrix)); - mLocalParticleMatrix.pos.x = 0.0f; - mLocalParticleMatrix.pos.y = 0.0f; - mLocalParticleMatrix.pos.z = 0.0f; - bLocalParticleMatrixCopied = true; - } - else - bLocalParticleMatrixCopied = false; -} - -void Gunflashes::GetMatrixForLocalParticleAfter(FxPrimBP_c *primBP, RwMatrix *out) { - if (bLocalParticleMatrixCopied) - memcpy(out, &mLocalParticleMatrix, sizeof(RwMatrix)); -} - void __fastcall Gunflashes::DoDriveByGunflash(CPed *driver, int, int, bool leftHand) { bLeftHand = leftHand; + bVehicleGunflash = true; MyTriggerGunflash(&g_fx, 0, driver, CVector(0.0f, 0.0f, 0.0f), CVector(0.0f, 0.0f, 0.0f), true); } void __fastcall Gunflashes::MyTriggerGunflash(Fx_c *fx, int, CEntity *entity, CVector &origin, CVector &target, bool doGunflash) { - RwMatrix *mat = g_fxMan.FxRwMatrixCreate(); - if (mat) { - if (entity && entity->m_nType == ENTITY_TYPE_PED && entity->m_pRwObject && entity->m_pRwObject->type == rpCLUMP) { - CPed *owner = reinterpret_cast(entity); - bool rotate = false; - bool smoke = false; - char *fxName = "gunflash"; - for (GunflashInfo &info : gunflashInfos) { - if (info.weapId == owner->m_aWeapons[owner->m_nActiveWeaponSlot].m_Type) { - rotate = info.rotate; - smoke = info.smoke; - fxName = info.fxName; - break; - } - } - char weapSkill = owner->GetWeaponSkill(owner->m_aWeapons[owner->m_nActiveWeaponSlot].m_Type); - CWeaponInfo *weapInfo = CWeaponInfo::GetWeaponInfo(owner->m_aWeapons[owner->m_nActiveWeaponSlot].m_Type, weapSkill); - RwV3d offset = weapInfo->m_vecFireOffset.ToRwV3d(); - if (bLeftHand) - offset.z *= -1.0f; - static RwV3d axis_y = { 0.0f, 1.0f, 0.0f }; - static RwV3d axis_z = { 0.0f, 0.0f, 1.0f }; - RpHAnimHierarchy *hierarchy = GetAnimHierarchyFromSkinClump(owner->m_pRwClump); - RwMatrix *boneMat = &RpHAnimHierarchyGetMatrixArray(hierarchy)[RpHAnimIDGetIndex(hierarchy, 24 + 10 * bLeftHand)]; - FxSystem_c *gunflashFx = g_fxMan.CreateFxSystem(fxName, &offset, boneMat, true); + if (entity && entity->m_nType == ENTITY_TYPE_PED) { + CPed *owner = reinterpret_cast(entity); + pedExt.Get(owner).bLeftHandGunflashThisFrame = bLeftHand; + pedExt.Get(owner).bRightHandGunflashThisFrame = !bLeftHand; + pedExt.Get(owner).bInVehicle = bVehicleGunflash; + } + else { + if (DistanceBetweenPoints(target, origin) > 0.0f) { + RwMatrix fxMat; + fx->CreateMatFromVec(&fxMat, &origin, &target); + RwV3d offset = { 0.0f, 0.0f, 0.0f }; + FxSystem_c *gunflashFx = g_fxMan.CreateFxSystem("gunflash", &offset, &fxMat, false); if (gunflashFx) { - RwMatrixRotate(&gunflashFx->m_localMatrix, &axis_z, -90.0f, rwCOMBINEPRECONCAT); - if (rotate) { - RwMatrixRotate(&gunflashFx->m_localMatrix, &axis_y, CGeneral::GetRandomNumberInRange(0.0f, 360.0f), rwCOMBINEPRECONCAT); - } - if(!IMFX::bSampGame) - gunflashFx->SetLocalParticles(true); + gunflashFx->CopyParentMatrix(); gunflashFx->PlayAndKill(); } - if (smoke) { - FxSystem_c *smokeFx = g_fxMan.CreateFxSystem("gunsmoke", &offset, boneMat, true); - if (smokeFx) { - RwMatrixRotate(&smokeFx->m_localMatrix, &axis_z, -90.0f, rwCOMBINEPRECONCAT); - smokeFx->PlayAndKill(); - } + FxSystem_c *smokeFx = g_fxMan.CreateFxSystem("gunsmoke", &offset, &fxMat, false); + if (smokeFx) { + smokeFx->CopyParentMatrix(); + smokeFx->PlayAndKill(); } } - else { - if (DistanceBetweenPoints(target, origin) > 0.0f) { - RwMatrix fxMat; - fx->CreateMatFromVec(&fxMat, &origin, &target); - RwV3d offset = { 0.0f, 0.0f, 0.0f }; - FxSystem_c *gunflashFx = g_fxMan.CreateFxSystem("gunflash", &offset, &fxMat, false); + } + bLeftHand = false; + bVehicleGunflash = false; +} + +void Gunflashes::CreateGunflashEffectsForPed(CPed *ped) { + bool ary[2]; + ary[0] = pedExt.Get(ped).bLeftHandGunflashThisFrame; + ary[1] = pedExt.Get(ped).bRightHandGunflashThisFrame; + bool inVehicle = pedExt.Get(ped).bInVehicle; + for (int i = 0; i < 2; i++) { + if (ary[i]) { + RwMatrix *mat = nullptr; + if (matrixCounter < 20 && !inVehicle) + mat = &matrixAry[matrixCounter++]; + bool leftHand = i == 0; + if (ped->m_pRwObject && ped->m_pRwObject->type == rpCLUMP) { + bool rotate = false; + bool smoke = false; + char *fxName = "gunflash"; + for (GunflashInfo &info : gunflashInfos) { + if (info.weapId == ped->m_aWeapons[ped->m_nActiveWeaponSlot].m_nType) { + rotate = info.rotate; + smoke = info.smoke; + fxName = info.fxName; + break; + } + } + char weapSkill = ped->GetWeaponSkill(ped->m_aWeapons[ped->m_nActiveWeaponSlot].m_nType); + CWeaponInfo *weapInfo = CWeaponInfo::GetWeaponInfo(ped->m_aWeapons[ped->m_nActiveWeaponSlot].m_nType, weapSkill); + RwV3d offset = weapInfo->m_vecFireOffset.ToRwV3d(); + if (leftHand) + offset.z *= -1.0f; + static RwV3d axis_y = { 0.0f, 1.0f, 0.0f }; + static RwV3d axis_z = { 0.0f, 0.0f, 1.0f }; + RpHAnimHierarchy *hierarchy = GetAnimHierarchyFromSkinClump(ped->m_pRwClump); + RwMatrix *boneMat = &RpHAnimHierarchyGetMatrixArray(hierarchy)[RpHAnimIDGetIndex(hierarchy, 24 + 10 * leftHand)]; + if (!mat) + mat = boneMat; + else + memcpy(mat, boneMat, sizeof(RwMatrix)); + FxSystem_c *gunflashFx = g_fxMan.CreateFxSystem(fxName, &offset, mat, true); if (gunflashFx) { - gunflashFx->CopyParentMatrix(); + RwMatrixRotate(&gunflashFx->m_localMatrix, &axis_z, -90.0f, rwCOMBINEPRECONCAT); + if (rotate) { + RwMatrixRotate(&gunflashFx->m_localMatrix, &axis_y, CGeneral::GetRandomNumberInRange(0.0f, 360.0f), rwCOMBINEPRECONCAT); + } gunflashFx->PlayAndKill(); } - FxSystem_c *smokeFx = g_fxMan.CreateFxSystem("gunsmoke", &offset, &fxMat, false); - if (smokeFx) { - smokeFx->CopyParentMatrix(); - smokeFx->PlayAndKill(); + if (smoke) { + FxSystem_c *smokeFx = g_fxMan.CreateFxSystem("gunsmoke", &offset, mat, true); + if (smokeFx) { + RwMatrixRotate(&smokeFx->m_localMatrix, &axis_z, -90.0f, rwCOMBINEPRECONCAT); + smokeFx->PlayAndKill(); + } } } } - g_fxMan.FxRwMatrixDestroy(mat); } - bLeftHand = false; + pedExt.Get(ped).Reset(); } \ No newline at end of file diff --git a/source/Gunflashes.h b/source/Gunflashes.h index 1999bea..fa090cf 100644 --- a/source/Gunflashes.h +++ b/source/Gunflashes.h @@ -1,4 +1,5 @@ #pragma once +#include "plugin.h" #include "game_sa\Fx_c.h" #include "game_sa\CPed.h" #include "game_sa\CTaskSimpleUseGun.h" @@ -14,17 +15,28 @@ struct GunflashInfo { class Gunflashes { public: + class PedExtension { + public: + bool bLeftHandGunflashThisFrame; + bool bRightHandGunflashThisFrame; + bool bInVehicle; + + PedExtension(CPed *); + void Reset(); + }; + + static RwMatrix matrixAry[20]; + static unsigned int matrixCounter; + static plugin::PedExtendedData pedExt; static std::vector gunflashInfos; - static RwMatrix mLocalParticleMatrix; - static bool bLocalParticleMatrixCopied; static bool bLeftHand; + static bool bVehicleGunflash; static void Setup(); static void ReadSettings(); - static void UpdateAfterPreRender(); static void __fastcall MyTriggerGunflash(Fx_c *fx, int, CEntity *owner, CVector &origin, CVector &target, bool doGunflash); static void __fastcall DoDriveByGunflash(CPed *driver, int, int, bool leftHand); - static void GetMatrixForLocalParticleBefore(FxPrimBP_c *primBP, RwMatrix *out); - static void GetMatrixForLocalParticleAfter(FxPrimBP_c *primBP, RwMatrix *out); static bool __fastcall MyProcessUseGunTask(CTaskSimpleUseGun *task, int, CPed *ped); + static void ProcessPerFrame(); + static void CreateGunflashEffectsForPed(CPed *ped); }; \ No newline at end of file diff --git a/source/imfx.cpp b/source/imfx.cpp index 8b8a413..f730d5a 100644 --- a/source/imfx.cpp +++ b/source/imfx.cpp @@ -29,8 +29,6 @@ IMFX::IMFX() { static CdeclEvent, PRIORITY_BEFORE, ArgPickNone, void()> imfxSpecialFxInit; static CdeclEvent, PRIORITY_BEFORE, ArgPickNone, void()> imfxSpecialFxUpdate; static CdeclEvent, PRIORITY_BEFORE, ArgPickNone, void()> imfxSpecialFxRender; - static CdeclEvent, PRIORITY_BEFORE, ArgPickNone, void()> imfxAfterPreRender; - static ThiscallEvent, PRIORITY_BEFORE, ArgPick2N, void(FxPrimBP_c*, RwMatrix*)> imfxGetLocalParticleMatrix; static ThiscallEvent, PRIORITY_AFTER, ArgPick2N, void(CPed*, int, int)> imfxRemovePedHeadEvent; if (settings.bEnableDebugConsole) { @@ -42,12 +40,7 @@ IMFX::IMFX() { } Events::initRwEvent += [] { - - bSampGame = GetModuleHandle("samp.dll") != NULL; - - if(bSampGame) - gConsole.AddMessage("SAMP game detected"); - + bSampGame = IsPluginInstalled("samp.dll"); settings.Read(); if (settings.bEnableHeadshot) { imfxRemovePedHeadEvent += Headshot::DoHeadshot; @@ -55,7 +48,6 @@ IMFX::IMFX() { if (settings.bEnableMoonphases) { Moonphases::Setup(); Events::shutdownRwEvent += Moonphases::Shutdown; - imfxIdleEvent += Moonphases::ProcessPerFrame; } if (settings.bEnableProportionalCoronas) { ProportionalCoronas::Setup(); @@ -63,7 +55,6 @@ IMFX::IMFX() { if (settings.bEnableWaterDrops) { WaterDrops::Setup(); Events::shutdownRwEvent += WaterDrops::Shutdown; - imfxIdleEvent += WaterDrops::ProcessPerFrame; imfxSpecialFxInit += WaterDrops::Clear; imfxSpecialFxUpdate += WaterDrops::Update; imfxSpecialFxRender += WaterDrops::Render; @@ -71,15 +62,9 @@ IMFX::IMFX() { if (settings.bEnableLensflare) { Lensflare::Setup(); Events::shutdownRwEvent += Lensflare::Shutdown; - imfxIdleEvent += Lensflare::ProcessPerFrame; } if (settings.bEnableGunflashes) { Gunflashes::Setup(); - if (!bSampGame) { - imfxAfterPreRender += Gunflashes::UpdateAfterPreRender; - imfxGetLocalParticleMatrix.before += Gunflashes::GetMatrixForLocalParticleBefore; - imfxGetLocalParticleMatrix.after += Gunflashes::GetMatrixForLocalParticleAfter; - } } if (settings.bEnableExplosions) { Explosions::Setup(); @@ -91,7 +76,24 @@ IMFX::IMFX() { if (settings.bEnableRoadsign) { Roadsign::Setup(); Events::shutdownRwEvent += Roadsign::Shutdown; - imfxIdleEvent += Roadsign::ProcessPerFrame; } + + if (settings.bEnableGunflashes) + Events::pedRenderEvent.after += Gunflashes::CreateGunflashEffectsForPed; + + imfxIdleEvent += ProcessPerFrame; }; +} + +void IMFX::ProcessPerFrame() { + if (settings.bEnableMoonphases) + Moonphases::ProcessPerFrame(); + if (settings.bEnableWaterDrops) + WaterDrops::ProcessPerFrame(); + if (settings.bEnableLensflare) + Lensflare::ProcessPerFrame(); + if (settings.bEnableRoadsign) + Roadsign::ProcessPerFrame(); + if (settings.bEnableGunflashes) + Gunflashes::ProcessPerFrame(); } \ No newline at end of file diff --git a/source/imfx.h b/source/imfx.h index a14c47e..96136fe 100644 --- a/source/imfx.h +++ b/source/imfx.h @@ -6,4 +6,6 @@ class IMFX { static bool bSampGame; IMFX(); + + static void ProcessPerFrame(); }; \ No newline at end of file