From 7d71a7c2ee52ce78bfbeecc10409c0eb3f9953e5 Mon Sep 17 00:00:00 2001 From: Yamagi Burmeister Date: Thu, 25 Nov 2010 16:44:50 +0000 Subject: [PATCH] =?UTF-8?q?R=C3=A4ume=20sv=5Fents.c=20auf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/sv_ents.c | 886 ++++++++++++++++++++++++------------------- 1 file changed, 491 insertions(+), 395 deletions(-) diff --git a/src/server/sv_ents.c b/src/server/sv_ents.c index fbe70058..26671af2 100644 --- a/src/server/sv_ents.c +++ b/src/server/sv_ents.c @@ -1,616 +1,712 @@ /* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -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. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ + * Copyright (C) 1997-2001 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ======================================================================= + * + * Server entity handling. Just encodes the entties of a client side + * frame into network / local communication packages and sends them to + * the appropriate clients. + * + * ======================================================================= + */ #include "header/server.h" -/* -============================================================================= - -Encode a client frame onto the network channel - -============================================================================= -*/ +byte fatpvs [ 65536 / 8 ]; /* -============= -SV_EmitPacketEntities - -Writes a delta update of an entity_state_t list to the message. -============= -*/ -void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg) + * Writes a delta update of an entity_state_t list to the message. + */ +void +SV_EmitPacketEntities ( client_frame_t *from, client_frame_t *to, sizebuf_t *msg ) { - entity_state_t *oldent, *newent; - int oldindex, newindex; - int oldnum, newnum; - int from_num_entities; - int bits; + entity_state_t *oldent, *newent; + int oldindex, newindex; + int oldnum, newnum; + int from_num_entities; + int bits; - MSG_WriteByte (msg, svc_packetentities); + MSG_WriteByte( msg, svc_packetentities ); - if (!from) + if ( !from ) + { from_num_entities = 0; + } else + { from_num_entities = from->num_entities; + } newindex = 0; oldindex = 0; newent = NULL; oldent = NULL; - while (newindex < to->num_entities || oldindex < from_num_entities) + + while ( newindex < to->num_entities || oldindex < from_num_entities ) { - if (msg->cursize > MAX_MSGLEN - 150) + if ( msg->cursize > MAX_MSGLEN - 150 ) + { break; - - if (newindex >= to->num_entities) + } + + if ( newindex >= to->num_entities ) + { newnum = 9999; + } else { - newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities]; + newent = &svs.client_entities [ ( to->first_entity + newindex ) % svs.num_client_entities ]; newnum = newent->number; } - if (oldindex >= from_num_entities) + if ( oldindex >= from_num_entities ) + { oldnum = 9999; + } else { - oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities]; + oldent = &svs.client_entities [ ( from->first_entity + oldindex ) % svs.num_client_entities ]; oldnum = oldent->number; } - if (newnum == oldnum) - { // delta update from old position - // because the force parm is false, this will not result - // in any bytes being emited if the entity has not changed at all - // note that players are always 'newentities', this updates their oldorigin always - // and prevents warping - MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value); + if ( newnum == oldnum ) + { + /* delta update from old position + because the force parm is false, this will not result + in any bytes being emited if the entity has not changed at all + note that players are always 'newentities', this updates their oldorigin always + and prevents warping */ + MSG_WriteDeltaEntity( oldent, newent, msg, false, newent->number <= maxclients->value ); oldindex++; newindex++; continue; } - if (newnum < oldnum) - { // this is a new entity, send it from the baseline - MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true); + if ( newnum < oldnum ) + { + /* this is a new entity, send it from the baseline */ + MSG_WriteDeltaEntity( &sv.baselines [ newnum ], newent, msg, true, true ); newindex++; continue; } - if (newnum > oldnum) - { // the old entity isn't present in the new message + if ( newnum > oldnum ) + { + /* the old entity isn't present in the new message */ bits = U_REMOVE; - if (oldnum >= 256) + + if ( oldnum >= 256 ) + { bits |= U_NUMBER16 | U_MOREBITS1; + } - MSG_WriteByte (msg, bits&255 ); - if (bits & 0x0000ff00) - MSG_WriteByte (msg, (bits>>8)&255 ); + MSG_WriteByte( msg, bits & 255 ); - if (bits & U_NUMBER16) - MSG_WriteShort (msg, oldnum); + if ( bits & 0x0000ff00 ) + { + MSG_WriteByte( msg, ( bits >> 8 ) & 255 ); + } + + if ( bits & U_NUMBER16 ) + { + MSG_WriteShort( msg, oldnum ); + } else - MSG_WriteByte (msg, oldnum); + { + MSG_WriteByte( msg, oldnum ); + } oldindex++; continue; } } - MSG_WriteShort (msg, 0); // end of packetentities + MSG_WriteShort( msg, 0 ); } -/* -============= -SV_WritePlayerstateToClient - -============= -*/ -void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg) +void +SV_WritePlayerstateToClient ( client_frame_t *from, client_frame_t *to, sizebuf_t *msg ) { - int i; - int pflags; - player_state_t *ps, *ops; - player_state_t dummy; - int statbits; + int i; + int pflags; + player_state_t *ps, *ops; + player_state_t dummy; + int statbits; ps = &to->ps; - if (!from) + + if ( !from ) { - memset (&dummy, 0, sizeof(dummy)); + memset( &dummy, 0, sizeof ( dummy ) ); ops = &dummy; } else + { ops = &from->ps; + } - // - // determine what needs to be sent - // + /* determine what needs to be sent */ pflags = 0; - if (ps->pmove.pm_type != ops->pmove.pm_type) + if ( ps->pmove.pm_type != ops->pmove.pm_type ) + { pflags |= PS_M_TYPE; + } - if (ps->pmove.origin[0] != ops->pmove.origin[0] - || ps->pmove.origin[1] != ops->pmove.origin[1] - || ps->pmove.origin[2] != ops->pmove.origin[2] ) + if ( ( ps->pmove.origin [ 0 ] != ops->pmove.origin [ 0 ] ) || + ( ps->pmove.origin [ 1 ] != ops->pmove.origin [ 1 ] ) || + ( ps->pmove.origin [ 2 ] != ops->pmove.origin [ 2 ] ) ) + { pflags |= PS_M_ORIGIN; + } - if (ps->pmove.velocity[0] != ops->pmove.velocity[0] - || ps->pmove.velocity[1] != ops->pmove.velocity[1] - || ps->pmove.velocity[2] != ops->pmove.velocity[2] ) + if ( ( ps->pmove.velocity [ 0 ] != ops->pmove.velocity [ 0 ] ) || + ( ps->pmove.velocity [ 1 ] != ops->pmove.velocity [ 1 ] ) || + ( ps->pmove.velocity [ 2 ] != ops->pmove.velocity [ 2 ] ) ) + { pflags |= PS_M_VELOCITY; + } - if (ps->pmove.pm_time != ops->pmove.pm_time) + if ( ps->pmove.pm_time != ops->pmove.pm_time ) + { pflags |= PS_M_TIME; + } - if (ps->pmove.pm_flags != ops->pmove.pm_flags) + if ( ps->pmove.pm_flags != ops->pmove.pm_flags ) + { pflags |= PS_M_FLAGS; + } - if (ps->pmove.gravity != ops->pmove.gravity) + if ( ps->pmove.gravity != ops->pmove.gravity ) + { pflags |= PS_M_GRAVITY; + } - if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0] - || ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1] - || ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] ) + if ( ( ps->pmove.delta_angles [ 0 ] != ops->pmove.delta_angles [ 0 ] ) || + ( ps->pmove.delta_angles [ 1 ] != ops->pmove.delta_angles [ 1 ] ) || + ( ps->pmove.delta_angles [ 2 ] != ops->pmove.delta_angles [ 2 ] ) ) + { pflags |= PS_M_DELTA_ANGLES; + } - - if (ps->viewoffset[0] != ops->viewoffset[0] - || ps->viewoffset[1] != ops->viewoffset[1] - || ps->viewoffset[2] != ops->viewoffset[2] ) + if ( ( ps->viewoffset [ 0 ] != ops->viewoffset [ 0 ] ) || + ( ps->viewoffset [ 1 ] != ops->viewoffset [ 1 ] ) || + ( ps->viewoffset [ 2 ] != ops->viewoffset [ 2 ] ) ) + { pflags |= PS_VIEWOFFSET; + } - if (ps->viewangles[0] != ops->viewangles[0] - || ps->viewangles[1] != ops->viewangles[1] - || ps->viewangles[2] != ops->viewangles[2] ) + if ( ( ps->viewangles [ 0 ] != ops->viewangles [ 0 ] ) || + ( ps->viewangles [ 1 ] != ops->viewangles [ 1 ] ) || + ( ps->viewangles [ 2 ] != ops->viewangles [ 2 ] ) ) + { pflags |= PS_VIEWANGLES; + } - if (ps->kick_angles[0] != ops->kick_angles[0] - || ps->kick_angles[1] != ops->kick_angles[1] - || ps->kick_angles[2] != ops->kick_angles[2] ) + if ( ( ps->kick_angles [ 0 ] != ops->kick_angles [ 0 ] ) || + ( ps->kick_angles [ 1 ] != ops->kick_angles [ 1 ] ) || + ( ps->kick_angles [ 2 ] != ops->kick_angles [ 2 ] ) ) + { pflags |= PS_KICKANGLES; + } - if (ps->blend[0] != ops->blend[0] - || ps->blend[1] != ops->blend[1] - || ps->blend[2] != ops->blend[2] - || ps->blend[3] != ops->blend[3] ) + if ( ( ps->blend [ 0 ] != ops->blend [ 0 ] ) || + ( ps->blend [ 1 ] != ops->blend [ 1 ] ) || + ( ps->blend [ 2 ] != ops->blend [ 2 ] ) || + ( ps->blend [ 3 ] != ops->blend [ 3 ] ) ) + { pflags |= PS_BLEND; + } - if (ps->fov != ops->fov) + if ( ps->fov != ops->fov ) + { pflags |= PS_FOV; + } - if (ps->rdflags != ops->rdflags) + if ( ps->rdflags != ops->rdflags ) + { pflags |= PS_RDFLAGS; + } - if (ps->gunframe != ops->gunframe) + if ( ps->gunframe != ops->gunframe ) + { pflags |= PS_WEAPONFRAME; + } pflags |= PS_WEAPONINDEX; - // - // write it - // - MSG_WriteByte (msg, svc_playerinfo); - MSG_WriteShort (msg, pflags); + /* write it */ + MSG_WriteByte( msg, svc_playerinfo ); + MSG_WriteShort( msg, pflags ); - // - // write the pmove_state_t - // - if (pflags & PS_M_TYPE) - MSG_WriteByte (msg, ps->pmove.pm_type); - - if (pflags & PS_M_ORIGIN) + /* write the pmove_state_t */ + if ( pflags & PS_M_TYPE ) { - MSG_WriteShort (msg, ps->pmove.origin[0]); - MSG_WriteShort (msg, ps->pmove.origin[1]); - MSG_WriteShort (msg, ps->pmove.origin[2]); + MSG_WriteByte( msg, ps->pmove.pm_type ); } - if (pflags & PS_M_VELOCITY) + if ( pflags & PS_M_ORIGIN ) { - MSG_WriteShort (msg, ps->pmove.velocity[0]); - MSG_WriteShort (msg, ps->pmove.velocity[1]); - MSG_WriteShort (msg, ps->pmove.velocity[2]); + MSG_WriteShort( msg, ps->pmove.origin [ 0 ] ); + MSG_WriteShort( msg, ps->pmove.origin [ 1 ] ); + MSG_WriteShort( msg, ps->pmove.origin [ 2 ] ); } - if (pflags & PS_M_TIME) - MSG_WriteByte (msg, ps->pmove.pm_time); - - if (pflags & PS_M_FLAGS) - MSG_WriteByte (msg, ps->pmove.pm_flags); - - if (pflags & PS_M_GRAVITY) - MSG_WriteShort (msg, ps->pmove.gravity); - - if (pflags & PS_M_DELTA_ANGLES) + if ( pflags & PS_M_VELOCITY ) { - MSG_WriteShort (msg, ps->pmove.delta_angles[0]); - MSG_WriteShort (msg, ps->pmove.delta_angles[1]); - MSG_WriteShort (msg, ps->pmove.delta_angles[2]); + MSG_WriteShort( msg, ps->pmove.velocity [ 0 ] ); + MSG_WriteShort( msg, ps->pmove.velocity [ 1 ] ); + MSG_WriteShort( msg, ps->pmove.velocity [ 2 ] ); } - // - // write the rest of the player_state_t - // - if (pflags & PS_VIEWOFFSET) + if ( pflags & PS_M_TIME ) { - MSG_WriteChar (msg, ps->viewoffset[0]*4); - MSG_WriteChar (msg, ps->viewoffset[1]*4); - MSG_WriteChar (msg, ps->viewoffset[2]*4); + MSG_WriteByte( msg, ps->pmove.pm_time ); } - if (pflags & PS_VIEWANGLES) + if ( pflags & PS_M_FLAGS ) { - MSG_WriteAngle16 (msg, ps->viewangles[0]); - MSG_WriteAngle16 (msg, ps->viewangles[1]); - MSG_WriteAngle16 (msg, ps->viewangles[2]); + MSG_WriteByte( msg, ps->pmove.pm_flags ); } - if (pflags & PS_KICKANGLES) + if ( pflags & PS_M_GRAVITY ) { - MSG_WriteChar (msg, ps->kick_angles[0]*4); - MSG_WriteChar (msg, ps->kick_angles[1]*4); - MSG_WriteChar (msg, ps->kick_angles[2]*4); + MSG_WriteShort( msg, ps->pmove.gravity ); } - if (pflags & PS_WEAPONINDEX) + if ( pflags & PS_M_DELTA_ANGLES ) { - MSG_WriteByte (msg, ps->gunindex); + MSG_WriteShort( msg, ps->pmove.delta_angles [ 0 ] ); + MSG_WriteShort( msg, ps->pmove.delta_angles [ 1 ] ); + MSG_WriteShort( msg, ps->pmove.delta_angles [ 2 ] ); } - if (pflags & PS_WEAPONFRAME) + /* write the rest of the player_state_t */ + if ( pflags & PS_VIEWOFFSET ) { - MSG_WriteByte (msg, ps->gunframe); - MSG_WriteChar (msg, ps->gunoffset[0]*4); - MSG_WriteChar (msg, ps->gunoffset[1]*4); - MSG_WriteChar (msg, ps->gunoffset[2]*4); - MSG_WriteChar (msg, ps->gunangles[0]*4); - MSG_WriteChar (msg, ps->gunangles[1]*4); - MSG_WriteChar (msg, ps->gunangles[2]*4); + MSG_WriteChar( msg, ps->viewoffset [ 0 ] * 4 ); + MSG_WriteChar( msg, ps->viewoffset [ 1 ] * 4 ); + MSG_WriteChar( msg, ps->viewoffset [ 2 ] * 4 ); } - if (pflags & PS_BLEND) + if ( pflags & PS_VIEWANGLES ) { - MSG_WriteByte (msg, ps->blend[0]*255); - MSG_WriteByte (msg, ps->blend[1]*255); - MSG_WriteByte (msg, ps->blend[2]*255); - MSG_WriteByte (msg, ps->blend[3]*255); - } - if (pflags & PS_FOV) - MSG_WriteByte (msg, ps->fov); - if (pflags & PS_RDFLAGS) - MSG_WriteByte (msg, ps->rdflags); + MSG_WriteAngle16( msg, ps->viewangles [ 0 ] ); + MSG_WriteAngle16( msg, ps->viewangles [ 1 ] ); + MSG_WriteAngle16( msg, ps->viewangles [ 2 ] ); + } - // send stats + if ( pflags & PS_KICKANGLES ) + { + MSG_WriteChar( msg, ps->kick_angles [ 0 ] * 4 ); + MSG_WriteChar( msg, ps->kick_angles [ 1 ] * 4 ); + MSG_WriteChar( msg, ps->kick_angles [ 2 ] * 4 ); + } + + if ( pflags & PS_WEAPONINDEX ) + { + MSG_WriteByte( msg, ps->gunindex ); + } + + if ( pflags & PS_WEAPONFRAME ) + { + MSG_WriteByte( msg, ps->gunframe ); + MSG_WriteChar( msg, ps->gunoffset [ 0 ] * 4 ); + MSG_WriteChar( msg, ps->gunoffset [ 1 ] * 4 ); + MSG_WriteChar( msg, ps->gunoffset [ 2 ] * 4 ); + MSG_WriteChar( msg, ps->gunangles [ 0 ] * 4 ); + MSG_WriteChar( msg, ps->gunangles [ 1 ] * 4 ); + MSG_WriteChar( msg, ps->gunangles [ 2 ] * 4 ); + } + + if ( pflags & PS_BLEND ) + { + MSG_WriteByte( msg, ps->blend [ 0 ] * 255 ); + MSG_WriteByte( msg, ps->blend [ 1 ] * 255 ); + MSG_WriteByte( msg, ps->blend [ 2 ] * 255 ); + MSG_WriteByte( msg, ps->blend [ 3 ] * 255 ); + } + + if ( pflags & PS_FOV ) + { + MSG_WriteByte( msg, ps->fov ); + } + + if ( pflags & PS_RDFLAGS ) + { + MSG_WriteByte( msg, ps->rdflags ); + } + + /* send stats */ statbits = 0; - for (i=0 ; istats[i] != ops->stats[i]) - statbits |= 1<stats[i]); + + for ( i = 0; i < MAX_STATS; i++ ) + { + if ( ps->stats [ i ] != ops->stats [ i ] ) + { + statbits |= 1 << i; + } + } + + MSG_WriteLong( msg, statbits ); + + for ( i = 0; i < MAX_STATS; i++ ) + { + if ( statbits & ( 1 << i ) ) + { + MSG_WriteShort( msg, ps->stats [ i ] ); + } + } } -/* -================== -SV_WriteFrameToClient -================== -*/ -void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg) +void +SV_WriteFrameToClient ( client_t *client, sizebuf_t *msg ) { - client_frame_t *frame, *oldframe; - int lastframe; + client_frame_t *frame, *oldframe; + int lastframe; - // this is the frame we are creating - frame = &client->frames[sv.framenum & UPDATE_MASK]; + /* this is the frame we are creating */ + frame = &client->frames [ sv.framenum & UPDATE_MASK ]; - if (client->lastframe <= 0) - { // client is asking for a retransmit + if ( client->lastframe <= 0 ) + { + /* client is asking for a retransmit */ oldframe = NULL; lastframe = -1; } - else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) ) - { // client hasn't gotten a good message through in a long time + else if ( sv.framenum - client->lastframe >= ( UPDATE_BACKUP - 3 ) ) + { + /* client hasn't gotten a good message through in a long time */ oldframe = NULL; lastframe = -1; } else - { // we have a valid message to delta from - oldframe = &client->frames[client->lastframe & UPDATE_MASK]; + { + /* we have a valid message to delta from */ + oldframe = &client->frames [ client->lastframe & UPDATE_MASK ]; lastframe = client->lastframe; } - MSG_WriteByte (msg, svc_frame); - MSG_WriteLong (msg, sv.framenum); - MSG_WriteLong (msg, lastframe); // what we are delta'ing from - MSG_WriteByte (msg, client->surpressCount); // rate dropped packets + MSG_WriteByte( msg, svc_frame ); + MSG_WriteLong( msg, sv.framenum ); + MSG_WriteLong( msg, lastframe ); /* what we are delta'ing from */ + MSG_WriteByte( msg, client->surpressCount ); /* rate dropped packets */ client->surpressCount = 0; - // send over the areabits - MSG_WriteByte (msg, frame->areabytes); - SZ_Write (msg, frame->areabits, frame->areabytes); + /* send over the areabits */ + MSG_WriteByte( msg, frame->areabytes ); + SZ_Write( msg, frame->areabits, frame->areabytes ); - // delta encode the playerstate - SV_WritePlayerstateToClient (oldframe, frame, msg); + /* delta encode the playerstate */ + SV_WritePlayerstateToClient( oldframe, frame, msg ); - // delta encode the entities - SV_EmitPacketEntities (oldframe, frame, msg); + /* delta encode the entities */ + SV_EmitPacketEntities( oldframe, frame, msg ); } - /* -============================================================================= - -Build a client frame structure - -============================================================================= -*/ - -byte fatpvs[65536/8]; // 32767 is MAX_MAP_LEAFS - -/* -============ -SV_FatPVS - -The client will interpolate the view position, -so we can't use a single PVS point -=========== -*/ -void SV_FatPVS (vec3_t org) + * The client will interpolate the view position, + * so we can't use a single PVS point + */ +void +SV_FatPVS ( vec3_t org ) { - int leafs[64]; - int i, j, count; - int longs; - byte *src; - vec3_t mins, maxs; + int leafs [ 64 ]; + int i, j, count; + int longs; + byte *src; + vec3_t mins, maxs; - for (i=0 ; i<3 ; i++) + for ( i = 0; i < 3; i++ ) { - mins[i] = org[i] - 8; - maxs[i] = org[i] + 8; + mins [ i ] = org [ i ] - 8; + maxs [ i ] = org [ i ] + 8; } - count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL); - if (count < 1) - Com_Error (ERR_FATAL, "SV_FatPVS: count < 1"); - longs = (CM_NumClusters()+31)>>5; + count = CM_BoxLeafnums( mins, maxs, leafs, 64, NULL ); - // convert leafs to clusters - for (i=0 ; i> 5; + + /* convert leafs to clusters */ + for ( i = 0; i < count; i++ ) + { + leafs [ i ] = CM_LeafCluster( leafs [ i ] ); + } + + memcpy( fatpvs, CM_ClusterPVS( leafs [ 0 ] ), longs << 2 ); + + /* or in all the other leaf bits */ + for ( i = 1; i < count; i++ ) + { + for ( j = 0; j < i; j++ ) + { + if ( leafs [ i ] == leafs [ j ] ) + { break; - if (j != i) - continue; // already have the cluster we want - src = CM_ClusterPVS(leafs[i]); - for (j=0 ; jedict; - if (!clent->client) - return; // not in game yet - // this is the frame we are creating - frame = &client->frames[sv.framenum & UPDATE_MASK]; + if ( !clent->client ) + { + return; /* not in game yet */ + } - frame->senttime = svs.realtime; // save it for ping calc later + /* this is the frame we are creating */ + frame = &client->frames [ sv.framenum & UPDATE_MASK ]; - // find the client's PVS - for (i=0 ; i<3 ; i++) - org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i]; + frame->senttime = svs.realtime; /* save it for ping calc later */ - leafnum = CM_PointLeafnum (org); - clientarea = CM_LeafArea (leafnum); - clientcluster = CM_LeafCluster (leafnum); + /* find the client's PVS */ + for ( i = 0; i < 3; i++ ) + { + org [ i ] = clent->client->ps.pmove.origin [ i ] * 0.125 + clent->client->ps.viewoffset [ i ]; + } - // calculate the visible areas - frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea); + leafnum = CM_PointLeafnum( org ); + clientarea = CM_LeafArea( leafnum ); + clientcluster = CM_LeafCluster( leafnum ); - // grab the current player_state_t + /* calculate the visible areas */ + frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea ); + + /* grab the current player_state_t */ frame->ps = clent->client->ps; + SV_FatPVS( org ); + clientphs = CM_ClusterPHS( clientcluster ); - SV_FatPVS (org); - clientphs = CM_ClusterPHS (clientcluster); - - // build up the list of visible entities + /* build up the list of visible entities */ frame->num_entities = 0; frame->first_entity = svs.next_client_entities; c_fullsend = 0; - for (e=1 ; enum_edicts ; e++) + for ( e = 1; e < ge->num_edicts; e++ ) { - ent = EDICT_NUM(e); + ent = EDICT_NUM( e ); - // ignore ents without visible models - if (ent->svflags & SVF_NOCLIENT) - continue; - - // ignore ents without visible models unless they have an effect - if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound - && !ent->s.event) - continue; - - // ignore if not touching a PV leaf - if (ent != clent) + /* ignore ents without visible models */ + if ( ent->svflags & SVF_NOCLIENT ) { - // check area - if (!CM_AreasConnected (clientarea, ent->areanum)) - { // doors can legally straddle two areas, so - // we may need to check another one - if (!ent->areanum2 - || !CM_AreasConnected (clientarea, ent->areanum2)) - continue; // blocked by a door + continue; + } + + /* ignore ents without visible models unless they have an effect */ + if ( !ent->s.modelindex && !ent->s.effects && !ent->s.sound && + !ent->s.event ) + { + continue; + } + + /* ignore if not touching a PV leaf */ + if ( ent != clent ) + { + /* check area */ + if ( !CM_AreasConnected( clientarea, ent->areanum ) ) + { + /* doors can legally straddle two areas, so + we may need to check another one */ + if ( !ent->areanum2 || + !CM_AreasConnected( clientarea, ent->areanum2 ) ) + { + continue; /* blocked by a door */ + } } - // beams just check one point for PHS - if (ent->s.renderfx & RF_BEAM) + /* beams just check one point for PHS */ + if ( ent->s.renderfx & RF_BEAM ) { - l = ent->clusternums[0]; - if ( !(clientphs[l >> 3] & (1 << (l&7) )) ) + l = ent->clusternums [ 0 ]; + + if ( !( clientphs [ l >> 3 ] & ( 1 << ( l & 7 ) ) ) ) + { continue; + } } else { - // FIXME: if an ent has a model and a sound, but isn't - // in the PVS, only the PHS, clear the model - bitvector = fatpvs; + bitvector = fatpvs; - if (ent->num_clusters == -1) - { // too many leafs for individual check, go by headnode - if (!CM_HeadnodeVisible (ent->headnode, bitvector)) + if ( ent->num_clusters == -1 ) + { + /* too many leafs for individual check, go by headnode */ + if ( !CM_HeadnodeVisible( ent->headnode, bitvector ) ) + { continue; + } + c_fullsend++; } else - { // check individual leafs - for (i=0 ; i < ent->num_clusters ; i++) + { + /* check individual leafs */ + for ( i = 0; i < ent->num_clusters; i++ ) { - l = ent->clusternums[i]; - if (bitvector[l >> 3] & (1 << (l&7) )) + l = ent->clusternums [ i ]; + + if ( bitvector [ l >> 3 ] & ( 1 << ( l & 7 ) ) ) + { break; + } + } + + if ( i == ent->num_clusters ) + { + continue; /* not visible */ } - if (i == ent->num_clusters) - continue; // not visible } - if (!ent->s.modelindex) - { // don't send sounds if they will be attenuated away - vec3_t delta; - float len; + if ( !ent->s.modelindex ) + { + /* don't send sounds if they will be attenuated away */ + vec3_t delta; + float len; - VectorSubtract (org, ent->s.origin, delta); - len = VectorLength (delta); - if (len > 400) + VectorSubtract( org, ent->s.origin, delta ); + len = VectorLength( delta ); + + if ( len > 400 ) + { continue; + } } } } - // add it to the circular client_entities array - state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities]; - if (ent->s.number != e) + /* add it to the circular client_entities array */ + state = &svs.client_entities [ svs.next_client_entities % svs.num_client_entities ]; + + if ( ent->s.number != e ) { - Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n"); + Com_DPrintf( "FIXING ENT->S.NUMBER!!!\n" ); ent->s.number = e; } + *state = ent->s; - // don't mark players missiles as solid - if (ent->owner == client->edict) + /* don't mark players missiles as solid */ + if ( ent->owner == client->edict ) + { state->solid = 0; + } svs.next_client_entities++; frame->num_entities++; } } - /* -================== -SV_RecordDemoMessage - -Save everything in the world out without deltas. -Used for recording footage for merged or assembled demos -================== -*/ -void SV_RecordDemoMessage (void) + * Save everything in the world out without deltas. + * Used for recording footage for merged or assembled demos + */ +void +SV_RecordDemoMessage ( void ) { - int e; - edict_t *ent; - entity_state_t nostate; - sizebuf_t buf; - byte buf_data[32768]; - int len; + int e; + edict_t *ent; + entity_state_t nostate; + sizebuf_t buf; + byte buf_data [ 32768 ]; + int len; - if (!svs.demofile) - return; - - memset (&nostate, 0, sizeof(nostate)); - SZ_Init (&buf, buf_data, sizeof(buf_data)); - - // write a frame message that doesn't contain a player_state_t - MSG_WriteByte (&buf, svc_frame); - MSG_WriteLong (&buf, sv.framenum); - - MSG_WriteByte (&buf, svc_packetentities); - - e = 1; - ent = EDICT_NUM(e); - while (e < ge->num_edicts) + if ( !svs.demofile ) { - // ignore ents without visible models unless they have an effect - if (ent->inuse && - ent->s.number && - (ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) && - !(ent->svflags & SVF_NOCLIENT)) - MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true); - - e++; - ent = EDICT_NUM(e); + return; } - MSG_WriteShort (&buf, 0); // end of packetentities + memset( &nostate, 0, sizeof ( nostate ) ); + SZ_Init( &buf, buf_data, sizeof ( buf_data ) ); - // now add the accumulated multicast information - SZ_Write (&buf, svs.demo_multicast.data, svs.demo_multicast.cursize); - SZ_Clear (&svs.demo_multicast); + /* write a frame message that doesn't contain a player_state_t */ + MSG_WriteByte( &buf, svc_frame ); + MSG_WriteLong( &buf, sv.framenum ); - // now write the entire message to the file, prefixed by the length - len = LittleLong (buf.cursize); - fwrite (&len, 4, 1, svs.demofile); - fwrite (buf.data, buf.cursize, 1, svs.demofile); + MSG_WriteByte( &buf, svc_packetentities ); + + e = 1; + ent = EDICT_NUM( e ); + + while ( e < ge->num_edicts ) + { + /* ignore ents without visible models unless they have an effect */ + if ( ent->inuse && + ent->s.number && + ( ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event ) && + !( ent->svflags & SVF_NOCLIENT ) ) + { + MSG_WriteDeltaEntity( &nostate, &ent->s, &buf, false, true ); + } + + e++; + ent = EDICT_NUM( e ); + } + + MSG_WriteShort( &buf, 0 ); /* end of packetentities */ + + /* now add the accumulated multicast information */ + SZ_Write( &buf, svs.demo_multicast.data, svs.demo_multicast.cursize ); + SZ_Clear( &svs.demo_multicast ); + + /* now write the entire message to the file, prefixed by the length */ + len = LittleLong( buf.cursize ); + fwrite( &len, 4, 1, svs.demofile ); + fwrite( buf.data, buf.cursize, 1, svs.demofile ); }