Annotation of quake2/client/cl_tent.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_tent.c -- client side temporary entities
                     21: 
                     22: #include "client.h"
                     23: 
                     24: typedef enum
                     25: {
1.1.1.2   root       26:        ex_free, ex_explosion, ex_misc, ex_flash, ex_mflash, ex_poly, ex_poly2
1.1       root       27: } exptype_t;
                     28: 
                     29: typedef struct
                     30: {
                     31:        exptype_t       type;
                     32:        entity_t        ent;
                     33: 
                     34:        int                     frames;
                     35:        float           light;
                     36:        vec3_t          lightcolor;
                     37:        float           start;
                     38:        int                     baseframe;
                     39: } explosion_t;
                     40: 
                     41: 
                     42: 
                     43: #define        MAX_EXPLOSIONS  32
                     44: explosion_t    cl_explosions[MAX_EXPLOSIONS];
                     45: 
                     46: 
                     47: #define        MAX_BEAMS       32
                     48: typedef struct
                     49: {
                     50:        int             entity;
1.1.1.3   root       51:        int             dest_entity;
1.1       root       52:        struct model_s  *model;
                     53:        int             endtime;
                     54:        vec3_t  offset;
                     55:        vec3_t  start, end;
                     56: } beam_t;
                     57: beam_t         cl_beams[MAX_BEAMS];
1.1.1.3   root       58: //PMM - added this for player-linked beams.  Currently only used by the plasma beam
                     59: beam_t         cl_playerbeams[MAX_BEAMS];
1.1       root       60: 
                     61: 
                     62: #define        MAX_LASERS      32
                     63: typedef struct
                     64: {
                     65:        entity_t        ent;
                     66:        int                     endtime;
                     67: } laser_t;
                     68: laser_t                cl_lasers[MAX_LASERS];
                     69: 
1.1.1.3   root       70: //ROGUE
                     71: cl_sustain_t   cl_sustains[MAX_SUSTAINS];
                     72: //ROGUE
                     73: 
                     74: //PGM
                     75: extern void CL_TeleportParticles (vec3_t org);
                     76: //PGM
1.1       root       77: 
                     78: void CL_BlasterParticles (vec3_t org, vec3_t dir);
                     79: void CL_ExplosionParticles (vec3_t org);
                     80: void CL_BFGExplosionParticles (vec3_t org);
1.1.1.2   root       81: // RAFAEL
                     82: void CL_BlueBlasterParticles (vec3_t org, vec3_t dir);
1.1       root       83: 
                     84: struct sfx_s   *cl_sfx_ric1;
                     85: struct sfx_s   *cl_sfx_ric2;
                     86: struct sfx_s   *cl_sfx_ric3;
                     87: struct sfx_s   *cl_sfx_lashit;
                     88: struct sfx_s   *cl_sfx_spark5;
                     89: struct sfx_s   *cl_sfx_spark6;
                     90: struct sfx_s   *cl_sfx_spark7;
                     91: struct sfx_s   *cl_sfx_railg;
                     92: struct sfx_s   *cl_sfx_rockexp;
                     93: struct sfx_s   *cl_sfx_grenexp;
                     94: struct sfx_s   *cl_sfx_watrexp;
1.1.1.2   root       95: // RAFAEL
                     96: struct sfx_s   *cl_sfx_plasexp;
1.1       root       97: struct sfx_s   *cl_sfx_footsteps[4];
                     98: 
                     99: struct model_s *cl_mod_explode;
                    100: struct model_s *cl_mod_smoke;
                    101: struct model_s *cl_mod_flash;
                    102: struct model_s *cl_mod_parasite_segment;
                    103: struct model_s *cl_mod_grapple_cable;
                    104: struct model_s *cl_mod_parasite_tip;
                    105: struct model_s *cl_mod_explo4;
                    106: struct model_s *cl_mod_bfg_explo;
                    107: struct model_s *cl_mod_powerscreen;
1.1.1.2   root      108: // RAFAEL
                    109: struct model_s *cl_mod_plasmaexplo;
1.1       root      110: 
1.1.1.3   root      111: //ROGUE
                    112: struct sfx_s   *cl_sfx_lightning;
                    113: struct sfx_s   *cl_sfx_disrexp;
                    114: struct model_s *cl_mod_lightning;
                    115: struct model_s *cl_mod_heatbeam;
                    116: struct model_s *cl_mod_monster_heatbeam;
                    117: struct model_s *cl_mod_explo4_big;
                    118: 
                    119: //ROGUE
