summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/animation/AnimationId.h2
-rw-r--r--src/control/CarCtrl.cpp62
-rw-r--r--src/control/Script.cpp49
-rw-r--r--src/core/Cam.cpp53
-rw-r--r--src/peds/Ped.cpp579
-rw-r--r--src/peds/Ped.h6
-rw-r--r--src/peds/Population.cpp2
-rw-r--r--src/vehicles/Automobile.cpp4
-rw-r--r--src/vehicles/Bike.cpp76
-rw-r--r--src/vehicles/Bike.h8
-rw-r--r--src/vehicles/CarGen.cpp30
-rw-r--r--src/vehicles/Vehicle.cpp25
-rw-r--r--src/vehicles/Vehicle.h2
13 files changed, 717 insertions, 181 deletions
diff --git a/src/animation/AnimationId.h b/src/animation/AnimationId.h
index 18d31cae..9cf470e0 100644
--- a/src/animation/AnimationId.h
+++ b/src/animation/AnimationId.h
@@ -146,7 +146,7 @@ enum AnimationId
ANIM_CAR_CRAWLOUT_RHS,
ANIM_CAR_CRAWLOUT_RHS2,
ANIM_CAR_ROLLOUT_LHS,
- ANIM_CAR_ROLLOUT_RHS, // was this meant to be RHS?
+ ANIM_CAR_ROLLOUT_RHS,
ANIM_GETUP1,
ANIM_GETUP2,
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index ebaa5f29..ae57e030 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -4,6 +4,7 @@
#include "Accident.h"
#include "Automobile.h"
+#include "Bike.h"
#include "Camera.h"
#include "CarAI.h"
#include "CarGen.h"
@@ -345,7 +346,7 @@ CCarCtrl::GenerateOneRandomCar()
if (CModelInfo::IsBoatModel(carModel))
pVehicle = new CBoat(carModel, RANDOM_VEHICLE);
else if (CModelInfo::IsBikeModel(carModel))
- return; // TODO(MIAMI): spawn bikes
+ pVehicle = new CBike(carModel, RANDOM_VEHICLE);
else
pVehicle = new CAutomobile(carModel, RANDOM_VEHICLE);
pVehicle->AutoPilot.m_nPrevRouteNode = 0;
@@ -2502,7 +2503,7 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
pSwerve, pAccel, pBrake, pHandbrake);
return;
case MISSION_HELI_FLYTOCOORS:
- //SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
+ SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
return;
case MISSION_ATTACKPLAYER:
SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
@@ -2656,9 +2657,8 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
else
speed *= 0.2f;
}
- CVector2D vecAdvanceThisFrame = vecToTarget;
- vecAdvanceThisFrame.Normalise();
- vecAdvanceThisFrame *= speed;
+ vecToTarget.Normalise();
+ CVector2D vecAdvanceThisFrame(vecToTarget * speed);
float resistance = Pow(0.997f, CTimer::GetTimeStep());
pHeli->m_vecMoveSpeed.x *= resistance;
pHeli->m_vecMoveSpeed.y *= resistance;
@@ -2673,9 +2673,55 @@ void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
pHeli->AddToMoveSpeed(vecAdvanceThisFrame);
else
pHeli->AddToMoveSpeed(vecSpeedChange * changeMultiplier);
- pHeli->SetPosition(pHeli->GetPosition() + CVector(CTimer::GetTimeStep() * pHeli->m_vecMoveSpeed.x, CTimer::GetTimeStep() * pHeli->m_vecMoveSpeed.y, 0.0f));
- assert(0);
- // This is not finished yet. Heli fields in CAutomobile required
+ pHeli->SetPosition(pHeli->GetPosition() + CVector(CTimer::GetTimeStep() * pHeli->GetMoveSpeed().x, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().y, 0.0f));
+ float ZTarget = pHeli->AutoPilot.m_vecDestinationCoors.z;
+ if (CTimer::GetTimeInMilliseconds() & 0x800) // switch every ~2 seconds
+ ZTarget += 2.0f;
+ float ZSpeedTarget = (ZTarget - pHeli->GetPosition().z) * 0.01f;
+ float ZSpeedChangeTarget = ZSpeedTarget - pHeli->GetMoveSpeed().z;
+ float ZSpeedChangeMax = 0.01f * CTimer::GetTimeStep();
+ if (!pHeli->bHeliDestroyed) {
+ if (Abs(ZSpeedChangeTarget) < ZSpeedChangeMax)
+ pHeli->SetMoveSpeed(pHeli->GetMoveSpeed().x, pHeli->GetMoveSpeed().y, ZSpeedTarget);
+ else if (ZSpeedChangeTarget < 0.0f)
+ pHeli->AddToMoveSpeed(0.0f, 0.0f, 1.5f * ZSpeedChangeMax);
+ else
+ pHeli->AddToMoveSpeed(0.0f, 0.0f, ZSpeedChangeMax);
+ }
+ pHeli->SetPosition(pHeli->GetPosition() + CVector(0.0f, 0.0f, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().z));
+ pHeli->SetTurnSpeed(pHeli->GetTurnSpeed().x, pHeli->GetTurnSpeed().y, pHeli->GetTurnSpeed().z * Pow(0.99f, CTimer::GetTimeStep()));
+ float ZTurnSpeedTarget;
+ if (distanceToTarget < 8.0f && pHeli->m_fHeliOrientation < 0.0f)
+ ZTurnSpeedTarget = 0.0f;
+ else {
+ float fAngleTarget = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y) + PI;
+ if (pHeli->m_fHeliOrientation >= 0.0f)
+ fAngleTarget = pHeli->m_fHeliOrientation;
+ while (fAngleTarget < -PI)
+ fAngleTarget += TWOPI;
+ while (fAngleTarget > PI)
+ fAngleTarget -= TWOPI;
+ if (Abs(fAngleTarget) <= 0.4f)
+ ZTurnSpeedTarget = 0.0f;
+ else if (fAngleTarget < 0.0f)
+ ZTurnSpeedTarget = 0.03f;
+ else
+ ZTurnSpeedTarget = -0.03f;
+ }
+ float ZTurnSpeedChangeTarget = ZTurnSpeedTarget - pHeli->GetTurnSpeed().z;
+ pHeli->m_fOrientation += pHeli->GetTurnSpeed().z * CTimer::GetTimeStep();
+ CVector up;
+ if (pHeli->bHeliMinimumTilt)
+ up = CVector(0.5f * pHeli->GetMoveSpeed().x, 0.5f * pHeli->GetMoveSpeed().y, 1.0f);
+ else
+ up = CVector(3.0f * pHeli->GetMoveSpeed().x, 3.0f * pHeli->GetMoveSpeed().y, 1.0f);
+ up.Normalise();
+ CVector forward(Sin(pHeli->m_fOrientation), Cos(pHeli->m_fOrientation), 0.0f);
+ CVector right = CrossProduct(up, forward);
+ forward = CrossProduct(up, right);
+ pHeli->GetMatrix().GetRight() = right;
+ pHeli->GetMatrix().GetForward() = forward;
+ pHeli->GetMatrix().GetUp() = up;
}
void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index f59701b3..a2c60872 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -4,6 +4,7 @@
#include "ScriptCommands.h"
#include "AnimBlendAssociation.h"
+#include "Bike.h"
#include "Boat.h"
#include "BulletInfo.h"
#include "Camera.h"
@@ -2189,9 +2190,12 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
else {
CVehicle* car;
- // TODO(MIAMI)
- //if (!CModelInfo::IsBikeModel(ScriptParams[0]))
- car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE);
+ if (!CModelInfo::IsBikeModel(ScriptParams[0]))
+ car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE);
+ else {
+ car = new CBike(ScriptParams[0], MISSION_VEHICLE);
+ ((CBike*)(car))->bIsStanding = true;
+ }
CVector pos = *(CVector*)&ScriptParams[1];
if (pos.z <= MAP_Z_LOW_LIMIT)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
@@ -4953,7 +4957,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
pPed->FlagToDestroyWhenNextProcessed();
}
else {
- pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ pPed->SetDie();
}
return 0;
}
@@ -7406,7 +7410,13 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
if (pPed->GetPedState() == PED_EXIT_CAR || pPed->GetPedState() == PED_DRAG_FROM_CAR) {
uint8 flags = 0;
if (pPed->m_pMyVehicle->IsBike()) {
- //TODO(MIAMI)
+ if (pPed->m_vehEnterType == CAR_DOOR_LF ||
+ pPed->m_vehEnterType == CAR_DOOR_RF ||
+ pPed->m_vehEnterType == CAR_WINDSCREEN)
+ flags = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF;
+ else if (pPed->m_vehEnterType == CAR_DOOR_LR ||
+ pPed->m_vehEnterType == CAR_DOOR_RR)
+ flags = CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR;
}
else {
switch (pPed->m_vehEnterType) {
@@ -8046,7 +8056,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
if (pVehicle->IsBike()) {
- //TODO(MIAMI)
+ CBike* pBike = (CBike*)pVehicle;
+ pBike->bWaterTight = ScriptParams[1] != 0;
}
else if (pVehicle->IsCar()) {
CAutomobile* pCar = (CAutomobile*)pVehicle;
@@ -8542,8 +8553,12 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (model == -1)
return 0;
CVehicle* car;
- //if (CModelInfo::IsBikeModel(model)) // TODO(MIAMI)
- car = new CAutomobile(model, MISSION_VEHICLE);
+ if (CModelInfo::IsBikeModel(model)) {
+ car = new CBike(model, MISSION_VEHICLE);
+ ((CBike*)(car))->bIsStanding = true;
+ }
+ else
+ car = new CAutomobile(model, MISSION_VEHICLE);
CVector pos = *(CVector*)&ScriptParams[0];
pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel();
car->SetPosition(pos);
@@ -9248,8 +9263,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
if (pVehicle->m_vehType == VEHICLE_TYPE_CAR)
((CAutomobile*)pVehicle)->m_fTraction = fTraction;
else
- // TODO(MIAMI)
- //((CBike*)pVehicle)->m_fTraction = fTraction;
+ ((CBike*)pVehicle)->m_fTraction = fTraction;
return 0;
}
case COMMAND_ARE_MEASUREMENTS_IN_METRES:
@@ -10337,8 +10351,21 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(pVehicle);
bool bIsBurst = false;
+ CBike* pBike = (CBike*)pVehicle;
if (pVehicle->m_vehType == VEHICLE_APPEARANCE_BIKE) {
- assert("IS_CAR_TYPE_BURST not yet implemented for bikes");
+ if (ScriptParams[1] == 4) {
+ for (int i = 0; i < 2; i++) {
+ if (pBike->m_wheelStatus[i] == WHEEL_STATUS_BURST)
+ bIsBurst = true;
+ }
+ }
+ else {
+ if (ScriptParams[1] == 2)
+ ScriptParams[1] = 0;
+ if (ScriptParams[1] == 3)
+ ScriptParams[1] = 1;
+ bIsBurst = pBike->m_wheelStatus[ScriptParams[1]] == WHEEL_STATUS_BURST;
+ }
}
else {
CAutomobile* pCar = (CAutomobile*)pVehicle;
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index ac80fe83..fd45a374 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -25,6 +25,7 @@
#include "Debug.h"
#include "Camera.h"
#include "DMAudio.h"
+#include "Bike.h"
bool PrintDebugCode = false;
int16 DebugCamMode;
@@ -4628,9 +4629,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
uint8 camSetArrPos = 0;
// We may need those later
- bool isPlane = car->GetModelIndex() == MI_DODO;
- bool isHeli = false;
- bool isBike = false;
+ bool isPlane = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_PLANE;
+ bool isHeli = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI;
+ bool isBike = car->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE || car->IsBike();
bool isCar = car->IsCar() && !isPlane && !isHeli && !isBike;
CPad* pad = CPad::GetPad(0);
@@ -4641,8 +4642,10 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (car->GetModelIndex() == MI_FIRETRUCK) {
camSetArrPos = 7;
- } else if (car->GetModelIndex() == MI_RCBANDIT) {
+ } else if (car->GetModelIndex() == MI_RCBANDIT || car->GetModelIndex() == MI_RCBARON) {
camSetArrPos = 5;
+ } else if (car->GetModelIndex() == MI_RCGOBLIN || car->GetModelIndex() == MI_RCRAIDER) {
+ camSetArrPos = 6;
} else if (car->IsBoat()) {
camSetArrPos = 4;
} else if (isBike) {
@@ -4699,6 +4702,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float newDistance = TheCamera.CarZoomValueSmooth + CARCAM_SET[camSetArrPos][1] + approxCarLength;
+ // Taken from VC CCam::Cam_On_A_String_Unobscured. If we don't this, we will end up seeing the world from the inside of RC Goblin/Raider.
+ // I couldn't find where SA does that. It's possible that they've increased the size of these veh.'s collision bounding box.
+ if (car->m_modelIndex == MI_RCRAIDER || car->m_modelIndex == MI_RCBANDIT) {
+ newDistance += 6.0f;
+ } else if (car->m_modelIndex == MI_RCBARON) {
+ newDistance += 9.5f;
+ }
+
float minDistForThisCar = approxCarLength * CARCAM_SET[camSetArrPos][3];
if (!isHeli || car->GetStatus() == STATUS_PLAYER_REMOTE) {
@@ -4713,6 +4724,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
TargetCoors += 0.6f * car->GetUp() * colMaxZ;
}
+ if (car->m_modelIndex == MI_RCGOBLIN)
+ zoomModeAlphaOffset += 0.178997f;
+
float minDistForVehType = CARCAM_SET[camSetArrPos][4];
if (TheCamera.CarZoomIndicator == CAM_ZOOM_1 && (camSetArrPos < 2 || camSetArrPos == 7)) {
@@ -4727,6 +4741,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (ResetStatics) {
FOV = DefaultFOV;
+ // TODO(Miami): Remove that when cam is done!
// GTA 3 has this in veh. camera
if (TheCamera.m_bIdleOn)
TheCamera.m_uiTimeWeEnteredIdle = CTimer::GetTimeInMilliseconds();
@@ -4763,10 +4778,12 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
ResetStatics = false;
Rotating = false;
m_bCollisionChecksOn = true;
- // TheCamera.m_bResetOldMatrix = 1;
+
+
+ // TODO(Miami): Uncomment that when cam is done!
// Garage exit cam is not working well in III...
- // if (!TheCamera.m_bJustCameOutOfGarage) // && !sthForScript)
+ // if (!TheCamera.m_bJustCameOutOfGarage)
// {
Alpha = 0.0f;
Beta = car->GetForward().Heading() - HALFPI;
@@ -4788,7 +4805,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
m_aTargetHistoryPosTwo = TargetCoors - newDistance * Front;
m_nCurrentHistoryPoints = 0;
- if (!TheCamera.m_bJustCameOutOfGarage) // && !sthForScript)
+ if (!TheCamera.m_bJustCameOutOfGarage)
Alpha = -zoomModeAlphaOffset;
}
@@ -4840,9 +4857,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// This is also original LCS and SA bug, or some attempt to fix lag. We'll never know
// if (car->m_vecMoveSpeed.MagnitudeSqr() < sq(0.2f))
- if (car->GetModelIndex() != MI_FIRETRUCK) {
- // if (!isBike || GetMysteriousWheelRelatedThingBike(car) > 3)
- // if (!isHeli && (!isPlane || car->GetWheelsOnGround())) {
+ if (car->GetModelIndex() != MI_FIRETRUCK)
+ if (!isBike || ((CBike*)car)->m_nWheelsOnGround > 3)
+ if (!isHeli && (!isPlane || ((CAutomobile*)car)->m_nWheelsOnGround)) {
CVector left = CrossProduct(car->GetForward(), CVector(0.0f, 0.0f, 1.0f));
left.Normalise();
@@ -5000,8 +5017,8 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
Beta += TWOPI;
if ((camSetArrPos <= 1 || camSetArrPos == 7) && targetAlpha < Alpha && carPosChange >= newDistance) {
- if (isCar && ((CAutomobile*)car)->m_nWheelsOnGround > 1)
- // || isBike && GetMysteriousWheelRelatedThingBike(car) > 1)
+ if (isCar && ((CAutomobile*)car)->m_nWheelsOnGround > 1 ||
+ isBike && ((CBike*)car)->m_nWheelsOnGround > 1)
alphaSpeedFromStickY += (targetAlpha - Alpha) * 0.075f;
}
@@ -5151,19 +5168,13 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (camSetArrPos == 5 && Source.z < 1.0f) // RC Bandit and Baron
Source.z = 1.0f;
- // Obviously some specific place in LC
- if (Source.x > 11.0f && Source.x < 91.0f) {
- if (Source.y > -680.0f && Source.y < -600.0f && Source.z < 24.4f)
- Source.z = 24.4f;
- }
-
// CCam::FixSourceAboveWaterLevel
if (CameraTarget.z >= -2.0f) {
float level = -6000.0;
- // +0.5f is needed for III
+
if (CWaterLevel::GetWaterLevelNoWaves(Source.x, Source.y, Source.z, &level)) {
- if (Source.z < level + 0.5f)
- Source.z = level + 0.5f;
+ if (Source.z < level)
+ Source.z = level;
}
}
Front = TargetCoors - Source;
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index e404463e..b0c821f8 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -91,6 +91,11 @@ CVector vecPedVanRearDoorAnimOffset;
CVector vecPedQuickDraggedOutCarAnimOffset;
CVector vecPedDraggedOutCarAnimOffset;
CVector vecPedTrainDoorAnimOffset;
+CVector vecPedStdBikeJumpRhsAnimOffset;
+CVector vecPedVespaBikeJumpRhsAnimOffset;
+CVector vecPedHarleyBikeJumpRhsAnimOffset;
+CVector vecPedDirtBikeJumpRhsAnimOffset;
+CVector vecPedBikeKickAnimOffset;
bool CPed::bNastyLimbsCheat;
bool CPed::bPedCheat2;
@@ -686,7 +691,7 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
// BUG: This condition will always return true. Even fixing it won't work, because these states are unused.
// if (m_nPedState != PED_PASSENGER || m_nPedState != PED_TAXI_PASSENGER) {
- CPed::SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ SetDie();
// }
bBodyPartJustCameOff = true;
@@ -1848,6 +1853,7 @@ CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset)
return veh->GetPosition() + doorPos;
}
+// --MIAMI: Done
void
CPed::LineUpPedWithCar(PedLineUpPhase phase)
{
@@ -1856,29 +1862,59 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
float seatPosMult = 0.0f;
float currentZ;
float adjustedTimeStep;
+ CVector autoZPos;
if (CReplay::IsPlayingBack())
return;
if (!bChangedSeat && phase != LINE_UP_TO_CAR_2) {
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SIT)) {
- SetPedPositionInCar();
- return;
- }
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT)) {
- SetPedPositionInCar();
- return;
- }
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITP)) {
- SetPedPositionInCar();
- return;
- }
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITPLO)) {
- SetPedPositionInCar();
- return;
+ if (m_pMyVehicle->IsBike()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_RIDE) ||
+ RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_PASSENGER)) {
+ SetPedPositionInCar();
+ return;
+ }
+ } else {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SIT)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITP)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITPLO)) {
+ SetPedPositionInCar();
+ return;
+ }
}
bChangedSeat = true;
}
+ if (phase == LINE_UP_TO_CAR_FALL) {
+ SetPedPositionInCar();
+ autoZPos = GetPosition();
+ CPedPlacement::FindZCoorForPed(&autoZPos);
+ if (m_pVehicleAnim && (m_pVehicleAnim->animId == ANIM_CAR_ROLLOUT_LHS || m_pVehicleAnim->animId == ANIM_CAR_ROLLOUT_RHS)
+ && autoZPos.z > GetPosition().z) {
+ m_matrix.GetPosition().z = autoZPos.z;
+ }
+ if (m_pVehicleAnim && m_pVehicleAnim->animId == ANIM_BIKE_HIT) {
+ if (autoZPos.z > GetPosition().z)
+ m_matrix.GetPosition().z += m_pVehicleAnim->GetProgress() * (autoZPos.z - GetPosition().z);
+
+ } else if (m_pVehicleAnim) {
+ if (m_pVehicleAnim->animId == ANIM_BIKE_GETOFF_BACK) {
+ if (autoZPos.z > GetPosition().z) {
+ m_matrix.GetPosition().z += (m_pVehicleAnim->currentTime * (20.f / 7.f)) * (autoZPos.z - GetPosition().z);
+ }
+ }
+ }
+ return;
+ }
if (phase == LINE_UP_TO_CAR_START) {
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
}
@@ -1916,14 +1952,9 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
}
}
- if (!bInVehicle)
- seatPosMult = 1.0f;
-
-#ifdef VC_PED_PORTS
bool multExtractedFromAnim = false;
bool multExtractedFromAnimBus = false;
float zBlend;
-#endif
if (m_pVehicleAnim) {
vehAnim = m_pVehicleAnim->animId;
@@ -1934,38 +1965,38 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_CAR_LJACKED_LHS:
case ANIM_VAN_GETIN_L:
case ANIM_VAN_GETIN:
-#ifdef VC_PED_PORTS
multExtractedFromAnim = true;
zBlend = Max(m_pVehicleAnim->GetProgress() - 0.3f, 0.0f) / (1.0f - 0.3f);
// fall through
-#endif
+
case ANIM_CAR_QJACKED:
case ANIM_CAR_GETOUT_LHS:
case ANIM_CAR_GETOUT_LOW_LHS:
case ANIM_CAR_GETOUT_RHS:
case ANIM_CAR_GETOUT_LOW_RHS:
-#ifdef VC_PED_PORTS
+
if (!multExtractedFromAnim) {
multExtractedFromAnim = true;
zBlend = Max(m_pVehicleAnim->GetProgress() - 0.5f, 0.0f) / (1.0f - 0.5f);
}
// fall through
-#endif
+
case ANIM_CAR_CRAWLOUT_RHS:
case ANIM_CAR_CRAWLOUT_RHS2:
case ANIM_VAN_GETOUT_L:
case ANIM_VAN_GETOUT:
+ case ANIM_BIKE_GETOFF_RHS:
+ case ANIM_BIKE_GETOFF_LHS:
seatPosMult = m_pVehicleAnim->GetProgress();
break;
case ANIM_CAR_GETIN_RHS:
case ANIM_CAR_GETIN_LHS:
-#ifdef VC_PED_PORTS
if (veh && veh->IsCar() && veh->bIsBus) {
multExtractedFromAnimBus = true;
zBlend = Min(m_pVehicleAnim->GetProgress(), 0.5f) / 0.5f;
}
// fall through
-#endif
+
case ANIM_CAR_QJACK:
case ANIM_CAR_GETIN_LOW_LHS:
case ANIM_CAR_GETIN_LOW_RHS:
@@ -1980,6 +2011,12 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_CAR_LSHUFFLE_RHS:
seatPosMult = 0.0f;
break;
+ case ANIM_CAR_JUMPIN_LHS:
+ {
+ float animLength = m_pVehicleAnim->hierarchy->totalLength;
+ seatPosMult = Max(0.0f, 0.5f * animLength - m_pVehicleAnim->currentTime) / animLength;
+ break;
+ }
case ANIM_CAR_CLOSE_LHS:
case ANIM_CAR_CLOSE_RHS:
case ANIM_COACH_OPEN_L:
@@ -1990,8 +2027,25 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
seatPosMult = 1.0f;
break;
default:
+ if (veh->IsBike()) {
+ seatPosMult = 0.0f;
+ } else {
+ if (bInVehicle)
+ seatPosMult = 0.0f;
+ else
+ seatPosMult = 1.0f;
+ }
break;
}
+ } else {
+ if (veh->IsBike()) {
+ seatPosMult = 0.0f;
+ } else {
+ if (bInVehicle)
+ seatPosMult = 0.0f;
+ else
+ seatPosMult = 1.0f;
+ }
}
CVector neededPos;
@@ -2002,7 +2056,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
neededPos = GetPositionToOpenCarDoor(veh, m_vehEnterType, seatPosMult);
}
- CVector autoZPos = neededPos;
+ autoZPos = neededPos;
if (veh->bIsInWater) {
if (veh->m_vehType == VEHICLE_TYPE_BOAT && veh->IsUpsideDown())
@@ -2032,11 +2086,24 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
}
if (autoZPos.z > neededPos.z) {
-#ifdef VC_PED_PORTS
- if (multExtractedFromAnim) {
+ vehAnim = m_pVehicleAnim->animId;
+ if (veh->IsBike() && (m_pVehicleAnim && vehAnim != ANIM_BIKE_KICK)) {
+ float zBlend;
+ if (vehAnim != ANIM_BIKE_GETOFF_RHS && vehAnim != ANIM_BIKE_GETOFF_LHS) {
+ if (vehAnim != ANIM_BIKE_JUMPON_R && vehAnim != ANIM_BIKE_JUMPON_L) {
+ zBlend = 0.0f;
+ } else {
+ float animLength = m_pVehicleAnim->hierarchy->totalLength;
+ zBlend = Min(1.0f, 2.0f * m_pVehicleAnim->currentTime / animLength);
+ }
+ } else {
+ zBlend = 1.0f - seatPosMult;
+ }
+ float curZ = veh->GetPosition().z + FEET_OFFSET;
+ neededPos.z = ((curZ - autoZPos.z) - veh->GetHeightAboveRoad()) * zBlend + autoZPos.z;
+ } else if (multExtractedFromAnim) {
neededPos.z += (autoZPos.z - neededPos.z) * zBlend;
} else {
-#endif
currentZ = GetPosition().z;
if (m_pVehicleAnim && vehAnim != ANIM_VAN_GETIN_L && vehAnim != ANIM_VAN_CLOSE_L && vehAnim != ANIM_VAN_CLOSE && vehAnim != ANIM_VAN_GETIN) {
neededPos.z = autoZPos.z;
@@ -2047,20 +2114,16 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
// Smoothly change ped position
neededPos.z = currentZ - (currentZ - neededPos.z) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep);
}
-#ifdef VC_PED_PORTS
}
-#endif
} else {
// We may need to raise up the ped
if (phase == LINE_UP_TO_CAR_START) {
currentZ = GetPosition().z;
if (neededPos.z > currentZ) {
-#ifdef VC_PED_PORTS
if (multExtractedFromAnimBus) {
neededPos.z = (neededPos.z - currentZ) * zBlend + currentZ;
} else {
-#endif
if (m_pVehicleAnim &&
(vehAnim == ANIM_CAR_GETIN_RHS || vehAnim == ANIM_CAR_GETIN_LOW_RHS || vehAnim == ANIM_CAR_GETIN_LHS || vehAnim == ANIM_CAR_GETIN_LOW_LHS
|| vehAnim == ANIM_CAR_QJACK || vehAnim == ANIM_VAN_GETIN_L || vehAnim == ANIM_VAN_GETIN)) {
@@ -2068,12 +2131,10 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
// Smoothly change ped position
neededPos.z = (neededPos.z - currentZ) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep) + currentZ;
- } else if (EnteringCar()) {
+ } else if (EnteringCar() || m_nPedState == PED_DRIVING && veh->IsBike()) {
neededPos.z = Max(currentZ, autoZPos.z);
}
-#ifdef VC_PED_PORTS
}
-#endif
}
}
}
@@ -2104,14 +2165,26 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
m_fRotationCur -= (m_fRotationCur - limitedDest) * (1.0f - timeUntilStateChange);
}
- if (seatPosMult > 0.2f || vehIsUpsideDown) {
+ if (seatPosMult > 0.2f || vehIsUpsideDown || veh->IsBike()) {
SetPosition(neededPos);
SetHeading(m_fRotationCur);
} else {
CMatrix vehDoorMat(veh->GetMatrix());
vehDoorMat.GetPosition() += Multiply3x3(vehDoorMat, GetLocalPositionToOpenCarDoor(veh, m_vehEnterType, 0.0f));
- // VC couch anims are inverted, so they're fixing it here.
+
+ // Cool huh? Entering from windscreen
+ if (m_vehEnterType == CAR_WINDSCREEN || veh->bIsBus) {
+ CMatrix correctionMat;
+ if (veh->bIsBus && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR))
+ correctionMat.SetRotateZ(-HALFPI);
+ else if (veh->bIsBus && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR))
+ correctionMat.SetRotateZ(HALFPI);
+ else
+ correctionMat.SetRotateZ(PI);
+
+ vehDoorMat = vehDoorMat * correctionMat;
+ }
GetMatrix() = vehDoorMat;
}
@@ -4270,33 +4343,40 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (method != WEAPONTYPE_DROWNING) {
#ifdef VC_PED_PORTS
if (m_pMyVehicle) {
-
- // TODO(Miami): Bikes
- if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) {
- if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
- m_pMyVehicle->SetStatus(STATUS_PHYSICS);
- CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
- }
- m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
- m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
- }
-// TODO(MIAMI): argument
- if (m_pMyVehicle->CanPedExitCar(false)) {
- SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
- } else {
+ bool bDone = false;
+ if (m_pMyVehicle->IsBike()) {
m_fHealth = 0.0f;
- if (m_pMyVehicle && m_pMyVehicle->pDriver == this) {
- SetRadioStation();
- m_pMyVehicle->SetStatus(STATUS_ABANDONED);
+ //CBike::KnockOffRider -- TODO(MIAMI)
+ bDone = true;
+ }
+ else {
+ if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) {
+ if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
+ m_pMyVehicle->SetStatus(STATUS_PHYSICS);
+ CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
+ }
+ m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ m_pMyVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
+ m_pMyVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
}
- SetDie(dieAnim, dieDelta, dieSpeed);
- /*
- if (damagedBy == FindPlayerPed() && damagedBy != this) {
- // TODO(Miami): PlayerInfo stuff
+ // TODO(MIAMI): argument
+ if (m_pMyVehicle->CanPedExitCar(false)) {
+ SetObjective(OBJECTIVE_LEAVE_CAR_AND_DIE, m_pMyVehicle);
+ }
+ else {
+ m_fHealth = 0.0f;
+ if (m_pMyVehicle && m_pMyVehicle->pDriver == this) {
+ SetRadioStation();
+ m_pMyVehicle->SetStatus(STATUS_ABANDONED);
+ }
+ SetDie(dieAnim, dieDelta, dieSpeed);
+ /*
+ if (damagedBy == FindPlayerPed() && damagedBy != this) {
+ // TODO(Miami): PlayerInfo stuff
+ }
+ */
}
- */
}
for (int i = 0; i < ARRAY_SIZE(m_pMyVehicle->pPassengers); i++) {
CPed* passenger = m_pMyVehicle->pPassengers[i];
@@ -4314,6 +4394,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
} else {
CDarkel::RegisterKillNotByPlayer(this, method);
}
+ if (bDone)
+ return true;
}
#endif
m_fHealth = 1.0f;
@@ -6682,11 +6764,12 @@ CPed::EndFight(uint8 endType)
m_nWaitTimer = 0;
}
+// --MIAMI: Done
void
CPed::EnterCar(void)
{
if (IsNotInWreckedVehicle() && m_fHealth > 0.0f) {
- CVehicle *veh = (CVehicle*)m_pSeekTarget;
+ CVehicle *veh = m_pMyVehicle;
// Not used.
// CVector posForDoor = GetPositionToOpenCarDoor(veh, m_vehEnterType);
@@ -6700,9 +6783,32 @@ CPed::EnterCar(void)
}
bIsInTheAir = false;
LineUpPedWithCar(LINE_UP_TO_CAR_START);
+ if (veh->IsBike()) {
+ CBike *bike = (CBike*)veh;
+ if (bike->GetStatus() != STATUS_ABANDONED || bike->m_bike_flag08 || !m_pVehicleAnim) {
+ if (m_nPedState == PED_CARJACK && m_pVehicleAnim) {
+ if (m_pVehicleAnim->currentTime > 0.4f && m_pVehicleAnim->currentTime - m_pVehicleAnim->timeStep <= 0.4f) {
+ int anim = m_pVehicleAnim->animId;
+ if (anim == ANIM_BIKE_KICK) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_187, 3.0f);
+ } else if (anim == ANIM_BIKE_ELBOW_R || anim == ANIM_BIKE_ELBOW_L) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_186, 3.0f);
+ }
+ }
+ }
+ } else {
+ int anim = m_pVehicleAnim->animId;
+
+ // One is pickup and other one is pullup, not same :p
+ if ((anim == ANIM_BIKE_PICKUP_R || anim == ANIM_BIKE_PICKUP_L) && m_pVehicleAnim->currentTime > 0.4667f)
+ bike->m_bike_flag08 = true;
+ else if ((anim == ANIM_BIKE_PULLUP_R || anim == ANIM_BIKE_PULLUP_L) && m_pVehicleAnim->currentTime > 0.4667f)
+ bike->m_bike_flag08 = true;
+ }
+ }
} else {
QuitEnteringCar();
- SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ SetDie();
}
}
@@ -8561,15 +8667,28 @@ CPed::Initialise(void)
debug("CPed ready\n");
}
+// --MIAMI: Done
void
CPed::SetAnimOffsetForEnterOrExitVehicle(void)
{
// FIX: If there were no translations on enter anims, there were overflows all over this function.
int vanBlock = CAnimManager::GetAnimationBlockIndex("van");
+ int bikesBlock = CAnimManager::GetAnimationBlockIndex("bikes");
+ int bikevBlock = CAnimManager::GetAnimationBlockIndex("bikev");
+ int bikehBlock = CAnimManager::GetAnimationBlockIndex("bikeh");
+ int bikedBlock = CAnimManager::GetAnimationBlockIndex("biked");
CStreaming::RequestAnim(vanBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikesBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikevBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikehBlock, STREAMFLAGS_DEPENDENCY);
+ CStreaming::RequestAnim(bikedBlock, STREAMFLAGS_DEPENDENCY);
CStreaming::LoadAllRequestedModels(false);
CAnimManager::AddAnimBlockRef(vanBlock);
+ CAnimManager::AddAnimBlockRef(bikesBlock);
+ CAnimManager::AddAnimBlockRef(bikevBlock);
+ CAnimManager::AddAnimBlockRef(bikehBlock);
+ CAnimManager::AddAnimBlockRef(bikedBlock);
CAnimBlendHierarchy *enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_JACKED_LHS)->hierarchy;
CAnimBlendSequence *seq = enterAssoc->sequences;
@@ -8630,8 +8749,8 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
vecPedVanRearDoorAnimOffset = lastFrame->translation;
}
}
-#ifdef GTA_TRAIN
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_TRAIN_GETOUT)->hierarchy;
+ // I think this is leftover and ANIM_TRAIN_GETOUT
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_IDLE_STANCE3)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
@@ -8642,7 +8761,72 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
vecPedTrainDoorAnimOffset = lastFrame->translation;
}
}
-#endif
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_STANDARD, ANIM_BIKE_JUMPON_R)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedStdBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedStdBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_VESPA, ANIM_BIKE_JUMPON_R)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedVespaBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedVespaBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_HARLEY, ANIM_BIKE_JUMPON_R)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedHarleyBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedHarleyBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_DIRT, ANIM_BIKE_JUMPON_R)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedDirtBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedDirtBikeJumpRhsAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_HARLEY, ANIM_BIKE_KICK)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedBikeKickAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedBikeKickAnimOffset = lastFrame->translation;
+ }
+ }
+
+ CAnimManager::RemoveAnimBlockRef(vanBlock);
+ CAnimManager::RemoveAnimBlockRef(bikesBlock);
+ CAnimManager::RemoveAnimBlockRef(bikevBlock);
+ CAnimManager::RemoveAnimBlockRef(bikehBlock);
+ CAnimManager::RemoveAnimBlockRef(bikedBlock);
}
void
@@ -9819,7 +10003,7 @@ CPed::ProcessControl(void)
++m_panicCounter;
if (m_fHealth <= 1.0f && m_nPedState <= PED_STATES_NO_AI && !bIsInTheAir && !bIsLanding)
- SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ SetDie();
bCollidedWithMyVehicle = false;
@@ -17032,10 +17216,11 @@ CPed::UpdateFromLeader(void)
}
}
+// --MIAMI: Done
void
CPed::UpdatePosition(void)
{
- if (CReplay::IsPlayingBack() || !bIsStanding)
+ if (CReplay::IsPlayingBack() || !bIsStanding || m_attachedTo)
return;
CVector2D velocityChange;
@@ -17082,7 +17267,7 @@ CPed::UpdatePosition(void)
}
// Take time step into account
- if (m_pCurrentPhysSurface) {
+ if (m_pCurrentPhysSurface && (!m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08)) {
float speedChange = velocityChange.Magnitude();
float changeMult = speedChange;
if (m_nPedState != PED_DIE || !m_pCurrentPhysSurface->IsVehicle()) {
@@ -17100,27 +17285,39 @@ CPed::UpdatePosition(void)
m_vecMoveSpeed.y += velocityChange.y;
}
+// --MIAMI: Done
void
CPed::SetPedPositionInCar(void)
{
+ bool notYet = false;
if (CReplay::IsPlayingBack())
return;
if (bChangedSeat) {
- bool notYet = false;
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LOW_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LOW_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SHUFFLE_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSHUFFLE_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE_L)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN_L)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_L)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_R)) {
- notYet = true;
+ if (m_pMyVehicle->IsBike()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_JUMPON_R)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_JUMPON_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_KICK)) {
+ LineUpPedWithCar(LINE_UP_TO_CAR_START);
+ return;
+ }
+ bChangedSeat = false;
+ } else {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LOW_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LOW_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SHUFFLE_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSHUFFLE_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_R)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_JUMPIN_LHS)) {
+ notYet = true;
+ }
}
if (notYet) {
LineUpPedWithCar(LINE_UP_TO_CAR_START);
@@ -17133,14 +17330,16 @@ CPed::SetPedPositionInCar(void)
CVector seatPos;
if (m_pMyVehicle->pDriver == this) {
seatPos = vehModel->GetFrontSeatPosn();
- if (!m_pMyVehicle->IsBoat() && m_pMyVehicle->m_vehType != VEHICLE_TYPE_BIKE)
+ if (!m_pMyVehicle->IsBoat() && !m_pMyVehicle->IsBike())
seatPos.x = -seatPos.x;
} else if (m_pMyVehicle->pPassengers[0] == this) {
- seatPos = vehModel->GetFrontSeatPosn();
+ seatPos = m_pMyVehicle->IsBike() ? vehModel->m_positions[CAR_POS_BACKSEAT]: vehModel->GetFrontSeatPosn();
+
} else if (m_pMyVehicle->pPassengers[1] == this) {
seatPos = vehModel->m_positions[CAR_POS_BACKSEAT];
seatPos.x = -seatPos.x;
+
} else {
if (m_pMyVehicle->pPassengers[2] == this) {
seatPos = vehModel->m_positions[CAR_POS_BACKSEAT];
@@ -17148,6 +17347,10 @@ CPed::SetPedPositionInCar(void)
seatPos = vehModel->GetFrontSeatPosn();
}
}
+ if (m_pMyVehicle->IsBike()) {
+ ((CBike*)m_pMyVehicle)->CalculateLeanMatrix();
+ newMat = ((CBike*)m_pMyVehicle)->m_leanMatrix;
+ }
newMat.GetPosition() += Multiply3x3(newMat, seatPos);
// Already done below (SetTranslate(0.0f, 0.0f, 0.0f))
// tempMat.SetUnity();
@@ -18257,10 +18460,8 @@ CPed::AddInCarAnims(CVehicle* car, bool isDriver)
} else if (car->IsBike()) {
if (isDriver) {
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ((CBike*)car)->m_bikeAnimType, ANIM_BIKE_RIDE, 100.0f);
- StopNonPartialAnims();
} else {
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ((CBike*)car)->m_bikeAnimType, ANIM_BIKE_PASSENGER, 100.0f);
- StopNonPartialAnims();
}
} else {
if (isDriver) {
@@ -18500,6 +18701,7 @@ CPed::PedShuffle(void)
}
}
+// --MIAMI: Bike part is done
void
CPed::DriveVehicle(void)
{
@@ -18508,8 +18710,203 @@ CPed::DriveVehicle(void)
CVehicle *veh = m_pMyVehicle;
if (veh->IsBike()) {
+ CBike *bike = (CBike*)veh;
+ float blendDelta = 1.0f;
+ float targetUDLean = 0.0f;
+ CAnimBlendAssociation *leftAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_LEFT);
+ CAnimBlendAssociation *rightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_RIGHT);
+ CAnimBlendAssociation *stillAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_STILL);
+ CAnimBlendAssociation *fwdAssoc, *backAssoc;
+ if (IsPlayer()) {
+ fwdAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_FWD);
+ backAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_BACK);
+ }
+ CAnimBlendAssociation *walkbackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_PUSHES);
+ CAnimBlendAssociation *drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if (!drivebyAssoc)
+ drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if (!drivebyAssoc)
+ drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_FT);
+
+ float velocityFwdDotProd = DotProduct(bike->m_vecMoveSpeed, bike->GetForward());
+ if (m_vecTurnSpeed.MagnitudeSqr() > 0.09f) {
+ // TODO(Miami)
+ /*
+ bike->KnockOffRider(walkbackAssoc, 44, 2, this, 0);
+ if (bike->pPassengers[0])
+ bike->KnockOffRider(walkbackAssoc, 44, 2, bike->pPassengers[0], 0);
+ */
+ return;
+ }
+ if (!drivebyAssoc && Abs(velocityFwdDotProd) < 0.02f) {
+ if (!stillAssoc || stillAssoc->blendAmount < 1.0 && stillAssoc->blendDelta <= 0.0) {
+ stillAssoc = CAnimManager::BlendAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_STILL, 2.0f);
+ }
+ } else {
+ if (velocityFwdDotProd >= 0.0f) {
+ if (stillAssoc && stillAssoc->blendDelta >= 0.0f)
+ stillAssoc->blendDelta = -4.0f;
+ if (walkbackAssoc && walkbackAssoc->blendDelta >= 0.0f)
+ walkbackAssoc->blendDelta = -4.0f;
+ } else {
+ float maxReverseSpeed = bike->pHandling->Transmission.fMaxReverseVelocity;
+ if (3.5f * maxReverseSpeed > velocityFwdDotProd && (bike->m_nWheelsOnGround || bike->GetUp().z < -0.5f)) {
+ // TODO(Miami)
+ /*
+ bike->KnockOffRider(walkbackAssoc, 44, 2, this, 0);
+ if (bike->pPassengers[0])
+ bike->KnockOffRider(walkbackAssoc, 44, 2, bike->pPassengers[0], 0);
+ */
+ return;
+ }
+ if (bike->m_fGasPedal >= 0.0 || velocityFwdDotProd <= maxReverseSpeed * 1.5) {
+ if (IsPlayer() && velocityFwdDotProd < maxReverseSpeed * 1.5)
+ targetUDLean = -1.0f;
+
+ if (stillAssoc && stillAssoc->blendDelta >= 0.0f)
+ stillAssoc->blendDelta = -4.0f;
+
+ if (walkbackAssoc && walkbackAssoc->blendDelta >= 0.0f) {
+ walkbackAssoc->blendDelta = -4.0f;
+ }
+ } else if (!walkbackAssoc || walkbackAssoc->blendAmount < 1.0f && walkbackAssoc->blendDelta <= 0.0f) {
+ walkbackAssoc = CAnimManager::BlendAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_PUSHES, 4.0f);
+ }
+ }
+ }
+ if (stillAssoc)
+ blendDelta -= Min(1.0f, CTimer::GetTimeStepNonClipped() * 0.02f * stillAssoc->blendDelta + stillAssoc->blendAmount);
+
+ if (drivebyAssoc)
+ blendDelta -= Min(blendDelta, CTimer::GetTimeStepNonClipped() * 0.02f * drivebyAssoc->blendDelta + drivebyAssoc->blendAmount);
+
+ if (walkbackAssoc)
+ blendDelta -= Min(blendDelta, CTimer::GetTimeStepNonClipped() * 0.02f * walkbackAssoc->blendDelta + walkbackAssoc->blendAmount);
+
+ float targetLRLean, timeBlend, neededAngForWheelie, stoppieAng;
+
+ // Smooth the lean amount
+ if (targetUDLean == -1.0f) {
+ targetLRLean = 0.0f;
+ timeBlend = Pow(0.86f, CTimer::GetTimeStep());
+ } else {
+ targetLRLean = clamp(bike->m_fLeanLRAngle / bike->pBikeHandling->fFullAnimLean, -1.0f, 1.0f);
+ timeBlend = Pow(0.86f, CTimer::GetTimeStep());
+ }
+
+ bike->m_fPedLeanAmountLR = bike->m_fPedLeanAmountLR * timeBlend + (1.0 - timeBlend) * targetLRLean;
+
+ if (!IsPlayer()) {
+ targetUDLean = 0.0f;
+
+ } else if (targetUDLean > -1.0f) {
+ targetUDLean = bike->m_fLeanInput;
+ bike->m_bike_flag80 = false;
+ neededAngForWheelie = 1.0f;
+ if (bike->m_aWheelTimer[0] != 0.0f || bike->m_aWheelTimer[1] != 0.0f || bike->GetForward().z <= 0.0f ||
+ (0.0f == bike->m_aWheelTimer[2] && 0.0f == bike->m_aWheelTimer[3])) {
+
+ if (0.0f == bike->m_aWheelTimer[2] && 0.0f == bike->m_aWheelTimer[3] &&
+ (bike->GetForward().y < 0.0f && (bike->m_aWheelTimer[0] != 0.0f || bike->m_aWheelTimer[1] != 0.0f))) {
+
+ stoppieAng = bike->pBikeHandling->fStoppieAng;
+ if (stoppieAng - bike->GetForward().z > 0.6f * stoppieAng)
+ bike->m_bike_flag80 = true;
+ }
+ } else {
+ float wheelieAng = bike->pBikeHandling->fWheelieAng;
+ neededAngForWheelie = wheelieAng - bike->GetForward().z;
+ if (neededAngForWheelie < wheelieAng / 2.f)
+ bike->m_bike_flag80 = true;
+ }
+ if (neededAngForWheelie >= 0.15f) {
+ if (bike->m_fBrakePedal <= 0.5f || velocityFwdDotProd <= 0.01f) {
+ if (bike->m_fGasPedal > 0.5f && targetUDLean <= 0.0f && 0.3f * bike->pHandling->Transmission.fUnkMaxVelocity > velocityFwdDotProd) {
+ targetUDLean = Min(0.1f, targetUDLean);
+ }
+ } else {
+ targetUDLean = Max(0.1f, targetUDLean);
+ }
+ } else {
+ targetUDLean = Max(0.25f, targetUDLean);
+ }
+ float targetLRLeanABS = Abs(targetLRLean);
+ if (targetLRLeanABS > 0.3f) {
+ // Yes, UD
+ targetUDLean *= Max(0.0f, 1.0f - (targetLRLeanABS - 0.3f) * 50.f / 13.f);
+ }
+ }
+ if (IsPlayer()) {
+ float timeBlend = Pow(0.89f, CTimer::GetTimeStep());
+ bike->m_fPedLeanAmountUD = (timeBlend * bike->m_fPedLeanAmountUD) + ((1.0f - timeBlend) * targetUDLean);
+ } else {
+ bike->m_fPedLeanAmountUD = 0.0f;
+ }
+
+ float fwdBackLeanAmount, leftRightLeanAmount;
+ if (Abs(bike->m_fPedLeanAmountLR) <= 0.56f && IsPlayer()) {
- // TODO(Miami): Bikes
+ if (Abs(bike->m_fPedLeanAmountUD) <= 0.56f) {
+ CVector2D smoothedLean(bike->m_fPedLeanAmountLR, bike->m_fPedLeanAmountUD);
+ float smoothLeanMag = smoothedLean.Magnitude();
+ if (smoothLeanMag <= 0.01f) {
+ fwdBackLeanAmount = Abs(smoothedLean.y);
+ leftRightLeanAmount = Abs(smoothedLean.x);
+ } else {
+ fwdBackLeanAmount = Abs(smoothedLean.y / smoothLeanMag);
+ leftRightLeanAmount = Abs(smoothedLean.x / smoothLeanMag);
+ }
+ } else {
+ fwdBackLeanAmount = 1.0f;
+ leftRightLeanAmount = 0.0f;
+ }
+ } else {
+ fwdBackLeanAmount = 0.0f;
+ leftRightLeanAmount = 1.0f;
+ }
+ float fwdBackBlend = fwdBackLeanAmount * blendDelta;
+ float leftRightBlend = leftRightLeanAmount * blendDelta;
+ if (IsPlayer()) {
+ if (!fwdAssoc)
+ fwdAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_FWD);
+ if (!backAssoc)
+ backAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_BACK);
+
+ if (bike->m_fPedLeanAmountUD < 0.0f) {
+ backAssoc->blendAmount = fwdBackBlend;
+ backAssoc->SetCurrentTime(-(bike->m_fPedLeanAmountUD * backAssoc->hierarchy->totalLength));
+ backAssoc->flags &= ~ASSOC_RUNNING;
+ fwdAssoc->blendAmount = 0.0f;
+ } else {
+ fwdAssoc->blendAmount = fwdBackBlend;
+ fwdAssoc->SetCurrentTime(bike->m_fPedLeanAmountUD* fwdAssoc->hierarchy->totalLength);
+ fwdAssoc->flags &= ~ASSOC_RUNNING;
+ backAssoc->blendAmount = 0.0f;
+ }
+ }
+ if (!leftAssoc)
+ leftAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_LEFT);
+ if (!rightAssoc)
+ rightAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_RIGHT);
+
+ if (bike->m_fPedLeanAmountLR < 0.0f) {
+ leftAssoc->blendAmount = leftRightBlend;
+ leftAssoc->SetCurrentTime(-(bike->m_fPedLeanAmountLR * leftAssoc->hierarchy->totalLength));
+ leftAssoc->flags &= ~ASSOC_RUNNING;
+ rightAssoc->blendAmount = 0.0f;
+ } else {
+ rightAssoc->blendAmount = leftRightBlend;
+ rightAssoc->SetCurrentTime(bike->m_fPedLeanAmountLR* rightAssoc->hierarchy->totalLength);
+ rightAssoc->flags &= ~ASSOC_RUNNING;
+ leftAssoc->blendAmount = 0.0f;
+ }
+ if (velocityFwdDotProd > 0.3f) {
+ RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
+ RwV3d Yaxis = { 0.0f, 1.0f, 0.0f };
+ RtQuatRotate(&m_pFrames[PED_HEAD]->hanimFrame->q, &Xaxis, CGeneral::GetRandomNumberInRange(-6.0f * velocityFwdDotProd, 6.0f * velocityFwdDotProd), rwCOMBINEPOSTCONCAT);
+ RtQuatRotate(&m_pFrames[PED_HEAD]->hanimFrame->q, &Yaxis, CGeneral::GetRandomNumberInRange(-6.0f * velocityFwdDotProd, 6.0f * velocityFwdDotProd), rwCOMBINEPOSTCONCAT);
+ bDontAcceptIKLookAts = true;
+ }
return;
}
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 0d7ff972..d4f338e8 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -9,6 +9,7 @@
#include "Physical.h"
#include "Weapon.h"
#include "WeaponInfo.h"
+#include "AnimationId.h"
#define FEET_OFFSET 1.04f
#define CHECK_NEARBY_THINGS_MAX_DIST 15.0f
@@ -251,7 +252,8 @@ enum {
enum PedLineUpPhase {
LINE_UP_TO_CAR_START,
LINE_UP_TO_CAR_END,
- LINE_UP_TO_CAR_2 // Buggy. Used for cops arresting you from passenger door
+ LINE_UP_TO_CAR_2, // Buggy. Used for cops arresting you from passenger door
+ LINE_UP_TO_CAR_FALL
};
enum PedOnGroundState {
@@ -655,7 +657,7 @@ public:
void SetLookFlag(CEntity *target, bool keepTryingToLook);
void SetLookFlag(float direction, bool keepTryingToLook);
void SetLookTimer(int time);
- void SetDie(AnimationId anim, float arg1, float arg2);
+ void SetDie(AnimationId anim = ANIM_KO_SHOT_FRONT1, float arg1 = 4.0f, float arg2 = 0.0f);
void SetDead(void);
void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer);
void RemoveBodyPart(PedNode nodeId, int8 direction);
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index ca530494..b853937b 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -1078,7 +1078,7 @@ CPopulation::AddDeadPedInFrontOfCar(const CVector& pos, CVehicle* pCulprit)
if (!CModelInfo::GetModelInfo(MI_MALE01)->GetRwObject()) // strange way to check it
return nil;
CPed* pPed = CPopulation::AddPed(PEDTYPE_CIVMALE, MI_MALE01, pos); // TODO(MIAMI): 4th parameter
- pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ pPed->SetDie();
pPed->m_nPedMoney = 0;
pPed->bDeadPedInFrontOfCar = true;
pPed->m_vehicleInAccident = pCulprit;
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 6fac4ec1..d0157c44 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -1546,10 +1546,8 @@ CAutomobile::ProcessControl(void)
// Blow up car after 5 seconds
m_fFireBlowUpTimer += CTimer::GetTimeStepInMilliseconds();
- if(m_fFireBlowUpTimer > 5000.0f){
- CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this);
+ if(m_fFireBlowUpTimer > 5000.0f)
BlowUpCar(m_pSetOnFireEntity);
- }
}else
m_fFireBlowUpTimer = 0.0f;
diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp
index e6a82288..a6fb2b82 100644
--- a/src/vehicles/Bike.cpp
+++ b/src/vehicles/Bike.cpp
@@ -86,8 +86,8 @@ CBike::CBike(int32 id, uint8 CreatedBy)
m_fGasPedal = 0.0f;
m_fBrakePedal = 0.0f;
m_fLeanInput = 0.0f;
- field_478 = 0;
- field_47C = 0;
+ m_fPedLeanAmountLR = 0.0f;
+ m_fPedLeanAmountUD = 0.0f;
m_pSetOnFireEntity = nil;
m_pBombRigger = nil;
m_fGasPedalAudio = 0.0f;
@@ -96,7 +96,7 @@ CBike::CBike(int32 id, uint8 CreatedBy)
m_bike_flag08 = false;
bIsStanding = false;
bExtraSpeed = false;
- m_bike_flag40 = false;
+ bIsOnFire = false;
m_bike_flag80 = false;
m_fTireTemperature = 0.0f;
@@ -209,22 +209,35 @@ CBike::ProcessControl(void)
if(m_fLeanInput < 0.0f){
m_vecCentreOfMass.y = pHandling->CentreOfMass.y + pBikeHandling->fLeanBakCOM*m_fLeanInput;
+ CVector com = m_vecCentreOfMass;
+#ifdef FIX_BUGS
+ // center of mass has to have world space orientation. unfortunately we can't do wheelies
+ // at high speed then, flipping y here is like riding south without this fix where wheelies work
+ com.y = -com.y;
+ com = Multiply3x3(GetMatrix(), com);
+#endif
if(m_fBrakePedal == 0.0f && !bIsHandbrakeOn || m_nWheelsOnGround == 0){
if(GetModelIndex() == MI_SANCHEZ){
float force = m_fLeanInput*m_fTurnMass*pBikeHandling->fLeanBackForce*Min(m_vecMoveSpeed.Magnitude(), 0.1f);
force *= 0.7f*m_fGasPedal + 0.3f;
- ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), m_vecCentreOfMass+GetForward());
+ ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), com+GetForward());
}else{
float force = m_fLeanInput*m_fTurnMass*pBikeHandling->fLeanBackForce*Min(m_vecMoveSpeed.Magnitude(), 0.1f);
force *= 0.5f*m_fGasPedal + 0.5f;
- ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), m_vecCentreOfMass+GetForward());
+ ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), com+GetForward());
}
}
}else{
m_vecCentreOfMass.y = pHandling->CentreOfMass.y + pBikeHandling->fLeanFwdCOM*m_fLeanInput;
+ CVector com = m_vecCentreOfMass;
+#ifdef FIX_BUGS
+ // see above
+ com.y = -com.y;
+ com = Multiply3x3(GetMatrix(), com);
+#endif
if(m_fBrakePedal < 0.0f || m_nWheelsOnGround == 0){
float force = m_fLeanInput*m_fTurnMass*pBikeHandling->fLeanFwdForce*Min(m_vecMoveSpeed.Magnitude(), 0.1f);
- ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), m_vecCentreOfMass+GetForward());
+ ApplyTurnForce(-force*CTimer::GetTimeStep()*GetUp(), com+GetForward());
}
}
@@ -307,8 +320,8 @@ CBike::ProcessControl(void)
m_nCarHornTimer = 0;
bCanStand = (pDriver || pPassengers[0] || bIsBeingCarJacked) && !bIsStanding;
- field_478 = 0;
- field_47C = 0;
+ m_fPedLeanAmountLR = 0.0f;
+ m_fPedLeanAmountUD = 0.0f;
m_bike_flag80 = false;
if(bIsBeingCarJacked){
@@ -331,8 +344,8 @@ CBike::ProcessControl(void)
bCanStand = false;
m_bike_flag80 = false;
- field_478 = 0;
- field_47C = 0;
+ m_fPedLeanAmountLR = 0.0f;
+ m_fPedLeanAmountUD = 0.0f;
break;
case STATUS_PLAYER_DISABLED:
@@ -388,12 +401,10 @@ CBike::ProcessControl(void)
float turnY = localTurnSpeed.y*(res.y - 1.0f);
res = -GetUp() * turnY * m_fTurnMass;
- // BUG? matrix multiplication
- ApplyTurnForce(res, GetRight() + Multiply3x3(GetMatrix(),m_vecCentreOfMass));
+ ApplyTurnForce(res, GetRight() + Multiply3x3(GetMatrix(), m_vecCentreOfMass));
res = GetUp() * turnX * m_fTurnMass;
- // BUG? matrix multiplication
- ApplyTurnForce(res, GetForward() + Multiply3x3(GetMatrix(),m_vecCentreOfMass));
+ ApplyTurnForce(res, GetForward() + Multiply3x3(GetMatrix(), m_vecCentreOfMass));
if(GetStatus() != STATUS_PLAYER)
m_vecCentreOfMass = pHandling->CentreOfMass;
@@ -1050,6 +1061,41 @@ CBike::ProcessControl(void)
}
}
+ if(m_fHealth < 250.0f && GetStatus() != STATUS_WRECKED){
+ // Car is on fire
+
+ CVector damagePos, fireDir;
+
+ // move fire forward if in first person
+ if(this == FindPlayerVehicle() && TheCamera.GetLookingForwardFirstPerson()){
+ damagePos = CVector(0.0f, 1.2f, -0.4f);
+ fireDir = CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.01125f, 0.09f));
+ }else{
+ damagePos = ((CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()))->m_positions[CAR_POS_BACKSEAT];
+ damagePos.z -= 0.3f;
+ fireDir = CGeneral::GetRandomNumberInRange(0.02025f, 0.09f) * GetRight();
+ fireDir -= CGeneral::GetRandomNumberInRange(0.02025f, 0.18f) * GetForward();
+ fireDir.z = CGeneral::GetRandomNumberInRange(0.00225f, 0.018f);
+ }
+
+ damagePos = GetMatrix()*damagePos;
+ CParticle::AddParticle(PARTICLE_CARFLAME, damagePos, fireDir,
+ nil, 0.9f);
+
+ CParticle::AddParticle(PARTICLE_ENGINE_SMOKE2, damagePos, CVector(0.0f, 0.0f, 0.0f), nil, 0.5f);
+
+ damagePos.x += CGeneral::GetRandomNumberInRange(-0.5625f, 0.5625f),
+ damagePos.y += CGeneral::GetRandomNumberInRange(-0.5625f, 0.5625f),
+ damagePos.z += CGeneral::GetRandomNumberInRange(0.5625f, 2.25f);
+ CParticle::AddParticle(PARTICLE_CARFLAME_SMOKE, damagePos, CVector(0.0f, 0.0f, 0.0f));
+
+ // Blow up car after 5 seconds
+ m_fFireBlowUpTimer += CTimer::GetTimeStepInMilliseconds();
+ if(m_fFireBlowUpTimer > 5000.0f)
+ BlowUpCar(m_pSetOnFireEntity);
+ }else
+ m_fFireBlowUpTimer = 0.0f;
+
ProcessDelayedExplosion();
// Find out how much to shake the pad depending on suspension and ground surface
@@ -1915,7 +1961,7 @@ void
CBike::Fix(void)
{
bIsDamaged = false;
- m_bike_flag40 = false;
+ bIsOnFire = false;
m_wheelStatus[0] = WHEEL_STATUS_OK;
m_wheelStatus[1] = WHEEL_STATUS_OK;
}
diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h
index aa85942d..02c63c1e 100644
--- a/src/vehicles/Bike.h
+++ b/src/vehicles/Bike.h
@@ -62,8 +62,8 @@ public:
float m_fLeanLRAngle;
float m_fLeanLRAngle2;
float m_fLeanInput;
- uint32 field_478;
- uint32 field_47C;
+ float m_fPedLeanAmountLR;
+ float m_fPedLeanAmountUD;
uint8 m_bike_unused2;
uint8 unused[3]; // looks like padding..but for what?
uint8 m_bike_flag01 : 1;
@@ -72,8 +72,8 @@ public:
uint8 m_bike_flag08 : 1;
uint8 bIsStanding : 1;
uint8 bExtraSpeed : 1; // leaning forward
- uint8 m_bike_flag40 : 1;
- uint8 m_bike_flag80 : 1;
+ uint8 bIsOnFire : 1;
+ uint8 m_bike_flag80 : 1; // doing wheelie?
int16 m_doingBurnout;
float m_fTireTemperature;
float m_fBrakeDestabilization;
diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp
index a1d58ab2..e6c3bbf3 100644
--- a/src/vehicles/CarGen.cpp
+++ b/src/vehicles/CarGen.cpp
@@ -3,6 +3,7 @@
#include "CarGen.h"
#include "Automobile.h"
+#include "Bike.h"
#include "Boat.h"
#include "Camera.h"
#include "CarCtrl.h"
@@ -88,7 +89,7 @@ void CCarGenerator::DoInternalProcessing()
pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
pBoat->SetStatus(STATUS_ABANDONED);
pBoat->m_nDoorLock = CARLOCK_UNLOCKED;
- }else{ // TODO(MIAMI): bikes
+ }else{
bool groundFound = false;
CVector pos = m_vecPos;
if (pos.z > -100.0f){
@@ -105,16 +106,23 @@ void CCarGenerator::DoInternalProcessing()
debug("CCarGenerator::DoInternalProcessing - can't find ground z for new car x = %f y = %f \n", m_vecPos.x, m_vecPos.y);
return;
}
- CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE);
- pVehicle = pCar;
- pCar->bIsStatic = false;
- pCar->bEngineOn = false;
- pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel();
- pCar->SetPosition(pos);
- pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
- pCar->SetStatus(STATUS_ABANDONED);
- pCar->bLightsOn = false;
- pCar->m_nDoorLock = CARLOCK_UNLOCKED;
+ if (CModelInfo::IsBikeModel(mi)) {
+ CBike* pBike = new CBike(mi, PARKED_VEHICLE);
+ pBike->bIsStanding = true;
+ pVehicle = pBike;
+ }
+ else {
+ CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE);
+ pVehicle = pCar;
+ }
+ pVehicle->bIsStatic = false;
+ pVehicle->bEngineOn = false;
+ pos.z += pVehicle->GetDistanceFromCentreOfMassToBaseOfModel();
+ pVehicle->SetPosition(pos);
+ pVehicle->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
+ pVehicle->SetStatus(STATUS_ABANDONED);
+ pVehicle->bLightsOn = false;
+ pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
}
CWorld::Add(pVehicle);
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index 764e49cc..c5537a48 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -5,6 +5,8 @@
#include "Timer.h"
#include "Pad.h"
#include "Vehicle.h"
+#include "Bike.h"
+#include "Automobile.h"
#include "Pools.h"
#include "HandlingMgr.h"
#include "CarCtrl.h"
@@ -893,7 +895,7 @@ float fTweakBikeWheelTurnForce = 2.0f;
void
CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
- int32 wheelsOnGround, float thrust, float brake, float adhesion, float unk, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus)
+ int32 wheelsOnGround, float thrust, float brake, float adhesion, float destabTraction, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus)
{
// BUG: using statics here is probably a bad idea
static bool bAlreadySkidding = false; // this is never reset
@@ -1010,14 +1012,14 @@ CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &whee
right *= adhesion * tractionLoss / l;
fwd *= adhesion * tractionLoss / l;
- if(unk < 1.0f)
- right *= unk;
- }else if(unk < 1.0f){
+ if(destabTraction < 1.0f)
+ right *= destabTraction;
+ }else if(destabTraction < 1.0f){
if(!bAlreadySkidding)
- unk *= pHandling->fTractionLoss;
- if(sq(adhesion*unk) < speedSq){
+ destabTraction *= pHandling->fTractionLoss;
+ if(sq(adhesion*destabTraction) < speedSq){
float l = Sqrt(speedSq);
- right *= adhesion * unk / l;
+ right *= adhesion * destabTraction / l;
}
}
@@ -1030,15 +1032,14 @@ CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &whee
float impulse = speed*m_fMass;
float turnImpulse = speed*GetMass(wheelContactPoint, direction);
CVector vTurnImpulse = turnImpulse * direction;
- float turnRight = DotProduct(vTurnImpulse, GetRight());
ApplyMoveForce(impulse * direction);
+ float turnRight = DotProduct(vTurnImpulse, GetRight());
float contactRight = DotProduct(wheelContactPoint, GetRight());
float contactFwd = DotProduct(wheelContactPoint, GetForward());
- if(wheelId != CARWHEEL_REAR_LEFT ||
- !bBraking && !bReversing)
+ if(wheelId != BIKEWHEEL_REAR || !bBraking && !bReversing)
ApplyTurnForce((vTurnImpulse - turnRight*GetRight()) * fTweakBikeWheelTurnForce,
wheelContactPoint - contactRight*GetRight());
@@ -2289,7 +2290,7 @@ CVehicle::KillPedsInVehicle(void)
if(!pDriver->IsPlayer())
pDriver->FlagToDestroyWhenNextProcessed();
}else
- pDriver->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ pDriver->SetDie();
}
for(i = 0; i < m_nNumMaxPassengers; i++){
if(pPassengers[i]){
@@ -2299,7 +2300,7 @@ CVehicle::KillPedsInVehicle(void)
if(!pPassengers[i]->IsPlayer())
pPassengers[i]->FlagToDestroyWhenNextProcessed();
}else
- pPassengers[i]->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ pPassengers[i]->SetDie();
}
}
}
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index b3a36c6d..bc14bc77 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -306,7 +306,7 @@ public:
void ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
int32 wheelsOnGround, float thrust, float brake, float adhesion, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, uint16 wheelStatus);
void ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
- int32 wheelsOnGround, float thrust, float brake, float adhesion, float unk, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus);
+ int32 wheelsOnGround, float thrust, float brake, float adhesion, float destabTraction, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus);
void ExtinguishCarFire(void);
void ProcessDelayedExplosion(void);
float ProcessWheelRotation(tWheelState state, const CVector &fwd, const CVector &speed, float radius);