Annotation of quake2/client/cl_ents.c, revision 1.1.1.3

1.1       root        1: // cl_ents.c -- entity parsing and management
1.1.1.2   root        2: 
1.1       root        3: #include "client.h"
                      4: 
1.1.1.2   root        5: 
1.1       root        6: extern struct model_s  *cl_mod_powerscreen;
1.1.1.2   root        7: 
1.1.1.3 ! root        8: //PGM
        !             9: int    vidref_val;
        !            10: //PGM
        !            11: 
1.1       root       12: /*
                     13: =========================================================================
1.1.1.2   root       14: 
1.1       root       15: FRAME PARSING
1.1.1.2   root       16: 
1.1       root       17: =========================================================================
                     18: */
1.1.1.2   root       19: 
                     20: #if 0
                     21: 
                     22: typedef struct
                     23: {
                     24:        int             modelindex;
                     25:        int             num; // entity number
                     26:        int             effects;
                     27:        vec3_t  origin;
                     28:        vec3_t  oldorigin;
                     29:        vec3_t  angles;
                     30:        qboolean present;
                     31: } projectile_t;
                     32: 
                     33: #define        MAX_PROJECTILES 64
                     34: projectile_t   cl_projectiles[MAX_PROJECTILES];
                     35: 
                     36: void CL_ClearProjectiles (void)
                     37: {
                     38:        int i;
                     39: 
                     40:        for (i = 0; i < MAX_PROJECTILES; i++) {
                     41: //             if (cl_projectiles[i].present)
                     42: //                     Com_DPrintf("PROJ: %d CLEARED\n", cl_projectiles[i].num);
                     43:                cl_projectiles[i].present = false;
                     44:        }
                     45: }
                     46: 
                     47: /*
                     48: =====================
                     49: CL_ParseProjectiles
                     50: 
1.1.1.3 ! root       51: Flechettes are passed as efficient temporary entities
1.1.1.2   root       52: =====================
                     53: */
                     54: void CL_ParseProjectiles (void)
                     55: {
                     56:        int             i, c, j;
                     57:        byte    bits[8];
                     58:        byte    b;
                     59:        projectile_t    pr;
                     60:        int lastempty = -1;
                     61:        qboolean old = false;
                     62: 
                     63:        c = MSG_ReadByte (&net_message);
                     64:        for (i=0 ; i<c ; i++)
                     65:        {
                     66:                bits[0] = MSG_ReadByte (&net_message);
                     67:                bits[1] = MSG_ReadByte (&net_message);
                     68:                bits[2] = MSG_ReadByte (&net_message);
                     69:                bits[3] = MSG_ReadByte (&net_message);
                     70:                bits[4] = MSG_ReadByte (&net_message);
                     71:                pr.origin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096;
                     72:                pr.origin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096;
                     73:                pr.origin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096;
                     74:                VectorCopy(pr.origin, pr.oldorigin);
                     75: 
                     76:                if (bits[4] & 64)
                     77:                        pr.effects = EF_BLASTER;
                     78:                else
                     79:                        pr.effects = 0;
                     80: 
                     81:                if (bits[4] & 128) {
                     82:                        old = true;
                     83:                        bits[0] = MSG_ReadByte (&net_message);
                     84:                        bits[1] = MSG_ReadByte (&net_message);
                     85:                        bits[2] = MSG_ReadByte (&net_message);
                     86:                        bits[3] = MSG_ReadByte (&net_message);
                     87:                        bits[4] = MSG_ReadByte (&net_message);
                     88:                        pr.oldorigin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096;
                     89:                        pr.oldorigin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096;
                     90:                        pr.oldorigin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096;
                     91:                }
                     92: 
                     93:                bits[0] = MSG_ReadByte (&net_message);
                     94:                bits[1] = MSG_ReadByte (&net_message);
                     95:                bits[2] = MSG_ReadByte (&net_message);
                     96: 
                     97:                pr.angles[0] = 360*bits[0]/256;
                     98:                pr.angles[1] = 360*bits[1]/256;
                     99:                pr.modelindex = bits[2];
                    100: 
                    101:                b = MSG_ReadByte (&net_message);
                    102:                pr.num = (b & 0x7f);
                    103:                if (b & 128) // extra entity number byte
                    104:                        pr.num |= (MSG_ReadByte (&net_message) << 7);
                    105: 
                    106:                pr.present = true;
                    107: 
                    108:                // find if this projectile already exists from previous frame 
                    109:                for (j = 0; j < MAX_PROJECTILES; j++) {
                    110:                        if (cl_projectiles[j].modelindex) {
                    111:                                if (cl_projectiles[j].num == pr.num) {
                    112:                                        // already present, set up oldorigin for interpolation
                    113:                                        if (!old)
                    114:                                                VectorCopy(cl_projectiles[j].origin, pr.oldorigin);
                    115:                                        cl_projectiles[j] = pr;
                    116:                                        break;
                    117:                                }
                    118:                        } else
                    119:                                lastempty = j;
                    120:                }
                    121: 
                    122:                // not present previous frame, add it
                    123:                if (j == MAX_PROJECTILES) {
                    124:                        if (lastempty != -1) {
                    125:                                cl_projectiles[lastempty] = pr;
                    126:                        }
                    127:                }
                    128:        }
                    129: }
                    130: 
                    131: /*
                    132: =============
                    133: CL_LinkProjectiles
                    134: 
                    135: =============
                    136: */
                    137: void CL_AddProjectiles (void)
                    138: {
                    139:        int             i, j;
                    140:        projectile_t    *pr;
                    141:        entity_t                ent;
                    142: 
                    143:        memset (&ent, 0, sizeof(ent));
                    144: 
                    145:        for (i=0, pr=cl_projectiles ; i < MAX_PROJECTILES ; i++, pr++)
                    146:        {
                    147:                // grab an entity to fill in
                    148:                if (pr->modelindex < 1)
                    149:                        continue;
                    150:                if (!pr->present) {
                    151:                        pr->modelindex = 0;
                    152:                        continue; // not present this frame (it was in the previous frame)
                    153:                }
                    154: 
                    155:                ent.model = cl.model_draw[pr->modelindex];
                    156: 
                    157:                // interpolate origin
                    158:                for (j=0 ; j<3 ; j++)
                    159:                {
                    160:                        ent.origin[j] = ent.oldorigin[j] = pr->oldorigin[j] + cl.lerpfrac * 
                    161:                                (pr->origin[j] - pr->oldorigin[j]);
                    162: 
                    163:                }
                    164: 
                    165:                if (pr->effects & EF_BLASTER)
                    166:                        CL_BlasterTrail (pr->oldorigin, ent.origin);
                    167:                V_AddLight (pr->origin, 200, 1, 1, 0);
                    168: 
                    169:                VectorCopy (pr->angles, ent.angles);
                    170:                V_AddEntity (&ent);
                    171:        }
                    172: }
                    173: #endif
                    174: 
1.1       root      175: /*
                    176: =================
                    177: CL_ParseEntityBits
                    178: 
                    179: Returns the entity number and the header bits
                    180: =================
                    181: */
                    182: int    bitcounts[32];  /// just for protocol profiling
                    183: int CL_ParseEntityBits (unsigned *bits)
                    184: {
                    185:        unsigned        b, total;
                    186:        int                     i;
1.1.1.3 ! root      187:        int                     number;
1.1       root      188: 
                    189:        total = MSG_ReadByte (&net_message);
                    190:        if (total & U_MOREBITS1)
                    191:        {
                    192:                b = MSG_ReadByte (&net_message);
                    193:                total |= b<<8;
                    194:        }
                    195:        if (total & U_MOREBITS2)
                    196:        {
                    197:                b = MSG_ReadByte (&net_message);
                    198:                total |= b<<16;
                    199:        }
                    200:        if (total & U_MOREBITS3)
                    201:        {
                    202:                b = MSG_ReadByte (&net_message);
                    203:                total |= b<<24;
                    204:        }
                    205: 
                    206:        // count the bits for net profiling
                    207:        for (i=0 ; i<32 ; i++)
                    208:                if (total&(1<<i))
                    209:                        bitcounts[i]++;
                    210: 
                    211:        if (total & U_NUMBER16)
                    212:                number = MSG_ReadShort (&net_message);
                    213:        else
                    214:                number = MSG_ReadByte (&net_message);
                    215: 
                    216:        *bits = total;
                    217: 
                    218:        return number;
                    219: }
