Skip to content

Commit 5415b1b

Browse files
Synchronize changes from 1.6 master branch [ci skip]
9ab6104 Fix invalid target and owner references in projectiles (#3879)
2 parents 342bd94 + 9ab6104 commit 5415b1b

File tree

6 files changed

+27
-1
lines changed

6 files changed

+27
-1
lines changed

Client/game_sa/CPlayerPedSA.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "CPlayerInfoSA.h"
1919
#include "CPlayerPedSA.h"
2020
#include "CWorldSA.h"
21+
#include "CProjectileInfoSA.h"
2122

2223
extern CCoreInterface* g_pCore;
2324
extern CGameSA* pGame;
@@ -137,6 +138,7 @@ CPlayerPedSA::~CPlayerPedSA()
137138
if ((DWORD)GetInterface()->vtbl != VTBL_CPlaceable)
138139
{
139140
CWorldSA* world = (CWorldSA*)pGame->GetWorld();
141+
pGame->GetProjectileInfo()->RemoveEntityReferences(this);
140142
world->Remove(m_pInterface, CPlayerPed_Destructor);
141143

142144
DWORD dwThis = (DWORD)m_pInterface;

Client/game_sa/CProjectileInfoSA.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,18 @@ DWORD CProjectileInfoSA::GetCounter()
180180
{
181181
return internalInterface->dwCounter - pGame->GetSystemTime();
182182
}
183+
184+
void CProjectileInfoSA::RemoveEntityReferences(CEntity* entity)
185+
{
186+
const CEntitySAInterface* entityInterface = entity->GetInterface();
187+
for (int i = 0; i < PROJECTILE_INFO_COUNT; i++)
188+
{
189+
auto projectileInterface = projectileInfo[i]->internalInterface;
190+
191+
if (projectileInterface->pEntProjectileOwner == entityInterface)
192+
projectileInterface->pEntProjectileOwner = nullptr;
193+
194+
if (projectileInterface->pEntProjectileTarget == entityInterface)
195+
projectileInterface->pEntProjectileTarget = nullptr;
196+
}
197+
}

Client/game_sa/CProjectileInfoSA.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class CProjectileInfoSAInterface
4242
};
4343
// #pragma pack(pop)
4444

45-
class CProjectileInfoSA : public CProjectileInfo
45+
// TODO extract manager class
46+
class CProjectileInfoSA final : public CProjectileInfo
4647
{
4748
private:
4849
CProjectileInfoSA* projectileInfo[PROJECTILE_INFO_COUNT];
@@ -65,6 +66,7 @@ class CProjectileInfoSA : public CProjectileInfo
6566
CProjectileInfo* GetProjectileInfo(DWORD dwIndex);
6667
bool AddProjectile(CEntity* creator, eWeaponType eWeapon, CVector vecOrigin, float fForce, CVector* target, CEntity* targetEntity);
6768
CProjectile* GetProjectile(void* projectilePointer);
69+
void RemoveEntityReferences(CEntity* entity);
6870

6971
CEntity* GetTarget();
7072
void SetTarget(CEntity* pEntity);

Client/game_sa/CVehicleSA.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ CVehicleSA::~CVehicleSA()
224224
}
225225

226226
CWorldSA* pWorld = (CWorldSA*)pGame->GetWorld();
227+
pGame->GetProjectileInfo()->RemoveEntityReferences(this);
227228
pWorld->Remove(m_pInterface, CVehicle_Destructor);
228229
pWorld->RemoveReferencesToDeletedObject(m_pInterface);
229230

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <game/Task.h>
3535
#include <game/CBuildingRemoval.h>
3636
#include "game/CClock.h"
37+
#include <game/CProjectileInfo.h>
3738
#include <windowsx.h>
3839
#include "CServerInfo.h"
3940

@@ -403,6 +404,10 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo())
403404
CClientGame::~CClientGame()
404405
{
405406
m_bBeingDeleted = true;
407+
// Remove active projectile references to local player
408+
if (auto pLocalPlayer = g_pClientGame->GetLocalPlayer())
409+
g_pGame->GetProjectileInfo()->RemoveEntityReferences(pLocalPlayer->GetGameEntity());
410+
406411
// Stop all explosions. Unfortunately this doesn't fix the crash
407412
// if a vehicle is destroyed while it explodes.
408413
g_pGame->GetExplosionManager()->RemoveAllExplosions();

Client/sdk/game/CProjectileInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class CProjectileInfo
2424
virtual CProjectileInfo* GetProjectileInfo(void* projectileInfoInterface) = 0; // don't use
2525
virtual void RemoveProjectile(CProjectileInfo* pProjectileInfo, CProjectile* pProjectile, bool bBlow = true) = 0;
2626
virtual CProjectileInfo* GetProjectileInfo(DWORD Index) = 0;
27+
virtual void RemoveEntityReferences(CEntity* entity) = 0;
2728

2829
virtual CEntity* GetTarget() = 0;
2930
virtual void SetTarget(CEntity* pEntity) = 0;

0 commit comments

Comments
 (0)