mirror of
https://github.com/GTAmodding/re3.git
synced 2024-11-16 06:18:59 +00:00
forgot the fucking file
This commit is contained in:
parent
2ca3c50463
commit
b73e42346e
1 changed files with 782 additions and 0 deletions
782
src/vehicles/Bike.cpp
Normal file
782
src/vehicles/Bike.cpp
Normal file
|
@ -0,0 +1,782 @@
|
|||
#include "common.h"
|
||||
#include "General.h"
|
||||
#include "Pad.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Camera.h"
|
||||
#include "Darkel.h"
|
||||
#include "Explosion.h"
|
||||
#include "World.h"
|
||||
#include "CarCtrl.h"
|
||||
#include "Stats.h"
|
||||
#include "AnimManager.h"
|
||||
#include "AnimBlendAssociation.h"
|
||||
#include "Ped.h"
|
||||
#include "PlayerPed.h"
|
||||
#include "DamageManager.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Automobile.h"
|
||||
#include "Bike.h"
|
||||
|
||||
#define FAKESUSPENSION (99999.992f)
|
||||
|
||||
CBike::CBike(int32 id, uint8 CreatedBy)
|
||||
: CVehicle(CreatedBy)
|
||||
{
|
||||
int i;
|
||||
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
|
||||
switch(GetModelIndex()){
|
||||
case MI_ANGEL:
|
||||
case MI_FREEWAY:
|
||||
m_bikeAnimType = ASSOCGRP_BIKE_HARLEY;
|
||||
break;
|
||||
case MI_PIZZABOY:
|
||||
case MI_FAGGIO:
|
||||
m_bikeAnimType = ASSOCGRP_BIKE_VESPA;
|
||||
break;
|
||||
case MI_PCJ600:
|
||||
m_bikeAnimType = ASSOCGRP_BIKE_STANDARD;
|
||||
break;
|
||||
case MI_SANCHEZ:
|
||||
m_bikeAnimType = ASSOCGRP_BIKE_DIRT;
|
||||
break;
|
||||
}
|
||||
m_vehType = VEHICLE_TYPE_BIKE;
|
||||
|
||||
m_fFireBlowUpTimer = 0.0f;
|
||||
m_doingBurnout = 0;
|
||||
m_bike_flag01 = false;
|
||||
|
||||
SetModelIndex(id);
|
||||
|
||||
pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId);
|
||||
pBikeHandling = mod_HandlingManager.GetBikePointer((eHandlingId)mi->m_handlingId);
|
||||
pFlyingHandling = mod_HandlingManager.GetFlyingPointer((eHandlingId)mi->m_handlingId);
|
||||
|
||||
m_bike_unused1 = 20.0f;
|
||||
m_bike_unused2 = 0;
|
||||
|
||||
mi->ChooseVehicleColour(m_currentColour1, m_currentColour2);
|
||||
|
||||
m_fRearForkLength = 0.0f;
|
||||
m_fFrontForkY = 0.0;
|
||||
m_fFrontForkZ = 0.0;
|
||||
m_fFrontForkSlope = Tan(DEGTORAD(mi->m_bikeSteerAngle));
|
||||
|
||||
m_fMass = pHandling->fMass;
|
||||
m_fTurnMass = pHandling->fTurnMass;
|
||||
m_vecCentreOfMass = pHandling->CentreOfMass;
|
||||
m_vecCentreOfMass.z = 0.1f;
|
||||
m_fAirResistance = pHandling->Dimension.x*pHandling->Dimension.z/m_fMass;
|
||||
m_fElasticity = 0.05f;
|
||||
m_fBuoyancy = pHandling->fBuoyancy;
|
||||
|
||||
m_fSteerAngle = 0.0f;
|
||||
m_fBikeSteerAngle = 0.0f;
|
||||
m_fLeanLRAngle = 0.0f;
|
||||
m_fLeanLRAngle2 = 0.0f;
|
||||
m_fGasPedal = 0.0f;
|
||||
m_fBrakePedal = 0.0f;
|
||||
m_fLeanInput = 0.0f;
|
||||
field_478 = 0;
|
||||
field_47C = 0;
|
||||
m_pSetOnFireEntity = nil;
|
||||
m_pBombRigger = nil;
|
||||
m_fGasPedalAudio = 0.0f;
|
||||
m_bike_flag02 = false;
|
||||
m_bike_flag04 = false;
|
||||
m_bike_flag08 = false;
|
||||
m_bike_flag10 = false;
|
||||
m_bike_flag20 = false;
|
||||
m_bike_flag40 = false;
|
||||
m_bike_flag80 = false;
|
||||
|
||||
m_fTireTemperature = 0.0f;
|
||||
someAngle = 0.0f;
|
||||
field_490 = 0;
|
||||
|
||||
for(i = 0; i < 2; i++){
|
||||
m_aWheelRotation[i] = 0.0f;
|
||||
m_aWheelSpeed[i] = 0.0f;
|
||||
m_aWheelState[i] = WHEEL_STATE_NORMAL;
|
||||
m_aWheelSkidmarkType[i] = SKIDMARK_NORMAL;
|
||||
m_aWheelSkidmarkBloody[i] = false;
|
||||
m_aWheelSkidmarkUnk[0] = false;
|
||||
m_wheelStatus[i] = WHEEL_STATUS_OK;
|
||||
}
|
||||
|
||||
for(i = 0; i < 4; i++){
|
||||
m_aGroundPhysical[i] = nil;
|
||||
m_aGroundOffset[i] = CVector(0.0f, 0.0f, 0.0f);
|
||||
m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i] = 1.0f;
|
||||
m_aWheelTimer[i] = 0.0f;
|
||||
}
|
||||
|
||||
m_nWheelsOnGround = 0;
|
||||
m_nDriveWheelsOnGround = 0;
|
||||
m_nDriveWheelsOnGroundPrev = 0;
|
||||
m_fHeightAboveRoad = 0.0f;
|
||||
m_fTraction = 1.0f;
|
||||
|
||||
CColModel *colModel = mi->GetColModel();
|
||||
if(colModel->lines == nil){
|
||||
colModel->lines = (CColLine*)RwMalloc(4*sizeof(CColLine));
|
||||
colModel->numLines = 4;
|
||||
}
|
||||
// BUG? this would make more sense in the if above
|
||||
colModel->lines[0].p0.z = FAKESUSPENSION;
|
||||
|
||||
SetupSuspensionLines();
|
||||
|
||||
AutoPilot.m_nCarMission = MISSION_NONE;
|
||||
AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
||||
AutoPilot.m_bStayInCurrentLevel = false;
|
||||
|
||||
SetStatus(STATUS_SIMPLE);
|
||||
bUseCollisionRecords = true;
|
||||
m_nNumPassengers = 0;
|
||||
bIsVan = false;
|
||||
bIsBus = false;
|
||||
bIsBig = false;
|
||||
bLowVehicle = false;
|
||||
bPedPhysics = false;
|
||||
|
||||
bLeanMatrixClean = false;
|
||||
m_leanMatrix = GetMatrix();
|
||||
}
|
||||
|
||||
void
|
||||
CBike::SetModelIndex(uint32 id)
|
||||
{
|
||||
CVehicle::SetModelIndex(id);
|
||||
SetupModelNodes();
|
||||
}
|
||||
|
||||
void
|
||||
CBike::ProcessControl(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CBike::Teleport(CVector pos)
|
||||
{
|
||||
CWorld::Remove(this);
|
||||
|
||||
SetPosition(pos);
|
||||
SetOrientation(0.0f, 0.0f, 0.0f);
|
||||
SetMoveSpeed(0.0f, 0.0f, 0.0f);
|
||||
SetTurnSpeed(0.0f, 0.0f, 0.0f);
|
||||
|
||||
ResetSuspension();
|
||||
|
||||
CWorld::Add(this);
|
||||
}
|
||||
|
||||
void
|
||||
CBike::PreRender(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CBike::Render(void)
|
||||
{
|
||||
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
|
||||
|
||||
m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 3000;
|
||||
mi->SetVehicleColour(m_currentColour1, m_currentColour2);
|
||||
CEntity::Render();
|
||||
}
|
||||
|
||||
int32
|
||||
CBike::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
|
||||
{
|
||||
int i;
|
||||
CColModel *colModel;
|
||||
|
||||
if(GetStatus() != STATUS_SIMPLE)
|
||||
bVehicleColProcessed = true;
|
||||
|
||||
colModel = GetColModel();
|
||||
|
||||
int numWheelCollisions = 0;
|
||||
float prevRatios[4] = { 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
for(i = 0; i < 4; i++)
|
||||
prevRatios[i] = m_aSuspensionSpringRatio[i];
|
||||
|
||||
if(m_bIsVehicleBeingShifted || bSkipLineCol || ent->IsPed() ||
|
||||
GetModelIndex() == MI_DODO && ent->IsVehicle())
|
||||
colModel->numLines = 0;
|
||||
|
||||
int numCollisions = CCollision::ProcessColModels(GetMatrix(), *colModel,
|
||||
ent->GetMatrix(), *ent->GetColModel(),
|
||||
colpoints,
|
||||
m_aWheelColPoints, m_aSuspensionSpringRatio);
|
||||
|
||||
// m_aSuspensionSpringRatio are now set to the point where the tyre touches ground.
|
||||
// In ProcessControl these will be re-normalized to ignore the tyre radius.
|
||||
|
||||
if(colModel->numLines){
|
||||
for(i = 0; i < 4; i++)
|
||||
if(m_aSuspensionSpringRatio[i] < 1.0f && m_aSuspensionSpringRatio[i] < prevRatios[i]){
|
||||
numWheelCollisions++;
|
||||
|
||||
// wheel is touching a physical
|
||||
if(ent->IsVehicle() || ent->IsObject()){
|
||||
CPhysical *phys = (CPhysical*)ent;
|
||||
|
||||
m_aGroundPhysical[i] = phys;
|
||||
phys->RegisterReference((CEntity**)&m_aGroundPhysical[i]);
|
||||
m_aGroundOffset[i] = m_aWheelColPoints[i].point - phys->GetPosition();
|
||||
}
|
||||
|
||||
m_nSurfaceTouched = m_aWheelColPoints[i].surfaceB;
|
||||
if(ent->IsBuilding())
|
||||
m_pCurGroundEntity = ent;
|
||||
}
|
||||
}else
|
||||
colModel->numLines = 4;
|
||||
|
||||
if(numCollisions > 0 || numWheelCollisions > 0){
|
||||
AddCollisionRecord(ent);
|
||||
if(!ent->IsBuilding())
|
||||
((CPhysical*)ent)->AddCollisionRecord(this);
|
||||
|
||||
if(numCollisions > 0)
|
||||
if(ent->IsBuilding() ||
|
||||
ent->IsObject() && ((CPhysical*)ent)->bInfiniteMass)
|
||||
bHasHitWall = true;
|
||||
}
|
||||
|
||||
return numCollisions;
|
||||
}
|
||||
|
||||
static int16 nLastControlInput;
|
||||
static float fMouseCentreRange = 0.35f;
|
||||
static float fMouseSteerSens = -0.0035f;
|
||||
static float fMouseCentreMult = 0.975f;
|
||||
|
||||
void
|
||||
CBike::ProcessControlInputs(uint8 pad)
|
||||
{
|
||||
float speed = DotProduct(m_vecMoveSpeed, GetForward());
|
||||
|
||||
if(CPad::GetPad(pad)->GetExitVehicle())
|
||||
bIsHandbrakeOn = true;
|
||||
else
|
||||
bIsHandbrakeOn = !!CPad::GetPad(pad)->GetHandBrake();
|
||||
|
||||
// Steer left/right
|
||||
#ifdef FIX_BUGS
|
||||
if(CCamera::m_bUseMouse3rdPerson && !CVehicle::m_bDisableMouseSteering){
|
||||
if(CPad::GetPad(pad)->GetMouseX() != 0.0f){
|
||||
m_fSteerInput += fMouseSteerSens*CPad::GetPad(pad)->GetMouseX();
|
||||
nLastControlInput = 2;
|
||||
if(Abs(m_fSteerInput) < fMouseCentreRange)
|
||||
m_fSteerInput *= Pow(fMouseCentreMult, CTimer::GetTimeStep());
|
||||
}else if(CPad::GetPad(pad)->GetSteeringLeftRight() || nLastControlInput != 2){
|
||||
// mouse hasn't move, steer with pad like below
|
||||
m_fSteerInput += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerInput)*
|
||||
0.2f*CTimer::GetTimeStep();
|
||||
nLastControlInput = 0;
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
m_fSteerInput += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerInput)*
|
||||
0.2f*CTimer::GetTimeStep();
|
||||
nLastControlInput = 0;
|
||||
}
|
||||
m_fSteerInput = clamp(m_fSteerInput, -1.0f, 1.0f);
|
||||
|
||||
// Lean forward/backward
|
||||
float updown = -CPad::GetPad(pad)->GetSteeringUpDown()/128.0f + CPad::GetPad(pad)->GetCarGunUpDown()/128.0f;
|
||||
m_fLeanInput += (updown - m_fLeanInput)*0.2f*CTimer::GetTimeStep();
|
||||
m_fLeanInput = clamp(m_fLeanInput, -1.0f, 1.0f);
|
||||
|
||||
// Accelerate/Brake
|
||||
float acceleration = (CPad::GetPad(pad)->GetAccelerate() - CPad::GetPad(pad)->GetBrake())/255.0f;
|
||||
if(GetModelIndex() == MI_DODO && acceleration < 0.0f)
|
||||
acceleration *= 0.3f;
|
||||
if(Abs(speed) < 0.01f){
|
||||
// standing still, go into direction we want
|
||||
if(CPad::GetPad(pad)->GetAccelerate() > 150.0f && CPad::GetPad(pad)->GetBrake() > 150.0f){
|
||||
m_fGasPedal = CPad::GetPad(pad)->GetAccelerate()/255.0f;
|
||||
m_fBrakePedal = CPad::GetPad(pad)->GetBrake()/255.0f;
|
||||
m_doingBurnout = 1;
|
||||
}else{
|
||||
m_fGasPedal = acceleration;
|
||||
m_fBrakePedal = 0.0f;
|
||||
}
|
||||
}else{
|
||||
#if 1
|
||||
// simpler than the code below
|
||||
if(speed * acceleration < 0.0f){
|
||||
// if opposite directions, have to brake first
|
||||
m_fGasPedal = 0.0f;
|
||||
m_fBrakePedal = Abs(acceleration);
|
||||
}else{
|
||||
// accelerating in same direction we were already going
|
||||
m_fGasPedal = acceleration;
|
||||
m_fBrakePedal = 0.0f;
|
||||
}
|
||||
#else
|
||||
if(speed < 0.0f){
|
||||
// moving backwards currently
|
||||
if(acceleration < 0.0f){
|
||||
// still go backwards
|
||||
m_fGasPedal = acceleration;
|
||||
m_fBrakePedal = 0.0f;
|
||||
}else{
|
||||
// want to go forwards, so brake
|
||||
m_fGasPedal = 0.0f;
|
||||
m_fBrakePedal = acceleration;
|
||||
}
|
||||
}else{
|
||||
// moving forwards currently
|
||||
if(acceleration < 0.0f){
|
||||
// want to go backwards, so brake
|
||||
m_fGasPedal = 0.0f;
|
||||
m_fBrakePedal = -acceleration;
|
||||
}else{
|
||||
// still go forwards
|
||||
m_fGasPedal = acceleration;
|
||||
m_fBrakePedal = 0.0f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Actually turn wheels
|
||||
static float fValue; // why static?
|
||||
if(m_fSteerInput < 0.0f)
|
||||
fValue = -sq(m_fSteerInput);
|
||||
else
|
||||
fValue = sq(m_fSteerInput);
|
||||
m_fSteerAngle = DEGTORAD(pHandling->fSteeringLock) * fValue;
|
||||
|
||||
if(bComedyControls){
|
||||
if(((CTimer::GetTimeInMilliseconds() >> 10) & 0xF) < 12)
|
||||
m_fGasPedal = 1.0f;
|
||||
if((((CTimer::GetTimeInMilliseconds() >> 10)+6) & 0xF) < 12)
|
||||
m_fBrakePedal = 0.0f;
|
||||
bIsHandbrakeOn = false;
|
||||
if(CTimer::GetTimeInMilliseconds() & 0x800)
|
||||
m_fSteerAngle += 0.08f;
|
||||
else
|
||||
m_fSteerAngle -= 0.03f;
|
||||
}
|
||||
|
||||
// Brake if player isn't in control
|
||||
// BUG: game always uses pad 0 here
|
||||
if(CPad::GetPad(pad)->ArePlayerControlsDisabled()){
|
||||
m_fBrakePedal = 1.0f;
|
||||
bIsHandbrakeOn = true;
|
||||
m_fGasPedal = 0.0f;
|
||||
|
||||
FindPlayerPed()->KeepAreaAroundPlayerClear();
|
||||
|
||||
// slow down car immediately
|
||||
speed = m_vecMoveSpeed.Magnitude();
|
||||
if(speed > 0.28f)
|
||||
m_vecMoveSpeed *= 0.28f/speed;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBike::GetComponentWorldPosition(int32 component, CVector &pos)
|
||||
{
|
||||
if(m_aBikeNodes[component] == nil){
|
||||
printf("BikeNode missing: %d %d\n", GetModelIndex(), component);
|
||||
return;
|
||||
}
|
||||
RwMatrix *ltm = RwFrameGetLTM(m_aBikeNodes[component]);
|
||||
pos = *RwMatrixGetPos(ltm);
|
||||
}
|
||||
|
||||
bool
|
||||
CBike::IsComponentPresent(int32 component)
|
||||
{
|
||||
return m_aBikeNodes[component] != nil;
|
||||
}
|
||||
|
||||
void
|
||||
CBike::SetComponentRotation(int32 component, CVector rotation)
|
||||
{
|
||||
CMatrix mat(RwFrameGetMatrix(m_aBikeNodes[component]));
|
||||
CVector pos = mat.GetPosition();
|
||||
// BUG: all these set the whole matrix
|
||||
mat.SetRotateX(DEGTORAD(rotation.x));
|
||||
mat.SetRotateY(DEGTORAD(rotation.y));
|
||||
mat.SetRotateZ(DEGTORAD(rotation.z));
|
||||
mat.Translate(pos);
|
||||
mat.UpdateRW();
|
||||
}
|
||||
|
||||
bool
|
||||
CBike::IsDoorReady(eDoors door)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CBike::IsDoorFullyOpen(eDoors door)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CBike::IsDoorClosed(eDoors door)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CBike::IsDoorMissing(eDoors door)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CBike::RemoveRefsToVehicle(CEntity *ent)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 4; i++)
|
||||
if(m_aGroundPhysical[i] == ent)
|
||||
m_aGroundPhysical[i] = nil;
|
||||
}
|
||||
|
||||
void
|
||||
CBike::BlowUpCar(CEntity *culprit)
|
||||
{
|
||||
if(!bCanBeDamaged)
|
||||
return;
|
||||
|
||||
// explosion pushes vehicle up
|
||||
m_vecMoveSpeed.z += 0.13f;
|
||||
SetStatus(STATUS_WRECKED);
|
||||
bRenderScorched = true;
|
||||
|
||||
m_fHealth = 0.0f;
|
||||
m_nBombTimer = 0;
|
||||
|
||||
TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z);
|
||||
|
||||
KillPedsInVehicle();
|
||||
|
||||
bEngineOn = false;
|
||||
bLightsOn = false;
|
||||
ChangeLawEnforcerState(false);
|
||||
|
||||
CExplosion::AddExplosion(this, culprit, EXPLOSION_CAR, GetPosition(), 0);
|
||||
CDarkel::RegisterCarBlownUpByPlayer(this);
|
||||
}
|
||||
|
||||
bool
|
||||
CBike::SetUpWheelColModel(CColModel *colModel)
|
||||
{
|
||||
// TODO, but unused
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CBike::BurstTyre(uint8 wheel, bool applyForces)
|
||||
{
|
||||
if(bTyresDontBurst)
|
||||
return;
|
||||
|
||||
switch(wheel){
|
||||
case CAR_PIECE_WHEEL_LF: wheel = BIKEWHEEL_FRONT; break;
|
||||
case CAR_PIECE_WHEEL_LR: wheel = BIKEWHEEL_REAR; break;
|
||||
default: assert(0 && "invalid wheel");
|
||||
}
|
||||
|
||||
if(m_wheelStatus[wheel] == WHEEL_STATUS_OK){
|
||||
m_wheelStatus[wheel] = WHEEL_STATUS_BURST;
|
||||
#ifdef FIX_BUGS
|
||||
CStats::TyresPopped++;
|
||||
#endif
|
||||
// TODO(MIAMI)
|
||||
// DMAudio.PlayOneShot(m_audioEntityId, SOUND_15, 0.0f);
|
||||
|
||||
if(GetStatus() == STATUS_SIMPLE){
|
||||
SetStatus(STATUS_PHYSICS);
|
||||
CCarCtrl::SwitchVehicleToRealPhysics(this);
|
||||
}
|
||||
|
||||
if(applyForces){
|
||||
ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-0.02f, 0.02f));
|
||||
ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.02f, 0.02f), GetForward());
|
||||
}
|
||||
// TODO: knock off driver
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CBike::IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset)
|
||||
{
|
||||
CColPoint colpoint;
|
||||
CEntity *ent;
|
||||
colpoint.point = CVector(0.0f, 0.0f, 0.0f);
|
||||
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
|
||||
|
||||
CVector seatPos = mi->GetFrontSeatPosn();
|
||||
if(component == CAR_DOOR_RR || component == CAR_DOOR_LR)
|
||||
seatPos = mi->m_positions[CAR_POS_BACKSEAT];
|
||||
if(component == CAR_DOOR_LF || component == CAR_DOOR_LR)
|
||||
seatPos.x = -seatPos.x;
|
||||
seatPos = GetMatrix() * seatPos;
|
||||
|
||||
CVector doorPos = CPed::GetPositionToOpenCarDoor(this, component);
|
||||
if(doorOffset){
|
||||
CVector off = *doorOffset;
|
||||
if(component == CAR_DOOR_RF || component == CAR_DOOR_RR)
|
||||
off.x = -off.x;
|
||||
doorPos += Multiply3x3(GetMatrix(), off);
|
||||
}
|
||||
|
||||
if(GetUp().z < 0.0f){
|
||||
seatPos.z += 0.5f;
|
||||
doorPos.z += 0.5f;
|
||||
}
|
||||
|
||||
CVector dist = doorPos - seatPos;
|
||||
|
||||
// Removing that makes thiProcessEntityCollisions func. return false for van doors.
|
||||
doorPos.z += 0.5f;
|
||||
float length = dist.Magnitude();
|
||||
CVector pedPos = seatPos + dist*((length+0.6f)/length);
|
||||
|
||||
if(!CWorld::GetIsLineOfSightClear(seatPos, pedPos, true, false, false, true, false, false))
|
||||
return false;
|
||||
if(CWorld::TestSphereAgainstWorld(doorPos, 0.6f, this, true, true, false, true, false, false))
|
||||
return false;
|
||||
if(CWorld::ProcessVerticalLine(doorPos, 1000.0f, colpoint, ent, true, false, false, true, false, false, nil))
|
||||
if(colpoint.point.z > doorPos.z && colpoint.point.z < doorPos.z + 0.6f)
|
||||
return false;
|
||||
float upperZ = colpoint.point.z;
|
||||
if(!CWorld::ProcessVerticalLine(doorPos, -1000.0f, colpoint, ent, true, false, false, true, false, false, nil))
|
||||
return false;
|
||||
if(upperZ != 0.0f && upperZ < colpoint.point.z)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
float
|
||||
CBike::GetHeightAboveRoad(void)
|
||||
{
|
||||
return m_fHeightAboveRoad;
|
||||
}
|
||||
|
||||
void
|
||||
CBike::PlayCarHorn(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (IsAlarmOn() || m_nCarHornTimer != 0)
|
||||
return;
|
||||
|
||||
if (m_nCarHornDelay) {
|
||||
m_nCarHornDelay--;
|
||||
return;
|
||||
}
|
||||
|
||||
m_nCarHornDelay = (CGeneral::GetRandomNumber() & 0x7F) + 150;
|
||||
r = m_nCarHornDelay & 7;
|
||||
if(r < 2){
|
||||
m_nCarHornTimer = 45;
|
||||
}else if(r < 4){
|
||||
if(pDriver)
|
||||
pDriver->Say(SOUND_PED_CAR_COLLISION);
|
||||
m_nCarHornTimer = 45;
|
||||
}else{
|
||||
if(pDriver)
|
||||
pDriver->Say(SOUND_PED_CAR_COLLISION);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBike::PlayHornIfNecessary(void)
|
||||
{
|
||||
if(AutoPilot.m_bSlowedDownBecauseOfPeds ||
|
||||
AutoPilot.m_bSlowedDownBecauseOfCars)
|
||||
PlayCarHorn();
|
||||
}
|
||||
|
||||
void
|
||||
CBike::ResetSuspension(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 2; i++){
|
||||
m_aWheelRotation[i] = 0.0f;
|
||||
m_aWheelState[i] = WHEEL_STATE_NORMAL;
|
||||
}
|
||||
for(i = 0; i < 4; i++){
|
||||
m_aSuspensionSpringRatio[i] = 1.0f;
|
||||
m_aWheelTimer[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: maybe put this somewhere else
|
||||
inline void
|
||||
GetRelativeMatrix(RwMatrix *mat, RwFrame *frm, RwFrame *end)
|
||||
{
|
||||
*mat = *RwFrameGetMatrix(frm);
|
||||
frm = RwFrameGetParent(frm);
|
||||
while(frm){
|
||||
RwMatrixTransform(mat, RwFrameGetMatrix(frm), rwCOMBINEPOSTCONCAT);
|
||||
frm = RwFrameGetParent(frm);
|
||||
if(frm == end)
|
||||
frm = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBike::SetupSuspensionLines(void)
|
||||
{
|
||||
int i;
|
||||
CVector posn;
|
||||
float suspOffset = 0.0f;
|
||||
RwFrame *node = nil;
|
||||
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
|
||||
CColModel *colModel = mi->GetColModel();
|
||||
RwMatrix *mat = RwMatrixCreate();
|
||||
|
||||
bool initialized = colModel->lines[0].p0.z != FAKESUSPENSION;
|
||||
|
||||
for(i = 0; i < 4; i++){
|
||||
if(initialized){
|
||||
posn = colModel->lines[i].p0;
|
||||
if(i < 2)
|
||||
posn.z = m_aWheelBasePosition[0];
|
||||
else
|
||||
posn.z = m_aWheelBasePosition[1];
|
||||
}else{
|
||||
switch(i){
|
||||
case BIKESUSP_FRONT_1:
|
||||
node = m_aBikeNodes[BIKE_WHEEL_FRONT];
|
||||
suspOffset = 0.25f*mi->m_wheelScale;
|
||||
break;
|
||||
case BIKESUSP_FRONT_2:
|
||||
node = m_aBikeNodes[BIKE_WHEEL_FRONT];
|
||||
suspOffset = -0.25f*mi->m_wheelScale;
|
||||
break;
|
||||
case BIKESUSP_REAR_1:
|
||||
node = m_aBikeNodes[BIKE_WHEEL_REAR];
|
||||
suspOffset = 0.25f*mi->m_wheelScale;
|
||||
break;
|
||||
case BIKESUSP_REAR_2:
|
||||
node = m_aBikeNodes[BIKE_WHEEL_REAR];
|
||||
suspOffset = -0.25f*mi->m_wheelScale;
|
||||
break;
|
||||
}
|
||||
|
||||
GetRelativeMatrix(mat, node, node);
|
||||
posn = *RwMatrixGetPos(mat);
|
||||
if(i == BIKESUSP_FRONT_1)
|
||||
m_aWheelBasePosition[BIKEWHEEL_FRONT] = posn.z;
|
||||
else if(i == BIKESUSP_REAR_1){
|
||||
m_aWheelBasePosition[BIKEWHEEL_REAR] = posn.z;
|
||||
|
||||
GetRelativeMatrix(mat, node, m_aBikeNodes[BIKE_FORKS_REAR]);
|
||||
float dz = posn.z - RwMatrixGetPos(mat)->z;
|
||||
float dy = posn.y - RwMatrixGetPos(mat)->y;
|
||||
m_fRearForkLength = Sqrt(SQR(dy) + SQR(dz));
|
||||
}
|
||||
posn.y += suspOffset;
|
||||
}
|
||||
|
||||
// uppermost wheel position
|
||||
posn.z += pHandling->fSuspensionUpperLimit;
|
||||
colModel->lines[i].p0 = posn;
|
||||
|
||||
// lowermost wheel position
|
||||
posn.z += pHandling->fSuspensionLowerLimit - pHandling->fSuspensionUpperLimit;
|
||||
// lowest point on tyre
|
||||
posn.z -= mi->m_wheelScale*0.5f;
|
||||
colModel->lines[i].p1 = posn;
|
||||
|
||||
// this is length of the spring at rest
|
||||
m_aSuspensionSpringLength[i] = pHandling->fSuspensionUpperLimit - pHandling->fSuspensionLowerLimit;
|
||||
m_aSuspensionLineLength[i] = colModel->lines[i].p0.z - colModel->lines[i].p1.z;
|
||||
}
|
||||
|
||||
if(!initialized){
|
||||
GetRelativeMatrix(mat, m_aBikeNodes[BIKE_FORKS_REAR], m_aBikeNodes[BIKE_FORKS_REAR]);
|
||||
m_fFrontForkY = RwMatrixGetPos(mat)->y;
|
||||
m_fFrontForkZ = RwMatrixGetPos(mat)->z;
|
||||
}
|
||||
|
||||
// Compress spring somewhat to get normal height on road
|
||||
m_fHeightAboveRoad = m_aSuspensionSpringLength[0]*(1.0f - 1.0f/(4.0f*pHandling->fSuspensionForceLevel))
|
||||
- colModel->lines[0].p0.z + mi->m_wheelScale*0.5f;
|
||||
for(i = 0; i < 2; i++)
|
||||
m_aWheelPosition[i] = mi->m_wheelScale*0.5f - m_fHeightAboveRoad;
|
||||
|
||||
// adjust col model to include suspension lines
|
||||
if(colModel->boundingBox.min.z > colModel->lines[0].p1.z)
|
||||
colModel->boundingBox.min.z = colModel->lines[0].p1.z;
|
||||
float radius = Max(colModel->boundingBox.min.Magnitude(), colModel->boundingBox.max.Magnitude());
|
||||
if(colModel->boundingSphere.radius < radius)
|
||||
colModel->boundingSphere.radius = radius;
|
||||
|
||||
#ifdef FIX_BUGS
|
||||
RwMatrixDestroy(mat);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CBike::CalculateLeanMatrix(void)
|
||||
{
|
||||
if(bLeanMatrixClean)
|
||||
return;
|
||||
|
||||
CMatrix mat;
|
||||
mat.SetRotateX(-0.05f*Abs(m_fLeanLRAngle));
|
||||
mat.RotateY(m_fLeanLRAngle);
|
||||
m_leanMatrix = GetMatrix();
|
||||
m_leanMatrix = m_leanMatrix * mat;
|
||||
// place wheel back on ground
|
||||
m_leanMatrix.GetPosition() += GetUp()*(1.0f-Cos(m_fLeanLRAngle))*GetColModel()->boundingBox.min.z;
|
||||
bLeanMatrixClean = true;
|
||||
}
|
||||
|
||||
void
|
||||
CBike::GetCorrectedWorldDoorPosition(CVector &pos, CVector p1, CVector p2)
|
||||
{
|
||||
CVector &fwd = GetForward();
|
||||
CVector rightWorld = CrossProduct(fwd, CVector(0.0f, 0.0f, 1.0f));
|
||||
CVector upWorld = CrossProduct(rightWorld, fwd);
|
||||
CColModel *colModel = GetColModel();
|
||||
float onSide = DotProduct(GetUp(), rightWorld);
|
||||
float diff = Max(colModel->boundingBox.max.z-colModel->boundingBox.max.x, 0.0f);
|
||||
pos = CVector(0.0f, 0.0f, 0.0f);
|
||||
float y = p2.y - p1.y;
|
||||
float x = onSide*diff + p2.x + p1.x;
|
||||
float z = p2.z - p1.z;
|
||||
pos = x*rightWorld + y*fwd + z*upWorld + GetPosition();
|
||||
}
|
||||
|
||||
void
|
||||
CBike::Fix(void)
|
||||
{
|
||||
bIsDamaged = false;
|
||||
m_bike_flag40 = false;
|
||||
m_wheelStatus[0] = WHEEL_STATUS_OK;
|
||||
m_wheelStatus[1] = WHEEL_STATUS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CBike::SetupModelNodes(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < BIKE_NUM_NODES; i++)
|
||||
m_aBikeNodes[i] = nil;
|
||||
CClumpModelInfo::FillFrameArray(GetClump(), m_aBikeNodes);
|
||||
}
|
||||
|
||||
void
|
||||
CBike::ReduceHornCounter(void)
|
||||
{
|
||||
if(m_nCarHornTimer != 0)
|
||||
m_nCarHornTimer--;
|
||||
}
|
Loading…
Reference in a new issue