1.1.1.2   root      220: 
1.1       root      221: /*
                    222: ==================
                    223: CL_ParseDelta
1.1.1.2   root      224: 
1.1       root      225: Can go from either a baseline or a previous packet_entity
                    226: ==================
                    227: */
                    228: void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int bits)
                    229: {
                    230:        // set everything to the state we are delta'ing from
                    231:        *to = *from;
1.1.1.2   root      232: 
                    233:        VectorCopy (from->origin, to->old_origin);
1.1       root      234:        to->number = number;
1.1.1.2   root      235: 
1.1       root      236:        if (bits & U_MODEL)
                    237:                to->modelindex = MSG_ReadByte (&net_message);
                    238:        if (bits & U_MODEL2)
                    239:                to->modelindex2 = MSG_ReadByte (&net_message);
                    240:        if (bits & U_MODEL3)
                    241:                to->modelindex3 = MSG_ReadByte (&net_message);
                    242:        if (bits & U_MODEL4)
                    243:                to->modelindex4 = MSG_ReadByte (&net_message);
                    244:                
                    245:        if (bits & U_FRAME8)
                    246:                to->frame = MSG_ReadByte (&net_message);
                    247:        if (bits & U_FRAME16)
                    248:                to->frame = MSG_ReadShort (&net_message);
1.1.1.2   root      249: 
1.1       root      250:        if ((bits & U_SKIN8) && (bits & U_SKIN16))              //used for laser colors
                    251:                to->skinnum = MSG_ReadLong(&net_message);
                    252:        else if (bits & U_SKIN8)
                    253:                to->skinnum = MSG_ReadByte(&net_message);
                    254:        else if (bits & U_SKIN16)
                    255:                to->skinnum = MSG_ReadShort(&net_message);
                    256: 
                    257:        if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
                    258:                to->effects = MSG_ReadLong(&net_message);
                    259:        else if (bits & U_EFFECTS8)
                    260:                to->effects = MSG_ReadByte(&net_message);
                    261:        else if (bits & U_EFFECTS16)
                    262:                to->effects = MSG_ReadShort(&net_message);
1.1.1.2   root      263: 
1.1       root      264:        if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
                    265:                to->renderfx = MSG_ReadLong(&net_message);
                    266:        else if (bits & U_RENDERFX8)
                    267:                to->renderfx = MSG_ReadByte(&net_message);
                    268:        else if (bits & U_RENDERFX16)
                    269:                to->renderfx = MSG_ReadShort(&net_message);
1.1.1.2   root      270: 
1.1       root      271:        if (bits & U_ORIGIN1)
                    272:                to->origin[0] = MSG_ReadCoord (&net_message);
                    273:        if (bits & U_ORIGIN2)
                    274:                to->origin[1] = MSG_ReadCoord (&net_message);
                    275:        if (bits & U_ORIGIN3)
                    276:                to->origin[2] = MSG_ReadCoord (&net_message);
                    277:                
                    278:        if (bits & U_ANGLE1)
                    279:                to->angles[0] = MSG_ReadAngle(&net_message);
                    280:        if (bits & U_ANGLE2)
                    281:                to->angles[1] = MSG_ReadAngle(&net_message);
                    282:        if (bits & U_ANGLE3)
                    283:                to->angles[2] = MSG_ReadAngle(&net_message);
1.1.1.2   root      284: 
1.1       root      285:        if (bits & U_OLDORIGIN)
                    286:                MSG_ReadPos (&net_message, to->old_origin);
1.1.1.2   root      287: 
1.1       root      288:        if (bits & U_SOUND)
                    289:                to->sound = MSG_ReadByte (&net_message);
                    290: 
                    291:        if (bits & U_EVENT)
                    292:                to->event = MSG_ReadByte (&net_message);
                    293:        else
                    294:                to->event = 0;
                    295: 
                    296:        if (bits & U_SOLID)
                    297:                to->solid = MSG_ReadShort (&net_message);
                    298: }
                    299: 
                    300: /*
                    301: ==================
                    302: CL_DeltaEntity
                    303: 
                    304: Parses deltas from the given base and adds the resulting entity
                    305: to the current frame
                    306: ==================
                    307: */
                    308: void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits)
                    309: {
                    310:        centity_t       *ent;
                    311:        entity_state_t  *state;
                    312: 
                    313:        ent = &cl_entities[newnum];
                    314: 
                    315:        state = &cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)];
                    316:        cl.parse_entities++;
                    317:        frame->num_entities++;
                    318: 
                    319:        CL_ParseDelta (old, state, newnum, bits);
                    320: 
                    321:        // some data changes will force no lerping
                    322:        if (state->modelindex != ent->current.modelindex
                    323:                || state->modelindex2 != ent->current.modelindex2
                    324:                || state->modelindex3 != ent->current.modelindex3
                    325:                || state->modelindex4 != ent->current.modelindex4
                    326:                || abs(state->origin[0] - ent->current.origin[0]) > 512
                    327:                || abs(state->origin[1] - ent->current.origin[1]) > 512
                    328:                || abs(state->origin[2] - ent->current.origin[2]) > 512
                    329:                || state->event == EV_PLAYER_TELEPORT
1.1.1.2   root      330:                || state->event == EV_OTHER_TELEPORT
1.1       root      331:                )
                    332:        {
                    333:                ent->serverframe = -99;
                    334:        }
                    335: 
                    336:        if (ent->serverframe != cl.frame.serverframe - 1)
                    337:        {       // wasn't in last update, so initialize some things
                    338:                ent->trailcount = 1024;         // for diminishing rocket / grenade trails
                    339:                // duplicate the current state so lerping doesn't hurt anything
                    340:                ent->prev = *state;
1.1.1.2   root      341:                if (state->event == EV_OTHER_TELEPORT)
                    342:                {
                    343:                        VectorCopy (state->origin, ent->prev.origin);
                    344:                        VectorCopy (state->origin, ent->lerp_origin);
                    345:                }
                    346:                else
                    347:                {
                    348:                        VectorCopy (state->old_origin, ent->prev.origin);
                    349:                        VectorCopy (state->old_origin, ent->lerp_origin);
                    350:                }
1.1       root      351:        }
                    352:        else
                    353:        {       // shuffle the last state to previous
                    354:                ent->prev = ent->current;
                    355:        }
                    356: 
                    357:        ent->serverframe = cl.frame.serverframe;
                    358:        ent->current = *state;
                    359: }
