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