summaryrefslogtreecommitdiff
path: root/src/sv_world.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sv_world.c')
-rw-r--r--src/sv_world.c323
1 files changed, 159 insertions, 164 deletions
diff --git a/src/sv_world.c b/src/sv_world.c
index 9f7e767..47aed67 100644
--- a/src/sv_world.c
+++ b/src/sv_world.c
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@@ -56,7 +56,8 @@ SV_CreateAreaNode
Builds a uniformly subdivided tree for the given world size
===============
*/
-static areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) {
+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;
@@ -64,32 +65,31 @@ static areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) {
anode = &sv_areanodes[sv_numareanodes];
sv_numareanodes++;
- List_Init (&anode->trigger_edicts);
- List_Init (&anode->solid_edicts);
-
- if (depth == AREA_DEPTH)
- {
+ 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);
+
+ 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);
-
+ 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);
+
+ anode->children[0] = SV_CreateAreaNode(depth + 1, mins2, maxs2);
+ anode->children[1] = SV_CreateAreaNode(depth + 1, mins1, maxs1);
return anode;
}
@@ -100,22 +100,23 @@ SV_ClearWorld
===============
*/
-void SV_ClearWorld( void ) {
+void SV_ClearWorld(void)
+{
mmodel_t *cm;
edict_t *ent;
int i;
- memset( sv_areanodes, 0, sizeof( sv_areanodes ) );
+ memset(sv_areanodes, 0, sizeof(sv_areanodes));
sv_numareanodes = 0;
- if( sv.cm.cache ) {
+ if (sv.cm.cache) {
cm = &sv.cm.cache->models[0];
- SV_CreateAreaNode( 0, cm->mins, cm->maxs );
+ SV_CreateAreaNode(0, cm->mins, cm->maxs);
}
// make sure all entities are unlinked
- for( i = 0; i < ge->max_edicts; i++ ) {
- ent = EDICT_NUM( i );
+ for (i = 0; i < ge->max_edicts; i++) {
+ ent = EDICT_NUM(i);
ent->area.prev = ent->area.next = NULL;
}
}
@@ -129,7 +130,8 @@ General purpose routine shared between game DLL and MVD code.
Links entity to PVS leafs.
===============
*/
-void SV_LinkEdict( cm_t *cm, edict_t *ent ) {
+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;
@@ -138,34 +140,32 @@ void SV_LinkEdict( cm_t *cm, edict_t *ent ) {
mnode_t *topnode;
// set the size
- VectorSubtract (ent->maxs, ent->mins, ent->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;
+ (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]);
+ for (i = 0; i < 3; i++) {
+ v = Q_fabs(ent->mins[i]);
if (v > max)
max = v;
- v = Q_fabs( ent->maxs[i]);
+ v = Q_fabs(ent->maxs[i]);
if (v > max)
max = v;
}
- for (i=0 ; i<3 ; i++)
- {
+ 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);
+ } 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,
@@ -183,52 +183,44 @@ void SV_LinkEdict( cm_t *cm, edict_t *ent ) {
ent->areanum2 = 0;
//get all leafs, including solids
- num_leafs = CM_BoxLeafs( cm, ent->absmin, ent->absmax,
- leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
+ 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,
+ 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]);
+ 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
+ } else
ent->areanum = area;
}
}
- if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
- { // assume we missed some leafs, and mark by headnode
+ 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->headnode = CM_NumNode(cm, topnode);
+ } else {
ent->num_clusters = 0;
- for (i=0 ; i<num_leafs ; i++)
- {
+ for (i = 0; i < num_leafs; i++) {
if (clusters[i] == -1)
continue; // not a visible leaf
- for (j=0 ; j<i ; j++)
+ 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
+ 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 );
+ ent->headnode = CM_NumNode(cm, topnode);
break;
}
@@ -238,14 +230,16 @@ void SV_LinkEdict( cm_t *cm, edict_t *ent ) {
}
}
-void PF_UnlinkEdict (edict_t *ent) {
+void PF_UnlinkEdict(edict_t *ent)
+{
if (!ent->area.prev)
return; // not linked in anywhere
- List_Remove (&ent->area);
+ List_Remove(&ent->area);
ent->area.prev = ent->area.next = NULL;
}
-void PF_LinkEdict (edict_t *ent) {
+void PF_LinkEdict(edict_t *ent)
+{
areanode_t *node;
server_entity_t *sent;
int entnum;
@@ -254,32 +248,32 @@ void PF_LinkEdict (edict_t *ent) {
#endif
if (ent->area.prev)
- PF_UnlinkEdict (ent); // unlink from old position
-
+ PF_UnlinkEdict(ent); // unlink from old position
+
if (ent == ge->edicts)
return; // don't add the world
if (!ent->inuse) {
- Com_DPrintf( "%s: entity %d is not in use\n", __func__, NUM_FOR_EDICT( ent ) );
+ Com_DPrintf("%s: entity %d is not in use\n", __func__, NUM_FOR_EDICT(ent));
return;
}
- if( !sv.cm.cache ) {
+ if (!sv.cm.cache) {
return;
}
- entnum = NUM_FOR_EDICT( ent );
+ entnum = NUM_FOR_EDICT(ent);
sent = &sv.entities[entnum];
// encode the size into the entity_state for client prediction
- switch( ent->solid ) {
+ switch (ent->solid) {
case SOLID_BBOX:
- if( ( ent->svflags & SVF_DEADMONSTER ) || VectorCompare( ent->mins, ent->maxs ) ) {
+ if ((ent->svflags & SVF_DEADMONSTER) || VectorCompare(ent->mins, ent->maxs)) {
ent->s.solid = 0;
sent->solid32 = 0;
} else {
- ent->s.solid = MSG_PackSolid16( ent->mins, ent->maxs );
- sent->solid32 = MSG_PackSolid32( ent->mins, ent->maxs );
+ ent->s.solid = MSG_PackSolid16(ent->mins, ent->maxs);
+ sent->solid32 = MSG_PackSolid32(ent->mins, ent->maxs);
}
break;
case SOLID_BSP:
@@ -292,13 +286,13 @@ void PF_LinkEdict (edict_t *ent) {
break;
}
- SV_LinkEdict( &sv.cm, ent );
+ 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);
+ VectorCopy(ent->s.origin, ent->s.old_origin);
#if USE_FPS
- VectorCopy( ent->s.origin, sent->create_origin );
+ VectorCopy(ent->s.origin, sent->create_origin);
sent->create_framenum = sv.framenum;
#endif
}
@@ -307,7 +301,7 @@ void PF_LinkEdict (edict_t *ent) {
#if USE_FPS
// save origin for later recovery
i = sv.framenum & ENT_HISTORY_MASK;
- VectorCopy( ent->s.origin, sent->history[i].origin );
+ VectorCopy(ent->s.origin, sent->history[i].origin);
sent->history[i].framenum = sv.framenum;
#endif
@@ -316,8 +310,7 @@ void PF_LinkEdict (edict_t *ent) {
// find the first node that the ent's box crosses
node = sv_areanodes;
- while (1)
- {
+ while (1) {
if (node->axis == -1)
break;
if (ent->absmin[node->axis] > node->dist)
@@ -327,12 +320,12 @@ void PF_LinkEdict (edict_t *ent) {
else
break; // crosses the node
}
-
- // link it in
+
+ // link it in
if (ent->solid == SOLID_TRIGGER)
- List_Append( &node->trigger_edicts, &ent->area );
+ List_Append(&node->trigger_edicts, &ent->area);
else
- List_Append( &node->solid_edicts, &ent->area );
+ List_Append(&node->solid_edicts, &ent->area);
}
@@ -342,7 +335,8 @@ SV_AreaEdicts_r
====================
*/
-static void SV_AreaEdicts_r (areanode_t *node) {
+static void SV_AreaEdicts_r(areanode_t *node)
+{
list_t *start;
edict_t *check;
@@ -352,34 +346,34 @@ static void SV_AreaEdicts_r (areanode_t *node) {
else
start = &node->trigger_edicts;
- LIST_FOR_EACH( edict_t, check, start, area ) {
+ 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])
+ || 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");
+ 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 (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]);
}
/*
@@ -387,8 +381,8 @@ static void SV_AreaEdicts_r (areanode_t *node) {
SV_AreaEdicts
================
*/
-int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list,
- int maxcount, int areatype)
+int SV_AreaEdicts(vec3_t mins, vec3_t maxs, edict_t **list,
+ int maxcount, int areatype)
{
area_mins = mins;
area_maxs = maxs;
@@ -397,7 +391,7 @@ int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list,
area_maxcount = maxcount;
area_type = areatype;
- SV_AreaEdicts_r (sv_areanodes);
+ SV_AreaEdicts_r(sv_areanodes);
return area_count;
}
@@ -413,16 +407,17 @@ Returns a headnode that can be used for testing or clipping an
object of mins/maxs size.
================
*/
-static mnode_t *SV_HullForEntity( edict_t *ent ) {
+static mnode_t *SV_HullForEntity(edict_t *ent)
+{
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",
- __func__, index );
+ 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];
@@ -430,7 +425,7 @@ static mnode_t *SV_HullForEntity( edict_t *ent ) {
}
// create a temp hull from bounding box sizes
- return CM_HeadnodeForBox( ent->mins, ent->maxs );
+ return CM_HeadnodeForBox(ent->mins, ent->maxs);
}
/*
@@ -438,32 +433,31 @@ static mnode_t *SV_HullForEntity( edict_t *ent ) {
SV_PointContents
=============
*/
-int SV_PointContents (vec3_t p)
+int SV_PointContents(vec3_t p)
{
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);
+ 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);
+ num = SV_AreaEdicts(p, p, touch, MAX_EDICTS, AREA_SOLID);
- for (i=0 ; i<num ; i++)
- {
+ for (i = 0; i < num; i++) {
hit = touch[i];
// might intersect, so do an exact clip
- headnode = SV_HullForEntity (hit);
+ headnode = SV_HullForEntity(hit);
- c2 = CM_TransformedPointContents (p, headnode,
- hit->s.origin, hit->s.angles);
+ c2 = CM_TransformedPointContents(p, headnode,
+ hit->s.origin, hit->s.angles);
contents |= c2;
}
@@ -488,19 +482,19 @@ SV_ClipMoveToEntities
====================
*/
-static void SV_ClipMoveToEntities( moveclip_t *clip ) {
+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);
+ 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++)
- {
+ for (i = 0; i < num; i++) {
touch = touchlist[i];
if (touch->solid == SOLID_NOT)
continue;
@@ -508,26 +502,25 @@ static void SV_ClipMoveToEntities( moveclip_t *clip ) {
continue;
if (clip->trace->allsolid)
return;
- if (clip->passedict)
- {
- if (touch->owner == clip->passedict)
+ 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;
+ if (!(clip->contentmask & CONTENTS_DEADMONSTER)
+ && (touch->svflags & SVF_DEADMONSTER))
+ continue;
// might intersect, so do an exact clip
- headnode = SV_HullForEntity (touch);
+ 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_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 );
+ CM_ClipEntity(clip->trace, &trace, touch);
}
}
@@ -537,10 +530,11 @@ static void SV_ClipMoveToEntities( moveclip_t *clip ) {
SV_TraceBounds
==================
*/
-static void SV_TraceBounds (moveclip_t *clip) {
+static void SV_TraceBounds(moveclip_t *clip)
+{
int i;
-
- for (i=0 ; i<3 ; 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;
@@ -560,26 +554,26 @@ 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.cm.cache) {
+ Com_Error(ERR_DROP, "%s: no map loaded", __func__);
}
- if( ++sv.tracecount > 10000 ) {
- Com_EPrintf( "%s: game DLL caught in infinite loop!\n", __func__ );
- memset( trace, 0, sizeof( *trace ) );
+ if (++sv.tracecount > 10000) {
+ Com_EPrintf("%s: game DLL caught in infinite loop!\n", __func__);
+ memset(trace, 0, sizeof(*trace));
trace->fraction = 1;
trace->ent = ge->edicts;
- VectorCopy( end, trace->endpos );
+ VectorCopy(end, trace->endpos);
sv.tracecount = 0;
return trace;
}
@@ -590,14 +584,14 @@ trace_t *SV_Trace( trace_t *trace,
maxs = vec3_origin;
// clip to world
- CM_BoxTrace( trace, start, end, mins, maxs,
- sv.cm.cache->nodes, contentmask );
+ 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 ) );
+ memset(&clip, 0, sizeof(clip));
clip.trace = trace;
clip.contentmask = contentmask;
clip.start = start;
@@ -605,12 +599,12 @@ trace_t *SV_Trace( trace_t *trace,
clip.mins = mins;
clip.maxs = maxs;
clip.passedict = passedict;
-
+
// create the bounding box of the entire move
- SV_TraceBounds( &clip );
+ SV_TraceBounds(&clip);
// clip to other solid entities
- SV_ClipMoveToEntities( &clip );
+ SV_ClipMoveToEntities(&clip);
return trace;
}
@@ -622,10 +616,11 @@ SV_Trace_Native
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 SV_Trace_Native(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask)
+{
trace_t trace;
- SV_Trace( &trace, start, mins, maxs, end, passedict, contentmask );
+ SV_Trace(&trace, start, mins, maxs, end, passedict, contentmask);
return trace;
}