1.1.1.2   root      360: 
1.1       root      361: /*
                    362: ==================
                    363: CL_ParsePacketEntities
1.1.1.2   root      364: 
1.1       root      365: An svc_packetentities has just been parsed, deal with the
                    366: rest of the data stream.
                    367: ==================
                    368: */
                    369: void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
                    370: {
                    371:        int                     newnum;
                    372:        int                     bits;
                    373:        entity_state_t  *oldstate;
                    374:        int                     oldindex, oldnum;
                    375: 
                    376:        newframe->parse_entities = cl.parse_entities;
                    377:        newframe->num_entities = 0;
                    378: 
                    379:        // delta from the entities present in oldframe
                    380:        oldindex = 0;
                    381:        if (!oldframe)
                    382:                oldnum = 99999;
                    383:        else
                    384:        {
                    385:                if (oldindex >= oldframe->num_entities)
                    386:                        oldnum = 99999;
                    387:                else
                    388:                {
                    389:                        oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    390:                        oldnum = oldstate->number;
                    391:                }
                    392:        }
1.1.1.2   root      393: 
1.1       root      394:        while (1)
                    395:        {
                    396:                newnum = CL_ParseEntityBits (&bits);
                    397:                if (newnum >= MAX_EDICTS)
                    398:                        Com_Error (ERR_DROP,"CL_ParsePacketEntities: bad number:%i", newnum);
                    399: 
                    400:                if (net_message.readcount > net_message.cursize)
                    401:                        Com_Error (ERR_DROP,"CL_ParsePacketEntities: end of message");
                    402: 
                    403:                if (!newnum)
                    404:                        break;
                    405: 
                    406:                while (oldnum < newnum)
                    407:                {       // one or more entities from the old packet are unchanged
                    408:                        if (cl_shownet->value == 3)
                    409:                                Com_Printf ("   unchanged: %i\n", oldnum);
                    410:                        CL_DeltaEntity (newframe, oldnum, oldstate, 0);
                    411:                        
                    412:                        oldindex++;
                    413: 
                    414:                        if (oldindex >= oldframe->num_entities)
                    415:                                oldnum = 99999;
                    416:                        else
                    417:                        {
                    418:                                oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    419:                                oldnum = oldstate->number;
                    420:                        }
                    421:                }
                    422: 
                    423:                if (bits & U_REMOVE)
                    424:                {       // the entity present in oldframe is not in the current frame
                    425:                        if (cl_shownet->value == 3)
                    426:                                Com_Printf ("   remove: %i\n", newnum);
                    427:                        if (oldnum != newnum)
                    428:                                Com_Printf ("U_REMOVE: oldnum != newnum\n");
                    429: 
                    430:                        oldindex++;
                    431: 
                    432:                        if (oldindex >= oldframe->num_entities)
                    433:                                oldnum = 99999;
                    434:                        else
                    435:                        {
                    436:                                oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    437:                                oldnum = oldstate->number;
                    438:                        }
                    439:                        continue;
                    440:                }
                    441: 
                    442:                if (oldnum == newnum)
                    443:                {       // delta from previous state
                    444:                        if (cl_shownet->value == 3)
                    445:                                Com_Printf ("   delta: %i\n", newnum);
                    446:                        CL_DeltaEntity (newframe, newnum, oldstate, bits);
                    447: 
                    448:                        oldindex++;
                    449: 
                    450:                        if (oldindex >= oldframe->num_entities)
                    451:                                oldnum = 99999;
                    452:                        else
                    453:                        {
                    454:                                oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    455:                                oldnum = oldstate->number;
                    456:                        }
                    457:                        continue;
                    458:                }
                    459: 
                    460:                if (oldnum > newnum)
                    461:                {       // delta from baseline
                    462:                        if (cl_shownet->value == 3)
                    463:                                Com_Printf ("   baseline: %i\n", newnum);
                    464:                        CL_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits);
                    465:                        continue;
                    466:                }
                    467: 
                    468:        }
                    469: 
                    470:        // any remaining entities in the old frame are copied over
                    471:        while (oldnum != 99999)
                    472:        {       // one or more entities from the old packet are unchanged
                    473:                if (cl_shownet->value == 3)
                    474:                        Com_Printf ("   unchanged: %i\n", oldnum);
                    475:                CL_DeltaEntity (newframe, oldnum, oldstate, 0);
                    476:                
                    477:                oldindex++;
                    478: 
                    479:                if (oldindex >= oldframe->num_entities)
                    480:                        oldnum = 99999;
                    481:                else
                    482:                {
                    483:                        oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
                    484:                        oldnum = oldstate->number;
                    485:                }
                    486:        }
                    487: }
1.1.1.2   root      488: 
                    489: 
                    490: 
1.1       root      491: /*
                    492: ===================
                    493: CL_ParsePlayerstate
                    494: ===================
                    495: */
                    496: void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe)
                    497: {
                    498:        int                     flags;
                    499:        player_state_t  *state;
                    500:        int                     i;
                    501:        int                     statbits;
1.1.1.2   root      502: 
1.1       root      503:        state = &newframe->playerstate;
                    504: 
                    505:        // clear to old value before delta parsing
                    506:        if (oldframe)
                    507:                *state = oldframe->playerstate;
                    508:        else
                    509:                memset (state, 0, sizeof(*state));
1.1.1.2   root      510: 
1.1       root      511:        flags = MSG_ReadShort (&net_message);
                    512: 
                    513:        //
                    514:        // parse the pmove_state_t
                    515:        //
                    516:        if (flags & PS_M_TYPE)
                    517:                state->pmove.pm_type = MSG_ReadByte (&net_message);
                    518: 
                    519:        if (flags & PS_M_ORIGIN)
                    520:        {
                    521:                state->pmove.origin[0] = MSG_ReadShort (&net_message);
                    522:                state->pmove.origin[1] = MSG_ReadShort (&net_message);
                    523:                state->pmove.origin[2] = MSG_ReadShort (&net_message);
                    524:        }
                    525: 
                    526:        if (flags & PS_M_VELOCITY)
                    527:        {
                    528:                state->pmove.velocity[0] = MSG_ReadShort (&net_message);
                    529:                state->pmove.velocity[1] = MSG_ReadShort (&net_message);
                    530:                state->pmove.velocity[2] = MSG_ReadShort (&net_message);
                    531:        }
                    532: 
                    533:        if (flags & PS_M_TIME)
                    534:                state->pmove.pm_time = MSG_ReadByte (&net_message);
                    535: 
                    536:        if (flags & PS_M_FLAGS)
                    537:                state->pmove.pm_flags = MSG_ReadByte (&net_message);
                    538: 
                    539:        if (flags & PS_M_GRAVITY)
                    540:                state->pmove.gravity = MSG_ReadShort (&net_message);
                    541: 
                    542:        if (flags & PS_M_DELTA_ANGLES)
                    543:        {
                    544:                state->pmove.delta_angles[0] = MSG_ReadShort (&net_message);
                    545:                state->pmove.delta_angles[1] = MSG_ReadShort (&net_message);
                    546:                state->pmove.delta_angles[2] = MSG_ReadShort (&net_message);
                    547:        }
                    548: 
                    549:        if (cl.attractloop)
                    550:                state->pmove.pm_type = PM_FREEZE;               // demo playback
                    551: 
                    552:        //
                    553:        // parse the rest of the player_state_t
                    554:        //
                    555:        if (flags & PS_VIEWOFFSET)
                    556:        {
                    557:                state->viewoffset[0] = MSG_ReadChar (&net_message) * 0.25;
                    558:                state->viewoffset[1] = MSG_ReadChar (&net_message) * 0.25;
                    559:                state->viewoffset[2] = MSG_ReadChar (&net_message) * 0.25;
                    560:        }
                    561: 
                    562:        if (flags & PS_VIEWANGLES)
                    563:        {
                    564:                state->viewangles[0] = MSG_ReadAngle16 (&net_message);
                    565:                state->viewangles[1] = MSG_ReadAngle16 (&net_message);
                    566:                state->viewangles[2] = MSG_ReadAngle16 (&net_message);
                    567:        }
                    568: 
                    569:        if (flags & PS_KICKANGLES)
                    570:        {
                    571:                state->kick_angles[0] = MSG_ReadChar (&net_message) * 0.25;
                    572:                state->kick_angles[1] = MSG_ReadChar (&net_message) * 0.25;
                    573:                state->kick_angles[2] = MSG_ReadChar (&net_message) * 0.25;
                    574:        }
1.1.1.2   root      575: 
1.1       root      576:        if (flags & PS_WEAPONINDEX)
                    577:        {
                    578:                state->gunindex = MSG_ReadByte (&net_message);
                    579:        }
1.1.1.2   root      580: 
1.1       root      581:        if (flags & PS_WEAPONFRAME)
                    582:        {
                    583:                state->gunframe = MSG_ReadByte (&net_message);
                    584:                state->gunoffset[0] = MSG_ReadChar (&net_message)*0.25;
                    585:                state->gunoffset[1] = MSG_ReadChar (&net_message)*0.25;
                    586:                state->gunoffset[2] = MSG_ReadChar (&net_message)*0.25;
                    587:                state->gunangles[0] = MSG_ReadChar (&net_message)*0.25;
                    588:                state->gunangles[1] = MSG_ReadChar (&net_message)*0.25;
                    589:                state->gunangles[2] = MSG_ReadChar (&net_message)*0.25;
                    590:        }
1.1.1.2   root      591: 
1.1       root      592:        if (flags & PS_BLEND)
                    593:        {
                    594:                state->blend[0] = MSG_ReadByte (&net_message)/255.0;
                    595:                state->blend[1] = MSG_ReadByte (&net_message)/255.0;
                    596:                state->blend[2] = MSG_ReadByte (&net_message)/255.0;
                    597:                state->blend[3] = MSG_ReadByte (&net_message)/255.0;
                    598:        }
1.1.1.2   root      599: 
1.1       root      600:        if (flags & PS_FOV)
                    601:                state->fov = MSG_ReadByte (&net_message);
1.1.1.2   root      602: 
1.1       root      603:        if (flags & PS_RDFLAGS)
                    604:                state->rdflags = MSG_ReadByte (&net_message);
1.1.1.2   root      605: 
1.1       root      606:        // parse stats
                    607:        statbits = MSG_ReadLong (&net_message);
                    608:        for (i=0 ; i<MAX_STATS ; i++)
                    609:                if (statbits & (1<<i) )
                    610:                        state->stats[i] = MSG_ReadShort(&net_message);
                    611: }
