diff --git a/src/client/component/slowmotion.cpp b/src/client/component/slowmotion.cpp index d688083..3a0e1b5 100644 --- a/src/client/component/slowmotion.cpp +++ b/src/client/component/slowmotion.cpp @@ -2,6 +2,9 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" +#include "command.hpp" +#include "console.hpp" + #include #include @@ -54,6 +57,25 @@ namespace slowmotion client->nextSnapshotTime = *game::mp::serverTime - 1; } } + + void set_code_time_scale(float timescale) + { + assert(timescale > 0.0f); + *game::com_codeTimeScale = timescale; + } + + void com_timescale_f(const command::params& params) + { + if (params.size() != 2) + { + console::info("timescale \n"); + return; + } + + const auto timescale = static_cast(std::atof(params.get(1))); + console::info("timescale set to %f\n", timescale); + set_code_time_scale(timescale); + } } class component final : public component_interface @@ -61,7 +83,17 @@ namespace slowmotion public: void post_unpack() override { - if (!game::environment::is_dedi()) return; + if (game::environment::is_sp()) + { + return; + } + + command::add("timescale", com_timescale_f); + + if (!game::environment::is_dedi()) + { + return; + } utils::hook::jump(0x1403B4A10, scr_cmd_set_slow_motion); diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 14a7a4e..af98092 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -308,6 +308,8 @@ namespace game WEAK symbol g_load{0x1418CF4A0, 0x141EEFBA0}; + WEAK symbol com_codeTimeScale{0x0, 0x1445CEF84}; + WEAK symbol g_wv{0x145A7BAD0, 0x147AD2630}; WEAK symbol s_wmv{0x145A73750, 0x147AC9D78}; diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 75a8117..b5f49ae 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -1,5 +1,6 @@ #pragma once #include "memory.hpp" +#include #include template @@ -29,7 +30,12 @@ namespace utils::string while (true) { - const auto res = vsnprintf_s(entry->buffer_, entry->size_, _TRUNCATE, format, ap); + va_list ap_copy; + va_copy(ap_copy, ap); + + const auto res = vsnprintf_s(entry->buffer_, entry->size_, _TRUNCATE, format, ap_copy); + va_end(ap_copy); + if (res > 0) break; // Success if (res == 0) return nullptr; // Error