]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_collision.c
Fix setinfo.
[xonotic/darkplaces.git] / cl_collision.c
index 05b1a799dc0eb592b4d62d55c7a16993e56b713c..eb7a4dd923517688357fb72500d0ff00cd11124f 100644 (file)
@@ -2,47 +2,27 @@
 #include "quakedef.h"
 #include "cl_collision.h"
 
-#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
-float CL_SelectTraceLine(const vec3_t start, const vec3_t pEnd, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent)
-#else
 float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent)
-#endif
 {
-       float maxfrac, maxrealfrac;
+       float maxfrac;
        int n;
        entity_render_t *ent;
        vec_t tracemins[3], tracemaxs[3];
        trace_t trace;
        vec_t tempnormal[3], starttransformed[3], endtransformed[3];
-#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
-       vec3_t end;
-       vec_t len = 0;
-
-       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);
-#endif
 
        memset (&trace, 0 , sizeof(trace_t));
        trace.fraction = 1;
-       trace.realfraction = 1;
        VectorCopy (end, trace.endpos);
 
        if (hitent)
                *hitent = 0;
        if (cl.worldmodel && cl.worldmodel->TraceLine)
-               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, start, end, SUPERCONTENTS_SOLID);
+               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, start, end, SUPERCONTENTS_SOLID, 0, 0);
 
        if (normal)
                VectorCopy(trace.plane.normal, normal);
        maxfrac = trace.fraction;
-       maxrealfrac = trace.realfraction;
 
        tracemins[0] = min(start[0], end[0]);
        tracemaxs[0] = max(start[0], end[0]);
@@ -70,22 +50,17 @@ float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, ve
                        continue;
                Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
                Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
-               Collision_ClipTrace_Box(&trace, ent->model->normalmins, ent->model->normalmaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID, SUPERCONTENTS_SOLID, 0, NULL);
-#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
-               if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
-                       Collision_ShortenTrace(&trace, len / (len + collision_endposnudge.value), pEnd);
-#endif
-               if (maxrealfrac < trace.realfraction)
+               Collision_ClipTrace_Box(&trace, ent->model->normalmins, ent->model->normalmaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID, 0, 0, SUPERCONTENTS_SOLID, 0, NULL);
+               if (maxfrac < trace.fraction)
                        continue;
 
-               ent->model->TraceLine(ent->model, ent->frameblend, ent->skeleton, &trace, starttransformed, endtransformed, SUPERCONTENTS_SOLID);
+               ent->model->TraceLine(ent->model, ent->frameblend, ent->skeleton, &trace, starttransformed, endtransformed, SUPERCONTENTS_SOLID, 0, 0);
 
