[REL/LIB] Handling Replacement
-
Handling Replacement
Info
A library/tool for script developers, to manage vehicle handling changes in non-intrusive way. It clones the handling of a vehicle, and assign the copy to the vehicle, so only that vehicle is affected by changes to its handling data.
This comes in handy for scripts that want to continuously vary certain parameters, without affecting other instances of that vehicle model.
An example is my variable drive bias, which changes
fDriveBiasFront
constantly:Usage
The header as of now:
#pragma once #ifdef HR_EXPORTS #define HR_API extern "C" __declspec(dllexport) #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) #define VER_MAJOR 1 #define VER_MINOR 0 #define VER_PATCH 0 #define HR_VER STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) #else #ifndef HR_RUNTIME #define HR_API extern "C" __declspec(dllimport) #else // noop #define HR_API #endif #endif /** * \brief Enables the replacement handling on the vehicle. Increments reference count if \p vehicle already has a * replaced handling. * * \param [in] vehicle Vehicle to enable the replacement handling on. * \param [out] ppHandlingData Pointer to replaced handling pointer.\n * nullptr when \p vehicle doesn't exist. * \return true if this HR_Enable call replaced the handling.\n * false if the handling already has been replaced, or\n * if \p ppHandlingData is nullptr, or\n * if \p vehicle doesn't exist. */ HR_API bool HR_Enable(int vehicle, void** ppHandlingData); /** * \brief Decrements reference count on \p vehicle. Disables the replacement handling on the vehicle when * the reference count has reached 0. * * \param [in] vehicle Vehicle to restore handling on. * \param [out] ppHandlingData Pointer to current handling pointer after deletion.\n * nullptr when \p vehicle doesn't exist. * \return true if this HR_Enable call restored the original handling.\n * false if the handling was not restored by this call, or\n * if \p vehicle didn't have a replaced handling, or\n * if \p ppHandlingData is nullptr, or\n * if \p vehicle doesn't exist. */ HR_API bool HR_Disable(int vehicle, void** ppHandlingData); /** * \brief Get the current handling data * * \param [in] vehicle Vehicle to get handling from. * \param [out] ppHandlingDataOriginal Pointer to the original handling.\n * nullptr if \p vehicle doesn't exist.\n * <b>DO NOT WRITE TO THIS!</b> * \param [out] ppHandlingDataReplaced Pointer to the replaced handling.\n * nullptr if \p vehicle doesn't exist or no replaced handling. * \return true if the handling has been replaced.\n * false if the handling is original, or\n * if either \p ppHandlingDataOriginal / \p ppHandlingDataReplaced * is null, or * if \p vehicle doesn't exist.\n */ HR_API bool HR_GetHandlingData(int vehicle, void** ppHandlingDataOriginal, void** ppHandlingDataReplaced);
Currently general usage:
void* handlingDataOrig = nullptr; void* handlingDataReplace = nullptr; if (!HR_GetHandlingData(g_playerVehicle, &handlingDataOrig, &handlingDataReplace)) { HR_Enable(g_playerVehicle, &handlingDataReplace); return; } // after this you can read or write stuff, e.g. *(float*)((uint8_t*)handlingDataReplace + fInitialDriveForceOffset) = 1.0f;
CHandlingData
is left to the user. The library only clonesCHandlingData
andCBaseSubHandlingData
and doesn't mess around or limit the user further. Thus,void**
is used to passCHandlingData*
around.Credits
FiveM: Couldn't get
CBaseSubHandlingData
to work without some helpDownload