cleaned up and fixed collisions with brush models (example: you can now ramp jump...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 4 May 2002 12:08:45 +0000 (12:08 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 4 May 2002 12:08:45 +0000 (12:08 +0000)
items suspended in the air on a func_door (or similar) entity which is then killed by a trigger, should now continue floating in the air (this is a gross hack, to make suspended items in various maps stay in the air)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1820 d7cf8633-e32d-0410-b094-e92efae38249

model_brush.c
model_brush.h
progs.h
sv_phys.c
world.c

index dc5b243..3301a7b 100644 (file)
@@ -1470,6 +1470,7 @@ static void Mod_LoadClipnodes (lump_t *l)
                hull->clip_maxs[0] = 16;
                hull->clip_maxs[1] = 16;
                hull->clip_maxs[2] = 36;
+               VectorSubtract(hull->clip_maxs, hull->clip_mins, hull->clip_size);
 
                hull = &loadmodel->hulls[2];
                hull->clipnodes = out;
@@ -1482,6 +1483,7 @@ static void Mod_LoadClipnodes (lump_t *l)
                hull->clip_maxs[0] = 32;
                hull->clip_maxs[1] = 32;
                hull->clip_maxs[2] = 32;
+               VectorSubtract(hull->clip_maxs, hull->clip_mins, hull->clip_size);
 
                hull = &loadmodel->hulls[3];
                hull->clipnodes = out;
@@ -1494,6 +1496,7 @@ static void Mod_LoadClipnodes (lump_t *l)
                hull->clip_maxs[0] = 16;
                hull->clip_maxs[1] = 16;
                hull->clip_maxs[2] = 18;
+               VectorSubtract(hull->clip_maxs, hull->clip_mins, hull->clip_size);
        }
        else
        {
@@ -1508,6 +1511,7 @@ static void Mod_LoadClipnodes (lump_t *l)
                hull->clip_maxs[0] = 16;
                hull->clip_maxs[1] = 16;
                hull->clip_maxs[2] = 32;
+               VectorSubtract(hull->clip_maxs, hull->clip_mins, hull->clip_size);
 
                hull = &loadmodel->hulls[2];
                hull->clipnodes = out;
@@ -1520,6 +1524,7 @@ static void Mod_LoadClipnodes (lump_t *l)
                hull->clip_maxs[0] = 32;
                hull->clip_maxs[1] = 32;
                hull->clip_maxs[2] = 64;
+               VectorSubtract(hull->clip_maxs, hull->clip_mins, hull->clip_size);
        }
 
        for (i=0 ; i<count ; i++, out++, in++)
index 29bfe05..04bae33 100644 (file)
@@ -261,6 +261,7 @@ typedef struct
        int                     lastclipnode;
        vec3_t          clip_mins;
        vec3_t          clip_maxs;
+       vec3_t          clip_size;
 }
 hull_t;
 
diff --git a/progs.h b/progs.h
index c377ec0..166d2ea 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -48,6 +48,7 @@ typedef struct edict_s
        entity_state_t  deltabaseline; // LordHavoc: previous frame
 #endif
 
+       int                     suspendedinairflag;     // LordHavoc: gross hack to make floating items still work
        float           freetime;                       // sv.time when the object was freed
        entvars_t       v;                                      // C exported fields from progs
 // other fields from progs come immediately after
index 9056bb2..d646562 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -831,7 +831,7 @@ qboolean SV_CheckWater (edict_t *ent)
                                ent->v.waterlevel = 3;
                }
        }
-       
+
        return ent->v.waterlevel > 1;
 }
 
