more fixes; started CAutomobile::ProcessControl

This commit is contained in:
aap 2019-07-16 19:48:50 +02:00
parent 03fc85bfe0
commit 36f3a517f9
9 changed files with 350 additions and 79 deletions

View File

@ -1891,9 +1891,9 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
CTheScripts::ClearSpaceForMissionEntity(pos, boat);
boat->m_status = STATUS_ABANDONED;
boat->bIsLocked = true;
boat->m_autoPilot.m_nCarMission = MISSION_NONE;
boat->m_autoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */
boat->m_autoPilot.m_nCruiseSpeed = boat->m_autoPilot.m_fMaxTrafficSpeed = 20.0f;
boat->AutoPilot.m_nCarMission = MISSION_NONE;
boat->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */
boat->AutoPilot.m_nCruiseSpeed = boat->AutoPilot.m_fMaxTrafficSpeed = 20.0f;
CWorld::Add(boat);
handle = CPools::GetVehiclePool()->GetIndex(boat);
}
@ -1909,11 +1909,11 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
CTheScripts::ClearSpaceForMissionEntity(pos, car);
car->m_status = STATUS_ABANDONED;
car->bIsLocked = true;
car->m_autoPilot.m_nCarMission = MISSION_NONE;
car->m_autoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */
car->m_autoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
car->m_autoPilot.m_nCruiseSpeed = car->m_autoPilot.m_fMaxTrafficSpeed = 9.0f;
car->m_autoPilot.m_nPreviousLane = car->m_autoPilot.m_nCurrentLane = 0;
car->AutoPilot.m_nCarMission = MISSION_NONE;
car->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */
car->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f;
car->AutoPilot.m_nPreviousLane = car->AutoPilot.m_nCurrentLane = 0;
car->bEngineOn = false;
car->m_level = CTheZones::GetLevelFromPosition(pos);
car->bHasBeenOwnedByPlayer = true;
@ -1949,13 +1949,13 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel();
if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, pos, false))
car->m_autoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
else
car->m_autoPilot.m_nCarMission = MISSION_GOTOCOORDS;
car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
car->m_status = STATUS_PHYSICS;
car->bEngineOn = true;
car->m_autoPilot.m_nCruiseSpeed = max(car->m_autoPilot.m_nCruiseSpeed, 6);
car->m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6);
car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
return 0;
}
case COMMAND_CAR_WANDER_RANDOMLY:
@ -1964,10 +1964,10 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car);
CCarCtrl::JoinCarWithRoadSystem(car);
car->m_autoPilot.m_nCarMission = MISSION_CRUISE;
car->AutoPilot.m_nCarMission = MISSION_CRUISE;
car->bEngineOn = true;
car->m_autoPilot.m_nCruiseSpeed = max(car->m_autoPilot.m_nCruiseSpeed, 6);
car->m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6);
car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
return 0;
}
case COMMAND_CAR_SET_IDLE:
@ -1975,7 +1975,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
CollectParameters(&m_nIp, 1);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car);
car->m_autoPilot.m_nCarMission = MISSION_NONE;
car->AutoPilot.m_nCarMission = MISSION_NONE;
return 0;
}
case COMMAND_GET_CAR_COORDINATES:
@ -2006,7 +2006,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
car->Teleport(pos);
CTheScripts::ClearSpaceForMissionEntity(pos, car);
/* May the following be inlined CCarCtrl function? */
switch (car->m_autoPilot.m_nCarMission) {
switch (car->AutoPilot.m_nCarMission) {
case MISSION_CRUISE:
CCarCtrl::JoinCarWithRoadSystem(car);
break;
@ -2019,18 +2019,18 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
break;
case MISSION_GOTOCOORDS:
case MISSION_GOTOCOORDS_STRAIGHT:
CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->m_autoPilot.m_vecDestinationCoors, false);
CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_vecDestinationCoors, false);
break;
case MISSION_GOTOCOORDS_ACCURATE:
case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE:
CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->m_autoPilot.m_vecDestinationCoors, false);
CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_vecDestinationCoors, false);
break;
case MISSION_RAMCAR_FARAWAY:
case MISSION_RAMCAR_CLOSE:
case MISSION_BLOCKCAR_FARAWAY:
case MISSION_BLOCKCAR_CLOSE:
case MISSION_BLOCKCAR_HANDBRAKESTOP:
CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->m_autoPilot.m_pTargetCar->GetPosition(), false);
CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_pTargetCar->GetPosition(), false);
break;
default:
break;
@ -2050,7 +2050,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car);
car->m_autoPilot.m_nCruiseSpeed = min(*(float*)&ScriptParams[1], 60.0f * car->m_handling->TransmissionData.fUnkMaxVelocity);
car->AutoPilot.m_nCruiseSpeed = min(*(float*)&ScriptParams[1], 60.0f * car->m_handling->TransmissionData.fUnkMaxVelocity);
return 0;
}
case COMMAND_SET_CAR_DRIVING_STYLE:
@ -2058,7 +2058,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car);
car->m_autoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1];
car->AutoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1];
return 0;
}
case COMMAND_SET_CAR_MISSION:
@ -2066,8 +2066,8 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car);
car->m_autoPilot.m_nCarMission = (eCarMission)ScriptParams[1];
car->m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
car->AutoPilot.m_nCarMission = (eCarMission)ScriptParams[1];
car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
car->bEngineOn = true;
return 0;
}