1.1       root      120: /*
                    121: =================
                    122: CL_RegisterTEntSounds
                    123: =================
                    124: */
                    125: void CL_RegisterTEntSounds (void)
                    126: {
                    127:        int             i;
                    128:        char    name[MAX_QPATH];
                    129: 
1.1.1.3   root      130:        // PMM - version stuff
                    131: //     Com_Printf ("%s\n", ROGUE_VERSION_STRING);
                    132:        // PMM
1.1       root      133:        cl_sfx_ric1 = S_RegisterSound ("world/ric1.wav");
                    134:        cl_sfx_ric2 = S_RegisterSound ("world/ric2.wav");
                    135:        cl_sfx_ric3 = S_RegisterSound ("world/ric3.wav");
                    136:        cl_sfx_lashit = S_RegisterSound("weapons/lashit.wav");
                    137:        cl_sfx_spark5 = S_RegisterSound ("world/spark5.wav");
                    138:        cl_sfx_spark6 = S_RegisterSound ("world/spark6.wav");
                    139:        cl_sfx_spark7 = S_RegisterSound ("world/spark7.wav");
                    140:        cl_sfx_railg = S_RegisterSound ("weapons/railgf1a.wav");
                    141:        cl_sfx_rockexp = S_RegisterSound ("weapons/rocklx1a.wav");
                    142:        cl_sfx_grenexp = S_RegisterSound ("weapons/grenlx1a.wav");
                    143:        cl_sfx_watrexp = S_RegisterSound ("weapons/xpld_wat.wav");
1.1.1.2   root      144:        // RAFAEL
                    145:        // cl_sfx_plasexp = S_RegisterSound ("weapons/plasexpl.wav");
1.1       root      146:        S_RegisterSound ("player/land1.wav");
                    147: 
                    148:        S_RegisterSound ("player/fall2.wav");
                    149:        S_RegisterSound ("player/fall1.wav");
                    150: 
                    151:        for (i=0 ; i<4 ; i++)
                    152:        {
                    153:                Com_sprintf (name, sizeof(name), "player/step%i.wav", i+1);
                    154:                cl_sfx_footsteps[i] = S_RegisterSound (name);
                    155:        }
1.1.1.3   root      156: 
                    157: //PGM
                    158:        cl_sfx_lightning = S_RegisterSound ("weapons/tesla.wav");
                    159:        cl_sfx_disrexp = S_RegisterSound ("weapons/disrupthit.wav");
                    160:        // version stuff
1.1.1.4 ! root      161: //     sprintf (name, "weapons/sound%d.wav", ROGUE_VERSION_ID);
        !           162: //     if (name[0] == 'w')
        !           163: //             name[0] = 'W';
1.1.1.3   root      164: //PGM
1.1       root      165: }      
                    166: 
                    167: /*
                    168: =================
                    169: CL_RegisterTEntModels
                    170: =================
                    171: */
                    172: void CL_RegisterTEntModels (void)
                    173: {
                    174:        cl_mod_explode = re.RegisterModel ("models/objects/explode/tris.md2");
                    175:        cl_mod_smoke = re.RegisterModel ("models/objects/smoke/tris.md2");
                    176:        cl_mod_flash = re.RegisterModel ("models/objects/flash/tris.md2");
                    177:        cl_mod_parasite_segment = re.RegisterModel ("models/monsters/parasite/segment/tris.md2");
                    178:        cl_mod_grapple_cable = re.RegisterModel ("models/ctf/segment/tris.md2");
                    179:        cl_mod_parasite_tip = re.RegisterModel ("models/monsters/parasite/tip/tris.md2");
                    180:        cl_mod_explo4 = re.RegisterModel ("models/objects/r_explode/tris.md2");
                    181:        cl_mod_bfg_explo = re.RegisterModel ("sprites/s_bfg2.sp2");
                    182:        cl_mod_powerscreen = re.RegisterModel ("models/items/armor/effect/tris.md2");
                    183: 
                    184: re.RegisterModel ("models/objects/laser/tris.md2");
                    185: re.RegisterModel ("models/objects/grenade2/tris.md2");
                    186: re.RegisterModel ("models/weapons/v_machn/tris.md2");
                    187: re.RegisterModel ("models/weapons/v_handgr/tris.md2");
                    188: re.RegisterModel ("models/weapons/v_shotg2/tris.md2");
                    189: re.RegisterModel ("models/objects/gibs/bone/tris.md2");
                    190: re.RegisterModel ("models/objects/gibs/sm_meat/tris.md2");
                    191: re.RegisterModel ("models/objects/gibs/bone2/tris.md2");
1.1.1.2   root      192: // RAFAEL
                    193: // re.RegisterModel ("models/objects/blaser/tris.md2");
1.1       root      194: 
                    195: re.RegisterPic ("w_machinegun");
                    196: re.RegisterPic ("a_bullets");
                    197: re.RegisterPic ("i_health");
                    198: re.RegisterPic ("a_grenades");
1.1.1.3   root      199: 
                    200: //ROGUE
                    201:        cl_mod_explo4_big = re.RegisterModel ("models/objects/r_explode2/tris.md2");
                    202:        cl_mod_lightning = re.RegisterModel ("models/proj/lightning/tris.md2");
                    203:        cl_mod_heatbeam = re.RegisterModel ("models/proj/beam/tris.md2");
                    204:        cl_mod_monster_heatbeam = re.RegisterModel ("models/proj/widowbeam/tris.md2");
                    205: //ROGUE
1.1       root      206: }      
                    207: 
                    208: /*
                    209: =================
                    210: CL_ClearTEnts
                    211: =================
                    212: */
                    213: void CL_ClearTEnts (void)
                    214: {
                    215:        memset (cl_beams, 0, sizeof(cl_beams));
                    216:        memset (cl_explosions, 0, sizeof(cl_explosions));
                    217:        memset (cl_lasers, 0, sizeof(cl_lasers));
1.1.1.3   root      218: 
                    219: //ROGUE
                    220:        memset (cl_playerbeams, 0, sizeof(cl_playerbeams));
                    221:        memset (cl_sustains, 0, sizeof(cl_sustains));
                    222: //ROGUE
1.1       root      223: }
                    224: 
                    225: /*
                    226: =================
                    227: CL_AllocExplosion
                    228: =================
                    229: */
                    230: explosion_t *CL_AllocExplosion (void)
                    231: {
                    232:        int             i;
                    233:        int             time;
                    234:        int             index;
                    235:        
                    236:        for (i=0 ; i<MAX_EXPLOSIONS ; i++)
                    237:        {
                    238:                if (cl_explosions[i].type == ex_free)
                    239:                {
                    240:                        memset (&cl_explosions[i], 0, sizeof (cl_explosions[i]));
                    241:                        return &cl_explosions[i];
                    242:                }
                    243:        }
                    244: // find the oldest explosion
                    245:        time = cl.time;
                    246:        index = 0;
                    247: 
                    248:        for (i=0 ; i<MAX_EXPLOSIONS ; i++)
                    249:                if (cl_explosions[i].start < time)
                    250:                {
                    251:                        time = cl_explosions[i].start;
                    252:                        index = i;
                    253:                }
                    254:        memset (&cl_explosions[index], 0, sizeof (cl_explosions[index]));
                    255:        return &cl_explosions[index];
                    256: }
                    257: 
                    258: /*
                    259: =================
                    260: CL_SmokeAndFlash
                    261: =================
                    262: */
                    263: void CL_SmokeAndFlash(vec3_t origin)
                    264: {
                    265:        explosion_t     *ex;
                    266: 
                    267:        ex = CL_AllocExplosion ();
                    268:        VectorCopy (origin, ex->ent.origin);
                    269:        ex->type = ex_misc;
                    270:        ex->frames = 4;
                    271:        ex->ent.flags = RF_TRANSLUCENT;
                    272:        ex->start = cl.frame.servertime - 100;
                    273:        ex->ent.model = cl_mod_smoke;
                    274: 
                    275:        ex = CL_AllocExplosion ();
                    276:        VectorCopy (origin, ex->ent.origin);
                    277:        ex->type = ex_flash;
                    278:        ex->ent.flags = RF_FULLBRIGHT;
                    279:        ex->frames = 2;
                    280:        ex->start = cl.frame.servertime - 100;
                    281:        ex->ent.model = cl_mod_flash;
                    282: }
                    283: 
                    284: /*
                    285: =================
                    286: CL_ParseParticles
                    287: =================
                    288: */
                    289: void CL_ParseParticles (void)
                    290: {
                    291:        int             color, count;
                    292:        vec3_t  pos, dir;
                    293: 
                    294:        MSG_ReadPos (&net_message, pos);
                    295:        MSG_ReadDir (&net_message, dir);
                    296: 
                    297:        color = MSG_ReadByte (&net_message);
                    298: 
                    299:        count = MSG_ReadByte (&net_message);
                    300: 
                    301:        CL_ParticleEffect (pos, dir, color, count);
                    302: }
                    303: 
                    304: /*
                    305: =================
                    306: CL_ParseBeam
                    307: =================
                    308: */
                    309: int CL_ParseBeam (struct model_s *model)
                    310: {
                    311:        int             ent;
                    312:        vec3_t  start, end;
                    313:        beam_t  *b;
                    314:        int             i;
                    315:        
                    316:        ent = MSG_ReadShort (&net_message);
                    317:        
                    318:        MSG_ReadPos (&net_message, start);
                    319:        MSG_ReadPos (&net_message, end);
                    320: 
                    321: // override any beam with the same entity
                    322:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    323:                if (b->entity == ent)
                    324:                {
                    325:                        b->entity = ent;
                    326:                        b->model = model;
                    327:                        b->endtime = cl.time + 200;
                    328:                        VectorCopy (start, b->start);
                    329:                        VectorCopy (end, b->end);
                    330:                        VectorClear (b->offset);
                    331:                        return ent;
                    332:                }
                    333: 
                    334: // find a free beam
                    335:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    336:        {
                    337:                if (!b->model || b->endtime < cl.time)
                    338:                {
                    339:                        b->entity = ent;
                    340:                        b->model = model;
                    341:                        b->endtime = cl.time + 200;
                    342:                        VectorCopy (start, b->start);
                    343:                        VectorCopy (end, b->end);
                    344:                        VectorClear (b->offset);
                    345:                        return ent;
                    346:                }
                    347:        }
                    348:        Com_Printf ("beam list overflow!\n");   
                    349:        return ent;
                    350: }
                    351: 
                    352: /*
                    353: =================
                    354: CL_ParseBeam2
                    355: =================
                    356: */
                    357: int CL_ParseBeam2 (struct model_s *model)
                    358: {
                    359:        int             ent;
                    360:        vec3_t  start, end, offset;
                    361:        beam_t  *b;
                    362:        int             i;
                    363:        
                    364:        ent = MSG_ReadShort (&net_message);
                    365:        
                    366:        MSG_ReadPos (&net_message, start);
                    367:        MSG_ReadPos (&net_message, end);
                    368:        MSG_ReadPos (&net_message, offset);
                    369: 
1.1.1.3   root      370: //     Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]);
                    371: 
1.1       root      372: // override any beam with the same entity
1.1.1.3   root      373: 
1.1       root      374:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    375:                if (b->entity == ent)
                    376:                {
                    377:                        b->entity = ent;
                    378:                        b->model = model;
                    379:                        b->endtime = cl.time + 200;
                    380:                        VectorCopy (start, b->start);
                    381:                        VectorCopy (end, b->end);
                    382:                        VectorCopy (offset, b->offset);
                    383:                        return ent;
                    384:                }
                    385: 
                    386: // find a free beam
                    387:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    388:        {
                    389:                if (!b->model || b->endtime < cl.time)
                    390:                {
                    391:                        b->entity = ent;
                    392:                        b->model = model;
1.1.1.3   root      393:                        b->endtime = cl.time + 200;     
                    394:                        VectorCopy (start, b->start);
                    395:                        VectorCopy (end, b->end);
                    396:                        VectorCopy (offset, b->offset);
                    397:                        return ent;
                    398:                }
                    399:        }
                    400:        Com_Printf ("beam list overflow!\n");   
                    401:        return ent;
                    402: }
                    403: 
                    404: // ROGUE
                    405: /*
                    406: =================
                    407: CL_ParsePlayerBeam
                    408:   - adds to the cl_playerbeam array instead of the cl_beams array
                    409: =================
                    410: */
                    411: int CL_ParsePlayerBeam (struct model_s *model)
                    412: {
                    413:        int             ent;
                    414:        vec3_t  start, end, offset;
                    415:        beam_t  *b;
                    416:        int             i;
                    417:        
                    418:        ent = MSG_ReadShort (&net_message);
                    419:        
                    420:        MSG_ReadPos (&net_message, start);
                    421:        MSG_ReadPos (&net_message, end);
                    422:        // PMM - network optimization
                    423:        if (model == cl_mod_heatbeam)
                    424:                VectorSet(offset, 2, 7, -3);
                    425:        else if (model == cl_mod_monster_heatbeam)
                    426:        {
                    427:                model = cl_mod_heatbeam;
                    428:                VectorSet(offset, 0, 0, 0);
                    429:        }
                    430:        else
                    431:                MSG_ReadPos (&net_message, offset);
                    432: 
                    433: //     Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]);
                    434: 
                    435: // override any beam with the same entity
                    436: // PMM - For player beams, we only want one per player (entity) so..
                    437:        for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++)
                    438:        {
                    439:                if (b->entity == ent)
                    440:                {
                    441:                        b->entity = ent;
                    442:                        b->model = model;
1.1       root      443:                        b->endtime = cl.time + 200;
                    444:                        VectorCopy (start, b->start);
                    445:                        VectorCopy (end, b->end);
                    446:                        VectorCopy (offset, b->offset);
                    447:                        return ent;
                    448:                }
                    449:        }
1.1.1.3   root      450: 
                    451: // find a free beam
                    452:        for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++)
                    453:        {
                    454:                if (!b->model || b->endtime < cl.time)
                    455:                {
                    456:                        b->entity = ent;
                    457:                        b->model = model;
                    458:                        b->endtime = cl.time + 100;             // PMM - this needs to be 100 to prevent multiple heatbeams
                    459:                        VectorCopy (start, b->start);
                    460:                        VectorCopy (end, b->end);
                    461:                        VectorCopy (offset, b->offset);
                    462:                        return ent;
                    463:                }
                    464:        }