1.1.1.2   root      612: 
                    613: 
1.1       root      614: /*
                    615: ==================
                    616: CL_FireEntityEvents
                    617: 
                    618: ==================
                    619: */
                    620: void CL_FireEntityEvents (frame_t *frame)
                    621: {
                    622:        entity_state_t          *s1;
                    623:        int                                     pnum, num;
                    624: 
                    625:        for (pnum = 0 ; pnum<frame->num_entities ; pnum++)
                    626:        {
                    627:                num = (frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1);
                    628:                s1 = &cl_parse_entities[num];
                    629:                if (s1->event)
                    630:                        CL_EntityEvent (s1);
                    631: 
                    632:                // EF_TELEPORTER acts like an event, but is not cleared each frame
                    633:                if (s1->effects & EF_TELEPORTER)
                    634:                        CL_TeleporterParticles (s1);
                    635:        }
                    636: }
                    637: 
                    638: 
                    639: /*
                    640: ================
                    641: CL_ParseFrame
                    642: ================
                    643: */
                    644: void CL_ParseFrame (void)
                    645: {
                    646:        int                     cmd;
                    647:        int                     len;
                    648:        frame_t         *old;
1.1.1.2   root      649: 
1.1       root      650:        memset (&cl.frame, 0, sizeof(cl.frame));
1.1.1.2   root      651: 
                    652: #if 0
                    653:        CL_ClearProjectiles(); // clear projectiles for new frame
                    654: #endif
                    655: 
1.1       root      656:        cl.frame.serverframe = MSG_ReadLong (&net_message);
                    657:        cl.frame.deltaframe = MSG_ReadLong (&net_message);
                    658:        cl.frame.servertime = cl.frame.serverframe*100;
                    659: 
                    660:        // BIG HACK to let old demos continue to work
                    661:        if (cls.serverProtocol != 26)
                    662:                cl.surpressCount = MSG_ReadByte (&net_message);
                    663: 
                    664:        if (cl_shownet->value == 3)
                    665:                Com_Printf ("   frame:%i  delta:%i\n", cl.frame.serverframe,
                    666:                cl.frame.deltaframe);
                    667: 
                    668:        // If the frame is delta compressed from data that we
                    669:        // no longer have available, we must suck up the rest of
                    670:        // the frame, but not use it, then ask for a non-compressed
                    671:        // message 
                    672:        if (cl.frame.deltaframe <= 0)
                    673:        {
                    674:                cl.frame.valid = true;          // uncompressed frame
                    675:                old = NULL;
                    676:                cls.demowaiting = false;        // we can start recording now
                    677:        }
                    678:        else
                    679:        {
                    680:                old = &cl.frames[cl.frame.deltaframe & UPDATE_MASK];
                    681:                if (!old->valid)
                    682:                {       // should never happen
                    683:                        Com_Printf ("Delta from invalid frame (not supposed to happen!).\n");
                    684:                }
                    685:                if (old->serverframe != cl.frame.deltaframe)
                    686:                {       // The frame that the server did the delta from
                    687:                        // is too old, so we can't reconstruct it properly.
                    688:                        Com_Printf ("Delta frame too old.\n");
                    689:                }
                    690:                else if (cl.parse_entities - old->parse_entities > MAX_PARSE_ENTITIES-128)
                    691:                {
                    692:                        Com_Printf ("Delta parse_entities too old.\n");
                    693:                }
                    694:                else
                    695:                        cl.frame.valid = true;  // valid delta parse
                    696:        }
1.1.1.2   root      697: 
1.1       root      698:        // clamp time 
                    699:        if (cl.time > cl.frame.servertime)
                    700:                cl.time = cl.frame.servertime;
                    701:        else if (cl.time < cl.frame.servertime - 100)
                    702:                cl.time = cl.frame.servertime - 100;
                    703: 
                    704:        // read areabits
                    705:        len = MSG_ReadByte (&net_message);
                    706:        MSG_ReadData (&net_message, &cl.frame.areabits, len);
                    707: 
                    708:        // read playerinfo
                    709:        cmd = MSG_ReadByte (&net_message);
                    710:        SHOWNET(svc_strings[cmd]);
                    711:        if (cmd != svc_playerinfo)
                    712:                Com_Error (ERR_DROP, "CL_ParseFrame: not playerinfo");
                    713:        CL_ParsePlayerstate (old, &cl.frame);
                    714: 
                    715:        // read packet entities
                    716:        cmd = MSG_ReadByte (&net_message);
                    717:        SHOWNET(svc_strings[cmd]);
                    718:        if (cmd != svc_packetentities)
                    719:                Com_Error (ERR_DROP, "CL_ParseFrame: not packetentities");
                    720:        CL_ParsePacketEntities (old, &cl.frame);
                    721: 
1.1.1.2   root      722: #if 0
                    723:        if (cmd == svc_packetentities2)
                    724:                CL_ParseProjectiles();
                    725: #endif
                    726: 
1.1       root      727:        // save the frame off in the backup array for later delta comparisons
                    728:        cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;
                    729: 
                    730:        if (cl.frame.valid)
                    731:        {
                    732:                // getting a valid frame message ends the connection process
                    733:                if (cls.state != ca_active)
                    734:                {
                    735:                        cls.state = ca_active;
                    736:                        cl.force_refdef = true;
                    737:                        cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125;
                    738:                        cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125;
                    739:                        cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2]*0.125;
                    740:                        VectorCopy (cl.frame.playerstate.viewangles, cl.predicted_angles);
                    741:                        if (cls.disable_servercount != cl.servercount
                    742:                                && cl.refresh_prepped)
                    743:                                SCR_EndLoadingPlaque ();        // get rid of loading plaque
                    744:                }
                    745:                cl.sound_prepped = true;        // can start mixing ambient sounds
                    746:        
                    747:                // fire entity events
                    748:                CL_FireEntityEvents (&cl.frame);
                    749:                CL_CheckPredictionError ();
                    750:        }
                    751: }
1.1.1.2   root      752: 
1.1       root      753: /*
                    754: ==========================================================================
                    755: 
                    756: INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS
                    757: 
                    758: ==========================================================================
                    759: */
                    760: 
