Skip to content

Commit 93067d4

Browse files
Synchronize changes from 1.6 master branch [ci skip]
9f54cfc Add new function spawnVehicleFlyingComponent (#3592)
2 parents 1bd850f + 9f54cfc commit 93067d4

22 files changed

+442
-81
lines changed

Client/game_sa/CAutomobileSA.h

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,6 @@
2121
#define MAX_PASSENGER_COUNT 8
2222
#define MAX_DOORS 6 // also in CDamageManager
2323

24-
namespace eCarNode
25-
{
26-
enum
27-
{
28-
NONE = 0,
29-
CHASSIS = 1,
30-
WHEEL_RF = 2,
31-
WHEEL_RM = 3,
32-
WHEEL_RB = 4,
33-
WHEEL_LF = 5,
34-
WHEEL_LM = 6,
35-
WHEEL_LB = 7,
36-
DOOR_RF = 8,
37-
DOOR_RR = 9,
38-
DOOR_LF = 10,
39-
DOOR_LR = 11,
40-
BUMP_FRONT = 12,
41-
BUMP_REAR = 13,
42-
WING_RF = 14,
43-
WING_LF = 15,
44-
BONNET = 16,
45-
BOOT = 17,
46-
WINDSCREEN = 18,
47-
EXHAUST = 19,
48-
MISC_A = 20,
49-
MISC_B = 21,
50-
MISC_C = 22,
51-
MISC_D = 23,
52-
MISC_E = 24,
53-
NUM_NODES
54-
};
55-
};
56-
5724
class CBouncingPanelSAInterface
5825
{
5926
public:
@@ -70,7 +37,7 @@ class CAutomobileSAInterface : public CVehicleSAInterface
7037
public:
7138
CDamageManagerSAInterface m_damageManager;
7239
CDoorSAInterface m_doors[MAX_DOORS];
73-
RwFrame* m_aCarNodes[eCarNode::NUM_NODES];
40+
RwFrame* m_aCarNodes[static_cast<std::size_t>(eCarNodes::NUM_NODES)];
7441
CBouncingPanelSAInterface m_panels[3];
7542
CDoorSAInterface m_swingingChassis;
7643
CColPointSAInterface m_wheelColPoint[MAX_WHEELS];

Client/game_sa/CBikeSA.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@
1414
#include <game/CBike.h>
1515
#include "CVehicleSA.h"
1616

17+
enum class eBikeNodes
18+
{
19+
NONE = 0,
20+
CHASSIS,
21+
FORKS_FRONT,
22+
FORKS_REAR,
23+
WHEEL_FRONT,
24+
WHEEL_REAR,
25+
MUDGUARD,
26+
HANDLEBARS,
27+
MISC_A,
28+
MISC_B,
29+
30+
NUM_NODES
31+
};
32+
1733
struct sRideAnimData
1834
{
1935
int32 iAnimGroup;
@@ -29,7 +45,7 @@ static_assert(sizeof(sRideAnimData) == 0x1C, "Invalid size for sRideAnimData");
2945
class CBikeSAInterface : public CVehicleSAInterface
3046
{
3147
public:
32-
int32 m_apModelNodes[10];
48+
RwFrame* m_apModelNodes[static_cast<std::size_t>(eBikeNodes::NUM_NODES)];
3349
int8 m_bLeanMatrixCalculated;
3450
int8 pad0[3]; // Maybe prev value is int32
3551
int8 m_mLeanMatrix[72];

Client/game_sa/CBmxSA.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@
1414
#include <game/CBmx.h>
1515
#include "CBikeSA.h"
1616

17+
enum class eBmxNodes
18+
{
19+
NONE = 0,
20+
CHASSIS,
21+
FORKS_FRONT,
22+
FORKS_REAR,
23+
WHEEL_FRONT,
24+
WHEEL_REAR,
25+
HANDLEBARS,
26+
CHAINSET,
27+
PEDAL_R,
28+
PEDAL_L,
29+
30+
NUM_NODES
31+
};
32+
1733
class CBmxSAInterface : public CBikeSAInterface
1834
{
1935
// fill this

Client/game_sa/CBoatSA.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,30 @@
1414
#include <game/CBoat.h>
1515
#include "CVehicleSA.h"
1616

17+
enum class eBoatNodes
18+
{
19+
NONE = 0,
20+
MOVING,
21+
WINDSCREEN,
22+
RUDDER,
23+
FLAP_LEFT,
24+
FLAP_RIGHT,
25+
REARFLAP_LEFT,
26+
REARFLAP_RIGHT,
27+
STATIC_PROP,
28+
MOVING_PROP,
29+
STATIC_PROP2,
30+
MOVING_PROP2,
31+
32+
NUM_NODES
33+
};
34+
1735
class CBoatSAInterface : public CVehicleSAInterface
1836
{
1937
public:
2038
uint32 pad1[3]; // 1440
2139
uint32 BoatFlags; // 1452
22-
RwFrame* pBoatParts[11]; // 1456 [[ find out correct size
40+
RwFrame* pBoatParts[static_cast<std::size_t>(eBoatNodes::NUM_NODES)]; // 1456
2341
uint32 pad2[3]; // 1500
2442
uint16 pad3; // 1512
2543
uint8 pad4[2]; // 1514

Client/game_sa/CTrainSA.h

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,27 @@
1414
#include "CVehicleSA.h"
1515
#include "CDoorSA.h"
1616

17-
namespace eTrainNode
17+
enum class eTrainNodes
1818
{
19-
enum
20-
{
21-
NONE = 0,
22-
DOOR_LF = 1,
23-
DOOR_RF = 2,
24-
WHEEL_RF1 = 3,
25-
WHEEL_RF2 = 4,
26-
WHEEL_RF3 = 5,
27-
WHEEL_RB1 = 6,
28-
WHEEL_RB2 = 7,
29-
WHEEL_RB3 = 8,
30-
WHEEL_LF1 = 9,
31-
WHEEL_LF2 = 10,
32-
WHEEL_LF3 = 11,
33-
WHEEL_LB1 = 12,
34-
WHEEL_LB2 = 13,
35-
WHEEL_LB3 = 14,
36-
BOGIE_FRONT = 15,
37-
BOGIE_REAR = 16,
38-
NUM_NODES
39-
};
19+
NONE = 0,
20+
DOOR_LF,
21+
DOOR_RF,
22+
WHEEL_RF1,
23+
WHEEL_RF2,
24+
WHEEL_RF3,
25+
WHEEL_RB1,
26+
WHEEL_RB2,
27+
WHEEL_RB3,
28+
WHEEL_LF1,
29+
WHEEL_LF2,
30+
WHEEL_LF3,
31+
WHEEL_LB1,
32+
WHEEL_LB2,
33+
WHEEL_LB3,
34+
BOGIE_FRONT,
35+
BOGIE_REAR,
36+
37+
NUM_NODES
4038
};
4139

4240
enum class eTrainPassengersGenerationState : unsigned char
@@ -101,7 +99,7 @@ class CTrainSAInterface : public CVehicleSAInterface
10199
CTrainSAInterface* m_prevCarriage;
102100
CTrainSAInterface* m_nextCarriage;
103101
CDoorSAInterface m_aDoors[MAX_DOORS];
104-
RwFrame* m_aTrainNodes[eTrainNode::NUM_NODES];
102+
RwFrame* m_aTrainNodes[static_cast<std::size_t>(eTrainNodes::NUM_NODES)];
105103
};
106104
static_assert(sizeof(CTrainSAInterface) == 0x6AC, "Invalid size for CTrainSAInterface");
107105

Client/game_sa/CVehicleSA.cpp

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "CTrainSA.h"
2222
#include "CPlaneSA.h"
2323
#include "CVehicleSA.h"
24+
#include "CBoatSA.h"
2425
#include "CVisibilityPluginsSA.h"
2526
#include "CWorldSA.h"
2627
#include "gamesa_renderware.h"
@@ -1504,27 +1505,97 @@ void CVehicleSA::SetGravity(const CVector* pvecGravity)
15041505
m_vecGravity = *pvecGravity;
15051506
}
15061507

1507-
CObject* CVehicleSA::SpawnFlyingComponent(int i_1, unsigned int ui_2)
1508+
bool CVehicleSA::SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime)
15081509
{
1509-
DWORD dwReturn;
1510-
DWORD dwThis = (DWORD)GetInterface();
1511-
DWORD dwFunc = FUNC_CAutomobile__SpawnFlyingComponent;
1512-
_asm
1510+
if (nodeIndex == eCarNodes::NONE)
1511+
return false;
1512+
1513+
DWORD nodesOffset = OFFSET_CAutomobile_Nodes;
1514+
RwFrame* defaultBikeChassisFrame = nullptr;
1515+
1516+
// CBike, CBmx, CBoat and CTrain don't inherit CAutomobile so let's do it manually!
1517+
switch (static_cast<VehicleClass>(GetVehicleInterface()->m_vehicleClass))
15131518
{
1514-
mov ecx, dwThis
1515-
push ui_2
1516-
push i_1
1517-
call dwFunc
1518-
mov dwReturn, eax
1519+
case VehicleClass::AUTOMOBILE:
1520+
case VehicleClass::MONSTER_TRUCK:
1521+
case VehicleClass::PLANE:
1522+
case VehicleClass::HELI:
1523+
case VehicleClass::TRAILER:
1524+
case VehicleClass::QUAD:
1525+
{
1526+
nodesOffset = OFFSET_CAutomobile_Nodes;
1527+
break;
1528+
}
1529+
case VehicleClass::TRAIN:
1530+
{
1531+
if (static_cast<eTrainNodes>(nodeIndex) >= eTrainNodes::NUM_NODES)
1532+
return false;
1533+
1534+
nodesOffset = OFFSET_CTrain_Nodes;
1535+
break;
1536+
}
1537+
case VehicleClass::BIKE:
1538+
case VehicleClass::BMX:
1539+
{
1540+
auto* bikeInterface = static_cast<CBikeSAInterface*>(GetVehicleInterface());
1541+
if (!bikeInterface)
1542+
return false;
1543+
1544+
if (static_cast<eBikeNodes>(nodeIndex) >= eBikeNodes::NUM_NODES)
1545+
return false;
1546+
1547+
nodesOffset = OFFSET_CBike_Nodes;
1548+
if (static_cast<eBikeNodes>(nodeIndex) != eBikeNodes::CHASSIS)
1549+
break;
1550+
1551+
// Set the correct "bike_chassis" frame for bikes
1552+
defaultBikeChassisFrame = bikeInterface->m_apModelNodes[1];
1553+
if (defaultBikeChassisFrame && std::strcmp(defaultBikeChassisFrame->szName, "chassis_dummy") == 0)
1554+
{
1555+
RwFrame* correctChassisFrame = RwFrameFindFrame(RpGetFrame(bikeInterface->m_pRwObject), "chassis");
1556+
if (correctChassisFrame)
1557+
bikeInterface->m_apModelNodes[1] = correctChassisFrame;
1558+
}
1559+
break;
1560+
}
1561+
case VehicleClass::BOAT:
1562+
{
1563+
if (static_cast<eBoatNodes>(nodeIndex) >= eBoatNodes::NUM_NODES)
1564+
return false;
1565+
1566+
nodesOffset = OFFSET_CBoat_Nodes;
1567+
break;
1568+
}
1569+
default:
1570+
return false;
15191571
}
15201572

1521-
CObject* pObject = NULL;
1522-
if (dwReturn)
1573+
// Patch nodes array in CAutomobile::SpawnFlyingComponent
1574+
MemPut(0x6A85B3, nodesOffset);
1575+
MemPut(0x6A8631, nodesOffset);
1576+
1577+
auto* componentObject = ((CObjectSAInterface * (__thiscall*)(CVehicleSAInterface*, int, int)) FUNC_CAutomobile__SpawnFlyingComponent)(GetVehicleInterface(), static_cast<int>(nodeIndex), static_cast<int>(collisionType));
1578+
1579+
// Restore default nodes array in CAutomobile::SpawnFlyingComponent
1580+
// CAutomobile::m_aCarNodes offset
1581+
MemPut(0x6A85B3, 0x648);
1582+
MemPut(0x6A8631, 0x648);
1583+
1584+
// Restore default chassis frame for bikes
1585+
if (static_cast<eBikeNodes>(nodeIndex) == eBikeNodes::CHASSIS && defaultBikeChassisFrame)
15231586
{
1524-
SClientEntity<CObjectSA>* pObjectClientEntity = pGame->GetPools()->GetObject((DWORD*)dwReturn);
1525-
pObject = pObjectClientEntity ? pObjectClientEntity->pEntity : nullptr;
1587+
auto* bikeInterface = static_cast<CBikeSAInterface*>(GetVehicleInterface());
1588+
if (bikeInterface && bikeInterface->m_apModelNodes)
1589+
bikeInterface->m_apModelNodes[1] = defaultBikeChassisFrame;
15261590
}
1527-
return pObject;
1591+
1592+
if (removalTime <= -1 || !componentObject)
1593+
return true;
1594+
1595+
std::uint32_t CTimer_ms = *reinterpret_cast<std::uint32_t*>(VAR_CTimer_snTimeInMilliseconds);
1596+
componentObject->uiObjectRemovalTime = CTimer_ms + static_cast<std::uint32_t>(removalTime);
1597+
1598+
return true;
15281599
}
15291600

15301601
void CVehicleSA::SetWheelVisibility(eWheelPosition wheel, bool bVisible)
@@ -1534,16 +1605,16 @@ void CVehicleSA::SetWheelVisibility(eWheelPosition wheel, bool bVisible)
15341605
switch (wheel)
15351606
{
15361607
case FRONT_LEFT_WHEEL:
1537-
pFrame = vehicle->m_aCarNodes[eCarNode::WHEEL_LF];
1608+
pFrame = vehicle->m_aCarNodes[static_cast<std::size_t>(eCarNodes::WHEEL_LF)];
15381609
break;
15391610
case REAR_LEFT_WHEEL:
1540-
pFrame = vehicle->m_aCarNodes[eCarNode::WHEEL_LB];
1611+
pFrame = vehicle->m_aCarNodes[static_cast<std::size_t>(eCarNodes::WHEEL_LB)];
15411612
break;
15421613
case FRONT_RIGHT_WHEEL:
1543-
pFrame = vehicle->m_aCarNodes[eCarNode::WHEEL_RF];
1614+
pFrame = vehicle->m_aCarNodes[static_cast<std::size_t>(eCarNodes::WHEEL_RF)];
15441615
break;
15451616
case REAR_RIGHT_WHEEL:
1546-
pFrame = vehicle->m_aCarNodes[eCarNode::WHEEL_RB];
1617+
pFrame = vehicle->m_aCarNodes[static_cast<std::size_t>(eCarNodes::WHEEL_RB)];
15471618
break;
15481619
default:
15491620
break;

Client/game_sa/CVehicleSA.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ struct RwTexture;
9494
#define FUNC_CAutomobile_OnVehiclePreRender 0x6ABCFD
9595
#define FUNC_CVehicle_DoSunGlare 0x6DD6F0
9696

97+
// CClumpModelInfo::GetFrameFromName
98+
#define FUNC_CClumpModelInfo_GetFrameFromName 0x4C5400
99+
100+
// CAutomobile::m_aCarNodes
101+
// CTrain::m_aTrainNodes
102+
// CBike::m_apModelNodes
103+
// CBoat::pBoatParts
104+
#define OFFSET_CAutomobile_Nodes 0x648
105+
#define OFFSET_CTrain_Nodes 0x668
106+
#define OFFSET_CBike_Nodes 0x5A0
107+
#define OFFSET_CBoat_Nodes 0x5B0
108+
109+
#define VAR_CTimer_snTimeInMilliseconds 0xB7CB84
110+
97111
struct SRailNodeSA
98112
{
99113
short sX; // x coordinate times 8
@@ -604,7 +618,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
604618
SharedUtil::SColor GetHeadLightColor() { return m_HeadLightColor; }
605619
void SetHeadLightColor(const SharedUtil::SColor color) { m_HeadLightColor = color; }
606620

607-
CObject* SpawnFlyingComponent(int i_1, unsigned int ui_2);
621+
bool SpawnFlyingComponent(const eCarNodes& nodeIndex, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime = -1);
608622
void SetWheelVisibility(eWheelPosition wheel, bool bVisible);
609623
CVector GetWheelPosition(eWheelPosition wheel);
610624

Client/mods/deathmatch/logic/CClientVehicle.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5037,6 +5037,14 @@ void CClientVehicle::ResetWheelScale()
50375037
m_bWheelScaleChanged = false;
50385038
}
50395039

5040+
bool CClientVehicle::SpawnFlyingComponent(const eCarNodes& nodeID, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime)
5041+
{
5042+
if (!m_pVehicle)
5043+
return false;
5044+
5045+
return m_pVehicle->SpawnFlyingComponent(nodeID, collisionType, removalTime);
5046+
}
5047+
50405048
CVector CClientVehicle::GetEntryPoint(std::uint32_t entryPointIndex)
50415049
{
50425050
static const uint32_t lookup[4] = {10, 8, 11, 9};

Client/mods/deathmatch/logic/CClientVehicle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,8 @@ class CClientVehicle : public CClientStreamElement
543543
bool SetDummyPosition(eVehicleDummies dummy, const CVector& position);
544544
bool ResetDummyPositions();
545545

546+
bool SpawnFlyingComponent(const eCarNodes& nodeID, const eCarComponentCollisionTypes& collisionType, std::int32_t removalTime);
547+
546548
CVector GetEntryPoint(std::uint32_t entryPointIndex);
547549

548550
protected:

0 commit comments

Comments
 (0)