Annotation of quake2/server/sv_ents.c, revision 1.1.1.3

1.1.1.3 ! root        1: /*
        !             2: Copyright (C) 1997-2001 Id Software, Inc.
        !             3: 
        !             4: This program is free software; you can redistribute it and/or
        !             5: modify it under the terms of the GNU General Public License
        !             6: as published by the Free Software Foundation; either version 2
        !             7: of the License, or (at your option) any later version.
        !             8: 
        !             9: This program is distributed in the hope that it will be useful,
        !            10: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
        !            12: 
        !            13: See the GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with this program; if not, write to the Free Software
        !            17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            18: 
        !            19: */
1.1       root       20: 
                     21: #include "server.h"
                     22: 
                     23: /*
                     24: =============================================================================
                     25: 
                     26: Encode a client frame onto the network channel
                     27: 
                     28: =============================================================================
                     29: */
                     30: 
1.1.1.2   root       31: #if 0
                     32: 
                     33: // because there can be a lot of projectiles, there is a special
                     34: // network protocol for them
                     35: #define        MAX_PROJECTILES         64
                     36: edict_t        *projectiles[MAX_PROJECTILES];
                     37: int            numprojs;
                     38: cvar_t  *sv_projectiles;
                     39: 
                     40: qboolean SV_AddProjectileUpdate (edict_t *ent)
                     41: {
                     42:        if (!sv_projectiles)
                     43:                sv_projectiles = Cvar_Get("sv_projectiles", "1", 0);
                     44: 
                     45:        if (!sv_projectiles->value)
                     46:                return false;
                     47: 
                     48:        if (!(ent->svflags & SVF_PROJECTILE))
                     49:                return false;
                     50:        if (numprojs == MAX_PROJECTILES)
                     51:                return true;
                     52: 
                     53:        projectiles[numprojs++] = ent;
                     54:        return true;
                     55: }
                     56: 
                     57: void SV_EmitProjectileUpdate (sizebuf_t *msg)
                     58: {
                     59:        byte    bits[16];       // [modelindex] [48 bits] xyz p y 12 12 12 8 8 [entitynum] [e2]
                     60:        int             n, i;
                     61:        edict_t *ent;
                     62:        int             x, y, z, p, yaw;
                     63:        int len;
                     64: 
                     65:        if (!numprojs)
                     66:                return;
                     67: 
                     68:        MSG_WriteByte (msg, numprojs);
                     69: 
                     70:        for (n=0 ; n<numprojs ; n++)
                     71:        {
                     72:                ent = projectiles[n];
                     73:                x = (int)(ent->s.origin[0]+4096)>>1;
                     74:                y = (int)(ent->s.origin[1]+4096)>>1;
                     75:                z = (int)(ent->s.origin[2]+4096)>>1;
                     76:                p = (int)(256*ent->s.angles[0]/360)&255;
                     77:                yaw = (int)(256*ent->s.angles[1]/360)&255;
                     78: 
                     79:                len = 0;
                     80:                bits[len++] = x;
                     81:                bits[len++] = (x>>8) | (y<<4);
                     82:                bits[len++] = (y>>4);
                     83:                bits[len++] = z;
                     84:                bits[len++] = (z>>8);
                     85:                if (ent->s.effects & EF_BLASTER)
                     86:                        bits[len-1] |= 64;
                     87: 
                     88:                if (ent->s.old_origin[0] != ent->s.origin[0] ||
                     89:                        ent->s.old_origin[1] != ent->s.origin[1] ||
                     90:                        ent->s.old_origin[2] != ent->s.origin[2]) {
                     91:                        bits[len-1] |= 128;
                     92:                        x = (int)(ent->s.old_origin[0]+4096)>>1;
                     93:                        y = (int)(ent->s.old_origin[1]+4096)>>1;
                     94:                        z = (int)(ent->s.old_origin[2]+4096)>>1;
                     95:                        bits[len++] = x;
                     96:                        bits[len++] = (x>>8) | (y<<4);
                     97:                        bits[len++] = (y>>4);
                     98:                        bits[len++] = z;
                     99:                        bits[len++] = (z>>8);
                    100:                }
                    101: 
                    102:                bits[len++] = p;
                    103:                bits[len++] = yaw;
                    104:                bits[len++] = ent->s.modelindex;
                    105: 
                    106:                bits[len++] = (ent->s.number & 0x7f);
                    107:                if (ent->s.number > 255) {
                    108:                        bits[len-1] |= 128;
                    109:                        bits[len++] = (ent->s.number >> 7);
                    110:                }
                    111: 
                    112:                for (i=0 ; i<len ; i++)
                    113:                        MSG_WriteByte (msg, bits[i]);
                    114:        }
                    115: }
                    116: #endif