1.1.1.2   root      761: struct model_s *S_RegisterSexedModel (entity_state_t *ent, char *base)
                    762: {
                    763:        int                             n;
                    764:        char                    *p;
                    765:        struct model_s  *mdl;
                    766:        char                    model[MAX_QPATH];
                    767:        char                    buffer[MAX_QPATH];
                    768: 
                    769:        // determine what model the client is using
                    770:        model[0] = 0;
                    771:        n = CS_PLAYERSKINS + ent->number - 1;
                    772:        if (cl.configstrings[n][0])
                    773:        {
                    774:                p = strchr(cl.configstrings[n], '\\');
                    775:                if (p)
                    776:                {
                    777:                        p += 1;
                    778:                        strcpy(model, p);
                    779:                        p = strchr(model, '/');
                    780:                        if (p)
                    781:                                *p = 0;
                    782:                }
                    783:        }
                    784:        // if we can't figure it out, they're male
                    785:        if (!model[0])
                    786:                strcpy(model, "male");
                    787: 
                    788:        Com_sprintf (buffer, sizeof(buffer), "players/%s/%s", model, base+1);
                    789:        mdl = re.RegisterModel(buffer);
                    790:        if (!mdl) {
                    791:                // not found, try default weapon model
                    792:                Com_sprintf (buffer, sizeof(buffer), "players/%s/weapon.md2", model);
                    793:                mdl = re.RegisterModel(buffer);
                    794:                if (!mdl) {
                    795:                        // no, revert to the male model
                    796:                        Com_sprintf (buffer, sizeof(buffer), "players/%s/%s", "male", base+1);
                    797:                        mdl = re.RegisterModel(buffer);
                    798:                        if (!mdl) {
                    799:                                // last try, default male weapon.md2
                    800:                                Com_sprintf (buffer, sizeof(buffer), "players/male/weapon.md2");
                    801:                                mdl = re.RegisterModel(buffer);
                    802:                        }
                    803:                } 
                    804:        }
                    805: 
                    806:        return mdl;
                    807: }
                    808: 
