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.c172
1 files changed, 75 insertions, 97 deletions
diff --git a/source/sv_world.c b/source/sv_world.c
index 52c6b8b..54f5e30 100644
--- a/source/sv_world.c
+++ b/source/sv_world.c
@@ -243,10 +243,46 @@ void PF_UnlinkEdict (edict_t *ent) {
ent->area.prev = ent->area.next = NULL;
}
+static int SV_CalcSolid( vec3_t mins, vec3_t maxs ) {
+ int i, j, k;
+
+ // assume that x/y are equal and symetric
+ i = maxs[0] / 8;
+ clamp( i, 1, 31 );
+
+ // z is not symetric
+ j = ( -mins[2] ) / 8;
+ clamp( j, 1, 31 );
+
+ // and z maxs can be negative...
+ k = ( maxs[2] + 32 ) / 8;
+ clamp( k, 1, 63 );
+
+ return ( k << 10 ) | ( j << 5 ) | i;
+}
+
+static int SV_CalcSolid32( vec3_t mins, vec3_t maxs ) {
+ int i, j, k;
+
+ // assume that x/y are equal and symetric
+ i = maxs[0];
+ clamp( i, 1, 255 );
+
+ // z is not symetric
+ j = -mins[2];
+ clamp( j, 1, 255 );
+
+ // and z maxs can be negative...
+ k = maxs[2] + 32768;
+ clamp( k, 1, 65535 );
+
+ return ( k << 16 ) | ( j << 8 ) | i;
+}
void PF_LinkEdict (edict_t *ent) {
areanode_t *node;
- int i, j, k;
+ server_entity_t *sent;
+ int entnum;
if (ent->area.prev)
PF_UnlinkEdict (ent); // unlink from old position
@@ -261,37 +297,29 @@ void PF_LinkEdict (edict_t *ent) {
return;
}
+ entnum = NUM_FOR_EDICT( ent );
+ sent = &sv.entities[entnum];
+
// encode the size into the entity_state for client prediction
- if (ent->solid == SOLID_BBOX && !(ent->svflags & SVF_DEADMONSTER))
- { // assume that x/y are equal and symetric
- i = ent->maxs[0]/8;
- if (i<1)
- i = 1;
- if (i>31)
- i = 31;
-
- // z is not symetric
- j = (-ent->mins[2])/8;
- if (j<1)
- j = 1;
- if (j>31)
- j = 31;
-
- // and z maxs can be negative...
- k = (ent->maxs[2]+32)/8;
- if (k<1)
- k = 1;
- if (k>63)
- k = 63;
-
- ent->s.solid = (k<<10) | (j<<5) | i;
- }
- else if (ent->solid == SOLID_BSP)
- {
+ switch( ent->solid ) {
+ case SOLID_BBOX:
+ if( ( ent->svflags & SVF_DEADMONSTER ) || VectorCompare( ent->mins, ent->maxs ) ) {
+ ent->s.solid = 0;
+ sent->solid32 = 0;
+ } else {
+ ent->s.solid = SV_CalcSolid( ent->mins, ent->maxs );
+ sent->solid32 = SV_CalcSolid32( ent->mins, ent->maxs );
+ }
+ break;
+ case SOLID_BSP:
ent->s.solid = 31; // a solid_bbox will never create this value
- }
- else
+ sent->solid32 = 31; // FIXME: use 255?
+ break;
+ default:
ent->s.solid = 0;
+ sent->solid32 = 0;
+ break;
+ }
SV_LinkEdict( &sv.cm, ent );
@@ -434,7 +462,7 @@ int SV_PointContents (vec3_t p)
cnode_t *headnode;
if( !sv.cm.cache ) {
- Com_Error( ERR_DROP, "SV_PointContents: no map loaded" );
+ Com_Error( ERR_DROP, "%s: no map loaded", __func__ );
}
// get base contents from world
@@ -545,80 +573,15 @@ SV_Trace
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 (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask) {
- moveclip_t clip;
- trace_t trace;
-
- if( !sv.cm.cache ) {
- Com_Error( ERR_DROP, "SV_Trace: no map loaded" );
- }
-
- 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;
-}
-
-/*
-==================
-SV_Trace_Old
-
-HACK: different compilers (and even different versions
-of the same compiler) handle returning of structures differently.
-
-This function is intended to be binary-compatible with
-game DLLs built by earlier versions of GCC.
-
-Game DLLs built by MSVC seems to behave similary to old GCC
-(except they additionaly require pointer to destination
-structure to be retured in EAX register), so this function is linked in
-when building with MinGW, under assumption that no mods built with MinGW ever exist.
-==================
-*/
-trace_t *SV_Trace_Old (trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
+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, "SV_Trace: no map loaded" );
+ Com_Error( ERR_DROP, "%s: no map loaded", __func__ );
}
if( ++sv.tracecount > 10000 ) {
@@ -661,3 +624,18 @@ trace_t *SV_Trace_Old (trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, v
return trace;
}
+/*
+==================
+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 trace;
+
+ SV_Trace( &trace, start, mins, maxs, end, passedict, contentmask );
+
+ return trace;
+}
+