CPhysical almost done
This commit is contained in:
parent
9e496100b7
commit
c4f9b9573f
@ -14,6 +14,7 @@ class CTimer
|
|||||||
static bool &m_CodePause;
|
static bool &m_CodePause;
|
||||||
public:
|
public:
|
||||||
static float GetTimeStep(void) { return ms_fTimeStep; }
|
static float GetTimeStep(void) { return ms_fTimeStep; }
|
||||||
|
static void SetTimeStep(float ts) { ms_fTimeStep = ts; }
|
||||||
static uint32 GetFrameCounter(void) { return m_FrameCounter; }
|
static uint32 GetFrameCounter(void) { return m_FrameCounter; }
|
||||||
static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
|
static uint32 GetTimeInMilliseconds(void) { return m_snTimeInMilliseconds; }
|
||||||
};
|
};
|
||||||
|
@ -2,4 +2,6 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
|
|
||||||
WRAPPER void cDMAudio::ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed) { EAXJMP(0x161684); }
|
cDMAudio &DMAudio = *(cDMAudio*)0x95CDBE;
|
||||||
|
|
||||||
|
WRAPPER void cDMAudio::ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed) { EAXJMP(0x57CBE0); }
|
||||||
|
@ -5,5 +5,6 @@ class CEntity;
|
|||||||
class cDMAudio
|
class cDMAudio
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed);
|
void ReportCollision(CEntity *A, CEntity *B, uint8 surfA, uint8 surfB, float impulse, float speed);
|
||||||
};
|
};
|
||||||
|
extern cDMAudio &DMAudio;
|
||||||
|
14
src/entities/Automobile.h
Normal file
14
src/entities/Automobile.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Vehicle.h"
|
||||||
|
|
||||||
|
class CAutomobile : public CVehicle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// 0x228
|
||||||
|
uint8 stuff1[484];
|
||||||
|
float m_afWheelSuspDist[4];
|
||||||
|
uint8 stuff2[300];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error");
|
||||||
|
static_assert(offsetof(CAutomobile, m_afWheelSuspDist) == 0x46C, "CAutomobile: error");
|
@ -41,7 +41,7 @@ public:
|
|||||||
int8 field_186;
|
int8 field_186;
|
||||||
int8 field_187;
|
int8 field_187;
|
||||||
CEntity *m_pCurSurface;
|
CEntity *m_pCurSurface;
|
||||||
CVehicle *m_pCollidingVehicle;
|
CEntity *m_pCollidingEntity;
|
||||||
int8 m_colour1, m_colour2;
|
int8 m_colour1, m_colour2;
|
||||||
|
|
||||||
static void *operator new(size_t);
|
static void *operator new(size_t);
|
||||||
|
9
src/entities/Ped.cpp
Normal file
9
src/entities/Ped.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "patcher.h"
|
||||||
|
#include "Ped.h"
|
||||||
|
#include "Pools.h"
|
||||||
|
|
||||||
|
//void *CPed::operator new(size_t sz) { return CPools::GetPedPool()->New(); }
|
||||||
|
//void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); }
|
||||||
|
|
||||||
|
WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); }
|
@ -13,7 +13,81 @@ class CPed : public CPhysical
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 0x128
|
// 0x128
|
||||||
uint8 stuff1[252];
|
CStoredCollPoly m_collPoly;
|
||||||
|
float m_fCollisionSpeed;
|
||||||
|
uint8 m_ped_flagA1 : 1;
|
||||||
|
uint8 m_ped_flagA2 : 1;
|
||||||
|
uint8 m_ped_flagA4 : 1;
|
||||||
|
uint8 m_ped_flagA8 : 1;
|
||||||
|
uint8 m_ped_flagA10 : 1;
|
||||||
|
uint8 m_ped_flagA20 : 1;
|
||||||
|
uint8 m_ped_flagA40 : 1;
|
||||||
|
uint8 m_ped_flagA80 : 1;
|
||||||
|
uint8 m_ped_flagB1 : 1;
|
||||||
|
uint8 m_ped_flagB2 : 1;
|
||||||
|
uint8 m_ped_flagB4 : 1;
|
||||||
|
uint8 m_ped_flagB8 : 1;
|
||||||
|
uint8 m_ped_flagB10 : 1;
|
||||||
|
uint8 m_ped_flagB20 : 1;
|
||||||
|
uint8 m_ped_flagB40 : 1;
|
||||||
|
uint8 m_ped_flagB80 : 1;
|
||||||
|
uint8 m_ped_flagC1 : 1;
|
||||||
|
uint8 m_ped_flagC2 : 1;
|
||||||
|
uint8 m_ped_flagC4 : 1;
|
||||||
|
uint8 m_ped_flagC8 : 1;
|
||||||
|
uint8 m_ped_flagC10 : 1;
|
||||||
|
uint8 m_ped_flagC20 : 1;
|
||||||
|
uint8 m_ped_flagC40 : 1;
|
||||||
|
uint8 m_ped_flagC80 : 1;
|
||||||
|
uint8 m_ped_flagD1 : 1;
|
||||||
|
uint8 m_ped_flagD2 : 1;
|
||||||
|
uint8 m_ped_flagD4 : 1;
|
||||||
|
uint8 m_ped_flagD8 : 1;
|
||||||
|
uint8 m_ped_flagD10 : 1;
|
||||||
|
uint8 m_ped_flagD20 : 1;
|
||||||
|
uint8 m_ped_flagD40 : 1;
|
||||||
|
uint8 m_ped_flagD80 : 1;
|
||||||
|
uint8 m_ped_flagE1 : 1;
|
||||||
|
uint8 m_ped_flagE2 : 1;
|
||||||
|
uint8 m_ped_flagE4 : 1;
|
||||||
|
uint8 m_ped_flagE8 : 1;
|
||||||
|
uint8 m_ped_flagE10 : 1;
|
||||||
|
uint8 m_ped_flagE20 : 1;
|
||||||
|
uint8 m_ped_flagE40 : 1;
|
||||||
|
uint8 m_ped_flagE80 : 1;
|
||||||
|
uint8 m_ped_flagF1 : 1;
|
||||||
|
uint8 m_ped_flagF2 : 1;
|
||||||
|
uint8 m_ped_flagF4 : 1;
|
||||||
|
uint8 m_ped_flagF8 : 1;
|
||||||
|
uint8 m_ped_flagF10 : 1;
|
||||||
|
uint8 m_ped_flagF20 : 1;
|
||||||
|
uint8 m_ped_flagF40 : 1;
|
||||||
|
uint8 m_ped_flagF80 : 1;
|
||||||
|
uint8 m_ped_flagG1 : 1;
|
||||||
|
uint8 m_ped_flagG2 : 1;
|
||||||
|
uint8 m_ped_flagG4 : 1;
|
||||||
|
uint8 m_ped_flagG8 : 1;
|
||||||
|
uint8 m_ped_flagG10 : 1;
|
||||||
|
uint8 m_ped_flagG20 : 1;
|
||||||
|
uint8 m_ped_flagG40 : 1;
|
||||||
|
uint8 m_ped_flagG80 : 1;
|
||||||
|
uint8 m_ped_flagH1 : 1;
|
||||||
|
uint8 m_ped_flagH2 : 1;
|
||||||
|
uint8 m_ped_flagH4 : 1;
|
||||||
|
uint8 m_ped_flagH8 : 1;
|
||||||
|
uint8 m_ped_flagH10 : 1;
|
||||||
|
uint8 m_ped_flagH20 : 1;
|
||||||
|
uint8 m_ped_flagH40 : 1;
|
||||||
|
uint8 m_ped_flagH80 : 1;
|
||||||
|
uint8 m_ped_flagI1 : 1;
|
||||||
|
uint8 m_ped_flagI2 : 1;
|
||||||
|
uint8 m_ped_flagI4 : 1;
|
||||||
|
uint8 m_ped_flagI8 : 1;
|
||||||
|
uint8 m_ped_flagI10 : 1;
|
||||||
|
uint8 m_ped_flagI20 : 1;
|
||||||
|
uint8 m_ped_flagI40 : 1;
|
||||||
|
uint8 m_ped_flagI80 : 1;
|
||||||
|
uint8 stuff1[199];
|
||||||
int32 m_nPedState;
|
int32 m_nPedState;
|
||||||
uint8 stuff2[196];
|
uint8 stuff2[196];
|
||||||
CEntity *m_pCurrentPhysSurface;
|
CEntity *m_pCurrentPhysSurface;
|
||||||
@ -26,14 +100,18 @@ public:
|
|||||||
int32 m_nPedType;
|
int32 m_nPedType;
|
||||||
|
|
||||||
uint8 stuff5[28];
|
uint8 stuff5[28];
|
||||||
CVehicle *m_pCollidingVehicle;
|
CEntity *m_pCollidingEntity;
|
||||||
uint8 stuff6[496];
|
uint8 stuff6[496];
|
||||||
|
|
||||||
|
// static void *operator new(size_t);
|
||||||
|
// static void operator delete(void*, size_t);
|
||||||
|
|
||||||
bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; }
|
bool IsPlayer(void) { return m_nPedType == 0 || m_nPedType== 1 || m_nPedType == 2 || m_nPedType == 3; }
|
||||||
|
void KillPedWithCar(CVehicle *veh, float impulse);
|
||||||
};
|
};
|
||||||
static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
|
static_assert(offsetof(CPed, m_nPedState) == 0x224, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
|
static_assert(offsetof(CPed, m_pCurSurface) == 0x2FC, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
|
static_assert(offsetof(CPed, m_pMyVehicle) == 0x310, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error");
|
static_assert(offsetof(CPed, m_nPedType) == 0x32C, "CPed: error");
|
||||||
static_assert(offsetof(CPed, m_pCollidingVehicle) == 0x34C, "CPed: error");
|
static_assert(offsetof(CPed, m_pCollidingEntity) == 0x34C, "CPed: error");
|
||||||
static_assert(sizeof(CPed) == 0x540, "CPed: error");
|
static_assert(sizeof(CPed) == 0x540, "CPed: error");
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "SurfaceTable.h"
|
#include "SurfaceTable.h"
|
||||||
#include "CarCtrl.h"
|
#include "CarCtrl.h"
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
|
#include "Automobile.h"
|
||||||
#include "Physical.h"
|
#include "Physical.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -176,11 +177,11 @@ CPhysical::RemoveFromMovingList(void)
|
|||||||
void
|
void
|
||||||
CPhysical::SetDamagedPieceRecord(uint16 piece, float impulse, CEntity *entity, CVector dir)
|
CPhysical::SetDamagedPieceRecord(uint16 piece, float impulse, CEntity *entity, CVector dir)
|
||||||
{
|
{
|
||||||
m_nCollisionPieceType = piece;
|
m_nDamagePieceType = piece;
|
||||||
m_fCollisionImpulse = impulse;
|
m_fDamageImpulse = impulse;
|
||||||
m_pCollidingEntity = entity;
|
m_pDamageEntity = entity;
|
||||||
entity->RegisterReference(&m_pCollidingEntity);
|
entity->RegisterReference(&m_pDamageEntity);
|
||||||
m_vecCollisionDirection = dir;
|
m_vecDamageNormal = dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -282,9 +283,9 @@ CPhysical::ProcessControl(void)
|
|||||||
|
|
||||||
m_nCollisionRecords = 0;
|
m_nCollisionRecords = 0;
|
||||||
bHasCollided = false;
|
bHasCollided = false;
|
||||||
m_nCollisionPieceType = 0;
|
m_nDamagePieceType = 0;
|
||||||
m_fCollisionImpulse = 0.0f;
|
m_fDamageImpulse = 0.0f;
|
||||||
m_pCollidingEntity = nil;
|
m_pDamageEntity = nil;
|
||||||
|
|
||||||
if(!bIsStuck){
|
if(!bIsStuck){
|
||||||
if(IsObject() ||
|
if(IsObject() ||
|
||||||
@ -927,18 +928,6 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ProcessCollision calls
|
|
||||||
// CheckCollision
|
|
||||||
// CheckCollision_SimpleCar
|
|
||||||
// CheckCollision calls
|
|
||||||
// ProcessCollisionSectorList
|
|
||||||
// CheckCollision_SimpleCar
|
|
||||||
// ProcessCollisionSectorList_SimpleCar
|
|
||||||
// ProcessShift calls
|
|
||||||
// ProcessCollisionSectorList
|
|
||||||
// ProcessShiftSectorList
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CPhysical::ProcessShiftSectorList(CPtrList *lists)
|
CPhysical::ProcessShiftSectorList(CPtrList *lists)
|
||||||
{
|
{
|
||||||
@ -996,21 +985,22 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
|
|||||||
B->GetUp().z < 0.66f &&
|
B->GetUp().z < 0.66f &&
|
||||||
IsTrafficLight(B->GetModelIndex()))
|
IsTrafficLight(B->GetModelIndex()))
|
||||||
skipShift = true;
|
skipShift = true;
|
||||||
|
// TODO: maybe flip some ifs here
|
||||||
else if(A->IsObject() && B->IsVehicle()){
|
else if(A->IsObject() && B->IsVehicle()){
|
||||||
CObject *Aobj = (CObject*)A;
|
CObject *Aobj = (CObject*)A;
|
||||||
if(Aobj->ObjectCreatedBy != TEMP_OBJECT &&
|
if(Aobj->ObjectCreatedBy != TEMP_OBJECT &&
|
||||||
!Aobj->bHasBeenDamaged &&
|
!Aobj->bHasBeenDamaged &&
|
||||||
Aobj->bIsStatic){
|
Aobj->bIsStatic){
|
||||||
if(Aobj->m_pCollidingVehicle == B)
|
if(Aobj->m_pCollidingEntity == B)
|
||||||
Aobj->m_pCollidingVehicle = nil;
|
Aobj->m_pCollidingEntity = nil;
|
||||||
}else if(Aobj->m_pCollidingVehicle != B){
|
}else if(Aobj->m_pCollidingEntity != B){
|
||||||
CMatrix inv;
|
CMatrix inv;
|
||||||
CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
||||||
size = A->GetMatrix() * size;
|
size = A->GetMatrix() * size;
|
||||||
if(size.z < B->GetPosition().z ||
|
if(size.z < B->GetPosition().z ||
|
||||||
(Invert(B->GetMatrix(), inv) * size).z < 0.0f){
|
(Invert(B->GetMatrix(), inv) * size).z < 0.0f){
|
||||||
skipShift = true;
|
skipShift = true;
|
||||||
Aobj->m_pCollidingVehicle = (CVehicle*)B;
|
Aobj->m_pCollidingEntity = B;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if(B->IsObject() && A->IsVehicle()){
|
}else if(B->IsObject() && A->IsVehicle()){
|
||||||
@ -1018,24 +1008,22 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
|
|||||||
if(Bobj->ObjectCreatedBy != TEMP_OBJECT &&
|
if(Bobj->ObjectCreatedBy != TEMP_OBJECT &&
|
||||||
!Bobj->bHasBeenDamaged &&
|
!Bobj->bHasBeenDamaged &&
|
||||||
Bobj->bIsStatic){
|
Bobj->bIsStatic){
|
||||||
if(Bobj->m_pCollidingVehicle == A)
|
if(Bobj->m_pCollidingEntity == A)
|
||||||
Bobj->m_pCollidingVehicle = nil;
|
Bobj->m_pCollidingEntity = nil;
|
||||||
}else if(Bobj->m_pCollidingVehicle != A){
|
}else if(Bobj->m_pCollidingEntity != A){
|
||||||
CMatrix inv;
|
CMatrix inv;
|
||||||
CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
||||||
size = B->GetMatrix() * size;
|
size = B->GetMatrix() * size;
|
||||||
if(size.z < A->GetPosition().z ||
|
if(size.z < A->GetPosition().z ||
|
||||||
(Invert(A->GetMatrix(), inv) * size).z < 0.0f){
|
(Invert(A->GetMatrix(), inv) * size).z < 0.0f)
|
||||||
skipShift = true;
|
skipShift = true;
|
||||||
Bobj->m_pCollidingVehicle = (CVehicle*)A;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else if(IsBodyPart(A->GetModelIndex()) && B->IsPed())
|
}else if(IsBodyPart(A->GetModelIndex()) && B->IsPed())
|
||||||
skipShift = true;
|
skipShift = true;
|
||||||
else if(A->IsPed() && IsBodyPart(B->GetModelIndex()))
|
else if(A->IsPed() && IsBodyPart(B->GetModelIndex()))
|
||||||
skipShift = true;
|
skipShift = true;
|
||||||
else if(A->IsPed() && ((CPed*)A)->m_pCollidingVehicle == B ||
|
else if(A->IsPed() && ((CPed*)A)->m_pCollidingEntity == B ||
|
||||||
B->IsPed() && ((CPed*)B)->m_pCollidingVehicle == A ||
|
B->IsPed() && ((CPed*)B)->m_pCollidingEntity == A ||
|
||||||
A->GetModelIndex() == MI_RCBANDIT && B->IsVehicle() ||
|
A->GetModelIndex() == MI_RCBANDIT && B->IsVehicle() ||
|
||||||
B->GetModelIndex() == MI_RCBANDIT && (A->IsPed() || A->IsVehicle()))
|
B->GetModelIndex() == MI_RCBANDIT && (A->IsPed() || A->IsVehicle()))
|
||||||
skipShift = true;
|
skipShift = true;
|
||||||
@ -1154,16 +1142,16 @@ collision:
|
|||||||
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(impulseA > A->m_fCollisionImpulse)
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
if(impulseB > B->m_fCollisionImpulse)
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
cDMAudio::ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
}
|
}
|
||||||
}else if(A->bHasContacted){
|
}else if(A->bHasContacted){
|
||||||
CVector savedMoveFriction = A->m_vecMoveFriction;
|
CVector savedMoveFriction = A->m_vecMoveFriction;
|
||||||
@ -1176,16 +1164,16 @@ collision:
|
|||||||
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(impulseA > A->m_fCollisionImpulse)
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
if(impulseB > B->m_fCollisionImpulse)
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
cDMAudio::ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
|
||||||
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
||||||
A->bHasContacted = true;
|
A->bHasContacted = true;
|
||||||
@ -1209,16 +1197,16 @@ collision:
|
|||||||
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(impulseA > A->m_fCollisionImpulse)
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
if(impulseB > B->m_fCollisionImpulse)
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
cDMAudio::ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
|
||||||
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
||||||
A->bHasContacted = true;
|
A->bHasContacted = true;
|
||||||
@ -1236,16 +1224,16 @@ collision:
|
|||||||
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(impulseA > A->m_fCollisionImpulse)
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
if(impulseB > B->m_fCollisionImpulse)
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
A->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
cDMAudio::ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
|
||||||
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
||||||
A->bHasContacted = true;
|
A->bHasContacted = true;
|
||||||
@ -1263,12 +1251,602 @@ collision:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPhysical::ProcessCollisionSectorList(CPtrList *lists)
|
||||||
|
{
|
||||||
|
static CColPoint aColPoints[32];
|
||||||
|
float radius;
|
||||||
|
CVector center;
|
||||||
|
CPtrList *list;
|
||||||
|
CPhysical *A, *B;
|
||||||
|
CObject *Aobj, *Bobj;
|
||||||
|
CPed *Aped, *Bped;
|
||||||
|
int numCollisions;
|
||||||
|
int numResponses;
|
||||||
|
int i, j;
|
||||||
|
bool skipCollision, altcollision;
|
||||||
|
float impulseA = -1.0f;
|
||||||
|
float impulseB = -1.0f;
|
||||||
|
|
||||||
|
A = (CPhysical*)this;
|
||||||
|
Aobj = (CObject*)A;
|
||||||
|
Aped = (CPed*)A;
|
||||||
|
|
||||||
|
radius = A->GetBoundRadius();
|
||||||
|
A->GetBoundCentre(center);
|
||||||
|
|
||||||
|
for(j = 0; j <= ENTITYLIST_PEDS_OVERLAP; j++){
|
||||||
|
list = &lists[j];
|
||||||
|
|
||||||
|
CPtrNode *listnode;
|
||||||
|
for(listnode = list->first; listnode; listnode = listnode->next){
|
||||||
|
B = (CPhysical*)listnode->item;
|
||||||
|
Bobj = (CObject*)B;
|
||||||
|
Bped = (CPed*)B;
|
||||||
|
|
||||||
|
bool isTouching = true;
|
||||||
|
if(B == A ||
|
||||||
|
B->m_scanCode == CWorld::GetCurrentScanCode() ||
|
||||||
|
!B->bUsesCollision ||
|
||||||
|
!(isTouching = B->GetIsTouching(center, radius))){
|
||||||
|
if(!isTouching){
|
||||||
|
if(A->IsObject() && Aobj->m_pCollidingEntity == B)
|
||||||
|
Aobj->m_pCollidingEntity = nil;
|
||||||
|
else if(B->IsObject() && Bobj->m_pCollidingEntity == A)
|
||||||
|
Bobj->m_pCollidingEntity = nil;
|
||||||
|
else if(A->IsPed() && Aped->m_pCollidingEntity == B)
|
||||||
|
Aped->m_pCollidingEntity = nil;
|
||||||
|
else if(B->IsPed() && Bped->m_pCollidingEntity == A)
|
||||||
|
Bped->m_pCollidingEntity = nil;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
A->m_phy_flagA80 = false;
|
||||||
|
skipCollision = false;
|
||||||
|
altcollision = false;
|
||||||
|
|
||||||
|
if(B->IsBuilding())
|
||||||
|
skipCollision = false;
|
||||||
|
else if(IsTrafficLight(A->GetModelIndex()) &&
|
||||||
|
(B->IsVehicle() || B->IsPed()) &&
|
||||||
|
A->GetUp().z < 0.66f){
|
||||||
|
skipCollision = true;
|
||||||
|
A->m_phy_flagA80 = true;
|
||||||
|
Aobj->m_pCollidingEntity = B;
|
||||||
|
}else if((A->IsVehicle() || A->IsPed()) &&
|
||||||
|
B->GetUp().z < 0.66f &&
|
||||||
|
IsTrafficLight(B->GetModelIndex())){
|
||||||
|
skipCollision = true;
|
||||||
|
A->m_phy_flagA80 = true;
|
||||||
|
Bobj->m_pCollidingEntity = A;
|
||||||
|
}else if(A->IsObject() && B->IsVehicle()){
|
||||||
|
if(A->GetModelIndex() == MI_CAR_BUMPER || A->GetModelIndex() == MI_FILES)
|
||||||
|
skipCollision = true;
|
||||||
|
else if(Aobj->ObjectCreatedBy == TEMP_OBJECT ||
|
||||||
|
Aobj->bHasBeenDamaged ||
|
||||||
|
!Aobj->bIsStatic){
|
||||||
|
if(Aobj->m_pCollidingEntity == B)
|
||||||
|
skipCollision = true;
|
||||||
|
else{
|
||||||
|
CMatrix inv;
|
||||||
|
CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
||||||
|
size = A->GetMatrix() * size;
|
||||||
|
if(size.z < B->GetPosition().z ||
|
||||||
|
(Invert(B->GetMatrix(), inv) * size).z < 0.0f){
|
||||||
|
skipCollision = true;
|
||||||
|
Aobj->m_pCollidingEntity = B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(B->IsObject() && A->IsVehicle()){
|
||||||
|
if(B->GetModelIndex() == MI_CAR_BUMPER || B->GetModelIndex() == MI_FILES)
|
||||||
|
skipCollision = true;
|
||||||
|
else if(Bobj->ObjectCreatedBy == TEMP_OBJECT ||
|
||||||
|
Bobj->bHasBeenDamaged ||
|
||||||
|
!Bobj->bIsStatic){
|
||||||
|
if(Bobj->m_pCollidingEntity == A)
|
||||||
|
skipCollision = true;
|
||||||
|
else{
|
||||||
|
CMatrix inv;
|
||||||
|
CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
|
||||||
|
size = B->GetMatrix() * size;
|
||||||
|
if(size.z < A->GetPosition().z ||
|
||||||
|
(Invert(A->GetMatrix(), inv) * size).z < 0.0f){
|
||||||
|
skipCollision = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(IsBodyPart(A->GetModelIndex()) && B->IsPed()){
|
||||||
|
skipCollision = true;
|
||||||
|
}else if(A->IsPed() && IsBodyPart(B->GetModelIndex())){
|
||||||
|
skipCollision = true;
|
||||||
|
A->m_phy_flagA80 = true;
|
||||||
|
}else if(A->IsPed() && Aped->m_pCollidingEntity == B){
|
||||||
|
skipCollision = true;
|
||||||
|
if(!Aped->m_ped_flagH1)
|
||||||
|
A->m_phy_flagA80 = true;
|
||||||
|
}else if(B->IsPed() && Bped->m_pCollidingEntity == A){
|
||||||
|
skipCollision = true;
|
||||||
|
A->m_phy_flagA80 = true;
|
||||||
|
}else if(A->GetModelIndex() == MI_RCBANDIT && (B->IsPed() || B->IsVehicle()) ||
|
||||||
|
B->GetModelIndex() == MI_RCBANDIT && (A->IsPed() || A->IsVehicle())){
|
||||||
|
skipCollision = true;
|
||||||
|
A->m_phy_flagA80 = true;
|
||||||
|
}else if(A->IsPed() && B->IsObject() && Bobj->m_fUprootLimit > 0.0f)
|
||||||
|
altcollision = true;
|
||||||
|
|
||||||
|
|
||||||
|
if(!A->bUsesCollision || skipCollision){
|
||||||
|
B->m_scanCode = CWorld::GetCurrentScanCode();
|
||||||
|
A->ProcessEntityCollision(B, aColPoints);
|
||||||
|
}else if(B->IsBuilding() || B->bIsStuck || B->bInfiniteMass || altcollision){
|
||||||
|
|
||||||
|
// This is the case where B doesn't move
|
||||||
|
|
||||||
|
B->m_scanCode = CWorld::GetCurrentScanCode();
|
||||||
|
numCollisions = A->ProcessEntityCollision(B, aColPoints);
|
||||||
|
if(numCollisions <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CVector moveSpeed = { 0.0f, 0.0f, 0.0f };
|
||||||
|
CVector turnSpeed = { 0.0f, 0.0f, 0.0f };
|
||||||
|
numResponses = 0;
|
||||||
|
if(A->bHasContacted){
|
||||||
|
for(i = 0; i < numCollisions; i++){
|
||||||
|
if(!A->ApplyCollisionAlt(B, aColPoints[i], impulseA, moveSpeed, turnSpeed))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
numResponses++;
|
||||||
|
|
||||||
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
|
float imp = impulseA;
|
||||||
|
if(A->IsVehicle() && A->GetUp().z < -0.6f &&
|
||||||
|
fabs(A->m_vecMoveSpeed.x) < 0.05f &&
|
||||||
|
fabs(A->m_vecMoveSpeed.y) < 0.05f)
|
||||||
|
imp *= 0.1f;
|
||||||
|
|
||||||
|
float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
|
||||||
|
float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
|
||||||
|
|
||||||
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
for(i = 0; i < numCollisions; i++){
|
||||||
|
if(!A->ApplyCollisionAlt(B, aColPoints[i], impulseA, moveSpeed, turnSpeed))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
numResponses++;
|
||||||
|
|
||||||
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
|
float imp = impulseA;
|
||||||
|
if(A->IsVehicle() && A->GetUp().z < -0.6f &&
|
||||||
|
fabs(A->m_vecMoveSpeed.x) < 0.05f &&
|
||||||
|
fabs(A->m_vecMoveSpeed.y) < 0.05f)
|
||||||
|
imp *= 0.1f;
|
||||||
|
|
||||||
|
float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
|
||||||
|
float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
|
||||||
|
|
||||||
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
|
||||||
|
float adhesion = CSurfaceTable::GetAdhesiveLimit(aColPoints[i]) / numCollisions;
|
||||||
|
|
||||||
|
if(A->GetModelIndex() == MI_RCBANDIT)
|
||||||
|
adhesion *= 0.2f;
|
||||||
|
else if(IsBoatModel(A->GetModelIndex())){
|
||||||
|
if(aColPoints[i].normal.z > 0.6f){
|
||||||
|
if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_LOOSE)
|
||||||
|
adhesion *= 3.0f;
|
||||||
|
}else
|
||||||
|
adhesion = 0.0f;
|
||||||
|
}else if(A->IsVehicle()){
|
||||||
|
if(A->m_status == STATUS_WRECKED)
|
||||||
|
adhesion *= 3.0f;
|
||||||
|
else if(A->GetUp().z > 0.3f)
|
||||||
|
adhesion = 0.0f;
|
||||||
|
else
|
||||||
|
adhesion *= max(5.0f, 0.03f*impulseA + 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(A->ApplyFriction(adhesion, aColPoints[i]))
|
||||||
|
A->bHasContacted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(numResponses){
|
||||||
|
m_vecMoveSpeed += moveSpeed / numResponses;
|
||||||
|
m_vecTurnSpeed += turnSpeed / numResponses;
|
||||||
|
if(!CWorld::bNoMoreCollisionTorque &&
|
||||||
|
A->m_status == STATUS_PLAYER && A->IsVehicle() &&
|
||||||
|
fabs(A->m_vecMoveSpeed.x) > 0.2f &&
|
||||||
|
fabs(A->m_vecMoveSpeed.y) > 0.2f){
|
||||||
|
A->m_vecMoveFriction.x += moveSpeed.x * -0.3f / numCollisions;
|
||||||
|
A->m_vecMoveFriction.y += moveSpeed.y * -0.3f / numCollisions;
|
||||||
|
A->m_vecTurnFriction += turnSpeed * -0.3f / numCollisions;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
|
||||||
|
// B can move
|
||||||
|
|
||||||
|
B->m_scanCode = CWorld::GetCurrentScanCode();
|
||||||
|
numCollisions = A->ProcessEntityCollision(B, aColPoints);
|
||||||
|
if(numCollisions <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float maxImpulseA = 0.0f;
|
||||||
|
float maxImpulseB = 0.0f;
|
||||||
|
if(A->bHasContacted && B->bHasContacted){
|
||||||
|
for(i = 0; i < numCollisions; i++){
|
||||||
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(impulseA > maxImpulseA) maxImpulseA = impulseA;
|
||||||
|
if(impulseB > maxImpulseB) maxImpulseB = impulseB;
|
||||||
|
|
||||||
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
}
|
||||||
|
}else if(A->bHasContacted){
|
||||||
|
CVector savedMoveFriction = A->m_vecMoveFriction;
|
||||||
|
CVector savedTurnFriction = A->m_vecTurnFriction;
|
||||||
|
A->m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
A->m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
A->bHasContacted = false;
|
||||||
|
|
||||||
|
for(i = 0; i < numCollisions; i++){
|
||||||
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(impulseA > maxImpulseA) maxImpulseA = impulseA;
|
||||||
|
if(impulseB > maxImpulseB) maxImpulseB = impulseB;
|
||||||
|
|
||||||
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
|
||||||
|
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
||||||
|
A->bHasContacted = true;
|
||||||
|
B->bHasContacted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!A->bHasContacted){
|
||||||
|
A->bHasContacted = true;
|
||||||
|
A->m_vecMoveFriction = savedMoveFriction;
|
||||||
|
A->m_vecTurnFriction = savedTurnFriction;
|
||||||
|
}
|
||||||
|
}else if(B->bHasContacted){
|
||||||
|
CVector savedMoveFriction = B->m_vecMoveFriction;
|
||||||
|
CVector savedTurnFriction = B->m_vecTurnFriction;
|
||||||
|
B->m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
B->m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
|
||||||
|
B->bHasContacted = false;
|
||||||
|
|
||||||
|
for(i = 0; i < numCollisions; i++){
|
||||||
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(impulseA > maxImpulseA) maxImpulseA = impulseA;
|
||||||
|
if(impulseB > maxImpulseB) maxImpulseB = impulseB;
|
||||||
|
|
||||||
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
|
||||||
|
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
||||||
|
A->bHasContacted = true;
|
||||||
|
B->bHasContacted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!B->bHasContacted){
|
||||||
|
B->bHasContacted = true;
|
||||||
|
B->m_vecMoveFriction = savedMoveFriction;
|
||||||
|
B->m_vecTurnFriction = savedTurnFriction;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
for(i = 0; i < numCollisions; i++){
|
||||||
|
if(!A->ApplyCollision(B, aColPoints[i], impulseA, impulseB))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(impulseA > maxImpulseA) maxImpulseA = impulseA;
|
||||||
|
if(impulseB > maxImpulseB) maxImpulseB = impulseB;
|
||||||
|
|
||||||
|
if(impulseA > A->m_fDamageImpulse)
|
||||||
|
A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
|
||||||
|
|
||||||
|
if(impulseB > B->m_fDamageImpulse)
|
||||||
|
B->SetDamagedPieceRecord(aColPoints[i].pieceB, impulseB, A, aColPoints[i].normal);
|
||||||
|
|
||||||
|
float turnSpeedDiff = (B->m_vecTurnSpeed - A->m_vecTurnSpeed).MagnitudeSqr();
|
||||||
|
float moveSpeedDiff = (B->m_vecMoveSpeed - A->m_vecMoveSpeed).MagnitudeSqr();
|
||||||
|
|
||||||
|
DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, max(turnSpeedDiff, moveSpeedDiff));
|
||||||
|
|
||||||
|
if(A->ApplyFriction(B, CSurfaceTable::GetAdhesiveLimit(aColPoints[i])/numCollisions, aColPoints[i])){
|
||||||
|
A->bHasContacted = true;
|
||||||
|
B->bHasContacted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(B->IsPed() && A->IsVehicle() &&
|
||||||
|
(!Bped->IsPlayer() || B->bHasHitWall && A->m_vecMoveSpeed.MagnitudeSqr() > 0.0025f))
|
||||||
|
Bped->KillPedWithCar((CVehicle*)A, maxImpulseB);
|
||||||
|
else if(B->GetModelIndex() == MI_TRAIN && A->IsPed() &&
|
||||||
|
(!Aped->IsPlayer() || A->bHasHitWall))
|
||||||
|
Aped->KillPedWithCar((CVehicle*)B, maxImpulseA*2.0f);
|
||||||
|
else if(B->IsObject() && B->bUsesCollision && A->IsVehicle()){
|
||||||
|
if(Bobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f)
|
||||||
|
Bobj->ObjectDamage(maxImpulseB);
|
||||||
|
}else if(A->IsObject() && A->bUsesCollision && B->IsVehicle()){
|
||||||
|
// BUG? not impulseA?
|
||||||
|
if(Aobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f)
|
||||||
|
Aobj->ObjectDamage(maxImpulseB);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(B->m_status == STATUS_SIMPLE){
|
||||||
|
B->m_status = STATUS_PHYSICS;
|
||||||
|
if(B->IsVehicle())
|
||||||
|
CCarCtrl::SwitchVehicleToRealPhysics((CVehicle*)B);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPhysical::CheckCollision(void)
|
||||||
|
{
|
||||||
|
CEntryInfoNode *node;
|
||||||
|
|
||||||
|
bCollisionProcessed = false;
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
for(node = m_entryInfoList.first; node; node = node->next)
|
||||||
|
if(ProcessCollisionSectorList(node->sector->m_lists))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CPhysical::CheckCollision_SimpleCar(void)
|
||||||
|
{
|
||||||
|
CEntryInfoNode *node;
|
||||||
|
|
||||||
|
bCollisionProcessed = false;
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
for(node = m_entryInfoList.first; node; node = node->next)
|
||||||
|
if(ProcessCollisionSectorList_SimpleCar(node->sector->m_lists))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPhysical::ProcessShift(void)
|
||||||
|
{
|
||||||
|
m_fDistanceTravelled = 0.0f;
|
||||||
|
if(m_status == STATUS_SIMPLE){
|
||||||
|
bIsStuck = false;
|
||||||
|
bIsInSafePosition = true;
|
||||||
|
RemoveAndAdd();
|
||||||
|
}else{
|
||||||
|
CMatrix matrix(GetMatrix());
|
||||||
|
ApplyMoveSpeed();
|
||||||
|
ApplyTurnSpeed();
|
||||||
|
GetMatrix().Reorthogonalise();
|
||||||
|
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
|
||||||
|
if(IsVehicle())
|
||||||
|
field_EF = true;
|
||||||
|
|
||||||
|
CEntryInfoNode *node;
|
||||||
|
bool hasshifted = false; // whatever that means...
|
||||||
|
for(node = m_entryInfoList.first; node; node = node->next)
|
||||||
|
hasshifted |= ProcessShiftSectorList(node->sector->m_lists);
|
||||||
|
field_EF = false;
|
||||||
|
if(hasshifted){
|
||||||
|
CWorld::AdvanceCurrentScanCode();
|
||||||
|
for(node = m_entryInfoList.first; node; node = node->next)
|
||||||
|
if(ProcessCollisionSectorList(node->sector->m_lists)){
|
||||||
|
GetMatrix() = matrix;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bIsStuck = false;
|
||||||
|
bIsInSafePosition = true;
|
||||||
|
m_fDistanceTravelled = (GetPosition() - *matrix.GetPosition()).Magnitude();
|
||||||
|
RemoveAndAdd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// x is the number of units (m) we would like to step
|
||||||
|
#define NUMSTEPS(x) ceil(sqrt(distSq) * (1.0f/(x)))
|
||||||
|
|
||||||
|
void
|
||||||
|
CPhysical::ProcessCollision(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
CPed *ped = (CPed*)this;
|
||||||
|
|
||||||
|
m_fDistanceTravelled = 0.0f;
|
||||||
|
field_EF = 0;
|
||||||
|
m_phy_flagA80 = false;
|
||||||
|
|
||||||
|
if(!bUsesCollision){
|
||||||
|
bIsStuck = false;
|
||||||
|
bIsInSafePosition = true;
|
||||||
|
RemoveAndAdd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_status == STATUS_SIMPLE){
|
||||||
|
if(CheckCollision_SimpleCar() && m_status == STATUS_SIMPLE){
|
||||||
|
m_status = STATUS_PHYSICS;
|
||||||
|
if(IsVehicle())
|
||||||
|
CCarCtrl::SwitchVehicleToRealPhysics((CVehicle*)this);
|
||||||
|
}
|
||||||
|
bIsStuck = false;
|
||||||
|
bIsInSafePosition = true;
|
||||||
|
RemoveAndAdd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save current state
|
||||||
|
CMatrix savedMatrix(GetMatrix());
|
||||||
|
float savedTimeStep = CTimer::GetTimeStep();
|
||||||
|
|
||||||
|
int8 n = 1; // The number of steps we divide the time step into
|
||||||
|
float step = 0.0f; // divided time step
|
||||||
|
float distSq = GetDistanceSq();
|
||||||
|
|
||||||
|
if(IsPed() && (distSq >= sq(0.2f) || ped->IsPlayer())){
|
||||||
|
if(ped->IsPlayer())
|
||||||
|
n = min(NUMSTEPS(0.2f), 2.0);
|
||||||
|
else
|
||||||
|
n = NUMSTEPS(0.3f);
|
||||||
|
step = savedTimeStep / n;
|
||||||
|
}else if(IsVehicle() && distSq >= sq(0.4f)){
|
||||||
|
if(m_status == STATUS_PLAYER)
|
||||||
|
n = NUMSTEPS(0.2f);
|
||||||
|
else
|
||||||
|
n = distSq > 0.32f ? NUMSTEPS(0.3f) : NUMSTEPS(0.4f);
|
||||||
|
step = savedTimeStep / n;
|
||||||
|
}else if(IsObject()){
|
||||||
|
int responsecase = ((CObject*)this)->m_bSpecialCollisionResponseCases;
|
||||||
|
if(responsecase == 1){
|
||||||
|
CVector speedUp = { 0.0f, 0.0f, 0.0f };
|
||||||
|
CVector speedDown = { 0.0f, 0.0f, 0.0f };
|
||||||
|
speedUp.z = GetBoundRadius();
|
||||||
|
speedDown.z = -speedUp.z;
|
||||||
|
speedUp = Multiply3x3(GetMatrix(), speedUp);
|
||||||
|
speedDown = Multiply3x3(GetMatrix(), speedDown);
|
||||||
|
speedUp = GetSpeed(speedUp);
|
||||||
|
speedDown = GetSpeed(speedDown);
|
||||||
|
distSq = max(speedUp.MagnitudeSqr(), speedDown.MagnitudeSqr()) * sq(CTimer::GetTimeStep());
|
||||||
|
if(distSq >= sq(0.3f)){
|
||||||
|
n = NUMSTEPS(0.3f);
|
||||||
|
step = savedTimeStep / n;
|
||||||
|
}
|
||||||
|
}else if(responsecase == 5){
|
||||||
|
if(distSq >= 0.009f){
|
||||||
|
n = NUMSTEPS(0.09f);
|
||||||
|
step = savedTimeStep / n;
|
||||||
|
}
|
||||||
|
}else if(responsecase == 2 || responsecase == 4){
|
||||||
|
if(distSq >= sq(0.15f)){
|
||||||
|
n = NUMSTEPS(0.15f);
|
||||||
|
step = savedTimeStep / n;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(distSq >= sq(0.3f)){
|
||||||
|
n = NUMSTEPS(0.3f);
|
||||||
|
step = savedTimeStep / n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 1; i < n; i++){
|
||||||
|
CTimer::SetTimeStep(i * step);
|
||||||
|
ApplyMoveSpeed();
|
||||||
|
ApplyTurnSpeed();
|
||||||
|
// TODO: get rid of copy paste?
|
||||||
|
if(CheckCollision()){
|
||||||
|
if(IsPed() && m_vecMoveSpeed.z == 0.0f &&
|
||||||
|
!ped->m_ped_flagA2 &&
|
||||||
|
ped->m_ped_flagA1)
|
||||||
|
savedMatrix.GetPosition()->z = GetPosition().z;
|
||||||
|
GetMatrix() = savedMatrix;
|
||||||
|
CTimer::SetTimeStep(savedTimeStep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(IsPed() && m_vecMoveSpeed.z == 0.0f &&
|
||||||
|
!ped->m_ped_flagA2 &&
|
||||||
|
ped->m_ped_flagA1)
|
||||||
|
savedMatrix.GetPosition()->z = GetPosition().z;
|
||||||
|
GetMatrix() = savedMatrix;
|
||||||
|
CTimer::SetTimeStep(savedTimeStep);
|
||||||
|
if(IsVehicle()){
|
||||||
|
CVehicle *veh = (CVehicle*)this;
|
||||||
|
if(veh->m_vehType == VEHICLE_TYPE_CAR){
|
||||||
|
CAutomobile *car = (CAutomobile*)this;
|
||||||
|
car->m_afWheelSuspDist[0] = 1.0f;
|
||||||
|
car->m_afWheelSuspDist[1] = 1.0f;
|
||||||
|
car->m_afWheelSuspDist[2] = 1.0f;
|
||||||
|
car->m_afWheelSuspDist[3] = 1.0f;
|
||||||
|
}else if(veh->m_vehType == VEHICLE_TYPE_BIKE){
|
||||||
|
assert(0 && "TODO - but unused");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyMoveSpeed();
|
||||||
|
ApplyTurnSpeed();
|
||||||
|
GetMatrix().Reorthogonalise();
|
||||||
|
field_EF = 0;
|
||||||
|
m_phy_flagA80 = false;
|
||||||
|
if(!m_vecMoveSpeed.IsZero() ||
|
||||||
|
!m_vecTurnSpeed.IsZero() ||
|
||||||
|
m_phy_flagA40 ||
|
||||||
|
m_status == STATUS_PLAYER || IsPed() && ped->IsPlayer()){
|
||||||
|
if(IsVehicle())
|
||||||
|
((CVehicle*)this)->m_veh_flagD4 = true;
|
||||||
|
if(CheckCollision()){
|
||||||
|
GetMatrix() = savedMatrix;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_phy_flagA40 = false;
|
||||||
|
m_fDistanceTravelled = (GetPosition() - *savedMatrix.GetPosition()).Magnitude();
|
||||||
|
m_phy_flagA80 = false;
|
||||||
|
|
||||||
|
bIsStuck = false;
|
||||||
|
bIsInSafePosition = true;
|
||||||
|
RemoveAndAdd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4951F0, &CPhysical::Add_, PATCH_JUMP);
|
InjectHook(0x4951F0, &CPhysical::Add_, PATCH_JUMP);
|
||||||
InjectHook(0x4954B0, &CPhysical::Remove_, PATCH_JUMP);
|
InjectHook(0x4954B0, &CPhysical::Remove_, PATCH_JUMP);
|
||||||
InjectHook(0x495540, &CPhysical::RemoveAndAdd, PATCH_JUMP);
|
InjectHook(0x495540, &CPhysical::RemoveAndAdd, PATCH_JUMP);
|
||||||
InjectHook(0x495F10, &CPhysical::ProcessControl_, PATCH_JUMP);
|
InjectHook(0x495F10, &CPhysical::ProcessControl_, PATCH_JUMP);
|
||||||
|
InjectHook(0x496F10, &CPhysical::ProcessShift_, PATCH_JUMP);
|
||||||
|
InjectHook(0x4961A0, &CPhysical::ProcessCollision_, PATCH_JUMP);
|
||||||
InjectHook(0x49F790, &CPhysical::ProcessEntityCollision_, PATCH_JUMP);
|
InjectHook(0x49F790, &CPhysical::ProcessEntityCollision_, PATCH_JUMP);
|
||||||
InjectHook(0x4958F0, &CPhysical::AddToMovingList, PATCH_JUMP);
|
InjectHook(0x4958F0, &CPhysical::AddToMovingList, PATCH_JUMP);
|
||||||
InjectHook(0x495940, &CPhysical::RemoveFromMovingList, PATCH_JUMP);
|
InjectHook(0x495940, &CPhysical::RemoveFromMovingList, PATCH_JUMP);
|
||||||
@ -1296,4 +1874,7 @@ STARTPATCHES
|
|||||||
|
|
||||||
InjectHook(0x49DA10, &CPhysical::ProcessShiftSectorList, PATCH_JUMP);
|
InjectHook(0x49DA10, &CPhysical::ProcessShiftSectorList, PATCH_JUMP);
|
||||||
InjectHook(0x49E790, &CPhysical::ProcessCollisionSectorList_SimpleCar, PATCH_JUMP);
|
InjectHook(0x49E790, &CPhysical::ProcessCollisionSectorList_SimpleCar, PATCH_JUMP);
|
||||||
|
InjectHook(0x49B620, &CPhysical::ProcessCollisionSectorList, PATCH_JUMP);
|
||||||
|
InjectHook(0x496E50, &CPhysical::CheckCollision, PATCH_JUMP);
|
||||||
|
InjectHook(0x496EB0, &CPhysical::CheckCollision_SimpleCar, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Lists.h"
|
#include "Lists.h"
|
||||||
|
#include "Timer.h"
|
||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "Treadable.h"
|
#include "Treadable.h"
|
||||||
|
|
||||||
@ -37,16 +38,16 @@ public:
|
|||||||
char field_EC;
|
char field_EC;
|
||||||
uint8 m_nStaticFrames;
|
uint8 m_nStaticFrames;
|
||||||
uint8 m_nCollisionRecords;
|
uint8 m_nCollisionRecords;
|
||||||
char field_EF;
|
bool field_EF;
|
||||||
CEntity *m_aCollisionRecords[PHYSICAL_MAX_COLLISIONRECORDS];
|
CEntity *m_aCollisionRecords[PHYSICAL_MAX_COLLISIONRECORDS];
|
||||||
|
|
||||||
float m_fDistanceTravelled;
|
float m_fDistanceTravelled;
|
||||||
|
|
||||||
// damaged piece
|
// damaged piece
|
||||||
float m_fCollisionImpulse;
|
float m_fDamageImpulse;
|
||||||
CEntity *m_pCollidingEntity;
|
CEntity *m_pDamageEntity;
|
||||||
CVector m_vecCollisionDirection;
|
CVector m_vecDamageNormal;
|
||||||
int16 m_nCollisionPieceType;
|
int16 m_nDamagePieceType;
|
||||||
|
|
||||||
uint8 m_phy_flagA1 : 1;
|
uint8 m_phy_flagA1 : 1;
|
||||||
uint8 bAffectedByGravity : 1;
|
uint8 bAffectedByGravity : 1;
|
||||||
@ -88,6 +89,7 @@ public:
|
|||||||
bool GetHasCollidedWith(CEntity *ent);
|
bool GetHasCollidedWith(CEntity *ent);
|
||||||
void RemoveRefsToEntity(CEntity *ent);
|
void RemoveRefsToEntity(CEntity *ent);
|
||||||
|
|
||||||
|
float GetDistanceSq(void) { return m_vecMoveSpeed.MagnitudeSqr() * sq(CTimer::GetTimeStep()); }
|
||||||
// get speed of point p relative to entity center
|
// get speed of point p relative to entity center
|
||||||
CVector GetSpeed(const CVector &r);
|
CVector GetSpeed(const CVector &r);
|
||||||
CVector GetSpeed(void) { return GetSpeed(CVector(0.0f, 0.0f, 0.0f)); }
|
CVector GetSpeed(void) { return GetSpeed(CVector(0.0f, 0.0f, 0.0f)); }
|
||||||
@ -133,12 +135,19 @@ public:
|
|||||||
|
|
||||||
bool ProcessShiftSectorList(CPtrList *ptrlists);
|
bool ProcessShiftSectorList(CPtrList *ptrlists);
|
||||||
bool ProcessCollisionSectorList_SimpleCar(CPtrList *lists);
|
bool ProcessCollisionSectorList_SimpleCar(CPtrList *lists);
|
||||||
|
bool ProcessCollisionSectorList(CPtrList *lists);
|
||||||
|
bool CheckCollision(void);
|
||||||
|
bool CheckCollision_SimpleCar(void);
|
||||||
|
void ProcessShift(void);
|
||||||
|
void ProcessCollision(void);
|
||||||
|
|
||||||
// to make patching virtual functions possible
|
// to make patching virtual functions possible
|
||||||
void Add_(void) { CPhysical::Add(); }
|
void Add_(void) { CPhysical::Add(); }
|
||||||
void Remove_(void) { CPhysical::Remove(); }
|
void Remove_(void) { CPhysical::Remove(); }
|
||||||
CRect GetBoundRect_(void) { return CPhysical::GetBoundRect(); }
|
CRect GetBoundRect_(void) { return CPhysical::GetBoundRect(); }
|
||||||
void ProcessControl_(void) { CPhysical::ProcessControl(); }
|
void ProcessControl_(void) { CPhysical::ProcessControl(); }
|
||||||
|
void ProcessShift_(void) { CPhysical::ProcessShift(); }
|
||||||
|
void ProcessCollision_(void) { CPhysical::ProcessCollision(); }
|
||||||
int32 ProcessEntityCollision_(CEntity *ent, CColPoint *point) { return CPhysical::ProcessEntityCollision(ent, point); }
|
int32 ProcessEntityCollision_(CEntity *ent, CColPoint *point) { return CPhysical::ProcessEntityCollision(ent, point); }
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CPhysical) == 0x128, "CPhysical: error");
|
static_assert(sizeof(CPhysical) == 0x128, "CPhysical: error");
|
||||||
|
@ -14,7 +14,40 @@ public:
|
|||||||
CPed *pPassengers[8];
|
CPed *pPassengers[8];
|
||||||
uint8 stuff2[24];
|
uint8 stuff2[24];
|
||||||
CEntity *m_pCurSurface;
|
CEntity *m_pCurSurface;
|
||||||
uint8 stuff3[160];
|
uint8 stuff3[17];
|
||||||
|
uint8 m_veh_flagA1 : 1;
|
||||||
|
uint8 m_veh_flagA2 : 1;
|
||||||
|
uint8 m_veh_flagA4 : 1;
|
||||||
|
uint8 m_veh_flagA8 : 1;
|
||||||
|
uint8 m_veh_flagA10 : 1;
|
||||||
|
uint8 m_veh_flagA20 : 1;
|
||||||
|
uint8 m_veh_flagA40 : 1;
|
||||||
|
uint8 m_veh_flagA80 : 1;
|
||||||
|
uint8 m_veh_flagB1 : 1;
|
||||||
|
uint8 m_veh_flagB2 : 1;
|
||||||
|
uint8 m_veh_flagB4 : 1;
|
||||||
|
uint8 m_veh_flagB8 : 1;
|
||||||
|
uint8 m_veh_flagB10 : 1;
|
||||||
|
uint8 m_veh_flagB20 : 1;
|
||||||
|
uint8 m_veh_flagB40 : 1;
|
||||||
|
uint8 m_veh_flagB80 : 1;
|
||||||
|
uint8 m_veh_flagC1 : 1;
|
||||||
|
uint8 m_veh_flagC2 : 1;
|
||||||
|
uint8 m_veh_flagC4 : 1;
|
||||||
|
uint8 m_veh_flagC8 : 1;
|
||||||
|
uint8 m_veh_flagC10 : 1;
|
||||||
|
uint8 m_veh_flagC20 : 1;
|
||||||
|
uint8 m_veh_flagC40 : 1;
|
||||||
|
uint8 m_veh_flagC80 : 1;
|
||||||
|
uint8 m_veh_flagD1 : 1;
|
||||||
|
uint8 m_veh_flagD2 : 1;
|
||||||
|
uint8 m_veh_flagD4 : 1;
|
||||||
|
uint8 m_veh_flagD8 : 1;
|
||||||
|
uint8 m_veh_flagD10 : 1;
|
||||||
|
uint8 m_veh_flagD20 : 1;
|
||||||
|
uint8 m_veh_flagD40 : 1;
|
||||||
|
uint8 m_veh_flagD80 : 1;
|
||||||
|
uint8 stuff4[139];
|
||||||
int32 m_vehType;
|
int32 m_vehType;
|
||||||
|
|
||||||
bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; }
|
bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; }
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
this->z /= t;
|
this->z /= t;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
bool IsZero(void) { return x == 0.0f && y == 0.0f && z == 0.0f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline float
|
inline float
|
||||||
|
@ -203,9 +203,14 @@ enum
|
|||||||
MI_FATFEMALE01,
|
MI_FATFEMALE01,
|
||||||
MI_FATFEMALE02,
|
MI_FATFEMALE02,
|
||||||
|
|
||||||
|
MI_PREDATOR = 120,
|
||||||
MI_RHINO = 122,
|
MI_RHINO = 122,
|
||||||
|
MI_TRAIN = 124,
|
||||||
MI_COACH = 127,
|
MI_COACH = 127,
|
||||||
MI_RCBANDIT = 131,
|
MI_RCBANDIT = 131,
|
||||||
|
MI_SPEEDER = 142,
|
||||||
|
MI_REEFER = 143,
|
||||||
|
MI_GHOST = 150,
|
||||||
|
|
||||||
MI_CAR_DOOR = 190,
|
MI_CAR_DOOR = 190,
|
||||||
MI_CAR_BUMPER,
|
MI_CAR_BUMPER,
|
||||||
@ -248,3 +253,13 @@ IsBodyPart(int16 id)
|
|||||||
{
|
{
|
||||||
return id == MI_BODYPARTA || id == MI_BODYPARTB;
|
return id == MI_BODYPARTA || id == MI_BODYPARTB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is bad and should perhaps not be used
|
||||||
|
inline bool
|
||||||
|
IsBoatModel(int16 id)
|
||||||
|
{
|
||||||
|
return id == MI_PREDATOR ||
|
||||||
|
id == MI_REEFER ||
|
||||||
|
id == MI_SPEEDER ||
|
||||||
|
id == MI_GHOST;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user