1.1       root      809: /*
                    810: ===============
                    811: CL_AddPacketEntities
                    812: 
                    813: ===============
                    814: */
                    815: void CL_AddPacketEntities (frame_t *frame)
                    816: {
                    817:        entity_t                        ent;
                    818:        entity_state_t          *s1;
                    819:        float                           autorotate;
                    820:        int                                     i;
                    821:        int                                     pnum;
                    822:        centity_t                       *cent;
                    823:        int                                     autoanim;
                    824:        clientinfo_t            *ci;
1.1.1.3 ! root      825:        unsigned int            effects, renderfx;
1.1       root      826: 
                    827:        // bonus items rotate at a fixed rate
                    828:        autorotate = anglemod(cl.time/10);
                    829: 
                    830:        // brush models can auto animate their frames
                    831:        autoanim = 2*cl.time/1000;
                    832: 
                    833:        memset (&ent, 0, sizeof(ent));
                    834: 
                    835:        for (pnum = 0 ; pnum<frame->num_entities ; pnum++)
                    836:        {
                    837:                s1 = &cl_parse_entities[(frame->parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)];
                    838: 
                    839:                cent = &cl_entities[s1->number];
                    840: 
                    841:                effects = s1->effects;
                    842:                renderfx = s1->renderfx;
                    843: 
                    844:                        // set frame
                    845:                if (effects & EF_ANIM01)
                    846:                        ent.frame = autoanim & 1;
                    847:                else if (effects & EF_ANIM23)
                    848:                        ent.frame = 2 + (autoanim & 1);
                    849:                else if (effects & EF_ANIM_ALL)
                    850:                        ent.frame = autoanim;
                    851:                else if (effects & EF_ANIM_ALLFAST)
                    852:                        ent.frame = cl.time / 100;
                    853:                else
                    854:                        ent.frame = s1->frame;
                    855: 
                    856:                // quad and pent can do different things on client
                    857:                if (effects & EF_PENT)
                    858:                {
                    859:                        effects &= ~EF_PENT;
                    860:                        effects |= EF_COLOR_SHELL;
                    861:                        renderfx |= RF_SHELL_RED;
                    862:                }
                    863: 
                    864:                if (effects & EF_QUAD)
                    865:                {
                    866:                        effects &= ~EF_QUAD;
                    867:                        effects |= EF_COLOR_SHELL;
                    868:                        renderfx |= RF_SHELL_BLUE;
                    869:                }
1.1.1.3 ! root      870: //======
        !           871: // PMM
        !           872:                if (effects & EF_DOUBLE)
        !           873:                {
        !           874:                        effects &= ~EF_DOUBLE;
        !           875:                        effects |= EF_COLOR_SHELL;
        !           876:                        renderfx |= RF_SHELL_DOUBLE;
        !           877:                }
1.1       root      878: 
1.1.1.3 ! root      879:                if (effects & EF_HALF_DAMAGE)
        !           880:                {
        !           881:                        effects &= ~EF_HALF_DAMAGE;
        !           882:                        effects |= EF_COLOR_SHELL;
        !           883:                        renderfx |= RF_SHELL_HALF_DAM;
        !           884:                }
        !           885: // pmm
        !           886: //======
1.1       root      887:                ent.oldframe = cent->prev.frame;
                    888:                ent.backlerp = 1.0 - cl.lerpfrac;
                    889: 
                    890:                if (renderfx & (RF_FRAMELERP|RF_BEAM))
                    891:                {       // step origin discretely, because the frames
                    892:                        // do the animation properly
                    893:                        VectorCopy (cent->current.origin, ent.origin);
                    894:                        VectorCopy (cent->current.old_origin, ent.oldorigin);
                    895:                }
                    896:                else
                    897:                {       // interpolate origin
                    898:                        for (i=0 ; i<3 ; i++)
                    899:                        {
                    900:                                ent.origin[i] = ent.oldorigin[i] = cent->prev.origin[i] + cl.lerpfrac * 
                    901:                                        (cent->current.origin[i] - cent->prev.origin[i]);
                    902:                        }
                    903:                }
                    904: 
                    905:                // create a new entity
                    906:        
                    907:                // tweak the color of beams
                    908:                if ( renderfx & RF_BEAM )
                    909:                {       // the four beam colors are encoded in 32 bits of skinnum (hack)
                    910:                        ent.alpha = 0.30;
                    911:                        ent.skinnum = (s1->skinnum >> ((rand() % 4)*8)) & 0xff;
                    912:                        ent.model = NULL;
                    913:                }
                    914:                else
                    915:                {
                    916:                        // set skin
                    917:                        if (s1->modelindex == 255)
                    918:                        {       // use custom player skin
                    919:                                ent.skinnum = 0;
1.1.1.2   root      920:                                ci = &cl.clientinfo[s1->skinnum & 0xff];
1.1       root      921:                                ent.skin = ci->skin;
                    922:                                ent.model = ci->model;
                    923:                                if (!ent.skin || !ent.model)
                    924:                                {
                    925:                                        ent.skin = cl.baseclientinfo.skin;
                    926:                                        ent.model = cl.baseclientinfo.model;
                    927:                                }
1.1.1.3 ! root      928: 
        !           929: //============
        !           930: //PGM
        !           931:                                if (renderfx & RF_USE_DISGUISE)
        !           932:                                {
        !           933:                                        if(!strncmp((char *)ent.skin, "players/male", 12))
        !           934:                                        {
        !           935:                                                ent.skin = re.RegisterSkin ("players/male/disguise.pcx");
        !           936:                                                ent.model = re.RegisterModel ("players/male/tris.md2");
        !           937:                                        }
        !           938:                                        else if(!strncmp((char *)ent.skin, "players/female", 14))
        !           939:                                        {
        !           940:                                                ent.skin = re.RegisterSkin ("players/female/disguise.pcx");
        !           941:                                                ent.model = re.RegisterModel ("players/female/tris.md2");
        !           942:                                        }
        !           943:                                        else if(!strncmp((char *)ent.skin, "players/cyborg", 14))
        !           944:                                        {
        !           945:                                                ent.skin = re.RegisterSkin ("players/cyborg/disguise.pcx");
        !           946:                                                ent.model = re.RegisterModel ("players/cyborg/tris.md2");
        !           947:                                        }
        !           948:                                }
        !           949: //PGM
        !           950: //============
1.1       root      951:                        }
                    952:                        else
                    953:                        {
                    954:                                ent.skinnum = s1->skinnum;
                    955:                                ent.skin = NULL;
                    956:                                ent.model = cl.model_draw[s1->modelindex];
                    957:                        }
                    958:                }
                    959: 
                    960:                // only used for black hole model right now, FIXME: do better
                    961:                if (renderfx == RF_TRANSLUCENT)
                    962:                        ent.alpha = 0.70;
                    963: 
                    964:                // render effects (fullbright, translucent, etc)
                    965:                if ((effects & EF_COLOR_SHELL))
                    966:                        ent.flags = 0;  // renderfx go on color shell entity
                    967:                else
                    968:                        ent.flags = renderfx;
                    969: 
                    970:                // calculate angles
                    971:                if (effects & EF_ROTATE)
                    972:                {       // some bonus items auto-rotate
                    973:                        ent.angles[0] = 0;
                    974:                        ent.angles[1] = autorotate;
                    975:                        ent.angles[2] = 0;
                    976:                }
1.1.1.2   root      977:                // RAFAEL
                    978:                else if (effects & EF_SPINNINGLIGHTS)
                    979:                {
                    980:                        ent.angles[0] = 0;
                    981:                        ent.angles[1] = anglemod(cl.time/2) + s1->angles[1];
                    982:                        ent.angles[2] = 180;
                    983:                        {
                    984:                                vec3_t forward;
                    985:                                vec3_t start;
                    986: 
                    987:                                AngleVectors (ent.angles, forward, NULL, NULL);
                    988:                                VectorMA (ent.origin, 64, forward, start);
                    989:                                V_AddLight (start, 100, 1, 0, 0);
                    990:                        }
                    991:                }
1.1       root      992:                else
                    993:                {       // interpolate angles
                    994:                        float   a1, a2;
                    995: 
                    996:                        for (i=0 ; i<3 ; i++)
                    997:                        {
                    998:                                a1 = cent->current.angles[i];
                    999:                                a2 = cent->prev.angles[i];
                   1000:                                ent.angles[i] = LerpAngle (a2, a1, cl.lerpfrac);
                   1001:                        }
                   1002:                }
                   1003: 
                   1004:                if (s1->number == cl.playernum+1)
                   1005:                {
                   1006:                        ent.flags |= RF_VIEWERMODEL;    // only draw from mirrors
                   1007:                        // FIXME: still pass to refresh
                   1008: 
                   1009:                        if (effects & EF_FLAG1)
                   1010:                                V_AddLight (ent.origin, 225, 1.0, 0.1, 0.1);
                   1011:                        else if (effects & EF_FLAG2)
                   1012:                                V_AddLight (ent.origin, 225, 0.1, 0.1, 1.0);
1.1.1.3 ! root     1013:                        else if (effects & EF_TAGTRAIL)                                         //PGM
        !          1014:                                V_AddLight (ent.origin, 225, 1.0, 1.0, 0.0);    //PGM
        !          1015:                        else if (effects & EF_TRACKERTRAIL)                                     //PGM
        !          1016:                                V_AddLight (ent.origin, 225, -1.0, -1.0, -1.0); //PGM
1.1       root     1017: 
                   1018:                        continue;
                   1019:                }
                   1020: 
                   1021:                // if set to invisible, skip
                   1022:                if (!s1->modelindex)
                   1023:                        continue;
                   1024: 
                   1025:                if (effects & EF_BFG)
                   1026:                {
                   1027:                        ent.flags |= RF_TRANSLUCENT;
                   1028:                        ent.alpha = 0.30;
                   1029:                }
                   1030: 
1.1.1.2   root     1031:                // RAFAEL
                   1032:                if (effects & EF_PLASMA)
                   1033:                {
                   1034:                        ent.flags |= RF_TRANSLUCENT;
                   1035:                        ent.alpha = 0.6;
                   1036:                }
                   1037: 
1.1.1.3 ! root     1038:                if (effects & EF_SPHERETRANS)
        !          1039:                {
        !          1040:                        ent.flags |= RF_TRANSLUCENT;
        !          1041:                        // PMM - *sigh*  yet more EF overloading
        !          1042:                        if (effects & EF_TRACKERTRAIL)
        !          1043:                                ent.alpha = 0.6;
        !          1044:                        else
        !          1045:                                ent.alpha = 0.3;
        !          1046:                }
        !          1047: //pmm
        !          1048: 
1.1       root     1049:                // add to refresh list
                   1050:                V_AddEntity (&ent);
                   1051: 
                   1052:                // color shells generate a seperate entity for the main model
                   1053:                if (effects & EF_COLOR_SHELL)
                   1054:                {
                   1055:                        ent.flags = renderfx | RF_TRANSLUCENT;
                   1056:                        ent.alpha = 0.30;
                   1057:                        V_AddEntity (&ent);
                   1058:                }
                   1059: 
                   1060:                ent.skin = NULL;                // never use a custom skin on others
                   1061:                ent.skinnum = 0;
                   1062:                ent.flags = 0;
                   1063:                ent.alpha = 0;
                   1064: 
                   1065:                // duplicate for linked models
                   1066:                if (s1->modelindex2)
                   1067:                {
                   1068:                        if (s1->modelindex2 == 255)
                   1069:                        {       // custom weapon
1.1.1.2   root     1070:                                ci = &cl.clientinfo[s1->skinnum & 0xff];
                   1071:                                i = (s1->skinnum >> 8); // 0 is default weapon model
                   1072:                                if (!cl_vwep->value || i > MAX_CLIENTWEAPONMODELS - 1)
                   1073:                                        i = 0;
                   1074:                                ent.model = ci->weaponmodel[i];
                   1075:                                if (!ent.model) {
                   1076:                                        if (i != 0)
                   1077:                                                ent.model = ci->weaponmodel[0];
                   1078:                                        if (!ent.model)
                   1079:                                                ent.model = cl.baseclientinfo.weaponmodel[0];
                   1080:                                }
1.1       root     1081:                        }
1.1.1.3 ! root     1082:                        //PGM - hack to allow translucent linked models (defender sphere's shell)
        !          1083:                        //              set the high bit 0x80 on modelindex2 to enable translucency
        !          1084:                        else if(s1->modelindex2 & 0x80)
        !          1085:                        {
        !          1086:                                ent.model = cl.model_draw[s1->modelindex2 & 0x7F];
        !          1087:                                ent.alpha = 0.32;
        !          1088:                                ent.flags = RF_TRANSLUCENT;
        !          1089:                        }
        !          1090:                        //PGM
1.1       root     1091:                        else
                   1092:                                ent.model = cl.model_draw[s1->modelindex2];
                   1093:                        V_AddEntity (&ent);
1.1.1.3 ! root     1094: 
        !          1095:                        //PGM - make sure these get reset.
        !          1096:                        ent.flags = 0;
        !          1097:                        ent.alpha = 0;
        !          1098:                        //PGM
1.1       root     1099:                }
                   1100:                if (s1->modelindex3)
                   1101:                {
                   1102:                        ent.model = cl.model_draw[s1->modelindex3];
                   1103:                        V_AddEntity (&ent);
                   1104:                }
                   1105:                if (s1->modelindex4)
                   1106:                {
                   1107:                        ent.model = cl.model_draw[s1->modelindex4];
                   1108:                        V_AddEntity (&ent);
                   1109:                }
                   1110: 
                   1111:                if ( effects & EF_POWERSCREEN )
                   1112:                {
                   1113:                        ent.model = cl_mod_powerscreen;
                   1114:                        ent.oldframe = 0;
                   1115:                        ent.frame = 0;
                   1116:                        ent.flags |= (RF_TRANSLUCENT | RF_SHELL_GREEN);
                   1117:                        ent.alpha = 0.30;
                   1118:                        V_AddEntity (&ent);
                   1119:                }
                   1120: 
                   1121:                // add automatic particle trails
                   1122:                if ( (effects&~EF_ROTATE) )
                   1123:                {
                   1124:                        if (effects & EF_ROCKET)
                   1125:                        {
                   1126:                                CL_RocketTrail (cent->lerp_origin, ent.origin, cent);
                   1127:                                V_AddLight (ent.origin, 200, 1, 1, 0);
                   1128:                        }
1.1.1.3 ! root     1129:                        // PGM - Do not reorder EF_BLASTER and EF_HYPERBLASTER. 
        !          1130:                        // EF_BLASTER | EF_TRACKER is a special case for EF_BLASTER2... Cheese!
1.1       root     1131:                        else if (effects & EF_BLASTER)
                   1132:                        {
1.1.1.3 ! root     1133: //                             CL_BlasterTrail (cent->lerp_origin, ent.origin);
        !          1134: //PGM
        !          1135:                                if (effects & EF_TRACKER)       // lame... problematic?
        !          1136:                                {
        !          1137:                                        CL_BlasterTrail2 (cent->lerp_origin, ent.origin);
        !          1138:                                        V_AddLight (ent.origin, 200, 0, 1, 0);          
        !          1139:                                }
        !          1140:                                else
        !          1141:                                {
        !          1142:                                        CL_BlasterTrail (cent->lerp_origin, ent.origin);
        !          1143:                                        V_AddLight (ent.origin, 200, 1, 1, 0);
        !          1144:                                }
        !          1145: //PGM
1.1       root     1146:                        }
                   1147:                        else if (effects & EF_HYPERBLASTER)
                   1148:                        {
1.1.1.3 ! root     1149:                                if (effects & EF_TRACKER)                                               // PGM  overloaded for blaster2.
        !          1150:                                        V_AddLight (ent.origin, 200, 0, 1, 0);          // PGM
        !          1151:                                else                                                                                    // PGM
        !          1152:                                        V_AddLight (ent.origin, 200, 1, 1, 0);
1.1       root     1153:                        }
                   1154:                        else if (effects & EF_GIB)
                   1155:                        {
                   1156:                                CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects);
                   1157:                        }
                   1158:                        else if (effects & EF_GRENADE)
                   1159:                        {
                   1160:                                CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects);
                   1161:                        }
                   1162:                        else if (effects & EF_FLIES)
                   1163:                        {
                   1164:                                CL_FlyEffect (cent, ent.origin);
                   1165:                        }
                   1166:                        else if (effects & EF_BFG)
                   1167:                        {
                   1168:                                static int bfg_lightramp[6] = {300, 400, 600, 300, 150, 75};
                   1169: 
                   1170:                                if (effects & EF_ANIM_ALLFAST)
                   1171:                                {
                   1172:                                        CL_BfgParticles (&ent);
                   1173:                                        i = 200;
                   1174:                                }
                   1175:                                else
                   1176:                                {
                   1177:                                        i = bfg_lightramp[s1->frame];
                   1178:                                }
                   1179:                                V_AddLight (ent.origin, i, 0, 1, 0);
                   1180:                        }
1.1.1.2   root     1181:                        // RAFAEL
                   1182:                        else if (effects & EF_TRAP)
                   1183:                        {
                   1184:                                ent.origin[2] += 32;
                   1185:                                CL_TrapParticles (&ent);
                   1186:                                i = (rand()%100) + 100;
                   1187:                                V_AddLight (ent.origin, i, 1, 0.8, 0.1);
                   1188:                        }
1.1       root     1189:                        else if (effects & EF_FLAG1)
                   1190:                        {
                   1191:                                CL_FlagTrail (cent->lerp_origin, ent.origin, 242);
                   1192:                                V_AddLight (ent.origin, 225, 1, 0.1, 0.1);
                   1193:                        }
                   1194:                        else if (effects & EF_FLAG2)
                   1195:                        {
                   1196:                                CL_FlagTrail (cent->lerp_origin, ent.origin, 115);
                   1197:                                V_AddLight (ent.origin, 225, 0.1, 0.1, 1);
                   1198:                        }
1.1.1.3 ! root     1199: //======
        !          1200: //ROGUE
        !          1201:                        else if (effects & EF_TAGTRAIL)
        !          1202:                        {
        !          1203:                                CL_TagTrail (cent->lerp_origin, ent.origin, 220);
        !          1204:                                V_AddLight (ent.origin, 225, 1.0, 1.0, 0.0);
        !          1205:                        }
        !          1206:                        else if (effects & EF_TRACKERTRAIL)
        !          1207:                        {
        !          1208:                                if (effects & EF_TRACKER)
        !          1209:                                {
        !          1210:                                        float intensity;
        !          1211: 
        !          1212:                                        intensity = 50 + (500 * (sin(cl.time/500.0) + 1.0));
        !          1213:                                        // FIXME - check out this effect in rendition
        !          1214:                                        if(vidref_val == VIDREF_GL)
        !          1215:                                                V_AddLight (ent.origin, intensity, -1.0, -1.0, -1.0);
        !          1216:                                        else
        !          1217:                                                V_AddLight (ent.origin, -1.0 * intensity, 1.0, 1.0, 1.0);
        !          1218:                                        }
        !          1219:                                else
        !          1220:                                {
        !          1221:                                        CL_Tracker_Shell (cent->lerp_origin);
        !          1222:                                        V_AddLight (ent.origin, 155, -1.0, -1.0, -1.0);
        !          1223:                                }
        !          1224:                        }
        !          1225:                        else if (effects & EF_TRACKER)
        !          1226:                        {
        !          1227:                                CL_TrackerTrail (cent->lerp_origin, ent.origin, 0);
        !          1228:                                // FIXME - check out this effect in rendition
        !          1229:                                if(vidref_val == VIDREF_GL)
        !          1230:                                        V_AddLight (ent.origin, 200, -1, -1, -1);
        !          1231:                                else
        !          1232:                                        V_AddLight (ent.origin, -200, 1, 1, 1);
        !          1233:                        }
        !          1234: //ROGUE
        !          1235: //======
1.1.1.2   root     1236:                        // RAFAEL
1.1       root     1237:                        else if (effects & EF_GREENGIB)
                   1238:                        {
                   1239:                                CL_DiminishingTrail (cent->lerp_origin, ent.origin, cent, effects);                             
                   1240:                        }
1.1.1.2   root     1241:                        // RAFAEL
                   1242:                        else if (effects & EF_IONRIPPER)
1.1       root     1243:                        {
1.1.1.2   root     1244:                                CL_IonripperTrail (cent->lerp_origin, ent.origin);
1.1       root     1245:                                V_AddLight (ent.origin, 100, 1, 0.5, 0.5);
                   1246:                        }
1.1.1.2   root     1247:                        // RAFAEL
                   1248:                        else if (effects & EF_BLUEHYPERBLASTER)
                   1249:                        {
                   1250:                                V_AddLight (ent.origin, 200, 0, 0, 1);
                   1251:                        }
                   1252:                        // RAFAEL
                   1253:                        else if (effects & EF_PLASMA)
                   1254:                        {
                   1255:                                if (effects & EF_ANIM_ALLFAST)
                   1256:                                {
                   1257:                                        CL_BlasterTrail (cent->lerp_origin, ent.origin);
                   1258:                                }
                   1259:                                V_AddLight (ent.origin, 130, 1, 0.5, 0.5);
                   1260:                        }
1.1       root     1261:                }
                   1262: 
                   1263:                VectorCopy (ent.origin, cent->lerp_origin);
                   1264:        }
                   1265: }
                   1266: 
                   1267: 
                   1268: 
                   1269: /*
                   1270: ==============
                   1271: CL_AddViewWeapon
                   1272: ==============
                   1273: */
                   1274: void CL_AddViewWeapon (player_state_t *ps, player_state_t *ops)
                   1275: {
                   1276:        entity_t        gun;            // view model
                   1277:        int                     i;
                   1278: 
                   1279:        // allow the gun to be completely removed
                   1280:        if (!cl_gun->value)
                   1281:                return;
                   1282: 
                   1283:        // don't draw gun if in wide angle view
                   1284:        if (ps->fov > 90)
                   1285:                return;
                   1286: 
                   1287:        memset (&gun, 0, sizeof(gun));
                   1288: 
                   1289:        if (gun_model)
                   1290:                gun.model = gun_model;  // development tool
                   1291:        else
                   1292:                gun.model = cl.model_draw[ps->gunindex];
                   1293:        if (!gun.model)
                   1294:                return;
                   1295: 
                   1296:        // set up gun position
                   1297:        for (i=0 ; i<3 ; i++)
                   1298:        {
                   1299:                gun.origin[i] = cl.refdef.vieworg[i] + ops->gunoffset[i]
                   1300:                        + cl.lerpfrac * (ps->gunoffset[i] - ops->gunoffset[i]);
                   1301:                gun.angles[i] = cl.refdef.viewangles[i] + LerpAngle (ops->gunangles[i],
                   1302:                        ps->gunangles[i], cl.lerpfrac);
                   1303:        }
                   1304: 
                   1305:        if (gun_frame)
                   1306:        {
                   1307:                gun.frame = gun_frame;  // development tool
                   1308:                gun.oldframe = gun_frame;       // development tool
                   1309:        }
                   1310:        else
                   1311:        {
                   1312:                gun.frame = ps->gunframe;
                   1313:                if (gun.frame == 0)
                   1314:                        gun.oldframe = 0;       // just changed weapons, don't lerp from old
                   1315:                else
                   1316:                        gun.oldframe = ops->gunframe;
                   1317:        }
                   1318: 
                   1319:        gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL;
                   1320:        gun.backlerp = 1.0 - cl.lerpfrac;
                   1321:        VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all
                   1322:        V_AddEntity (&gun);
                   1323: }
                   1324: 
