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

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

unix.superglobalmegacorp.com

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