1.1       root      117: 
                    118: /*
                    119: =============
                    120: SV_EmitPacketEntities
                    121: 
                    122: Writes a delta update of an entity_state_t list to the message.
                    123: =============
                    124: */
                    125: void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
                    126: {
                    127:        entity_state_t  *oldent, *newent;
                    128:        int             oldindex, newindex;
                    129:        int             oldnum, newnum;
                    130:        int             from_num_entities;
                    131:        int             bits;
                    132: 
1.1.1.2   root      133: #if 0
                    134:        if (numprojs)
                    135:                MSG_WriteByte (msg, svc_packetentities2);
                    136:        else
                    137: #endif
                    138:                MSG_WriteByte (msg, svc_packetentities);
1.1       root      139: 
                    140:        if (!from)
                    141:                from_num_entities = 0;
                    142:        else
                    143:                from_num_entities = from->num_entities;
                    144: 
                    145:        newindex = 0;
                    146:        oldindex = 0;
                    147:        while (newindex < to->num_entities || oldindex < from_num_entities)
                    148:        {
                    149:                if (newindex >= to->num_entities)
                    150:                        newnum = 9999;
                    151:                else
                    152:                {
                    153:                        newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities];
                    154:                        newnum = newent->number;
                    155:                }
                    156: 
                    157:                if (oldindex >= from_num_entities)
                    158:                        oldnum = 9999;
                    159:                else
                    160:                {
                    161:                        oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities];
                    162:                        oldnum = oldent->number;
                    163:                }
                    164: 
                    165:                if (newnum == oldnum)
                    166:                {       // delta update from old position
                    167:                        // because the force parm is false, this will not result
                    168:                        // in any bytes being emited if the entity has not changed at all
1.1.1.2   root      169:                        // note that players are always 'newentities', this updates their oldorigin always
                    170:                        // and prevents warping
                    171:                        MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
1.1       root      172:                        oldindex++;
                    173:                        newindex++;
                    174:                        continue;
                    175:                }
                    176: 
                    177:                if (newnum < oldnum)
                    178:                {       // this is a new entity, send it from the baseline
1.1.1.2   root      179:                        MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
1.1       root      180:                        newindex++;
                    181:                        continue;
                    182:                }
                    183: 
                    184:                if (newnum > oldnum)
                    185:                {       // the old entity isn't present in the new message
                    186:                        bits = U_REMOVE;
                    187:                        if (oldnum >= 256)
                    188:                                bits |= U_NUMBER16 | U_MOREBITS1;
                    189: 
                    190:                        MSG_WriteByte (msg,     bits&255 );
                    191:                        if (bits & 0x0000ff00)
                    192:                                MSG_WriteByte (msg,     (bits>>8)&255 );
                    193: 
                    194:                        if (bits & U_NUMBER16)
                    195:                                MSG_WriteShort (msg, oldnum);
                    196:                        else
                    197:                                MSG_WriteByte (msg, oldnum);
                    198: 
                    199:                        oldindex++;
                    200:                        continue;
                    201:                }
                    202:        }
                    203: 
                    204:        MSG_WriteShort (msg, 0);        // end of packetentities
1.1.1.2   root      205: 
                    206: #if 0
                    207:        if (numprojs)
                    208:                SV_EmitProjectileUpdate(msg);
                    209: #endif
