summaryrefslogtreecommitdiffstats
path: root/src/entities/Physical.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/entities/Physical.cpp80
1 files changed, 63 insertions, 17 deletions
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 172bae3f..ed01297e 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -16,6 +16,7 @@
#include "DMAudio.h"
#include "Automobile.h"
#include "Physical.h"
+#include "Bike.h"
CPhysical::CPhysical(void)
{
@@ -302,14 +303,15 @@ CPhysical::GetHasCollidedWith(CEntity *ent)
void
CPhysical::RemoveRefsToEntity(CEntity *ent)
{
- int i, j;
+ int i = 0, j;
- for(i = 0; i < m_nCollisionRecords; i++){
+ while(i < m_nCollisionRecords) {
if(m_aCollisionRecords[i] == ent){
for(j = i; j < m_nCollisionRecords-1; j++)
m_aCollisionRecords[j] = m_aCollisionRecords[j+1];
m_nCollisionRecords--;
- }
+ } else
+ i++;
}
}
@@ -517,13 +519,12 @@ CPhysical::ApplyAirResistance(void)
m_vecMoveSpeed *= f;
m_vecTurnSpeed *= f;
}else{
- float f = Pow(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep());
+ float f = Pow(1.0f/Abs(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep());
m_vecMoveSpeed *= f;
m_vecTurnSpeed *= 0.99f;
}
}
-
bool
CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, float &impulseB)
{
@@ -782,9 +783,13 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(B->GetStatus() == STATUS_PLAYER)
pointposB *= 0.8f;
if(CWorld::bNoMoreCollisionTorque){
- // BUG: the game actually uses A here, but this can't be right
+#ifdef FIX_BUGS
B->ApplyFrictionMoveForce(fB*-0.3f);
B->ApplyFrictionTurnForce(fB*-0.3f, pointposB);
+#else
+ A->ApplyFrictionMoveForce(fB*-0.3f);
+ A->ApplyFrictionTurnForce(fB*-0.3f, pointposB);
+#endif
}
}
if(!A->bInfiniteMass){
@@ -824,7 +829,7 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV
normalSpeed = DotProduct(speed, colpoint.normal);
if(normalSpeed < 0.0f){
float minspeed = 1.3f*GRAVITY * CTimer::GetTimeStep();
-#ifdef GTA3_1_1_PATCH
+#if GTA_VERSION >= GTA3_PC_11
if ((IsObject() || IsVehicle() && (GetUp().z < -0.3f || ((CVehicle*)this)->IsBike() && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED))) &&
#else
if((IsObject() || IsVehicle() && GetUp().z < -0.3f) &&
@@ -880,14 +885,24 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint)
fOtherSpeedA = vOtherSpeedA.Magnitude();
fOtherSpeedB = vOtherSpeedB.Magnitude();
+#ifdef FIX_BUGS // division by 0
+ frictionDir = vOtherSpeedA;
+ frictionDir.Normalise();
+#else
frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA);
+#endif
+
speedSum = (B->m_fMass*fOtherSpeedB + A->m_fMass*fOtherSpeedA)/(B->m_fMass + A->m_fMass);
if(fOtherSpeedA > speedSum){
impulseA = (speedSum - fOtherSpeedA) * A->m_fMass;
impulseB = (speedSum - fOtherSpeedB) * B->m_fMass;
impulseLimit = adhesiveLimit*CTimer::GetTimeStep();
if(impulseA < -impulseLimit) impulseA = -impulseLimit;
- if(impulseB > impulseLimit) impulseB = impulseLimit; // BUG: game has A's clamp again here, but this can't be right
+#ifdef FIX_BUGS
+ if(impulseB > impulseLimit) impulseB = impulseLimit;
+#else
+ if(impulseA < -impulseLimit) impulseA = -impulseLimit; // duplicate
+#endif
A->ApplyFrictionMoveForce(frictionDir*impulseA);
B->ApplyFrictionMoveForce(frictionDir*impulseB);
return true;
@@ -906,7 +921,12 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint)
fOtherSpeedA = vOtherSpeedA.Magnitude();
fOtherSpeedB = vOtherSpeedB.Magnitude();
+#ifdef FIX_BUGS // division by 0
+ frictionDir = vOtherSpeedA;
+ frictionDir.Normalise();
+#else
frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA);
+#endif
float massB = B->GetMass(pointposB, frictionDir);
speedSum = (massB*fOtherSpeedB + A->m_fMass*fOtherSpeedA)/(massB + A->m_fMass);
if(fOtherSpeedA > speedSum){
@@ -934,7 +954,12 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint)
fOtherSpeedA = vOtherSpeedA.Magnitude();
fOtherSpeedB = vOtherSpeedB.Magnitude();
+#ifdef FIX_BUGS // division by 0
+ frictionDir = vOtherSpeedA;
+ frictionDir.Normalise();
+#else
frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA);
+#endif
float massA = A->GetMass(pointposA, frictionDir);
speedSum = (B->m_fMass*fOtherSpeedB + massA*fOtherSpeedA)/(B->m_fMass + massA);
if(fOtherSpeedA > speedSum){
@@ -962,7 +987,12 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint)
fOtherSpeedA = vOtherSpeedA.Magnitude();
fOtherSpeedB = vOtherSpeedB.Magnitude();
+#ifdef FIX_BUGS // division by 0
+ frictionDir = vOtherSpeedA;
+ frictionDir.Normalise();
+#else
frictionDir = vOtherSpeedA * (1.0f/fOtherSpeedA);
+#endif
float massA = A->GetMass(pointposA, frictionDir);
float massB = B->GetMass(pointposB, frictionDir);
speedSum = (massB*fOtherSpeedB + massA*fOtherSpeedA)/(massB + massA);
@@ -999,7 +1029,12 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint)
fOtherSpeed = vOtherSpeed.Magnitude();
if(fOtherSpeed > 0.0f){
+#ifdef FIX_BUGS // division by 0
+ frictionDir = vOtherSpeed;
+ frictionDir.Normalise();
+#else
frictionDir = vOtherSpeed * (1.0f/fOtherSpeed);
+#endif
// not really impulse but speed
// maybe use ApplyFrictionMoveForce instead?
fImpulse = -fOtherSpeed;
@@ -1017,9 +1052,14 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint)
fOtherSpeed = vOtherSpeed.Magnitude();
if(fOtherSpeed > 0.0f){
+#ifdef FIX_BUGS // division by 0
+ frictionDir = vOtherSpeed;
+ frictionDir.Normalise();
+#else
frictionDir = vOtherSpeed * (1.0f/fOtherSpeed);
+#endif
fImpulse = -fOtherSpeed * m_fMass;
- impulseLimit = adhesiveLimit*CTimer::GetTimeStep() * 1.5f;
+ impulseLimit = adhesiveLimit*CTimer::GetTimeStep() * 1.5;
if(fImpulse < -impulseLimit) fImpulse = -impulseLimit;
ApplyFrictionMoveForce(frictionDir*fImpulse);
ApplyFrictionTurnForce(frictionDir*fImpulse, pointpos);
@@ -1052,7 +1092,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
int numCollisions;
int mostColliding;
CColPoint colpoints[MAX_COLLISION_POINTS];
- CVector shift = { 0.0f, 0.0f, 0.0f };
+ CVector shift = CVector(0.0f, 0.0f, 0.0f);
bool doShift = false;
CEntity *boat = nil;
@@ -1110,7 +1150,8 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
skipShift = true;
Aobj->m_pCollidingEntity = B;
}
- }
+ } else
+ skipShift = true;
}else if(B->IsObject() && A->IsVehicle()){
CObject *Bobj = (CObject*)B;
if(Bobj->ObjectCreatedBy != TEMP_OBJECT &&
@@ -1125,7 +1166,8 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
if(size.z < A->GetPosition().z ||
(Invert(A->GetMatrix(), inv) * size).z < 0.0f)
skipShift = true;
- }
+ } else
+ skipShift = true;
}else if(IsBodyPart(A->GetModelIndex()) && B->IsPed())
skipShift = true;
else if(A->IsPed() && IsBodyPart(B->GetModelIndex()))
@@ -1497,8 +1539,8 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
if(numCollisions <= 0)
continue;
- CVector moveSpeed = { 0.0f, 0.0f, 0.0f };
- CVector turnSpeed = { 0.0f, 0.0f, 0.0f };
+ CVector moveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ CVector turnSpeed = CVector(0.0f, 0.0f, 0.0f);
numResponses = 0;
if(A->bHasContacted){
for(i = 0; i < numCollisions; i++){
@@ -1857,8 +1899,8 @@ CPhysical::ProcessCollision(void)
}else if(IsObject()){
int responsecase = ((CObject*)this)->m_nSpecialCollisionResponseCases;
if(responsecase == COLLRESPONSE_LAMPOST){
- CVector speedUp = { 0.0f, 0.0f, 0.0f };
- CVector speedDown = { 0.0f, 0.0f, 0.0f };
+ CVector speedUp = CVector(0.0f, 0.0f, 0.0f);
+ CVector speedDown = CVector(0.0f, 0.0f, 0.0f);
speedUp.z = GetBoundRadius();
speedDown.z = -speedUp.z;
speedUp = Multiply3x3(GetMatrix(), speedUp);
@@ -1917,7 +1959,11 @@ CPhysical::ProcessCollision(void)
car->m_aSuspensionSpringRatio[2] = 1.0f;
car->m_aSuspensionSpringRatio[3] = 1.0f;
}else if(veh->m_vehType == VEHICLE_TYPE_BIKE){
- assert(0 && "TODO - but unused");
+ CBike* bike = (CBike*)this;
+ bike->m_aSuspensionSpringRatio[0] = 1.0f;
+ bike->m_aSuspensionSpringRatio[1] = 1.0f;
+ bike->m_aSuspensionSpringRatio[2] = 1.0f;
+ bike->m_aSuspensionSpringRatio[3] = 1.0f;
}
}
}