2
0
mirror of https://github.com/rehlds/rehlds.git synced 2024-12-28 15:45:46 +03:00

Refactoring world.cpp, sv_phys.cpp, sv_move.cpp

This commit is contained in:
s1lent 2017-12-09 12:21:09 +07:00
parent 70efca6185
commit 4fad5255ba
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
19 changed files with 1970 additions and 1776 deletions

11
.gitignore vendored
View File

@ -2,22 +2,23 @@
**/.gradle **/.gradle
.idea .idea
*.iml *.iml
*.bat
*.log
*.lnk
**/msvc/Debug* **/msvc/Debug*
**/msvc/Release* **/msvc/Release*
**/msvc/Tests **/msvc/Tests
**/msvc/Test Fixes **/msvc/Test Fixes
**/msvc/.vs
**/msvc/*.db
**/msvc/*.opendb
**/msvc/*.sdf **/msvc/*.sdf
**/msvc/*.opensdf **/msvc/*.opensdf
**/msvc/*.user **/msvc/*.user
**/msvc/*.suo **/msvc/*.suo
**/msvc/*.db **/msvc/*.db
**/msvc/*.opendb **/msvc/*.opendb
**/msvc/PublishPath*.txt **/msvc/*.txt
**/msvc/ipch **/msvc/*.amplxeproj
**/msvc/.vs **/msvc/.vs
**/msvc/ipch
rehlds/version/appversion.h rehlds/version/appversion.h
rehlds/_rehldsTestImg rehlds/_rehldsTestImg

View File

