Last active
March 13, 2017 14:29
-
-
Save ikt32/d83a8ea80577df4092cc0ddd78c4ad0a to your computer and use it in GitHub Desktop.
Very first attempt at gear locking in GTA V
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using GTA; | |
using GTA.Native; | |
public class Gears : Script { | |
Random random = new Random(); | |
public Gears() { | |
Tick += OnTick; | |
Interval = 0; | |
} | |
void OnTick(object sender, EventArgs e) { | |
Ped player = Game.Player.Character; | |
Vehicle vehicle = player.CurrentVehicle; | |
if (player.IsInVehicle() && vehicle.Model.IsCar) { | |
ulong address = vehicle.GetAddress; | |
uint gears = vehicle.CurrentGear; | |
float rpm = vehicle.CurrentRPM; | |
float clutch = vehicle.Clutch; | |
float throttle = vehicle.Throttle; | |
float turbo = vehicle.Turbo; | |
uint currGear = (0xFFFF0000 & gears) >> 16; | |
uint nextGear = 0x0000FFFF & gears; | |
// Park/Reverse. Gear 0. Prevent going forward in gear 0. | |
if (currGear == 0 && !Game.IsControlPressed(0, Control.VehicleBrake) && vehicle.Speed < 1.0f) { | |
vehicle.HandbrakeOn = true; | |
vehicle.BrakeLightsOn = true; | |
} | |
// Forward gears. Prevent reversing. | |
else if (currGear > 0 && !Game.IsControlPressed(0, Control.VehicleAccelerate) && Game.IsControlPressed(0, Control.VehicleBrake) && vehicle.Speed < 1.0f) | |
{ | |
vehicle.HandbrakeOn = true; | |
vehicle.BrakeLightsOn = true; | |
} | |
else | |
{ | |
vehicle.HandbrakeOn = false; | |
} | |
// Game wants to shift up. Triggered at high RPM, high speed. | |
// Desired result: high RPM, same gear (currGear) | |
if (currGear < nextGear) { | |
vehicle.CurrentGear = currGear | (currGear << 16); | |
vehicle.CurrentRPM = 1.6f; | |
vehicle.Clutch = 1.0f; | |
vehicle.Throttle = 1.0f; | |
} | |
// Game wants to shift down. Usually triggered when user accelerates | |
// while in a too high gear. | |
// Desired result: low RPM or stall, even. Stay in current gear! | |
// Otherwise: force car to drive anyway to keep RPM up. | |
// Current: Game cuts engine power | |
if (currGear > nextGear) { | |
vehicle.CurrentGear = currGear | (currGear << 16); | |
vehicle.Clutch = 1.0f; | |
vehicle.Throttle = 1.0f; | |
/*if (currGear == 2) { | |
vehicle.CurrentRPM = Game.GetControlNormal(0, Control.VehicleAccelerate) * 0.40f; | |
} | |
else | |
{ | |
vehicle.Clutch = 1.0f; | |
vehicle.Throttle = 1.0f; | |
}*/ | |
} | |
// Shift up | |
if (Game.IsControlJustPressed(0, Control.VehicleDuck)) { | |
vehicle.CurrentGear = currGear + 1 | (currGear + 1 << 16); | |
vehicle.Clutch = 0.1f; | |
vehicle.Throttle = 0.5f; | |
} | |
// Shift down | |
if (Game.IsControlJustPressed(0, Control.VehicleSelectNextWeapon)) { | |
if (currGear > 0) { | |
vehicle.CurrentGear = currGear - 1 | (currGear - 1 << 16); | |
if (vehicle.EngineRunning == false) { | |
vehicle.EngineRunning = true; | |
} | |
} | |
} | |
// Trying stuff | |
if (Game.IsControlPressed(0, Control.VehicleAim)) { | |
vehicle.Throttle = 1.0f; | |
vehicle.Clutch = 1.0f; | |
vehicle.CurrentRPM = 2.2f; | |
} | |
string info = "RPM: " + rpm + | |
"\nCurrGear: " + currGear + | |
"\nNextGear: " + nextGear + | |
"\nClutch: " + clutch + | |
"\nThrottle: " + throttle + | |
"\nTurbo: " + turbo + | |
"\nAddress: " + address.ToString("X"); | |
Function.Call(Hash.SET_TEXT_FONT, 0); | |
Function.Call(Hash.SET_TEXT_SCALE, 0.4f, 0.4f); | |
Function.Call(Hash.SET_TEXT_COLOUR, 255, 255, 255, 255); | |
Function.Call(Hash.SET_TEXT_WRAP, 0.0, 1.0); | |
Function.Call(Hash.SET_TEXT_CENTRE, 0); | |
Function.Call(Hash.SET_TEXT_DROPSHADOW, 0, 0, 0, 0, 0); | |
Function.Call(Hash.SET_TEXT_EDGE, 1, 0, 0, 0, 205); | |
Function.Call(Hash._SET_TEXT_ENTRY, "STRING"); | |
Function.Call(Hash._ADD_TEXT_COMPONENT_STRING, info); | |
Function.Call(Hash._DRAW_TEXT, 0.01, 0.5); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
System::UInt32 Vehicle::CurrentGear::get() | |
{ | |
unsigned char *const address = reinterpret_cast<unsigned char *>(Native::MemoryAccess::GetAddressOfEntity(Handle)); | |
int offset = 0x7a0; | |
return address == 0 ? 0 : *reinterpret_cast<const System::UInt32 *>(address + offset); | |
} | |
void Vehicle::CurrentGear::set(System::UInt32 value) | |
{ | |
unsigned char *const address = reinterpret_cast<unsigned char *>(Native::MemoryAccess::GetAddressOfEntity(Handle)); | |
int offset = 0x7a0; | |
*(address + offset) = value; | |
} | |
float Vehicle::Clutch::get() | |
{ | |
unsigned char *const address = reinterpret_cast<unsigned char *>(Native::MemoryAccess::GetAddressOfEntity(Handle)); | |
int offset = 0x7E0; | |
return address == 0 ? 0 : *reinterpret_cast<const float *>(address + offset); | |
} | |
void Vehicle::Clutch::set(float value) | |
{ | |
System::UInt64 address = Native::MemoryAccess::GetAddressOfEntity(Handle); | |
int offset = 0x7E0; | |
*reinterpret_cast<float *>(address + offset) = value; | |
} | |
float Vehicle::Turbo::get() | |
{ | |
unsigned char *const address = reinterpret_cast<unsigned char *>(Native::MemoryAccess::GetAddressOfEntity(Handle)); | |
int offset = 0x7F8; | |
return address == 0 ? 0 : *reinterpret_cast<const float *>(address + offset); | |
} | |
void Vehicle::Turbo::set(float value) | |
{ | |
System::UInt64 address = Native::MemoryAccess::GetAddressOfEntity(Handle); | |
int offset = 0x7F8; | |
*reinterpret_cast<float *>(address + offset) = value; | |
} | |
float Vehicle::Throttle::get() | |
{ | |
System::UInt64 address = Native::MemoryAccess::GetAddressOfEntity(Handle); | |
int offset = 0x7E4; | |
return *reinterpret_cast<float *>(address + offset); | |
} | |
void Vehicle::Throttle::set(float value) | |
{ | |
System::UInt64 address = Native::MemoryAccess::GetAddressOfEntity(Handle); | |
int offset = 0x7E4; | |
*reinterpret_cast<float *>(address + offset) = value; | |
} | |
System::UInt64 Vehicle::GetAddress::get() | |
{ | |
const System::UInt64 address = Native::MemoryAccess::GetAddressOfEntity(Handle); | |
return address; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a ScriptHookVDotNet file.
vehicle.cpp was modified from ScriptHookVDotNet to access more CVehicle members. If, for some reason, you want to re-build the version I started everything with, SHVDN version 2.something was used. Version 3 onwards is fully C# for game code.