]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_collision.c
replaced sv_clmovement_waitforinput with sv_clmovement_inputtimeout
[xonotic/darkplaces.git] / cl_collision.c
index 0dae92c90f36e77784127beeb29347f1e72b8500..802b8adccc6b849cf39fe1fe1f05e7e66d869d21 100644 (file)
@@ -52,9 +52,12 @@ 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);
+               if (maxrealfrac < trace.realfraction)
+                       continue;
 
                //if (ent->model && ent->model->TraceBox)
-                       ent->model->TraceBox(ent->model, ent->frameblend[0].frame, &trace, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID);
+                       ent->model->TraceBox(ent->model, ent->frameblend[0].subframe, &trace, starttransformed, vec3_origin, vec3_origin, endtransformed, SUPERCONTENTS_SOLID);
 
                if (maxrealfrac > trace.realfraction)
                {
@@ -84,7 +87,7 @@ void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius)
                cl.worldmodel->brush.FindNonSolidLocation(cl.worldmodel, in, out, radius);
 }
 
-model_t *CL_GetModelByIndex(int modelindex)
+dp_model_t *CL_GetModelByIndex(int modelindex)
 {
        if(!modelindex)
                return NULL;
@@ -102,7 +105,7 @@ model_t *CL_GetModelByIndex(int modelindex)
        return NULL;
 }
 
-model_t *CL_GetModelFromEdict(prvm_edict_t *ed)
+dp_model_t *CL_GetModelFromEdict(prvm_edict_t *ed)
 {
        if (!ed || ed->priv.server->free)
                return NULL;
@@ -111,14 +114,62 @@ model_t *CL_GetModelFromEdict(prvm_edict_t *ed)
 
 void CL_LinkEdict(prvm_edict_t *ent)
 {
+       vec3_t mins, maxs;
+
        if (ent == prog->edicts)
                return;         // don't add the world
 
        if (ent->priv.server->free)
                return;
 
-       VectorAdd(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->absmin);
-       VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, ent->fields.client->absmax);
+       // set the abs box
+
+       if (ent->fields.client->solid == SOLID_BSP)
+       {
+               dp_model_t *model = CL_GetModelByIndex( (int)ent->fields.client->modelindex );
+               if (model == NULL)
+               {
+                       Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", PRVM_NUM_FOR_EDICT(ent));
+
+                       model = CL_GetModelByIndex( 0 );
+               }
+
+               if( model != NULL )
+               {
+                       if (!model->TraceBox && developer.integer >= 1)
+                               Con_Printf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
+
+                       if (ent->fields.client->angles[0] || ent->fields.client->angles[2] || ent->fields.client->avelocity[0] || ent->fields.client->avelocity[2])
+                       {
+                               VectorAdd(ent->fields.client->origin, model->rotatedmins, mins);
+                               VectorAdd(ent->fields.client->origin, model->rotatedmaxs, maxs);
+                       }
+                       else if (ent->fields.client->angles[1] || ent->fields.client->avelocity[1])
+                       {
+                               VectorAdd(ent->fields.client->origin, model->yawmins, mins);
+                               VectorAdd(ent->fields.client->origin, model->yawmaxs, maxs);
+                       }
+                       else
+                       {
+                               VectorAdd(ent->fields.client->origin, model->normalmins, mins);
+                               VectorAdd(ent->fields.client->origin, model->normalmaxs, maxs);
+                       }
+               }
+               else
+               {
+                       // SOLID_BSP with no model is valid, mainly because some QC setup code does so temporarily
+                       VectorAdd(ent->fields.client->origin, ent->fields.client->mins, mins);
+                       VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, maxs);
+               }
+       }
+       else
+       {
+               VectorAdd(ent->fields.client->origin, ent->fields.client->mins, mins);
+               VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, maxs);
+       }
+
+       VectorCopy(mins, ent->fields.client->absmin);
+       VectorCopy(maxs, ent->fields.client->absmax);
 
        World_LinkEdict(&cl.world, ent, ent->fields.client->absmin, ent->fields.client->absmax);
 }
@@ -140,6 +191,8 @@ int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
                }
                else if (passedict->fields.client->solid == SOLID_CORPSE)
                        return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