@ -558,11 +558,11 @@ NOBODY void InterpolateAngles(float *start, float *end, float *output, float fra
// NormalizeAngles(float *angles); // 453 // NormalizeAngles(float *angles); // 453
//} //}
void VectorTransform(const vec_t *in1, float *in2, vec_t *out) void VectorTransform(const vec_t *in1, float (*in2)[4], vec_t *out)
{ {
out[0] = _DotProduct(in1, in2 + 0) + in2[3]; out[0] = _DotProduct(in1, in2[0]) + in2[0][3];
out[1] = _DotProduct(in1, in2 + 4) + in2[7]; out[1] = _DotProduct(in1, in2[1]) + in2[1][3];
out[2] = _DotProduct(in1, in2 + 8) + in2[11]; out[2] = _DotProduct(in1, in2[2]) + in2[2][3];
} }
int VectorCompare(const vec_t *v1, const vec_t *v2) int VectorCompare(const vec_t *v1, const vec_t *v2)
@ -595,7 +595,7 @@ void VectorMA(const vec_t *veca, float scale, const vec_t *vecm, vec_t *out)
#endif #endif
#ifndef REHLDS_FIXES #ifndef REHLDS_FIXES
long double _DotProduct(const vec_t *v1, const vec_t *v2) real_t _DotProduct(const vec_t *v1, const vec_t *v2)
{ {
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
} }
@ -689,13 +689,6 @@ NOBODY void VectorInverse(vec_t *v);
//{ //{
//} //}
void VectorScale(const vec_t *in, float scale, vec_t *out)
{
out[0] = scale * in[0];
out[1] = scale * in[1];
out[2] = scale * in[2];
}
NOBODY int Q_log2(int val); NOBODY int Q_log2(int val);
//{ //{
// int answer; // 568 // int answer; // 568

View File

@ -31,6 +31,16 @@
#include "maintypes.h" #include "maintypes.h"
#include "model.h" #include "model.h"
#ifndef REHLDS_FIXES
// NOTE: In some cases we need high precision of floating-point,
// so use double instead of float, otherwise unittest will fail
typedef double real_t;
#else
typedef float real_t;
#endif
typedef real_t real3_t[3];
enum enum
{ {
PITCH = 0, // up / down PITCH = 0, // up / down
@ -45,6 +55,22 @@ enum
#define vec3_origin (*pvec3_origin) #define vec3_origin (*pvec3_origin)
#endif // HOOK_ENGINE #endif // HOOK_ENGINE
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
(((p)->type < 3) ? \
( \
((p)->dist <= (emins)[(p)->type]) ? \
1 \
: \
( \
((p)->dist >= (emaxs)[(p)->type]) ? \
2 \
: \
3 \
) \
) \
: \
BoxOnPlaneSide((emins), (emaxs), (p)))
extern vec3_t vec3_origin; extern vec3_t vec3_origin;
static const int nanmask = 0x7F800000; static const int nanmask = 0x7F800000;
@ -104,6 +130,71 @@ inline T M_clamp(T a, T min, T max) {
return clamp(a, min, max); return clamp(a, min, max);
} }
inline void VectorAdd(const vec_t *veca, const vec_t *vecb, vec_t *out)
{
out[0] = veca[0] + vecb[0];
out[1] = veca[1] + vecb[1];
out[2] = veca[2] + vecb[2];
}
template <typename T = vec_t>
inline void VectorSubtract(const vec_t *veca, const vec_t *vecb, T *out)
{
out[0] = veca[0] - vecb[0];
out[1] = veca[1] - vecb[1];
out[2] = veca[2] - vecb[2];
}
#ifndef REHLDS_FIXES
template <typename T = vec_t>
inline void VectorMA(const vec_t *veca, float scale, const T *vecm, vec_t *out)
{
out[0] = scale * vecm[0] + veca[0];
out[1] = scale * vecm[1] + veca[1];
out[2] = scale * vecm[2] + veca[2];
}
#endif
inline void VectorScale(const vec_t *in, float scale, vec_t *out)
{
out[0] = scale * in[0];
out[1] = scale * in[1];
out[2] = scale * in[2];
}
inline void VectorClear(vec_t *in)
{
in[0] = 0.0f;
in[1] = 0.0f;
in[2] = 0.0f;
}
inline void VectorCopy(const vec_t *in, vec_t *out)
{
out[0] = in[0];
out[1] = in[1];
out[2] = in[2];
}
inline void VectorNegate(const vec_t *in, vec_t *out)
{
out[0] = -in[0];
out[1] = -in[1];
out[2] = -in[2];
}
inline void VectorAverage(const vec_t *veca, const vec_t *vecb, vec_t *out)
{
out[0] = (veca[0] + vecb[0]) * 0.5f;
out[1] = (veca[1] + vecb[1]) * 0.5f;
out[2] = (veca[2] + vecb[2]) * 0.5f;
}
inline bool VectorIsZero(const vec_t *in)
{
return (in[0] == 0.0f && in[1] == 0.0f && in[2] == 0.0f);
}
float anglemod(float a); float anglemod(float a);
void BOPS_Error(void); void BOPS_Error(void);
@ -116,14 +207,10 @@ void AngleMatrix(const vec_t *angles, float(*matrix)[4]);
NOBODY void AngleIMatrix(const vec_t *angles, float *matrix); NOBODY void AngleIMatrix(const vec_t *angles, float *matrix);
NOBODY void NormalizeAngles(float *angles); NOBODY void NormalizeAngles(float *angles);
NOBODY void InterpolateAngles(float *start, float *end, float *output, float frac); NOBODY void InterpolateAngles(float *start, float *end, float *output, float frac);
void VectorTransform(const vec_t *in1, float *in2, vec_t *out); void VectorTransform(const vec_t *in1, float (*in2)[4], vec_t *out);
int VectorCompare(const vec_t *v1, const vec_t *v2); int VectorCompare(const vec_t *v1, const vec_t *v2);
void VectorMA(const vec_t *veca, float scale, const vec_t *vecm, vec_t *out); void VectorMA(const vec_t *veca, float scale, const vec_t *vecm, vec_t *out);
#ifdef REHLDS_FIXES real_t _DotProduct(const vec_t *v1, const vec_t *v2);
float _DotProduct(const vec_t *v1, const vec_t *v2); // with sse support
#else // REHLDS_FIXES
long double _DotProduct(const vec_t *v1, const vec_t *v2); // precise
#endif // REHLDS_FIXES
NOBODY void _VectorSubtract(vec_t *veca, vec_t *vecb, vec_t *out); NOBODY void _VectorSubtract(vec_t *veca, vec_t *vecb, vec_t *out);
void _VectorAdd(vec_t *veca, vec_t *vecb, vec_t *out); void _VectorAdd(vec_t *veca, vec_t *vecb, vec_t *out);
NOBODY void _VectorCopy(vec_t *in, vec_t *out); NOBODY void _VectorCopy(vec_t *in, vec_t *out);

View File

@ -54,6 +54,17 @@ const char S2C_CONNECTION = 'B';
// HLMaster rejected a server's connection because the server needs to be updated // HLMaster rejected a server's connection because the server needs to be updated
const char M2S_REQUESTRESTART = 'O'; const char M2S_REQUESTRESTART = 'O';
// Response details about each player on the server
const char S2A_PLAYERS = 'D';
// Response as multi-packeted the rules the server is using
const char S2A_RULES = 'E';
// info request
const char S2A_INFO = 'C'; // deprecated goldsrc response
const char S2A_INFO_DETAILED = 'm'; // New Query protocol, returns dedicated or not, + other performance info.
// send a log event as key value // send a log event as key value
const char S2A_LOGSTRING = 'R'; const char S2A_LOGSTRING = 'R';
@ -78,6 +89,9 @@ const char A2A_PING = 'i'; // respond with an A2A_ACK
// Generic Ack // Generic Ack
const char A2A_ACK = 'j'; // general acknowledgement without info const char A2A_ACK = 'j'; // general acknowledgement without info
// Print to client console
const char A2A_PRINT = 'l'; // print a message on client
// Challenge response from master // Challenge response from master
const char M2A_CHALLENGE = 's'; // + challenge value const char M2A_CHALLENGE = 's'; // + challenge value

View File

@ -1273,7 +1273,7 @@ qboolean NET_GetPacket(netsrc_t sock)
{ {
Q_memcpy(net_message.data, in_message.data, in_message.cursize); Q_memcpy(net_message.data, in_message.data, in_message.cursize);
net_message.cursize = in_message.cursize; net_message.cursize = in_message.cursize;
Q_memcpy(&net_from, &in_from, 0x14u); Q_memcpy(&net_from, &in_from, sizeof(netadr_t));
NET_ThreadUnlock(); NET_ThreadUnlock();
return bret; return bret;
} }

View File

@ -501,7 +501,7 @@ pmtrace_t _PM_PlayerTrace(vec_t *start, vec_t *end, int traceFlags, int numphyse
closest = 0; closest = 0;
for (int j = 0; j < pNumHulls; j++) for (int j = 0; j < pNumHulls; j++)
{ {
Q_memset(&testtrace, 0, 0x44u); Q_memset(&testtrace, 0, sizeof(testtrace));
testtrace.endpos[0] = end[0]; testtrace.endpos[0] = end[0];
testtrace.endpos[1] = end[1]; testtrace.endpos[1] = end[1];
testtrace.endpos[2] = end[2]; testtrace.endpos[2] = end[2];

View File

@ -339,7 +339,7 @@ void EXT_FUNC PF_traceline_Shared(const float *v1, const float *v2, int nomonste
#ifdef REHLDS_OPT_PEDANTIC #ifdef REHLDS_OPT_PEDANTIC
trace_t trace = SV_Move_Point(v1, v2, nomonsters, ent); trace_t trace = SV_Move_Point(v1, v2, nomonsters, ent);
#else // REHLDS_OPT_PEDANTIC #else // REHLDS_OPT_PEDANTIC
trace_t trace = SV_Move(v1, vec3_origin, vec3_origin, v2, nomonsters, ent, 0); trace_t trace = SV_Move(v1, vec3_origin, vec3_origin, v2, nomonsters, ent, FALSE);
#endif // REHLDS_OPT_PEDANTIC #endif // REHLDS_OPT_PEDANTIC
gGlobalVariables.trace_flags = 0; gGlobalVariables.trace_flags = 0;
@ -370,7 +370,8 @@ void EXT_FUNC TraceHull(const float *v1, const float *v2, int fNoMonsters, int h
hullNumber = hullNumber; hullNumber = hullNumber;
if (hullNumber < 0 || hullNumber > 3) if (hullNumber < 0 || hullNumber > 3)
hullNumber = 0; hullNumber = 0;
trace_t trace = SV_Move(v1, gHullMins[hullNumber], gHullMaxs[hullNumber], v2, fNoMonsters, pentToSkip, 0);
trace_t trace = SV_Move(v1, gHullMins[hullNumber], gHullMaxs[hullNumber], v2, fNoMonsters, pentToSkip, FALSE);
ptr->fAllSolid = trace.allsolid; ptr->fAllSolid = trace.allsolid;
ptr->fStartSolid = trace.startsolid; ptr->fStartSolid = trace.startsolid;
@ -608,7 +609,7 @@ void EXT_FUNC PF_TraceToss_DLL(edict_t *pent, edict_t *pentToIgnore, TraceResult
int EXT_FUNC TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr) int EXT_FUNC TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr)
{ {
qboolean monsterClip = (pEdict->v.flags & FL_MONSTERCLIP) ? 1 : 0; qboolean monsterClip = (pEdict->v.flags & FL_MONSTERCLIP) ? TRUE : FALSE;
trace_t trace = SV_Move(v1, pEdict->v.mins, pEdict->v.maxs, v2, fNoMonsters, pentToSkip, monsterClip); trace_t trace = SV_Move(v1, pEdict->v.mins, pEdict->v.maxs, v2, fNoMonsters, pentToSkip, monsterClip);
if (ptr) if (ptr)
{ {
@ -1676,12 +1677,12 @@ int EXT_FUNC PF_droptofloor_I(edict_t *ent)
{ {
vec3_t end; vec3_t end;
trace_t trace; trace_t trace;
qboolean monsterClip = (ent->v.flags & FL_MONSTERCLIP) ? 1 : 0; qboolean monsterClip = (ent->v.flags & FL_MONSTERCLIP) ? TRUE : FALSE;
end[0] = ent->v.origin[0]; end[0] = ent->v.origin[0];
end[1] = ent->v.origin[1]; end[1] = ent->v.origin[1];
end[2] = ent->v.origin[2] - 256.0; end[2] = ent->v.origin[2] - 256.0;
trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, end, 0, ent, monsterClip); trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent, monsterClip);
if (trace.allsolid) if (trace.allsolid)
return -1; return -1;
@ -1772,7 +1773,7 @@ void EXT_FUNC PF_aim_I(edict_t *ent, float speed, float *rgflReturn)
start[1] += ent->v.view_ofs[1]; start[1] += ent->v.view_ofs[1];
start[2] += ent->v.view_ofs[2]; start[2] += ent->v.view_ofs[2];
VectorMA(start, 2048.0, dir, end); VectorMA(start, 2048.0, dir, end);
tr = SV_Move(start, vec3_origin, vec3_origin, end, 0, ent, 0); tr = SV_Move(start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, FALSE);
if (tr.ent && tr.ent->v.takedamage == 2.0f && (ent->v.team <= 0 || ent->v.team != tr.ent->v.team)) if (tr.ent && tr.ent->v.takedamage == 2.0f && (ent->v.team <= 0 || ent->v.team != tr.ent->v.team))
{ {
@ -1811,7 +1812,7 @@ void EXT_FUNC PF_aim_I(edict_t *ent, float speed, float *rgflReturn)
if (dist >= bestdist) if (dist >= bestdist)
{ {
tr = SV_Move(start, vec3_origin, vec3_origin, end, 0, ent, 0); tr = SV_Move(start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, FALSE);
if (tr.ent == check) if (tr.ent == check)
{ {
bestdist = dist; bestdist = dist;

View File

@ -950,7 +950,7 @@ void EXT_FUNC GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflO
); );
if (rgflOrigin) if (rgflOrigin)
VectorTransform(pattachment->org, (float *)bonetransform[pattachment->bone], rgflOrigin); VectorTransform(pattachment->org, bonetransform[pattachment->bone], rgflOrigin);
} }
int ModelFrameCount(model_t *model) int ModelFrameCount(model_t *model)

View File

@ -2832,7 +2832,7 @@ NOXREF void ReplyServerChallenge(netadr_t *adr)
buf.flags = SIZEBUF_ALLOW_OVERFLOW; buf.flags = SIZEBUF_ALLOW_OVERFLOW;
MSG_WriteLong(&buf, 0xffffffff); MSG_WriteLong(&buf, 0xffffffff);
MSG_WriteByte(&buf, 65); MSG_WriteByte(&buf, S2C_CHALLENGE);
MSG_WriteLong(&buf, GetChallengeNr(adr)); MSG_WriteLong(&buf, GetChallengeNr(adr));
NET_SendPacket(NS_SERVER, buf.cursize, (char *)buf.data, *adr); NET_SendPacket(NS_SERVER, buf.cursize, (char *)buf.data, *adr);
} }
@ -3000,7 +3000,7 @@ NOXREF void SVC_Info(qboolean bDetailed)
} }
MSG_WriteLong(&buf, 0xffffffff); MSG_WriteLong(&buf, 0xffffffff);
MSG_WriteByte(&buf, bDetailed ? 109 : 67); MSG_WriteByte(&buf, bDetailed ? S2A_INFO_DETAILED : S2A_INFO);
if (noip) if (noip)
{ {
@ -3102,7 +3102,7 @@ NOXREF void SVC_PlayerInfo(void)
buf.flags = SIZEBUF_ALLOW_OVERFLOW; buf.flags = SIZEBUF_ALLOW_OVERFLOW;
MSG_WriteLong(&buf, 0xffffffff); MSG_WriteLong(&buf, 0xffffffff);
MSG_WriteByte(&buf, 68); MSG_WriteByte(&buf, S2A_PLAYERS);
for (i = 0; i < g_psvs.maxclients; i++) for (i = 0; i < g_psvs.maxclients; i++)
{ {
@ -3154,7 +3154,7 @@ NOXREF void SVC_RuleInfo(void)
return; return;
MSG_WriteLong(&buf, 0xffffffff); MSG_WriteLong(&buf, 0xffffffff);
MSG_WriteByte(&buf, 69); MSG_WriteByte(&buf, S2A_RULES);
MSG_WriteShort(&buf, nNumRules); MSG_WriteShort(&buf, nNumRules);
var = cvar_vars; var = cvar_vars;
@ -3216,7 +3216,7 @@ void SV_FlushRedirect(void)
buf.flags = SIZEBUF_ALLOW_OVERFLOW; buf.flags = SIZEBUF_ALLOW_OVERFLOW;
MSG_WriteLong(&buf, -1); MSG_WriteLong(&buf, -1);
MSG_WriteByte(&buf, 0x6Cu); MSG_WriteByte(&buf, A2A_PRINT);
MSG_WriteString(&buf, outputbuf); MSG_WriteString(&buf, outputbuf);
MSG_WriteByte(&buf, 0); MSG_WriteByte(&buf, 0);
NET_SendPacket(NS_SERVER, buf.cursize, buf.data, sv_redirectto); NET_SendPacket(NS_SERVER, buf.cursize, buf.data, sv_redirectto);

View File

@ -28,21 +28,7 @@
#include "precompiled.h" #include "precompiled.h"
/* // Returns false if any part of the bottom of the entity is off an edge that is not a staircase.
* Local initialization
*/
#ifndef HOOK_ENGINE
static int c_yes = 0;
static int c_no = 0;
#else // HOOK_ENGINE
int c_yes;
int c_no;
#endif // HOOK_ENGINE
qboolean SV_CheckBottom(edict_t *ent) qboolean SV_CheckBottom(edict_t *ent)
{ {
vec3_t mins; vec3_t mins;
@ -54,12 +40,17 @@ qboolean SV_CheckBottom(edict_t *ent)
int y; int y;
float mid; float mid;
float bottom; float bottom;
qboolean monsterClip = (ent->v.flags & FL_MONSTERCLIP) ? 1 : 0;
_VectorAdd(ent->v.origin, ent->v.mins, mins); qboolean monsterClip = (ent->v.flags & FL_MONSTERCLIP) ? TRUE : FALSE;
_VectorAdd(ent->v.origin, ent->v.maxs, maxs);
VectorAdd(ent->v.origin, ent->v.mins, mins);
VectorAdd(ent->v.origin, ent->v.maxs, maxs);
// if all of the points under the corners are solid world, don't bother
// with the tougher checks
// the corners must be within 16 of the midpoint
start[2] = mins[2] - 1.0f;
start[2] = mins[2] - 1;
for (x = 0; x <= 1; x++) for (x = 0; x <= 1; x++)
{ {
for (y = 0; y <= 1; y++) for (y = 0; y <= 1; y++)
@ -73,23 +64,28 @@ qboolean SV_CheckBottom(edict_t *ent)
goto realcheck; goto realcheck;
} }
} }
++c_yes;
return 1; // we got out easy
return TRUE;
realcheck: realcheck:
++c_no;
// check it for real...
start[2] = mins[2]; start[2] = mins[2];
// the midpoint must be within 16 of the bottom
start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5f; start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5f;
start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5f; start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5f;
stop[2] = start[2] - 2 * sv_stepsize.value;
trace = SV_Move(start, vec3_origin, vec3_origin, stop, 1, ent, monsterClip); stop[2] = start[2] - 2.0f * sv_stepsize.value;
trace = SV_Move(start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent, monsterClip);
if (trace.fraction == 1.0f) if (trace.fraction == 1.0f)
return 0; return FALSE;
mid = bottom = trace.endpos[2]; mid = bottom = trace.endpos[2];
// the corners must be within 16 of the midpoint
for (x = 0; x <= 1; x++) for (x = 0; x <= 1; x++)
{ {
for (y = 0; y <= 1; y++) for (y = 0; y <= 1; y++)
@ -97,18 +93,23 @@ realcheck:
start[0] = stop[0] = x ? maxs[0] : mins[0]; start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1]; start[1] = stop[1] = y ? maxs[1] : mins[1];
trace = SV_Move(start, vec3_origin, vec3_origin, stop, 1, ent, monsterClip); trace = SV_Move(start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent, monsterClip);
if (trace.fraction != 1.0f && trace.endpos[2] > bottom) if (trace.fraction != 1.0f && trace.endpos[2] > bottom)
bottom = trace.endpos[2]; bottom = trace.endpos[2];
if (trace.fraction == 1.0f || mid - trace.endpos[2] > sv_stepsize.value) if (trace.fraction == 1.0f || mid - trace.endpos[2] > sv_stepsize.value)
return 0; return FALSE;
} }
} }
return 1; return TRUE;
} }
// Called by monster program code.
// The move will be adjusted for slopes and stairs, but if the move isn't
// possible, no move is done, false is returned, and
// pr_global_struct->trace_normal is set to the normal of the blocking wall
qboolean SV_movetest(edict_t *ent, vec_t *move, qboolean relink) qboolean SV_movetest(edict_t *ent, vec_t *move, qboolean relink)
{ {
vec3_t oldorg; vec3_t oldorg;
@ -116,223 +117,255 @@ qboolean SV_movetest(edict_t *ent, vec_t *move, qboolean relink)
vec3_t end; vec3_t end;
trace_t trace; trace_t trace;
oldorg[0] = ent->v.origin[0]; // try the move
oldorg[1] = ent->v.origin[1]; VectorCopy(ent->v.origin, oldorg);
oldorg[2] = ent->v.origin[2]; VectorAdd(ent->v.origin, move, neworg);
neworg[0] = ent->v.origin[0] + move[0];
neworg[1] = ent->v.origin[1] + move[1];
neworg[2] = ent->v.origin[2] + move[2];
end[0] = neworg[0];
end[1] = neworg[1];
// push down from a step height above the wished position
neworg[2] += sv_stepsize.value; neworg[2] += sv_stepsize.value;
end[2] = neworg[2] - (2 * sv_stepsize.value); VectorCopy(neworg, end);
trace = SV_MoveNoEnts(neworg, ent->v.mins, ent->v.maxs, end, 0, ent); end[2] -= sv_stepsize.value * 2.0f;
trace = SV_MoveNoEnts(neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
if (trace.allsolid) if (trace.allsolid)
return 0; return FALSE;
if (trace.startsolid) if (trace.startsolid)
{ {
neworg[2] -= sv_stepsize.value; neworg[2] -= sv_stepsize.value;
trace = SV_MoveNoEnts(neworg, ent->v.mins, ent->v.maxs, end, 0, ent); trace = SV_MoveNoEnts(neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
if (trace.allsolid || trace.startsolid) if (trace.allsolid || trace.startsolid)
return 0; return FALSE;
} }
if (trace.fraction == 1.0f) if (trace.fraction == 1.0f)
{ {
// if monster had the ground pulled out, go ahead and fall
if (ent->v.flags & FL_PARTIALGROUND) if (ent->v.flags & FL_PARTIALGROUND)
{ {
ent->v.origin[0] = *move + ent->v.origin[0]; VectorAdd(ent->v.origin, move, ent->v.origin);
ent->v.origin[1] = ent->v.origin[1] + move[1];
ent->v.origin[2] = ent->v.origin[2] + move[2];
if (relink)
SV_LinkEdict(ent, TRUE);
if (relink)
{
SV_LinkEdict(ent, TRUE);
}
// fall down
ent->v.flags &= ~FL_ONGROUND; ent->v.flags &= ~FL_ONGROUND;
return 1; return TRUE;
} }
return 0;
// walked off an edge
return FALSE;
} }
ent->v.origin[0] = trace.endpos[0]; // check point traces down for dangling corners
ent->v.origin[1] = trace.endpos[1]; VectorCopy(trace.endpos, ent->v.origin);
ent->v.origin[2] = trace.endpos[2];
if (SV_CheckBottom(ent) == 0) if (!SV_CheckBottom(ent))
{ {
if (!(ent->v.flags & FL_PARTIALGROUND)) if (!(ent->v.flags & FL_PARTIALGROUND))
{ {
ent->v.origin[0] = oldorg[0]; VectorCopy(oldorg, ent->v.origin);
ent->v.origin[1] = oldorg[1]; return FALSE;
ent->v.origin[2] = oldorg[2];
return 0;
} }
// entity had floor mostly pulled out from underneath it
// and is trying to correct
} }
else else
{ {
if (ent->v.flags & FL_PARTIALGROUND) if (ent->v.flags & FL_PARTIALGROUND)
{ {
// back on ground
ent->v.flags &= ~FL_PARTIALGROUND; ent->v.flags &= ~FL_PARTIALGROUND;
} }
ent->v.groundentity = trace.ent; ent->v.groundentity = trace.ent;
} }
// the move is ok
if (relink) if (relink)
{
SV_LinkEdict(ent, TRUE); SV_LinkEdict(ent, TRUE);
}
return 1; return TRUE;
} }
// Called by monster program code.
// The move will be adjusted for slopes and stairs, but if the move isn't
// possible, no move is done, false is returned, and
// pr_global_struct->trace_normal is set to the normal of the blocking wall
qboolean SV_movestep(edict_t *ent, vec_t *move, qboolean relink) qboolean SV_movestep(edict_t *ent, vec_t *move, qboolean relink)
{ {
trace_t trace; trace_t trace;
vec3_t end; vec3_t neworg, oldorg, end;
vec3_t oldorg;
float dz;
qboolean monsterClipBrush;
vec3_t start;
oldorg[0] = ent->v.origin[0]; // try the move
oldorg[1] = ent->v.origin[1]; VectorCopy(ent->v.origin, oldorg);
oldorg[2] = ent->v.origin[2]; VectorAdd(ent->v.origin, move, neworg);
start[0] = ent->v.origin[0] + move[0]; qboolean monsterClipBrush = (ent->v.flags & FL_MONSTERCLIP) ? TRUE : FALSE;
start[1] = ent->v.origin[1] + move[1];
start[2] = ent->v.origin[2] + move[2]; // flying monsters don't step up
monsterClipBrush = (ent->v.flags & FL_MONSTERCLIP) != 0;
if (ent->v.flags & (FL_FLY | FL_SWIM)) if (ent->v.flags & (FL_FLY | FL_SWIM))
{ {
int i = 0; // try one move with vertical motion, then one without
while (i < 2) for (int i = 0; i < 2; i++)
{ {
start[0] = ent->v.origin[0] + move[0]; VectorAdd(ent->v.origin, move, neworg);
start[1] = ent->v.origin[1] + move[1];
start[2] = ent->v.origin[2] + move[2];
edict_t* enemy = ent->v.enemy;
edict_t *enemy = ent->v.enemy;
if (i == 0 && enemy) if (i == 0 && enemy)
{ {
dz = ent->v.origin[2] - enemy->v.origin[2]; float dz = ent->v.origin[2] - enemy->v.origin[2];
if (dz > 40.0)
start[2] = start[2] - 8.0; if (dz > 40.0f)
if (dz < 30.0) neworg[2] -= 8.0f;
start[2] = start[2] + 8.0; else if (dz < 30.0f)
neworg[2] += 8.0f;
} }
trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, start, 0, ent, monsterClipBrush);
trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, neworg, MOVE_NORMAL, ent, monsterClipBrush);
if (trace.fraction == 1.0f) if (trace.fraction == 1.0f)
break; {
g_groupmask = ent->v.groupinfo;
if ((ent->v.flags & FL_SWIM) && SV_PointContents(trace.endpos) == CONTENTS_EMPTY)
{
// swim monster left water
return FALSE;
}
VectorCopy(trace.endpos, ent->v.origin);
if (relink)
{
SV_LinkEdict(ent, TRUE);
}
return TRUE;
}
if (!enemy) if (!enemy)
return 0; {
break;
if (i == 1) }
return 0;
i++;
} }
g_groupmask = ent->v.groupinfo; return FALSE;
if ((ent->v.flags & FL_SWIM) && SV_PointContents(trace.endpos) == -1)
return 0;
ent->v.origin[0] = trace.endpos[0];
ent->v.origin[1] = trace.endpos[1];
ent->v.origin[2] = trace.endpos[2];
if (relink)
SV_LinkEdict(ent, TRUE);
return 1;
} }
start[2] += sv_stepsize.value; // push down from a step height above the wished position
end[0] = start[0]; neworg[2] += sv_stepsize.value;
end[1] = start[1]; VectorCopy(neworg, end);
end[2] = start[2] - (2 * sv_stepsize.value); end[2] -= sv_stepsize.value * 2.0f;
trace = SV_Move(start, ent->v.mins, ent->v.maxs, end, 0, ent, (ent->v.flags & FL_MONSTERCLIP) != 0);
trace = SV_Move(neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent, monsterClipBrush);
if (trace.allsolid) if (trace.allsolid)
return 0; return FALSE;
if (trace.startsolid) if (trace.startsolid)
{ {
start[2] = start[2] - sv_stepsize.value; neworg[2] = neworg[2] - sv_stepsize.value;
trace = SV_Move(start, ent->v.mins, ent->v.maxs, end, 0, ent, monsterClipBrush); trace = SV_Move(neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent, monsterClipBrush);
if (trace.allsolid || trace.startsolid) if (trace.allsolid || trace.startsolid)
return 0; return FALSE;
} }
if (trace.fraction != 1.0f) if (trace.fraction == 1.0f)
{ {
ent->v.origin[0] = trace.endpos[0]; // if monster had the ground pulled out, go ahead and fall
ent->v.origin[1] = trace.endpos[1]; if (ent->v.flags & FL_PARTIALGROUND)
ent->v.origin[2] = trace.endpos[2];
if (SV_CheckBottom(ent) == 0)
{ {
if (!(ent->v.flags & FL_PARTIALGROUND)) VectorAdd(ent->v.origin, move, ent->v.origin);
if (relink)
{ {
ent->v.origin[0] = oldorg[0]; SV_LinkEdict(ent, TRUE);
ent->v.origin[1] = oldorg[1];
ent->v.origin[2] = oldorg[2];
return 0;
} }
}
else
{
if (ent->v.flags & FL_PARTIALGROUND)
ent->v.flags &= ~FL_PARTIALGROUND;
ent->v.groundentity = trace.ent; // fall down
ent->v.flags &= ~FL_ONGROUND;
return TRUE;
} }
if (relink) // walked off an edge
SV_LinkEdict(ent, TRUE); return FALSE;
return 1;
} }
if (!(ent->v.flags & FL_PARTIALGROUND)) // check point traces down for dangling corners
return 0; VectorCopy(trace.endpos, ent->v.origin);
ent->v.origin[0] += move[0]; if (!SV_CheckBottom(ent))
ent->v.origin[1] += move[1]; {
ent->v.origin[2] += move[2]; if (!(ent->v.flags & FL_PARTIALGROUND))
{
VectorCopy(oldorg, ent->v.origin);
return FALSE;
}
// entity had floor mostly pulled out from underneath it
// and is trying to correct
}
else
{
if (ent->v.flags & FL_PARTIALGROUND)
{
// back on ground
ent->v.flags &= ~FL_PARTIALGROUND;
}
ent->v.groundentity = trace.ent;
}
// the move is ok
if (relink) if (relink)
{
SV_LinkEdict(ent, TRUE); SV_LinkEdict(ent, TRUE);
}
ent->v.flags &= ~FL_ONGROUND; return TRUE;
return 1;
} }
// Turns to the movement direction, and walks the current distance if facing it.
qboolean SV_StepDirection(edict_t *ent, float yaw, float dist) qboolean SV_StepDirection(edict_t *ent, float yaw, float dist)
{ {
vec3_t move; vec3_t move;
move[0] = cos(yaw * (2 * M_PI) / 360.0) * dist; yaw = yaw * (M_PI * 2.0f) / 360.0f;
move[1] = sin(yaw * (2 * M_PI) / 360.0) * dist;
move[2] = 0; move[0] = cos(yaw) * dist;
if (SV_movestep(ent, move, 0)) move[1] = sin(yaw) * dist;
move[2] = 0.0f;
if (SV_movestep(ent, move, FALSE))
{ {
SV_LinkEdict(ent, TRUE); SV_LinkEdict(ent, TRUE);
return 1; return TRUE;
}
else
{
SV_LinkEdict(ent, TRUE);
return 0;
} }
SV_LinkEdict(ent, TRUE);
return FALSE;
} }
qboolean SV_FlyDirection(edict_t *ent, vec_t *direction) qboolean SV_FlyDirection(edict_t *ent, vec_t *direction)
{ {
if (SV_movestep(ent, direction, 0)) if (SV_movestep(ent, direction, FALSE))
{ {
SV_LinkEdict(ent, TRUE); SV_LinkEdict(ent, TRUE);
return 1; return TRUE;
} }
else else
{ {
SV_LinkEdict(ent, TRUE); SV_LinkEdict(ent, TRUE);
return 0; return FALSE;
} }
} }
@ -341,51 +374,91 @@ void SV_FixCheckBottom(edict_t *ent)
ent->v.flags |= FL_PARTIALGROUND; ent->v.flags |= FL_PARTIALGROUND;
} }
const int DI_NODIR = -1;
NOXREF void SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist) NOXREF void SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist)
{ {
NOXREFCHECK; NOXREFCHECK;
float deltax;
float deltay;
float d[3];
float tdir;
float olddir;
float turnaround;
olddir = anglemod(45.0 * (int)(actor->v.ideal_yaw / 45.0)); SV_NewChaseDir2(actor, enemy->v.origin, dist);
turnaround = anglemod(olddir - 180.0); }
deltax = enemy->v.origin[0] - actor->v.origin[0]; NOXREF qboolean SV_CloseEnough(edict_t *ent, edict_t *goal, float dist)
deltay = enemy->v.origin[1] - actor->v.origin[1]; {
NOXREFCHECK;
if (deltax > 10.0) for (int i = 0; i < 3; i++)
d[1] = 0.0; {
else if (deltax <- 10.0) if (goal->v.absmin[i] > ent->v.absmax[i] + dist)
d[1]= 180.0; return FALSE;
if (goal->v.absmax[i] < ent->v.absmin[i] - dist)
return FALSE;
}
return TRUE;
}
NOXREF qboolean SV_ReachedGoal(edict_t *ent, vec_t *vecGoal, float flDist)
{
NOXREFCHECK;
for (int i = 0; i < 3; i++)
{
if (vecGoal[i] > ent->v.absmax[i] + flDist)
return FALSE;
if (vecGoal[i] < ent->v.absmin[i] - flDist)
return FALSE;
}
return TRUE;
}
void SV_NewChaseDir2(edict_t *actor, vec_t *vecGoal, float dist)
{
vec3_t d;
float deltax, deltay;
float tempdir, olddir, turnaround;
olddir = anglemod(45.0f * (int)(actor->v.ideal_yaw / 45.0f));
turnaround = anglemod(olddir - 180.0f);
deltax = vecGoal[0] - actor->v.origin[0];
deltay = vecGoal[1] - actor->v.origin[1];
if (deltax > 10.0f)
d[1] = 0.0f;
else if (deltax < -10.0f)
d[1] = 180.0f;
else else
d[1]= DI_NODIR; d[1] = DI_NODIR;
if (deltay < -10.0)
d[2] = 270.0;
else if (deltay > 10.0)
d[2] = 90.0;
else
d[2]= DI_NODIR;
if (deltay < -10.0f)
d[2] = 270.0f;
else if (deltay > 10.0f)
d[2] = 90.0f;
else
d[2] = DI_NODIR;
// try direct route
if (d[1] != DI_NODIR && d[2] != DI_NODIR) if (d[1] != DI_NODIR && d[2] != DI_NODIR)
{ {
if (d[1] == 0.0) if (d[1] == 0.0f)
tdir = d[2] == 90.0 ? 45.0 : 315.0; tempdir = d[2] == 90.0f ? 45.0f : 315.0f;
else else
tdir = d[2] == 90.0 ? 135.0 : 215.0; tempdir = d[2] == 90.0f ? 135.0f : 215.0f;
if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) if (tempdir != turnaround && SV_StepDirection(actor, tempdir, dist))
return; return;
} }
if (RandomLong(0, 1) || abs(deltay) > abs(deltax)) // try other directions
if (RandomLong(0, 1) || abs(deltay) > abs(deltax))
{ {
tdir = d[1]; tempdir = d[1];
d[1] = d[2]; d[1] = d[2];
d[2] = tdir; d[2] = tempdir;
} }
if (d[1] != DI_NODIR && d[1] != turnaround && SV_StepDirection(actor, d[1], dist)) if (d[1] != DI_NODIR && d[1] != turnaround && SV_StepDirection(actor, d[1], dist))
@ -394,168 +467,68 @@ NOXREF void SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist)
if (d[2] != DI_NODIR && d[2] != turnaround && SV_StepDirection(actor, d[2], dist)) if (d[2] != DI_NODIR && d[2] != turnaround && SV_StepDirection(actor, d[2], dist))
return; return;
// there is no direct path to the player, so pick another direction
if (olddir != DI_NODIR && SV_StepDirection(actor, olddir, dist)) if (olddir != DI_NODIR && SV_StepDirection(actor, olddir, dist))
return; return;
// randomly determine direction of search
if (RandomLong(0, 1)) if (RandomLong(0, 1))
{ {
for (tdir = 0.0; tdir <= 315.0; tdir += 45.0) for (tempdir = 0.0f; tempdir <= 315.0f; tempdir += 45.0f)
if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) {
return; if (tempdir != turnaround && SV_StepDirection(actor, tempdir, dist))
return;
}
} }
else else
{ {
for (tdir = 315.0 ; tdir >= 0.0; tdir -= 45.0) for (tempdir = 315.0f; tempdir >= 0.0f; tempdir -= 45.0f)
if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) {
return; if (tempdir != turnaround && SV_StepDirection(actor, tempdir, dist))
return;
}
} }
// we tried. run backwards. that ought to work...
if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist)) if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist))
return; return;
// can't move, we're stuck somehow
actor->v.ideal_yaw = olddir; actor->v.ideal_yaw = olddir;
// if a bridge was pulled out from underneath a monster, it may not have
// a valid standing position at all
if (!SV_CheckBottom(actor)) if (!SV_CheckBottom(actor))
{
SV_FixCheckBottom(actor); SV_FixCheckBottom(actor);
}
NOXREF qboolean SV_CloseEnough(edict_t *ent, edict_t *goal, float dist)
{
NOXREFCHECK;
int i;
for (i = 0; i < 3; i++)
{
if (goal->v.absmin[i] > ent->v.absmax[i] + dist)
return FALSE;
if (goal->v.absmax[i] < ent->v.absmin[i] - dist)
return FALSE;
}
return TRUE;
}
NOXREF qboolean SV_ReachedGoal(edict_t *ent, vec_t *vecGoal, float flDist)
{
NOXREFCHECK;
int i;
for (i = 0; i < 3; i++)
{
if (vecGoal[i] > ent->v.absmax[i] + flDist)
return FALSE;
if (vecGoal[i] < ent->v.absmin[i] - flDist)
return FALSE;
}
return TRUE;
}
void SV_NewChaseDir2(edict_t *actor, vec_t *vecGoal, float dist)
{
float deltax;
float deltay;
float d_1, d_2;
float tdir;
float olddir;
float turnaround;
olddir = anglemod(45 * (int)(actor->v.ideal_yaw / 45.0));
turnaround = anglemod(olddir - 180.0);
deltax = vecGoal[0] - actor->v.origin[0];
deltay = vecGoal[1] - actor->v.origin[1];
if (deltax > 10)
d_1 = 0;
else if (deltax < -10)
d_1 = 180;
else
d_1 = DI_NODIR;
if (deltay < -10)
d_2 = 270;
else if (deltay > 10)
d_2 = 90;
else
d_2 = DI_NODIR;
if (d_1 != DI_NODIR && d_2 != DI_NODIR)
{
if (d_1 == 0.0)
tdir = d_2 == 90 ? 45 : 315;
else
tdir = d_2 == 90 ? 135 : 215;
if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))
return;
}
if (RandomLong(0, 1) || abs(deltay) > abs(deltax))
{
tdir = d_1;
d_1 = d_2;
d_2 = tdir;
}
if (d_1 != DI_NODIR && d_1 != turnaround
&& SV_StepDirection(actor, d_1, dist))
return;
if (d_2 != DI_NODIR && d_2 != turnaround
&& SV_StepDirection(actor, d_2, dist))
return;
if (olddir != DI_NODIR && SV_StepDirection(actor, olddir, dist))
return;
if (RandomLong(0, 1))
{
for (tdir = 0; tdir <= 315; tdir += 45)
{
if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))
return;
}
}
else
{
for (tdir = 315; tdir >= 0; tdir -= 45)
{
if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))
return;
}
}
if (turnaround == DI_NODIR || !SV_StepDirection(actor, turnaround, dist))
{
actor->v.ideal_yaw = olddir;
if (!SV_CheckBottom(actor))
SV_FixCheckBottom(actor);
} }
} }
void EXT_FUNC SV_MoveToOrigin_I(edict_t *ent, const float *pflGoal, float dist, int iStrafe) void EXT_FUNC SV_MoveToOrigin_I(edict_t *ent, const float *pflGoal, float dist, int iMoveType)
{ {
vec3_t vecGoal; vec3_t vecGoal;
vec3_t vecDir; VectorCopy(pflGoal, vecGoal);
vecGoal[0] = pflGoal[0]; if (ent->v.flags & (FL_FLY | FL_SWIM | FL_ONGROUND))
vecGoal[1] = pflGoal[1];
vecGoal[2] = pflGoal[2];
if (ent->v.flags & (FL_ONGROUND | FL_SWIM | FL_FLY))
{ {
if (iStrafe) if (iMoveType == MOVE_NORMAL)
{ {
vecDir[0] = vecGoal[0] - ent->v.origin[0]; if (!SV_StepDirection(ent, ent->v.ideal_yaw, dist))
vecDir[1] = vecGoal[1] - ent->v.origin[1]; {
vecDir[2] = vecGoal[2] - ent->v.origin[2]; SV_NewChaseDir2(ent, vecGoal, dist);
}
}
else
{
vec3_t vecDir;
VectorSubtract(vecGoal, ent->v.origin, vecDir);
if (!(ent->v.flags & (FL_SWIM | FL_FLY))) if (!(ent->v.flags & (FL_SWIM | FL_FLY)))
vecDir[2] = 0; vecDir[2] = 0.0f;
VectorNormalize(vecDir); VectorNormalize(vecDir);
VectorScale(vecDir, dist, vecDir); VectorScale(vecDir, dist, vecDir);
SV_FlyDirection(ent, vecDir); SV_FlyDirection(ent, vecDir);
} }
else
{
if (!SV_StepDirection(ent, ent->v.ideal_yaw, dist))
SV_NewChaseDir2(ent, vecGoal, dist);
}
} }
} }

