]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
added DP_QC_TRACE_MOVETYPE_HITMODEL extension (and added DP_QC_TRACE_MOVETYPE_WORLDON...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 11 Oct 2003 05:34:49 +0000 (05:34 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 11 Oct 2003 05:34:49 +0000 (05:34 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3572 d7cf8633-e32d-0410-b094-e92efae38249

cl_collision.c
cl_main.c
model_alias.c
model_brush.c
model_shared.h
pr_cmds.c
snd_dma.c
sv_main.c
world.c
world.h

index ce613001f3e9f066bdc680a70aca4c402eeff878..3a842bc8a4b5d9290ff6866c962d3e681ed6b40e 100644 (file)
@@ -44,8 +44,8 @@ float CL_TraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t n
        if (hitent)
                *hitent = &cl_entities[0].render;
        Mod_CheckLoaded(cl.worldmodel);
-       if (cl.worldmodel && cl.worldmodel->brush.TraceBox)
-               cl.worldmodel->brush.TraceBox(cl.worldmodel, &trace, start, start, end, end, hitsupercontentsmask);
+       if (cl.worldmodel && cl.worldmodel->TraceBox)
+               cl.worldmodel->TraceBox(cl.worldmodel, 0, &trace, start, start, end, end, hitsupercontentsmask);
 
        if (impact)
                VectorLerp(start, trace.fraction, end, impact);
@@ -77,8 +77,8 @@ float CL_TraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t n
                        Matrix4x4_Transform(&imatrix, start, starttransformed);
                        Matrix4x4_Transform(&imatrix, end, endtransformed);
 
-                       if (ent->model && ent->model->brush.TraceBox)
-                               ent->model->brush.TraceBox(ent->model, &trace, starttransformed, starttransformed, endtransformed, endtransformed, hitsupercontentsmask);
+                       if (ent->model && ent->model->TraceBox)
+                               ent->model->TraceBox(ent->model, 0, &trace, starttransformed, starttransformed, endtransformed, endtransformed, hitsupercontentsmask);
 
                        cl_traceline_startsupercontents |= trace.startsupercontents;
                        if (maxfrac > trace.fraction)
index ace38eedc93f5a07c1a068538016cbb0ea305bc2..d67183929a497b4fee32b7e82aa5270f070d0bbf 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -794,7 +794,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                // as soon as player is known we can call V_CalcRefDef
                if ((e - cl_entities) == cl.viewentity)
                        V_CalcRefdef();
-               if (e->render.model && e->render.model->name[0] == '*' && e->render.model->brush.TraceBox)
+               if (e->render.model && e->render.model->name[0] == '*' && e->render.model->TraceBox)
                        cl_brushmodel_entities[cl_num_brushmodel_entities++] = &e->render;
                // don't show entities with no modelindex (note: this still shows
                // entities which have a modelindex that resolved to a NULL model)
index 6ef693b0d0979ccca3b40b453af4f7b699a1c9fc..e3c0345c650ae1a568f4f17e7b18437679a4c4ba 100644 (file)
@@ -26,6 +26,49 @@ void Mod_AliasInit (void)
 {
 }
 
+static void Mod_MDLMD2MD3_TraceBox(model_t *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
+{
+       int i, framenum;
+       float segmentmins[3], segmentmaxs[3];
+       colbrushf_t *thisbrush_start, *thisbrush_end;
+       matrix4x4_t startmatrix, endmatrix;
+       memset(trace, 0, sizeof(*trace));
+       trace->fraction = 1;
+       trace->hitsupercontentsmask = hitsupercontentsmask;
+       segmentmins[0] = min(boxstartmins[0], boxendmins[0]);
+       segmentmins[1] = min(boxstartmins[1], boxendmins[1]);
+       segmentmins[2] = min(boxstartmins[2], boxendmins[2]);
+       segmentmaxs[0] = max(boxstartmaxs[0], boxendmaxs[0]);
+       segmentmaxs[1] = max(boxstartmaxs[1], boxendmaxs[1]);
+       segmentmaxs[2] = max(boxstartmaxs[2], boxendmaxs[2]);
+       if (VectorCompare(boxstartmins, boxstartmaxs) && VectorCompare(boxendmins, boxendmaxs))
+       {
+               // line trace
+               for (i = 0;i < model->alias.aliasnum_meshes;i++)
+               {
+                       framenum = frame;
+                       if (framenum < 0 || framenum > model->alias.aliasdata_meshes[i].num_frames)
+                               framenum = 0;
+                       Collision_TraceLineTriangleMeshFloat(trace, boxstartmins, boxendmins, model->alias.aliasdata_meshes[i].num_triangles, model->alias.aliasdata_meshes[i].data_element3i, model->alias.aliasdata_meshes[i].data_aliasvertex3f + framenum * model->alias.aliasdata_meshes[i].num_vertices * 3, SUPERCONTENTS_SOLID, segmentmins, segmentmaxs);
+               }
+       }
+       else
+       {
+               // box trace, performed as brush trace
+               Matrix4x4_CreateIdentity(&startmatrix);
+               Matrix4x4_CreateIdentity(&endmatrix);
+               thisbrush_start = Collision_BrushForBox(&startmatrix, boxstartmins, boxstartmaxs);
+               thisbrush_end = Collision_BrushForBox(&endmatrix, boxendmins, boxendmaxs);
+               for (i = 0;i < model->alias.aliasnum_meshes;i++)
+               {
+                       framenum = frame;
+                       if (framenum < 0 || framenum > model->alias.aliasdata_meshes[i].num_frames)
+                               framenum = 0;
+                       Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, model->alias.aliasdata_meshes[i].num_triangles, model->alias.aliasdata_meshes[i].data_element3i, model->alias.aliasdata_meshes[i].data_aliasvertex3f + framenum * model->alias.aliasdata_meshes[i].num_vertices * 3, SUPERCONTENTS_SOLID, segmentmins, segmentmaxs);
+               }
+       }
+}
+
 static void Mod_CalcAliasModelBBoxes (void)
 {
        int vnum, meshnum;
@@ -305,6 +348,7 @@ void Mod_IDP0_Load(model_t *mod, void *buffer)
        loadmodel->Draw = R_Model_Alias_Draw;
        loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
        loadmodel->DrawLight = R_Model_Alias_DrawLight;
+       loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
 
        loadmodel->alias.aliasnum_meshes = 1;
        loadmodel->alias.aliasdata_meshes = Mem_Alloc(loadmodel->mempool, sizeof(aliasmesh_t));
@@ -607,6 +651,7 @@ void Mod_IDP2_Load(model_t *mod, void *buffer)
        loadmodel->Draw = R_Model_Alias_Draw;
        loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
        loadmodel->DrawLight = R_Model_Alias_DrawLight;
+       loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
 
        if (LittleLong(pinmodel->num_tris) < 1 || LittleLong(pinmodel->num_tris) > (65536 / 3))
                Host_Error ("%s has invalid number of triangles: %i", loadmodel->name, LittleLong(pinmodel->num_tris));
@@ -827,6 +872,7 @@ void Mod_IDP3_Load(model_t *mod, void *buffer)
        loadmodel->Draw = R_Model_Alias_Draw;
        loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
        loadmodel->DrawLight = R_Model_Alias_DrawLight;
+       loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
        loadmodel->flags = LittleLong(pinmodel->flags);
        loadmodel->synctype = ST_RAND;
 
index bf061151edbf31ec013cdce9dfbb932f2e4e1434..e927d009b90d0442b4029699aee9cbe15d91da46 100644 (file)
@@ -509,7 +509,7 @@ loc0:
        return HULLCHECKSTATE_DONE;
 }
 
-static void Mod_Q1BSP_TraceBox(struct model_s *model, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
+static void Mod_Q1BSP_TraceBox(struct model_s *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
 {
        // this function currently only supports same size start and end
        double boxsize[3];
@@ -2660,6 +2660,8 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer)
                Host_Error("Mod_Q1BSP_Load: %s has wrong version number(%i should be %i(Quake) or 30(HalfLife))", mod->name, i, BSPVERSION);
        mod->brush.ishlbsp = i == 30;
 
+       mod->soundfromcenter = true;
+       mod->TraceBox = Mod_Q1BSP_TraceBox;
        mod->brush.SuperContentsFromNativeContents = Mod_Q1BSP_SuperContentsFromNativeContents;
        mod->brush.NativeContentsFromSuperContents = Mod_Q1BSP_NativeContentsFromSuperContents;
        mod->brush.GetPVS = Mod_Q1BSP_GetPVS;
@@ -2667,7 +2669,6 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer)
        mod->brush.BoxTouchingPVS = Mod_Q1BSP_BoxTouchingPVS;
        mod->brush.LightPoint = Mod_Q1BSP_LightPoint;
        mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation;
-       mod->brush.TraceBox = Mod_Q1BSP_TraceBox;
        mod->brush.AmbientSoundLevelsForPoint = Mod_Q1BSP_AmbientSoundLevelsForPoint;
        mod->brush.RoundUpToHullSize = Mod_Q1BSP_RoundUpToHullSize;
        mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
@@ -4377,7 +4378,7 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, q3mnode_t *nod
        }
 }
 
-static void Mod_Q3BSP_TraceBox(model_t *model, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
+static void Mod_Q3BSP_TraceBox(model_t *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
 {
        int i;
        float segmentmins[3], segmentmaxs[3];
@@ -4589,6 +4590,8 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer)
                R_ResetQuakeSky();
        }
 
+       mod->soundfromcenter = true;
+       mod->TraceBox = Mod_Q3BSP_TraceBox;
        mod->brush.SuperContentsFromNativeContents = Mod_Q3BSP_SuperContentsFromNativeContents;
        mod->brush.NativeContentsFromSuperContents = Mod_Q3BSP_NativeContentsFromSuperContents;
        mod->brush.GetPVS = Mod_Q3BSP_GetPVS;
@@ -4596,7 +4599,6 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer)
        mod->brush.BoxTouchingPVS = Mod_Q3BSP_BoxTouchingPVS;
        mod->brush.LightPoint = Mod_Q3BSP_LightPoint;
        mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation;
-       mod->brush.TraceBox = Mod_Q3BSP_TraceBox;
        //mod->DrawSky = R_Q3BSP_DrawSky;
        mod->Draw = R_Q3BSP_Draw;
        mod->DrawShadowVolume = R_Q3BSP_DrawShadowVolume;
index d1d11e2355fdecfd21cf07625b2b046a0dde1bcc..cb8a15015a494bb5a87a7a3fd9cdf8d78dfc8bba 100644 (file)
@@ -159,7 +159,6 @@ typedef struct model_brush_s
        int (*BoxTouchingPVS)(struct model_s *model, const qbyte *pvs, const vec3_t mins, const vec3_t maxs);
        void (*LightPoint)(struct model_s *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal);
        void (*FindNonSolidLocation)(struct model_s *model, const vec3_t in, vec3_t out, vec_t radius);
-       void (*TraceBox)(struct model_s *model, struct trace_s *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask);
        // these are actually only found on brushq1, but NULL is handled gracefully
        void (*AmbientSoundLevelsForPoint)(struct model_s *model, const vec3_t p, qbyte *out, int outsize);
        void (*RoundUpToHullSize)(struct model_s *cmodel, const vec3_t inmins, const vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs);
@@ -517,6 +516,8 @@ typedef struct model_s
        void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
        // draw the lighting on a model (through stencil)
        void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+       // trace a box against this model
+       void (*TraceBox)(struct model_s *model, int frame, struct trace_s *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask);
        // fields belonging to each type of model
        model_alias_t   alias;
        model_sprite_t  sprite;
@@ -528,6 +529,8 @@ typedef struct model_s
        model_brushq3_t brushq3;
        // skin files can have different tags for each skin
        overridetagnameset_t    *data_overridetagnamesforskin;
+       // flags this model for offseting sounds to the model center (used by brush models)
+       int soundfromcenter;
 }
 model_t;
 
index d9762d83c28f0fe0203dcb7429bad32d5a529b3f..a7468f0a39368aff17728db196df3077e7b04638 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -107,6 +107,8 @@ char *ENGINE_EXTENSIONS =
 "DP_QC_SINCOSSQRTPOW "
 "DP_QC_TRACEBOX "
 "DP_QC_TRACETOSS "
+"DP_QC_TRACE_MOVETYPE_WORLDONLY "
+"DP_QC_TRACE_MOVETYPE_HITMODEL "
 "DP_QC_VECTORVECTORS "
 "DP_QUAKE2_MODEL "
 "DP_QUAKE3_MODEL "
index 8e749b695615dd649fe54d7293963f16cab97159..68f33488da269bf2dacce3352fff6d5b016bc094 100644 (file)
--- a/snd_dma.c
+++ b/snd_dma.c
@@ -401,7 +401,7 @@ void SND_Spatialize(channel_t *ch, int isstatic)
                {
                        //Con_Printf("-- entnum %i origin %f %f %f neworigin %f %f %f\n", ch->entnum, ch->origin[0], ch->origin[1], ch->origin[2], cl_entities[ch->entnum].state_current.origin[0], cl_entities[ch->entnum].state_current.origin[1], cl_entities[ch->entnum].state_current.origin[2]);
                        VectorCopy(cl_entities[ch->entnum].state_current.origin, ch->origin);
-                       if (cl_entities[ch->entnum].state_current.modelindex && cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->brush.TraceBox)
+                       if (cl_entities[ch->entnum].state_current.modelindex && cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->soundfromcenter)
                                VectorMAMAM(1.0f, ch->origin, 0.5f, cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->normalmins, 0.5f, cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->normalmaxs, ch->origin);
                }
 
index 8332e7351d658b79f4e02bf11fa921f04d427e7b..4470a753ccc338f78dd24f9c26da11f6e1328d1a 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -505,14 +505,14 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                        }
 
                        // don't try to cull embedded brush models with this, they're sometimes huge (spanning several rooms)