View File

@ -607,12 +607,12 @@ CWorld::FindObjectsInRange(CVector &centre, float distance, bool ignoreZ, short
minY = 0;
int maxX = GetSectorIndexX(centre.x + distance);
if (maxX >= 100)
maxX = 100;
if (maxX >= NUMSECTORS_X)
maxX = NUMSECTORS_X;
int maxY = GetSectorIndexY(centre.y + distance);
if (maxY >= 100)
maxY = 100;
if (maxY >= NUMSECTORS_Y)
maxY = NUMSECTORS_Y;
AdvanceCurrentScanCode();
@ -658,12 +658,12 @@ CWorld::TestSphereAgainstWorld(CVector centre, float distance, CEntity* entityTo
minY = 0;
int maxX = GetSectorIndexX(centre.x + distance);
if (maxX >= 100)
maxX = 100;
if (maxX >= NUMSECTORS_X)
maxX = NUMSECTORS_X;
int maxY = GetSectorIndexY(centre.y + distance);
if (maxY >= 100)
maxY = 100;
if (maxY >= NUMSECTORS_Y)
maxY = NUMSECTORS_Y;
AdvanceCurrentScanCode();

View File

@ -13,14 +13,11 @@ enum eEntityType
ENTITY_TYPE_PED,
ENTITY_TYPE_OBJECT,
ENTITY_TYPE_DUMMY,
ENTITY_TYPE_6,
ENTITY_TYPE_7,
};
enum eEntityStatus
{
// from SA MTA! let's hope they didn't change from III
STATUS_PLAYER = 0,
STATUS_PLAYER,
STATUS_PLAYER_PLAYBACKFROMBUFFER,
STATUS_SIMPLE,
STATUS_PHYSICS,
@ -32,8 +29,6 @@ enum eEntityStatus
STATUS_PLANE,
STATUS_PLAYER_REMOTE,
STATUS_PLAYER_DISABLED,
//STATUS_TRAILER,
//STATUS_SIMPLE_TRAILER
};
class CEntity : public CPlaceable

View File

@ -2733,8 +2733,8 @@ CPed::QuitEnteringCar(void)
m_pVehicleAnim = nil;
if (veh) {
if (veh->m_autoPilot.m_nCruiseSpeed == 0)
veh->m_autoPilot.m_nCruiseSpeed = 17;
if (veh->AutoPilot.m_nCruiseSpeed == 0)
veh->AutoPilot.m_nCruiseSpeed = 17;
}
}

View File