View File

@ -31,18 +31,6 @@
#include "maintypes.h" #include "maintypes.h"
#include "server.h" #include "server.h"
const int DI_NODIR = -1;
#ifdef HOOK_ENGINE
#define c_yes (*pc_yes)
#define c_no (*pc_no)
extern int c_yes;
extern int c_no;
#endif // HOOK_ENGINE
qboolean SV_CheckBottom(edict_t *ent); qboolean SV_CheckBottom(edict_t *ent);
qboolean SV_movetest(edict_t *ent, vec_t *move, qboolean relink); qboolean SV_movetest(edict_t *ent, vec_t *move, qboolean relink);
qboolean SV_movestep(edict_t *ent, vec_t *move, qboolean relink); qboolean SV_movestep(edict_t *ent, vec_t *move, qboolean relink);
@ -53,4 +41,4 @@ NOXREF void SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist);
NOXREF qboolean SV_CloseEnough(edict_t *ent, edict_t *goal, float dist); NOXREF qboolean SV_CloseEnough(edict_t *ent, edict_t *goal, float dist);
NOXREF qboolean SV_ReachedGoal(edict_t *ent, vec_t *vecGoal, float flDist); NOXREF qboolean SV_ReachedGoal(edict_t *ent, vec_t *vecGoal, float flDist);
void SV_NewChaseDir2(edict_t *actor, vec_t *vecGoal, float dist); void SV_NewChaseDir2(edict_t *actor, vec_t *vecGoal, float dist);
void SV_MoveToOrigin_I(edict_t *ent, const float *pflGoal, float dist, int iStrafe); void SV_MoveToOrigin_I(edict_t *ent, const float *pflGoal, float dist, int iMoveType);

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,6 @@
#include "model.h" #include "model.h"
#include "cvar.h" #include "cvar.h"
#ifdef HOOK_ENGINE #ifdef HOOK_ENGINE
#define sv_maxvelocity (*psv_maxvelocity) #define sv_maxvelocity (*psv_maxvelocity)
#define sv_gravity (*psv_gravity) #define sv_gravity (*psv_gravity)
@ -54,8 +53,7 @@ extern cvar_t sv_stopspeed;
extern vec3_t *g_moved_from; extern vec3_t *g_moved_from;
extern edict_t **g_moved_edict; extern edict_t **g_moved_edict;
NOXREF void SV_CheckAllEnts();
NOXREF void SV_CheckAllEnts(void);
void SV_CheckVelocity(edict_t *ent); void SV_CheckVelocity(edict_t *ent);
qboolean SV_RunThink(edict_t *ent); qboolean SV_RunThink(edict_t *ent);
void SV_Impact(edict_t *e1, edict_t *e2, trace_t *ptrace); void SV_Impact(edict_t *e1, edict_t *e2, trace_t *ptrace);
@ -69,7 +67,7 @@ void SV_PushMove(edict_t *pusher, float movetime);
int SV_PushRotate(edict_t *pusher, float movetime); int SV_PushRotate(edict_t *pusher, float movetime);
void SV_Physics_Pusher(edict_t *ent); void SV_Physics_Pusher(edict_t *ent);
qboolean SV_CheckWater(edict_t *ent); qboolean SV_CheckWater(edict_t *ent);
float SV_RecursiveWaterLevel(vec_t *center, float out, float in, int count); float SV_RecursiveWaterLevel(const vec_t *origin, float mins, float maxs, int depth);
float SV_Submerged(edict_t *ent); float SV_Submerged(edict_t *ent);
void SV_Physics_None(edict_t *ent); void SV_Physics_None(edict_t *ent);
void SV_Physics_Follow(edict_t *ent); void SV_Physics_Follow(edict_t *ent);