1.1       root      465:        Com_Printf ("beam list overflow!\n");   
                    466:        return ent;
                    467: }
1.1.1.3   root      468: //rogue
                    469: 
                    470: /*
                    471: =================
                    472: CL_ParseLightning
                    473: =================
                    474: */
                    475: int CL_ParseLightning (struct model_s *model)
                    476: {
                    477:        int             srcEnt, destEnt;
                    478:        vec3_t  start, end;
                    479:        beam_t  *b;
                    480:        int             i;
                    481:        
                    482:        srcEnt = MSG_ReadShort (&net_message);
                    483:        destEnt = MSG_ReadShort (&net_message);
                    484: 
                    485:        MSG_ReadPos (&net_message, start);
                    486:        MSG_ReadPos (&net_message, end);
                    487: 
                    488: // override any beam with the same source AND destination entities
                    489:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    490:                if (b->entity == srcEnt && b->dest_entity == destEnt)
                    491:                {
                    492: //                     Com_Printf("%d: OVERRIDE  %d -> %d\n", cl.time, srcEnt, destEnt);
                    493:                        b->entity = srcEnt;
                    494:                        b->dest_entity = destEnt;
                    495:                        b->model = model;
                    496:                        b->endtime = cl.time + 200;
                    497:                        VectorCopy (start, b->start);
                    498:                        VectorCopy (end, b->end);
                    499:                        VectorClear (b->offset);
                    500:                        return srcEnt;
                    501:                }
                    502: 
                    503: // find a free beam
                    504:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    505:        {
                    506:                if (!b->model || b->endtime < cl.time)
                    507:                {
                    508: //                     Com_Printf("%d: NORMAL  %d -> %d\n", cl.time, srcEnt, destEnt);
                    509:                        b->entity = srcEnt;
                    510:                        b->dest_entity = destEnt;
                    511:                        b->model = model;
                    512:                        b->endtime = cl.time + 200;
                    513:                        VectorCopy (start, b->start);
                    514:                        VectorCopy (end, b->end);
                    515:                        VectorClear (b->offset);
                    516:                        return srcEnt;
                    517:                }
                    518:        }
                    519:        Com_Printf ("beam list overflow!\n");   
                    520:        return srcEnt;
                    521: }
1.1       root      522: 
                    523: /*
                    524: =================
                    525: CL_ParseLaser
                    526: =================
                    527: */
                    528: void CL_ParseLaser (int colors)
                    529: {
                    530:        vec3_t  start;
                    531:        vec3_t  end;
                    532:        laser_t *l;
                    533:        int             i;
                    534: 
                    535:        MSG_ReadPos (&net_message, start);
                    536:        MSG_ReadPos (&net_message, end);
                    537: 
                    538:        for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
                    539:        {
                    540:                if (l->endtime < cl.time)
                    541:                {
                    542:                        l->ent.flags = RF_TRANSLUCENT | RF_BEAM;
                    543:                        VectorCopy (start, l->ent.origin);
                    544:                        VectorCopy (end, l->ent.oldorigin);
                    545:                        l->ent.alpha = 0.30;
                    546:                        l->ent.skinnum = (colors >> ((rand() % 4)*8)) & 0xff;
                    547:                        l->ent.model = NULL;
                    548:                        l->ent.frame = 4;
                    549:                        l->endtime = cl.time + 100;
                    550:                        return;
                    551:                }
                    552:        }
                    553: }
                    554: 
