diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index 33841956baa..919aa639ff5 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -3495,6 +3495,9 @@ void CClientGame::Event_OnIngame() g_pGame->GetVehicleAudioSettingsManager()->ResetAudioSettingsData(); + // Reset framerate fixing property + g_pMultiplayer->FramerateFixingResetPhysicsTimeStep(); + // Tell doggy we got the game running WatchDogCompletedSection("L1"); } diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 7f7521452c7..c8bcf2a0703 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -981,6 +981,10 @@ ADD_ENUM(VehicleAudioSettingProperty::VEHICLE_TYPE_FOR_AUDIO, "vehicle-type-for- IMPLEMENT_ENUM_CLASS_END("vehicle-audio-setting") +IMPLEMENT_ENUM_CLASS_BEGIN(FramerateFixingProperty) +ADD_ENUM(FramerateFixingProperty::FFP_VEHICLE_PHYSICS, "vehicle_physics") +IMPLEMENT_ENUM_END("framerate-fixing-property") + // // CResource from userdata // diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index da35c0d1cc2..403762eb005 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -25,6 +25,7 @@ #include "enums/SoundEffectParams.h" #include "enums/SoundEffectType.h" #include "enums/ObjectGroupPhysicalProperties.h" +#include "enums/FramerateFixingProperty.h" enum eLuaType { @@ -101,6 +102,7 @@ DECLARE_ENUM_CLASS(PreloadAreaOption); DECLARE_ENUM_CLASS(taskType); DECLARE_ENUM(eEntityType); DECLARE_ENUM_CLASS(VehicleAudioSettingProperty); +DECLARE_ENUM_CLASS(FramerateFixingProperty); class CRemoteCall; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 1fdc3fe7364..9f33fc8f204 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "CLuaEngineDefs.h" #include @@ -150,6 +151,9 @@ void CLuaEngineDefs::LoadFunctions() {"engineGetPoolUsedCapacity", ArgumentParser}, {"engineSetPoolCapacity", ArgumentParser}, {"enginePreloadWorldArea", ArgumentParser}, + {"engineFramerateFixingSetProperty", ArgumentParser}, + {"engineFramerateFixingGetProperty", ArgumentParser}, + {"engineFramerateFixingResetProperties", ArgumentParser}, // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); // CLuaCFunctions::AddFunction ( "engineReplaceWheelAtomics", EngineReplaceWheelAtomics ); @@ -199,6 +203,10 @@ void CLuaEngineDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setModelTXDID", "engineSetModelTXDID"); lua_classfunction(luaVM, "resetModelTXDID", "engineResetModelTXDID"); + lua_classfunction(luaVM, "framerateFixingSetProperty", "engineFramerateFixingSetProperty"); + lua_classfunction(luaVM, "framerateFixingGetProperty", "engineFramerateFixingGetProperty"); + lua_classfunction(luaVM, "framerateFixingResetProperties", "engineFramerateFixingResetProperties"); + lua_registerstaticclass(luaVM, "Engine"); // `EngineStreaming` class @@ -2602,3 +2610,28 @@ void CLuaEngineDefs::EnginePreloadWorldArea(CVector position, std::optionalGetStreaming()->LoadSceneCollision(&position); } + +void CLuaEngineDefs::EngineFramerateFixingResetProperties() +{ + g_pMultiplayer->FramerateFixingResetPhysicsTimeStep(); +} + +void CLuaEngineDefs::EngineFramerateFixingSetProperty(FramerateFixingProperty propertyName, float timestep) +{ + switch (propertyName) + { + case FramerateFixingProperty::FFP_VEHICLE_PHYSICS: + g_pMultiplayer->FramerateFixingSetPhysicsTimeStep(timestep); + break; + } +} + +std::variant CLuaEngineDefs::EngineFramerateFixingGetProperty(FramerateFixingProperty propertyName) +{ + switch (propertyName) + { + case FramerateFixingProperty::FFP_VEHICLE_PHYSICS: + return g_pMultiplayer->FramerateFixingGetPhysicsTimeStep(); + } + return false; +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 48fa2706a41..edb7f78ff6d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -97,6 +97,10 @@ class CLuaEngineDefs : public CLuaDefs static void EnginePreloadWorldArea(CVector position, std::optional option); + static void EngineFramerateFixingResetProperties(); + static void EngineFramerateFixingSetProperty(FramerateFixingProperty propertyName, float timestep); + static std::variant EngineFramerateFixingGetProperty(FramerateFixingProperty propertyName); + private: static void AddEngineColClass(lua_State* luaVM); static void AddEngineTxdClass(lua_State* luaVM); diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 0aad6ce10d9..2d6252a565e 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -365,6 +365,11 @@ class CMultiplayerSA : public CMultiplayer unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept override; unsigned int PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept override; + //Framerate Fixing Property + void FramerateFixingResetPhysicsTimeStep() override; + void FramerateFixingSetPhysicsTimeStep(float timestep) override; + float FramerateFixingGetPhysicsTimeStep() const noexcept override; + CVector m_vecAkimboTarget; bool m_bAkimboTargetUp; static char* ms_PlayerImgCachePtr; @@ -390,7 +395,6 @@ class CMultiplayerSA : public CMultiplayer float m_fShadowsOffset; bool m_isRapidVehicleStopFixEnabled{false}; - /* VOID SetPlayerShotVectors(CPlayerPed* player, Vector3D * vecTarget, Vector3D * vecStart); VOID SetPlayerCameraVectors(CPlayerPed* player, Vector3D * vecSource, Vector3D * vecFront); Vector3D * GetLocalShotOriginVector();*/ diff --git a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp index bf8216ec936..14d6f8e5d95 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_FrameRateFixes.cpp @@ -13,8 +13,12 @@ static bool bWouldBeNewFrame = false; static unsigned int nLastFrameTime = 0; +// The global constant timestep for framerate fixing. constexpr float kOriginalTimeStep = 50.0f / 30.0f; +// The timestep for vehicle physics framerate fixing is adjustable by script. +static float kPhysicTimeStep = kOriginalTimeStep; + // Fixes player movement issue while aiming and walking on high FPS. #define HOOKPOS_CTaskSimpleUseGun__SetMoveAnim 0x61E4F2 #define HOOKSIZE_CTaskSimpleUseGun__SetMoveAnim 0x6 @@ -714,7 +718,7 @@ static void __declspec(naked) HOOK_CPhysical__ApplyAirResistance() { fld ds:[0x862CD0] // 0.99000001f fld ds:[0xB7CB5C] // CTimer::ms_fTimeStep - fdiv kOriginalTimeStep // 1.666f + fdiv kPhysicTimeStep // 1.666f mov eax, 0x822130 // powf call eax @@ -742,11 +746,27 @@ static void __declspec(naked) HOOK_VehicleRapidStopFix() { fld ds:[0xC2B9CC] // mod_HandlingManager.m_fWheelFriction fmul ds:[0xB7CB5C] // CTimer::ms_fTimeStep - fdiv kOriginalTimeStep // 1.666f + fdiv kPhysicTimeStep // 1.666f jmp RETURN_VehicleRapidStopFix } } +void CMultiplayerSA::FramerateFixingResetPhysicsTimeStep() +{ + kPhysicTimeStep = kOriginalTimeStep; +} + +void CMultiplayerSA::FramerateFixingSetPhysicsTimeStep(float timestep) +{ + // Just change time step, will be automatically applied when related hook is installed + kPhysicTimeStep = timestep; +} + +float CMultiplayerSA::FramerateFixingGetPhysicsTimeStep() const noexcept +{ + return kPhysicTimeStep; +} + void CMultiplayerSA::SetRapidVehicleStopFixEnabled(bool enabled) { if (m_isRapidVehicleStopFixEnabled == enabled) diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index e5e591ad5d3..3e9c7f331a5 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -465,6 +465,10 @@ class CMultiplayer virtual eAnimID GetLastStaticAnimationID() = 0; virtual DWORD GetLastAnimArrayAddress() = 0; + virtual void FramerateFixingResetPhysicsTimeStep() = 0; + virtual void FramerateFixingSetPhysicsTimeStep(float timestep) = 0; + virtual float FramerateFixingGetPhysicsTimeStep() const noexcept = 0; + virtual unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept = 0; virtual unsigned int PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept = 0; }; diff --git a/Shared/sdk/enums/FramerateFixingProperty.h b/Shared/sdk/enums/FramerateFixingProperty.h new file mode 100644 index 00000000000..fdb4864243d --- /dev/null +++ b/Shared/sdk/enums/FramerateFixingProperty.h @@ -0,0 +1,17 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/FramerateFixingProperty.h + * PURPOSE: Header for common definitions + * + * Multi Theft Auto is available from https://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +enum class FramerateFixingProperty +{ + FFP_VEHICLE_PHYSICS +};