X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=sv_phys.c;h=4ad211bc6053f9e1c3cb79836276915d1aca4e22;hb=c1878bd6bc94e9e53a1eeef0db5cd001f97f79f4;hp=50117fa6522db3b59e7c3daffe3e678521b8c4e2;hpb=6deb337afd3183721d10723fccd629fd3f5b990c;p=xonotic%2Fdarkplaces.git diff --git a/sv_phys.c b/sv_phys.c index 50117fa6..4ad211bc 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -101,7 +101,7 @@ int SV_GenericHitSuperContentsMask(const prvm_edict_t *passedict) SV_TracePoint ================== */ -trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask) +trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask) { prvm_prog_t *prog = SVVM_prog; int i, bodysupercontents; @@ -127,7 +127,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; - //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask); + //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask, skipsupercontentsmask); VectorCopy(start, clipstart); VectorClear(clipmins2); @@ -137,7 +137,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int #endif // clip to world - Collision_ClipPointToWorld(&cliptrace, sv.worldmodel, clipstart, hitsupercontentsmask); + Collision_ClipPointToWorld(&cliptrace, sv.worldmodel, clipstart, hitsupercontentsmask, skipsupercontentsmask); cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid; if (cliptrace.startsolid || cliptrace.fraction < 1) cliptrace.ent = prog->edicts; @@ -231,9 +231,9 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int VectorCopy(PRVM_serveredictvector(touch, mins), touchmins); VectorCopy(PRVM_serveredictvector(touch, maxs), touchmaxs); if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER) - Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask); + Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask, skipsupercontentsmask, 0.0f); else - Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask); + Collision_ClipPointToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask, skipsupercontentsmask); Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_serveredictfloat(touch, solid) == SOLID_BSP); } @@ -247,11 +247,7 @@ finished: SV_TraceLine ================== */ -#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND -trace_t SV_TraceLine(const vec3_t start, const vec3_t pEnd, int type, prvm_edict_t *passedict, int hitsupercontentsmask) -#else -trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask) -#endif +trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend) { prvm_prog_t *prog = SVVM_prog; int i, bodysupercontents; @@ -276,26 +272,8 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; -#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND - vec3_t end; - vec_t len = 0; - - if (VectorCompare(start, pEnd)) - return SV_TracePoint(start, type, passedict, hitsupercontentsmask); - - if(collision_endposnudge.value > 0) - { - // TRICK: make the trace 1 qu longer! - VectorSubtract(pEnd, start, end); - len = VectorNormalizeLength(end); - VectorMA(pEnd, collision_endposnudge.value, end, end); - } - else - VectorCopy(pEnd, end); -#else if (VectorCompare(start, end)) - return SV_TracePoint(start, type, passedict, hitsupercontentsmask); -#endif + return SV_TracePoint(start, type, passedict, hitsupercontentsmask, skipsupercontentsmask); //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask); @@ -308,7 +286,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ #endif // clip to world - Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask, false); + Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, extend, false); cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid; if (cliptrace.startsolid || cliptrace.fraction < 1) cliptrace.ent = prog->edicts; @@ -402,18 +380,14 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ VectorCopy(PRVM_serveredictvector(touch, mins), touchmins); VectorCopy(PRVM_serveredictvector(touch, maxs), touchmaxs); if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER) - Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask); + Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, extend); else - Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, false); + Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, extend, false); Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_serveredictfloat(touch, solid) == SOLID_BSP); } finished: -#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND - if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0) - Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd); -#endif return cliptrace; } @@ -422,18 +396,10 @@ finished: SV_Move ================== */ -#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND #if COLLISIONPARANOID >= 1 -trace_t SV_TraceBox_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t pEnd, int type, prvm_edict_t *passedict, int hitsupercontentsmask) +trace_t SV_TraceBox_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend) #else -trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t pEnd, int type, prvm_edict_t *passedict, int hitsupercontentsmask) -#endif -#else -#if COLLISIONPARANOID >= 1 -trace_t SV_TraceBox_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask) -#else -trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask) -#endif +trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, float extend) #endif { prvm_prog_t *prog = SVVM_prog; @@ -463,46 +429,18 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; -#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND - vec3_t end; - vec_t len = 0; - - if (VectorCompare(mins, maxs)) - { - vec3_t shiftstart, shiftend; - VectorAdd(start, mins, shiftstart); - VectorAdd(pEnd, mins, shiftend); - if (VectorCompare(start, pEnd)) - trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask); - else - trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask); - VectorSubtract(trace.endpos, mins, trace.endpos); - return trace; - } - - if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0) - { - // TRICK: make the trace 1 qu longer! - VectorSubtract(pEnd, start, end); - len = VectorNormalizeLength(end); - VectorMA(pEnd, collision_endposnudge.value, end, end); - } - else - VectorCopy(pEnd, end); -#else if (VectorCompare(mins, maxs)) { vec3_t shiftstart, shiftend; VectorAdd(start, mins, shiftstart); VectorAdd(end, mins, shiftend); if (VectorCompare(start, end)) - trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask); + trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, skipsupercontentsmask); else - trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask); + trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, skipsupercontentsmask, extend); VectorSubtract(trace.endpos, mins, trace.endpos); return trace; } -#endif VectorCopy(start, clipstart); VectorCopy(end, clipend); @@ -515,7 +453,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co #endif // clip to world - Collision_ClipToWorld(&cliptrace, sv.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask); + Collision_ClipToWorld(&cliptrace, sv.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, extend); cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid; if (cliptrace.startsolid || cliptrace.fraction < 1) cliptrace.ent = prog->edicts; @@ -620,32 +558,29 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co VectorCopy(PRVM_serveredictvector(touch, mins), touchmins); VectorCopy(PRVM_serveredictvector(touch, maxs), touchmaxs); if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER) - Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask); + Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask, skipsupercontentsmask, extend); else - Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask); + Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, extend); Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_serveredictfloat(touch, solid) == SOLID_BSP); } finished: -#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND - if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0) - Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd); -#endif return cliptrace; } #if COLLISIONPARANOID >= 1 -trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask) +trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask) { + prvm_prog_t *prog = SVVM_prog; int endstuck; trace_t trace; vec3_t temp; - trace = SV_TraceBox_(start, mins, maxs, end, type, passedict, hitsupercontentsmask); + trace = SV_TraceBox_(start, mins, maxs, end, type, passedict, hitsupercontentsmask, skipsupercontentsmask); if (passedict) { VectorCopy(trace.endpos, temp); - endstuck = SV_TraceBox_(temp, mins, maxs, temp, type, passedict, hitsupercontentsmask).startsolid; + endstuck = SV_TraceBox_(temp, mins, maxs, temp, type, passedict, hitsupercontentsmask, skipsupercontentsmask).startsolid; #if COLLISIONPARANOID < 3 if (trace.startsolid || endstuck) #endif @@ -979,7 +914,7 @@ static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset) VectorCopy(PRVM_serveredictvector(ent, origin), entorigin); VectorCopy(PRVM_serveredictvector(ent, mins), entmins); VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs); - trace = SV_TraceBox(org, entmins, entmaxs, entorigin, ((PRVM_serveredictfloat(ent, movetype) == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), ent, contents); + trace = SV_TraceBox(org, entmins, entmaxs, entorigin, ((PRVM_serveredictfloat(ent, movetype) == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), ent, contents, 0, collision_extendmovelength.value); if (trace.startsupercontents & contents) return true; else @@ -1018,7 +953,7 @@ static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset) #else // verify if the endpos is REALLY outside solid VectorCopy(trace.endpos, org); - trace = SV_TraceBox(org, entmins, entmaxs, org, MOVE_NOMONSTERS, ent, contents); + trace = SV_TraceBox(org, entmins, entmaxs, org, MOVE_NOMONSTERS, ent, contents, 0, collision_extendmovelength.value); if(trace.startsolid) Con_Printf("SV_TestEntityPosition: trace.endpos detected to be in solid. NOT using it.\n"); else @@ -1101,7 +1036,7 @@ void SV_CheckVelocity (prvm_edict_t *ent) // LordHavoc: a hack to ensure that the (rather silly) id1 quakec // player_run/player_stand1 does not horribly malfunction if the // velocity becomes a denormalized float - if (VectorLength2(PRVM_serveredictvector(ent, velocity)) < 0.0001) + if (VectorLength2(PRVM_serveredictvector(ent, velocity)) < 0.0000001) VectorClear(PRVM_serveredictvector(ent, velocity)); // LordHavoc: max velocity fix, inspired by Maddes's source fixes, but this is faster @@ -1241,7 +1176,7 @@ If stepnormal is not NULL, the plane normal of any vertical wall hit will be sto static float SV_Gravity (prvm_edict_t *ent); static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean dolink); #define MAX_CLIP_PLANES 5 -static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, float stepheight) +static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, int skipsupercontentsmask, float stepheight) { prvm_prog_t *prog = SVVM_prog; int blocked, bumpcount; @@ -1458,7 +1393,7 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo { // LordHavoc: fix the 'fall to your death in a wedge corner' glitch // flag ONGROUND if there's ground under it - trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, hitsupercontentsmask); + trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, hitsupercontentsmask, skipsupercontentsmask); } */ @@ -1541,7 +1476,7 @@ static qboolean SV_NudgeOutOfSolid_PivotIsKnownGood(prvm_edict_t *ent, vec3_t pi testorigin[coord] += stuckmins[coord] - goodmins[coord]; } - stucktrace = SV_TraceBox(stuckorigin, goodmins, goodmaxs, testorigin, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent)); + stucktrace = SV_TraceBox(stuckorigin, goodmins, goodmaxs, testorigin, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value); if (stucktrace.bmodelstartsolid) { // BAD BAD, can't fix that @@ -1611,7 +1546,7 @@ qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent) VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin); for (bump = 0;bump < 10;bump++) { - stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent)); + stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value); if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0) { // found a good location, use it @@ -1667,7 +1602,7 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q else type = MOVE_NORMAL; - *trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent)); + *trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent), 0, collision_extendmovelength.value); // fail the move if stuck in world if (trace->worldstartsolid) return true; @@ -1680,7 +1615,7 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q #if 0 if(!trace->startsolid) - if(SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), PRVM_serveredictvector(ent, origin), type, ent, SV_GenericHitSuperContentsMask(ent)).startsolid) + if(SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), PRVM_serveredictvector(ent, origin), type, ent, SV_GenericHitSuperContentsMask(ent), 0).startsolid) { Con_Printf("something eeeeevil happened\n"); } @@ -1893,7 +1828,7 @@ static void SV_PushMove (prvm_edict_t *pusher, float movetime) VectorCopy(PRVM_serveredictvector(check, origin), checkorigin); VectorCopy(PRVM_serveredictvector(check, mins), checkmins); VectorCopy(PRVM_serveredictvector(check, maxs), checkmaxs); - Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents); + Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, 0, collision_extendmovelength.value); //trace = SV_TraceBox(PRVM_serveredictvector(check, origin), PRVM_serveredictvector(check, mins), PRVM_serveredictvector(check, maxs), PRVM_serveredictvector(check, origin), MOVE_NOMONSTERS, check, checkcontents); if (!trace.startsolid) { @@ -1960,7 +1895,7 @@ static void SV_PushMove (prvm_edict_t *pusher, float movetime) VectorCopy(PRVM_serveredictvector(check, origin), checkorigin); VectorCopy(PRVM_serveredictvector(check, mins), checkmins); VectorCopy(PRVM_serveredictvector(check, maxs), checkmaxs); - Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents); + Collision_ClipToGenericEntity(&trace, pushermodel, pusher->priv.server->frameblend, &pusher->priv.server->skeleton, pushermins, pushermaxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, checkorigin, checkmins, checkmaxs, checkorigin, checkcontents, 0, collision_extendmovelength.value); if (trace.startsolid) { vec3_t move2; @@ -2313,7 +2248,7 @@ int SV_TryUnstick (prvm_edict_t *ent, vec3_t oldvel) PRVM_serveredictvector(ent, velocity)[0] = oldvel[0]; PRVM_serveredictvector(ent, velocity)[1] = oldvel[1]; PRVM_serveredictvector(ent, velocity)[2] = 0; - clip = SV_FlyMove (ent, 0.1, NULL, SV_GenericHitSuperContentsMask(ent)); + clip = SV_FlyMove (ent, 0.1, NULL, SV_GenericHitSuperContentsMask(ent), 0); if (fabs(oldorg[1] - PRVM_serveredictvector(ent, origin)[1]) > 4 || fabs(oldorg[0] - PRVM_serveredictvector(ent, origin)[0]) > 4) @@ -2349,6 +2284,7 @@ static void SV_WalkMove (prvm_edict_t *ent) int originalmove_flags; int originalmove_groundentity; int hitsupercontentsmask; + int skipsupercontentsmask; int type; vec3_t upmove, downmove, start_origin, start_velocity, stepnormal, originalmove_origin, originalmove_velocity, entmins, entmaxs; trace_t downtrace, trace; @@ -2365,6 +2301,7 @@ static void SV_WalkMove (prvm_edict_t *ent) applygravity = !SV_CheckWater (ent) && PRVM_serveredictfloat(ent, movetype) == MOVETYPE_WALK && ! ((int)PRVM_serveredictfloat(ent, flags) & FL_WATERJUMP); hitsupercontentsmask = SV_GenericHitSuperContentsMask(ent); + skipsupercontentsmask = 0; SV_CheckVelocity(ent); @@ -2374,7 +2311,7 @@ static void SV_WalkMove (prvm_edict_t *ent) VectorCopy (PRVM_serveredictvector(ent, origin), start_origin); VectorCopy (PRVM_serveredictvector(ent, velocity), start_velocity); - clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask, sv_gameplayfix_stepmultipletimes.integer ? sv_stepheight.value : 0); + clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask, skipsupercontentsmask, sv_gameplayfix_stepmultipletimes.integer ? sv_stepheight.value : 0); if(sv_gameplayfix_downtracesupportsongroundflag.integer) if(!(clip & 1)) @@ -2394,7 +2331,7 @@ static void SV_WalkMove (prvm_edict_t *ent) type = MOVE_NORMAL; VectorCopy(PRVM_serveredictvector(ent, mins), entmins); VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs); - trace = SV_TraceBox(upmove, entmins, entmaxs, downmove, type, ent, SV_GenericHitSuperContentsMask(ent)); + trace = SV_TraceBox(upmove, entmins, entmaxs, downmove, type, ent, SV_GenericHitSuperContentsMask(ent), skipsupercontentsmask, collision_extendmovelength.value); if(trace.fraction < 1 && trace.plane.normal[2] > 0.7) clip |= 1; // but we HAVE found a floor } @@ -2457,7 +2394,7 @@ static void SV_WalkMove (prvm_edict_t *ent) // move forward PRVM_serveredictvector(ent, velocity)[2] = 0; - clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask, 0); + clip = SV_FlyMove (ent, sv.frametime, applygravity, stepnormal, hitsupercontentsmask, skipsupercontentsmask, 0); PRVM_serveredictvector(ent, velocity)[2] += start_velocity[2]; if(clip & 8) { @@ -2554,10 +2491,6 @@ static void SV_Physics_Follow (prvm_edict_t *ent) vec3_t vf, vr, vu, angles, v; prvm_edict_t *e; - // regular thinking - if (!SV_RunThink (ent)) - return; - // LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects e = PRVM_PROG_TO_EDICT(PRVM_serveredictedict(ent, aiment)); if (PRVM_serveredictvector(e, angles)[0] == PRVM_serveredictvector(ent, punchangle)[0] && PRVM_serveredictvector(e, angles)[1] == PRVM_serveredictvector(ent, punchangle)[1] && PRVM_serveredictvector(e, angles)[2] == PRVM_serveredictvector(ent, punchangle)[2]) @@ -2778,10 +2711,14 @@ void SV_Physics_Toss (prvm_edict_t *ent) ent->priv.server->suspendedinairflag = true; VectorClear (PRVM_serveredictvector(ent, velocity)); VectorClear (PRVM_serveredictvector(ent, avelocity)); + movetime = 0; } else + { PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_ONGROUND; - movetime = 0; + if (!sv_gameplayfix_slidemoveprojectiles.integer) + movetime = 0; + } break; } } @@ -2830,7 +2767,7 @@ static void SV_Physics_Step (prvm_edict_t *ent) { PRVM_serveredictfloat(ent, flags) -= FL_ONGROUND; SV_CheckVelocity(ent); - SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0); + SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0, 0); SV_LinkEdict(ent); SV_LinkEdict_TouchAreaGrid(ent); ent->priv.server->waterposition_forceupdate = true; @@ -2842,7 +2779,7 @@ static void SV_Physics_Step (prvm_edict_t *ent) int hitsound = PRVM_serveredictvector(ent, velocity)[2] < sv_gravity.value * -0.1; SV_CheckVelocity(ent); - SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0); + SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent), 0, 0); SV_LinkEdict(ent); SV_LinkEdict_TouchAreaGrid(ent); @@ -2872,17 +2809,6 @@ static void SV_Physics_Step (prvm_edict_t *ent) ent->priv.server->waterposition_forceupdate = true; } } - -// regular thinking - if (!SV_RunThink(ent)) - return; - - if (ent->priv.server->waterposition_forceupdate || !VectorCompare(PRVM_serveredictvector(ent, origin), ent->priv.server->waterposition_origin)) - { - ent->priv.server->waterposition_forceupdate = false; - VectorCopy(PRVM_serveredictvector(ent, origin), ent->priv.server->waterposition_origin); - SV_CheckWaterTransition(ent); - } } //============================================================================ @@ -2912,7 +2838,8 @@ static void SV_Physics_Entity (prvm_edict_t *ent) SV_RunThink (ent); break; case MOVETYPE_FOLLOW: - SV_Physics_Follow (ent); + if(SV_RunThink(ent)) + SV_Physics_Follow (ent); break; case MOVETYPE_NOCLIP: if (SV_RunThink(ent)) @@ -2925,6 +2852,14 @@ static void SV_Physics_Entity (prvm_edict_t *ent) break; case MOVETYPE_STEP: SV_Physics_Step (ent); + // regular thinking + if (SV_RunThink(ent)) + if (ent->priv.server->waterposition_forceupdate || !VectorCompare(PRVM_serveredictvector(ent, origin), ent->priv.server->waterposition_origin)) + { + ent->priv.server->waterposition_forceupdate = false; + VectorCopy(PRVM_serveredictvector(ent, origin), ent->priv.server->waterposition_origin); + SV_CheckWaterTransition(ent); + } break; case MOVETYPE_WALK: if (SV_RunThink (ent)) @@ -2948,11 +2883,63 @@ static void SV_Physics_Entity (prvm_edict_t *ent) } break; default: + if((int) PRVM_serveredictfloat(ent, movetype) >= MOVETYPE_USER_FIRST && (int) PRVM_serveredictfloat(ent, movetype) <= MOVETYPE_USER_LAST) + break; Con_Printf ("SV_Physics: bad movetype %i\n", (int)PRVM_serveredictfloat(ent, movetype)); break; } } +static void SV_Physics_ClientEntity_NoThink (prvm_edict_t *ent) +{ + prvm_prog_t *prog = SVVM_prog; + + // don't run think at all, that is done during server frames + // instead, call the movetypes directly so they match client input + + // This probably only makes sense for CSQC-networked (SendEntity field set) player entities + switch ((int) PRVM_serveredictfloat(ent, movetype)) + { + case MOVETYPE_PUSH: + case MOVETYPE_FAKEPUSH: + // push physics relies heavily on think times and calls, and so cannot be predicted currently + Con_Printf ("SV_Physics_ClientEntity_NoThink: bad movetype %i\n", (int)PRVM_serveredictfloat(ent, movetype)); + break; + case MOVETYPE_NONE: + break; + case MOVETYPE_FOLLOW: + SV_Physics_Follow (ent); + break; + case MOVETYPE_NOCLIP: + VectorMA(PRVM_serveredictvector(ent, origin), sv.frametime, PRVM_serveredictvector(ent, velocity), PRVM_serveredictvector(ent, origin)); + VectorMA(PRVM_serveredictvector(ent, angles), sv.frametime, PRVM_serveredictvector(ent, avelocity), PRVM_serveredictvector(ent, angles)); + break; + case MOVETYPE_STEP: + SV_Physics_Step (ent); + break; + case MOVETYPE_WALK: + SV_WalkMove (ent); + break; + case MOVETYPE_TOSS: + case MOVETYPE_BOUNCE: + case MOVETYPE_BOUNCEMISSILE: + case MOVETYPE_FLYMISSILE: + SV_Physics_Toss (ent); + break; + case MOVETYPE_FLY: + case MOVETYPE_FLY_WORLDONLY: + SV_WalkMove (ent); + break; + case MOVETYPE_PHYSICS: + break; + default: + if((int) PRVM_serveredictfloat(ent, movetype) >= MOVETYPE_USER_FIRST && (int) PRVM_serveredictfloat(ent, movetype) <= MOVETYPE_USER_LAST) + break; + Con_Printf ("SV_Physics_ClientEntity_NoThink: bad movetype %i\n", (int)PRVM_serveredictfloat(ent, movetype)); + break; + } +} + void SV_Physics_ClientMove(void) { prvm_prog_t *prog = SVVM_prog; @@ -2973,8 +2960,9 @@ void SV_Physics_ClientMove(void) // make sure the velocity is sane (not a NaN) SV_CheckVelocity(ent); - // perform MOVETYPE_WALK behavior - SV_WalkMove (ent); + // perform movetype behaviour + // note: will always be MOVETYPE_WALK if disableclientprediction = 0 + SV_Physics_ClientEntity_NoThink (ent); // call standard player post-think, with frametime = 0 PRVM_serverglobalfloat(time) = sv.time; @@ -3086,16 +3074,29 @@ static void SV_Physics_ClientEntity(prvm_edict_t *ent) SV_RunThink (ent); break; case MOVETYPE_FOLLOW: - SV_Physics_Follow (ent); + SV_RunThink (ent); + if (host_client->clmovement_inputtimeout <= 0) // don't run physics here if running asynchronously + SV_Physics_Follow (ent); break; case MOVETYPE_NOCLIP: SV_RunThink(ent); - SV_CheckWater(ent); - VectorMA(PRVM_serveredictvector(ent, origin), sv.frametime, PRVM_serveredictvector(ent, velocity), PRVM_serveredictvector(ent, origin)); - VectorMA(PRVM_serveredictvector(ent, angles), sv.frametime, PRVM_serveredictvector(ent, avelocity), PRVM_serveredictvector(ent, angles)); + if (host_client->clmovement_inputtimeout <= 0) // don't run physics here if running asynchronously + { + SV_CheckWater(ent); + VectorMA(PRVM_serveredictvector(ent, origin), sv.frametime, PRVM_serveredictvector(ent, velocity), PRVM_serveredictvector(ent, origin)); + VectorMA(PRVM_serveredictvector(ent, angles), sv.frametime, PRVM_serveredictvector(ent, avelocity), PRVM_serveredictvector(ent, angles)); + } break; case MOVETYPE_STEP: - SV_Physics_Step (ent); + if (host_client->clmovement_inputtimeout <= 0) // don't run physics here if running asynchronously + SV_Physics_Step (ent); + if (SV_RunThink(ent)) + if (ent->priv.server->waterposition_forceupdate || !VectorCompare(PRVM_serveredictvector(ent, origin), ent->priv.server->waterposition_origin)) + { + ent->priv.server->waterposition_forceupdate = false; + VectorCopy(PRVM_serveredictvector(ent, origin), ent->priv.server->waterposition_origin); + SV_CheckWaterTransition(ent); + } break; case MOVETYPE_WALK: SV_RunThink (ent); @@ -3109,17 +3110,21 @@ static void SV_Physics_ClientEntity(prvm_edict_t *ent) case MOVETYPE_FLYMISSILE: // regular thinking SV_RunThink (ent); - SV_Physics_Toss (ent); + if (host_client->clmovement_inputtimeout <= 0) // don't run physics here if running asynchronously + SV_Physics_Toss (ent); break; case MOVETYPE_FLY: case MOVETYPE_FLY_WORLDONLY: SV_RunThink (ent); - SV_WalkMove (ent); + if (host_client->clmovement_inputtimeout <= 0) // don't run physics here if running asynchronously + SV_WalkMove (ent); break; case MOVETYPE_PHYSICS: SV_RunThink (ent); break; default: + if((int) PRVM_serveredictfloat(ent, movetype) >= MOVETYPE_USER_FIRST && (int) PRVM_serveredictfloat(ent, movetype) <= MOVETYPE_USER_LAST) + break; Con_Printf ("SV_Physics_ClientEntity: bad movetype %i\n", (int)PRVM_serveredictfloat(ent, movetype)); break; }