#include "common.h" #include "Timer.h" #include "HandlingMgr.h" #include "Transmission.h" //--LCS: file done void cTransmission::InitGearRatios(void) { static tGear *pGearRatio0 = nil; static tGear *pGearRatio1 = nil; int i; float velocityDiff; 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 = baseVelocity + i*step; velocityDiff = pGearRatio1->fMaxVelocity - pGearRatio0->fMaxVelocity; if(i >= nNumberOfGears){ pGearRatio1->fShiftUpVelocity = fMaxVelocity; }else{ Gears[i+1].fShiftDownVelocity = velocityDiff*0.42f + pGearRatio0->fMaxVelocity; pGearRatio1->fShiftUpVelocity = velocityDiff*0.6667f + pGearRatio0->fMaxVelocity; } } // Reverse gear Gears[0].fMaxVelocity = fMaxReverseVelocity; Gears[0].fShiftUpVelocity = -0.01f; Gears[0].fShiftDownVelocity = fMaxReverseVelocity; Gears[1].fShiftDownVelocity = -0.01f; } void cTransmission::CalculateGearForSimpleCar(float speed, uint8 &gear) { static tGear *pGearRatio; pGearRatio = &Gears[gear]; fCurVelocity = speed; if(speed > pGearRatio->fShiftUpVelocity){ if(gear + 1 > nNumberOfGears) gear = nNumberOfGears; else gear++; }else if(speed < pGearRatio->fShiftDownVelocity){ if(gear - 1 < 0) gear = 0; else 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) { static float fAcceleration = 0.0f; static float fVelocity; static float fCheat; static tGear *pGearRatio; fVelocity = velocity; if(fVelocity < fMaxReverseVelocity){ fVelocity = fMaxReverseVelocity; return 0.0f; } if(fVelocity > fMaxVelocity){ 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, false); } }else if(fVelocity < pGearRatio->fShiftDownVelocity && gear != 0){ if(gear != 1 || gasPedal < 0.0f){ gear--; return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, false); } } float speedMul, accelMul; if(gear < 1){ // going reverse accelMul = (Flags & HANDLING_2G_BOOST) ? 2.0f : 1.0f; speedMul = -1.0f; }else if(nNumberOfGears == 1){ accelMul = 1.0f; speedMul = 1.0f; }else{ // BUG or not? this is 1.0 normally but 0.0 in the highest gear float f = 1.0f - (gear-1)/(nNumberOfGears-1); speedMul = 3.0f*sq(f) + 1.0f; // This is pretty ugly, could be written more clearly if(Flags & HANDLING_2G_BOOST){ if(gear == 1) accelMul = (Flags & HANDLING_1G_BOOST) ? 2.0f : 1.6f; else if(gear == 2) accelMul = 1.3f; else accelMul = 1.0f; }else if(Flags & HANDLING_1G_BOOST && gear == 1){ accelMul = 2.0f; }else accelMul = 1.0f; } if(cheat) fCheat = 1.2f; else fCheat = 1.0f; float targetVelocity = Gears[gear].fMaxVelocity*speedMul*fCheat; float accel = (targetVelocity - fVelocity) * (fEngineAcceleration*accelMul) / Abs(targetVelocity); if(Abs(fVelocity) < Abs(Gears[gear].fMaxVelocity*fCheat)) fAcceleration = gasPedal * accel * CTimer::GetTimeStep(); else fAcceleration = 0.0f; return fAcceleration; }