From 9a50a59a3ced80d782ac1b89aed1e5e86a91dd64 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 26 Jul 2019 14:27:13 +0200 Subject: [PATCH] CAutomobile::FireTruckControl and HydraulicControl --- src/audio/DMAudio.h | 6 +- src/core/Collision.cpp | 6 +- src/core/Fire.cpp | 1 + src/core/Fire.h | 3 +- src/core/PlayerInfo.h | 2 +- src/core/re3.cpp | 1 + src/render/WaterCannon.cpp | 1 + src/render/WaterCannon.h | 1 + src/vehicles/Automobile.cpp | 366 +++++++++++++++++++++++++++++++++++- src/vehicles/Automobile.h | 2 +- src/vehicles/Vehicle.cpp | 2 +- src/vehicles/Vehicle.h | 2 +- 12 files changed, 373 insertions(+), 20 deletions(-) diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h index da20dc31..4428c958 100644 --- a/src/audio/DMAudio.h +++ b/src/audio/DMAudio.h @@ -20,9 +20,9 @@ enum eSound : int16 SOUND_F = 15, SOUND_CAR_ENGINE_START = 16, SOUND_CAR_LIGHT_BREAK = 17, - SOUND_CAR_HYDRALIC_1 = 18, - SOUND_CAR_HYDRALIC_2 = 19, - SOUND_CAR_HYDRALIC_3 = 20, + SOUND_CAR_HYDRAULIC_1 = 18, + SOUND_CAR_HYDRAULIC_2 = 19, + SOUND_CAR_HYDRAULIC_3 = 20, SOUND_CAR_JERK = 21, SOUND_CAR_SPLASH = 22, SOUND_17 = 23, diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp index 7982e77d..cc360f79 100644 --- a/src/core/Collision.cpp +++ b/src/core/Collision.cpp @@ -2023,11 +2023,11 @@ CColModel::operator=(const CColModel &other) numVerts = 0; for(i = 0; i < other.numTriangles; i++){ if(other.triangles[i].a > numVerts) - other.triangles[i].a = numVerts; + numVerts = other.triangles[i].a; if(other.triangles[i].b > numVerts) - other.triangles[i].b = numVerts; + numVerts = other.triangles[i].b; if(other.triangles[i].c > numVerts) - other.triangles[i].c = numVerts; + numVerts = other.triangles[i].c; } numVerts++; if(vertices) diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index bc59de2f..a2894d43 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -7,3 +7,4 @@ CFireManager &gFireManager = *(CFireManager*)0x8F31D0; WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); } +WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); } diff --git a/src/core/Fire.h b/src/core/Fire.h index 9c9e1dec..040e9a25 100644 --- a/src/core/Fire.h +++ b/src/core/Fire.h @@ -4,6 +4,7 @@ class CEntity; class CFire { +public: bool m_bIsOngoing; bool m_bExists; bool m_bPropogationFlag; @@ -18,7 +19,6 @@ class CFire int field_28; float field_2C; -public: void Extinguish(void); }; @@ -26,5 +26,6 @@ class CFireManager { public: void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32); + CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float); }; extern CFireManager &gFireManager; diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index a5f69122..decfb24c 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -20,7 +20,7 @@ public: CPlayerPed *m_pPed; CVehicle *m_pRemoteVehicle; CColModel m_ColModel; - CVehicle *m_pVehicleEx; + CVehicle *m_pVehicleEx; // vehicle using the col model above char m_aPlayerName[70]; int32 m_nMoney; int32 m_nVisibleMoney; diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 6566a282..c2787bc3 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -295,6 +295,7 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); }); DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); }); DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); }); + DebugMenuAddCmd("Spawn", "Spawn Yardie", [](){ SpawnCar(MI_YARDIE); }); DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); }); DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); }); DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); }); diff --git a/src/render/WaterCannon.cpp b/src/render/WaterCannon.cpp index afb40f6f..9398c847 100644 --- a/src/render/WaterCannon.cpp +++ b/src/render/WaterCannon.cpp @@ -2,4 +2,5 @@ #include "patcher.h" #include "WaterCannon.h" +WRAPPER void CWaterCannons::UpdateOne(uint32 id, CVector *pos, CVector *dir) { EAXJMP(0x522470); } WRAPPER void CWaterCannons::Render(void) { EAXJMP(0x522550); } diff --git a/src/render/WaterCannon.h b/src/render/WaterCannon.h index 1a18e75f..55949803 100644 --- a/src/render/WaterCannon.h +++ b/src/render/WaterCannon.h @@ -3,5 +3,6 @@ class CWaterCannons { public: + static void UpdateOne(uint32 id, CVector *pos, CVector *dir); static void Render(void); }; diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 0c4d0ff9..e1484fa4 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -15,6 +15,7 @@ #include "Explosion.h" #include "Particle.h" #include "ParticleObject.h" +#include "WaterCannon.h" #include "WaterLevel.h" #include "Floater.h" #include "World.h" @@ -122,7 +123,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) bNotDamagedUpsideDown = false; bMoreResistantToDamage = false; m_fVelocityChangeForAudio = 0.f; - field_4E2 = 0; + m_hydraulicState = 0; for(i = 0; i < 4; i++){ m_aGroundPhysical[i] = nil; @@ -205,7 +206,7 @@ CAutomobile::ProcessControl(void) int i; CColModel *colModel; - if(m_veh_flagC80) + if(bUseSpecialColModel) colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel; else colModel = GetColModel(); @@ -488,7 +489,7 @@ CAutomobile::ProcessControl(void) m_aSuspensionSpringRatio[0] < 1.0f && CPad::GetPad(0)->HornJustDown()){ - DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRALIC_1, 0.0f); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_1, 0.0f); DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP, 1.0f); CParticle::AddParticle(PARTICLE_ENGINE_STEAM, @@ -1213,7 +1214,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) if(m_status != STATUS_SIMPLE) bVehicleColProcessed = true; - if(m_veh_flagC80) + if(bUseSpecialColModel) colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel; else colModel = GetColModel(); @@ -1416,9 +1417,62 @@ CAutomobile::ProcessControlInputs(uint8 pad) } } -WRAPPER void +void CAutomobile::FireTruckControl(void) -{ EAXJMP(0x522590); +{ + if(this == FindPlayerVehicle()){ + if(!CPad::GetPad(0)->GetWeapon()) + return; + m_fCarGunLR += CPad::GetPad(0)->GetCarGunLeftRight()*0.00025f*CTimer::GetTimeStep(); + m_fCarGunUD += CPad::GetPad(0)->GetCarGunUpDown()*0.0001f*CTimer::GetTimeStep(); + m_fCarGunUD = clamp(m_fCarGunUD, 0.05f, 0.3f); + + CVector cannonPos(0.0f, 1.5f, 1.9f); + cannonPos = GetMatrix() * cannonPos; + CVector cannonDir( + Sin(m_fCarGunLR) * Cos(m_fCarGunUD), + Cos(m_fCarGunLR) * Cos(m_fCarGunUD), + Sin(m_fCarGunUD)); + cannonDir = Multiply3x3(GetMatrix(), cannonDir); + cannonDir.z += (CGeneral::GetRandomNumber()&0xF)/1000.0f; + CWaterCannons::UpdateOne((uintptr)this, &cannonPos, &cannonDir); + }else if(m_status == STATUS_PHYSICS){ + CFire *fire = gFireManager.FindFurthestFire_NeverMindFireMen(GetPosition(), 10.0f, 35.0f); + if(fire == nil) + return; + + // Target cannon onto fire + float targetAngle = CGeneral::GetATanOfXY(fire->m_vecPos.x-GetPosition().x, fire->m_vecPos.y-GetPosition().y); + float fwdAngle = CGeneral::GetATanOfXY(GetForward().x, GetForward().y); + float targetCannonAngle = fwdAngle - targetAngle; + float angleDelta = CTimer::GetTimeStep()*0.01f; + float cannonDelta = targetCannonAngle - m_fCarGunLR; + while(cannonDelta < PI) cannonDelta += TWOPI; + while(cannonDelta > PI) cannonDelta -= TWOPI; + if(Abs(cannonDelta) < angleDelta) + m_fCarGunLR = targetCannonAngle; + else if(cannonDelta > 0.0f) + m_fCarGunLR += angleDelta; + else + m_fCarGunLR -= angleDelta; + + // Go up and down a bit + float upDown = Sin((float)(CTimer::GetTimeInMilliseconds() & 0xFFF)/0x1000 * TWOPI); + m_fCarGunUD = 0.2f + 0.2f*upDown; + + // Spray water every once in a while + if((CTimer::GetTimeInMilliseconds()>>10) & 3){ + CVector cannonPos(0.0f, 0.0f, 2.2f); // different position than player's firetruck! + cannonPos = GetMatrix() * cannonPos; + CVector cannonDir( + Sin(m_fCarGunLR) * Cos(m_fCarGunUD), + Cos(m_fCarGunLR) * Cos(m_fCarGunUD), + Sin(m_fCarGunUD)); + cannonDir = Multiply3x3(GetMatrix(), cannonDir); + cannonDir.z += (CGeneral::GetRandomNumber()&0xF)/1000.0f; + CWaterCannons::UpdateOne((uintptr)this, &cannonPos, &cannonDir); + } + } } void @@ -1528,13 +1582,307 @@ CAutomobile::TankControl(void) } } -WRAPPER void +void CAutomobile::HydraulicControl(void) -{ EAXJMP(0x52D4E0); +{ + int i; + float wheelPositions[4]; + CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); + CColModel *normalColModel = mi->GetColModel(); + float wheelRadius = 0.5f*mi->m_wheelScale; + CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus]; + CColModel *specialColModel = &playerInfo->m_ColModel; + + if(m_status != STATUS_PLAYER){ + // reset hydraulics for non-player cars + + if(!bUseSpecialColModel) + return; + if(specialColModel != nil) // this is always true + for(i = 0; i < 4; i++) + wheelPositions[i] = specialColModel->lines[i].p0.z - m_aSuspensionSpringRatio[i]*m_aSuspensionLineLength[i]; + for(i = 0; i < 4; i++){ + m_aSuspensionSpringLength[i] = pHandling->fSuspensionUpperLimit - pHandling->fSuspensionLowerLimit; + m_aSuspensionLineLength[i] = normalColModel->lines[i].p0.z - normalColModel->lines[i].p1.z; + m_aSuspensionSpringRatio[i] = (normalColModel->lines[i].p0.z - wheelPositions[i]) / m_aSuspensionLineLength[i]; + if(m_aSuspensionSpringRatio[i] > 1.0f) + m_aSuspensionSpringRatio[i] = 1.0f; + } + + if(m_hydraulicState == 0) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_1, 0.0f); + else if(m_hydraulicState >= 100) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); + + if(playerInfo->m_pVehicleEx == this) + playerInfo->m_pVehicleEx = nil; + bUseSpecialColModel = false; + m_hydraulicState = 0; + return; + } + + // Player car + + float normalUpperLimit = pHandling->fSuspensionUpperLimit; + float normalLowerLimit = pHandling->fSuspensionLowerLimit; + float normalSpringLength = normalUpperLimit - normalLowerLimit; + float extendedUpperLimit = normalUpperLimit - 0.2f; + float extendedLowerLimit = normalLowerLimit - 0.2f; + float extendedSpringLength = extendedUpperLimit - extendedLowerLimit; + + if(!bUseSpecialColModel){ + // Init special col model + + if(playerInfo->m_pVehicleEx && playerInfo->m_pVehicleEx == this) + playerInfo->m_pVehicleEx->bUseSpecialColModel = false; + playerInfo->m_pVehicleEx = this; + playerInfo->m_ColModel = *normalColModel; + bUseSpecialColModel = true; + specialColModel = &playerInfo->m_ColModel; + + if(m_fVelocityChangeForAudio > 0.1f) + m_hydraulicState = 20; + else{ + m_hydraulicState = 0; + normalUpperLimit += -0.12f; + normalSpringLength = normalUpperLimit - (normalLowerLimit+0.14f); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); + } + + // Setup suspension + float normalLineLength = normalSpringLength + wheelRadius; + CVector pos; + for(i = 0; i < 4; i++){ + wheelPositions[i] = normalColModel->lines[i].p0.z - m_aSuspensionSpringRatio[i]*m_aSuspensionLineLength[i]; + mi->GetWheelPosn(i, pos); + pos.z += normalUpperLimit; + specialColModel->lines[i].p0 = pos; + pos.z -= normalLineLength; + specialColModel->lines[i].p1 = pos; + m_aSuspensionSpringLength[i] = normalSpringLength; + m_aSuspensionLineLength[i] = normalLineLength; + + if(m_aSuspensionSpringRatio[i] < 1.0f){ + m_aSuspensionSpringRatio[i] = (specialColModel->lines[i].p0.z - wheelPositions[i])/m_aSuspensionLineLength[i]; + if(m_aSuspensionSpringRatio[i] > 1.0f) + m_aSuspensionSpringRatio[i] = 1.0f; + } + } + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); + + // Adjust col model + mi->GetWheelPosn(0, pos); + float minz = pos.z + extendedLowerLimit - wheelRadius; + if(minz < specialColModel->boundingBox.min.z) + specialColModel->boundingBox.min.z = minz; + float radius = max(specialColModel->boundingBox.min.Magnitude(), specialColModel->boundingBox.max.Magnitude()); + if(specialColModel->boundingSphere.radius < radius) + specialColModel->boundingSphere.radius = radius; + + } + + if(playerInfo->m_WBState != WBSTATE_PLAYING) + return; + + bool setPrevRatio = false; + if(m_hydraulicState < 20 && m_fVelocityChangeForAudio > 0.2f){ + if(m_hydraulicState == 0){ + m_hydraulicState = 20; + for(i = 0; i < 4; i++) + m_aWheelPosition[i] -= 0.06f; + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_1, 0.0f); + setPrevRatio = true; + }else{ + m_hydraulicState++; + } + }else if(m_hydraulicState != 0){ // must always be true + if(m_hydraulicState < 21 && m_fVelocityChangeForAudio < 0.1f){ + m_hydraulicState--; + if(m_hydraulicState == 0) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); + } + } + + if(CPad::GetPad(0)->HornJustDown()){ + // Switch between normal and extended + + if(m_hydraulicState < 100) + m_hydraulicState = 100; + else{ + if(m_fVelocityChangeForAudio > 0.1f) + m_hydraulicState = 20; + else + m_hydraulicState = 0; + } + + if(m_hydraulicState < 100){ + if(m_hydraulicState == 0){ + normalUpperLimit += -0.12f; + normalLowerLimit += 0.14f; + normalSpringLength = normalUpperLimit - normalLowerLimit; + } + + // Reset suspension to normal + float normalLineLength = normalSpringLength + wheelRadius; + CVector pos; + for(i = 0; i < 4; i++){ + wheelPositions[i] = specialColModel->lines[i].p0.z - m_aSuspensionSpringRatio[i]*m_aSuspensionLineLength[i]; + mi->GetWheelPosn(i, pos); + pos.z += normalUpperLimit; + specialColModel->lines[i].p0 = pos; + pos.z -= normalLineLength; + specialColModel->lines[i].p1 = pos; + m_aSuspensionSpringLength[i] = normalSpringLength; + m_aSuspensionLineLength[i] = normalLineLength; + + if(m_aSuspensionSpringRatio[i] < 1.0f){ + m_aSuspensionSpringRatio[i] = (specialColModel->lines[i].p0.z - wheelPositions[i])/m_aSuspensionLineLength[i]; + if(m_aSuspensionSpringRatio[i] > 1.0f) + m_aSuspensionSpringRatio[i] = 1.0f; + } + } + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); + }else{ + // Reset suspension to extended + float extendedLineLength = extendedSpringLength + wheelRadius; + CVector pos; + for(i = 0; i < 4; i++){ + wheelPositions[i] = specialColModel->lines[i].p0.z - m_aSuspensionSpringRatio[i]*m_aSuspensionLineLength[i]; + mi->GetWheelPosn(i, pos); + pos.z += extendedUpperLimit; + specialColModel->lines[i].p0 = pos; + pos.z -= extendedLineLength; + specialColModel->lines[i].p1 = pos; + m_aSuspensionSpringLength[i] = extendedSpringLength; + m_aSuspensionLineLength[i] = extendedLineLength; + + if(m_aSuspensionSpringRatio[i] < 1.0f){ + m_aSuspensionSpringRatio[i] = (specialColModel->lines[i].p0.z - wheelPositions[i])/m_aSuspensionLineLength[i]; + if(m_aSuspensionSpringRatio[i] > 1.0f) + m_aSuspensionSpringRatio[i] = 1.0f; + } + + setPrevRatio = true; + m_aWheelPosition[i] -= 0.05f; + } + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); + } + }else{ + float suspChange[4]; + float maxDelta = 0.0f; + float rear = CPad::GetPad(0)->GetCarGunUpDown()/128.0f; + float front = -rear; + float right = CPad::GetPad(0)->GetCarGunLeftRight()/128.0f; + float left = -right; + suspChange[CARWHEEL_FRONT_LEFT] = max(front+left, 0.0f); + suspChange[CARWHEEL_REAR_LEFT] = max(rear+left, 0.0f); + suspChange[CARWHEEL_FRONT_RIGHT] = max(front+right, 0.0f); + suspChange[CARWHEEL_REAR_RIGHT] = max(rear+right, 0.0f); + + if(m_hydraulicState < 100){ + // Lowered, move wheels up + + if(m_hydraulicState == 0){ + normalUpperLimit += -0.12f; + normalLowerLimit += 0.14f; + normalSpringLength = normalUpperLimit - normalLowerLimit; + } + + // Set suspension + CVector pos; + for(i = 0; i < 4; i++){ + if(suspChange[i] > 1.0f) + suspChange[i] = 1.0f; + + float oldZ = specialColModel->lines[i].p1.z; + float upperLimit = suspChange[i]*(extendedUpperLimit-normalUpperLimit) + normalUpperLimit; + float springLength = suspChange[i]*(extendedSpringLength-normalSpringLength) + normalSpringLength; + float lineLength = springLength + wheelRadius; + + wheelPositions[i] = specialColModel->lines[i].p0.z - m_aSuspensionSpringRatio[i]*m_aSuspensionLineLength[i]; + mi->GetWheelPosn(i, pos); + pos.z += upperLimit; + specialColModel->lines[i].p0 = pos; + pos.z -= lineLength; + if(Abs(pos.z - specialColModel->lines[i].p1.z) > Abs(maxDelta)) + maxDelta = pos.z - specialColModel->lines[i].p1.z; + specialColModel->lines[i].p1 = pos; + m_aSuspensionSpringLength[i] = springLength; + m_aSuspensionLineLength[i] = lineLength; + + if(m_aSuspensionSpringRatio[i] < 1.0f){ + m_aSuspensionSpringRatio[i] = (specialColModel->lines[i].p0.z - wheelPositions[i])/m_aSuspensionLineLength[i]; + if(m_aSuspensionSpringRatio[i] > 1.0f) + m_aSuspensionSpringRatio[i] = 1.0f; + m_aWheelPosition[i] -= (oldZ - specialColModel->lines[i].p1.z)*0.3f; + } + } + }else{ + if(m_hydraulicState < 104){ + m_hydraulicState++; + for(i = 0; i < 4; i++) + m_aWheelPosition[i] -= 0.1f; + } + + if(m_fVelocityChangeForAudio < 0.1f){ + normalUpperLimit += -0.12f; + normalLowerLimit += 0.14f; + normalSpringLength = normalUpperLimit - normalLowerLimit; + } + + // Set suspension + CVector pos; + for(i = 0; i < 4; i++){ + if(suspChange[i] > 1.0f) + suspChange[i] = 1.0f; + + float upperLimit = suspChange[i]*(normalUpperLimit-extendedUpperLimit) + extendedUpperLimit; + float springLength = suspChange[i]*(normalSpringLength-extendedSpringLength) + extendedSpringLength; + float lineLength = springLength + wheelRadius; + + wheelPositions[i] = specialColModel->lines[i].p0.z - m_aSuspensionSpringRatio[i]*m_aSuspensionLineLength[i]; + mi->GetWheelPosn(i, pos); + pos.z += upperLimit; + specialColModel->lines[i].p0 = pos; + pos.z -= lineLength; + if(Abs(pos.z - specialColModel->lines[i].p1.z) > Abs(maxDelta)) + maxDelta = pos.z - specialColModel->lines[i].p1.z; + specialColModel->lines[i].p1 = pos; + m_aSuspensionSpringLength[i] = springLength; + m_aSuspensionLineLength[i] = lineLength; + + if(m_aSuspensionSpringRatio[i] < 1.0f){ + m_aSuspensionSpringRatio[i] = (specialColModel->lines[i].p0.z - wheelPositions[i])/m_aSuspensionLineLength[i]; + if(m_aSuspensionSpringRatio[i] > 1.0f) + m_aSuspensionSpringRatio[i] = 1.0f; + } + } + } + + float limitDiff = extendedLowerLimit - normalLowerLimit; + if(limitDiff != 0.0f && Abs(maxDelta/limitDiff) > 0.01f){ + float f = (maxDelta + limitDiff)/2.0f/limitDiff; + f = clamp(f, 0.0f, 1.0f); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_3, f); + if(f < 0.4f || f > 0.6f) + setPrevRatio = true; + if(f < 0.25f) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f); + else if(f > 0.75f) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_1, 0.0f); + } + } + + if(setPrevRatio) + for(i = 0; i < 4; i++){ + // wheel radius in relation to suspension line + float wheelRadius = 1.0f - m_aSuspensionSpringLength[i]/m_aSuspensionLineLength[i]; + m_aSuspensionSpringRatioPrev[i] = (m_aSuspensionSpringRatio[i]-wheelRadius)/(1.0f-wheelRadius); + } } void -CAutomobile::ProcessBuoyancy(void) +CAutomobile::ProcessBuoyancy(void) { int i; CVector impulse, point; diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index fd3eb203..81b02634 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -54,7 +54,7 @@ public: uint8 field_4DB; CEntity *m_pBombRigger; int16 field_4E0; - int16 field_4E2; + uint16 m_hydraulicState; uint32 m_nBusDoorTimerEnd; uint32 m_nBusDoorTimerStart; float m_aSuspensionSpringLength[4]; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 4bcd08db..d8ea6211 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -70,7 +70,7 @@ CVehicle::CVehicle(uint8 CreatedBy) bHasBeenOwnedByPlayer = false; m_veh_flagC20 = false; bCanBeDamaged = true; - m_veh_flagC80 = false; + bUseSpecialColModel = false; m_veh_flagD1 = false; m_veh_flagD2 = false; m_nGunFiringTime = 0; diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 38d411cd..825c1a6c 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -186,7 +186,7 @@ public: uint8 m_veh_flagC10 : 1; uint8 m_veh_flagC20 : 1; uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions - uint8 m_veh_flagC80 : 1; + uint8 bUseSpecialColModel : 1; uint8 m_veh_flagD1 : 1; uint8 m_veh_flagD2 : 1;