1.1.1.2   root     1325: 
1.1       root     1326: /*
                   1327: ===============
                   1328: CL_CalcViewValues
1.1.1.2   root     1329: 
1.1       root     1330: Sets cl.refdef view values
                   1331: ===============
                   1332: */
                   1333: void CL_CalcViewValues (void)
                   1334: {
                   1335:        int                     i;
                   1336:        float           lerp, backlerp;
                   1337:        centity_t       *ent;
                   1338:        frame_t         *oldframe;
                   1339:        player_state_t  *ps, *ops;
                   1340: 
                   1341:        // find the previous frame to interpolate from
                   1342:        ps = &cl.frame.playerstate;
                   1343:        i = (cl.frame.serverframe - 1) & UPDATE_MASK;
                   1344:        oldframe = &cl.frames[i];
                   1345:        if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid)
                   1346:                oldframe = &cl.frame;           // previous frame was dropped or involid
                   1347:        ops = &oldframe->playerstate;
1.1.1.2   root     1348: 
1.1       root     1349:        // see if the player entity was teleported this frame
                   1350:        if ( fabs(ops->pmove.origin[0] - ps->pmove.origin[0]) > 256*8
                   1351:                || abs(ops->pmove.origin[1] - ps->pmove.origin[1]) > 256*8
                   1352:                || abs(ops->pmove.origin[2] - ps->pmove.origin[2]) > 256*8)
                   1353:                ops = ps;               // don't interpolate
                   1354: 
                   1355:        ent = &cl_entities[cl.playernum+1];
                   1356:        lerp = cl.lerpfrac;
                   1357: 
                   1358:        // calculate the origin
                   1359:        if ((cl_predict->value) && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
                   1360:        {       // use predicted values
                   1361:                unsigned        delta;
                   1362: 
                   1363:                backlerp = 1.0 - lerp;
                   1364:                for (i=0 ; i<3 ; i++)
                   1365:                {
                   1366:                        cl.refdef.vieworg[i] = cl.predicted_origin[i] + ops->viewoffset[i] 
                   1367:                                + cl.lerpfrac * (ps->viewoffset[i] - ops->viewoffset[i])
                   1368:                                - backlerp * cl.prediction_error[i];
                   1369:                }
                   1370: 
                   1371:                // smooth out stair climbing
                   1372:                delta = cls.realtime - cl.predicted_step_time;
                   1373:                if (delta < 100)
                   1374:                        cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
                   1375:        }
                   1376:        else
                   1377:        {       // just use interpolated values
                   1378:                for (i=0 ; i<3 ; i++)
                   1379:                        cl.refdef.vieworg[i] = ops->pmove.origin[i]*0.125 + ops->viewoffset[i] 
                   1380:                                + lerp * (ps->pmove.origin[i]*0.125 + ps->viewoffset[i] 
                   1381:                                - (ops->pmove.origin[i]*0.125 + ops->viewoffset[i]) );
                   1382:        }
                   1383: 
                   1384:        // if not running a demo or on a locked frame, add the local angle movement
                   1385:        if ( cl.frame.playerstate.pmove.pm_type < PM_DEAD )
                   1386:        {       // use predicted values
                   1387:                for (i=0 ; i<3 ; i++)
                   1388:                        cl.refdef.viewangles[i] = cl.predicted_angles[i];
                   1389:        }
                   1390:        else
                   1391:        {       // just use interpolated values
                   1392:                for (i=0 ; i<3 ; i++)
                   1393:                        cl.refdef.viewangles[i] = LerpAngle (ops->viewangles[i], ps->viewangles[i], lerp);
                   1394:        }
                   1395: 
                   1396:        for (i=0 ; i<3 ; i++)
                   1397:                cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp);