-                       if (sv_cullentities_trace.integer && (model == NULL || model->brush.TraceBox == NULL || model->name[0] != '*'))
+                       if (sv_cullentities_trace.integer && (model == NULL || model->name[0] != '*'))
                        {
                                // LordHavoc: test random offsets, to maximize chance of detection
                                testorigin[0] = lhrandom(entmins[0], entmaxs[0]);
                                testorigin[1] = lhrandom(entmins[1], entmaxs[1]);
                                testorigin[2] = lhrandom(entmins[2], entmaxs[2]);
 
-                               sv.worldmodel->brush.TraceBox(sv.worldmodel, &trace, testeye, testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                               sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, testeye, testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
                                if (trace.fraction == 1)
                                        client->visibletime[e] = realtime + 1;
                                else
@@ -522,7 +522,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                                        testorigin[1] = bound(entmins[1], testeye[1], entmaxs[1]);
                                        testorigin[2] = bound(entmins[2], testeye[2], entmaxs[2]);
 
-                                       sv.worldmodel->brush.TraceBox(sv.worldmodel, &trace, testeye, testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                                       sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, testeye, testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
                                        if (trace.fraction == 1)
                                                client->visibletime[e] = realtime + 1;
                                        else if (realtime > client->visibletime[e])
@@ -929,7 +929,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                                testorigin[0] = (entmins[0] + entmaxs[0]) * 0.5f;
                                testorigin[1] = (entmins[1] + entmaxs[1]) * 0.5f;
                                testorigin[2] = (entmins[2] + entmaxs[2]) * 0.5f;
-                               sv.worldmodel->brush.TraceBox(sv.worldmodel, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                               sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
                                if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, entmins, entmaxs))
                                        sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
                                else
@@ -938,7 +938,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                                        testorigin[0] = lhrandom(entmins[0], entmaxs[0]);
                                        testorigin[1] = lhrandom(entmins[1], entmaxs[1]);
                                        testorigin[2] = lhrandom(entmins[2], entmaxs[2]);
-                                       sv.worldmodel->brush.TraceBox(sv.worldmodel, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                                       sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
                                        if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, entmins, entmaxs))
                                                sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
                                        else
@@ -949,7 +949,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                                                        testorigin[0] = lhrandom(lightmins[0], lightmaxs[0]);
                                                        testorigin[1] = lhrandom(lightmins[1], lightmaxs[1]);
                                                        testorigin[2] = lhrandom(lightmins[2], lightmaxs[2]);
-                                                       sv.worldmodel->brush.TraceBox(sv.worldmodel, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                                                       sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
                                                        if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, entmins, entmaxs))
                                                                sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
                                                }
