initial work on vehicles

This commit is contained in:
aap 2021-01-16 19:38:05 +01:00
parent d1b2dd2831
commit a672860c40
18 changed files with 674 additions and 617 deletions

View File

@ -76,7 +76,7 @@
GlobalScene Scene;
uint8 work_buff[55000];
uint8 work_buff[102400];
char gString[256];
char gString2[512];
wchar gUString[256];

View File

@ -7,7 +7,7 @@ struct GlobalScene
};
extern GlobalScene Scene;
extern uint8 work_buff[55000];
extern uint8 work_buff[102400];
extern char gString[256];
extern char gString2[512];
extern wchar gUString[256];

View File

@ -24,11 +24,11 @@ enum eEntityStatus
STATUS_PHYSICS,
STATUS_ABANDONED,
STATUS_WRECKED,
STATUS_TRAIN_MOVING,
STATUS_TRAIN_MOVING, // these probably copied for FERRY
STATUS_TRAIN_NOT_MOVING,
STATUS_HELI,
STATUS_PLANE,
STATUS_PLAYER_REMOTE,
STATUS_PLAYER_REMOTE, // 12 in LCS
STATUS_PLAYER_DISABLED,
STATUS_GHOST
};

View File

@ -21,11 +21,7 @@
#include "Pickups.h"
#include "Physical.h"
//--MIAMI: file done
#ifdef WALLCLIMB_CHEAT
bool gGravityCheat;
#endif
CPhysical::CPhysical(void)
@ -359,7 +355,7 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
return numSpheres;
}
// --MIAMI: Proof-read once
//--LCS: done
void
CPhysical::ProcessControl(void)
{
@ -427,7 +423,7 @@ CPhysical::GetSpeed(const CVector &r)
return m_vecMoveSpeed + m_vecMoveFriction + CrossProduct(m_vecTurnFriction + m_vecTurnSpeed, r);
}
// --MIAMI: Proof-read once
//--LCS: done
void
CPhysical::ApplyMoveSpeed(void)
{
@ -437,13 +433,13 @@ CPhysical::ApplyMoveSpeed(void)
GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep());
}
// --MIAMI: Proof-read once
//--LCS: done
void
CPhysical::ApplyTurnSpeed(void)
{
if(bIsFrozen){
m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
}else{
}else if(!m_vecTurnSpeed.IsZero()){
// Move the coordinate axes by their speed
// Note that this denormalizes the matrix
CVector turnvec = m_vecTurnSpeed*CTimer::GetTimeStep();
@ -453,29 +449,36 @@ CPhysical::ApplyTurnSpeed(void)
}
}
// --MIAMI: Proof-read once
//--LCS: done
void
CPhysical::ApplyMoveForce(float jx, float jy, float jz)
{
m_vecMoveSpeed += CVector(jx, jy, jz)*(1.0f/m_fMass);
m_vecTurnSpeed.x = clamp(m_vecTurnSpeed.x, -4.0f, 4.0f);
m_vecTurnSpeed.y = clamp(m_vecTurnSpeed.y, -4.0f, 4.0f);
m_vecTurnSpeed.z = clamp(m_vecTurnSpeed.z, -4.0f, 4.0f);
}
// --MIAMI: Proof-read once
//--LCS: done
void
CPhysical::ApplyTurnForce(float jx, float jy, float jz, float px, float py, float pz)
{
CVector com = Multiply3x3(m_matrix, m_vecCentreOfMass);
CVector turnimpulse = CrossProduct(CVector(px, py, pz)-com, CVector(jx, jy, jz));
m_vecTurnSpeed += turnimpulse*(1.0f/m_fTurnMass);
m_vecTurnSpeed.x = clamp(m_vecTurnSpeed.x, -4.0f, 4.0f);
m_vecTurnSpeed.y = clamp(m_vecTurnSpeed.y, -4.0f, 4.0f);
m_vecTurnSpeed.z = clamp(m_vecTurnSpeed.z, -4.0f, 4.0f);
}
//--LCS: done
void
CPhysical::ApplyFrictionMoveForce(float jx, float jy, float jz)
{
m_vecMoveFriction += CVector(jx, jy, jz)*(1.0f/m_fMass);
}
// --MIAMI: Proof-read once
//--LCS: done
void
CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float py, float pz)
{
@ -484,7 +487,7 @@ CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float
m_vecTurnFriction += turnimpulse*(1.0f/m_fTurnMass);
}
// --MIAMI: Proof-read once
//--LCS: done
bool
CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias)
{
@ -498,16 +501,16 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &
return true;
}
// --MIAMI: Proof-read once
//--LCS: done
bool
CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir)
CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir, float &impulse)
{
float compression = 1.0f - springRatio;
if(compression > 0.0f){
if(DotProduct(springDir, forceDir) > 0.0f)
forceDir *= -1.0f;
float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = GRAVITY*m_fMass*step * springConst * compression * bias*2.0f;
impulse = GRAVITY*m_fMass*step * springConst * compression * bias*2.0f;
if(bIsHeavy)
impulse *= 0.75f;
ApplyMoveForce(forceDir*impulse);
@ -516,58 +519,75 @@ CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVecto
return true;
}
// --MIAMI: Proof-read once
float DAMPING_LIMIT_OF_SPRING_FORCE = 0.999f;
float DAMPING_LIMIT_IN_FRAME= 0.25f;
//--LCS: done
// What exactly is speed?
bool
CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed)
CPhysical::ApplySpringDampening(float damping, float dampingLimit, CVector &springDir, CVector &point, CVector &speed)
{
float speedA = DotProduct(speed, springDir);
float speedB = DotProduct(GetSpeed(point), springDir);
float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f;
damping *= step;
if(bIsHeavy)
impulse *= 2.0f;
damping *= 2.0f;
damping = clamp(damping, -DAMPING_LIMIT_IN_FRAME, DAMPING_LIMIT_IN_FRAME);
// what is this?
float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass);
a = Min(a, 1.0f);
float b = Abs(impulse / (speedB * m_fMass));
if(a < b)
impulse *= a/b;
float fSpeed = -speedA * damping;
if(fSpeed > 0.0f && fSpeed+speedB > 0.0f){
if(speedB < 0.0f)
fSpeed = -speedB;
else
fSpeed = 0.0f;
}else if(fSpeed < 0.0f && fSpeed+speedB < 0.0f){
if(speedB > 0.0f)
fSpeed = -speedB;
else
fSpeed = 0.0f;
}
CVector com = Multiply3x3(m_matrix, m_vecCentreOfMass);
float impulse = fSpeed*GetMass(point-com, springDir);
float limit = Abs(dampingLimit)*DAMPING_LIMIT_OF_SPRING_FORCE;
if(impulse > limit)
impulse = limit;
ApplyMoveForce(springDir*impulse);
ApplyTurnForce(springDir*impulse, point);
return true;
}
//--LCS: done
void
CPhysical::ApplyGravity(void)
{
if (!bAffectedByGravity)
return;
#ifdef WALLCLIMB_CHEAT
if (gGravityCheat && this == FindPlayerVehicle()) {
static CVector v1(0.0f, 0.0f, 1.0f), v2(0.0f, 0.0f, 1.0f);
CVector prop = GetPosition() - (GetUp() + GetUp());
static CVector gravityUp(0.0f, 0.0f, 1.0f), surfaceUp(0.0f, 0.0f, 1.0f);
CVector belowCar = GetPosition() - 2.0f*GetUp();
CColPoint point;
CEntity* entity;
if (CWorld::ProcessLineOfSight(GetPosition(), prop, point, entity, true, false, false, false, false, false))
v2 = point.normal;
if (CWorld::ProcessLineOfSight(GetPosition(), belowCar, point, entity, true, false, false, false, false, false))
surfaceUp = point.normal;
else
v2 = CVector(0.0f, 0.0f, 1.0f);
float coef = clamp(CTimer::GetTimeStep() * 0.5f, 0.05f, 0.8f);
v1 = v1 * (1.0f - coef) + v2 * coef;
if (v1.MagnitudeSqr() < 0.1f)
v1 = CVector(0.0f, 0.0f, 1.0f);
surfaceUp = CVector(0.0f, 0.0f, 1.0f);
float t = clamp(CTimer::GetTimeStep() * 0.5f, 0.05f, 0.8f);
gravityUp = gravityUp * (1.0f - t) + surfaceUp * t;
if (gravityUp.MagnitudeSqr() < 0.1f)
gravityUp = CVector(0.0f, 0.0f, 1.0f);
else
v1.Normalise();
m_vecMoveSpeed -= GRAVITY * CTimer::GetTimeStep() * v1;
gravityUp.Normalise();
m_vecMoveSpeed -= GRAVITY * CTimer::GetTimeStep() * gravityUp;
return;
}
#endif
m_vecMoveSpeed.z -= GRAVITY * CTimer::GetTimeStep();
}
//--LCS: done
void
CPhysical::ApplyFriction(void)
{
@ -577,7 +597,7 @@ CPhysical::ApplyFriction(void)
m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
}
// --MIAMI: Proof-read once
//--LCS: done
void
CPhysical::ApplyAirResistance(void)
{
@ -585,8 +605,8 @@ CPhysical::ApplyAirResistance(void)
float f = Pow(m_fAirResistance, CTimer::GetTimeStep());
m_vecMoveSpeed *= f;
m_vecTurnSpeed *= f;
}else if(GetStatus() != STATUS_GHOST){
float f = Pow(1.0f/Abs(1.0f + m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr()), CTimer::GetTimeStep());
}else{
float f = Pow(1.0f - m_fAirResistance*m_vecMoveSpeed.Magnitude(), CTimer::GetTimeStep());
m_vecMoveSpeed *= f;
m_vecTurnSpeed *= 0.99f;
}
@ -2310,3 +2330,44 @@ CPhysical::ProcessCollision(void)
m_fElasticity = savedElasticity;
RemoveAndAdd();
}
// TEMP old VC code until bikes are done
bool
CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir)
{
float compression = 1.0f - springRatio;
if(compression > 0.0f){
if(DotProduct(springDir, forceDir) > 0.0f)
forceDir *= -1.0f;
float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = GRAVITY*m_fMass*step * springConst * compression * bias*2.0f;
if(bIsHeavy)
impulse *= 0.75f;
ApplyMoveForce(forceDir*impulse);
ApplyTurnForce(forceDir*impulse, point);
}
return true;
}
bool
CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed)
{
float speedA = DotProduct(speed, springDir);
float speedB = DotProduct(GetSpeed(point), springDir);
float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f;
if(bIsHeavy)
impulse *= 2.0f;
// what is this?
float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass);
a = Min(a, 1.0f);
float b = Abs(impulse / (speedB * m_fMass));
if(a < b)
impulse *= a/b;
ApplyMoveForce(springDir*impulse);
ApplyTurnForce(springDir*impulse, point);
return true;
}

