2
0
mirror of https://github.com/rehlds/rehlds.git synced 2025-02-26 21:41:06 +03:00

Improve movement toss (#555)

This commit is contained in:
Dmitry Novikov 2017-12-18 19:01:18 +07:00 committed by GitHub
parent a761c5d380
commit 5e2bd82b00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 8 deletions

View File

@ -200,7 +200,7 @@ void SV_ClipVelocity(vec_t *in, vec_t *normal, vec_t *out, float overbounce)
#define MAX_CLIP_PLANES 5
// The basic solid body movement clip that slides along multiple planes
void SV_FlyMove(edict_t *ent, float time)
void SV_FlyMove(edict_t *ent, float time, float bounce)
{
int numplanes = 0; // and not sliding along any planes
float time_left = time; // Total time for this movement operation.
@ -212,6 +212,14 @@ void SV_FlyMove(edict_t *ent, float time)
VectorCopy(ent->v.velocity, original_velocity); // Store original velocity
VectorCopy(ent->v.velocity, primal_velocity);
int moveType;
#ifdef REHLDS_FIXES
if (ent->v.solid == SOLID_TRIGGER || ent->v.solid == SOLID_NOT)
moveType = MOVE_NOMONSTERS;
#endif
moveType = MOVE_NORMAL;
qboolean monsterClip = (ent->v.flags & FL_MONSTERCLIP) ? TRUE : FALSE;
for (int bumpcount = 0; bumpcount < MAX_CLIP_PLANES - 1; bumpcount++)
@ -223,7 +231,7 @@ void SV_FlyMove(edict_t *ent, float time)
VectorMA(ent->v.origin, time_left, ent->v.velocity, move);
// See if we can make it from origin to end point
trace_t trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, move, MOVE_NORMAL, ent, monsterClip);
trace_t trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, move, moveType, ent, monsterClip);
// If we started in a solid object, or we were in solid space the whole way, zero out our velocity.
if (trace.allsolid)
@ -237,7 +245,7 @@ void SV_FlyMove(edict_t *ent, float time)
// the copy the end position into the ent->v.origin and zero the plane counter.
if (trace.fraction > 0.0f)
{
trace_t test = SV_Move(trace.endpos, ent->v.mins, ent->v.maxs, trace.endpos, MOVE_NORMAL, ent, monsterClip);
trace_t test = SV_Move(trace.endpos, ent->v.mins, ent->v.maxs, trace.endpos, moveType, ent, monsterClip);
if (!test.allsolid)
{
// actually covered some distance
@ -275,6 +283,14 @@ void SV_FlyMove(edict_t *ent, float time)
ent->v.flags |= FL_ONGROUND;
ent->v.groundentity = trace.ent;
}
#ifdef REHLDS_FIXES
if ((ent->v.flags & FL_ONGROUND) && ent->v.movetype == MOVETYPE_TOSS)
{
VectorClear(ent->v.velocity);
return;
}
#endif
}
// run the impact function
@ -326,7 +342,7 @@ void SV_FlyMove(edict_t *ent, float time)
// modify original_velocity so it parallels all of the clip planes
for (i = 0; i < numplanes; i++)
{
SV_ClipVelocity(original_velocity, planes[i], new_velocity, 1.0f);
SV_ClipVelocity(original_velocity, planes[i], new_velocity, bounce);
for (j = 0; j < numplanes; j++)
{
@ -1018,7 +1034,7 @@ void SV_CheckWaterTransition(edict_t *ent)
}
}
// Toss, bounce, and fly movement. When onground, do nothing.
// Toss movement. When onground, do nothing.
void SV_Physics_Toss(edict_t *ent)
{
SV_CheckWater(ent);
@ -1042,6 +1058,83 @@ void SV_Physics_Toss(edict_t *ent)
SV_CheckVelocity(ent);
// add gravity
SV_AddGravity(ent);
// move angles
VectorMA(ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles);
// move origin
VectorAdd(ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
SV_CheckVelocity(ent);
SV_FlyMove(ent, host_frametime, 1.1f);
SV_CheckVelocity(ent);
VectorSubtract(ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
SV_CheckVelocity(ent);
// determine if it's on solid ground at all
{
int x, y;
vec3_t point, mins, 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
point[2] = mins[2] - 1.0f;
for (x = 0; x <= 1; x++)
{
for (y = 0; y <= 1; y++)
{
point[0] = x ? maxs[0] : mins[0];
point[1] = y ? maxs[1] : mins[1];
g_groupmask = ent->v.groupinfo;
if (SV_PointContents(point) == CONTENTS_SOLID)
{
ent->v.flags |= FL_ONGROUND;
break;
}
}
}
}
SV_LinkEdict(ent, TRUE);
// check for in water
SV_CheckWaterTransition(ent);
}
// Bounce and fly movement. When onground, do nothing.
void SV_Physics_Bounce(edict_t *ent)
{
SV_CheckWater(ent);
// regular thinking
if (!SV_RunThink(ent))
return;
if (ent->v.velocity[2] > 0.0f || !ent->v.groundentity || (ent->v.groundentity->v.flags & (FL_MONSTER | FL_CLIENT))) {
ent->v.flags &= ~FL_ONGROUND;
}
// if on ground and not moving, return.
if ((ent->v.flags & FL_ONGROUND) && VectorIsZero(ent->v.velocity))
{
VectorClear(ent->v.avelocity);
if (VectorIsZero(ent->v.basevelocity))
return; // at rest
}
SV_CheckVelocity(ent);
// add gravity
switch (ent->v.movetype)
{
@ -1317,7 +1410,7 @@ void SV_Physics_Step(edict_t *ent)
VectorAdd(ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
SV_CheckVelocity(ent);
SV_FlyMove(ent, host_frametime);
SV_FlyMove(ent, host_frametime, 1.0f);
SV_CheckVelocity(ent);
VectorSubtract(ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
@ -1436,11 +1529,15 @@ void SV_Physics()
SV_Physics_Step(ent);
break;
case MOVETYPE_TOSS:
#ifdef REHLDS_FIXES
SV_Physics_Toss(ent);
break;
#endif
case MOVETYPE_BOUNCE:
case MOVETYPE_BOUNCEMISSILE:
case MOVETYPE_FLY:
case MOVETYPE_FLYMISSILE:
SV_Physics_Toss(ent);
SV_Physics_Bounce(ent);
break;
default:
Sys_Error("%s: %s bad movetype %d", __func__, &pr_strings[ent->v.classname], ent->v.movetype);

View File

@ -47,7 +47,7 @@ void SV_CheckVelocity(edict_t *ent);
qboolean SV_RunThink(edict_t *ent);
void SV_Impact(edict_t *e1, edict_t *e2, trace_t *ptrace);
void SV_ClipVelocity(vec_t *in, vec_t *normal, vec_t *out, float overbounce);
void SV_FlyMove(edict_t *ent, float time);
void SV_FlyMove(edict_t *ent, float time, float bounce);
void SV_AddGravity(edict_t *ent);
NOXREF void SV_AddCorrectGravity(edict_t *ent);
NOXREF void SV_FixupGravityVelocity(edict_t *ent);