@ -38,7 +38,270 @@ CAutomobile::SetModelIndex(uint32 id)
SetupModelNodes();
}
WRAPPER void CAutomobile::ProcessControl(void) { EAXJMP(0x531470); }
//WRAPPER void CAutomobile::ProcessControl(void) { EAXJMP(0x531470); }
void
CAutomobile::ProcessControl(void)
{
int i;
CColModel *colModel;
if(m_veh_flagC80)
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
else
colModel = GetColModel();
bWarnedPeds = false;
// skip if the collision isn't for the current level
if(colModel->level > LEVEL_NONE && colModel->level != CCollision::ms_collisionInMemory)
return;
bool strongGrip = false;
assert(0 && "some player stuff");
if(bIsBus)
ProcessAutoBusDoors();
ProcessCarAlarm();
// Scan if this car is committing a crime that the police can see
if(m_status != STATUS_ABANDONED && m_status != STATUS_WRECKED &&
m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE && m_status != STATUS_PLAYER_DISABLED){
switch(GetModelIndex())
case MI_FBICAR:
case MI_POLICE:
case MI_ENFORCER:
case MI_SECURICA:
case MI_RHINO:
case MI_BARRACKS:
ScanForCrimes();
}
// Process driver
if(pDriver){
if(!bHadDriver && m_bombType == 5){
// If someone enters the car and there is a bomb, detonate
m_nBombTimer = 1000;
m_pBlowUpEntity = field_4DC;
if(m_pBlowUpEntity)
m_pBlowUpEntity->RegisterReference((CEntity**)&m_pBlowUpEntity);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TICK, 1.0f);
}
bHadDriver = true;
if(IsUpsideDown() && CanPedEnterCar()){
if(!pDriver->IsPlayer() &&
!(pDriver->m_leader && pDriver->m_leader->bInVehicle) &&
pDriver->CharCreatedBy != MISSION_CHAR)
pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this);
}
}else
bHadDriver = false;
// Process passengers
if(m_nNumPassengers != 0 && IsUpsideDown() && CanPedEnterCar()){
for(i = 0; i < m_nNumMaxPassengers; i++)
if(pPassengers[i])
if(!pPassengers[i]->IsPlayer() &&
!(pPassengers[i]->m_leader && pPassengers[i]->m_leader->bInVehicle) &&
pPassengers[i]->CharCreatedBy != MISSION_CHAR)
pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this);
}
// CRubbish::StirUp
// blend in clump
int clumpAlpha = CVisibilityPlugins::GetClumpAlpha((RpClump*)m_rwObject);
if(bFadeOut){
clumpAlpha -= 8;
if(clumpAlpha < 0)
clumpAlpha = 0;
}else if(clumpAlpha < 255){
clumpAlpha += 16;
if(clumpAlpha > 255)
clumpAlpha = 255;
}
CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha);
AutoPilot.m_flag1 = false;
AutoPilot.m_flag2 = false;
// Set Center of Mass to make car more stable
if(strongGrip || bCheat3)
m_vecCentreOfMass.z = 0.3f*m_aSuspensionSpringLength[0] + -1.0*m_fHeightAboveRoad;
else if(m_handling->Flags & HANDLING_NONPLAYER_STABILISER && m_status == STATUS_PHYSICS)
m_vecCentreOfMass.z = m_handling->CentreOfMass.z - 0.2f*m_handling->Dimension.z;
else
m_vecCentreOfMass.z = m_handling->CentreOfMass.z;
// Process depending on status
switch(m_status){
case STATUS_PLAYER:
case STATUS_SIMPLE:
case STATUS_PHYSICS:
case STATUS_ABANDONED:
case STATUS_WRECKED:
case STATUS_PLAYER_REMOTE:
case STATUS_PLAYER_DISABLED:
assert(0);
}
if(GetPosition().z < -0.6f){
assert(0);
}
bool skipPhysics = false;
if(!bIsStuck){
assert(0);
}
// Postpone
for(i = 0; i < 4; i++)
if(m_aGroundPhysical[i] && !CWorld::bForceProcessControl && m_aGroundPhysical[i]->bIsInSafePosition){
bWasPostponed = true;
return;
}
// VehicleDamage
// special control
switch(GetModelIndex()){
case MI_FIRETRUCK:
case MI_RHINO:
case MI_YARDIE:
default:
assert(0);
}
if(skipPhysics){
bHasContacted = false;
bIsInSafePosition = false;
bWasPostponed = false;
bHasHitWall = false;
m_nCollisionRecords = 0;
bHasCollided = false;
bVehicleColProcessed = false;
m_nDamagePieceType = 0;
m_fDamageImpulse = 0.0f;
m_pDamageEntity = nil;
m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
}else{
// This has to be done if ProcessEntityCollision wasn't called
if(!bVehicleColProcessed){
CMatrix mat(GetMatrix());
bIsStuck = false;
bHasContacted = false;
bIsInSafePosition = false;
bWasPostponed = false;
bHasHitWall = false;
m_fDistanceTravelled = 0.0f;
field_EF = false;
m_phy_flagA80 = false;
ApplyMoveSpeed();
ApplyTurnSpeed();
for(i = 0; CheckCollision() && i < 5; i++){
GetMatrix() = mat;
ApplyMoveSpeed();
ApplyTurnSpeed();
}
bIsInSafePosition = true;
bIsStuck = false;
}
CPhysical::ProcessControl();
ProcessBuoyancy();
// Rescale spring ratios, i.e. subtract wheel radius
for(i = 0; i < 4; i++){
// wheel radius in relation to suspension line
float wheelRadius = 1.0f - m_aSuspensionSpringLength[i]/m_aSuspensionLineLength[i];
// rescale such that 0.0 is fully compressed and 1.0 is fully extended
m_aSuspensionSpringRatio[i] = (m_aSuspensionSpringRatio[i]-wheelRadius)/(1.0f-wheelRadius);
}
float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
CVector contactPoints[4]; // relative to model
CVector contactSpeeds[4]; // speed at contact points
CVector springDirections[4]; // normalized, in model space
for(i = 0; i < 4; i++){
// Set spring under certain circumstances
if(Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING)
m_aSuspensionSpringRatio[i] = 1.0f;
else if(Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST){
// wheel more bumpy the faster we are
if(CGeneral::GetRandomNumberInRange(0, (uint16)(40*fwdSpeed) + 98) < 100){
m_aSuspensionSpringRatio[i] += 0.3f*(m_aSuspensionLineLength[i]-m_aSuspensionSpringLength[i])/m_aSuspensionSpringLength[i];
if(m_aSuspensionSpringRatio[i] > 1.0f)
m_aSuspensionSpringRatio[i] = 1.0f;
}
}
// get points and directions if spring is compressed
if(m_aSuspensionSpringRatio[i] < 1.0f){
contactPoints[i] = m_aWheelColPoints[i].point - GetPosition();
springDirections[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1 - colModel->lines[i].p0);
springDirections[i].Normalise();
}
}
// Make springs push up vehicle
for(i = 0; i < 4; i++){
if(m_aSuspensionSpringRatio[i] < 1.0f){
float bias = m_handling->fSuspensionBias;
if(i == 1 || i == 3) // rear
bias = 1.0f - bias;
ApplySpringCollision(m_handling->fSuspensionForceLevel,
springDirections[i], contactPoints[i],
m_aSuspensionSpringRatio[i], bias);
m_aWheelSkidmarkMuddy[i] =
m_aWheelColPoints[i].surfaceB == SURFACE_GRASS ||
m_aWheelColPoints[i].surfaceB == SURFACE_DIRTTRACK ||
m_aWheelColPoints[i].surfaceB == SURFACE_SAND;
}else{
contactPoints[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1);
}
}
// Get speed at contact points
for(i = 0; i < 4; i++){
contactSpeeds[i] = GetSpeed(contactPoints[i]);
if(m_aGroundPhysical[i]){
// subtract movement of physical we're standing on
contactSpeeds[i] -= m_aGroundPhysical[i]->GetSpeed(m_aGroundOffset[i]);
#ifndef FIX_BUGS
// this shouldn't be reset because we still need it below
m_aGroundPhysical[i] = nil;
#endif
}
}
// dampen springs
for(i = 0; i < 4; i++)
if(m_aSuspensionSpringRatio[i] < 1.0f)
ApplySpringDampening(m_handling->fSuspensionDampingLevel,
springDirections[i], contactPoints[i], contactSpeeds[i]);
// Get speed at contact points again
for(i = 0; i < 4; i++){
contactSpeeds[i] = GetSpeed(contactPoints[i]);
if(m_aGroundPhysical[i]){
// subtract movement of physical we're standing on
contactSpeeds[i] -= m_aGroundPhysical[i]->GetSpeed(m_aGroundOffset[i]);
m_aGroundPhysical[i] = nil;
}
}
assert(0);
}
assert(0 && "misc stuff");
}
void
CAutomobile::Teleport(CVector pos)
@ -271,6 +534,11 @@ CAutomobile::ProcessControlInputs(uint8 pad)
}
}
WRAPPER void
CAutomobile::ProcessBuoyancy(void)
{ EAXJMP(0x5308D0);
}
void
CAutomobile::GetComponentWorldPosition(int32 component, CVector &pos)
{
@ -524,7 +792,7 @@ CAutomobile::BlowUpCar(CEntity *culprit)
m_fHealth = 0.0f;
m_nBombTimer = 0;
m_auto_flagA7 = 0;
m_bombType = 0;
TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z);
@ -660,8 +928,8 @@ CAutomobile::PlayCarHorn(void)
void
CAutomobile::PlayHornIfNecessary(void)
{
if(m_autoPilot.m_flag2 ||
m_autoPilot.m_flag1)
if(AutoPilot.m_flag2 ||
AutoPilot.m_flag1)
if(!HasCarStoppedBecauseOfLight())
PlayCarHorn();
}
@ -761,20 +1029,20 @@ CAutomobile::HasCarStoppedBecauseOfLight(void)
if(m_status != STATUS_SIMPLE && m_status != STATUS_PHYSICS)
return false;
if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nNextRouteNode){
CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode];
if(AutoPilot.m_nCurrentRouteNode && AutoPilot.m_nNextRouteNode){
CPathNode *curnode = &ThePaths.m_pathNodes[AutoPilot.m_nCurrentRouteNode];
for(i = 0; i < curnode->numLinks; i++)
if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_nNextRouteNode)
if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nNextRouteNode)
break;
if(i < curnode->numLinks &&
ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO
return true;
}
if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nPrevRouteNode){
CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode];
if(AutoPilot.m_nCurrentRouteNode && AutoPilot.m_nPrevRouteNode){
CPathNode *curnode = &ThePaths.m_pathNodes[AutoPilot.m_nCurrentRouteNode];
for(i = 0; i < curnode->numLinks; i++)
if(ThePaths.m_connections[curnode->firstLink + i] == m_autoPilot.m_nPrevRouteNode)
if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nPrevRouteNode)
break;
if(i < curnode->numLinks &&
ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO

View File

@ -6,6 +6,12 @@
class CObject;
// Wheels are in order:
// FRONT LEFT
// REAR LEFT
// FRONT RIGHT
// REAR RIGHT
class CAutomobile : public CVehicle
{
public:
@ -24,13 +30,15 @@ public:
float m_aWheelPosition[4];
float m_aWheelSpeed[4];
uint8 field_4D8;
uint8 m_auto_flagA7 : 1;
uint8 m_bombType : 3;
uint8 bTaxiLight : 1;
uint8 m_auto_flagA10 : 1;
uint8 bHadDriver : 1; // for bombs
uint8 m_auto_flagA20 : 1;
uint8 m_auto_flagA40 : 1;
uint8 m_auto_flagA80 : 1;
uint8 field_4DA[10];
uint8 field_4DA[2];
CEntity *field_4DC; // blow up entity
uint8 field_4E0[4];
uint32 m_nBusDoorTimerEnd;
uint32 m_nBusDoorTimerStart;
float m_aSuspensionSpringLength[4];
@ -41,7 +49,7 @@ public:
float field_530;
CPhysical *m_aGroundPhysical[4]; // physicals touching wheels
CVector m_aGroundOffset[4]; // from ground object to colpoint
CEntity *m_pBlowUpEntity;
CEntity *m_pSetOnFireEntity;
float m_weaponThingA; // TODO
float m_weaponThingB; // TODO
float m_fCarGunLR;
@ -87,6 +95,7 @@ public:
float GetHeightAboveRoad(void);
void PlayCarHorn(void);
void ProcessBuoyancy(void);
void PlayHornIfNecessary(void);
void ResetSuspension(void);
void SetupSuspensionLines(void);

View File

@ -23,7 +23,8 @@ enum ePanelStatus
enum eWheelStatus
{
WHEEL_STATUS_OK,
WHEEL_STATUS_BURST
WHEEL_STATUS_BURST,
WHEEL_STATUS_MISSING
};
enum tComponent

View File

@ -56,14 +56,14 @@ CVehicle::CVehicle(uint8 CreatedBy)
for(i = 0; i < m_nNumMaxPassengers; i++)
pPassengers[i] = nil;
m_nBombTimer = 0;
m_pWhoSetMeOnFire = nil;
m_pBlowUpEntity = nil;
field_1FB = 0;
bComedyControls = false;
m_veh_flagB40 = false;
m_veh_flagB80 = false;
m_veh_flagC1 = false;
bIsDamaged = false;
m_veh_flagC8 = false;
bFadeOut = false;
m_veh_flagC10 = false;
bHasBeenOwnedByPlayer = false;
m_veh_flagC20 = false;
@ -96,11 +96,11 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_comedyControlState = 0;
m_aCollPolys[0].valid = false;
m_aCollPolys[1].valid = false;
m_autoPilot.m_nCarMission = MISSION_NONE;
m_autoPilot.m_nAnimationId = TEMPACT_NONE;
m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
m_autoPilot.m_flag4 = false;
m_autoPilot.m_flag10 = false;
AutoPilot.m_nCarMission = MISSION_NONE;
AutoPilot.m_nAnimationId = TEMPACT_NONE;
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
AutoPilot.m_flag4 = false;
AutoPilot.m_flag10 = false;
}
CVehicle::~CVehicle()
@ -374,20 +374,18 @@ CVehicle::ProcessDelayedExplosion(void)
if(m_nBombTimer == 0)
return;
if(m_nBombTimer == 0){
int tick = CTimer::GetTimeStep()/60.0f*1000.0f;
if(tick > m_nBombTimer)
m_nBombTimer = 0;
else
m_nBombTimer -= tick;
int tick = CTimer::GetTimeStep()/60.0f*1000.0f;
if(tick > m_nBombTimer)
m_nBombTimer = 0;
else
m_nBombTimer -= tick;
if(IsCar() && ((CAutomobile*)this)->m_auto_flagA7 == 4 && (m_nBombTimer & 0xFE00) != 0xFE00)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f);
if(IsCar() && ((CAutomobile*)this)->m_bombType == 4 && (m_nBombTimer & 0xFE00) != 0xFE00)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f);
if(FindPlayerVehicle() != this && m_pWhoSetMeOnFire == FindPlayerPed())
CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this);
BlowUpCar(m_pWhoSetMeOnFire);
}
if(FindPlayerVehicle() != this && m_pBlowUpEntity == FindPlayerPed())
CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this);
BlowUpCar(m_pBlowUpEntity);
}
bool