View File

@ -396,8 +396,10 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
pe->origin[0] = check->v.origin[0]; pe->origin[0] = check->v.origin[0];
pe->origin[1] = check->v.origin[1]; pe->origin[1] = check->v.origin[1];
pe->info = e;
pe->origin[2] = check->v.origin[2]; pe->origin[2] = check->v.origin[2];
pe->info = e;
if (e < 1 || e > g_psvs.maxclients) if (e < 1 || e > g_psvs.maxclients)
{ {
pe->player = 0; pe->player = 0;
@ -411,30 +413,32 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
pe->angles[0] = check->v.angles[0]; pe->angles[0] = check->v.angles[0];
pe->angles[1] = check->v.angles[1]; pe->angles[1] = check->v.angles[1];
pe->angles[2] = check->v.angles[2]; pe->angles[2] = check->v.angles[2];
pe->studiomodel = 0;
pe->studiomodel = nullptr;
pe->rendermode = check->v.rendermode; pe->rendermode = check->v.rendermode;
if (check->v.solid == SOLID_BSP) if (check->v.solid == SOLID_BSP)
{ {
pe->model = g_psv.models[check->v.modelindex]; pe->model = g_psv.models[check->v.modelindex];
Q_strncpy(pe->name, pe->model->name, 0x20u); Q_strncpy(pe->name, pe->model->name, sizeof(pe->name) - 1);
pe->name[31] = 0; pe->name[sizeof(pe->name) - 1] = 0;
} }
else if (check->v.solid == SOLID_NOT) else if (check->v.solid == SOLID_NOT)
{ {
if (check->v.modelindex) if (check->v.modelindex)
{ {
pe->model = g_psv.models[check->v.modelindex]; pe->model = g_psv.models[check->v.modelindex];
Q_strncpy(pe->name, pe->model->name, 0x20u); Q_strncpy(pe->name, pe->model->name, sizeof(pe->name) - 1);
pe->name[31] = 0; pe->name[sizeof(pe->name) - 1] = 0;
} }
else else
{ {
pe->model = 0; pe->model = nullptr;
} }
} }
else else
{ {
pe->model = NULL; pe->model = nullptr;
if (check->v.solid != SOLID_BBOX) if (check->v.solid != SOLID_BBOX)
{ {
pe->mins[0] = check->v.mins[0]; pe->mins[0] = check->v.mins[0];
@ -443,10 +447,11 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
pe->mins[2] = check->v.mins[2]; pe->mins[2] = check->v.mins[2];
pe->maxs[1] = check->v.maxs[1]; pe->maxs[1] = check->v.maxs[1];
pe->maxs[2] = check->v.maxs[2]; pe->maxs[2] = check->v.maxs[2];
if (check->v.classname) if (check->v.classname)
{ {
Q_strncpy(pe->name, &pr_strings[check->v.classname], 0x20u); Q_strncpy(pe->name, &pr_strings[check->v.classname], sizeof(pe->name) - 1);
pe->name[31] = 0; pe->name[sizeof(pe->name) - 1] = 0;
} }
else else
{ {
@ -460,13 +465,14 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
pModel = g_psv.models[check->v.modelindex]; pModel = g_psv.models[check->v.modelindex];
if (pModel) if (pModel)
{ {
if (pModel->flags & 0x200) if (pModel->flags & STUDIO_TRACE_HITBOX)
pe->studiomodel = pModel; pe->studiomodel = pModel;
Q_strncpy(pe->name, pModel->name, 0x20u); Q_strncpy(pe->name, pModel->name, sizeof(pe->name) - 1);
pe->name[31] = 0; pe->name[sizeof(pe->name) - 1] = 0;
} }
} }
pe->mins[0] = check->v.mins[0]; pe->mins[0] = check->v.mins[0];
pe->mins[1] = check->v.mins[1]; pe->mins[1] = check->v.mins[1];
pe->mins[2] = check->v.mins[2]; pe->mins[2] = check->v.mins[2];
@ -475,13 +481,16 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
pe->maxs[2] = check->v.maxs[2]; pe->maxs[2] = check->v.maxs[2];
} }
} }
pe->skin = check->v.skin; pe->skin = check->v.skin;
pe->frame = check->v.frame; pe->frame = check->v.frame;
pe->solid = check->v.solid; pe->solid = check->v.solid;
pe->sequence = check->v.sequence; pe->sequence = check->v.sequence;
Q_memcpy(pe->controller, check->v.controller, 4);
Q_memcpy(pe->blending, check->v.blending, 2);
pe->movetype = check->v.movetype; pe->movetype = check->v.movetype;
Q_memcpy(&pe->controller[0], &check->v.controller[0], 4 * sizeof(byte));
Q_memcpy(&pe->blending[0], &check->v.blending[0], 2 * sizeof(byte));
pe->iuser1 = check->v.iuser1; pe->iuser1 = check->v.iuser1;
pe->iuser2 = check->v.iuser2; pe->iuser2 = check->v.iuser2;
pe->iuser3 = check->v.iuser3; pe->iuser3 = check->v.iuser3;
@ -490,6 +499,7 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
pe->fuser2 = check->v.fuser2; pe->fuser2 = check->v.fuser2;
pe->fuser3 = check->v.fuser3; pe->fuser3 = check->v.fuser3;
pe->fuser4 = check->v.fuser4; pe->fuser4 = check->v.fuser4;
pe->vuser1[0] = check->v.vuser1[0]; pe->vuser1[0] = check->v.vuser1[0];
pe->vuser1[1] = check->v.vuser1[1]; pe->vuser1[1] = check->v.vuser1[1];
pe->vuser1[2] = check->v.vuser1[2]; pe->vuser1[2] = check->v.vuser1[2];
@ -499,8 +509,10 @@ void SV_CopyEdictToPhysent(physent_t *pe, int e, edict_t *check)
pe->vuser3[0] = check->v.vuser3[0]; pe->vuser3[0] = check->v.vuser3[0];
pe->vuser3[1] = check->v.vuser3[1]; pe->vuser3[1] = check->v.vuser3[1];
pe->vuser3[2] = check->v.vuser3[2]; pe->vuser3[2] = check->v.vuser3[2];
pe->takedamage = 0; pe->takedamage = 0;
pe->blooddecal = 0; pe->blooddecal = 0;
pe->vuser4[0] = check->v.vuser4[0]; pe->vuser4[0] = check->v.vuser4[0];
pe->vuser4[1] = check->v.vuser4[1]; pe->vuser4[1] = check->v.vuser4[1];
pe->vuser4[2] = check->v.vuser4[2]; pe->vuser4[2] = check->v.vuser4[2];
@ -619,8 +631,8 @@ void SV_AddLinksToPM(areanode_t *node, vec_t *origin)
pmove->physents[0].model = g_psv.worldmodel; pmove->physents[0].model = g_psv.worldmodel;
if (g_psv.worldmodel != NULL) if (g_psv.worldmodel != NULL)
{ {
Q_strncpy(pmove->physents[0].name, g_psv.worldmodel->name, 0x20u); Q_strncpy(pmove->physents[0].name, g_psv.worldmodel->name, sizeof(pmove->physents[0].name) - 1);
pmove->physents[0].name[31] = 0; pmove->physents[0].name[sizeof(pmove->physents[0].name) - 1] = 0;
} }
pmove->physents[0].origin[0] = vec3_origin[0]; pmove->physents[0].origin[0] = vec3_origin[0];
pmove->physents[0].origin[1] = vec3_origin[1]; pmove->physents[0].origin[1] = vec3_origin[1];
@ -813,50 +825,62 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
sv_player->v.clbasevelocity[1] = sv_player->v.basevelocity[1]; sv_player->v.clbasevelocity[1] = sv_player->v.basevelocity[1];
sv_player->v.clbasevelocity[2] = sv_player->v.basevelocity[2]; sv_player->v.clbasevelocity[2] = sv_player->v.basevelocity[2];
} }
pmove->server = 1;
pmove->multiplayer = (qboolean)(g_psvs.maxclients > 1); pmove->server = TRUE;
pmove->multiplayer = (g_psvs.maxclients > 1) ? TRUE : FALSE;
pmove->time = float(1000.0 * host_client->svtimebase); pmove->time = float(1000.0 * host_client->svtimebase);
pmove->usehull = (sv_player->v.flags & 0x4000) != 0; pmove->usehull = (sv_player->v.flags & FL_DUCKING) == FL_DUCKING;
pmove->maxspeed = sv_maxspeed.value; pmove->maxspeed = sv_maxspeed.value;
pmove->clientmaxspeed = sv_player->v.maxspeed; pmove->clientmaxspeed = sv_player->v.maxspeed;
pmove->flDuckTime = (float) sv_player->v.flDuckTime; pmove->flDuckTime = (float)sv_player->v.flDuckTime;
pmove->bInDuck = sv_player->v.bInDuck; pmove->bInDuck = sv_player->v.bInDuck;
pmove->flTimeStepSound = sv_player->v.flTimeStepSound; pmove->flTimeStepSound = sv_player->v.flTimeStepSound;
pmove->iStepLeft = sv_player->v.iStepLeft; pmove->iStepLeft = sv_player->v.iStepLeft;
pmove->flFallVelocity = sv_player->v.flFallVelocity; pmove->flFallVelocity = sv_player->v.flFallVelocity;
pmove->flSwimTime = (float)sv_player->v.flSwimTime; pmove->flSwimTime = (float)sv_player->v.flSwimTime;
pmove->oldbuttons = sv_player->v.oldbuttons; pmove->oldbuttons = sv_player->v.oldbuttons;
Q_strncpy(pmove->physinfo, host_client->physinfo, 0xFFu);
pmove->physinfo[255] = 0; Q_strncpy(pmove->physinfo, host_client->physinfo, sizeof(pmove->physinfo) - 1);
pmove->physinfo[sizeof(pmove->physinfo) - 1] = 0;
pmove->velocity[0] = sv_player->v.velocity[0]; pmove->velocity[0] = sv_player->v.velocity[0];
pmove->velocity[1] = sv_player->v.velocity[1]; pmove->velocity[1] = sv_player->v.velocity[1];
pmove->velocity[2] = sv_player->v.velocity[2]; pmove->velocity[2] = sv_player->v.velocity[2];
pmove->movedir[0] = sv_player->v.movedir[0]; pmove->movedir[0] = sv_player->v.movedir[0];
pmove->movedir[1] = sv_player->v.movedir[1]; pmove->movedir[1] = sv_player->v.movedir[1];
pmove->movedir[2] = sv_player->v.movedir[2]; pmove->movedir[2] = sv_player->v.movedir[2];
pmove->angles[0] = sv_player->v.v_angle[0]; pmove->angles[0] = sv_player->v.v_angle[0];
pmove->angles[1] = sv_player->v.v_angle[1]; pmove->angles[1] = sv_player->v.v_angle[1];
pmove->angles[2] = sv_player->v.v_angle[2]; pmove->angles[2] = sv_player->v.v_angle[2];
pmove->basevelocity[0] = sv_player->v.basevelocity[0]; pmove->basevelocity[0] = sv_player->v.basevelocity[0];
pmove->basevelocity[1] = sv_player->v.basevelocity[1]; pmove->basevelocity[1] = sv_player->v.basevelocity[1];
pmove->basevelocity[2] = sv_player->v.basevelocity[2]; pmove->basevelocity[2] = sv_player->v.basevelocity[2];
pmove->view_ofs[0] = sv_player->v.view_ofs[0]; pmove->view_ofs[0] = sv_player->v.view_ofs[0];
pmove->view_ofs[1] = sv_player->v.view_ofs[1]; pmove->view_ofs[1] = sv_player->v.view_ofs[1];
pmove->view_ofs[2] = sv_player->v.view_ofs[2]; pmove->view_ofs[2] = sv_player->v.view_ofs[2];
pmove->punchangle[0] = sv_player->v.punchangle[0]; pmove->punchangle[0] = sv_player->v.punchangle[0];
pmove->punchangle[1] = sv_player->v.punchangle[1]; pmove->punchangle[1] = sv_player->v.punchangle[1];
pmove->punchangle[2] = sv_player->v.punchangle[2]; pmove->punchangle[2] = sv_player->v.punchangle[2];
pmove->deadflag = sv_player->v.deadflag; pmove->deadflag = sv_player->v.deadflag;
pmove->effects = sv_player->v.effects; pmove->effects = sv_player->v.effects;
pmove->gravity = sv_player->v.gravity; pmove->gravity = sv_player->v.gravity;
pmove->friction = sv_player->v.friction; pmove->friction = sv_player->v.friction;
pmove->spectator = 0; pmove->spectator = 0;
pmove->waterjumptime = sv_player->v.teleport_time; pmove->waterjumptime = sv_player->v.teleport_time;
Q_memcpy(&pmove->cmd, &cmd, sizeof(pmove->cmd)); Q_memcpy(&pmove->cmd, &cmd, sizeof(pmove->cmd));
pmove->dead = sv_player->v.health <= 0.0; pmove->dead = sv_player->v.health <= 0.0;
pmove->movetype = sv_player->v.movetype; pmove->movetype = sv_player->v.movetype;
pmove->flags = sv_player->v.flags; pmove->flags = sv_player->v.flags;
pmove->player_index = NUM_FOR_EDICT(sv_player) - 1; pmove->player_index = NUM_FOR_EDICT(sv_player) - 1;
pmove->iuser1 = sv_player->v.iuser1; pmove->iuser1 = sv_player->v.iuser1;
pmove->iuser2 = sv_player->v.iuser2; pmove->iuser2 = sv_player->v.iuser2;
pmove->iuser3 = sv_player->v.iuser3; pmove->iuser3 = sv_player->v.iuser3;
@ -865,28 +889,37 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
pmove->fuser2 = sv_player->v.fuser2; pmove->fuser2 = sv_player->v.fuser2;
pmove->fuser3 = sv_player->v.fuser3; pmove->fuser3 = sv_player->v.fuser3;
pmove->fuser4 = sv_player->v.fuser4; pmove->fuser4 = sv_player->v.fuser4;
pmove->vuser1[0] = sv_player->v.vuser1[0]; pmove->vuser1[0] = sv_player->v.vuser1[0];
pmove->vuser1[1] = sv_player->v.vuser1[1]; pmove->vuser1[1] = sv_player->v.vuser1[1];
pmove->vuser1[2] = sv_player->v.vuser1[2]; pmove->vuser1[2] = sv_player->v.vuser1[2];
pmove->vuser2[0] = sv_player->v.vuser2[0]; pmove->vuser2[0] = sv_player->v.vuser2[0];
pmove->vuser2[1] = sv_player->v.vuser2[1]; pmove->vuser2[1] = sv_player->v.vuser2[1];
pmove->vuser2[2] = sv_player->v.vuser2[2]; pmove->vuser2[2] = sv_player->v.vuser2[2];
pmove->vuser3[0] = sv_player->v.vuser3[0]; pmove->vuser3[0] = sv_player->v.vuser3[0];
pmove->vuser3[1] = sv_player->v.vuser3[1]; pmove->vuser3[1] = sv_player->v.vuser3[1];
pmove->vuser3[2] = sv_player->v.vuser3[2]; pmove->vuser3[2] = sv_player->v.vuser3[2];
pmove->vuser4[0] = sv_player->v.vuser4[0]; pmove->vuser4[0] = sv_player->v.vuser4[0];
pmove->vuser4[1] = sv_player->v.vuser4[1]; pmove->vuser4[1] = sv_player->v.vuser4[1];
pmove->vuser4[2] = sv_player->v.vuser4[2]; pmove->vuser4[2] = sv_player->v.vuser4[2];
pmove->origin[0] = sv_player->v.origin[0]; pmove->origin[0] = sv_player->v.origin[0];
pmove->origin[1] = sv_player->v.origin[1]; pmove->origin[1] = sv_player->v.origin[1];
pmove->origin[2] = sv_player->v.origin[2]; pmove->origin[2] = sv_player->v.origin[2];
SV_AddLinksToPM(sv_areanodes, pmove->origin); SV_AddLinksToPM(sv_areanodes, pmove->origin);
pmove->frametime = frametime; pmove->frametime = frametime;
pmove->runfuncs = 1; pmove->runfuncs = TRUE;
pmove->PM_PlaySound = PM_SV_PlaySound; pmove->PM_PlaySound = PM_SV_PlaySound;
pmove->PM_TraceTexture = PM_SV_TraceTexture; pmove->PM_TraceTexture = PM_SV_TraceTexture;
pmove->PM_PlaybackEventFull = PM_SV_PlaybackEventFull; pmove->PM_PlaybackEventFull = PM_SV_PlaybackEventFull;
gEntityInterface.pfnPM_Move(pmove, 1);
gEntityInterface.pfnPM_Move(pmove, TRUE);
sv_player->v.deadflag = pmove->deadflag; sv_player->v.deadflag = pmove->deadflag;
sv_player->v.effects = pmove->effects; sv_player->v.effects = pmove->effects;
sv_player->v.teleport_time = pmove->waterjumptime; sv_player->v.teleport_time = pmove->waterjumptime;
@ -897,15 +930,19 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
sv_player->v.movetype = pmove->movetype; sv_player->v.movetype = pmove->movetype;
sv_player->v.maxspeed = pmove->clientmaxspeed; sv_player->v.maxspeed = pmove->clientmaxspeed;
sv_player->v.iStepLeft = pmove->iStepLeft; sv_player->v.iStepLeft = pmove->iStepLeft;
sv_player->v.view_ofs[0] = pmove->view_ofs[0]; sv_player->v.view_ofs[0] = pmove->view_ofs[0];
sv_player->v.view_ofs[1] = pmove->view_ofs[1]; sv_player->v.view_ofs[1] = pmove->view_ofs[1];
sv_player->v.view_ofs[2] = pmove->view_ofs[2]; sv_player->v.view_ofs[2] = pmove->view_ofs[2];
sv_player->v.movedir[0] = pmove->movedir[0]; sv_player->v.movedir[0] = pmove->movedir[0];
sv_player->v.movedir[1] = pmove->movedir[1]; sv_player->v.movedir[1] = pmove->movedir[1];
sv_player->v.movedir[2] = pmove->movedir[2]; sv_player->v.movedir[2] = pmove->movedir[2];
sv_player->v.punchangle[0] = pmove->punchangle[0]; sv_player->v.punchangle[0] = pmove->punchangle[0];
sv_player->v.punchangle[1] = pmove->punchangle[1]; sv_player->v.punchangle[1] = pmove->punchangle[1];
sv_player->v.punchangle[2] = pmove->punchangle[2]; sv_player->v.punchangle[2] = pmove->punchangle[2];
if (pmove->onground == -1) if (pmove->onground == -1)
{ {
sv_player->v.flags &= ~FL_ONGROUND; sv_player->v.flags &= ~FL_ONGROUND;
@ -915,15 +952,19 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
sv_player->v.flags |= FL_ONGROUND; sv_player->v.flags |= FL_ONGROUND;
sv_player->v.groundentity = EDICT_NUM(pmove->physents[pmove->onground].info); sv_player->v.groundentity = EDICT_NUM(pmove->physents[pmove->onground].info);
} }
sv_player->v.origin[0] = pmove->origin[0]; sv_player->v.origin[0] = pmove->origin[0];
sv_player->v.origin[1] = pmove->origin[1]; sv_player->v.origin[1] = pmove->origin[1];
sv_player->v.origin[2] = pmove->origin[2]; sv_player->v.origin[2] = pmove->origin[2];
sv_player->v.velocity[0] = pmove->velocity[0]; sv_player->v.velocity[0] = pmove->velocity[0];
sv_player->v.velocity[1] = pmove->velocity[1]; sv_player->v.velocity[1] = pmove->velocity[1];
sv_player->v.velocity[2] = pmove->velocity[2]; sv_player->v.velocity[2] = pmove->velocity[2];
sv_player->v.basevelocity[0] = pmove->basevelocity[0]; sv_player->v.basevelocity[0] = pmove->basevelocity[0];
sv_player->v.basevelocity[1] = pmove->basevelocity[1]; sv_player->v.basevelocity[1] = pmove->basevelocity[1];
sv_player->v.basevelocity[2] = pmove->basevelocity[2]; sv_player->v.basevelocity[2] = pmove->basevelocity[2];
if (!sv_player->v.fixangle) if (!sv_player->v.fixangle)
{ {
sv_player->v.v_angle[0] = pmove->angles[0]; sv_player->v.v_angle[0] = pmove->angles[0];
@ -933,12 +974,14 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
sv_player->v.angles[1] = pmove->angles[1]; sv_player->v.angles[1] = pmove->angles[1];
sv_player->v.angles[2] = pmove->angles[2]; sv_player->v.angles[2] = pmove->angles[2];
} }
sv_player->v.bInDuck = pmove->bInDuck; sv_player->v.bInDuck = pmove->bInDuck;
sv_player->v.flDuckTime = (int)pmove->flDuckTime; sv_player->v.flDuckTime = (int)pmove->flDuckTime;
sv_player->v.flTimeStepSound = pmove->flTimeStepSound; sv_player->v.flTimeStepSound = pmove->flTimeStepSound;
sv_player->v.flFallVelocity = pmove->flFallVelocity; sv_player->v.flFallVelocity = pmove->flFallVelocity;
sv_player->v.flSwimTime = (int)pmove->flSwimTime; sv_player->v.flSwimTime = (int)pmove->flSwimTime;
sv_player->v.oldbuttons = pmove->cmd.buttons; sv_player->v.oldbuttons = pmove->cmd.buttons;
sv_player->v.iuser1 = pmove->iuser1; sv_player->v.iuser1 = pmove->iuser1;
sv_player->v.iuser2 = pmove->iuser2; sv_player->v.iuser2 = pmove->iuser2;
sv_player->v.iuser3 = pmove->iuser3; sv_player->v.iuser3 = pmove->iuser3;
@ -947,18 +990,23 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
sv_player->v.fuser2 = pmove->fuser2; sv_player->v.fuser2 = pmove->fuser2;
sv_player->v.fuser3 = pmove->fuser3; sv_player->v.fuser3 = pmove->fuser3;
sv_player->v.fuser4 = pmove->fuser4; sv_player->v.fuser4 = pmove->fuser4;
sv_player->v.vuser1[0] = pmove->vuser1[0]; sv_player->v.vuser1[0] = pmove->vuser1[0];
sv_player->v.vuser1[1] = pmove->vuser1[1]; sv_player->v.vuser1[1] = pmove->vuser1[1];
sv_player->v.vuser1[2] = pmove->vuser1[2]; sv_player->v.vuser1[2] = pmove->vuser1[2];
sv_player->v.vuser2[0] = pmove->vuser2[0]; sv_player->v.vuser2[0] = pmove->vuser2[0];
sv_player->v.vuser2[1] = pmove->vuser2[1]; sv_player->v.vuser2[1] = pmove->vuser2[1];
sv_player->v.vuser2[2] = pmove->vuser2[2]; sv_player->v.vuser2[2] = pmove->vuser2[2];
sv_player->v.vuser3[0] = pmove->vuser3[0]; sv_player->v.vuser3[0] = pmove->vuser3[0];
sv_player->v.vuser3[1] = pmove->vuser3[1]; sv_player->v.vuser3[1] = pmove->vuser3[1];
sv_player->v.vuser3[2] = pmove->vuser3[2]; sv_player->v.vuser3[2] = pmove->vuser3[2];
sv_player->v.vuser4[0] = pmove->vuser4[0]; sv_player->v.vuser4[0] = pmove->vuser4[0];
sv_player->v.vuser4[1] = pmove->vuser4[1]; sv_player->v.vuser4[1] = pmove->vuser4[1];
sv_player->v.vuser4[2] = pmove->vuser4[2]; sv_player->v.vuser4[2] = pmove->vuser4[2];
SetMinMaxSize(sv_player, player_mins[pmove->usehull], player_maxs[pmove->usehull], 0); SetMinMaxSize(sv_player, player_mins[pmove->usehull], player_maxs[pmove->usehull], 0);
if (host_client->edict->v.solid) if (host_client->edict->v.solid)
{ {
@ -982,6 +1030,7 @@ void SV_RunCmd(usercmd_t *ucmd, int random_seed)
sv_player->v.velocity[1] = vel[1]; sv_player->v.velocity[1] = vel[1];
sv_player->v.velocity[2] = vel[2]; sv_player->v.velocity[2] = vel[2];
} }
gGlobalVariables.time = (float)host_client->svtimebase; gGlobalVariables.time = (float)host_client->svtimebase;
gGlobalVariables.frametime = frametime; gGlobalVariables.frametime = frametime;
gEntityInterface.pfnPlayerPostThink(sv_player); gEntityInterface.pfnPlayerPostThink(sv_player);