-               if (maxrealfrac > trace.realfraction)
+               if (maxfrac > trace.fraction)
                {
                        if (hitent)
                                *hitent = n;
                        maxfrac = trace.fraction;
-                       maxrealfrac = trace.realfraction;
                        if (normal)
                        {
                                VectorCopy(trace.plane.normal, tempnormal);
@@ -228,7 +203,7 @@ int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 CL_Move
 ==================
 */
-trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
+trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
 {
        prvm_prog_t *prog = CLVM_prog;
        int i, bodysupercontents;
@@ -264,8 +239,8 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
 #endif
 
        // clip to world
-       Collision_ClipPointToWorld(&cliptrace, cl.worldmodel, clipstart, hitsupercontentsmask);
-       cliptrace.bmodelstartsolid = cliptrace.startsolid;
+       Collision_ClipPointToWorld(&cliptrace, cl.worldmodel, clipstart, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
+       cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
        if (type == MOVE_WORLDONLY)
@@ -313,8 +288,8 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                        entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                        if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                                continue;
-                       Collision_ClipPointToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, hitsupercontentsmask);
-                       if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+                       Collision_ClipPointToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
+                       if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
                }
@@ -326,7 +301,7 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                vec3_t origin, entmins, entmaxs;
                matrix4x4_t entmatrix, entinversematrix;
 
-               if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
+               if(IS_OLDNEXUIZ_DERIVED(gamemode))
                {
                        // don't hit network players, if we are a nonsolid player
                        if(cl.scores[cl.playerentity-1].frags == -666 || cl.scores[cl.playerentity-1].frags == -616)
@@ -342,10 +317,12 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                                continue;
 
                        // don't hit players that don't exist
+                       if (!cl.entities_active[i])
+                               continue;
                        if (!cl.scores[i-1].name[0])
                                continue;
 
-                       if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
+                       if(IS_OLDNEXUIZ_DERIVED(gamemode))
                        {
                                // don't hit spectators or nonsolid players
                                if(cl.scores[i-1].frags == -666 || cl.scores[i-1].frags == -616)
@@ -359,8 +336,8 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
                                continue;
                        Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
                        Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
-                       Collision_ClipPointToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, hitsupercontentsmask);
-                       if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+                       Collision_ClipPointToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
+                       if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
                }
@@ -423,11 +400,11 @@ skipnetworkplayers:
                VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
                VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
                if ((int)PRVM_clientedictfloat(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, skipmaterialflagsmask, 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, skipmaterialflagsmask);
 
-               if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+               if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                        *hitnetworkentity = 0;
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(touch, solid) == SOLID_BSP);
        }
@@ -441,11 +418,7 @@ finished:
 CL_TraceLine
 ==================
 */
-#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
-trace_t CL_TraceLine(const vec3_t start, const vec3_t pEnd, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
-#else
-trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
-#endif
+trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
 {
        prvm_prog_t *prog = CLVM_prog;
        int i, bodysupercontents;
@@ -469,26 +442,8 @@ trace_t CL_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 CL_TracePoint(start, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
-
-       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 CL_TracePoint(start, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
-#endif
+               return CL_TracePoint(start, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
 
        if (hitnetworkentity)
                *hitnetworkentity = 0;
@@ -502,8 +457,8 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
 #endif
 
        // clip to world
-       Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, hitsurfaces);
-       cliptrace.bmodelstartsolid = cliptrace.startsolid;
+       Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
+       cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
        if (type == MOVE_WORLDONLY)
@@ -551,8 +506,8 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                        entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                        if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                                continue;
-                       Collision_ClipLineToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, hitsurfaces);
-                       if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+                       Collision_ClipLineToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
+                       if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
                }
@@ -564,7 +519,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                vec3_t origin, entmins, entmaxs;
                matrix4x4_t entmatrix, entinversematrix;
 
-               if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
+               if(IS_OLDNEXUIZ_DERIVED(gamemode))
                {
                        // don't hit network players, if we are a nonsolid player
                        if(cl.scores[cl.playerentity-1].frags == -666 || cl.scores[cl.playerentity-1].frags == -616)
@@ -580,10 +535,12 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                                continue;
 
                        // don't hit players that don't exist
+                       if (!cl.entities_active[i])
+                               continue;
                        if (!cl.scores[i-1].name[0])
                                continue;
 
-                       if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
+                       if(IS_OLDNEXUIZ_DERIVED(gamemode))
                        {
                                // don't hit spectators or nonsolid players
                                if(cl.scores[i-1].frags == -666 || cl.scores[i-1].frags == -616)
@@ -597,8 +554,8 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                                continue;
                        Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
                        Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
-                       Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask, hitsurfaces);
-                       if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+                       Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
+                       if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
                }
@@ -661,20 +618,16 @@ skipnetworkplayers:
                VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
                VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
                if (type == MOVE_MISSILE && (int)PRVM_clientedictfloat(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, skipmaterialflagsmask, extend);
                else
-                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, hitsurfaces);
+                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touchmins, touchmaxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitsurfaces);
 
-               if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+               if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                        *hitnetworkentity = 0;
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(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;
 }
 
@@ -683,11 +636,7 @@ finished:
 CL_Move
 ==================
 */
-#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
-trace_t CL_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, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
-#else
-trace_t CL_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, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
-#endif
+trace_t CL_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, int skipmaterialflagsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
 {
        prvm_prog_t *prog = CLVM_prog;
        vec3_t hullmins, hullmaxs;
@@ -715,46 +664,18 @@ trace_t CL_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 = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
-               else
-                       trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, false);
-               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 = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
+                       trace = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
                else
-                       trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, false);
+                       trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, false);
                VectorSubtract(trace.endpos, mins, trace.endpos);
                return trace;
        }
-#endif
 
        if (hitnetworkentity)
                *hitnetworkentity = 0;
@@ -770,8 +691,8 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 #endif
 
        // clip to world