@@ -1243,14 +1243,29 @@ void SV_Physics_Toss (edict_t *ent)
 {
        trace_t trace;
        vec3_t  move;
+       edict_t *groundentity;
        //edict_t *groundentity;
        // regular thinking
        if (!SV_RunThink (ent))
                return;
 
 // if onground, return without moving
-       if (((int)ent->v.flags & FL_ONGROUND) && ent->v.groundentity == 0)
-               return;
+       if ((int)ent->v.flags & FL_ONGROUND)
+       {
+               if (ent->v.groundentity == 0)
+                       return;
+               groundentity = PROG_TO_EDICT(ent->v.groundentity);
+               if (groundentity != NULL && groundentity->v.solid == SOLID_BSP)
+                       ent->suspendedinairflag = true;
+               else if (ent->suspendedinairflag && (groundentity == NULL || groundentity->v.solid != SOLID_BSP))
+               {
+                       // leave it suspended in the air
+                       ent->v.groundentity = 0;
+                       return;
+               }
+       }
+       ent->suspendedinairflag = false;
+
        /*
        if ( ((int)ent->v.flags & FL_ONGROUND) )
        {
@@ -1268,8 +1283,8 @@ void SV_Physics_Toss (edict_t *ent)
 
 // add gravity
        if (ent->v.movetype != MOVETYPE_FLY
-       && ent->v.movetype != MOVETYPE_BOUNCEMISSILE // LordHavoc: enabled MOVETYPE_BOUNCEMISSILE
-       && ent->v.movetype != MOVETYPE_FLYMISSILE)
+        && ent->v.movetype != MOVETYPE_BOUNCEMISSILE // LordHavoc: enabled MOVETYPE_BOUNCEMISSILE
+        && ent->v.movetype != MOVETYPE_FLYMISSILE)
                SV_AddGravity (ent);
 
 // move angles
diff --git a/world.c b/world.c
index d8d092f..d5444cd 100644 (file)
--- a/world.c
+++ b/world.c
@@ -81,14 +81,31 @@ void InsertLinkAfter (link_t *l, link_t *after)
 
 typedef struct
 {
-       vec3_t          boxmins, boxmaxs;// enclose the test object along entire move
-       float           *mins, *maxs;   // size of the moving object
-       vec3_t          mins2, maxs2;   // size when clipping against mosnters
-       float           *start, *end;
+       // bounding box of entire move area
+       vec3_t          boxmins, boxmaxs;
+
+       // size of the moving object
+       vec3_t          mins, maxs;
+
+       // size when clipping against monsters
+       vec3_t          mins2, maxs2;
+
+       // size when clipping against brush models
+       vec3_t          hullmins, hullmaxs;
+
+       // start and end origin of move
+       vec3_t          start, end;
+
+       // trace results
        trace_t         trace;
+
+       // type of move (like ignoring monsters, or similar)
        int                     type;
+
+       // the edict that is moving (if any)
        edict_t         *passedict;
-} moveclip_t;
+}
+moveclip_t;
 
 
 /*
@@ -181,7 +198,8 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
 
 // decide which clipping hull to use, based on the size
        if (ent->v.solid == SOLID_BSP)
-       {       // explicit hulls in the BSP model
+       {
+               // explicit hulls in the BSP model
                if (ent->v.movetype != MOVETYPE_PUSH)
                        Host_Error ("SOLID_BSP without MOVETYPE_PUSH");
 
@@ -198,7 +216,7 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
 
                VectorSubtract (maxs, mins, size);
                // LordHavoc: FIXME!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-               if (sv.worldmodel->ishlbsp)
+               if (model->ishlbsp)
                {
                        if (size[0] < 3)
                                hull = &model->hulls[0]; // 0x0x0
@@ -240,6 +258,39 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
        return hull;
 }
 
+void SV_RoundUpToHullSize(vec3_t inmins, vec3_t inmaxs, vec3_t outmins, vec3_t outmaxs)
+{
+       vec3_t size;
+       hull_t *hull;
+
+       VectorSubtract(inmaxs, inmins, size);
+       if (sv.worldmodel->ishlbsp)
+       {
+               if (size[0] < 3)
+                       hull = &sv.worldmodel->hulls[0]; // 0x0x0
+               else if (size[0] <= 32)
+               {
+                       if (size[2] < 54) // pick the nearest of 36 or 72
+                               hull = &sv.worldmodel->hulls[3]; // 32x32x36
+                       else
+                               hull = &sv.worldmodel->hulls[1]; // 32x32x72
+               }
+               else
+                       hull = &sv.worldmodel->hulls[2]; // 64x64x64
+       }
+       else
+       {
+               if (size[0] < 3)
+                       hull = &sv.worldmodel->hulls[0]; // 0x0x0
+               else if (size[0] <= 32)
+                       hull = &sv.worldmodel->hulls[1]; // 32x32x56
+               else
+                       hull = &sv.worldmodel->hulls[2]; // 64x64x88
+       }
+       VectorCopy(inmins, outmins);
+       VectorAdd(inmins, hull->clip_size, outmaxs);
+}
+
 /*
 ===============================================================================
 
@@ -413,6 +464,7 @@ SV_LinkEdict
 */
 void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
 {
+       model_t         *model;
        areanode_t      *node;
 
        if (ent->area.prev)
@@ -426,6 +478,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
 
 // set the abs box
 
+       /*
 // LordHavoc: enabling rotating bmodels
        if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
        {
@@ -438,6 +491,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                if (max < v)
                        max = v;
                max = sqrt(max);
+       */
                /*
                max = 0;
                for (i=0 ; i<3 ; i++)
@@ -450,6 +504,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                                max = v;
                }
                */
+       /*
                for (i=0 ; i<3 ; i++)
                {
                        ent->v.absmin[i] = ent->v.origin[i] - max;
@@ -461,6 +516,46 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
                VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
        }
+       */
+
+       if (ent->v.solid == SOLID_BSP)
+       {
+               if (ent->v.modelindex < 0 || ent->v.modelindex > MAX_MODELS)
+                       PR_RunError("SOLID_BSP with invalid modelindex!\n");
+               model = sv.models[(int) ent->v.modelindex];
+               if (model != NULL)
+               {
+                       if (model->type != mod_brush)
+                               PR_RunError("SOLID_BSP with non-BSP model\n");
+
+                       if (ent->v.angles[0] || ent->v.angles[2] || ent->v.avelocity[0] || ent->v.avelocity[2])
+                       {
+                               VectorAdd(ent->v.origin, model->rotatedmins, ent->v.absmin);
+                               VectorAdd(ent->v.origin, model->rotatedmaxs, ent->v.absmax);
+                       }
+                       else if (ent->v.angles[1] || ent->v.avelocity[1])
+                       {
+                               VectorAdd(ent->v.origin, model->yawmins, ent->v.absmin);
+                               VectorAdd(ent->v.origin, model->yawmaxs, ent->v.absmax);
+                       }
+                       else
+                       {
+                               VectorAdd(ent->v.origin, model->normalmins, ent->v.absmin);
+                               VectorAdd(ent->v.origin, model->normalmaxs, ent->v.absmax);
+                       }
+               }
+               else
+               {
+                       // SOLID_BSP with no model is valid, mainly because some QC setup code does so temporarily
+                       VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
+                       VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
+               }
+       }
+       else
+       {
+               VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
+               VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
+       }
 
 //
 // to make items easier to pick up and allow them to be grabbed off
@@ -470,8 +565,10 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
        {
                ent->v.absmin[0] -= 15;
                ent->v.absmin[1] -= 15;
+               ent->v.absmin[2] -= 1;
                ent->v.absmax[0] += 15;
                ent->v.absmax[1] += 15;
+               ent->v.absmax[2] += 1;
        }
        else
        {
@@ -756,7 +853,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
        VectorSubtract(start, offset, startd);
        VectorSubtract(end, offset, endd);
 
-       // rotate start and end into the models frame of reference
+       // rotate start and end into the model's frame of reference
        if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
        {
                AngleVectorsFLU (ent->v.angles, forward, left, up);
@@ -867,6 +964,8 @@ loc0:
                // might interact, so do an exact clip
                if ((int)touch->v.flags & FL_MONSTER)
                        trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
+               else if (touch->v.solid == SOLID_BSP)
+                       trace = SV_ClipMoveToEntity (touch, clip->start, clip->hullmins, clip->hullmaxs, clip->end);
                else
                        trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
                // LordHavoc: take the 'best' answers from the new trace and combine with existing data
@@ -940,8 +1039,8 @@ void SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, vec3_t b
 {
 #if 0
 // debug to test against everything
-boxmins[0] = boxmins[1] = boxmins[2] = -9999;
-boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999;
+boxmins[0] = boxmins[1] = boxmins[2] = -999999999;
+boxmaxs[0] = boxmaxs[1] = boxmaxs[2] =  999999999;
 #else
        int             i;
 
@@ -969,23 +1068,27 @@ SV_Move
 trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict)
 {
        moveclip_t      clip;
+       vec3_t          bigmins, bigmaxs;
        int                     i;
 
        memset ( &clip, 0, sizeof ( moveclip_t ) );
 
-       clip.start = start;
-       clip.end = end;
-       clip.mins = mins;
-       clip.maxs = maxs;
+       VectorCopy(start, clip.start);
+       VectorCopy(end, clip.end);
+       VectorCopy(mins, clip.mins);
+       VectorCopy(maxs, clip.maxs);
        clip.type = type;
        clip.passedict = passedict;
 
+       SV_RoundUpToHullSize(clip.mins, clip.maxs, clip.hullmins, clip.hullmaxs);
+
        if (type == MOVE_MISSILE)
        {
+               // LordHavoc: modified this, was = -15, now = clip.mins[i] - 15
                for (i=0 ; i<3 ; i++)
                {
-                       clip.mins2[i] = -15;
-                       clip.maxs2[i] = 15;
+                       clip.mins2[i] = clip.mins[i] - 15;
+                       clip.maxs2[i] = clip.maxs[i] + 15;
                }
        }
        else
@@ -994,6 +1097,13 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
                VectorCopy (clip.maxs, clip.maxs2);
        }
 
+       bigmins[0] = min(clip.mins2[0], clip.hullmins[0]);
+       bigmaxs[0] = max(clip.maxs2[0], clip.hullmaxs[0]);
+       bigmins[1] = min(clip.mins2[1], clip.hullmins[1]);
+       bigmaxs[1] = max(clip.maxs2[1], clip.hullmaxs[1]);
+       bigmins[2] = min(clip.mins2[2], clip.hullmins[2]);
+       bigmaxs[2] = max(clip.maxs2[2], clip.hullmaxs[2]);
+
        // clip to world
        clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end);
 
@@ -1001,7 +1111,7 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
        //if (!clip.trace.allsolid)
        {
                // create the bounding box of the entire move
-               SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs );
+               SV_MoveBounds ( start, bigmins, bigmaxs, end, clip.boxmins, clip.boxmaxs );
 
                SV_ClipToLinks ( sv_areanodes, &clip );
        }