diff --git a/world.c b/world.c
index 7310d90db1a947dd6451fbb27ac7b2d5e41ce9a6..78c3af3bade27d294441fe99ae243f52a12eebf6 100644 (file)
--- a/world.c
+++ b/world.c
@@ -342,8 +342,8 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                if (model != NULL)
                {
                        Mod_CheckLoaded(model);
-                       if (!model->brush.TraceBox)
-                               Host_Error("SOLID_BSP with non-BSP model\n");
+                       if (!model->TraceBox)
+                               Host_Error("SOLID_BSP with non-collidable model\n");
 
                        if (ent->v->angles[0] || ent->v->angles[2] || ent->v->avelocity[0] || ent->v->avelocity[2])
                        {
@@ -448,7 +448,7 @@ Handles selection or creation of a clipping hull, and offseting (and
 eventually rotation) of the end points
 ==================
 */
-trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end)
+trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int movetype)
 {
        int i;
        trace_t trace;
@@ -457,7 +457,7 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
        float tempnormal[3], starttransformed[3], endtransformed[3];
        float starttransformedmins[3], starttransformedmaxs[3], endtransformedmins[3], endtransformedmaxs[3];
 
-       if ((int) ent->v->solid == SOLID_BSP)
+       if ((int) ent->v->solid == SOLID_BSP || movetype == MOVE_HITMODEL)
        {
                i = ent->v->modelindex;
                if ((unsigned int) i >= MAX_MODELS)
@@ -467,14 +467,17 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
                        Host_Error("SV_ClipMoveToEntity: invalid modelindex\n");
 
                Mod_CheckLoaded(model);
-               if (!model->brush.TraceBox)
+               if ((int) ent->v->solid == SOLID_BSP)
                {
-                       Con_Printf ("SV_ClipMoveToEntity: SOLID_BSP with a non bsp model, entity dump:\n");
-                       ED_Print (ent);
-                       Host_Error ("SV_ClipMoveToEntity: SOLID_BSP with a non bsp model\n");
+                       if (!model->TraceBox)
+                       {
+                               Con_Printf("SV_ClipMoveToEntity: SOLID_BSP with a non-collidable model, entity dump:\n");
+                               ED_Print(ent);
+                               Host_Error("SV_ClipMoveToEntity: SOLID_BSP with a non-collidable model\n");
+                       }
+                       if (ent->v->movetype != MOVETYPE_PUSH)
+                               Host_Error("SV_ClipMoveToEntity: SOLID_BSP without MOVETYPE_PUSH");
                }
-               if (ent->v->movetype != MOVETYPE_PUSH)
-                       Host_Error ("SV_ClipMoveToEntity: SOLID_BSP without MOVETYPE_PUSH");
        }
 
        Matrix4x4_CreateFromQuakeEntity(&matrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], ent->v->angles[0], ent->v->angles[1], ent->v->angles[2], 1);