-       Collision_ClipToWorld(&cliptrace, cl.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
-       cliptrace.bmodelstartsolid = cliptrace.startsolid;
+       Collision_ClipToWorld(&cliptrace, cl.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
+       cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
        if (type == MOVE_WORLDONLY)
@@ -830,8 +751,8 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                        entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                        if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                                continue;
-                       Collision_ClipToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask);
-                       if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+                       Collision_ClipToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
+                       if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
                }
@@ -843,7 +764,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                vec3_t origin, entmins, entmaxs;
                matrix4x4_t entmatrix, entinversematrix;
 
-               if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
+               if(IS_OLDNEXUIZ_DERIVED(gamemode))
                {
                        // don't hit network players, if we are a nonsolid player
                        if(cl.scores[cl.playerentity-1].frags == -666 || cl.scores[cl.playerentity-1].frags == -616)
@@ -859,10 +780,12 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                                continue;
 
                        // don't hit players that don't exist
+                       if (!cl.entities_active[i])
+                               continue;
                        if (!cl.scores[i-1].name[0])
                                continue;
 
-                       if(gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
+                       if(IS_OLDNEXUIZ_DERIVED(gamemode))
                        {
                                // don't hit spectators or nonsolid players
                                if(cl.scores[i-1].frags == -666 || cl.scores[i-1].frags == -616)
@@ -876,8 +799,8 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                                continue;
                        Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
                        Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
-                       Collision_ClipToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask);
-                       if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+                       Collision_ClipToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend);
+                       if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
                }
@@ -940,20 +863,16 @@ skipnetworkplayers:
                VectorCopy(PRVM_clientedictvector(touch, mins), touchmins);
                VectorCopy(PRVM_clientedictvector(touch, maxs), touchmaxs);
                if ((int)PRVM_clientedictfloat(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, skipmaterialflagsmask, 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, skipmaterialflagsmask, extend);
 
-               if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+               if (cliptrace.fraction > trace.fraction && hitnetworkentity)
                        *hitnetworkentity = 0;
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(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;
 }
 
@@ -962,11 +881,7 @@ finished:
 CL_Cache_TraceLine
 ==================
 */
-#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
-trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t pEnd, int type, int hitsupercontentsmask)
-#else
-trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask)
-#endif
+trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
 {
        prvm_prog_t *prog = CLVM_prog;
        int i;
@@ -985,20 +900,6 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int typ
        // 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(collision_endposnudge.value > 0 && !VectorCompare(start, pEnd))
-       {
-               // 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);
-#endif
 
        VectorCopy(start, clipstart);
        VectorCopy(end, clipend);
@@ -1007,8 +908,8 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int typ
 #endif
 
        // clip to world
-       Collision_Cache_ClipLineToWorldSurfaces(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask);
-       cliptrace.bmodelstartsolid = cliptrace.startsolid;
+       Collision_Cache_ClipLineToWorldSurfaces(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
+       cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
        if (type == MOVE_WORLDONLY)
@@ -1031,7 +932,7 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int typ
                entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                        continue;
-               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, ent->model, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask);
+               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, ent->model, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
                Collision_CombineTraces(&cliptrace, &trace, NULL, true);
        }
 
@@ -1058,22 +959,18 @@ trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int typ
                model = CL_GetModelFromEdict(touch);
                if (!model)
                        continue;
-               // animated models are too slow to collide against and can't be cached
-               if (touch->priv.server->frameblend || touch->priv.server->skeleton.relativetransforms)
+               // animated models are not suitable for caching
+               if ((touch->priv.server->frameblend && (touch->priv.server->frameblend[0].lerp != 1.0 || touch->priv.server->frameblend[0].subframe != 0)) || touch->priv.server->skeleton.relativetransforms)
                        continue;
                if (type == MOVE_NOMONSTERS && PRVM_clientedictfloat(touch, solid) != SOLID_BSP)
                        continue;
                Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_clientedictvector(touch, origin)[0], PRVM_clientedictvector(touch, origin)[1], PRVM_clientedictvector(touch, origin)[2], PRVM_clientedictvector(touch, angles)[0], PRVM_clientedictvector(touch, angles)[1], PRVM_clientedictvector(touch, angles)[2], 1);
                Matrix4x4_Invert_Simple(&imatrix, &matrix);
-               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, model, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask);
+               Collision_Cache_ClipLineToGenericEntitySurfaces(&trace, model, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask);
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, PRVM_clientedictfloat(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;
 }