fix killcam slowmotion

This commit is contained in:
quaK 2024-07-13 02:13:05 +03:00
parent dcab6a35f8
commit 5c66f8b5de
6 changed files with 118 additions and 5 deletions

View File

@ -83,7 +83,11 @@ namespace dedicated
// R_SyncGpu
utils::hook::invoke<void>(0x140E08AE0, a1);
std::this_thread::sleep_for(1ms);
const auto frame_time = *game::com_frameTime;
const auto sys_msec = game::Sys_Milliseconds();
const auto msec = frame_time - sys_msec;
std::this_thread::sleep_for(std::chrono::milliseconds(msec));
}
void gscr_is_using_match_rules_data_stub()

View File

@ -40,7 +40,15 @@ namespace patches
game::dvar_t* com_maxfps;
name_dvar = game::Dvar_RegisterString("name", get_login_username().data(), game::DVAR_FLAG_SAVED, "Player name.");
if (game::environment::is_dedi())
{
com_maxfps = game::Dvar_RegisterInt("com_maxfps", 85, 0, 100, game::DVAR_FLAG_NONE, "Cap frames per second");
}
else
{
com_maxfps = game::Dvar_RegisterInt("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED, "Cap frames per second");
}
*reinterpret_cast<game::dvar_t**>(0x146005758) = com_maxfps;
dvars::disable::re_register("com_maxfps");
@ -222,7 +230,7 @@ namespace patches
com_register_common_dvars_hook.create(0x140BADF30, com_register_common_dvars_stub);
// patch some features
com_game_mode_supports_feature_hook.create(0x1405AFDE0, com_game_mode_supports_feature_stub);
com_game_mode_supports_feature_hook.create(game::Com_GameMode_SupportsFeature, com_game_mode_supports_feature_stub);
// get client name from dvar
utils::hook::jump(0x140D32770, live_get_local_client_name);

View File

@ -0,0 +1,89 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game/dvars.hpp"
#include "dvars.hpp"
#include "gsc/script_extension.hpp"
#include <utils/hook.hpp>
namespace timescale
{
namespace
{
template <typename T, typename T2>
T get_timescale_safe(const scripting::value_wrap& arg)
{
if (arg.is<T>())
{
return arg.as<T>();
}
return static_cast<T>(arg.as<T2>());
}
void com_init_dobj_stub()
{
utils::hook::invoke<void>(0x140BB17E0); // call original
if (game::Com_GameMode_SupportsFeature(game::Com_GameMode_Feature::FEATURE_TIMESCALE))
{
auto com_timescale = game::Dvar_FindVar("com_timescale");
game::Dvar_SetFloat(com_timescale, 1.0f);
}
}
utils::hook::detour com_set_slow_motion_hook;
void com_set_slow_motion_stub(float startTimescale, float endTimescale, int deltaMsec)
{
com_set_slow_motion_hook.invoke<void>(startTimescale, endTimescale, deltaMsec);
if (game::Com_GameMode_SupportsFeature(game::Com_GameMode_Feature::FEATURE_TIMESCALE))
{
if (endTimescale == startTimescale)
{
auto com_timescale = game::Dvar_FindVar("com_timescale");
game::Dvar_SetFloat(com_timescale, endTimescale);
}
}
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
dvars::override::register_float("timescale", 1.0f, 0.1f, 1000.0f, game::DVAR_FLAG_CHEAT);
dvars::override::register_float("com_timescale", 1.0f, 0.1f, 1000.0f, game::DVAR_FLAG_CHEAT | 0x40 | game::DVAR_FLAG_READ);
// reset com_timeScale dvar in Com_Restart
utils::hook::call(0x140BAF16D, com_init_dobj_stub);
// set com_timeScale in Com_SetSlowMotion
com_set_slow_motion_hook.create(game::Com_SetSlowMotion, com_set_slow_motion_stub);
gsc::function::add("setslowmotion", [](const gsc::function_args& args)
{
if (args.size() == 0)
{
return scripting::script_value{};
}
const auto start = get_timescale_safe<float, int>(args[0]);
const auto end = (args.size() > 0 ? get_timescale_safe<float, int>(args[1]) : 1.0f);
const auto duration = (args.size() > 1 ? get_timescale_safe<int, float>(args[2]) : 1) * 1000;
game::SV_SetConfigString(game::CS_TIMESCALE, utils::string::va("%i %i %g %g", *game::gameTime, duration, start, end));
game::Com_SetSlowMotion(start, end, duration);
return scripting::script_value{};
});
}
};
}
REGISTER_COMPONENT(timescale::component)

View File

@ -244,7 +244,7 @@ namespace game
va_end(ap);
const auto file = dvars::g_log->current.string;
const auto time = *game::level_time / 1000;
const auto time = *game::gameTime / 1000;
utils::io::write_file(file, utils::string::va("%3i:%i%i %s",
time / 60,

View File

@ -560,6 +560,11 @@ namespace game
SAY_TELL = 0x2,
};
enum ConfigString : std::int32_t
{
CS_TIMESCALE = 3464,
};
namespace entity
{
enum connstate_t : std::uint32_t

View File

@ -37,12 +37,15 @@ namespace game
WEAK symbol<void(GameModeType)> Com_GameMode_SetDesiredGameMode{ 0x1405AFDA0 };
WEAK symbol<GameModeType()> Com_GameMode_GetActiveGameMode{ 0x1405AFD50 };
WEAK symbol<bool(const char* name)> Com_GameMode_SupportsMap{ 0x1405AFE10 };
WEAK symbol<bool(Com_GameMode_Feature)> Com_GameMode_SupportsFeature{ 0x1405AFDE0 };
WEAK symbol<bool()> Com_IsAnyLocalServerStarting{ 0x140BAD9C0 };
WEAK symbol<bool()> Com_IsAnyLocalServerRunning{ 0x140BAD9A0 };
WEAK symbol<void(const char* localizedMessage, const char* localizedTitle)> Com_SetLocalizedErrorMessage{ 0x140BAF300 };
WEAK symbol<void(float startTimescale, float endTimescale, int deltaMsec)> Com_SetSlowMotion{ 0x140BAFD70 };
WEAK symbol<void()> Com_SyncThreads{ 0x140BB02D0 };
WEAK symbol<void(const char* finalmsg)> Com_Shutdown{ 0x140BAFEA0 };
@ -121,6 +124,7 @@ namespace game
WEAK symbol<void(dvar_t* dvar, DvarSetSource source)> Dvar_Reset{ 0x140CEC490 };
WEAK symbol<unsigned int(const char* name)> Dvar_GenerateChecksum{ 0x140CEA520 };
WEAK symbol<void(dvar_t* dvar, int value)> Dvar_SetInt{ 0x140CED3D0 };
WEAK symbol<void(dvar_t* dvar, float value)> Dvar_SetFloat{ 0x140CECD90 };
WEAK symbol<void(bool cheatOverride)> Dvar_OverrideCheatProtection{ 0x140CEB250 };
WEAK symbol<__int64(const char* qpath, char** buffer)> FS_ReadFile{ 0x140CDE200 };
@ -265,6 +269,7 @@ namespace game
WEAK symbol<bool()> SV_Loaded{ 0x140C114C0 };
WEAK symbol<bool(const char* name)> SV_MapExists{ 0x140CDB620 };
WEAK symbol<playerState_s* (int num)> SV_GetPlayerstateForClientNum{ 0x140C123A0 };
WEAK symbol<void(unsigned int index, const char* val)> SV_SetConfigString{ 0x140C11CD0 };
WEAK symbol<gentity_s* (const char* bot_name, unsigned int head, unsigned int body, unsigned int helmet)> SV_AddBot{ 0x140C4E340 };
WEAK symbol<bool(int clientNum)> SV_BotIsBot{ 0x140C3BC90 };
@ -350,7 +355,9 @@ namespace game
WEAK symbol<bool> g_quitRequested{ 0x14779CD44 };
WEAK symbol<unsigned int> gameEntityId{ 0x14665A124 };
WEAK symbol<int> level_time{ 0x143C986D8 };
WEAK symbol<int> gameTime{ 0x143C986D8 };
WEAK symbol<int> com_frameTime{ 0x1460053C0 };
WEAK symbol<int> s_frontEndScene_state{ 0x144BFF608 };