+               else if (passedict->fields.client->solid == SOLID_TRIGGER)
+                       return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
                else
                        return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
        }
@@ -152,7 +205,6 @@ int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 CL_Move
 ==================
 */
-extern cvar_t sv_debugmove;
 trace_t CL_Move(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)
 {
        vec3_t hullmins, hullmaxs;
@@ -174,7 +226,7 @@ trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        // matrices to transform into/out of other entity's space
        matrix4x4_t matrix, imatrix;
        // model of other entity
-       model_t *model;
+       dp_model_t *model;
        // list of entities to test for collisions
        int numtouchedicts;
        prvm_edict_t *touchedicts[MAX_EDICTS];
@@ -243,7 +295,7 @@ trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        // figure out whether this is a point trace for comparisons
        pointtrace = VectorCompare(clipmins, clipmaxs);
        // precalculate passedict's owner edict pointer for comparisons
-       traceowner = passedict ? PRVM_PROG_TO_EDICT(passedict->fields.client->owner) : 0;
+       traceowner = passedict ? PRVM_PROG_TO_EDICT(passedict->fields.client->owner) : NULL;
 
        // collide against network entities
        if (hitnetworkbrushmodels)
@@ -253,7 +305,7 @@ trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
                        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->frame, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask);
+                       Collision_ClipToGenericEntity(&trace, ent->model, ent->frameblend[0].subframe, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask);
                        if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
@@ -265,12 +317,33 @@ trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        {
                vec3_t origin, entmins, entmaxs;
                matrix4x4_t entmatrix, entinversematrix;
-               for (i = 1;i < cl.maxclients+1;i++)
+
+               if(gamemode == GAME_NEXUIZ)
+               {
+                       // 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)
+                               goto skipnetworkplayers;
+               }
+
+               for (i = 1;i <= cl.maxclients;i++)
                {
                        entity_render_t *ent = &cl.entities[i].render;
+
                        // don't hit ourselves
                        if (i == cl.playerentity)
                                continue;
+
+                       // don't hit players that don't exist
+                       if (!cl.scores[i-1].name[0])
+                               continue;
+
+                       if(gamemode == GAME_NEXUIZ)
+                       {
+                               // don't hit spectators or nonsolid players
+                               if(cl.scores[i-1].frags == -666 || cl.scores[i-1].frags == -616)
+                                       continue;
+                       }
+
                        Matrix4x4_OriginFromMatrix(&ent->matrix, origin);
                        VectorAdd(origin, cl.playerstandmins, entmins);
                        VectorAdd(origin, cl.playerstandmaxs, entmaxs);
@@ -283,6 +356,9 @@ trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
                }
+
+skipnetworkplayers:
+               ;
        }
 
        // clip to entities
@@ -334,7 +410,7 @@ trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
                        unsigned int modelindex = (unsigned int)touch->fields.client->modelindex;
                        // if the modelindex is 0, it shouldn't be SOLID_BSP!
                        if (modelindex > 0 && modelindex < MAX_MODELS)
-                               model = sv.models[(int)touch->fields.client->modelindex];
+                               model = cl.model_precache[(int)touch->fields.client->modelindex];
                }
                if (model)
                        Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.client->origin[0], touch->fields.client->origin[1], touch->fields.client->origin[2], touch->fields.client->angles[0], touch->fields.client->angles[1], touch->fields.client->angles[2], 1);
@@ -342,9 +418,9 @@ trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
                        Matrix4x4_CreateTranslate(&matrix, touch->fields.client->origin[0], touch->fields.client->origin[1], touch->fields.client->origin[2]);
                Matrix4x4_Invert_Simple(&imatrix, &matrix);
                if ((int)touch->fields.client->flags & FL_MONSTER)
-                       Collision_ClipToGenericEntity(&trace, model, touch->fields.client->frame, touch->fields.client->mins, touch->fields.client->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
+                       Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.client->frame, touch->fields.client->mins, touch->fields.client->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
                else
-                       Collision_ClipToGenericEntity(&trace, model, touch->fields.client->frame, touch->fields.client->mins, touch->fields.client->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
+                       Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.client->frame, touch->fields.client->mins, touch->fields.client->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
 
                if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
                        *hitnetworkentity = 0;