1.1       root      210: }
                    211: 
                    212: 
                    213: 
                    214: /*
                    215: =============
                    216: SV_WritePlayerstateToClient
                    217: 
                    218: =============
                    219: */
                    220: void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
                    221: {
                    222:        int                             i;
                    223:        int                             pflags;
                    224:        player_state_t  *ps, *ops;
                    225:        player_state_t  dummy;
                    226:        int                             statbits;
                    227: 
                    228:        ps = &to->ps;
                    229:        if (!from)
                    230:        {
                    231:                memset (&dummy, 0, sizeof(dummy));
                    232:                ops = &dummy;
                    233:        }
                    234:        else
                    235:                ops = &from->ps;
                    236: 
                    237:        //
                    238:        // determine what needs to be sent
                    239:        //
                    240:        pflags = 0;
                    241: 
                    242:        if (ps->pmove.pm_type != ops->pmove.pm_type)
                    243:                pflags |= PS_M_TYPE;
                    244: 
                    245:        if (ps->pmove.origin[0] != ops->pmove.origin[0]
                    246:                || ps->pmove.origin[1] != ops->pmove.origin[1]
                    247:                || ps->pmove.origin[2] != ops->pmove.origin[2] )
                    248:                pflags |= PS_M_ORIGIN;
                    249: 
                    250:        if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
                    251:                || ps->pmove.velocity[1] != ops->pmove.velocity[1]
                    252:                || ps->pmove.velocity[2] != ops->pmove.velocity[2] )
                    253:                pflags |= PS_M_VELOCITY;
                    254: 
                    255:        if (ps->pmove.pm_time != ops->pmove.pm_time)
                    256:                pflags |= PS_M_TIME;
                    257: 
                    258:        if (ps->pmove.pm_flags != ops->pmove.pm_flags)
                    259:                pflags |= PS_M_FLAGS;
                    260: 
                    261:        if (ps->pmove.gravity != ops->pmove.gravity)
                    262:                pflags |= PS_M_GRAVITY;
                    263: 
                    264:        if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
                    265:                || ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
                    266:                || ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
                    267:                pflags |= PS_M_DELTA_ANGLES;
                    268: 
                    269: 
                    270:        if (ps->viewoffset[0] != ops->viewoffset[0]
                    271:                || ps->viewoffset[1] != ops->viewoffset[1]
                    272:                || ps->viewoffset[2] != ops->viewoffset[2] )
                    273:                pflags |= PS_VIEWOFFSET;
                    274: 
                    275:        if (ps->viewangles[0] != ops->viewangles[0]
                    276:                || ps->viewangles[1] != ops->viewangles[1]
                    277:                || ps->viewangles[2] != ops->viewangles[2] )
                    278:                pflags |= PS_VIEWANGLES;
                    279: 
                    280:        if (ps->kick_angles[0] != ops->kick_angles[0]
                    281:                || ps->kick_angles[1] != ops->kick_angles[1]
                    282:                || ps->kick_angles[2] != ops->kick_angles[2] )
                    283:                pflags |= PS_KICKANGLES;
                    284: 
                    285:        if (ps->blend[0] != ops->blend[0]
                    286:                || ps->blend[1] != ops->blend[1]
                    287:                || ps->blend[2] != ops->blend[2]
                    288:                || ps->blend[3] != ops->blend[3] )
                    289:                pflags |= PS_BLEND;
                    290: 
                    291:        if (ps->fov != ops->fov)
                    292:                pflags |= PS_FOV;
                    293: 
                    294:        if (ps->rdflags != ops->rdflags)
                    295:                pflags |= PS_RDFLAGS;
                    296: 
                    297:        if (ps->gunframe != ops->gunframe)
                    298:                pflags |= PS_WEAPONFRAME;
                    299: 
                    300:        pflags |= PS_WEAPONINDEX;
                    301: 
                    302:        //
                    303:        // write it
                    304:        //
                    305:        MSG_WriteByte (msg, svc_playerinfo);
                    306:        MSG_WriteShort (msg, pflags);
                    307: 
                    308:        //
                    309:        // write the pmove_state_t
                    310:        //
                    311:        if (pflags & PS_M_TYPE)
                    312:                MSG_WriteByte (msg, ps->pmove.pm_type);
                    313: 
                    314:        if (pflags & PS_M_ORIGIN)
                    315:        {
                    316:                MSG_WriteShort (msg, ps->pmove.origin[0]);
                    317:                MSG_WriteShort (msg, ps->pmove.origin[1]);
                    318:                MSG_WriteShort (msg, ps->pmove.origin[2]);
                    319:        }
                    320: 
                    321:        if (pflags & PS_M_VELOCITY)
                    322:        {
                    323:                MSG_WriteShort (msg, ps->pmove.velocity[0]);
                    324:                MSG_WriteShort (msg, ps->pmove.velocity[1]);
                    325:                MSG_WriteShort (msg, ps->pmove.velocity[2]);
                    326:        }
                    327: 
                    328:        if (pflags & PS_M_TIME)
                    329:                MSG_WriteByte (msg, ps->pmove.pm_time);
                    330: 
                    331:        if (pflags & PS_M_FLAGS)
                    332:                MSG_WriteByte (msg, ps->pmove.pm_flags);
                    333: 
                    334:        if (pflags & PS_M_GRAVITY)
                    335:                MSG_WriteShort (msg, ps->pmove.gravity);
                    336: 
                    337:        if (pflags & PS_M_DELTA_ANGLES)
                    338:        {
                    339:                MSG_WriteShort (msg, ps->pmove.delta_angles[0]);
                    340:                MSG_WriteShort (msg, ps->pmove.delta_angles[1]);
                    341:                MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
                    342:        }
                    343: 
                    344:        //
                    345:        // write the rest of the player_state_t
                    346:        //
                    347:        if (pflags & PS_VIEWOFFSET)
                    348:        {
                    349:                MSG_WriteChar (msg, ps->viewoffset[0]*4);
                    350:                MSG_WriteChar (msg, ps->viewoffset[1]*4);
                    351:                MSG_WriteChar (msg, ps->viewoffset[2]*4);
                    352:        }
                    353: 
                    354:        if (pflags & PS_VIEWANGLES)
                    355:        {
                    356:                MSG_WriteAngle16 (msg, ps->viewangles[0]);
                    357:                MSG_WriteAngle16 (msg, ps->viewangles[1]);
                    358:                MSG_WriteAngle16 (msg, ps->viewangles[2]);
                    359:        }
                    360: 
                    361:        if (pflags & PS_KICKANGLES)
                    362:        {
                    363:                MSG_WriteChar (msg, ps->kick_angles[0]*4);
                    364:                MSG_WriteChar (msg, ps->kick_angles[1]*4);
                    365:                MSG_WriteChar (msg, ps->kick_angles[2]*4);
                    366:        }
                    367: 
                    368:        if (pflags & PS_WEAPONINDEX)
                    369:        {
                    370:                MSG_WriteByte (msg, ps->gunindex);
                    371:        }
                    372: 
                    373:        if (pflags & PS_WEAPONFRAME)
                    374:        {
                    375:                MSG_WriteByte (msg, ps->gunframe);
                    376:                MSG_WriteChar (msg, ps->gunoffset[0]*4);
                    377:                MSG_WriteChar (msg, ps->gunoffset[1]*4);
                    378:                MSG_WriteChar (msg, ps->gunoffset[2]*4);
                    379:                MSG_WriteChar (msg, ps->gunangles[0]*4);
                    380:                MSG_WriteChar (msg, ps->gunangles[1]*4);
                    381:                MSG_WriteChar (msg, ps->gunangles[2]*4);
                    382:        }
                    383: 
                    384:        if (pflags & PS_BLEND)
                    385:        {
                    386:                MSG_WriteByte (msg, ps->blend[0]*255);
                    387:                MSG_WriteByte (msg, ps->blend[1]*255);
                    388:                MSG_WriteByte (msg, ps->blend[2]*255);
                    389:                MSG_WriteByte (msg, ps->blend[3]*255);
                    390:        }
                    391:        if (pflags & PS_FOV)
                    392:                MSG_WriteByte (msg, ps->fov);
                    393:        if (pflags & PS_RDFLAGS)
                    394:                MSG_WriteByte (msg, ps->rdflags);
                    395: 
                    396:        // send stats
                    397:        statbits = 0;
                    398:        for (i=0 ; i<MAX_STATS ; i++)
                    399:                if (ps->stats[i] != ops->stats[i])
                    400:                        statbits |= 1<<i;
                    401:        MSG_WriteLong (msg, statbits);
                    402:        for (i=0 ; i<MAX_STATS ; i++)
                    403:                if (statbits & (1<<i) )
                    404:                        MSG_WriteShort (msg, ps->stats[i]);
                    405: }
                    406: 
                    407: 
                    408: /*
                    409: ==================
                    410: SV_WriteFrameToClient
                    411: ==================
                    412: */
                    413: void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg)
                    414: {
                    415:        client_frame_t          *frame, *oldframe;
                    416:        int                                     lastframe;
                    417: 
                    418: //Com_Printf ("%i -> %i\n", client->lastframe, sv.framenum);
                    419:        // this is the frame we are creating
                    420:        frame = &client->frames[sv.framenum & UPDATE_MASK];
                    421: 
                    422:        if (client->lastframe <= 0)
                    423:        {       // client is asking for a retransmit
                    424:                oldframe = NULL;
                    425:                lastframe = -1;
                    426:        }
                    427:        else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
                    428:        {       // client hasn't gotten a good message through in a long time
                    429: //             Com_Printf ("%s: Delta request from out-of-date packet.\n", client->name);
                    430:                oldframe = NULL;
                    431:                lastframe = -1;
                    432:        }
                    433:        else
                    434:        {       // we have a valid message to delta from
                    435:                oldframe = &client->frames[client->lastframe & UPDATE_MASK];
                    436:                lastframe = client->lastframe;
                    437:        }
                    438: 
                    439:        MSG_WriteByte (msg, svc_frame);
                    440:        MSG_WriteLong (msg, sv.framenum);
                    441:        MSG_WriteLong (msg, lastframe); // what we are delta'ing from
                    442:        MSG_WriteByte (msg, client->surpressCount);     // rate dropped packets
                    443:        client->surpressCount = 0;
                    444: 
                    445:        // send over the areabits
                    446:        MSG_WriteByte (msg, frame->areabytes);
                    447:        SZ_Write (msg, frame->areabits, frame->areabytes);
                    448: 
                    449:        // delta encode the playerstate
                    450:        SV_WritePlayerstateToClient (oldframe, frame, msg);
                    451: 
                    452:        // delta encode the entities
                    453:        SV_EmitPacketEntities (oldframe, frame, msg);
                    454: }
                    455: 
                    456: 
                    457: /*
                    458: =============================================================================
                    459: 
                    460: Build a client frame structure
                    461: 
                    462: =============================================================================
                    463: */
                    464: 
                    465: byte           fatpvs[65536/8];        // 32767 is MAX_MAP_LEAFS
                    466: 
                    467: /*
                    468: ============
                    469: SV_FatPVS
                    470: 
                    471: The client will interpolate the view position,
                    472: so we can't use a single PVS point
                    473: ===========
                    474: */
                    475: void SV_FatPVS (vec3_t org)
                    476: {
                    477:        int             leafs[64];
                    478:        int             i, j, count;
                    479:        int             longs;
                    480:        byte    *src;
                    481:        vec3_t  mins, maxs;
                    482: 
                    483:        for (i=0 ; i<3 ; i++)
                    484:        {
                    485:                mins[i] = org[i] - 8;
                    486:                maxs[i] = org[i] + 8;
                    487:        }
                    488: 
                    489:        count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL);
                    490:        if (count < 1)
                    491:                Com_Error (ERR_FATAL, "SV_FatPVS: count < 1");
                    492:        longs = (CM_NumClusters()+31)>>5;
                    493: 
                    494:        // convert leafs to clusters
                    495:        for (i=0 ; i<count ; i++)
                    496:                leafs[i] = CM_LeafCluster(leafs[i]);
                    497: 
                    498:        memcpy (fatpvs, CM_ClusterPVS(leafs[0]), longs<<2);
                    499:        // or in all the other leaf bits
                    500:        for (i=1 ; i<count ; i++)
                    501:        {
                    502:                for (j=0 ; j<i ; j++)
                    503:                        if (leafs[i] == leafs[j])
                    504:                                break;
                    505:                if (j != i)
                    506:                        continue;               // already have the cluster we want
                    507:                src = CM_ClusterPVS(leafs[i]);
                    508:                for (j=0 ; j<longs ; j++)
                    509:                        ((long *)fatpvs)[j] |= ((long *)src)[j];
                    510:        }
                    511: }
                    512: 
                    513: 
                    514: /*
                    515: =============
                    516: SV_BuildClientFrame
                    517: 
                    518: Decides which entities are going to be visible to the client, and
                    519: copies off the playerstat and areabits.
                    520: =============
                    521: */
                    522: void SV_BuildClientFrame (client_t *client)
                    523: {
                    524:        int             e, i;
                    525:        vec3_t  org;
                    526:        edict_t *ent;
                    527:        edict_t *clent;
                    528:        client_frame_t  *frame;
                    529:        entity_state_t  *state;
                    530:        int             l;
                    531:        int             clientarea, clientcluster;
                    532:        int             leafnum;
                    533:        int             c_fullsend;
                    534:        byte    *clientphs;
                    535:        byte    *bitvector;
                    536: 
                    537:        clent = client->edict;
                    538:        if (!clent->client)
                    539:                return;         // not in game yet
                    540: 
1.1.1.2   root      541: #if 0
                    542:        numprojs = 0; // no projectiles yet
                    543: #endif
                    544: 
1.1       root      545:        // this is the frame we are creating
                    546:        frame = &client->frames[sv.framenum & UPDATE_MASK];
                    547: 
1.1.1.2   root      548:        frame->senttime = svs.realtime; // save it for ping calc later
                    549: 
1.1       root      550:        // find the client's PVS
                    551:        for (i=0 ; i<3 ; i++)
                    552:                org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
                    553: 
                    554:        leafnum = CM_PointLeafnum (org);
                    555:        clientarea = CM_LeafArea (leafnum);
                    556:        clientcluster = CM_LeafCluster (leafnum);
                    557: 
                    558:        // calculate the visible areas
                    559:        frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
                    560: 
                    561:        // grab the current player_state_t
                    562:        frame->ps = clent->client->ps;
                    563: 
                    564: 
                    565:        SV_FatPVS (org);
                    566:        clientphs = CM_ClusterPHS (clientcluster);
                    567: 
                    568:        // build up the list of visible entities
                    569:        frame->num_entities = 0;
                    570:        frame->first_entity = svs.next_client_entities;
                    571: 
                    572:        c_fullsend = 0;
                    573: 
                    574:        for (e=1 ; e<ge->num_edicts ; e++)
                    575:        {
                    576:                ent = EDICT_NUM(e);
                    577: 
                    578:                // ignore ents without visible models
                    579:                if (ent->svflags & SVF_NOCLIENT)
                    580:                        continue;
                    581: 
                    582:                // ignore ents without visible models unless they have an effect
                    583:                if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
                    584:                        && !ent->s.event)
                    585:                        continue;
                    586: 
                    587:                // ignore if not touching a PV leaf
                    588:                if (ent != clent)
                    589:                {
                    590:                        // check area
                    591:                        if (!CM_AreasConnected (clientarea, ent->areanum))
                    592:                        {       // doors can legally straddle two areas, so
                    593:                                // we may need to check another one
                    594:                                if (!ent->areanum2
                    595:                                        || !CM_AreasConnected (clientarea, ent->areanum2))
                    596:                                        continue;               // blocked by a door
                    597:                        }
                    598: 
                    599:                        // beams just check one point for PHS
                    600:                        if (ent->s.renderfx & RF_BEAM)
                    601:                        {
                    602:                                l = ent->clusternums[0];
                    603:                                if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
                    604:                                        continue;
                    605:                        }
                    606:                        else
                    607:                        {
                    608:                                // FIXME: if an ent has a model and a sound, but isn't
                    609:                                // in the PVS, only the PHS, clear the model
                    610:                                if (ent->s.sound)
                    611:                                {
                    612:                                        bitvector = fatpvs;     //clientphs;
                    613:                                }
                    614:                                else
                    615:                                        bitvector = fatpvs;
                    616: 
                    617:                                if (ent->num_clusters == -1)
                    618:                                {       // too many leafs for individual check, go by headnode
                    619:                                        if (!CM_HeadnodeVisible (ent->headnode, bitvector))
                    620:                                                continue;
                    621:                                        c_fullsend++;
                    622:                                }
                    623:                                else
                    624:                                {       // check individual leafs
                    625:                                        for (i=0 ; i < ent->num_clusters ; i++)
                    626:                                        {
                    627:                                                l = ent->clusternums[i];
                    628:                                                if (bitvector[l >> 3] & (1 << (l&7) ))
                    629:                                                        break;
                    630:                                        }
                    631:                                        if (i == ent->num_clusters)
                    632:                                                continue;               // not visible
                    633:                                }
                    634: 
                    635:                                if (!ent->s.modelindex)
                    636:                                {       // don't send sounds if they will be attenuated away
                    637:                                        vec3_t  delta;
                    638:                                        float   len;
                    639: 
                    640:                                        VectorSubtract (org, ent->s.origin, delta);
                    641:                                        len = VectorLength (delta);
                    642:                                        if (len > 400)
                    643:                                                continue;
                    644:                                }
                    645:                        }
                    646:                }
                    647: 
1.1.1.2   root      648: #if 0
                    649:                if (SV_AddProjectileUpdate(ent))
                    650:                        continue; // added as a special projectile
                    651: #endif
                    652: 
1.1       root      653:                // add it to the circular client_entities array
                    654:                state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities];
                    655:                if (ent->s.number != e)
                    656:                {
                    657:                        Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
                    658:                        ent->s.number = e;
                    659:                }
                    660:                *state = ent->s;
                    661: 
                    662:                // don't mark players missiles as solid
                    663:                if (ent->owner == client->edict)
                    664:                        state->solid = 0;
                    665: 
                    666:                svs.next_client_entities++;
                    667:                frame->num_entities++;
                    668:        }
                    669: }
                    670: 
                    671: 
                    672: /*
                    673: ==================
                    674: SV_RecordDemoMessage
                    675: 
                    676: Save everything in the world out without deltas.
                    677: Used for recording footage for merged or assembled demos
                    678: ==================
                    679: */
                    680: void SV_RecordDemoMessage (void)
                    681: {
                    682:        int                     e;
                    683:        edict_t         *ent;
                    684:        entity_state_t  nostate;
                    685:        sizebuf_t       buf;
                    686:        byte            buf_data[32768];
                    687:        int                     len;
                    688: 
                    689:        if (!svs.demofile)
                    690:                return;
                    691: 
                    692:        memset (&nostate, 0, sizeof(nostate));
                    693:        SZ_Init (&buf, buf_data, sizeof(buf_data));
                    694: 
                    695:        // write a frame message that doesn't contain a player_state_t
                    696:        MSG_WriteByte (&buf, svc_frame);
                    697:        MSG_WriteLong (&buf, sv.framenum);
                    698: 
                    699:        MSG_WriteByte (&buf, svc_packetentities);
                    700: 
1.1.1.2   root      701:        e = 1;
                    702:        ent = EDICT_NUM(e);
                    703:        while (e < ge->num_edicts) 
1.1       root      704:        {
                    705:                // ignore ents without visible models unless they have an effect
1.1.1.2   root      706:                if (ent->inuse &&
                    707:                        ent->s.number && 
                    708:                        (ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) && 
                    709:                        !(ent->svflags & SVF_NOCLIENT))
                    710:                        MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true);
1.1       root      711: 
1.1.1.2   root      712:                e++;
                    713:                ent = EDICT_NUM(e);
1.1       root      714:        }
                    715: 
                    716:        MSG_WriteShort (&buf, 0);               // end of packetentities
                    717: 
                    718:        // now add the accumulated multicast information
                    719:        SZ_Write (&buf, svs.demo_multicast.data, svs.demo_multicast.cursize);
                    720:        SZ_Clear (&svs.demo_multicast);
                    721: 
                    722:        // now write the entire message to the file, prefixed by the length
                    723:        len = LittleLong (buf.cursize);
                    724:        fwrite (&len, 4, 1, svs.demofile);
                    725:        fwrite (buf.data, buf.cursize, 1, svs.demofile);
                    726: }
                    727: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.