1.1.1.3   root      555: //=============
                    556: //ROGUE
                    557: void CL_ParseSteam (void)
                    558: {
                    559:        vec3_t  pos, dir;
                    560:        int             id, i;
                    561:        int             r;
                    562:        int             cnt;
                    563:        int             color;
                    564:        int             magnitude;
                    565:        cl_sustain_t    *s, *free_sustain;
                    566: 
                    567:        id = MSG_ReadShort (&net_message);              // an id of -1 is an instant effect
                    568:        if (id != -1) // sustains
                    569:        {
                    570: //                     Com_Printf ("Sustain effect id %d\n", id);
                    571:                free_sustain = NULL;
                    572:                for (i=0, s=cl_sustains; i<MAX_SUSTAINS; i++, s++)
                    573:                {
                    574:                        if (s->id == 0)
                    575:                        {
                    576:                                free_sustain = s;
                    577:                                break;
                    578:                        }
                    579:                }
                    580:                if (free_sustain)
                    581:                {
                    582:                        s->id = id;
                    583:                        s->count = MSG_ReadByte (&net_message);
                    584:                        MSG_ReadPos (&net_message, s->org);
                    585:                        MSG_ReadDir (&net_message, s->dir);
                    586:                        r = MSG_ReadByte (&net_message);
                    587:                        s->color = r & 0xff;
                    588:                        s->magnitude = MSG_ReadShort (&net_message);
                    589:                        s->endtime = cl.time + MSG_ReadLong (&net_message);
                    590:                        s->think = CL_ParticleSteamEffect2;
                    591:                        s->thinkinterval = 100;
                    592:                        s->nextthink = cl.time;
                    593:                }
                    594:                else
                    595:                {
                    596: //                             Com_Printf ("No free sustains!\n");
                    597:                        // FIXME - read the stuff anyway
                    598:                        cnt = MSG_ReadByte (&net_message);
                    599:                        MSG_ReadPos (&net_message, pos);
                    600:                        MSG_ReadDir (&net_message, dir);
                    601:                        r = MSG_ReadByte (&net_message);
                    602:                        magnitude = MSG_ReadShort (&net_message);
                    603:                        magnitude = MSG_ReadLong (&net_message); // really interval
                    604:                }
                    605:        }
                    606:        else // instant
                    607:        {
                    608:                cnt = MSG_ReadByte (&net_message);
                    609:                MSG_ReadPos (&net_message, pos);
                    610:                MSG_ReadDir (&net_message, dir);
                    611:                r = MSG_ReadByte (&net_message);
                    612:                magnitude = MSG_ReadShort (&net_message);
                    613:                color = r & 0xff;
                    614:                CL_ParticleSteamEffect (pos, dir, color, cnt, magnitude);
                    615: //             S_StartSound (pos,  0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                    616:        }
                    617: }
                    618: 
                    619: void CL_ParseWidow (void)
                    620: {
                    621:        vec3_t  pos;
                    622:        int             id, i;
                    623:        cl_sustain_t    *s, *free_sustain;
                    624: 
                    625:        id = MSG_ReadShort (&net_message);
                    626: 
                    627:        free_sustain = NULL;
                    628:        for (i=0, s=cl_sustains; i<MAX_SUSTAINS; i++, s++)
                    629:        {
                    630:                if (s->id == 0)
                    631:                {
                    632:                        free_sustain = s;
                    633:                        break;
                    634:                }
                    635:        }
                    636:        if (free_sustain)
                    637:        {
                    638:                s->id = id;
                    639:                MSG_ReadPos (&net_message, s->org);
                    640:                s->endtime = cl.time + 2100;
                    641:                s->think = CL_Widowbeamout;
                    642:                s->thinkinterval = 1;
                    643:                s->nextthink = cl.time;
                    644:        }
                    645:        else // no free sustains
                    646:        {
                    647:                // FIXME - read the stuff anyway
                    648:                MSG_ReadPos (&net_message, pos);
                    649:        }
                    650: }
                    651: 
                    652: void CL_ParseNuke (void)
                    653: {
                    654:        vec3_t  pos;
                    655:        int             i;
                    656:        cl_sustain_t    *s, *free_sustain;
                    657: 
                    658:        free_sustain = NULL;
                    659:        for (i=0, s=cl_sustains; i<MAX_SUSTAINS; i++, s++)
                    660:        {
                    661:                if (s->id == 0)
                    662:                {
                    663:                        free_sustain = s;
                    664:                        break;
                    665:                }
                    666:        }
                    667:        if (free_sustain)
                    668:        {
                    669:                s->id = 21000;
                    670:                MSG_ReadPos (&net_message, s->org);
                    671:                s->endtime = cl.time + 1000;
                    672:                s->think = CL_Nukeblast;
                    673:                s->thinkinterval = 1;
                    674:                s->nextthink = cl.time;
                    675:        }
                    676:        else // no free sustains
                    677:        {
                    678:                // FIXME - read the stuff anyway
                    679:                MSG_ReadPos (&net_message, pos);
                    680:        }
                    681: }
                    682: 
                    683: //ROGUE
                    684: //=============
                    685: 
1.1       root      686: 
                    687: /*
                    688: =================
                    689: CL_ParseTEnt
                    690: =================
                    691: */
                    692: static byte splash_color[] = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8};
                    693: 
                    694: void CL_ParseTEnt (void)
                    695: {
                    696:        int             type;
                    697:        vec3_t  pos, pos2, dir;
                    698:        explosion_t     *ex;
                    699:        int             cnt;
                    700:        int             color;
                    701:        int             r;
                    702:        int             ent;
1.1.1.3   root      703:        int             magnitude;
1.1       root      704: 
                    705:        type = MSG_ReadByte (&net_message);
                    706: 
                    707:        switch (type)
                    708:        {
                    709:        case TE_BLOOD:                  // bullet hitting flesh
                    710:                MSG_ReadPos (&net_message, pos);
                    711:                MSG_ReadDir (&net_message, dir);
                    712:                CL_ParticleEffect (pos, dir, 0xe8, 60);
                    713:                break;
                    714: 
                    715:        case TE_GUNSHOT:                        // bullet hitting wall
                    716:        case TE_SPARKS:
                    717:        case TE_BULLET_SPARKS:
                    718:                MSG_ReadPos (&net_message, pos);
                    719:                MSG_ReadDir (&net_message, dir);
                    720:                if (type == TE_GUNSHOT)
                    721:                        CL_ParticleEffect (pos, dir, 0, 40);
                    722:                else
                    723:                        CL_ParticleEffect (pos, dir, 0xe0, 6);
                    724: 
                    725:                if (type != TE_SPARKS)
                    726:                {
                    727:                        CL_SmokeAndFlash(pos);
1.1.1.3   root      728:                        
1.1       root      729:                        // impact sound
                    730:                        cnt = rand()&15;
                    731:                        if (cnt == 1)
                    732:                                S_StartSound (pos, 0, 0, cl_sfx_ric1, 1, ATTN_NORM, 0);
                    733:                        else if (cnt == 2)
                    734:                                S_StartSound (pos, 0, 0, cl_sfx_ric2, 1, ATTN_NORM, 0);
                    735:                        else if (cnt == 3)
                    736:                                S_StartSound (pos, 0, 0, cl_sfx_ric3, 1, ATTN_NORM, 0);
                    737:                }
                    738: 
                    739:                break;
                    740:                
                    741:        case TE_SCREEN_SPARKS:
                    742:        case TE_SHIELD_SPARKS:
                    743:                MSG_ReadPos (&net_message, pos);
                    744:                MSG_ReadDir (&net_message, dir);
                    745:                if (type == TE_SCREEN_SPARKS)
                    746:                        CL_ParticleEffect (pos, dir, 0xd0, 40);
                    747:                else
                    748:                        CL_ParticleEffect (pos, dir, 0xb0, 40);
                    749:                //FIXME : replace or remove this sound
                    750:                S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                    751:                break;
                    752:                
                    753:        case TE_SHOTGUN:                        // bullet hitting wall
                    754:                MSG_ReadPos (&net_message, pos);
                    755:                MSG_ReadDir (&net_message, dir);
                    756:                CL_ParticleEffect (pos, dir, 0, 20);
                    757:                CL_SmokeAndFlash(pos);
                    758:                break;
                    759: 
                    760:        case TE_SPLASH:                 // bullet hitting water
                    761:                cnt = MSG_ReadByte (&net_message);
                    762:                MSG_ReadPos (&net_message, pos);
                    763:                MSG_ReadDir (&net_message, dir);
                    764:                r = MSG_ReadByte (&net_message);
                    765:                if (r > 6)
                    766:                        color = 0x00;
                    767:                else
                    768:                        color = splash_color[r];
                    769:                CL_ParticleEffect (pos, dir, color, cnt);
                    770: 
                    771:                if (r == SPLASH_SPARKS)
                    772:                {
                    773:                        r = rand() & 3;
                    774:                        if (r == 0)
                    775:                                S_StartSound (pos, 0, 0, cl_sfx_spark5, 1, ATTN_STATIC, 0);
                    776:                        else if (r == 1)
                    777:                                S_StartSound (pos, 0, 0, cl_sfx_spark6, 1, ATTN_STATIC, 0);
                    778:                        else
                    779:                                S_StartSound (pos, 0, 0, cl_sfx_spark7, 1, ATTN_STATIC, 0);
                    780:                }
                    781:                break;
                    782: 
                    783:        case TE_LASER_SPARKS:
                    784:                cnt = MSG_ReadByte (&net_message);
                    785:                MSG_ReadPos (&net_message, pos);
                    786:                MSG_ReadDir (&net_message, dir);
                    787:                color = MSG_ReadByte (&net_message);
                    788:                CL_ParticleEffect2 (pos, dir, color, cnt);
                    789:                break;
                    790: 
1.1.1.2   root      791:        // RAFAEL
                    792:        case TE_BLUEHYPERBLASTER:
                    793:                MSG_ReadPos (&net_message, pos);
                    794:                MSG_ReadPos (&net_message, dir);
                    795:                CL_BlasterParticles (pos, dir);
                    796:                break;
                    797: 
1.1       root      798:        case TE_BLASTER:                        // blaster hitting wall
                    799:                MSG_ReadPos (&net_message, pos);
                    800:                MSG_ReadDir (&net_message, dir);
                    801:                CL_BlasterParticles (pos, dir);
                    802: 
                    803:                ex = CL_AllocExplosion ();
                    804:                VectorCopy (pos, ex->ent.origin);
                    805:                ex->ent.angles[0] = acos(dir[2])/M_PI*180;
1.1.1.3   root      806:        // PMM - fixed to correct for pitch of 0
1.1.1.2   root      807:                if (dir[0])
1.1.1.3   root      808:                        ex->ent.angles[1] = atan2(dir[1], dir[0])/M_PI*180;
                    809:                else if (dir[1] > 0)
                    810:                        ex->ent.angles[1] = 90;
                    811:                else if (dir[1] < 0)
                    812:                        ex->ent.angles[1] = 270;
1.1.1.2   root      813:                else
1.1.1.3   root      814:                        ex->ent.angles[1] = 0;
                    815: 
1.1       root      816:                ex->type = ex_misc;
                    817:                ex->ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT;
                    818:                ex->start = cl.frame.servertime - 100;
                    819:                ex->light = 150;
                    820:                ex->lightcolor[0] = 1;
                    821:                ex->lightcolor[1] = 1;
                    822:                ex->ent.model = cl_mod_explode;
                    823:                ex->frames = 4;
                    824:                S_StartSound (pos,  0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                    825:                break;
                    826:                
                    827:        case TE_RAILTRAIL:                      // railgun effect
                    828:                MSG_ReadPos (&net_message, pos);
                    829:                MSG_ReadPos (&net_message, pos2);
                    830:                CL_RailTrail (pos, pos2);
                    831:                S_StartSound (pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0);
                    832:                break;
1.1.1.3   root      833: 
1.1       root      834:        case TE_EXPLOSION2:
                    835:        case TE_GRENADE_EXPLOSION:
                    836:        case TE_GRENADE_EXPLOSION_WATER:
                    837:                MSG_ReadPos (&net_message, pos);
                    838: 
                    839:                ex = CL_AllocExplosion ();
                    840:                VectorCopy (pos, ex->ent.origin);
                    841:                ex->type = ex_poly;
                    842:                ex->ent.flags = RF_FULLBRIGHT;
                    843:                ex->start = cl.frame.servertime - 100;
                    844:                ex->light = 350;
                    845:                ex->lightcolor[0] = 1.0;
                    846:                ex->lightcolor[1] = 0.5;
                    847:                ex->lightcolor[2] = 0.5;
                    848:                ex->ent.model = cl_mod_explo4;
                    849:                ex->frames = 19;
                    850:                ex->baseframe = 30;
                    851:                ex->ent.angles[1] = rand() % 360;
                    852:                CL_ExplosionParticles (pos);
                    853:                if (type == TE_GRENADE_EXPLOSION_WATER)
                    854:                        S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0);
                    855:                else
                    856:                        S_StartSound (pos, 0, 0, cl_sfx_grenexp, 1, ATTN_NORM, 0);
                    857:                break;
                    858: 
1.1.1.2   root      859:        // RAFAEL
                    860:        case TE_PLASMA_EXPLOSION:
                    861:                MSG_ReadPos (&net_message, pos);
                    862:                ex = CL_AllocExplosion ();
                    863:                VectorCopy (pos, ex->ent.origin);
                    864:                ex->type = ex_poly;
                    865:                ex->ent.flags = RF_FULLBRIGHT;
                    866:                ex->start = cl.frame.servertime - 100;
                    867:                ex->light = 350;
                    868:                ex->lightcolor[0] = 1.0; 
                    869:                ex->lightcolor[1] = 0.5;
                    870:                ex->lightcolor[2] = 0.5;
                    871:                ex->ent.angles[1] = rand() % 360;
                    872:                ex->ent.model = cl_mod_explo4;
                    873:                if (frand() < 0.5)
                    874:                        ex->baseframe = 15;
                    875:                ex->frames = 15;
                    876:                CL_ExplosionParticles (pos);
                    877:                S_StartSound (pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0);
                    878:                break;
                    879:        
1.1       root      880:        case TE_EXPLOSION1:
1.1.1.3   root      881:        case TE_EXPLOSION1_BIG:                                         // PMM
1.1       root      882:        case TE_ROCKET_EXPLOSION:
                    883:        case TE_ROCKET_EXPLOSION_WATER:
1.1.1.3   root      884:        case TE_EXPLOSION1_NP:                                          // PMM
1.1       root      885:                MSG_ReadPos (&net_message, pos);
                    886: 
                    887:                ex = CL_AllocExplosion ();
                    888:                VectorCopy (pos, ex->ent.origin);
                    889:                ex->type = ex_poly;
                    890:                ex->ent.flags = RF_FULLBRIGHT;
                    891:                ex->start = cl.frame.servertime - 100;
                    892:                ex->light = 350;
                    893:                ex->lightcolor[0] = 1.0;
                    894:                ex->lightcolor[1] = 0.5;
                    895:                ex->lightcolor[2] = 0.5;
                    896:                ex->ent.angles[1] = rand() % 360;
1.1.1.3   root      897:                if (type != TE_EXPLOSION1_BIG)                          // PMM
                    898:                        ex->ent.model = cl_mod_explo4;                  // PMM
                    899:                else
                    900:                        ex->ent.model = cl_mod_explo4_big;
1.1       root      901:                if (frand() < 0.5)
                    902:                        ex->baseframe = 15;
                    903:                ex->frames = 15;
1.1.1.3   root      904:                if ((type != TE_EXPLOSION1_BIG) && (type != TE_EXPLOSION1_NP))          // PMM
                    905:                        CL_ExplosionParticles (pos);                                                                    // PMM
1.1       root      906:                if (type == TE_ROCKET_EXPLOSION_WATER)
                    907:                        S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0);
                    908:                else
                    909:                        S_StartSound (pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0);
                    910:                break;
                    911: 
                    912:        case TE_BFG_EXPLOSION:
                    913:                MSG_ReadPos (&net_message, pos);
                    914:                ex = CL_AllocExplosion ();
                    915:                VectorCopy (pos, ex->ent.origin);
                    916:                ex->type = ex_poly;
                    917:                ex->ent.flags = RF_FULLBRIGHT;
                    918:                ex->start = cl.frame.servertime - 100;
                    919:                ex->light = 350;
                    920:                ex->lightcolor[0] = 0.0;
                    921:                ex->lightcolor[1] = 1.0;
                    922:                ex->lightcolor[2] = 0.0;
                    923:                ex->ent.model = cl_mod_bfg_explo;
                    924:                ex->ent.flags |= RF_TRANSLUCENT;
                    925:                ex->ent.alpha = 0.30;
                    926:                ex->frames = 4;
                    927:                break;
                    928: 
                    929:        case TE_BFG_BIGEXPLOSION:
                    930:                MSG_ReadPos (&net_message, pos);
                    931:                CL_BFGExplosionParticles (pos);
                    932:                break;
                    933: 
                    934:        case TE_BFG_LASER:
                    935:                CL_ParseLaser (0xd0d1d2d3);
                    936:                break;
                    937: 
                    938:        case TE_BUBBLETRAIL:
                    939:                MSG_ReadPos (&net_message, pos);
                    940:                MSG_ReadPos (&net_message, pos2);
                    941:                CL_BubbleTrail (pos, pos2);
                    942:                break;
                    943: 
                    944:        case TE_PARASITE_ATTACK:
                    945:        case TE_MEDIC_CABLE_ATTACK:
                    946:                ent = CL_ParseBeam (cl_mod_parasite_segment);
                    947:                break;
                    948: 
                    949:        case TE_BOSSTPORT:                      // boss teleporting to station
                    950:                MSG_ReadPos (&net_message, pos);
                    951:                CL_BigTeleportParticles (pos);
                    952:                S_StartSound (pos, 0, 0, S_RegisterSound ("misc/bigtele.wav"), 1, ATTN_NONE, 0);
                    953:                break;
                    954: 
                    955:        case TE_GRAPPLE_CABLE:
                    956:                ent = CL_ParseBeam2 (cl_mod_grapple_cable);
                    957:                break;
                    958: 
1.1.1.2   root      959:        // RAFAEL
1.1       root      960:        case TE_WELDING_SPARKS:
                    961:                cnt = MSG_ReadByte (&net_message);
                    962:                MSG_ReadPos (&net_message, pos);
                    963:                MSG_ReadDir (&net_message, dir);
                    964:                color = MSG_ReadByte (&net_message);
                    965:                CL_ParticleEffect2 (pos, dir, color, cnt);
                    966: 
                    967:                ex = CL_AllocExplosion ();
                    968:                VectorCopy (pos, ex->ent.origin);
                    969:                ex->type = ex_flash;
                    970:                // note to self
                    971:                // we need a better no draw flag
                    972:                ex->ent.flags = RF_BEAM;
                    973:                ex->start = cl.frame.servertime - 0.1;
                    974:                ex->light = 100 + (rand()%75);
                    975:                ex->lightcolor[0] = 1.0;
                    976:                ex->lightcolor[1] = 1.0;
                    977:                ex->lightcolor[2] = 0.3;
                    978:                ex->ent.model = cl_mod_flash;
                    979:                ex->frames = 2;
                    980:                break;
                    981: 
                    982:        case TE_GREENBLOOD:
                    983:                MSG_ReadPos (&net_message, pos);
                    984:                MSG_ReadDir (&net_message, dir);
1.1.1.2   root      985:                CL_ParticleEffect2 (pos, dir, 0xdf, 30);
                    986:                break;
                    987: 
1.1.1.3   root      988:        // RAFAEL
                    989:        case TE_TUNNEL_SPARKS:
1.1.1.2   root      990:                cnt = MSG_ReadByte (&net_message);
                    991:                MSG_ReadPos (&net_message, pos);
                    992:                MSG_ReadDir (&net_message, dir);
                    993:                color = MSG_ReadByte (&net_message);
                    994:                CL_ParticleEffect3 (pos, dir, color, cnt);
1.1       root      995:                break;
1.1.1.3   root      996: 
                    997: //=============
                    998: //PGM
                    999:                // PMM -following code integrated for flechette (different color)
                   1000:        case TE_BLASTER2:                       // green blaster hitting wall
                   1001:        case TE_FLECHETTE:                      // flechette
                   1002:                MSG_ReadPos (&net_message, pos);
                   1003:                MSG_ReadDir (&net_message, dir);
                   1004:                
                   1005:                // PMM
                   1006:                if (type == TE_BLASTER2)
                   1007:                        CL_BlasterParticles2 (pos, dir, 0xd0);
                   1008:                else
                   1009:                        CL_BlasterParticles2 (pos, dir, 0x6f); // 75
                   1010: 
                   1011:                ex = CL_AllocExplosion ();
                   1012:                VectorCopy (pos, ex->ent.origin);
                   1013:                ex->ent.angles[0] = acos(dir[2])/M_PI*180;
                   1014:        // PMM - fixed to correct for pitch of 0
                   1015:                if (dir[0])
                   1016:                        ex->ent.angles[1] = atan2(dir[1], dir[0])/M_PI*180;
                   1017:                else if (dir[1] > 0)
                   1018:                        ex->ent.angles[1] = 90;
                   1019:                else if (dir[1] < 0)
                   1020:                        ex->ent.angles[1] = 270;
                   1021:                else
                   1022:                        ex->ent.angles[1] = 0;
                   1023: 
                   1024:                ex->type = ex_misc;
                   1025:                ex->ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT;
                   1026: 
                   1027:                // PMM
                   1028:                if (type == TE_BLASTER2)
                   1029:                        ex->ent.skinnum = 1;
                   1030:                else // flechette
                   1031:                        ex->ent.skinnum = 2;
                   1032: 
                   1033:                ex->start = cl.frame.servertime - 100;
                   1034:                ex->light = 150;
                   1035:                // PMM
                   1036:                if (type == TE_BLASTER2)
                   1037:                        ex->lightcolor[1] = 1;
                   1038:                else // flechette
                   1039:                {
                   1040:                        ex->lightcolor[0] = 0.19;
                   1041:                        ex->lightcolor[1] = 0.41;
                   1042:                        ex->lightcolor[2] = 0.75;
                   1043:                }
                   1044:                ex->ent.model = cl_mod_explode;
                   1045:                ex->frames = 4;
                   1046:                S_StartSound (pos,  0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                   1047:                break;
                   1048: 
                   1049: 
                   1050:        case TE_LIGHTNING:
                   1051:                ent = CL_ParseLightning (cl_mod_lightning);
                   1052:                S_StartSound (NULL, ent, CHAN_WEAPON, cl_sfx_lightning, 1, ATTN_NORM, 0);
                   1053:                break;
                   1054: 
                   1055:        case TE_DEBUGTRAIL:
                   1056:                MSG_ReadPos (&net_message, pos);
                   1057:                MSG_ReadPos (&net_message, pos2);
                   1058:                CL_DebugTrail (pos, pos2);
                   1059:                break;
                   1060: 
                   1061:        case TE_PLAIN_EXPLOSION:
                   1062:                MSG_ReadPos (&net_message, pos);
                   1063: 
                   1064:                ex = CL_AllocExplosion ();
                   1065:                VectorCopy (pos, ex->ent.origin);
                   1066:                ex->type = ex_poly;
                   1067:                ex->ent.flags = RF_FULLBRIGHT;
                   1068:                ex->start = cl.frame.servertime - 100;
                   1069:                ex->light = 350;
                   1070:                ex->lightcolor[0] = 1.0;
                   1071:                ex->lightcolor[1] = 0.5;
                   1072:                ex->lightcolor[2] = 0.5;
                   1073:                ex->ent.angles[1] = rand() % 360;
                   1074:                ex->ent.model = cl_mod_explo4;
                   1075:                if (frand() < 0.5)
                   1076:                        ex->baseframe = 15;
                   1077:                ex->frames = 15;
                   1078:                if (type == TE_ROCKET_EXPLOSION_WATER)
                   1079:                        S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0);
                   1080:                else
                   1081:                        S_StartSound (pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0);
                   1082:                break;
                   1083: 
                   1084:        case TE_FLASHLIGHT:
                   1085:                MSG_ReadPos(&net_message, pos);
                   1086:                ent = MSG_ReadShort(&net_message);
                   1087:                CL_Flashlight(ent, pos);
                   1088:                break;
                   1089: 
                   1090:        case TE_FORCEWALL:
                   1091:                MSG_ReadPos(&net_message, pos);
                   1092:                MSG_ReadPos(&net_message, pos2);
                   1093:                color = MSG_ReadByte (&net_message);
                   1094:                CL_ForceWall(pos, pos2, color);
                   1095:                break;
                   1096: 
                   1097:        case TE_HEATBEAM:
                   1098:                ent = CL_ParsePlayerBeam (cl_mod_heatbeam);
                   1099:                break;
                   1100: 
                   1101:        case TE_MONSTER_HEATBEAM:
                   1102:                ent = CL_ParsePlayerBeam (cl_mod_monster_heatbeam);
                   1103:                break;
                   1104: 
                   1105:        case TE_HEATBEAM_SPARKS:
                   1106: //             cnt = MSG_ReadByte (&net_message);
                   1107:                cnt = 50;
                   1108:                MSG_ReadPos (&net_message, pos);
                   1109:                MSG_ReadDir (&net_message, dir);
                   1110: //             r = MSG_ReadByte (&net_message);
                   1111: //             magnitude = MSG_ReadShort (&net_message);
                   1112:                r = 8;
                   1113:                magnitude = 60;
                   1114:                color = r & 0xff;
                   1115:                CL_ParticleSteamEffect (pos, dir, color, cnt, magnitude);
                   1116:                S_StartSound (pos,  0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                   1117:                break;
1.1       root     1118:        
1.1.1.3   root     1119:        case TE_HEATBEAM_STEAM:
                   1120: //             cnt = MSG_ReadByte (&net_message);
                   1121:                cnt = 20;
                   1122:                MSG_ReadPos (&net_message, pos);
                   1123:                MSG_ReadDir (&net_message, dir);
                   1124: //             r = MSG_ReadByte (&net_message);
                   1125: //             magnitude = MSG_ReadShort (&net_message);
                   1126: //             color = r & 0xff;
                   1127:                color = 0xe0;
                   1128:                magnitude = 60;
                   1129:                CL_ParticleSteamEffect (pos, dir, color, cnt, magnitude);
                   1130:                S_StartSound (pos,  0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                   1131:                break;
                   1132: 
                   1133:        case TE_STEAM:
                   1134:                CL_ParseSteam();
                   1135:                break;
                   1136: 
                   1137:        case TE_BUBBLETRAIL2:
                   1138: //             cnt = MSG_ReadByte (&net_message);
                   1139:                cnt = 8;
                   1140:                MSG_ReadPos (&net_message, pos);
                   1141:                MSG_ReadPos (&net_message, pos2);
                   1142:                CL_BubbleTrail2 (pos, pos2, cnt);
                   1143:                S_StartSound (pos,  0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                   1144:                break;
                   1145: 
                   1146:        case TE_MOREBLOOD:
                   1147:                MSG_ReadPos (&net_message, pos);
                   1148:                MSG_ReadDir (&net_message, dir);
                   1149:                CL_ParticleEffect (pos, dir, 0xe8, 250);
                   1150:                break;
                   1151: 
                   1152:        case TE_CHAINFIST_SMOKE:
                   1153:                dir[0]=0; dir[1]=0; dir[2]=1;
                   1154:                MSG_ReadPos(&net_message, pos);
                   1155:                CL_ParticleSmokeEffect (pos, dir, 0, 20, 20);
                   1156:                break;
                   1157: 
                   1158:        case TE_ELECTRIC_SPARKS:
                   1159:                MSG_ReadPos (&net_message, pos);
                   1160:                MSG_ReadDir (&net_message, dir);
                   1161: //             CL_ParticleEffect (pos, dir, 109, 40);
                   1162:                CL_ParticleEffect (pos, dir, 0x75, 40);
                   1163:                //FIXME : replace or remove this sound
                   1164:                S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                   1165:                break;
                   1166: 
                   1167:        case TE_TRACKER_EXPLOSION:
                   1168:                MSG_ReadPos (&net_message, pos);
                   1169:                CL_ColorFlash (pos, 0, 150, -1, -1, -1);
                   1170:                CL_ColorExplosionParticles (pos, 0, 1);
                   1171: //             CL_Tracker_Explode (pos);
                   1172:                S_StartSound (pos, 0, 0, cl_sfx_disrexp, 1, ATTN_NORM, 0);
                   1173:                break;
                   1174: 
                   1175:        case TE_TELEPORT_EFFECT:
                   1176:        case TE_DBALL_GOAL:
                   1177:                MSG_ReadPos (&net_message, pos);
                   1178:                CL_TeleportParticles (pos);
                   1179:                break;
                   1180: 
                   1181:        case TE_WIDOWBEAMOUT:
                   1182:                CL_ParseWidow ();
                   1183:                break;
                   1184: 
                   1185:        case TE_NUKEBLAST:
                   1186:                CL_ParseNuke ();
                   1187:                break;
                   1188: 
                   1189:        case TE_WIDOWSPLASH:
                   1190:                MSG_ReadPos (&net_message, pos);
                   1191:                CL_WidowSplash (pos);
                   1192:                break;
                   1193: //PGM
                   1194: //==============
                   1195: 
1.1       root     1196:        default:
                   1197:                Com_Error (ERR_DROP, "CL_ParseTEnt: bad type");
                   1198:        }
                   1199: }
                   1200: 
                   1201: /*
                   1202: =================
                   1203: CL_AddBeams
                   1204: =================
                   1205: */
                   1206: void CL_AddBeams (void)
                   1207: {
                   1208:        int                     i,j;
                   1209:        beam_t          *b;
                   1210:        vec3_t          dist, org;
                   1211:        float           d;
                   1212:        entity_t        ent;
                   1213:        float           yaw, pitch;
                   1214:        float           forward;
1.1.1.3   root     1215:        float           len, steps;
                   1216:        float           model_length;
                   1217:        
1.1       root     1218: // update beams
                   1219:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                   1220:        {
                   1221:                if (!b->model || b->endtime < cl.time)
                   1222:                        continue;
                   1223: 
1.1.1.3   root     1224:                // if coming from the player, update the start position
1.1       root     1225:                if (b->entity == cl.playernum+1)        // entity 0 is the world
                   1226:                {
                   1227:                        VectorCopy (cl.refdef.vieworg, b->start);
                   1228:                        b->start[2] -= 22;      // adjust for view height
                   1229:                }
                   1230:                VectorAdd (b->start, b->offset, org);
                   1231: 
                   1232:        // calculate pitch and yaw
                   1233:                VectorSubtract (b->end, org, dist);
                   1234: 
                   1235:                if (dist[1] == 0 && dist[0] == 0)
                   1236:                {
                   1237:                        yaw = 0;
                   1238:                        if (dist[2] > 0)
                   1239:                                pitch = 90;
                   1240:                        else
                   1241:                                pitch = 270;
                   1242:                }
                   1243:                else
                   1244:                {
1.1.1.3   root     1245:        // PMM - fixed to correct for pitch of 0
1.1.1.2   root     1246:                        if (dist[0])
1.1.1.3   root     1247:                                yaw = (atan2(dist[1], dist[0]) * 180 / M_PI);
                   1248:                        else if (dist[1] > 0)
                   1249:                                yaw = 90;
1.1.1.2   root     1250:                        else
1.1.1.3   root     1251:                                yaw = 270;
1.1       root     1252:                        if (yaw < 0)
                   1253:                                yaw += 360;
                   1254:        
                   1255:                        forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
1.1.1.3   root     1256:                        pitch = (atan2(dist[2], forward) * -180.0 / M_PI);
1.1       root     1257:                        if (pitch < 0)
1.1.1.3   root     1258:                                pitch += 360.0;
1.1       root     1259:                }
                   1260: 
                   1261:        // add new entities for the beams
                   1262:                d = VectorNormalize(dist);
1.1.1.3   root     1263: 
1.1       root     1264:                memset (&ent, 0, sizeof(ent));
1.1.1.3   root     1265:                if (b->model == cl_mod_lightning)
                   1266:                {
                   1267:                        model_length = 35.0;
                   1268:                        d-= 20.0;  // correction so it doesn't end in middle of tesla
                   1269:                }
                   1270:                else
                   1271:                {
                   1272:                        model_length = 30.0;
                   1273:                }
                   1274:                steps = ceil(d/model_length);
                   1275:                len = (d-model_length)/(steps-1);
                   1276: 
                   1277:                // PMM - special case for lightning model .. if the real length is shorter than the model,
                   1278:                // flip it around & draw it from the end to the start.  This prevents the model from going
                   1279:                // through the tesla mine (instead it goes through the target)
                   1280:                if ((b->model == cl_mod_lightning) && (d <= model_length))
                   1281:                {
                   1282: //                     Com_Printf ("special case\n");
                   1283:                        VectorCopy (b->end, ent.origin);
                   1284:                        // offset to push beam outside of tesla model (negative because dist is from end to start
                   1285:                        // for this beam)
                   1286: //                     for (j=0 ; j<3 ; j++)
                   1287: //                             ent.origin[j] -= dist[j]*10.0;
                   1288:                        ent.model = b->model;
                   1289:                        ent.flags = RF_FULLBRIGHT;
                   1290:                        ent.angles[0] = pitch;
                   1291:                        ent.angles[1] = yaw;
                   1292:                        ent.angles[2] = rand()%360;
                   1293:                        V_AddEntity (&ent);                     
                   1294:                        return;
                   1295:                }
1.1       root     1296:                while (d > 0)
                   1297:                {
                   1298:                        VectorCopy (org, ent.origin);
                   1299:                        ent.model = b->model;
1.1.1.3   root     1300:                        if (b->model == cl_mod_lightning)
                   1301:                        {
                   1302:                                ent.flags = RF_FULLBRIGHT;
                   1303:                                ent.angles[0] = -pitch;
                   1304:                                ent.angles[1] = yaw + 180.0;
                   1305:                                ent.angles[2] = rand()%360;
                   1306:                        }
                   1307:                        else
                   1308:                        {
                   1309:                                ent.angles[0] = pitch;
                   1310:                                ent.angles[1] = yaw;
                   1311:                                ent.angles[2] = rand()%360;
                   1312:                        }
                   1313:                        
                   1314: //                     Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity);
                   1315:                        V_AddEntity (&ent);
                   1316: 
                   1317:                        for (j=0 ; j<3 ; j++)
                   1318:                                org[j] += dist[j]*len;
                   1319:                        d -= model_length;
                   1320:                }
                   1321:        }
                   1322: }
                   1323: 
                   1324: 
                   1325: /*
                   1326: //                             Com_Printf ("Endpoint:  %f %f %f\n", b->end[0], b->end[1], b->end[2]);
                   1327: //                             Com_Printf ("Pred View Angles:  %f %f %f\n", cl.predicted_angles[0], cl.predicted_angles[1], cl.predicted_angles[2]);
                   1328: //                             Com_Printf ("Act View Angles: %f %f %f\n", cl.refdef.viewangles[0], cl.refdef.viewangles[1], cl.refdef.viewangles[2]);
                   1329: //                             VectorCopy (cl.predicted_origin, b->start);
                   1330: //                             b->start[2] += 22;      // adjust for view height
                   1331: //                             if (fabs(cl.refdef.vieworg[2] - b->start[2]) >= 10) {
                   1332: //                                     b->start[2] = cl.refdef.vieworg[2];
                   1333: //                             }
                   1334: 
                   1335: //                             Com_Printf ("Time:  %d %d %f\n", cl.time, cls.realtime, cls.frametime);
                   1336: */
                   1337: 
                   1338: extern cvar_t *hand;
                   1339: 
                   1340: /*
                   1341: =================
                   1342: ROGUE - draw player locked beams
                   1343: CL_AddPlayerBeams
                   1344: =================
                   1345: */
                   1346: void CL_AddPlayerBeams (void)
                   1347: {
                   1348:        int                     i,j;
                   1349:        beam_t          *b;
                   1350:        vec3_t          dist, org;
                   1351:        float           d;
                   1352:        entity_t        ent;
                   1353:        float           yaw, pitch;
                   1354:        float           forward;
                   1355:        float           len, steps;
                   1356:        int                     framenum;
                   1357:        float           model_length;
                   1358:        
                   1359:        float           hand_multiplier;
                   1360:        frame_t         *oldframe;
                   1361:        player_state_t  *ps, *ops;
                   1362: 
                   1363: //PMM
                   1364:        if (hand)
                   1365:        {
                   1366:                if (hand->value == 2)
                   1367:                        hand_multiplier = 0;
                   1368:                else if (hand->value == 1)
                   1369:                        hand_multiplier = -1;
                   1370:                else
                   1371:                        hand_multiplier = 1;
                   1372:        }
                   1373:        else 
                   1374:        {
                   1375:                hand_multiplier = 1;
                   1376:        }
                   1377: //PMM
                   1378: 
                   1379: // update beams
                   1380:        for (i=0, b=cl_playerbeams ; i< MAX_BEAMS ; i++, b++)
                   1381:        {
                   1382:                vec3_t          f,r,u;
                   1383:                if (!b->model || b->endtime < cl.time)
                   1384:                        continue;
                   1385: 
                   1386:                if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam))
                   1387:                {
                   1388: 
                   1389:                        // if coming from the player, update the start position
                   1390:                        if (b->entity == cl.playernum+1)        // entity 0 is the world
                   1391:                        {       
                   1392:                                // set up gun position
                   1393:                                // code straight out of CL_AddViewWeapon
                   1394:                                ps = &cl.frame.playerstate;
                   1395:                                j = (cl.frame.serverframe - 1) & UPDATE_MASK;
                   1396:                                oldframe = &cl.frames[j];
                   1397:                                if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid)
                   1398:                                        oldframe = &cl.frame;           // previous frame was dropped or involid
                   1399:                                ops = &oldframe->playerstate;
                   1400:                                for (j=0 ; j<3 ; j++)
                   1401:                                {
                   1402:                                        b->start[j] = cl.refdef.vieworg[j] + ops->gunoffset[j]
                   1403:                                                + cl.lerpfrac * (ps->gunoffset[j] - ops->gunoffset[j]);
                   1404:                                }
                   1405:                                VectorMA (b->start, (hand_multiplier * b->offset[0]), cl.v_right, org);
                   1406:                                VectorMA (     org, b->offset[1], cl.v_forward, org);
                   1407:                                VectorMA (     org, b->offset[2], cl.v_up, org);
                   1408:                                if ((hand) && (hand->value == 2)) {
                   1409:                                        VectorMA (org, -1, cl.v_up, org);
                   1410:                                }
                   1411:                                // FIXME - take these out when final
                   1412:                                VectorCopy (cl.v_right, r);
                   1413:                                VectorCopy (cl.v_forward, f);
                   1414:                                VectorCopy (cl.v_up, u);
                   1415: 
                   1416:                        }
                   1417:                        else
                   1418:                                VectorCopy (b->start, org);
                   1419:                }
                   1420:                else
                   1421:                {
                   1422:                        // if coming from the player, update the start position
                   1423:                        if (b->entity == cl.playernum+1)        // entity 0 is the world
                   1424:                        {
                   1425:                                VectorCopy (cl.refdef.vieworg, b->start);
                   1426:                                b->start[2] -= 22;      // adjust for view height
                   1427:                        }
                   1428:                        VectorAdd (b->start, b->offset, org);
                   1429:                }
                   1430: 
                   1431:        // calculate pitch and yaw
                   1432:                VectorSubtract (b->end, org, dist);
                   1433: 
                   1434: //PMM
                   1435:                if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.playernum+1))
                   1436:                {
                   1437:                        vec_t len;
                   1438: 
                   1439:                        len = VectorLength (dist);
                   1440:                        VectorScale (f, len, dist);
                   1441:                        VectorMA (dist, (hand_multiplier * b->offset[0]), r, dist);
                   1442:                        VectorMA (dist, b->offset[1], f, dist);
                   1443:                        VectorMA (dist, b->offset[2], u, dist);
                   1444:                        if ((hand) && (hand->value == 2)) {
                   1445:                                VectorMA (org, -1, cl.v_up, org);
                   1446:                        }
                   1447:                }
                   1448: //PMM
                   1449: 
                   1450:                if (dist[1] == 0 && dist[0] == 0)
                   1451:                {
                   1452:                        yaw = 0;
                   1453:                        if (dist[2] > 0)
                   1454:                                pitch = 90;
                   1455:                        else
                   1456:                                pitch = 270;
                   1457:                }
                   1458:                else
                   1459:                {
                   1460:        // PMM - fixed to correct for pitch of 0
                   1461:                        if (dist[0])
                   1462:                                yaw = (atan2(dist[1], dist[0]) * 180 / M_PI);
                   1463:                        else if (dist[1] > 0)
                   1464:                                yaw = 90;
                   1465:                        else
                   1466:                                yaw = 270;
                   1467:                        if (yaw < 0)
                   1468:                                yaw += 360;
                   1469:        
                   1470:                        forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
                   1471:                        pitch = (atan2(dist[2], forward) * -180.0 / M_PI);
                   1472:                        if (pitch < 0)
                   1473:                                pitch += 360.0;
                   1474:                }
                   1475:                
                   1476:                if (cl_mod_heatbeam && (b->model == cl_mod_heatbeam))
                   1477:                {
                   1478:                        if (b->entity != cl.playernum+1)
                   1479:                        {
                   1480:                                framenum = 2;
                   1481: //                             Com_Printf ("Third person\n");
                   1482:                                ent.angles[0] = -pitch;
                   1483:                                ent.angles[1] = yaw + 180.0;
                   1484:                                ent.angles[2] = 0;
                   1485: //                             Com_Printf ("%f %f - %f %f %f\n", -pitch, yaw+180.0, b->offset[0], b->offset[1], b->offset[2]);
                   1486:                                AngleVectors(ent.angles, f, r, u);
                   1487:                                        
                   1488:                                // if it's a non-origin offset, it's a player, so use the hardcoded player offset
                   1489:                                if (!VectorCompare (b->offset, vec3_origin))
                   1490:                                {
                   1491:                                        VectorMA (org, -(b->offset[0])+1, r, org);
                   1492:                                        VectorMA (org, -(b->offset[1]), f, org);
                   1493:                                        VectorMA (org, -(b->offset[2])-10, u, org);
                   1494:                                }
                   1495:                                else
                   1496:                                {
                   1497:                                        // if it's a monster, do the particle effect
                   1498:                                        CL_MonsterPlasma_Shell(b->start);
                   1499:                                }
                   1500:                        }
                   1501:                        else
                   1502:                        {
                   1503:                                framenum = 1;
                   1504:                        }
                   1505:                }
                   1506: 
                   1507:                // if it's the heatbeam, draw the particle effect
                   1508:                if ((cl_mod_heatbeam && (b->model == cl_mod_heatbeam) && (b->entity == cl.playernum+1)))
                   1509:                {
                   1510:                        CL_Heatbeam (org, dist);
                   1511:                }
                   1512: 
                   1513:        // add new entities for the beams
                   1514:                d = VectorNormalize(dist);
                   1515: 
                   1516:                memset (&ent, 0, sizeof(ent));
                   1517:                if (b->model == cl_mod_heatbeam)
                   1518:                {
                   1519:                        model_length = 32.0;
                   1520:                }
                   1521:                else if (b->model == cl_mod_lightning)
                   1522:                {
                   1523:                        model_length = 35.0;
                   1524:                        d-= 20.0;  // correction so it doesn't end in middle of tesla
                   1525:                }
                   1526:                else
                   1527:                {
                   1528:                        model_length = 30.0;
                   1529:                }
                   1530:                steps = ceil(d/model_length);
                   1531:                len = (d-model_length)/(steps-1);
                   1532: 
                   1533:                // PMM - special case for lightning model .. if the real length is shorter than the model,
                   1534:                // flip it around & draw it from the end to the start.  This prevents the model from going
                   1535:                // through the tesla mine (instead it goes through the target)
                   1536:                if ((b->model == cl_mod_lightning) && (d <= model_length))
                   1537:                {
                   1538: //                     Com_Printf ("special case\n");
                   1539:                        VectorCopy (b->end, ent.origin);
                   1540:                        // offset to push beam outside of tesla model (negative because dist is from end to start
                   1541:                        // for this beam)
                   1542: //                     for (j=0 ; j<3 ; j++)
                   1543: //                             ent.origin[j] -= dist[j]*10.0;
                   1544:                        ent.model = b->model;
                   1545:                        ent.flags = RF_FULLBRIGHT;
1.1       root     1546:                        ent.angles[0] = pitch;
                   1547:                        ent.angles[1] = yaw;
                   1548:                        ent.angles[2] = rand()%360;
1.1.1.3   root     1549:                        V_AddEntity (&ent);                     
                   1550:                        return;
                   1551:                }
                   1552:                while (d > 0)
                   1553:                {
                   1554:                        VectorCopy (org, ent.origin);
                   1555:                        ent.model = b->model;
                   1556:                        if(cl_mod_heatbeam && (b->model == cl_mod_heatbeam))
                   1557:                        {
                   1558: //                             ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT;
                   1559: //                             ent.alpha = 0.3;
                   1560:                                ent.flags = RF_FULLBRIGHT;
                   1561:                                ent.angles[0] = -pitch;
                   1562:                                ent.angles[1] = yaw + 180.0;
                   1563:                                ent.angles[2] = (cl.time) % 360;
                   1564: //                             ent.angles[2] = rand()%360;
                   1565:                                ent.frame = framenum;
                   1566:                        }
                   1567:                        else if (b->model == cl_mod_lightning)
                   1568:                        {
                   1569:                                ent.flags = RF_FULLBRIGHT;
                   1570:                                ent.angles[0] = -pitch;
                   1571:                                ent.angles[1] = yaw + 180.0;
                   1572:                                ent.angles[2] = rand()%360;
                   1573:                        }
                   1574:                        else
                   1575:                        {
                   1576:                                ent.angles[0] = pitch;
                   1577:                                ent.angles[1] = yaw;
                   1578:                                ent.angles[2] = rand()%360;
                   1579:                        }
                   1580:                        
                   1581: //                     Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity);
1.1       root     1582:                        V_AddEntity (&ent);
                   1583: 
                   1584:                        for (j=0 ; j<3 ; j++)
1.1.1.3   root     1585:                                org[j] += dist[j]*len;
                   1586:                        d -= model_length;
1.1       root     1587:                }
                   1588:        }
                   1589: }
                   1590: 
                   1591: /*
                   1592: =================
                   1593: CL_AddExplosions
                   1594: =================
                   1595: */
                   1596: void CL_AddExplosions (void)
                   1597: {
                   1598:        entity_t        *ent;
                   1599:        int                     i;
                   1600:        explosion_t     *ex;
                   1601:        float           frac;
                   1602:        int                     f;
                   1603: 
                   1604:        memset (&ent, 0, sizeof(ent));
                   1605: 
                   1606:        for (i=0, ex=cl_explosions ; i< MAX_EXPLOSIONS ; i++, ex++)
                   1607:        {
                   1608:                if (ex->type == ex_free)
                   1609:                        continue;
                   1610:                frac = (cl.time - ex->start)/100.0;
                   1611:                f = floor(frac);
                   1612: 
                   1613:                ent = &ex->ent;
                   1614: 
                   1615:                switch (ex->type)
                   1616:                {
                   1617:                case ex_mflash:
                   1618:                        if (f >= ex->frames-1)
                   1619:                                ex->type = ex_free;
                   1620:                        break;
                   1621:                case ex_misc:
                   1622:                        if (f >= ex->frames-1)
                   1623:                        {
                   1624:                                ex->type = ex_free;
                   1625:                                break;
                   1626:                        }
                   1627:                        ent->alpha = 1.0 - frac/(ex->frames-1);
                   1628:                        break;
                   1629:                case ex_flash:
                   1630:                        if (f >= 1)
                   1631:                        {
                   1632:                                ex->type = ex_free;
                   1633:                                break;
                   1634:                        }
                   1635:                        ent->alpha = 1.0;
                   1636:                        break;
                   1637:                case ex_poly:
                   1638:                        if (f >= ex->frames-1)
                   1639:                        {
                   1640:                                ex->type = ex_free;
                   1641:                                break;
                   1642:                        }
                   1643: 
                   1644:                        ent->alpha = (16.0 - (float)f)/16.0;
                   1645: 
                   1646:                        if (f < 10)
                   1647:                        {
                   1648:                                ent->skinnum = (f>>1);
                   1649:                                if (ent->skinnum < 0)
                   1650:                                        ent->skinnum = 0;
                   1651:                        }
                   1652:                        else
                   1653:                        {
                   1654:                                ent->flags |= RF_TRANSLUCENT;
                   1655:                                if (f < 13)
                   1656:                                        ent->skinnum = 5;
                   1657:                                else
                   1658:                                        ent->skinnum = 6;
                   1659:                        }
                   1660:                        break;
1.1.1.2   root     1661:                case ex_poly2:
                   1662:                        if (f >= ex->frames-1)
                   1663:                        {
                   1664:                                ex->type = ex_free;
                   1665:                                break;
                   1666:                        }
                   1667: 
                   1668:                        ent->alpha = (5.0 - (float)f)/5.0;
                   1669:                        ent->skinnum = 0;
                   1670:                        ent->flags |= RF_TRANSLUCENT;
                   1671:                        break;
1.1       root     1672:                }
                   1673: 
                   1674:                if (ex->type == ex_free)
                   1675:                        continue;
                   1676:                if (ex->light)
                   1677:                {
                   1678:                        V_AddLight (ent->origin, ex->light*ent->alpha,
                   1679:                                ex->lightcolor[0], ex->lightcolor[1], ex->lightcolor[2]);
                   1680:                }
                   1681: 
                   1682:                VectorCopy (ent->origin, ent->oldorigin);
                   1683: 
                   1684:                if (f < 0)
                   1685:                        f = 0;
                   1686:                ent->frame = ex->baseframe + f + 1;
                   1687:                ent->oldframe = ex->baseframe + f;
                   1688:                ent->backlerp = 1.0 - cl.lerpfrac;
                   1689: 
                   1690:                V_AddEntity (ent);
                   1691:        }
                   1692: }
                   1693: 
                   1694: 
                   1695: /*
                   1696: =================
                   1697: CL_AddLasers
                   1698: =================
                   1699: */
                   1700: void CL_AddLasers (void)
                   1701: {
                   1702:        laser_t         *l;
                   1703:        int                     i;
                   1704: 
                   1705:        for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
                   1706:        {
                   1707:                if (l->endtime >= cl.time)
                   1708:                        V_AddEntity (&l->ent);
                   1709:        }
                   1710: }
                   1711: 
