CAutomobile::FireTruckControl and HydraulicControl
This commit is contained in:
parent
7d6a04b5c6
commit
9a50a59a3c
@ -20,9 +20,9 @@ enum eSound : int16
|
|||||||
SOUND_F = 15,
|
SOUND_F = 15,
|
||||||
SOUND_CAR_ENGINE_START = 16,
|
SOUND_CAR_ENGINE_START = 16,
|
||||||
SOUND_CAR_LIGHT_BREAK = 17,
|
SOUND_CAR_LIGHT_BREAK = 17,
|
||||||
SOUND_CAR_HYDRALIC_1 = 18,
|
SOUND_CAR_HYDRAULIC_1 = 18,
|
||||||
SOUND_CAR_HYDRALIC_2 = 19,
|
SOUND_CAR_HYDRAULIC_2 = 19,
|
||||||
SOUND_CAR_HYDRALIC_3 = 20,
|
SOUND_CAR_HYDRAULIC_3 = 20,
|
||||||
SOUND_CAR_JERK = 21,
|
SOUND_CAR_JERK = 21,
|
||||||
SOUND_CAR_SPLASH = 22,
|
SOUND_CAR_SPLASH = 22,
|
||||||
SOUND_17 = 23,
|
SOUND_17 = 23,
|
||||||
|
@ -2023,11 +2023,11 @@ CColModel::operator=(const CColModel &other)
|
|||||||
numVerts = 0;
|
numVerts = 0;
|
||||||
for(i = 0; i < other.numTriangles; i++){
|
for(i = 0; i < other.numTriangles; i++){
|
||||||
if(other.triangles[i].a > numVerts)
|
if(other.triangles[i].a > numVerts)
|
||||||
other.triangles[i].a = numVerts;
|
numVerts = other.triangles[i].a;
|
||||||
if(other.triangles[i].b > numVerts)
|
if(other.triangles[i].b > numVerts)
|
||||||
other.triangles[i].b = numVerts;
|
numVerts = other.triangles[i].b;
|
||||||
if(other.triangles[i].c > numVerts)
|
if(other.triangles[i].c > numVerts)
|
||||||
other.triangles[i].c = numVerts;
|
numVerts = other.triangles[i].c;
|
||||||
}
|
}
|
||||||
numVerts++;
|
numVerts++;
|
||||||
if(vertices)
|
if(vertices)
|
||||||
|
@ -7,3 +7,4 @@ CFireManager &gFireManager = *(CFireManager*)0x8F31D0;
|
|||||||
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
|
WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); }
|
||||||
|
|
||||||
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
|
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
|
||||||
|
WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
|
||||||
|
@ -4,6 +4,7 @@ class CEntity;
|
|||||||
|
|
||||||
class CFire
|
class CFire
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
bool m_bIsOngoing;
|
bool m_bIsOngoing;
|
||||||
bool m_bExists;
|
bool m_bExists;
|
||||||
bool m_bPropogationFlag;
|
bool m_bPropogationFlag;
|
||||||
@ -18,7 +19,6 @@ class CFire
|
|||||||
int field_28;
|
int field_28;
|
||||||
float field_2C;
|
float field_2C;
|
||||||
|
|
||||||
public:
|
|
||||||
void Extinguish(void);
|
void Extinguish(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,5 +26,6 @@ class CFireManager
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32);
|
void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32);
|
||||||
|
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
|
||||||
};
|
};
|
||||||
extern CFireManager &gFireManager;
|
extern CFireManager &gFireManager;
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
CPlayerPed *m_pPed;
|
CPlayerPed *m_pPed;
|
||||||
CVehicle *m_pRemoteVehicle;
|
CVehicle *m_pRemoteVehicle;
|
||||||
CColModel m_ColModel;
|
CColModel m_ColModel;
|
||||||
CVehicle *m_pVehicleEx;
|
CVehicle *m_pVehicleEx; // vehicle using the col model above
|
||||||
char m_aPlayerName[70];
|
char m_aPlayerName[70];
|
||||||
int32 m_nMoney;
|
int32 m_nMoney;
|
||||||
int32 m_nVisibleMoney;
|
int32 m_nVisibleMoney;
|
||||||
|
@ -295,6 +295,7 @@ DebugMenuPopulate(void)
|
|||||||
DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); });
|
DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); });
|
||||||
DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); });
|
DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); });
|
||||||
DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); });
|
DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); });
|
||||||
|
DebugMenuAddCmd("Spawn", "Spawn Yardie", [](){ SpawnCar(MI_YARDIE); });
|
||||||
DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); });
|
DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); });
|
||||||
DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); });
|
DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); });
|
||||||
DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); });
|
DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); });
|
||||||
|
@ -2,4 +2,5 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "WaterCannon.h"
|
#include "WaterCannon.h"
|
||||||
|
|
||||||
|
WRAPPER void CWaterCannons::UpdateOne(uint32 id, CVector *pos, CVector *dir) { EAXJMP(0x522470); }
|
||||||
WRAPPER void CWaterCannons::Render(void) { EAXJMP(0x522550); }
|
WRAPPER void CWaterCannons::Render(void) { EAXJMP(0x522550); }
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
class CWaterCannons
|
class CWaterCannons
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static void UpdateOne(uint32 id, CVector *pos, CVector *dir);
|
||||||
static void Render(void);
|
static void Render(void);
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "Explosion.h"
|
#include "Explosion.h"
|
||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
#include "ParticleObject.h"
|
#include "ParticleObject.h"
|
||||||
|
#include "WaterCannon.h"
|
||||||
#include "WaterLevel.h"
|
#include "WaterLevel.h"
|
||||||
#include "Floater.h"
|
#include "Floater.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
@ -122,7 +123,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
|
|||||||
bNotDamagedUpsideDown = false;
|
bNotDamagedUpsideDown = false;
|
||||||
bMoreResistantToDamage = false;
|
bMoreResistantToDamage = false;
|
||||||
m_fVelocityChangeForAudio = 0.f;
|
m_fVelocityChangeForAudio = 0.f;
|
||||||
field_4E2 = 0;
|
m_hydraulicState = 0;
|
||||||
|
|
||||||
for(i = 0; i < 4; i++){
|
for(i = 0; i < 4; i++){
|
||||||
m_aGroundPhysical[i] = nil;
|
m_aGroundPhysical[i] = nil;
|
||||||
@ -205,7 +206,7 @@ CAutomobile::ProcessControl(void)
|
|||||||
int i;
|
int i;
|
||||||
CColModel *colModel;
|
CColModel *colModel;
|
||||||
|
|
||||||
if(m_veh_flagC80)
|
if(bUseSpecialColModel)
|
||||||
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
|
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
|
||||||
else
|
else
|
||||||
colModel = GetColModel();
|
colModel = GetColModel();
|
||||||
@ -488,7 +489,7 @@ CAutomobile::ProcessControl(void)
|
|||||||
m_aSuspensionSpringRatio[0] < 1.0f &&
|
m_aSuspensionSpringRatio[0] < 1.0f &&
|
||||||
CPad::GetPad(0)->HornJustDown()){
|
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);
|
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP, 1.0f);
|
||||||
|
|
||||||
CParticle::AddParticle(PARTICLE_ENGINE_STEAM,
|
CParticle::AddParticle(PARTICLE_ENGINE_STEAM,
|
||||||
@ -1213,7 +1214,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
|
|||||||
if(m_status != STATUS_SIMPLE)
|
if(m_status != STATUS_SIMPLE)
|
||||||
bVehicleColProcessed = true;
|
bVehicleColProcessed = true;
|
||||||
|
|
||||||
if(m_veh_flagC80)
|
if(bUseSpecialColModel)
|
||||||
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
|
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
|
||||||
else
|
else
|
||||||
colModel = GetColModel();
|
colModel = GetColModel();
|
||||||
@ -1416,9 +1417,62 @@ CAutomobile::ProcessControlInputs(uint8 pad)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRAPPER void
|
void
|
||||||
CAutomobile::FireTruckControl(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
|
void
|
||||||
@ -1528,9 +1582,303 @@ CAutomobile::TankControl(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRAPPER void
|
void
|
||||||
CAutomobile::HydraulicControl(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
|
void
|
||||||
|
@ -54,7 +54,7 @@ public:
|
|||||||
uint8 field_4DB;
|
uint8 field_4DB;
|
||||||
CEntity *m_pBombRigger;
|
CEntity *m_pBombRigger;
|
||||||
int16 field_4E0;
|
int16 field_4E0;
|
||||||
int16 field_4E2;
|
uint16 m_hydraulicState;
|
||||||
uint32 m_nBusDoorTimerEnd;
|
uint32 m_nBusDoorTimerEnd;
|
||||||
uint32 m_nBusDoorTimerStart;
|
uint32 m_nBusDoorTimerStart;
|
||||||
float m_aSuspensionSpringLength[4];
|
float m_aSuspensionSpringLength[4];
|
||||||
|
@ -70,7 +70,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
|||||||
bHasBeenOwnedByPlayer = false;
|
bHasBeenOwnedByPlayer = false;
|
||||||
m_veh_flagC20 = false;
|
m_veh_flagC20 = false;
|
||||||
bCanBeDamaged = true;
|
bCanBeDamaged = true;
|
||||||
m_veh_flagC80 = false;
|
bUseSpecialColModel = false;
|
||||||
m_veh_flagD1 = false;
|
m_veh_flagD1 = false;
|
||||||
m_veh_flagD2 = false;
|
m_veh_flagD2 = false;
|
||||||
m_nGunFiringTime = 0;
|
m_nGunFiringTime = 0;
|
||||||
|
@ -186,7 +186,7 @@ public:
|
|||||||
uint8 m_veh_flagC10 : 1;
|
uint8 m_veh_flagC10 : 1;
|
||||||
uint8 m_veh_flagC20 : 1;
|
uint8 m_veh_flagC20 : 1;
|
||||||
uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions
|
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_flagD1 : 1;
|
||||||
uint8 m_veh_flagD2 : 1;
|
uint8 m_veh_flagD2 : 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user