From 0548476ba6b9e2273ceec94ca9f62e76c69d7ef4 Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 11 Jul 2019 12:48:49 +0200 Subject: [PATCH] CAutomobile::ProcessControlInputs --- src/core/Pad.h | 4 ++ src/core/re3.cpp | 13 +++- src/peds/PlayerPed.cpp | 2 + src/peds/PlayerPed.h | 1 + src/vehicles/Automobile.cpp | 132 +++++++++++++++++++++++++++++++++++- src/vehicles/Vehicle.cpp | 4 +- src/vehicles/Vehicle.h | 6 +- 7 files changed, 154 insertions(+), 8 deletions(-) diff --git a/src/core/Pad.h b/src/core/Pad.h index 30cdb8df..30a9980b 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -289,6 +289,10 @@ public: // mouse bool GetLeftMouseJustDown() { return !!(NewMouseControllerState.LMB && !OldMouseControllerState.LMB); } + bool GetRightMouseJustDown() { return !!(NewMouseControllerState.RMB && !OldMouseControllerState.RMB); } + bool GetMiddleMouseJustDown() { return !!(NewMouseControllerState.MMB && !OldMouseControllerState.MMB); } + float GetMouseX() { return NewMouseControllerState.x; } + float GetMouseY() { return NewMouseControllerState.y; } // keyboard diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 8bb9caee..4876c555 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -154,7 +154,7 @@ spawnCar(int id) } #endif -void +static void FixCar(void) { CVehicle *veh = FindPlayerVehicle(); @@ -167,6 +167,15 @@ FixCar(void) ((CAutomobile*)veh)->Fix(); } +static void +ToggleComedy(void) +{ + CVehicle *veh = FindPlayerVehicle(); + if(veh == nil) + return; + veh->bComedyControls = !veh->bComedyControls; +} + void DebugMenuPopulate(void) { @@ -212,6 +221,8 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat); DebugMenuAddCmd("Debug", "Fix Car", FixCar); + DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy); + DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil); DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil); DebugMenuAddVarBool8("Debug", "Show Collision Polys", (int8*)&gbShowCollisionPolys, nil); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 4b484a7f..3bab2d31 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -13,6 +13,8 @@ WRAPPER void CPlayerPed::ReApplyMoveAnims(void) { EAXJMP(0x4F07C0); } WRAPPER void CPlayerPed::SetupPlayerPed(int32) { EAXJMP(0x4EFB60); } WRAPPER void CPlayerPed::DeactivatePlayerPed(int32) { EAXJMP(0x4EFC00); } WRAPPER void CPlayerPed::ReactivatePlayerPed(int32) { EAXJMP(0x4EFC20); } +WRAPPER void CPlayerPed::KeepAreaAroundPlayerClear(void) { EAXJMP(0x4F3460); } + void CPlayerPed::ClearWeaponTarget() { diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 51a45203..1dfa33fa 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -45,6 +45,7 @@ public: void ClearWeaponTarget(); void SetWantedLevel(int32 level); void SetWantedLevelNoDrop(int32 level); + void KeepAreaAroundPlayerClear(void); static void SetupPlayerPed(int32); static void DeactivatePlayerPed(int32); 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;