View File

@ -158,8 +158,8 @@ public:
void ApplyFrictionTurnForce(const CVector &j, const CVector &p) { ApplyFrictionTurnForce(j.x, j.y, j.z, p.x, p.y, p.z); }
// springRatio: 1.0 fully extended, 0.0 fully compressed
bool ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias);
bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir);
bool ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed);
bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir, float &impulse);
bool ApplySpringDampening(float damping, float dampingLimit, CVector &springDir, CVector &point, CVector &speed);
void ApplyGravity(void);
void ApplyFriction(void);
void ApplyAirResistance(void);
@ -174,4 +174,8 @@ public:
bool ProcessCollisionSectorList(CPtrList *lists);
bool CheckCollision(void);
bool CheckCollision_SimpleCar(void);
// TEMP
bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir);
bool ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed);
};

View File

@ -3,8 +3,8 @@
#include "ClumpModelInfo.h"
enum {
NUM_FIRST_MATERIALS = 24,
NUM_SECOND_MATERIALS = 20,
NUM_FIRST_MATERIALS = 25,
NUM_SECOND_MATERIALS = 25,
NUM_VEHICLE_COLOURS = 8,
};
@ -98,7 +98,7 @@ public:
uint8 m_lastColorVariation;
uint8 m_currentColour1;
uint8 m_currentColour2;
RpAtomic *m_comps[6];
RpAtomic *m_comps[6]; // LCS(TODO): pointer
// This is stupid, CClumpModelInfo already has it!
union {
int32 m_animFileIndex;

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@ public:
float m_aSuspensionSpringRatioPrev[4];
float m_aWheelTimer[4]; // set to 4.0 when wheel is touching ground, then decremented
float m_auto_unused1;
float m_fEngineInertiaVar1;
float m_fEngineInertiaVar2;
eSkidmarkType m_aWheelSkidmarkType[4];
bool m_aWheelSkidmarkBloody[4];
bool m_aWheelSkidmarkUnk[4];
@ -114,6 +116,7 @@ public:
float GetHeightAboveRoad(void);
void PlayCarHorn(void);
void ProcessCarWheelPair(int leftWheel, int rightWheel, float steerAngle, CVector *contactSpeeds, CVector *contactPoints, float traction, float acceleration, float brake, bool bFront);
void FireTruckControl(void);
void TankControl(void);
void HydraulicControl(void);

View File

@ -111,7 +111,7 @@ CBike::CBike(int32 id, uint8 CreatedBy)
m_fTurnMass = pHandling->fTurnMass;
m_vecCentreOfMass = pHandling->CentreOfMass;
m_vecCentreOfMass.z = 0.1f;
m_fAirResistance = pHandling->Dimension.x*pHandling->Dimension.z/m_fMass;
m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult;
m_fElasticity = 0.05f;
m_fBuoyancy = pHandling->fBuoyancy;

View File

@ -72,7 +72,7 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
m_fMass = pHandling->fMass;
m_fTurnMass = pHandling->fTurnMass / 2.0f;
m_vecCentreOfMass = pHandling->CentreOfMass;
m_fAirResistance = pHandling->Dimension.x * pHandling->Dimension.z / m_fMass;
m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult;
m_fElasticity = 0.1f;
m_fBuoyancy = pHandling->fBuoyancy;
m_fSteerAngle = 0.0f;

View File

@ -10,7 +10,8 @@ float G_aComponentDamage[] = { 2.5f, 1.25f, 3.2f, 1.4f, 2.5f, 2.8f, 0.5f };
CDamageManager::CDamageManager(void)
{
ResetDamageStatus();
m_fWheelDamageEffect = 0.5f;
m_fWheelDamageEffect = 0.65f;
m_bSmashedDoorDoesntClose = false;
field_18 = 1;
}
@ -136,6 +137,8 @@ void
CDamageManager::SetDoorStatus(int32 door, uint32 status)
{
m_doorStatus[door] = status;
if(m_bSmashedDoorDoesntClose && door != DOOR_BONNET && status == DOOR_STATUS_SMASHED)
m_doorStatus[door] = DOOR_STATUS_SWINGING;
}
int32

View File

@ -81,6 +81,7 @@ class CDamageManager
public:
float m_fWheelDamageEffect;
bool m_bSmashedDoorDoesntClose;
uint8 m_engineStatus;
uint8 m_wheelStatus[4];
uint8 m_doorStatus[6];

View File

@ -115,18 +115,17 @@ void
cHandlingDataMgr::LoadHandlingData(void)
{
char *start, *end;
char line[201]; // weird value
char line[300];
char delim[4]; // not sure
char *word;
int field, handlingId;
int keepGoing;
tHandlingData *handling;
tFlyingHandlingData *flyingHandling;
tBoatHandlingData *boatHandling;
tBikeHandlingData *bikeHandling;
CFileMgr::SetDir("DATA");
CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r");
ssize_t filesz = CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r");
CFileMgr::SetDir("");
start = (char*)work_buff;
@ -135,21 +134,18 @@ cHandlingDataMgr::LoadHandlingData(void)
flyingHandling = nil;
boatHandling = nil;
bikeHandling = nil;
keepGoing = 1;
while(keepGoing){
while(start < (char*)&work_buff[filesz]){
// find end of line
while(*end != '\n') end++;
// get line
strncpy(line, start, end - start);
line[end - start] = '\0';
start = end+1;
end = start+1;
// yeah, this is kinda crappy
if(strcmp(line, ";the end") == 0)
keepGoing = 0;
break;
else if(line[0] != ';'){
if(line[0] == '!'){
// Bike data
@ -263,19 +259,19 @@ cHandlingDataMgr::LoadHandlingData(void)
handling->nIdentifier = (tVehicleType)handlingId;
break;
case 1: handling->fMass = atof(word); break;
case 2: handling->Dimension.x = atof(word); break;
case 3: handling->Dimension.y = atof(word); break;
case 4: handling->Dimension.z = atof(word); break;
case 5: handling->CentreOfMass.x = atof(word); break;
case 6: handling->CentreOfMass.y = atof(word); break;
case 7: handling->CentreOfMass.z = atof(word); break;
case 8: handling->nPercentSubmerged = atoi(word); break;
case 9: handling->fTractionMultiplier = atof(word); break;
case 10: handling->fTractionLoss = atof(word); break;
case 11: handling->fTractionBias = atof(word); break;
case 12: handling->Transmission.nNumberOfGears = atoi(word); break;
case 13: handling->Transmission.fMaxVelocity = atof(word); break;
case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4; break;
case 2: handling->fTurnMass = atof(word); break;
case 3: handling->fDragMult = atof(word); break;
case 4: handling->CentreOfMass.x = atof(word); break;
case 5: handling->CentreOfMass.y = atof(word); break;
case 6: handling->CentreOfMass.z = atof(word); break;
case 7: handling->nPercentSubmerged = atoi(word); break;
case 8: handling->fTractionMultiplier = atof(word); break;
case 9: handling->fTractionLoss = atof(word); break;
case 10: handling->fTractionBias = atof(word); break;
case 11: handling->Transmission.nNumberOfGears = atoi(word); break;
case 12: handling->Transmission.fMaxVelocity = atof(word); break;
case 13: handling->Transmission.fEngineAcceleration = atof(word) * 0.4; break;
case 14: handling->Transmission.fEngineInertia = atof(word); break;
case 15: handling->Transmission.nDriveType = word[0]; break;
case 16: handling->Transmission.nEngineType = word[0]; break;
case 17: handling->fBrakeDeceleration = atof(word); break;
@ -284,25 +280,28 @@ cHandlingDataMgr::LoadHandlingData(void)
case 20: handling->fSteeringLock = atof(word); break;
case 21: handling->fSuspensionForceLevel = atof(word); break;
case 22: handling->fSuspensionDampingLevel = atof(word); break;
case 23: handling->fSeatOffsetDistance = atof(word); break;
case 24: handling->fCollisionDamageMultiplier = atof(word); break;
case 25: handling->nMonetaryValue = atoi(word); break;
case 26: handling->fSuspensionUpperLimit = atof(word); break;
case 27: handling->fSuspensionLowerLimit = atof(word); break;
case 28: handling->fSuspensionBias = atof(word); break;
case 29: handling->fSuspensionAntidiveMultiplier = atof(word); break;
case 30:
// case 23: // fSuspensionHighSpdComDamp unused
case 24: handling->fSuspensionUpperLimit = atof(word); break;
case 25: handling->fSuspensionLowerLimit = atof(word); break;
case 26: handling->fSuspensionBias = atof(word); break;
case 27: handling->fSuspensionAntidiveMultiplier = atof(word); break;
case 28: handling->fSeatOffsetDistance = atof(word); break;
case 29: handling->fCollisionDamageMultiplier = atof(word); break;
case 30: handling->nMonetaryValue = atoi(word); break;
case 31:
sscanf(word, "%x", &handling->Flags);
handling->Transmission.Flags = handling->Flags;
// handling->Transmission.Flags = handling->Flags;
break;
case 31: handling->FrontLights = atoi(word); break;
case 32: handling->RearLights = atoi(word); break;
case 32: handling->FrontLights = atoi(word); break;
case 33: handling->RearLights = atoi(word); break;
}
field++;
}
ConvertDataToGameUnits(handling);
}
}
start = end+1;
end = start+1;
}
}
@ -330,12 +329,9 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
handling->Transmission.fEngineAcceleration *= 1.0f/(50.0f*50.0f);
handling->Transmission.fMaxVelocity *= 1000.0f/(60.0f*60.0f * 50.0f);
handling->fBrakeDeceleration *= 1.0f/(50.0f*50.0f);
handling->fTurnMass = (sq(handling->Dimension.x) + sq(handling->Dimension.y)) * handling->fMass / 12.0f;
if(handling->fTurnMass < 10.0f)
handling->fTurnMass *= 5.0f;
handling->fInvMass = 1.0f/handling->fMass;
handling->fCollisionDamageMultiplier *= 2000.0f/handling->fMass;
handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * GRAVITY*handling->fMass;
handling->fInvMass = 1.0f/handling->GetMass();
handling->fCollisionDamageMultiplier = handling->GetCollisionDamageMultiplier() * 2000.0f/handling->GetMass();
handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * GRAVITY*handling->GetMass();
// Don't quite understand this. What seems to be going on is that
// we calculate a drag (air resistance) deceleration for a given velocity and
@ -348,10 +344,13 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
velocity -= 0.01f;
// what's the 1/6?
a = handling->Transmission.fEngineAcceleration/6.0f;
// no density or drag coefficient here...
float a_drag = 0.5f*SQR(velocity) * handling->Dimension.x*handling->Dimension.z / handling->fMass;
// can't make sense of this... maybe v - v/(drag + 1) ? but that doesn't make so much sense either
b = -velocity * (1.0f/(a_drag + 1.0f) - 1.0f);
// no idea what's happening here
float drag;
if(handling->fDragMult < 0.01f)
drag = 1.0f - 1.0f/(SQR(velocity)*handling->fDragMult + 1.0f);
else
drag = 0.0005f*handling->fDragMult * velocity;
b = velocity * drag;
}
if(handling->nIdentifier == HANDLING_RCBANDIT){

View File

@ -93,7 +93,7 @@ enum tVehicleType
NUMBIKEHANDLINGS = HANDLING_FREEWAY+1 - HANDLING_BIKE,
NUMFLYINGHANDLINGS = HANDLING_RCCOPTER+1 - HANDLING_MAVERICK,
NUMBOATHANDLINGS = HANDLING_COASTMAV+1 - HANDLING_PREDATOR,
NUMBOATHANDLINGS = HANDLING_REEFER+1 - HANDLING_PREDATOR,
};
enum tField // most likely a handling field enum, never used so :shrug:
@ -131,19 +131,21 @@ enum
HANDLING_NARROW_FRONTW = 0x2000000,
HANDLING_GOOD_INSAND = 0x4000000,
HANDLING_UNKNOWN = 0x8000000, // something for helis and planes
HANDLING_FORCE_GRND_CLR = 0x10000000
};
struct tHandlingData
{
tVehicleType nIdentifier;
float fMass;
float fInvMass;
float fTurnMass;
CVector Dimension;
float fTractionMultiplier;
float fCollisionDamageMultiplier;
tVehicleType nIdentifier;
float fInvMass;
float fDragMult;
CVector CentreOfMass;
int8 nPercentSubmerged;
float fBuoyancy;
float fTractionMultiplier;
cTransmission Transmission;
float fBrakeDeceleration;
float fBrakeBias;
@ -158,12 +160,17 @@ struct tHandlingData
float fSuspensionLowerLimit;
float fSuspensionBias;
float fSuspensionAntidiveMultiplier;
float fCollisionDamageMultiplier;
uint32 Flags;
float fSeatOffsetDistance;
int32 nMonetaryValue;
int8 FrontLights;
int8 RearLights;
int unk[4];
float GetMass(void) const { return fMass; }
float GetTurnMass(void) const { return fTurnMass; }
float GetTractionMultiplier(void) const { return fTractionMultiplier; }
float GetCollisionDamageMultiplier(void) const { return fCollisionDamageMultiplier; }
};
struct tBikeHandlingData
@ -249,7 +256,7 @@ public:
tBikeHandlingData *GetBikePointer(uint8 id) { return &BikeHandlingData[id-HANDLING_BIKE]; }
tFlyingHandlingData *GetFlyingPointer(uint8 id);
tBoatHandlingData *GetBoatPointer(uint8 id);
bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'R'; }
bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'F'; }
bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'R'; }
};
extern cHandlingDataMgr mod_HandlingManager;

