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

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

unix.superglobalmegacorp.com

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