View File

@ -126,7 +126,7 @@ class CVehicle : public CPhysical
public:
// 0x128
tHandlingData *m_handling;
CAutoPilot m_autoPilot;
CAutoPilot AutoPilot;
uint8 m_currentColour1;
uint8 m_currentColour2;
uint8 m_aExtras[2];
@ -162,14 +162,14 @@ public:
uint8 bIsBig: 1; // Is this vehicle a bus
uint8 bLowVehicle: 1; // Need this for sporty type cars to use low getting-in/out anims
uint8 bComedyControls : 1; // Will make the car hard to control (hopefully in a funny way)
uint8 m_veh_flagB20 : 1;
uint8 bWarnedPeds : 1; // Has scan and warn peds of danger been processed?
uint8 m_veh_flagB40 : 1;
uint8 m_veh_flagB80 : 1;
uint8 m_veh_flagC1 : 1;
uint8 bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components
uint8 bHasBeenOwnedByPlayer : 1;
uint8 m_veh_flagC8 : 1;
uint8 bHasBeenOwnedByPlayer : 1;// To work out whether stealing it is a crime
uint8 bFadeOut : 1; // Fade vehicle out
uint8 m_veh_flagC10 : 1;
uint8 m_veh_flagC20 : 1;
uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions
@ -196,7 +196,7 @@ public:
uint32 m_nTimeOfDeath;
int16 field_214;
int16 m_nBombTimer; // goes down with each frame
CPed *m_pWhoSetMeOnFire;
CEntity *m_pBlowUpEntity;
float field_21C;
float field_220;
eCarLock m_nDoorLock;