View File

@ -4,7 +4,7 @@
#include "HandlingMgr.h"
#include "Transmission.h"
//--MIAMI: done
//--LCS: file done
void
cTransmission::InitGearRatios(void)
@ -16,11 +16,14 @@ cTransmission::InitGearRatios(void)
memset(Gears, 0, sizeof(Gears));
float baseVelocity = 0.5f*fMaxVelocity / nNumberOfGears;
float step = (fMaxVelocity - baseVelocity) / nNumberOfGears;
for(i = 1; i <= nNumberOfGears; i++){
pGearRatio0 = &Gears[i-1];
pGearRatio1 = &Gears[i];
pGearRatio1->fMaxVelocity = (float)i / nNumberOfGears * fMaxVelocity;
pGearRatio1->fMaxVelocity = baseVelocity + i*step;
velocityDiff = pGearRatio1->fMaxVelocity - pGearRatio0->fMaxVelocity;
@ -47,9 +50,12 @@ cTransmission::CalculateGearForSimpleCar(float speed, uint8 &gear)
pGearRatio = &Gears[gear];
fCurVelocity = speed;
if(speed > pGearRatio->fShiftUpVelocity)
gear++;
else if(speed < pGearRatio->fShiftDownVelocity){
if(speed > pGearRatio->fShiftUpVelocity){
if(gear + 1 > nNumberOfGears)
gear = nNumberOfGears;
else
gear++;
}else if(speed < pGearRatio->fShiftDownVelocity){
if(gear - 1 < 0)
gear = 0;
else
@ -57,6 +63,110 @@ cTransmission::CalculateGearForSimpleCar(float speed, uint8 &gear)
}
}
float TRANSMISSION_NITROS_INERTIA_MULT = 0.5f;
float TRANSMISSION_AI_CHEAT_INERTIA_MULT = 0.75f;
float TRANSMISSION_NITROS_MULT = 2.0f;
float TRANSMISSION_AI_CHEAT_MULT = 1.2f;
float TRANSMISSION_SMOOTHER_FRAC = 0.85f;
float TRANSMISSION_FREE_ACCELERATION = 0.1f;
//--LCS: done
float
cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, float *inertiaVar1, float *inertiaVar2, uint8 nDriveWheels, uint8 cheat)
{
static float fAcceleration = 0.0f;
static float fVelocity;
static float fCheat;
static tGear *pGearRatio;
fVelocity = velocity;
if(fVelocity < fMaxReverseVelocity)
return 0.0f;
if(fVelocity > fMaxVelocity)
return 0.0f;
fCurVelocity = fVelocity;
assert(gear <= nNumberOfGears);
pGearRatio = &Gears[gear];
if(fVelocity > pGearRatio->fShiftUpVelocity){
if(gear != 0 || gasPedal > 0.0f){
gear++;
return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, nil, nil, 0, false);
}
}else if(fVelocity < pGearRatio->fShiftDownVelocity && gear != 0){
if(gear != 1 || gasPedal < 0.0f){
gear--;
return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, nil, nil, 0, false);
}
}
float accelMul;
if(nNumberOfGears == 1){
accelMul = 1.0f;
}else if(gear == 0){
accelMul = 4.5f;
}else{
float f = 1.0f - (gear-1.0f)/(nNumberOfGears-1.0f);
if(Flags & HANDLING_1G_BOOST)
accelMul = SQR(f)*5.0f + 1.0f;
else if(Flags & HANDLING_2G_BOOST)
accelMul = SQR(f)*4.0f + 1.0f;
else
accelMul = SQR(f)*3.0f + 1.0f;
}
fCheat = 1.0f;
float nitroMult = 1.0f;
if(cheat == 1)
fCheat = TRANSMISSION_AI_CHEAT_MULT;
else if(cheat == 2)
nitroMult = TRANSMISSION_NITROS_MULT;
fAcceleration = fEngineAcceleration*CTimer::GetTimeStep()*0.4f*accelMul*gasPedal*fCheat*nitroMult;
if(inertiaVar1 != nil && inertiaVar2 != nil){
if(nDriveWheels == 0){
float f = TRANSMISSION_FREE_ACCELERATION*CTimer::GetTimeStep()*Abs(gasPedal)/fEngineInertia;
*inertiaVar1 = Min(*inertiaVar1 + f, 1.0f);
*inertiaVar2 = 0.1f;
}else{
float var1;
// What is being calculated here?
// TODO: find better names for the inertia vars
if(gear == 0){
var1 = ((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) - fVelocity) /
((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) - Gears[gear].fShiftDownVelocity);
}else if(gear == 1){
var1 = ((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) + fVelocity) /
((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) + Gears[gear].fShiftUpVelocity);
}else{
var1 = (fVelocity - Gears[gear].fShiftDownVelocity) /
(Gears[gear].fShiftUpVelocity - Gears[gear].fShiftDownVelocity);
}
float inertiaMult = var1 - *inertiaVar1;
if(cheat == 1)
inertiaMult *= TRANSMISSION_AI_CHEAT_INERTIA_MULT;
else if(cheat == 2)
inertiaMult *= TRANSMISSION_NITROS_INERTIA_MULT;
float var2target = 1.0f - inertiaMult*fEngineInertia;
var2target = clamp(var2target, 0.1f, 1.0f);
*inertiaVar2 = (1.0f-TRANSMISSION_SMOOTHER_FRAC)*var2target + TRANSMISSION_SMOOTHER_FRAC*(*inertiaVar2);
*inertiaVar1 = var1;
fAcceleration *= *inertiaVar2;
}
}
float targetVelocity = Gears[gear].fMaxVelocity*fCheat;
if(Gears[gear].fMaxVelocity < 0.0f && targetVelocity > fVelocity)
fAcceleration *= 1.0f - Min((targetVelocity - fVelocity)/0.05f, 1.0f);
else if(Gears[gear].fMaxVelocity > 0.0f && targetVelocity < fVelocity)
fAcceleration *= 1.0f - Min((fVelocity - targetVelocity)/0.05f, 1.0f);
return fAcceleration;
}
// TEMP old VC code until we have bikes
float
cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, bool cheat)
{

View File

@ -17,6 +17,7 @@ public:
int8 nNumberOfGears;
uint8 Flags;
float fEngineAcceleration;
float fEngineInertia;
float fMaxVelocity;
float fMaxCruiseVelocity;
float fMaxReverseVelocity;
@ -24,5 +25,6 @@ public:
void InitGearRatios(void);
void CalculateGearForSimpleCar(float speed, uint8 &gear);
float CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, float *inertiaVar1, float *inertiaVar2, uint8 nDriveWheels, uint8 cheat);
float CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, bool cheat);
};

