Implement cl_paused 2

This commit is contained in:
fed 2023-08-13 04:14:04 +02:00
parent 23d1f2e997
commit 4101540add
3 changed files with 157 additions and 1 deletions

View File

@ -0,0 +1,142 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game/dvars.hpp"
#include "command.hpp"
#include "console.hpp"
#include <utils/hook.hpp>
namespace camera
{
namespace
{
game::dvar_t* cl_free_move_scale = nullptr;
float angle_normalize(const float angle)
{
const auto value = ((angle * 0.0027777778f) - std::floorf(angle * 0.0027777778f)) * 360.f;
auto result = value - 360.f;
if ((value - 360.f) < 0.f)
{
result = value;
}
return result;
}
void vec_cross(float* a1, float* a2, float* a3)
{
a3[0] = (a2[2] * a1[1]) - (a2[1] * a1[2]);
a3[1] = (a1[2] * a2[0]) - (a2[2] * a1[0]);
a3[2] = (a2[1] * a1[0]) - (a1[1] * a2[0]);
}
void paused_free_move()
{
const auto cg_paused = *reinterpret_cast<game::dvar_t**>(0x141E39FC0);
if (cg_paused->current.integer != 2)
{
return;
}
constexpr auto local_client_num = 0;
const auto ps = game::CG_GetPredictedPlayerState(local_client_num);
const auto cmd_number = game::CL_GetCurrentCmdNumber(local_client_num);
game::usercmd_s cmd{};
if (!game::CL_GetUserCmd(local_client_num, cmd_number, &cmd))
{
return;
}
float viewangles[3]{};
viewangles[0] = angle_normalize((cmd.angles[0] * 0.000021457672f) + ps->delta_angles[0]);
viewangles[1] = angle_normalize((cmd.angles[1] * 0.000021457672f) + ps->delta_angles[1]);
viewangles[2] = angle_normalize((cmd.angles[2] * 0.000021457672f) + ps->delta_angles[2]);
const auto game_time = game::CG_GetGameTime(local_client_num);
static auto saved_game_time = 0;
static auto saved_ms = 0;
if (saved_game_time != game_time)
{
saved_game_time = game_time;
saved_ms = game::Sys_Milliseconds();
}
const auto now = game::Sys_Milliseconds();
const auto diff = now - saved_ms;
saved_ms = game::Sys_Milliseconds();
auto scale = 1.f;
if ((cmd.buttons & 0x6) != 0)
{
scale = 10.f;
}
scale *= cl_free_move_scale->current.value;
game::AnglesToAxis(viewangles, game::refdef->axis);
float v1[3] = {0.f, 0.f, 1.f};
float v2[3] = {game::refdef->axis[0][0], game::refdef->axis[0][1], game::refdef->axis[0][2]};
float v3[3]{};
vec_cross(v1, v2, v3);
vec_cross(v3, v1, v2);
if (cmd.forwardmove)
{
ps->origin[0] += scale * (game::refdef->axis[0][0] * (static_cast<float>(cmd.forwardmove) * 0.2f) * (static_cast<float>(diff) * 0.05f));
ps->origin[1] += scale * (game::refdef->axis[0][1] * (static_cast<float>(cmd.forwardmove) * 0.2f) * (static_cast<float>(diff) * 0.05f));
ps->origin[2] += scale * (game::refdef->axis[0][2] * (static_cast<float>(cmd.forwardmove) * 0.2f) * (static_cast<float>(diff) * 0.05f));
}
if (cmd.rightmove)
{
ps->origin[0] += scale * (v3[0] * (static_cast<float>(-1 * cmd.rightmove) * 0.2f) * (static_cast<float>(diff) * 0.05f));
ps->origin[1] += scale * (v3[1] * (static_cast<float>(-1 * cmd.rightmove) * 0.2f) * (static_cast<float>(diff) * 0.05f));
ps->origin[2] += scale * (v3[2] * (static_cast<float>(-1 * cmd.rightmove) * 0.2f) * (static_cast<float>(diff) * 0.05f));
}
if ((cmd.buttons & 0x1) != 0)
{
ps->origin[2] += scale * 10.f;
}
if ((cmd.buttons & 0x800) != 0)
{
ps->origin[2] -= scale * 10.f;
}
game::refdef->org[0] = ps->origin[0];
game::refdef->org[1] = ps->origin[1];
game::refdef->org[2] = ps->origin[2];
}
void set_viewpos_now_stub(void* a1)
{
paused_free_move();
utils::hook::invoke<void>(0x1403B07C0, a1);
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
cl_free_move_scale = dvars::register_float("cl_freemoveScale", 1.f, 0.01f, 100.f,
game::DVAR_FLAG_SAVED, "Scale how fast you move in cl_freemove mode");
utils::hook::call(0x1403ACB2D, set_viewpos_now_stub);
}
};
}
REGISTER_COMPONENT(camera::component)

View File

@ -752,9 +752,12 @@ namespace game
char __pad2[40];
vec3_t origin;
vec3_t velocity;
char __pad3[144];
vec3_t delta_angles;
};
static_assert(offsetof(playerState_s, origin) == 128);
static_assert(offsetof(playerState_s, delta_angles) == 296);
struct SprintState_s
{
@ -769,7 +772,9 @@ namespace game
{
int serverTime;
int buttons;
char __pad0[20];
int angles[3];
unsigned int weapon;
unsigned int offHand;
char forwardmove;
char rightmove;
char __pad1[2];

View File

@ -6,6 +6,8 @@ namespace game
{
// Functions
WEAK symbol<void(float* angles, float(*axis)[3])> AnglesToAxis{0x140613090};
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x1405C0EB0};
WEAK symbol<void(unsigned int id)> AddRefToObject{0x1405C0EA0};
WEAK symbol<unsigned int(unsigned int id)> AllocThread{0x1405C1200};
@ -22,10 +24,16 @@ namespace game
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessageBold{0x14037F1B0};
WEAK symbol<char*(const unsigned int weapon,
bool isAlternate, char* outputBuffer, int bufferLen)> CG_GetWeaponDisplayName{0x1403B9210};
WEAK symbol<int(int localClientNum)> CG_GetGameTime{0x14037F580};
WEAK symbol<playerState_s*(int localClientNum)> CG_GetPredictedPlayerState{0x14037F720};
WEAK symbol<void(ScreenPlacement* place, float x, float y, float w, float h, int horzAlign, int vertAlign,
float t0, float s0, float t1, float s1, float* color, Material* material)> CL_DrawStretchPic{0x1403C9570};
WEAK symbol<int(int localClientNum, int cmdNumber, usercmd_s* cmd)> CL_GetUserCmd{0x1403C9F10};
WEAK symbol<int(int localClientNum)> CL_GetCurrentCmdNumber{0x1403C9D80};
WEAK symbol<void(const char* cmdName, void(), cmd_function_s* allocedCmd)> Cmd_AddCommandInternal{0x14059A5F0};
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{0x14059ABA0};
@ -252,6 +260,7 @@ namespace game
WEAK symbol<int> g_poolSize{0x140BF2E40};
WEAK symbol<GfxWorld*> gfx_map{0x14EE49000};
WEAK symbol<ComWorld> comWorld{0x14AD26078};
WEAK symbol<gentity_s> g_entities{0x1452DDDA0};
WEAK symbol<gclient_s> g_clients{0x1455DA980};