@@ -482,13 +485,16 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
        Matrix4x4_Transform(&imatrix, start, starttransformed);
        Matrix4x4_Transform(&imatrix, end, endtransformed);
 
-       if (model && model->brush.TraceBox)
+       if (model && model->TraceBox)
        {
+               int frame;
+               frame = (int)ent->v->frame;
+               frame = bound(0, frame, (model->numframes - 1));
                VectorAdd(starttransformed, maxs, starttransformedmaxs);
                VectorAdd(endtransformed, maxs, endtransformedmaxs);
                VectorAdd(starttransformed, mins, starttransformedmins);
                VectorAdd(endtransformed, mins, endtransformedmins);
-               model->brush.TraceBox(model, &trace, starttransformedmins, starttransformedmaxs, endtransformedmins, endtransformedmaxs, SUPERCONTENTS_SOLID);
+               model->TraceBox(model, frame, &trace, starttransformedmins, starttransformedmaxs, endtransformedmins, endtransformedmaxs, SUPERCONTENTS_SOLID);
        }
        else
                Collision_ClipTrace_Box(&trace, ent->v->mins, ent->v->maxs, starttransformed, mins, maxs, endtransformed, SUPERCONTENTS_SOLID, SUPERCONTENTS_SOLID);
@@ -564,11 +570,11 @@ void SV_ClipToNode(moveclip_t *clip, link_t *list)
 
                // might interact, so do an exact clip
                if (touch->v->solid == SOLID_BSP)