View File

@ -33,8 +33,6 @@
#include "Weather.h"
#include "Coronas.h"
//--MIAMI: done
bool CVehicle::bWheelsOnlyCheat;
bool CVehicle::bAllDodosCheat;
bool CVehicle::bCheat3;
@ -764,7 +762,9 @@ CVehicle::BladeColSectorList(CPtrList &list, CColModel &rotorColModel, CMatrix &
}
float fBurstSpeedMax = 0.3f;
float WS_ALREADY_SPINNING_LOSS = 0.2f;
float WS_TRAC_FRAC_LIMIT = 0.3f;
float fBurstSpeedMax = 0.2f;
float fBurstTyreMod = 0.13f;
void
@ -792,13 +792,15 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
float contactSpeedFwd = DotProduct(wheelContactSpeed, wheelFwd);
float contactSpeedRight = DotProduct(wheelContactSpeed, wheelRight);
if(*wheelState != WHEEL_STATE_NORMAL)
adhesion *= CTimer::GetTimeStep();
if(*wheelState != WHEEL_STATE_NORMAL){
bAlreadySkidding = true;
adhesion *= pHandling->fTractionLoss;
if(*wheelState == WHEEL_STATE_SPINNING && (GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_REMOTE))
adhesion *= 1.0f - Abs(m_fGasPedal) * WS_ALREADY_SPINNING_LOSS;
}
*wheelState = WHEEL_STATE_NORMAL;
adhesion *= CTimer::GetTimeStep();
if(bAlreadySkidding)
adhesion *= pHandling->fTractionLoss;
// moving sideways
if(contactSpeedRight != 0.0f){
@ -838,13 +840,15 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
if(!bBraking){
if(m_fGasPedal < 0.01f){
if(IsBike())
brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f);
else if(pHandling->fMass < 500.0f)
brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass;
brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->GetMass() + 200.0f);
else if(IsPlane())
brake = 0.0f;
else if(pHandling->GetMass() < 500.0f)
brake = 0.1f * mod_HandlingManager.fWheelFriction / pHandling->GetMass();
else if(GetModelIndex() == MI_RCBANDIT)
brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass;
brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->GetMass();
else
brake = mod_HandlingManager.fWheelFriction / pHandling->fMass;
brake = mod_HandlingManager.fWheelFriction / pHandling->GetMass();
#ifdef FIX_BUGS
brake *= CTimer::GetTimeStepFix();
#endif
@ -868,7 +872,10 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
float speedSq = sq(right) + sq(fwd);
if(sq(adhesion) < speedSq){
if(*wheelState != WHEEL_STATE_FIXED){
if(bDriving && contactSpeedFwd < 0.2f)
float tractionLimit = WS_TRAC_FRAC_LIMIT;
if(contactSpeedFwd > 0.15f && (wheelId == CARWHEEL_FRONT_LEFT || wheelId == CARWHEEL_FRONT_RIGHT))
tractionLimit *= 2.0f;
if(bDriving && tractionLimit*adhesion < Abs(fwd))
*wheelState = WHEEL_STATE_SPINNING;
else
*wheelState = WHEEL_STATE_SKIDDING;
@ -876,6 +883,8 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
float l = Sqrt(speedSq);
float tractionLoss = bAlreadySkidding ? 1.0f : pHandling->fTractionLoss;
if(*wheelState == WHEEL_STATE_SPINNING && (GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_REMOTE))
tractionLoss *= 1.0f - Abs(m_fGasPedal) * WS_ALREADY_SPINNING_LOSS;
right *= adhesion * tractionLoss / l;
fwd *= adhesion * tractionLoss / l;
}
@ -884,7 +893,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
CVector totalSpeed = fwd*wheelFwd + right*wheelRight;
CVector turnDirection = totalSpeed;
bool separateTurnForce = false; // BUG: not initialized on PC
bool separateTurnForce = false;
if(pHandling->fSuspensionAntidiveMultiplier > 0.0f){
if(bBraking){
separateTurnForce = true;
@ -921,6 +930,7 @@ float fBurstBikeSpeedMax = 0.12f;
float fBurstBikeTyreMod = 0.05f;
float fTweakBikeWheelTurnForce = 2.0f;
//--LCS: done
void
CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
int32 wheelsOnGround, float thrust, float brake, float adhesion, float destabTraction, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus)

View File

@ -250,6 +250,7 @@ public:
int8 m_nPacManPickupsCarried;
uint8 m_nRoadblockType;
float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode
float m_fEngineEnergy; // TODO(LCS): better name. it adds up acceleration force, so possibly kinetic energy??
uint8 m_nCurrentGear;
float m_fChangeGearTime;
#if (!defined GTA_PS2 || defined FIX_BUGS)
@ -288,6 +289,7 @@ public:
~CVehicle(void);
// from CEntity
void SetModelIndex(uint32 id);
void PreRender(void) {}
bool SetupLighting(void);
void RemoveLighting(bool);
void FlagToDestroyWhenNextProcessed(void) {}