Skip to content

Commit bdf3e3e

Browse files
authored
Allow to use peds and vehicles as a camera target (with fixes) (#1753)
1 parent ec1b27a commit bdf3e3e

File tree

10 files changed

+68
-34
lines changed

10 files changed

+68
-34
lines changed

Client/mods/deathmatch/logic/CClientCamera.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,15 @@ void CClientCamera::SetFocusToLocalPlayer()
412412
// Restore the camera
413413
SetFocusToLocalPlayerImpl();
414414

415+
Reset();
416+
}
417+
418+
void CClientCamera::Reset()
419+
{
415420
// Remove stream reference from the previous target
416421
if (m_pFocusedEntity && m_pFocusedEntity->IsStreamingCompatibleClass())
417422
static_cast<CClientStreamElement*>((CClientEntity*)m_pFocusedEntity)->RemoveStreamReference();
418423

419-
// Reset
420424
m_pFocusedPlayer = NULL;
421425
m_pFocusedEntity = NULL;
422426
m_pFocusedGameEntity = NULL;

Client/mods/deathmatch/logic/CClientCamera.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class CClientCamera final : public CClientEntity
6060
void SetFocus(CClientEntity* pEntity, eCamMode eMode, bool bSmoothTransition = false);
6161
void SetFocus(CClientPlayer* pPlayer, eCamMode eMode, bool bSmoothTransition = false);
6262
void SetFocusToLocalPlayer();
63+
void Reset();
6364

6465
void SetCameraVehicleViewMode(eVehicleCamMode eMode);
6566
void SetCameraPedViewMode(ePedCamMode eMode);

Client/mods/deathmatch/logic/CClientPed.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,9 +1460,6 @@ void CClientPed::WarpIntoVehicle(CClientVehicle* pVehicle, unsigned int uiSeat)
14601460
pGameVehicle->GetVehicleAudioEntity()->JustGotInVehicleAsDriver();
14611461
}
14621462

1463-
// Make sure our camera is fixed on the new vehicle
1464-
if (m_bIsLocalPlayer)
1465-
m_pManager->GetCamera()->SetTargetEntity(pVehicle);
14661463
}
14671464

14681465
// Update the vehicle and us so we know we've occupied it
@@ -1506,9 +1503,6 @@ void CClientPed::WarpIntoVehicle(CClientVehicle* pVehicle, unsigned int uiSeat)
15061503
pGameVehicle->GetVehicleAudioEntity()->JustGotInVehicleAsDriver();
15071504
}
15081505

1509-
// Make sure our camera is fixed on the new vehicle
1510-
if (m_bIsLocalPlayer)
1511-
m_pManager->GetCamera()->SetTargetEntity(pVehicle);
15121506
}
15131507
}
15141508

Client/mods/deathmatch/logic/CNetAPI.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,11 +1981,15 @@ void CNetAPI::WriteCameraSync(NetBitStreamInterface& BitStream)
19811981
{
19821982
// Write our target
19831983
ElementID ID = INVALID_ELEMENT_ID;
1984-
CClientPlayer* pPlayer = pCamera->GetFocusedPlayer();
1985-
if (!pPlayer)
1986-
pPlayer = g_pClientGame->GetLocalPlayer();
1987-
if (!pPlayer->IsLocalEntity())
1988-
ID = pPlayer->GetID();
1984+
CClientEntity* pTarget = pCamera->GetFocusedPlayer();
1985+
1986+
if (!pTarget)
1987+
pTarget = pCamera->GetTargetEntity();
1988+
1989+
if (!pTarget)
1990+
pTarget = g_pClientGame->GetLocalPlayer();
1991+
if (!pTarget->IsLocalEntity())
1992+
ID = pTarget->GetID();
19891993

19901994
BitStream.Write(ID);
19911995
}

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4806,9 +4806,14 @@ bool CStaticFunctionDefinitions::GetCameraMatrix(CVector& vecPosition, CVector&
48064806

48074807
CClientEntity* CStaticFunctionDefinitions::GetCameraTarget()
48084808
{
4809-
if (!m_pCamera->IsInFixedMode())
4810-
return m_pCamera->GetTargetEntity();
4811-
return NULL;
4809+
if (m_pCamera->IsInFixedMode())
4810+
return NULL;
4811+
4812+
CClientEntity* pPlayer = m_pCamera->GetFocusedPlayer();
4813+
if (pPlayer)
4814+
return pPlayer;
4815+
4816+
return m_pCamera->GetTargetEntity();
48124817
}
48134818

48144819
bool CStaticFunctionDefinitions::GetCameraInterior(unsigned char& ucInterior)
@@ -4842,9 +4847,6 @@ bool CStaticFunctionDefinitions::SetCameraTarget(CClientEntity* pEntity)
48424847
{
48434848
assert(pEntity);
48444849

4845-
// Save our current target for later
4846-
CClientEntity* pPreviousTarget = m_pCamera->GetTargetEntity();
4847-
48484850
switch (pEntity->GetType())
48494851
{
48504852
case CCLIENTPLAYER:
@@ -4864,6 +4866,15 @@ bool CStaticFunctionDefinitions::SetCameraTarget(CClientEntity* pEntity)
48644866
}
48654867
break;
48664868
}
4869+
case CCLIENTPED:
4870+
case CCLIENTVEHICLE:
4871+
{
4872+
// Reset camera focus and remove all references
4873+
m_pCamera->Reset();
4874+
// Put the focus on entity
4875+
m_pCamera->SetFocus(pEntity, MODE_CAM_ON_A_STRING, false);
4876+
break;
4877+
}
48674878
default:
48684879
return false;
48694880
}

