mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-16 08:38:10 +03:00
Better hitbox tracking
Exposed SV_SetupMove/SV_RestoreMove to the API
This commit is contained in:
parent
39179e694b
commit
91112615cb
@ -1350,6 +1350,247 @@ void SV_SetupMove(client_t *_host_client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* <c0030> ../engine/sv_user.c:1426 */
|
||||||
|
bool EXT_FUNC SV_SetupMoveEx_api(IGameClient* client, float* rewindTime)
|
||||||
|
{
|
||||||
|
struct client_s *cl;
|
||||||
|
float cl_interptime;
|
||||||
|
client_frame_t *nextFrame;
|
||||||
|
entity_state_t *state;
|
||||||
|
sv_adjusted_positions_t *pos;
|
||||||
|
float frac;
|
||||||
|
entity_state_t *pnextstate;
|
||||||
|
int i;
|
||||||
|
client_frame_t *frame;
|
||||||
|
vec3_t origin;
|
||||||
|
vec3_t delta;
|
||||||
|
|
||||||
|
client_t* _host_client = client->GetClient();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef REHLDS_FIXES
|
||||||
|
double targettime; //FP precision fix
|
||||||
|
#else
|
||||||
|
float targettime;
|
||||||
|
#endif // REHLDS_FIXES
|
||||||
|
|
||||||
|
Q_memset(truepositions, 0, sizeof(truepositions));
|
||||||
|
nofind = 1;
|
||||||
|
if (!gEntityInterface.pfnAllowLagCompensation())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (sv_unlag.value == 0.0f || !_host_client->lw || !_host_client->lc)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (g_psvs.maxclients <= 1 || !_host_client->active)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nofind = 0;
|
||||||
|
for (int i = 0; i < g_psvs.maxclients; i++)
|
||||||
|
{
|
||||||
|
cl = &g_psvs.clients[i];
|
||||||
|
if (cl == _host_client || !cl->active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
truepositions[i].oldorg[0] = cl->edict->v.origin[0];
|
||||||
|
truepositions[i].oldorg[1] = cl->edict->v.origin[1];
|
||||||
|
truepositions[i].oldorg[2] = cl->edict->v.origin[2];
|
||||||
|
truepositions[i].oldabsmin[0] = cl->edict->v.absmin[0];
|
||||||
|
truepositions[i].oldabsmin[1] = cl->edict->v.absmin[1];
|
||||||
|
truepositions[i].oldabsmin[2] = cl->edict->v.absmin[2];
|
||||||
|
truepositions[i].oldabsmax[0] = cl->edict->v.absmax[0];
|
||||||
|
truepositions[i].oldabsmax[1] = cl->edict->v.absmax[1];
|
||||||
|
truepositions[i].active = 1;
|
||||||
|
truepositions[i].oldabsmax[2] = cl->edict->v.absmax[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
float clientLatency = _host_client->latency;
|
||||||
|
if (clientLatency > 1.5)
|
||||||
|
clientLatency = 1.5f;
|
||||||
|
|
||||||
|
if (sv_maxunlag.value != 0.0f)
|
||||||
|
{
|
||||||
|
if (sv_maxunlag.value < 0.0)
|
||||||
|
Cvar_SetValue("sv_maxunlag", 0.0);
|
||||||
|
|
||||||
|
if (clientLatency >= sv_maxunlag.value)
|
||||||
|
clientLatency = sv_maxunlag.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_interptime = _host_client->lastcmd.lerp_msec / 1000.0f;
|
||||||
|
|
||||||
|
if (cl_interptime > 0.1)
|
||||||
|
cl_interptime = 0.1f;
|
||||||
|
|
||||||
|
if (_host_client->next_messageinterval > cl_interptime)
|
||||||
|
cl_interptime = (float)_host_client->next_messageinterval;
|
||||||
|
|
||||||
|
#ifdef REHLDS_FIXES
|
||||||
|
// FP Precision fix (targettime is double there, not float)
|
||||||
|
if (rewindTime) {
|
||||||
|
targettime = realtime - *rewindTime;
|
||||||
|
} else {
|
||||||
|
targettime = realtime - clientLatency - cl_interptime + sv_unlagpush.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (rewindTime) {
|
||||||
|
targettime = float(realtime - clientLatency - cl_interptime + sv_unlagpush.value);
|
||||||
|
} else {
|
||||||
|
targettime = float(realtime - *rewindTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // REHLDS_FIXES
|
||||||
|
|
||||||
|
if (targettime > realtime)
|
||||||
|
targettime = realtime;
|
||||||
|
|
||||||
|
if (SV_UPDATE_BACKUP <= 0)
|
||||||
|
{
|
||||||
|
Q_memset(truepositions, 0, sizeof(truepositions));
|
||||||
|
nofind = 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame = nextFrame = NULL;
|
||||||
|
for (i = 0; i < SV_UPDATE_BACKUP; i++, frame = nextFrame)
|
||||||
|
{
|
||||||
|
nextFrame = &_host_client->frames[SV_UPDATE_MASK & (_host_client->netchan.outgoing_sequence + ~i)];
|
||||||
|
for (int j = 0; j < nextFrame->entities.num_entities; j++)
|
||||||
|
{
|
||||||
|
state = &nextFrame->entities.entities[j];
|
||||||
|
|
||||||
|
#ifdef REHLDS_OPT_PEDANTIC
|
||||||
|
if (state->number <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (state->number > g_psvs.maxclients)
|
||||||
|
break; // players are always in the beginning of the list, no need to look more
|
||||||
|
#else
|
||||||
|
if (state->number <= 0 || state->number > g_psvs.maxclients)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pos = &truepositions[state->number - 1];
|
||||||
|
if (pos->deadflag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
if (state->health <= 0)
|
||||||
|
pos->deadflag = 1;
|
||||||
|
|
||||||
|
if (state->effects & EF_NOINTERP)
|
||||||
|
pos->deadflag = 1;
|
||||||
|
|
||||||
|
if (pos->temp_org_setflag)
|
||||||
|
{
|
||||||
|
if (SV_UnlagCheckTeleport(state->origin, pos->temp_org))
|
||||||
|
pos->deadflag = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos->temp_org_setflag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos->temp_org[0] = state->origin[0];
|
||||||
|
pos->temp_org[1] = state->origin[1];
|
||||||
|
pos->temp_org[2] = state->origin[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targettime > nextFrame->senttime)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= SV_UPDATE_BACKUP || targettime - nextFrame->senttime > 1.0)
|
||||||
|
{
|
||||||
|
Q_memset(truepositions, 0, 0xB00u);
|
||||||
|
nofind = 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame)
|
||||||
|
{
|
||||||
|
float timeDiff = float(frame->senttime - nextFrame->senttime);
|
||||||
|
if (timeDiff == 0.0)
|
||||||
|
frac = 0.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frac = float((targettime - nextFrame->senttime) / timeDiff);
|
||||||
|
if (frac <= 1.0)
|
||||||
|
{
|
||||||
|
if (frac < 0.0)
|
||||||
|
frac = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
frac = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frame = nextFrame;
|
||||||
|
frac = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nextFrame->entities.num_entities; i++)
|
||||||
|
{
|
||||||
|
state = &nextFrame->entities.entities[i];
|
||||||
|
if (state->number <= 0 || state->number > g_psvs.maxclients)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cl = &g_psvs.clients[state->number - 1];
|
||||||
|
if (cl == _host_client || !cl->active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pos = &truepositions[state->number - 1];
|
||||||
|
if (pos->deadflag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!pos->active)
|
||||||
|
{
|
||||||
|
Con_DPrintf("tried to store off position of bogus player %i/%s\n", i, cl->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pnextstate = SV_FindEntInPack(state->number, &frame->entities);
|
||||||
|
|
||||||
|
if (pnextstate)
|
||||||
|
{
|
||||||
|
delta[0] = pnextstate->origin[0] - state->origin[0];
|
||||||
|
delta[1] = pnextstate->origin[1] - state->origin[1];
|
||||||
|
delta[2] = pnextstate->origin[2] - state->origin[2];
|
||||||
|
VectorMA(state->origin, frac, delta, origin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
origin[0] = state->origin[0];
|
||||||
|
origin[1] = state->origin[1];
|
||||||
|
origin[2] = state->origin[2];
|
||||||
|
}
|
||||||
|
pos->neworg[0] = origin[0];
|
||||||
|
pos->neworg[1] = origin[1];
|
||||||
|
pos->neworg[2] = origin[2];
|
||||||
|
pos->initial_correction_org[0] = origin[0];
|
||||||
|
pos->initial_correction_org[1] = origin[1];
|
||||||
|
pos->initial_correction_org[2] = origin[2];
|
||||||
|
if (!VectorCompare(origin, cl->edict->v.origin))
|
||||||
|
{
|
||||||
|
cl->edict->v.origin[0] = origin[0];
|
||||||
|
cl->edict->v.origin[1] = origin[1];
|
||||||
|
cl->edict->v.origin[2] = origin[2];
|
||||||
|
SV_LinkEdict(cl->edict, 0);
|
||||||
|
pos->needrelink = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EXT_FUNC SV_RestoreMove_api(IGameClient* client) {
|
||||||
|
SV_RestoreMove(client->GetClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* <c01e6> ../engine/sv_user.c:1670 */
|
/* <c01e6> ../engine/sv_user.c:1670 */
|
||||||
void SV_RestoreMove(client_t *_host_client)
|
void SV_RestoreMove(client_t *_host_client)
|
||||||
{
|
{
|
||||||
|
@ -138,7 +138,9 @@ void SV_GetTrueOrigin(int player, vec_t *origin);
|
|||||||
void SV_GetTrueMinMax(int player, float **fmin, float **fmax);
|
void SV_GetTrueMinMax(int player, float **fmin, float **fmax);
|
||||||
entity_state_t *SV_FindEntInPack(int index, packet_entities_t *pack);
|
entity_state_t *SV_FindEntInPack(int index, packet_entities_t *pack);
|
||||||
void SV_SetupMove(client_t *_host_client);
|
void SV_SetupMove(client_t *_host_client);
|
||||||
|
bool SV_SetupMoveEx_api(IGameClient* client, float* rewindTime);
|
||||||
void SV_RestoreMove(client_t *_host_client);
|
void SV_RestoreMove(client_t *_host_client);
|
||||||
|
void SV_RestoreMove_api(IGameClient* client);
|
||||||
void SV_ParseStringCommand(client_t *pSenderClient);
|
void SV_ParseStringCommand(client_t *pSenderClient);
|
||||||
void SV_ParseDelta(client_t *pSenderClient);
|
void SV_ParseDelta(client_t *pSenderClient);
|
||||||
void SV_EstablishTimeBase(client_t *cl, usercmd_t *cmds, int dropped, int numbackup, int numcmds);
|
void SV_EstablishTimeBase(client_t *cl, usercmd_t *cmds, int dropped, int numbackup, int numcmds);
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
#define REHLDS_API_VERSION_MAJOR 1
|
#define REHLDS_API_VERSION_MAJOR 1
|
||||||
#define REHLDS_API_VERSION_MINOR 3
|
#define REHLDS_API_VERSION_MINOR 4
|
||||||
|
|
||||||
//Steam_NotifyClientConnect hook
|
//Steam_NotifyClientConnect hook
|
||||||
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
|
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
|
||||||
@ -200,6 +200,9 @@ struct RehldsFuncs_t {
|
|||||||
void(*MSG_EndBitWriting)(sizebuf_t *buf);
|
void(*MSG_EndBitWriting)(sizebuf_t *buf);
|
||||||
void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
|
void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
|
||||||
bool(*GetHitboxCorners)(int hitboxId, float* /* [8*3] */ corners, int* pGroupId);
|
bool(*GetHitboxCorners)(int hitboxId, float* /* [8*3] */ corners, int* pGroupId);
|
||||||
|
void(*SetupHitboxTracing)();
|
||||||
|
bool(*SV_SetupMoveEx)(IGameClient* client, float* rewindTime);
|
||||||
|
void(*SV_RestoreMove)(IGameClient* client);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IRehldsApi {
|
class IRehldsApi {
|
||||||
|
@ -33,6 +33,7 @@ class IGameClient;
|
|||||||
#include "archtypes.h"
|
#include "archtypes.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "netadr.h"
|
#include "netadr.h"
|
||||||
|
#include "usercmd.h"
|
||||||
|
|
||||||
#include "common_rehlds.h"
|
#include "common_rehlds.h"
|
||||||
#include "userid_rehlds.h"
|
#include "userid_rehlds.h"
|
||||||
@ -67,6 +68,9 @@ public:
|
|||||||
virtual bool IsConnected() = 0;
|
virtual bool IsConnected() = 0;
|
||||||
virtual void SetConnected(bool connected) = 0;
|
virtual void SetConnected(bool connected) = 0;
|
||||||
|
|
||||||
|
virtual usercmd_t* GetLastCommand() = 0;
|
||||||
|
virtual float GetLatency() = 0;
|
||||||
|
|
||||||
|
|
||||||
// this must be the last virtual function in class
|
// this must be the last virtual function in class
|
||||||
#ifdef REHLDS_SELF
|
#ifdef REHLDS_SELF
|
||||||
|
@ -119,6 +119,10 @@ bool EXT_FUNC GetHitboxCorners(int hitboxId, float* /* [8*3] */ corners, int* pG
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EXT_FUNC SetupHitboxTracing() {
|
||||||
|
g_studio_numhulls = 0;
|
||||||
|
}
|
||||||
|
|
||||||
CRehldsServerStatic g_RehldsServerStatic;
|
CRehldsServerStatic g_RehldsServerStatic;
|
||||||
CRehldsServerData g_RehldsServerData;
|
CRehldsServerData g_RehldsServerData;
|
||||||
CRehldsHookchains g_RehldsHookchains;
|
CRehldsHookchains g_RehldsHookchains;
|
||||||
@ -154,7 +158,10 @@ RehldsFuncs_t g_RehldsApiFuncs =
|
|||||||
&MSG_WriteBitVec3Coord,
|
&MSG_WriteBitVec3Coord,
|
||||||
&MSG_EndBitWriting,
|
&MSG_EndBitWriting,
|
||||||
&SZ_GetSpace,
|
&SZ_GetSpace,
|
||||||
&GetHitboxCorners
|
&GetHitboxCorners,
|
||||||
|
&SetupHitboxTracing,
|
||||||
|
&SV_SetupMoveEx_api,
|
||||||
|
&SV_RestoreMove_api
|
||||||
};
|
};
|
||||||
|
|
||||||
sizebuf_t* EXT_FUNC GetNetMessage_api()
|
sizebuf_t* EXT_FUNC GetNetMessage_api()
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "rehlds_interfaces_impl.h"
|
#include "rehlds_interfaces_impl.h"
|
||||||
|
|
||||||
extern bool GetHitboxCorners(int hitboxId, float* /* [8*3] */ corners, int* pGroupId);
|
extern bool GetHitboxCorners(int hitboxId, float* /* [8*3] */ corners, int* pGroupId);
|
||||||
|
extern void SetupHitboxTracing();
|
||||||
|
|
||||||
//Steam_NotifyClientConnect
|
//Steam_NotifyClientConnect
|
||||||
typedef IHookChainImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHook_Steam_NotifyClientConnect;
|
typedef IHookChainImpl<qboolean, IGameClient*, const void*, unsigned int> CRehldsHook_Steam_NotifyClientConnect;
|
||||||
|
@ -70,6 +70,14 @@ void EXT_FUNC CGameClient::SetConnected(bool connected) {
|
|||||||
m_pClient->connected = connected ? 1 : 0;
|
m_pClient->connected = connected ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usercmd_t* EXT_FUNC CGameClient::GetLastCommand() {
|
||||||
|
return &m_pClient->lastcmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
float EXT_FUNC CGameClient::GetLatency() {
|
||||||
|
return m_pClient->latency;
|
||||||
|
}
|
||||||
|
|
||||||
INetChan* EXT_FUNC CGameClient::GetNetChan()
|
INetChan* EXT_FUNC CGameClient::GetNetChan()
|
||||||
{
|
{
|
||||||
return &m_NetChan;
|
return &m_NetChan;
|
||||||
|
@ -77,6 +77,9 @@ public:
|
|||||||
virtual bool IsConnected();
|
virtual bool IsConnected();
|
||||||
virtual void SetConnected(bool connected);
|
virtual void SetConnected(bool connected);
|
||||||
|
|
||||||
|
virtual usercmd_t* GetLastCommand();
|
||||||
|
virtual float GetLatency();
|
||||||
|
|
||||||
|
|
||||||
virtual client_t* GetClient();
|
virtual client_t* GetClient();
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user