View File

@ -214,8 +214,8 @@ void TEX_AddAnimatingTextures(void)
if (miptex[i][0] != '+' && miptex[i][0] != '-') if (miptex[i][0] != '+' && miptex[i][0] != '-')
continue; continue;
Q_strncpy(name, miptex[i], 0x1Fu); Q_strncpy(name, miptex[i], sizeof(name) - 1);
name[31] = 0; name[sizeof(name) - 1] = 0;
for (int j = 0; j < 20; j++) for (int j = 0; j < 20; j++)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,9 @@ typedef struct areanode_s
link_t solid_edicts; link_t solid_edicts;
} areanode_t; } areanode_t;
const int AREA_DEPTH = 4;
const int AREA_NODES = 32;
typedef struct moveclip_s // TODO: Move it to world.cpp someday typedef struct moveclip_s // TODO: Move it to world.cpp someday
{ {
vec3_t boxmins; vec3_t boxmins;
@ -57,6 +60,15 @@ typedef struct moveclip_s // TODO: Move it to world.cpp someday
qboolean monsterClipBrush; qboolean monsterClipBrush;
} moveclip_t; } moveclip_t;
#define CONTENTS_NONE 0 // no custom contents specified
#define MOVE_NORMAL 0 // normal trace
#define MOVE_NOMONSTERS 1 // ignore monsters (edicts with flags (FL_MONSTER|FL_FAKECLIENT|FL_CLIENT) set)
#define MOVE_MISSILE 2 // extra size for monsters
#define FMOVE_IGNORE_GLASS 0x100
#define FMOVE_SIMPLEBOX 0x200
typedef dclipnode_t box_clipnodes_t[6]; typedef dclipnode_t box_clipnodes_t[6];
typedef mplane_t box_planes_t[6]; typedef mplane_t box_planes_t[6];
typedef mplane_t beam_planes_t[6]; typedef mplane_t beam_planes_t[6];
@ -78,7 +90,7 @@ extern hull_t beam_hull;
extern box_clipnodes_t box_clipnodes; extern box_clipnodes_t box_clipnodes;
extern box_planes_t box_planes; extern box_planes_t box_planes;
extern beam_planes_t beam_planes; extern beam_planes_t beam_planes;
extern areanode_t sv_areanodes[32]; extern areanode_t sv_areanodes[AREA_NODES];
extern int sv_numareanodes; extern int sv_numareanodes;
extern cvar_t sv_force_ent_intersection; extern cvar_t sv_force_ent_intersection;
@ -87,13 +99,13 @@ void ClearLink(link_t *l);
void RemoveLink(link_t *l); void RemoveLink(link_t *l);
void InsertLinkBefore(link_t *l, link_t *before); void InsertLinkBefore(link_t *l, link_t *before);
NOXREF void InsertLinkAfter(link_t *l, link_t *after); NOXREF void InsertLinkAfter(link_t *l, link_t *after);
void SV_InitBoxHull(void); void SV_InitBoxHull();
hull_t *SV_HullForBox(const vec_t *mins, const vec_t *maxs); hull_t *SV_HullForBox(const vec_t *mins, const vec_t *maxs);
NOXREF hull_t *SV_HullForBeam(const vec_t *start, const vec_t *end, const vec_t *size); NOXREF hull_t *SV_HullForBeam(const vec_t *start, const vec_t *end, const vec_t *size);
struct hull_s *SV_HullForBsp(edict_t *ent, const vec_t *mins, const vec_t *maxs, vec_t *offset); hull_t *SV_HullForBsp(edict_t *ent, const vec_t *mins, const vec_t *maxs, vec_t *offset);
hull_t *SV_HullForEntity(edict_t *ent, const vec_t *mins, const vec_t *maxs, vec_t *offset); hull_t *SV_HullForEntity(edict_t *ent, const vec_t *mins, const vec_t *maxs, vec_t *offset);
areanode_t *SV_CreateAreaNode(int depth, vec_t *mins, vec_t *maxs); areanode_t *SV_CreateAreaNode(int depth, vec_t *mins, vec_t *maxs);
void SV_ClearWorld(void); void SV_ClearWorld();
void SV_UnlinkEdict(edict_t *ent); void SV_UnlinkEdict(edict_t *ent);
void SV_TouchLinks(edict_t *ent, areanode_t *node); void SV_TouchLinks(edict_t *ent, areanode_t *node);
void SV_FindTouchedLeafs(edict_t *ent, mnode_t *node, int *topnode); void SV_FindTouchedLeafs(edict_t *ent, mnode_t *node, int *topnode);