Client/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "StdInc.h"
1414
#include <lua/CLuaFunctionParser.h>
1515

16+
#define MIN_CLIENT_REQ_SETCAMERATARGET_USE_ANY_ELEMENTS "1.5.8-9.20677"
17+
1618
void CLuaCameraDefs::LoadFunctions()
1719
{
1820
constexpr static const std::pair<const char*, lua_CFunction> functions[]{
@@ -330,6 +332,9 @@ int CLuaCameraDefs::SetCameraTarget(lua_State* luaVM)
330332
CClientEntity* pTarget;
331333
argStream.ReadUserData(pTarget);
332334

335+
if (pTarget->GetType() != CCLIENTPLAYER)
336+
MinClientReqCheck(argStream, MIN_CLIENT_REQ_SETCAMERATARGET_USE_ANY_ELEMENTS, "target is not a player");
337+
333338
if (!argStream.HasErrors())
334339
{
335340
if (CStaticFunctionDefinitions::SetCameraTarget(pTarget))

Client/mods/deathmatch/logic/rpc/CCameraRPCs.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ void CCameraRPCs::SetCameraTarget(NetBitStreamInterface& bitStream)
6363
CClientEntity* pEntity = CElementIDs::GetElement(targetID);
6464
if (pEntity)
6565
{
66-
// Save our current target for later
67-
CClientEntity* pPreviousTarget = m_pCamera->GetTargetEntity();
68-
6966
switch (pEntity->GetType())
7067
{
7168
case CCLIENTPLAYER:
@@ -83,6 +80,12 @@ void CCameraRPCs::SetCameraTarget(NetBitStreamInterface& bitStream)
8380
}
8481
break;
8582
}
83+
case CCLIENTPED:
84+
case CCLIENTVEHICLE:
85+
{
86+
m_pCamera->SetFocus(pEntity, MODE_CAM_ON_A_STRING, false);
87+
break;
88+
}
8689
default:
8790
return;
8891
}

Server/mods/deathmatch/logic/CGame.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3856,7 +3856,7 @@ void CGame::Packet_CameraSync(CCameraSyncPacket& Packet)
38563856
}
38573857
else
38583858
{
3859-
CPlayer* pTarget = GetElementFromId<CPlayer>(Packet.m_TargetID);
3859+
CElement* pTarget = GetElementFromId<CElement>(Packet.m_TargetID);
38603860
if (!pTarget)
38613861
pTarget = pPlayer;
38623862

Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4501,20 +4501,27 @@ bool CStaticFunctionDefinitions::SetCameraTarget(CElement* pElement, CElement* p
45014501
if (!pTarget)
45024502
pTarget = pPlayer;
45034503

4504-
// Make sure our target is a player element
4505-
if (pTarget->GetType() == CElement::PLAYER)
4504+
// Make sure our target is supported
4505+
switch (pTarget->GetType())
45064506
{
4507-
pCamera->SetMode(CAMERAMODE_PLAYER);
4508-
pCamera->SetTarget(pTarget);
4509-
pCamera->SetRoll(0.0f);
4510-
pCamera->SetFOV(70.0f);
4507+
case CElement::PLAYER:
4508+
case CElement::PED:
4509+
case CElement::VEHICLE:
4510+
{
4511+
pCamera->SetMode(CAMERAMODE_PLAYER);
4512+
pCamera->SetTarget(pTarget);
4513+
pCamera->SetRoll(0.0f);
4514+
pCamera->SetFOV(70.0f);
45114515

4512-
CBitStream BitStream;
4513-
if (pPlayer->GetBitStreamVersion() >= 0x5E)
4514-
BitStream.pBitStream->Write(pCamera->GenerateSyncTimeContext());
4515-
BitStream.pBitStream->Write(pTarget->GetID());
4516-
pPlayer->Send(CLuaPacket(SET_CAMERA_TARGET, *BitStream.pBitStream));
4517-
return true;
4516+
CBitStream BitStream;
4517+
if (pPlayer->GetBitStreamVersion() >= 0x5E)
4518+
BitStream.pBitStream->Write(pCamera->GenerateSyncTimeContext());
4519+
BitStream.pBitStream->Write(pTarget->GetID());
4520+
pPlayer->Send(CLuaPacket(SET_CAMERA_TARGET, *BitStream.pBitStream));
4521+
return true;
4522+
}
4523+
default:
4524+
return false;
45184525
}
45194526
}
45204527

Server/mods/deathmatch/logic/luadefs/CLuaCameraDefs.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#include "StdInc.h"
1313

14+
#define MIN_SERVER_REQ_SETCAMERATARGET_USE_ANY_ELEMENTS "1.5.8-9.20677"
15+
1416
void CLuaCameraDefs::LoadFunctions()
1517
{
1618
constexpr static const std::pair<const char*, lua_CFunction> functions[]{
@@ -193,6 +195,9 @@ int CLuaCameraDefs::setCameraTarget(lua_State* luaVM)
193195
argStream.ReadUserData(pPlayer);
194196
argStream.ReadUserData(pTarget, NULL);
195197

198+
if (pTarget && pTarget->GetType() != CElement::PLAYER)
199+
MinServerReqCheck(argStream, MIN_SERVER_REQ_SETCAMERATARGET_USE_ANY_ELEMENTS, "target is not a player");
200+
196201
if (!argStream.HasErrors())
197202
{
198203
if (CStaticFunctionDefinitions::SetCameraTarget(pPlayer, pTarget))

0 commit comments

Comments
 (0)