-                       trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
+                       trace = SV_ClipMoveToEntity(touch, clip->start, clip->mins, clip->maxs, clip->end, clip->type);
                else if ((int)touch->v->flags & FL_MONSTER)
-                       trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
+                       trace = SV_ClipMoveToEntity(touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->type);
                else
-                       trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
+                       trace = SV_ClipMoveToEntity(touch, clip->start, clip->mins, clip->maxs, clip->end, clip->type);
                // LordHavoc: take the 'best' answers from the new trace and combine with existing data
                if (trace.allsolid)
                        clip->trace.allsolid = true;
@@ -619,7 +625,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        clip.passedict = passedict;
 
        // clip to world
-       clip.trace = SV_ClipMoveToEntity(sv.edicts, clip.start, clip.mins, clip.maxs, clip.end);
+       clip.trace = SV_ClipMoveToEntity(sv.edicts, clip.start, clip.mins, clip.maxs, clip.end, clip.type);
        if (clip.type == MOVE_WORLDONLY)
        //if (clip.trace.allsolid)
                return clip.trace;
diff --git a/world.h b/world.h
index 1e8486c7d51e326b3b1f2a0d4f4602657fac6d7d..59a01e8a8eac90d41d2859a55960be3dca0473b2 100644 (file)
--- a/world.h
+++ b/world.h
@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define MOVE_NOMONSTERS 1
 #define MOVE_MISSILE    2
 #define MOVE_WORLDONLY  3
+#define MOVE_HITMODEL   4
 
 
 // called after the world model has been loaded, before linking any entities