View File

@ -1381,7 +1381,7 @@ FunctionHook g_FunctionHooks[] =
HOOK_DEF(0x01D50460, Length), HOOK_DEF(0x01D50460, Length),
HOOK_DEF(0x01D504A0, VectorNormalize), HOOK_DEF(0x01D504A0, VectorNormalize),
//HOOK_DEF(0x, VectorInverse), //HOOK_DEF(0x, VectorInverse),
HOOK_DEF(0x01D50550, VectorScale), //HOOK_DEF(0x01D50550, VectorScale),
//HOOK_DEF(0x, Q_log2), //HOOK_DEF(0x, Q_log2),
//HOOK_DEF(0x, VectorMatrix), //HOOK_DEF(0x, VectorMatrix),
HOOK_DEF(0x01D50640, VectorAngles), HOOK_DEF(0x01D50640, VectorAngles),
@ -2371,8 +2371,8 @@ AddressRef g_DataRefs[] =
GLOBALVAR_LINK(0x01E48EA0, "sv_stopspeed", psv_stopspeed), GLOBALVAR_LINK(0x01E48EA0, "sv_stopspeed", psv_stopspeed),
GLOBALVAR_LINK(0x021C2B48, "g_moved_from", pg_moved_from), GLOBALVAR_LINK(0x021C2B48, "g_moved_from", pg_moved_from),
GLOBALVAR_LINK(0x021C2B4C, "sv_numareanodes", pg_moved_edict), GLOBALVAR_LINK(0x021C2B4C, "sv_numareanodes", pg_moved_edict),
GLOBALVAR_LINK(0x021C2B50, "c_yes", pc_yes), //GLOBALVAR_LINK(0x021C2B50, "c_yes", pc_yes),
GLOBALVAR_LINK(0x021C2B54, "c_no", pc_no), //GLOBALVAR_LINK(0x021C2B54, "c_no", pc_no),
GLOBALVAR_LINK(0x020042AC, "net_thread_initialized", pnet_thread_initialized), GLOBALVAR_LINK(0x020042AC, "net_thread_initialized", pnet_thread_initialized),
GLOBALVAR_LINK(0x01E3E8DC, "net_address", pnet_address), GLOBALVAR_LINK(0x01E3E8DC, "net_address", pnet_address),
GLOBALVAR_LINK(0x01E3E900, "ipname", pipname), GLOBALVAR_LINK(0x01E3E900, "ipname", pipname),

View File

@ -60,7 +60,7 @@ struct event_state_s
#include "edict.h" #include "edict.h"
#endif #endif
#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m))) #define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - offsetof(t, m)))
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) #define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
//============================================================================ //============================================================================