1.1.1.2   root     1398: 
1.1       root     1399:        AngleVectors (cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up);
                   1400: 
                   1401:        // interpolate field of view
                   1402:        cl.refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
1.1.1.2   root     1403: 
1.1       root     1404:        // don't interpolate blend color
                   1405:        for (i=0 ; i<4 ; i++)
                   1406:                cl.refdef.blend[i] = ps->blend[i];
                   1407: 
                   1408:        // add the weapon
                   1409:        CL_AddViewWeapon (ps, ops);
                   1410: }
1.1.1.2   root     1411: 
1.1       root     1412: /*
                   1413: ===============
                   1414: CL_AddEntities
1.1.1.2   root     1415: 
1.1       root     1416: Emits all entities, particles, and lights to the refresh
                   1417: ===============
                   1418: */
                   1419: void CL_AddEntities (void)
                   1420: {
                   1421:        if (cls.state != ca_active)
                   1422:                return;
1.1.1.2   root     1423: 
1.1       root     1424:        if (cl.time > cl.frame.servertime)
                   1425:        {
                   1426:                if (cl_showclamp->value)
                   1427:                        Com_Printf ("high clamp %i\n", cl.time - cl.frame.servertime);
                   1428:                cl.time = cl.frame.servertime;
                   1429:                cl.lerpfrac = 1.0;
                   1430:        }
                   1431:        else if (cl.time < cl.frame.servertime - 100)
                   1432:        {
                   1433:                if (cl_showclamp->value)
                   1434:                        Com_Printf ("low clamp %i\n", cl.frame.servertime-100 - cl.time);
                   1435:                cl.time = cl.frame.servertime - 100;
                   1436:                cl.lerpfrac = 0;
                   1437:        }
                   1438:        else
                   1439:                cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * 0.01;
                   1440: 
                   1441:        if (cl_timedemo->value)
                   1442:                cl.lerpfrac = 1.0;
                   1443: 
1.1.1.3 ! root     1444: //     CL_AddPacketEntities (&cl.frame);
        !          1445: //     CL_AddTEnts ();
        !          1446: //     CL_AddParticles ();
        !          1447: //     CL_AddDLights ();
        !          1448: //     CL_AddLightStyles ();
        !          1449: 
        !          1450:        CL_CalcViewValues ();
        !          1451:        // PMM - moved this here so the heat beam has the right values for the vieworg, and can lock the beam to the gun
1.1       root     1452:        CL_AddPacketEntities (&cl.frame);
1.1.1.2   root     1453: #if 0
                   1454:        CL_AddProjectiles ();
                   1455: #endif
1.1       root     1456:        CL_AddTEnts ();
                   1457:        CL_AddParticles ();
                   1458:        CL_AddDLights ();
                   1459:        CL_AddLightStyles ();
                   1460: }
1.1.1.2   root     1461: 
                   1462: 
                   1463: 
1.1       root     1464: /*
                   1465: ===============
                   1466: CL_GetEntitySoundOrigin
1.1.1.2   root     1467: 
1.1       root     1468: Called to get the sound spatialization origin
                   1469: ===============
                   1470: */
                   1471: void CL_GetEntitySoundOrigin (int ent, vec3_t org)
                   1472: {
                   1473:        centity_t       *old;
1.1.1.2   root     1474: 
1.1       root     1475:        if (ent < 0 || ent >= MAX_EDICTS)
                   1476:                Com_Error (ERR_DROP, "CL_GetEntitySoundOrigin: bad ent");
                   1477:        old = &cl_entities[ent];
                   1478:        VectorCopy (old->lerp_origin, org);
1.1.1.2   root     1479: 
1.1       root     1480:        // FIXME: bmodel issues...
                   1481: }

unix.superglobalmegacorp.com

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