1.1.1.3   root     1712: /* PMM - CL_Sustains */
                   1713: void CL_ProcessSustain ()
                   1714: {
                   1715:        cl_sustain_t    *s;
                   1716:        int                             i;
                   1717: 
                   1718:        for (i=0, s=cl_sustains; i< MAX_SUSTAINS; i++, s++)
                   1719:        {
                   1720:                if (s->id)
                   1721:                        if ((s->endtime >= cl.time) && (cl.time >= s->nextthink))
                   1722:                        {
                   1723: //                             Com_Printf ("think %d %d %d\n", cl.time, s->nextthink, s->thinkinterval);
                   1724:                                s->think (s);
                   1725:                        }
                   1726:                        else if (s->endtime < cl.time)
                   1727:                                s->id = 0;
                   1728:        }
                   1729: }
1.1       root     1730: 
                   1731: /*
                   1732: =================
                   1733: CL_AddTEnts
                   1734: =================
                   1735: */
                   1736: void CL_AddTEnts (void)
                   1737: {
                   1738:        CL_AddBeams ();
1.1.1.3   root     1739:        // PMM - draw plasma beams
                   1740:        CL_AddPlayerBeams ();
1.1       root     1741:        CL_AddExplosions ();
                   1742:        CL_AddLasers ();
1.1.1.3   root     1743:        // PMM - set up sustain
                   1744:        CL_ProcessSustain();
1.1       root     1745: }

unix.superglobalmegacorp.com

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