CS strafing dvar
This commit is contained in:
parent
502b7ac3dd
commit
84973e0837
@ -133,7 +133,7 @@ namespace gameplay
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void pm_player_trace_stub(game::pmove_t* pm, game::trace_t* trace, const float* f3,
|
void pm_player_trace_stub(game::mp::pmove_t* pm, game::trace_t* trace, const float* f3,
|
||||||
const float* f4, const game::Bounds* bounds, int a6, int a7)
|
const float* f4, const game::Bounds* bounds, int a6, int a7)
|
||||||
{
|
{
|
||||||
pm_player_trace_hook.invoke<void>(pm, trace, f3, f4, bounds, a6, a7);
|
pm_player_trace_hook.invoke<void>(pm, trace, f3, f4, bounds, a6, a7);
|
||||||
|
180
src/client/component/movement.cpp
Normal file
180
src/client/component/movement.cpp
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include "loader/component_loader.hpp"
|
||||||
|
#include "game/game.hpp"
|
||||||
|
#include "game/dvars.hpp"
|
||||||
|
|
||||||
|
#include <utils/hook.hpp>
|
||||||
|
#include <utils/vector.hpp>
|
||||||
|
|
||||||
|
// https://github.com/xoxor4d/iw3xo-dev/blob/develop/src/components/modules/movement.cpp :)
|
||||||
|
|
||||||
|
namespace movement
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
utils::hook::detour pm_airmove_hook;
|
||||||
|
|
||||||
|
game::dvar_t* pm_cs_airAccelerate;
|
||||||
|
game::dvar_t* pm_cs_airSpeedCap;
|
||||||
|
game::dvar_t* pm_cs_strafing;
|
||||||
|
|
||||||
|
void pm_air_accelerate(game::vec3_t wishdir, float wishspeed, game::mp::playerState_s* ps, game::mp::pml_t* pml)
|
||||||
|
{
|
||||||
|
float wishspd = wishspeed, accelspeed, currentspeed, addspeed;
|
||||||
|
|
||||||
|
auto accel = pm_cs_airAccelerate->current.value;
|
||||||
|
auto airspeedcap = pm_cs_airSpeedCap->current.value;
|
||||||
|
|
||||||
|
if (wishspd > airspeedcap)
|
||||||
|
{
|
||||||
|
wishspd = airspeedcap;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentspeed = utils::vector::product(ps->velocity, wishdir);
|
||||||
|
addspeed = wishspd - currentspeed;
|
||||||
|
|
||||||
|
if (addspeed > 0)
|
||||||
|
{
|
||||||
|
accelspeed = pml->frametime * accel * wishspeed * 1.0f;
|
||||||
|
|
||||||
|
if (accelspeed > addspeed)
|
||||||
|
{
|
||||||
|
accelspeed = addspeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
ps->velocity[i] += wishdir[i] * accelspeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pm_clip_velocity(game::vec3_t in, game::vec3_t normal, game::vec3_t out, float overbounce)
|
||||||
|
{
|
||||||
|
float backoff, change, angle, adjust;
|
||||||
|
|
||||||
|
angle = normal[2];
|
||||||
|
backoff = utils::vector::product(in, normal) * overbounce;
|
||||||
|
|
||||||
|
for (auto i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
change = normal[i] * backoff;
|
||||||
|
out[i] = in[i] - change;
|
||||||
|
}
|
||||||
|
|
||||||
|
adjust = utils::vector::product(out, normal);
|
||||||
|
|
||||||
|
if (adjust < 0)
|
||||||
|
{
|
||||||
|
game::vec3_t reduce{};
|
||||||
|
|
||||||
|
utils::vector::scale(normal, adjust, reduce);
|
||||||
|
utils::vector::subtract(out, reduce, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pm_try_playermove(game::mp::pmove_t* pm, game::mp::pml_t* pml)
|
||||||
|
{
|
||||||
|
const auto surf_slope = 0.7f;
|
||||||
|
const auto ps = pm->ps;
|
||||||
|
|
||||||
|
game::vec3_t end{};
|
||||||
|
game::trace_t trace{};
|
||||||
|
|
||||||
|
if (utils::vector::length(ps->velocity) == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::vector::ma(ps->origin, pml->frametime, ps->velocity, end);
|
||||||
|
utils::hook::invoke<void>(0x2D14C0_b, pm, &trace, ps->origin, end,
|
||||||
|
&pm->bounds, ps->clientNum, pm->tracemask); // PM_playerTrace
|
||||||
|
|
||||||
|
if (trace.fraction == 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trace.normal[2] > surf_slope)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_clip_velocity(ps->velocity, trace.normal, ps->velocity, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pm_airmove_stub(game::mp::pmove_t* pm, game::mp::pml_t* pml)
|
||||||
|
{
|
||||||
|
if (!pm_cs_strafing->current.enabled)
|
||||||
|
{
|
||||||
|
return pm_airmove_hook.invoke<void>(pm, pml);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ps = pm->ps;
|
||||||
|
|
||||||
|
ps->sprintButtonUpRequired = 1;
|
||||||
|
|
||||||
|
float fmove{}, smove{}, wishspeed{};
|
||||||
|
game::vec3_t wishvel{}, wishdir{};
|
||||||
|
|
||||||
|
fmove = pm->cmd.forwardmove;
|
||||||
|
smove = pm->cmd.rightmove;
|
||||||
|
|
||||||
|
pml->forward[2] = 0.0f;
|
||||||
|
pml->right[2] = 0.0f;
|
||||||
|
|
||||||
|
utils::vector::normalize(pml->forward);
|
||||||
|
utils::vector::normalize(pml->right);
|
||||||
|
|
||||||
|
for (auto i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
wishvel[i] = pml->forward[i] * fmove + pml->right[i] * smove;
|
||||||
|
}
|
||||||
|
|
||||||
|
wishvel[2] = 0;
|
||||||
|
|
||||||
|
utils::vector::copy(wishvel, wishdir);
|
||||||
|
wishspeed = utils::vector::normalize(wishdir);
|
||||||
|
|
||||||
|
if (wishspeed != 0 && (wishspeed > 320.0f))
|
||||||
|
{
|
||||||
|
utils::vector::scale(wishvel, 320.0f / wishspeed, wishvel);
|
||||||
|
wishspeed = 320.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_air_accelerate(wishdir, wishspeed, ps, pml);
|
||||||
|
|
||||||
|
utils::hook::invoke<void>(0x2D3380_b, pm, pml, 1, 1); // PM_StepSlideMove
|
||||||
|
|
||||||
|
pm_try_playermove(pm, pml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class component final : public component_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void post_unpack() override
|
||||||
|
{
|
||||||
|
if (game::environment::is_sp())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_airmove_hook.create(0x2C93B0_b, pm_airmove_stub);
|
||||||
|
|
||||||
|
pm_cs_airAccelerate = dvars::register_float("pm_cs_airAccelerate", 100.0f, 1.0f, 500.0f,
|
||||||
|
game::DvarFlags::DVAR_FLAG_REPLICATED,
|
||||||
|
"Defines player acceleration mid-air");
|
||||||
|
|
||||||
|
pm_cs_airSpeedCap = dvars::register_float("pm_cs_airSpeedCap", 30.0f, 1.0f, 500.0f,
|
||||||
|
game::DvarFlags::DVAR_FLAG_REPLICATED,
|
||||||
|
"Maximum speed mid-air");
|
||||||
|
|
||||||
|
pm_cs_strafing = dvars::register_bool("pm_cs_strafing", false,
|
||||||
|
game::DvarFlags::DVAR_FLAG_REPLICATED,
|
||||||
|
"Enable CS like strafing");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_COMPONENT(movement::component)
|
@ -1442,9 +1442,12 @@ namespace game
|
|||||||
|
|
||||||
struct trace_t
|
struct trace_t
|
||||||
{
|
{
|
||||||
char __pad0[41];
|
float fraction;
|
||||||
|
float normal[3];
|
||||||
|
char __pad0[25];
|
||||||
bool allsolid;
|
bool allsolid;
|
||||||
bool startsolid;
|
bool startsolid;
|
||||||
|
char __pad1[0x2C]; // not correct
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bounds
|
struct Bounds
|
||||||
@ -1453,10 +1456,6 @@ namespace game
|
|||||||
float halfSize[3];
|
float halfSize[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pmove_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
// made up
|
// made up
|
||||||
struct client_state_t
|
struct client_state_t
|
||||||
{
|
{
|
||||||
@ -1519,6 +1518,14 @@ namespace game
|
|||||||
static_assert(offsetof(gclient_s, name) == 18834);
|
static_assert(offsetof(gclient_s, name) == 18834);
|
||||||
static_assert(offsetof(gclient_s, flags) == 19488);
|
static_assert(offsetof(gclient_s, flags) == 19488);
|
||||||
|
|
||||||
|
struct usercmd_s
|
||||||
|
{
|
||||||
|
char __pad0[28];
|
||||||
|
char forwardmove;
|
||||||
|
char rightmove;
|
||||||
|
char __pad1[34];
|
||||||
|
};
|
||||||
|
|
||||||
struct EntityState
|
struct EntityState
|
||||||
{
|
{
|
||||||
uint16_t entityNum;
|
uint16_t entityNum;
|
||||||
@ -1540,6 +1547,33 @@ namespace game
|
|||||||
|
|
||||||
struct playerState_s
|
struct playerState_s
|
||||||
{
|
{
|
||||||
|
int clientNum;
|
||||||
|
char __pad0[116];
|
||||||
|
vec3_t origin;
|
||||||
|
vec3_t velocity;
|
||||||
|
char __pad1[312];
|
||||||
|
int sprintButtonUpRequired;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pmove_t
|
||||||
|
{
|
||||||
|
playerState_s* ps;
|
||||||
|
usercmd_s cmd;
|
||||||
|
usercmd_s oldcmd;
|
||||||
|
int tracemask;
|
||||||
|
int numtouch;
|
||||||
|
int touchents[32];
|
||||||
|
Bounds bounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(offsetof(pmove_t, touchents) == 144);
|
||||||
|
|
||||||
|
struct pml_t
|
||||||
|
{
|
||||||
|
float forward[3];
|
||||||
|
float right[3];
|
||||||
|
float up[3];
|
||||||
|
float frametime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clientHeader_t
|
struct clientHeader_t
|
||||||
|
59
src/common/utils/vector.cpp
Normal file
59
src/common/utils/vector.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "vector.hpp"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace utils::vector
|
||||||
|
{
|
||||||
|
float normalize(float* v)
|
||||||
|
{
|
||||||
|
const auto length = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
const auto ilength = 1 / length;
|
||||||
|
v[0] *= ilength;
|
||||||
|
v[1] *= ilength;
|
||||||
|
v[2] *= ilength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy(const float* in, float* out, int size)
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
out[i] = in[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scale(const float* in, float scale, float* out)
|
||||||
|
{
|
||||||
|
out[0] = in[0] * scale;
|
||||||
|
out[1] = in[1] * scale;
|
||||||
|
out[2] = in[2] * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ma(const float* v1, float scale, const float* v2, float* out)
|
||||||
|
{
|
||||||
|
out[0] = v1[0] + scale * v2[0];
|
||||||
|
out[1] = v1[1] + scale * v2[1];
|
||||||
|
out[2] = v1[2] + scale * v2[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void subtract(const float* veca, const float* vecb, float* out)
|
||||||
|
{
|
||||||
|
out[0] = veca[0] - vecb[0];
|
||||||
|
out[1] = veca[1] - vecb[1];
|
||||||
|
out[2] = veca[2] - vecb[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
float length(float* v)
|
||||||
|
{
|
||||||
|
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
float product(const float* v1, const float* v2)
|
||||||
|
{
|
||||||
|
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
|
||||||
|
}
|
||||||
|
}
|
12
src/common/utils/vector.hpp
Normal file
12
src/common/utils/vector.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace utils::vector
|
||||||
|
{
|
||||||
|
float normalize(float* v);
|
||||||
|
void copy(const float* in, float* out, int size = 3);
|
||||||
|
void scale(const float* in, float scale, float* out);
|
||||||
|
void ma(const float* v1, float scale, const float* v2, float* out);
|
||||||
|
void subtract(const float* veca, const float* vecb, float* out);
|
||||||
|
float length(float* v);
|
||||||
|
float product(const float* v1, const float* v2);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user