summaryrefslogtreecommitdiffstats
path: root/src/vehicles
diff options
context:
space:
mode:
Diffstat (limited to 'src/vehicles')
-rw-r--r--src/vehicles/Automobile.cpp132
-rw-r--r--src/vehicles/Vehicle.cpp4
-rw-r--r--src/vehicles/Vehicle.h6
3 files changed, 135 insertions, 7 deletions
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 7d3f8ee3..1f64228b 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "General.h"
+#include "Pad.h"
#include "ModelIndices.h"
#include "VisibilityPlugins.h"
#include "DMAudio.h"
@@ -141,8 +142,134 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
return numCollisions;
}
+static int16 nLastControlInput;
+static float fMouseCentreRange = 0.35f;
+static float fMouseSteerSens = -0.0035f;
+static float fMouseCentreMult = 0.975f;
-WRAPPER void CAutomobile::ProcessControlInputs(uint8) { EAXJMP(0x53B660); }
+void
+CAutomobile::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
+ if(CCamera::m_bUseMouse3rdPerson && !CVehicle::m_bDisableMouseSteering){
+ if(CPad::GetPad(pad)->GetMouseX() != 0.0f){
+ m_fSteerRatio += fMouseSteerSens*CPad::GetPad(pad)->GetMouseX();
+ nLastControlInput = 2;
+ if(Abs(m_fSteerRatio) < fMouseCentreRange)
+ m_fSteerRatio *= Pow(fMouseCentreMult, CTimer::GetTimeStep());
+ }else if(CPad::GetPad(pad)->GetSteeringLeftRight() || nLastControlInput != 2){
+ // mouse hasn't move, steer with pad like below
+ m_fSteerRatio += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerRatio)*
+ 0.2f*CTimer::GetTimeStep();
+ nLastControlInput = 0;
+ }
+ }else{
+ m_fSteerRatio += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerRatio)*
+ 0.2f*CTimer::GetTimeStep();
+ nLastControlInput = 0;
+ }
+ m_fSteerRatio = clamp(m_fSteerRatio, -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
+ 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_fSteerRatio < 0.0f)
+ fValue = -sq(m_fSteerRatio);
+ else
+ fValue = sq(m_fSteerRatio);
+ m_fSteerAngle = DEGTORAD(m_handling->fSteeringLock) * fValue;
+
+ if(bComedyControls){
+ int rnd = CGeneral::GetRandomNumber() % 10;
+ switch(m_comedyControlState){
+ case 0:
+ if(rnd < 2)
+ m_comedyControlState = 1;
+ else if(rnd < 4)
+ m_comedyControlState = 2;
+ break;
+ case 1:
+ m_fSteerAngle += 0.05f;
+ if(rnd < 2)
+ m_comedyControlState = 0;
+ break;
+ case 2:
+ m_fSteerAngle -= 0.05f;
+ if(rnd < 2)
+ m_comedyControlState = 0;
+ break;
+ }
+ }else
+ m_comedyControlState = 0;
+
+ // Brake if player isn't in control
+ // BUG: game always uses pad 0 here
+ if(CPad::GetPad(pad)->DisablePlayerControls){
+ 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
CAutomobile::GetComponentWorldPosition(int32 component, CVector &pos)
@@ -1091,7 +1218,7 @@ public:
int32 ProcessEntityCollision_(CEntity *ent, CColPoint *colpoints){ return CAutomobile::ProcessEntityCollision(ent, colpoints); }
- void ProcessControlInputs_(uint8 x) { CAutomobile::ProcessControlInputs(x); }
+ void ProcessControlInputs_(uint8 pad) { CAutomobile::ProcessControlInputs(pad); }
void GetComponentWorldPosition_(int32 component, CVector &pos) { CAutomobile::GetComponentWorldPosition(component, pos); }
bool IsComponentPresent_(int32 component) { return CAutomobile::IsComponentPresent(component); }
void SetComponentRotation_(int32 component, CVector rotation) { CAutomobile::SetComponentRotation(component, rotation); }
@@ -1115,6 +1242,7 @@ STARTPATCHES
InjectHook(0x52D190, &CAutomobile_::SetModelIndex_, PATCH_JUMP);
InjectHook(0x535180, &CAutomobile_::Teleport_, PATCH_JUMP);
InjectHook(0x53B270, &CAutomobile_::ProcessEntityCollision_, PATCH_JUMP);
+ InjectHook(0x53B660, &CAutomobile_::ProcessControlInputs_, PATCH_JUMP);
InjectHook(0x52E5F0, &CAutomobile_::GetComponentWorldPosition_, PATCH_JUMP);
InjectHook(0x52E660, &CAutomobile_::IsComponentPresent_, PATCH_JUMP);
InjectHook(0x52E680, &CAutomobile_::SetComponentRotation_, PATCH_JUMP);
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index d8ed1a15..b21c859a 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -58,7 +58,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_nBombTimer = 0;
m_pWhoSetMeOnFire = nil;
field_1FB = 0;
- m_veh_flagB10 = false;
+ bComedyControls = false;
m_veh_flagB40 = false;
m_veh_flagB80 = false;
m_veh_flagC1 = false;
@@ -93,7 +93,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_pCurGroundEntity = nil;
field_22A = 0;
field_22B = 0;
- field_22F = 0;
+ m_comedyControlState = 0;
m_aCollPolys[0].valid = false;
m_aCollPolys[1].valid = false;
m_autoPilot.m_nCarMission = MISSION_NONE;
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index c293b8a6..55805e9d 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -144,7 +144,7 @@ public:
CFire *m_pCarFire;
float m_fSteerAngle;
float m_fGasPedal;
- float m_fBreakPedal;
+ float m_fBrakePedal;
uint8 VehicleCreatedBy;
// cf. https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/CVehicle.h from R*
@@ -161,7 +161,7 @@ public:
uint8 bIsBus: 1; // Is this vehicle a bus
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 m_veh_flagB10 : 1;
+ uint8 bComedyControls : 1; // Will make the car hard to control (hopefully in a funny way)
uint8 m_veh_flagB20 : 1;
uint8 m_veh_flagB40 : 1;
uint8 m_veh_flagB80 : 1;
@@ -207,7 +207,7 @@ public:
uint8 m_nCarHornTimer;
int8 field_22D;
bool m_bSirenOrAlarm;
- int8 field_22F;
+ int8 m_comedyControlState;
CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car
float m_fSteerRatio;
eVehicleType m_vehType;