summaryrefslogtreecommitdiff
path: root/source/sv_world.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/sv_world.c')
-rw-r--r--source/sv_world.c784
1 files changed, 395 insertions, 389 deletions
diff --git a/source/sv_world.c b/source/sv_world.c
index 2d35b94..432cce4 100644
--- a/source/sv_world.c
+++ b/source/sv_world.c
@@ -31,23 +31,23 @@ FIXME: this use of "area" is different from the bsp file use
*/
typedef struct areanode_s {
- int axis; // -1 = leaf node
- float dist;
- struct areanode_s *children[2];
- list_t trigger_edicts;
- list_t solid_edicts;
+ int axis; // -1 = leaf node
+ float dist;
+ struct areanode_s *children[2];
+ list_t trigger_edicts;
+ list_t solid_edicts;
} areanode_t;
-#define AREA_DEPTH 4
-#define AREA_NODES 32
+#define AREA_DEPTH 4
+#define AREA_NODES 32
-static areanode_t sv_areanodes[AREA_NODES];
-static int sv_numareanodes;
+static areanode_t sv_areanodes[AREA_NODES];
+static int sv_numareanodes;
-static float *area_mins, *area_maxs;
-static edict_t **area_list;
-static int area_count, area_maxcount;
-static int area_type;
+static float *area_mins, *area_maxs;
+static edict_t **area_list;
+static int area_count, area_maxcount;
+static int area_type;
/*
===============
@@ -57,41 +57,41 @@ Builds a uniformly subdivided tree for the given world size
===============
*/
static areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) {
- areanode_t *anode;
- vec3_t size;
- vec3_t mins1, maxs1, mins2, maxs2;
-
- anode = &sv_areanodes[sv_numareanodes];
- sv_numareanodes++;
-
- List_Init (&anode->trigger_edicts);
- List_Init (&anode->solid_edicts);
-
- if (depth == AREA_DEPTH)
- {
- anode->axis = -1;
- anode->children[0] = anode->children[1] = NULL;
- return anode;
- }
-
- VectorSubtract (maxs, mins, size);
- if (size[0] > size[1])
- anode->axis = 0;
- else
- anode->axis = 1;
-
- anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]);
- VectorCopy (mins, mins1);
- VectorCopy (mins, mins2);
- VectorCopy (maxs, maxs1);
- VectorCopy (maxs, maxs2);
-
- maxs1[anode->axis] = mins2[anode->axis] = anode->dist;
-
- anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2);
- anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1);
-
- return anode;
+ areanode_t *anode;
+ vec3_t size;
+ vec3_t mins1, maxs1, mins2, maxs2;
+
+ anode = &sv_areanodes[sv_numareanodes];
+ sv_numareanodes++;
+
+ List_Init (&anode->trigger_edicts);
+ List_Init (&anode->solid_edicts);
+
+ if (depth == AREA_DEPTH)
+ {
+ anode->axis = -1;
+ anode->children[0] = anode->children[1] = NULL;
+ return anode;
+ }
+
+ VectorSubtract (maxs, mins, size);
+ if (size[0] > size[1])
+ anode->axis = 0;
+ else
+ anode->axis = 1;
+
+ anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]);
+ VectorCopy (mins, mins1);
+ VectorCopy (mins, mins2);
+ VectorCopy (maxs, maxs1);
+ VectorCopy (maxs, maxs2);
+
+ maxs1[anode->axis] = mins2[anode->axis] = anode->dist;
+
+ anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2);
+ anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1);
+
+ return anode;
}
/*
@@ -101,23 +101,23 @@ SV_ClearWorld
===============
*/
void SV_ClearWorld( void ) {
- mmodel_t *cm;
- edict_t *ent;
- int i;
-
- memset( sv_areanodes, 0, sizeof( sv_areanodes ) );
- sv_numareanodes = 0;
-
- if( sv.cm.cache ) {
- cm = &sv.cm.cache->models[0];
- SV_CreateAreaNode( 0, cm->mins, cm->maxs );
- }
-
- // make sure all entities are unlinked
- for( i = 0; i < MAX_EDICTS; i++ ) {
- ent = EDICT_NUM( i );
- ent->area.prev = ent->area.next = NULL;
- }
+ mmodel_t *cm;
+ edict_t *ent;
+ int i;
+
+ memset( sv_areanodes, 0, sizeof( sv_areanodes ) );
+ sv_numareanodes = 0;
+
+ if( sv.cm.cache ) {
+ cm = &sv.cm.cache->models[0];
+ SV_CreateAreaNode( 0, cm->mins, cm->maxs );
+ }
+
+ // make sure all entities are unlinked
+ for( i = 0; i < MAX_EDICTS; i++ ) {
+ ent = EDICT_NUM( i );
+ ent->area.prev = ent->area.next = NULL;
+ }
}
@@ -130,121 +130,121 @@ Links entity to PVS leafs.
===============
*/
void SV_LinkEdict( cm_t *cm, edict_t *ent ) {
- mleaf_t *leafs[MAX_TOTAL_ENT_LEAFS];
- int clusters[MAX_TOTAL_ENT_LEAFS];
- int num_leafs;
- int i, j;
- int area;
- mnode_t *topnode;
-
- // set the size
- VectorSubtract (ent->maxs, ent->mins, ent->size);
-
- // set the abs box
- if (ent->solid == SOLID_BSP &&
+ mleaf_t *leafs[MAX_TOTAL_ENT_LEAFS];
+ int clusters[MAX_TOTAL_ENT_LEAFS];
+ int num_leafs;
+ int i, j;
+ int area;
+ mnode_t *topnode;
+
+ // set the size
+ VectorSubtract (ent->maxs, ent->mins, ent->size);
+
+ // set the abs box
+ if (ent->solid == SOLID_BSP &&
(ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2]) )
- { // expand for rotation
- float max, v;
- int i;
-
- max = 0;
- for (i=0 ; i<3 ; i++) {
- v = Q_fabs( ent->mins[i]);
- if (v > max)
- max = v;
- v = Q_fabs( ent->maxs[i]);
- if (v > max)
- max = v;
- }
- for (i=0 ; i<3 ; i++)
- {
- ent->absmin[i] = ent->s.origin[i] - max;
- ent->absmax[i] = ent->s.origin[i] + max;
- }
- }
- else
- { // normal
- VectorAdd (ent->s.origin, ent->mins, ent->absmin);
- VectorAdd (ent->s.origin, ent->maxs, ent->absmax);
- }
-
- // because movement is clipped an epsilon away from an actual edge,
- // we must fully check even when bounding boxes don't quite touch
- ent->absmin[0] -= 1;
- ent->absmin[1] -= 1;
- ent->absmin[2] -= 1;
- ent->absmax[0] += 1;
- ent->absmax[1] += 1;
- ent->absmax[2] += 1;
+ { // expand for rotation
+ float max, v;
+ int i;
+
+ max = 0;
+ for (i=0 ; i<3 ; i++) {
+ v = Q_fabs( ent->mins[i]);
+ if (v > max)
+ max = v;
+ v = Q_fabs( ent->maxs[i]);
+ if (v > max)
+ max = v;
+ }
+ for (i=0 ; i<3 ; i++)
+ {
+ ent->absmin[i] = ent->s.origin[i] - max;
+ ent->absmax[i] = ent->s.origin[i] + max;
+ }
+ }
+ else
+ { // normal
+ VectorAdd (ent->s.origin, ent->mins, ent->absmin);
+ VectorAdd (ent->s.origin, ent->maxs, ent->absmax);
+ }
+
+ // because movement is clipped an epsilon away from an actual edge,
+ // we must fully check even when bounding boxes don't quite touch
+ ent->absmin[0] -= 1;
+ ent->absmin[1] -= 1;
+ ent->absmin[2] -= 1;
+ ent->absmax[0] += 1;
+ ent->absmax[1] += 1;
+ ent->absmax[2] += 1;
// link to PVS leafs
- ent->num_clusters = 0;
- ent->areanum = 0;
- ent->areanum2 = 0;
-
- //get all leafs, including solids
- num_leafs = CM_BoxLeafs( cm, ent->absmin, ent->absmax,
- leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
-
- // set areas
- for (i=0 ; i<num_leafs ; i++)
- {
- clusters[i] = CM_LeafCluster (leafs[i]);
- area = CM_LeafArea (leafs[i]);
- if (area)
- { // doors may legally straggle two areas,
- // but nothing should evern need more than that
- if (ent->areanum && ent->areanum != area)
- {
- if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading)
- Com_DPrintf ("Object touching 3 areas at %f %f %f\n",
- ent->absmin[0], ent->absmin[1], ent->absmin[2]);
- ent->areanum2 = area;
- }
- else
- ent->areanum = area;
- }
- }
-
- if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
- { // assume we missed some leafs, and mark by headnode
- ent->num_clusters = -1;
- ent->headnode = CM_NumNode( cm, topnode );
- }
- else
- {
- ent->num_clusters = 0;
- for (i=0 ; i<num_leafs ; i++)
- {
- if (clusters[i] == -1)
- continue; // not a visible leaf
- for (j=0 ; j<i ; j++)
- if (clusters[j] == clusters[i])
- break;
- if (j == i)
- {
- if (ent->num_clusters == MAX_ENT_CLUSTERS)
- { // assume we missed some leafs, and mark by headnode
- ent->num_clusters = -1;
- ent->headnode = CM_NumNode( cm, topnode );
- break;
- }
-
- ent->clusternums[ent->num_clusters++] = clusters[i];
- }
- }
- }
+ ent->num_clusters = 0;
+ ent->areanum = 0;
+ ent->areanum2 = 0;
+
+ //get all leafs, including solids
+ num_leafs = CM_BoxLeafs( cm, ent->absmin, ent->absmax,
+ leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
+
+ // set areas
+ for (i=0 ; i<num_leafs ; i++)
+ {
+ clusters[i] = CM_LeafCluster (leafs[i]);
+ area = CM_LeafArea (leafs[i]);
+ if (area)
+ { // doors may legally straggle two areas,
+ // but nothing should evern need more than that
+ if (ent->areanum && ent->areanum != area)
+ {
+ if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading)
+ Com_DPrintf ("Object touching 3 areas at %f %f %f\n",
+ ent->absmin[0], ent->absmin[1], ent->absmin[2]);
+ ent->areanum2 = area;
+ }
+ else
+ ent->areanum = area;
+ }
+ }
+
+ if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
+ { // assume we missed some leafs, and mark by headnode
+ ent->num_clusters = -1;
+ ent->headnode = CM_NumNode( cm, topnode );
+ }
+ else
+ {
+ ent->num_clusters = 0;
+ for (i=0 ; i<num_leafs ; i++)
+ {
+ if (clusters[i] == -1)
+ continue; // not a visible leaf
+ for (j=0 ; j<i ; j++)
+ if (clusters[j] == clusters[i])
+ break;
+ if (j == i)
+ {
+ if (ent->num_clusters == MAX_ENT_CLUSTERS)
+ { // assume we missed some leafs, and mark by headnode
+ ent->num_clusters = -1;
+ ent->headnode = CM_NumNode( cm, topnode );
+ break;
+ }
+
+ ent->clusternums[ent->num_clusters++] = clusters[i];
+ }
+ }
+ }
}
void PF_UnlinkEdict (edict_t *ent) {
- if (!ent->area.prev)
- return; // not linked in anywhere
- List_Remove (&ent->area);
- ent->area.prev = ent->area.next = NULL;
+ if (!ent->area.prev)
+ return; // not linked in anywhere
+ List_Remove (&ent->area);
+ ent->area.prev = ent->area.next = NULL;
}
static int SV_CalcSolid( vec3_t mins, vec3_t maxs ) {
- int i, j, k;
+ int i, j, k;
// assume that x/y are equal and symetric
i = maxs[0] / 8;
@@ -262,7 +262,7 @@ static int SV_CalcSolid( vec3_t mins, vec3_t maxs ) {
}
static int SV_CalcSolid32( vec3_t mins, vec3_t maxs ) {
- int i, j, k;
+ int i, j, k;
// assume that x/y are equal and symetric
i = maxs[0];
@@ -280,28 +280,28 @@ static int SV_CalcSolid32( vec3_t mins, vec3_t maxs ) {
}
void PF_LinkEdict (edict_t *ent) {
- areanode_t *node;
+ areanode_t *node;
server_entity_t *sent;
int entnum;
- if (ent->area.prev)
- PF_UnlinkEdict (ent); // unlink from old position
-
- if (ent == ge->edicts)
- return; // don't add the world
+ if (ent->area.prev)
+ PF_UnlinkEdict (ent); // unlink from old position
+
+ if (ent == ge->edicts)
+ return; // don't add the world
- if (!ent->inuse)
- return;
+ if (!ent->inuse)
+ return;
- if( !sv.cm.cache ) {
- return;
- }
+ if( !sv.cm.cache ) {
+ return;
+ }
entnum = NUM_FOR_EDICT( ent );
sent = &sv.entities[entnum];
- // encode the size into the entity_state for client prediction
- switch( ent->solid ) {
+ // encode the size into the entity_state for client prediction
+ switch( ent->solid ) {
case SOLID_BBOX:
if( ( ent->svflags & SVF_DEADMONSTER ) || VectorCompare( ent->mins, ent->maxs ) ) {
ent->s.solid = 0;
@@ -312,44 +312,44 @@ void PF_LinkEdict (edict_t *ent) {
}
break;
case SOLID_BSP:
- ent->s.solid = 31; // a solid_bbox will never create this value
+ ent->s.solid = 31; // a solid_bbox will never create this value
sent->solid32 = 31; // FIXME: use 255?
break;
default:
- ent->s.solid = 0;
+ ent->s.solid = 0;
sent->solid32 = 0;
break;
}
SV_LinkEdict( &sv.cm, ent );
- // if first time, make sure old_origin is valid
- if (!ent->linkcount) {
- VectorCopy (ent->s.origin, ent->s.old_origin);
- }
- ent->linkcount++;
+ // if first time, make sure old_origin is valid
+ if (!ent->linkcount) {
+ VectorCopy (ent->s.origin, ent->s.old_origin);
+ }
+ ent->linkcount++;
- if (ent->solid == SOLID_NOT)
- return;
+ if (ent->solid == SOLID_NOT)
+ return;
// find the first node that the ent's box crosses
- node = sv_areanodes;
- while (1)
- {
- if (node->axis == -1)
- break;
- if (ent->absmin[node->axis] > node->dist)
- node = node->children[0];
- else if (ent->absmax[node->axis] < node->dist)
- node = node->children[1];
- else
- break; // crosses the node
- }
-
- // link it in
- if (ent->solid == SOLID_TRIGGER)
+ node = sv_areanodes;
+ while (1)
+ {
+ if (node->axis == -1)
+ break;
+ if (ent->absmin[node->axis] > node->dist)
+ node = node->children[0];
+ else if (ent->absmax[node->axis] < node->dist)
+ node = node->children[1];
+ else
+ break; // crosses the node
+ }
+
+ // link it in
+ if (ent->solid == SOLID_TRIGGER)
List_Append( &node->trigger_edicts, &ent->area );
- else
+ else
List_Append( &node->solid_edicts, &ent->area );
}
@@ -361,43 +361,43 @@ SV_AreaEdicts_r
====================
*/
static void SV_AreaEdicts_r (areanode_t *node) {
- list_t *start;
- edict_t *check;
+ list_t *start;
+ edict_t *check;
- // touch linked edicts
- if (area_type == AREA_SOLID)
- start = &node->solid_edicts;
- else
- start = &node->trigger_edicts;
+ // touch linked edicts
+ if (area_type == AREA_SOLID)
+ start = &node->solid_edicts;
+ else
+ start = &node->trigger_edicts;
LIST_FOR_EACH( edict_t, check, start, area ) {
- if (check->solid == SOLID_NOT)
- continue; // deactivated
- if (check->absmin[0] > area_maxs[0]
- || check->absmin[1] > area_maxs[1]
- || check->absmin[2] > area_maxs[2]
- || check->absmax[0] < area_mins[0]
- || check->absmax[1] < area_mins[1]
- || check->absmax[2] < area_mins[2])
- continue; // not touching
-
- if (area_count == area_maxcount) {
- Com_WPrintf ("SV_AreaEdicts: MAXCOUNT\n");
- return;
- }
-
- area_list[area_count] = check;
- area_count++;
- }
-
- if (node->axis == -1)
- return; // terminal node
-
- // recurse down both sides
- if ( area_maxs[node->axis] > node->dist )
- SV_AreaEdicts_r ( node->children[0] );
- if ( area_mins[node->axis] < node->dist )
- SV_AreaEdicts_r ( node->children[1] );
+ if (check->solid == SOLID_NOT)
+ continue; // deactivated
+ if (check->absmin[0] > area_maxs[0]
+ || check->absmin[1] > area_maxs[1]
+ || check->absmin[2] > area_maxs[2]
+ || check->absmax[0] < area_mins[0]
+ || check->absmax[1] < area_mins[1]
+ || check->absmax[2] < area_mins[2])
+ continue; // not touching
+
+ if (area_count == area_maxcount) {
+ Com_WPrintf ("SV_AreaEdicts: MAXCOUNT\n");
+ return;
+ }
+
+ area_list[area_count] = check;
+ area_count++;
+ }
+
+ if (node->axis == -1)
+ return; // terminal node
+
+ // recurse down both sides
+ if ( area_maxs[node->axis] > node->dist )
+ SV_AreaEdicts_r ( node->children[0] );
+ if ( area_mins[node->axis] < node->dist )
+ SV_AreaEdicts_r ( node->children[1] );
}
/*
@@ -406,18 +406,18 @@ SV_AreaEdicts
================
*/
int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list,
- int maxcount, int areatype)
+ int maxcount, int areatype)
{
- area_mins = mins;
- area_maxs = maxs;
- area_list = list;
- area_count = 0;
- area_maxcount = maxcount;
- area_type = areatype;
+ area_mins = mins;
+ area_maxs = maxs;
+ area_list = list;
+ area_count = 0;
+ area_maxcount = maxcount;
+ area_type = areatype;
- SV_AreaEdicts_r (sv_areanodes);
+ SV_AreaEdicts_r (sv_areanodes);
- return area_count;
+ return area_count;
}
@@ -432,23 +432,23 @@ object of mins/maxs size.
================
*/
static mnode_t *SV_HullForEntity( edict_t *ent ) {
- mmodel_t *model;
+ mmodel_t *model;
- if( ent->solid == SOLID_BSP ) {
+ if( ent->solid == SOLID_BSP ) {
int index = ent->s.modelindex - 1;
- // explicit hulls in the BSP model
- if( index <= 0 || index >= sv.cm.cache->nummodels ) {
- Com_Error( ERR_DROP, "%s: inline model %d out of range",
+ // explicit hulls in the BSP model
+ if( index <= 0 || index >= sv.cm.cache->nummodels ) {
+ Com_Error( ERR_DROP, "%s: inline model %d out of range",
__func__, index );
- }
+ }
- model = &sv.cm.cache->models[index];
- return model->headnode;
- }
+ model = &sv.cm.cache->models[index];
+ return model->headnode;
+ }
- // create a temp hull from bounding box sizes
- return CM_HeadnodeForBox( ent->mins, ent->maxs );
+ // create a temp hull from bounding box sizes
+ return CM_HeadnodeForBox( ent->mins, ent->maxs );
}
/*
@@ -458,46 +458,46 @@ SV_PointContents
*/
int SV_PointContents (vec3_t p)
{
- edict_t *touch[MAX_EDICTS], *hit;
- int i, num;
- int contents, c2;
- mnode_t *headnode;
+ edict_t *touch[MAX_EDICTS], *hit;
+ int i, num;
+ int contents, c2;
+ mnode_t *headnode;
- if( !sv.cm.cache ) {
- Com_Error( ERR_DROP, "%s: no map loaded", __func__ );
- }
+ if( !sv.cm.cache ) {
+ Com_Error( ERR_DROP, "%s: no map loaded", __func__ );
+ }
- // get base contents from world
- contents = CM_PointContents (p, sv.cm.cache->nodes);
+ // get base contents from world
+ contents = CM_PointContents (p, sv.cm.cache->nodes);
- // or in contents from all the other entities
- num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID);
+ // or in contents from all the other entities
+ num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID);
- for (i=0 ; i<num ; i++)
- {
- hit = touch[i];
+ for (i=0 ; i<num ; i++)
+ {
+ hit = touch[i];
- // might intersect, so do an exact clip
- headnode = SV_HullForEntity (hit);
+ // might intersect, so do an exact clip
+ headnode = SV_HullForEntity (hit);
- c2 = CM_TransformedPointContents (p, headnode,
+ c2 = CM_TransformedPointContents (p, headnode,
hit->s.origin, hit->s.angles);
- contents |= c2;
- }
+ contents |= c2;
+ }
- return contents;
+ return contents;
}
typedef struct {
- vec3_t boxmins, boxmaxs;// enclose the test object along entire move
- vec_t *mins, *maxs; // size of the moving object
- vec_t *start, *end;
- trace_t *trace;
- edict_t *passedict;
- int contentmask;
+ vec3_t boxmins, boxmaxs;// enclose the test object along entire move
+ vec_t *mins, *maxs; // size of the moving object
+ vec_t *start, *end;
+ trace_t *trace;
+ edict_t *passedict;
+ int contentmask;
} moveclip_t;
/*
@@ -507,46 +507,46 @@ SV_ClipMoveToEntities
====================
*/
static void SV_ClipMoveToEntities( moveclip_t *clip ) {
- int i, num;
- edict_t *touchlist[MAX_EDICTS], *touch;
- trace_t trace;
- mnode_t *headnode;
-
- num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist
- , MAX_EDICTS, AREA_SOLID);
-
- // be careful, it is possible to have an entity in this
- // list removed before we get to it (killtriggered)
- for (i=0 ; i<num ; i++)
- {
- touch = touchlist[i];
- if (touch->solid == SOLID_NOT)
- continue;
- if (touch == clip->passedict)
- continue;
- if (clip->trace->allsolid)
- return;
- if (clip->passedict)
- {
- if (touch->owner == clip->passedict)
- continue; // don't clip against own missiles
- if (clip->passedict->owner == touch)
- continue; // don't clip against owner
- }
-
- if ( !(clip->contentmask & CONTENTS_DEADMONSTER)
- && (touch->svflags & SVF_DEADMONSTER) )
- continue;
-
- // might intersect, so do an exact clip
- headnode = SV_HullForEntity (touch);
-
- CM_TransformedBoxTrace (&trace, clip->start, clip->end,
- clip->mins, clip->maxs, headnode, clip->contentmask,
- touch->s.origin, touch->s.angles);
-
- CM_ClipEntity( clip->trace, &trace, touch );
- }
+ int i, num;
+ edict_t *touchlist[MAX_EDICTS], *touch;
+ trace_t trace;
+ mnode_t *headnode;
+
+ num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist
+ , MAX_EDICTS, AREA_SOLID);
+
+ // be careful, it is possible to have an entity in this
+ // list removed before we get to it (killtriggered)
+ for (i=0 ; i<num ; i++)
+ {
+ touch = touchlist[i];
+ if (touch->solid == SOLID_NOT)
+ continue;
+ if (touch == clip->passedict)
+ continue;
+ if (clip->trace->allsolid)
+ return;
+ if (clip->passedict)
+ {
+ if (touch->owner == clip->passedict)
+ continue; // don't clip against own missiles
+ if (clip->passedict->owner == touch)
+ continue; // don't clip against owner
+ }
+
+ if ( !(clip->contentmask & CONTENTS_DEADMONSTER)
+ && (touch->svflags & SVF_DEADMONSTER) )
+ continue;
+
+ // might intersect, so do an exact clip
+ headnode = SV_HullForEntity (touch);
+
+ CM_TransformedBoxTrace (&trace, clip->start, clip->end,
+ clip->mins, clip->maxs, headnode, clip->contentmask,
+ touch->s.origin, touch->s.angles);
+
+ CM_ClipEntity( clip->trace, &trace, touch );
+ }
}
@@ -556,17 +556,17 @@ SV_TraceBounds
==================
*/
static void SV_TraceBounds (moveclip_t *clip) {
- int i;
-
- for (i=0 ; i<3 ; i++) {
- if (clip->end[i] > clip->start[i]) {
- clip->boxmins[i] = clip->start[i] + clip->mins[i] - 1;
- clip->boxmaxs[i] = clip->end[i] + clip->maxs[i] + 1;
- } else {
- clip->boxmins[i] = clip->end[i] + clip->mins[i] - 1;
- clip->boxmaxs[i] = clip->start[i] + clip->maxs[i] + 1;
- }
- }
+ int i;
+
+ for (i=0 ; i<3 ; i++) {
+ if (clip->end[i] > clip->start[i]) {
+ clip->boxmins[i] = clip->start[i] + clip->mins[i] - 1;
+ clip->boxmaxs[i] = clip->end[i] + clip->maxs[i] + 1;
+ } else {
+ clip->boxmins[i] = clip->end[i] + clip->mins[i] - 1;
+ clip->boxmaxs[i] = clip->start[i] + clip->maxs[i] + 1;
+ }
+ }
}
/*
@@ -578,53 +578,59 @@ Moves the given mins/maxs volume through the world from start to end.
Passedict and edicts owned by passedict are explicitly not checked.
==================
*/
-trace_t *SV_Trace(trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
- edict_t *passedict, int contentmask)
+trace_t *SV_Trace( trace_t *trace,
+ vec3_t start,
+ vec3_t mins,
+ vec3_t maxs,
+ vec3_t end,
+ edict_t *passedict,
+ int contentmask )
{
- moveclip_t clip;
-
- if( !sv.cm.cache ) {
- Com_Error( ERR_DROP, "%s: no map loaded", __func__ );
- }
-
- if( ++sv.tracecount > 10000 ) {
- Com_EPrintf( "SV_Trace: game DLL caught in infinite loop!\n" );
- memset( trace, 0, sizeof( *trace ) );
- trace->fraction = 1;
- trace->ent = ge->edicts;
- VectorCopy( end, trace->endpos );
- sv.tracecount = 0;
- return trace;
- }
-
- if (!mins)
- mins = vec3_origin;
- if (!maxs)
- maxs = vec3_origin;
-
- // clip to world
- CM_BoxTrace( trace, start, end, mins, maxs, sv.cm.cache->nodes, contentmask );
- trace->ent = ge->edicts;
- if (trace->fraction == 0) {
- return trace; // blocked by the world
- }
-
- memset( &clip, 0, sizeof( clip ) );
- clip.trace = trace;
- clip.contentmask = contentmask;
- clip.start = start;
- clip.end = end;
- clip.mins = mins;
- clip.maxs = maxs;
- clip.passedict = passedict;
-
- // create the bounding box of the entire move
- SV_TraceBounds( &clip );
-
- // clip to other solid entities
- SV_ClipMoveToEntities( &clip );
-
- return trace;
+ moveclip_t clip;
+
+ if( !sv.cm.cache ) {
+ Com_Error( ERR_DROP, "%s: no map loaded", __func__ );
+ }
+
+ if( ++sv.tracecount > 10000 ) {
+ Com_EPrintf( "SV_Trace: game DLL caught in infinite loop!\n" );
+ memset( trace, 0, sizeof( *trace ) );
+ trace->fraction = 1;
+ trace->ent = ge->edicts;
+ VectorCopy( end, trace->endpos );
+ sv.tracecount = 0;
+ return trace;
+ }
+
+ if (!mins)
+ mins = vec3_origin;
+ if (!maxs)
+ maxs = vec3_origin;
+
+ // clip to world
+ CM_BoxTrace( trace, start, end, mins, maxs,
+ sv.cm.cache->nodes, contentmask );
+ trace->ent = ge->edicts;
+ if (trace->fraction == 0) {
+ return trace; // blocked by the world
+ }
+
+ memset( &clip, 0, sizeof( clip ) );
+ clip.trace = trace;
+ clip.contentmask = contentmask;
+ clip.start = start;
+ clip.end = end;
+ clip.mins = mins;
+ clip.maxs = maxs;
+ clip.passedict = passedict;
+
+ // create the bounding box of the entire move
+ SV_TraceBounds( &clip );
+
+ // clip to other solid entities
+ SV_ClipMoveToEntities( &clip );
+
+ return trace;
}
/*
@@ -635,10 +641,10 @@ Variant of SV_Trace for native game ABI
==================
*/
trace_t SV_Trace_Native (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask) {
- trace_t trace;
+ trace_t trace;
SV_Trace( &trace, start, mins, maxs, end, passedict, contentmask );
- return trace;
+ return trace;
}