Annotation of quake2/client/cl_tent.c, revision 1.1.1.1

1.1       root        1: // cl_tent.c -- client side temporary entities
                      2: 
                      3: #include "client.h"
                      4: 
                      5: typedef enum
                      6: {
                      7:        ex_free, ex_explosion, ex_misc, ex_flash, ex_mflash, ex_poly
                      8: } exptype_t;
                      9: 
                     10: typedef struct
                     11: {
                     12:        exptype_t       type;
                     13:        entity_t        ent;
                     14: 
                     15:        int                     frames;
                     16:        float           light;
                     17:        vec3_t          lightcolor;
                     18:        float           start;
                     19:        int                     baseframe;
                     20: } explosion_t;
                     21: 
                     22: 
                     23: 
                     24: #define        MAX_EXPLOSIONS  32
                     25: explosion_t    cl_explosions[MAX_EXPLOSIONS];
                     26: 
                     27: 
                     28: #define        MAX_BEAMS       32
                     29: typedef struct
                     30: {
                     31:        int             entity;
                     32:        struct model_s  *model;
                     33:        int             endtime;
                     34:        vec3_t  offset;
                     35:        vec3_t  start, end;
                     36: } beam_t;
                     37: beam_t         cl_beams[MAX_BEAMS];
                     38: 
                     39: 
                     40: #define        MAX_LASERS      32
                     41: typedef struct
                     42: {
                     43:        entity_t        ent;
                     44:        int                     endtime;
                     45: } laser_t;
                     46: laser_t                cl_lasers[MAX_LASERS];
                     47: 
                     48: 
                     49: void CL_BlasterParticles (vec3_t org, vec3_t dir);
                     50: void CL_ExplosionParticles (vec3_t org);
                     51: void CL_BFGExplosionParticles (vec3_t org);
                     52: 
                     53: struct sfx_s   *cl_sfx_ric1;
                     54: struct sfx_s   *cl_sfx_ric2;
                     55: struct sfx_s   *cl_sfx_ric3;
                     56: struct sfx_s   *cl_sfx_lashit;
                     57: struct sfx_s   *cl_sfx_spark5;
                     58: struct sfx_s   *cl_sfx_spark6;
                     59: struct sfx_s   *cl_sfx_spark7;
                     60: struct sfx_s   *cl_sfx_railg;
                     61: struct sfx_s   *cl_sfx_rockexp;
                     62: struct sfx_s   *cl_sfx_grenexp;
                     63: struct sfx_s   *cl_sfx_watrexp;
                     64: 
                     65: struct sfx_s   *cl_sfx_footsteps[4];
                     66: 
                     67: struct model_s *cl_mod_explode;
                     68: struct model_s *cl_mod_smoke;
                     69: struct model_s *cl_mod_flash;
                     70: struct model_s *cl_mod_parasite_segment;
                     71: struct model_s *cl_mod_grapple_cable;
                     72: struct model_s *cl_mod_parasite_tip;
                     73: struct model_s *cl_mod_explo4;
                     74: struct model_s *cl_mod_bfg_explo;
                     75: struct model_s *cl_mod_powerscreen;
                     76: 
                     77: /*
                     78: =================
                     79: CL_RegisterTEntSounds
                     80: =================
                     81: */
                     82: void CL_RegisterTEntSounds (void)
                     83: {
                     84:        int             i;
                     85:        char    name[MAX_QPATH];
                     86: 
                     87:        cl_sfx_ric1 = S_RegisterSound ("world/ric1.wav");
                     88:        cl_sfx_ric2 = S_RegisterSound ("world/ric2.wav");
                     89:        cl_sfx_ric3 = S_RegisterSound ("world/ric3.wav");
                     90:        cl_sfx_lashit = S_RegisterSound("weapons/lashit.wav");
                     91:        cl_sfx_spark5 = S_RegisterSound ("world/spark5.wav");
                     92:        cl_sfx_spark6 = S_RegisterSound ("world/spark6.wav");
                     93:        cl_sfx_spark7 = S_RegisterSound ("world/spark7.wav");
                     94:        cl_sfx_railg = S_RegisterSound ("weapons/railgf1a.wav");
                     95:        cl_sfx_rockexp = S_RegisterSound ("weapons/rocklx1a.wav");
                     96:        cl_sfx_grenexp = S_RegisterSound ("weapons/grenlx1a.wav");
                     97:        cl_sfx_watrexp = S_RegisterSound ("weapons/xpld_wat.wav");
                     98: 
                     99:        S_RegisterSound ("player/land1.wav");
                    100: 
                    101:        S_RegisterSound ("player/fall2.wav");
                    102:        S_RegisterSound ("player/fall1.wav");
                    103: 
                    104:        for (i=0 ; i<4 ; i++)
                    105:        {
                    106:                Com_sprintf (name, sizeof(name), "player/step%i.wav", i+1);
                    107:                cl_sfx_footsteps[i] = S_RegisterSound (name);
                    108:        }
                    109: }      
                    110: 
                    111: /*
                    112: =================
                    113: CL_RegisterTEntModels
                    114: =================
                    115: */
                    116: void CL_RegisterTEntModels (void)
                    117: {
                    118:        cl_mod_explode = re.RegisterModel ("models/objects/explode/tris.md2");
                    119:        cl_mod_smoke = re.RegisterModel ("models/objects/smoke/tris.md2");
                    120:        cl_mod_flash = re.RegisterModel ("models/objects/flash/tris.md2");
                    121:        cl_mod_parasite_segment = re.RegisterModel ("models/monsters/parasite/segment/tris.md2");
                    122:        cl_mod_grapple_cable = re.RegisterModel ("models/ctf/segment/tris.md2");
                    123:        cl_mod_parasite_tip = re.RegisterModel ("models/monsters/parasite/tip/tris.md2");
                    124:        cl_mod_explo4 = re.RegisterModel ("models/objects/r_explode/tris.md2");
                    125:        cl_mod_bfg_explo = re.RegisterModel ("sprites/s_bfg2.sp2");
                    126:        cl_mod_powerscreen = re.RegisterModel ("models/items/armor/effect/tris.md2");
                    127: 
                    128: re.RegisterModel ("models/objects/laser/tris.md2");
                    129: re.RegisterModel ("models/objects/grenade2/tris.md2");
                    130: re.RegisterModel ("models/weapons/v_machn/tris.md2");
                    131: re.RegisterModel ("models/weapons/v_handgr/tris.md2");
                    132: re.RegisterModel ("models/weapons/v_shotg2/tris.md2");
                    133: re.RegisterModel ("models/objects/gibs/bone/tris.md2");
                    134: re.RegisterModel ("models/objects/gibs/sm_meat/tris.md2");
                    135: re.RegisterModel ("models/objects/gibs/bone2/tris.md2");
                    136: 
                    137: re.RegisterPic ("w_machinegun");
                    138: re.RegisterPic ("a_bullets");
                    139: re.RegisterPic ("i_health");
                    140: re.RegisterPic ("a_grenades");
                    141: }      
                    142: 
                    143: /*
                    144: =================
                    145: CL_ClearTEnts
                    146: =================
                    147: */
                    148: void CL_ClearTEnts (void)
                    149: {
                    150:        memset (cl_beams, 0, sizeof(cl_beams));
                    151:        memset (cl_explosions, 0, sizeof(cl_explosions));
                    152:        memset (cl_lasers, 0, sizeof(cl_lasers));
                    153: }
                    154: 
                    155: /*
                    156: =================
                    157: CL_AllocExplosion
                    158: =================
                    159: */
                    160: explosion_t *CL_AllocExplosion (void)
                    161: {
                    162:        int             i;
                    163:        int             time;
                    164:        int             index;
                    165:        
                    166:        for (i=0 ; i<MAX_EXPLOSIONS ; i++)
                    167:        {
                    168:                if (cl_explosions[i].type == ex_free)
                    169:                {
                    170:                        memset (&cl_explosions[i], 0, sizeof (cl_explosions[i]));
                    171:                        return &cl_explosions[i];
                    172:                }
                    173:        }
                    174: // find the oldest explosion
                    175:        time = cl.time;
                    176:        index = 0;
                    177: 
                    178:        for (i=0 ; i<MAX_EXPLOSIONS ; i++)
                    179:                if (cl_explosions[i].start < time)
                    180:                {
                    181:                        time = cl_explosions[i].start;
                    182:                        index = i;
                    183:                }
                    184:        memset (&cl_explosions[index], 0, sizeof (cl_explosions[index]));
                    185:        return &cl_explosions[index];
                    186: }
                    187: 
                    188: /*
                    189: =================
                    190: CL_SmokeAndFlash
                    191: =================
                    192: */
                    193: void CL_SmokeAndFlash(vec3_t origin)
                    194: {
                    195:        explosion_t     *ex;
                    196: 
                    197:        ex = CL_AllocExplosion ();
                    198:        VectorCopy (origin, ex->ent.origin);
                    199:        ex->type = ex_misc;
                    200:        ex->frames = 4;
                    201:        ex->ent.flags = RF_TRANSLUCENT;
                    202:        ex->start = cl.frame.servertime - 100;
                    203:        ex->ent.model = cl_mod_smoke;
                    204: 
                    205:        ex = CL_AllocExplosion ();
                    206:        VectorCopy (origin, ex->ent.origin);
                    207:        ex->type = ex_flash;
                    208:        ex->ent.flags = RF_FULLBRIGHT;
                    209:        ex->frames = 2;
                    210:        ex->start = cl.frame.servertime - 100;
                    211:        ex->ent.model = cl_mod_flash;
                    212: }
                    213: 
                    214: /*
                    215: =================
                    216: CL_ParseParticles
                    217: =================
                    218: */
                    219: void CL_ParseParticles (void)
                    220: {
                    221:        int             color, count;
                    222:        vec3_t  pos, dir;
                    223: 
                    224:        MSG_ReadPos (&net_message, pos);
                    225:        MSG_ReadDir (&net_message, dir);
                    226: 
                    227:        color = MSG_ReadByte (&net_message);
                    228: 
                    229:        count = MSG_ReadByte (&net_message);
                    230: 
                    231:        CL_ParticleEffect (pos, dir, color, count);
                    232: }
                    233: 
                    234: /*
                    235: =================
                    236: CL_ParseBeam
                    237: =================
                    238: */
                    239: int CL_ParseBeam (struct model_s *model)
                    240: {
                    241:        int             ent;
                    242:        vec3_t  start, end;
                    243:        beam_t  *b;
                    244:        int             i;
                    245:        
                    246:        ent = MSG_ReadShort (&net_message);
                    247:        
                    248:        MSG_ReadPos (&net_message, start);
                    249:        MSG_ReadPos (&net_message, end);
                    250: 
                    251: // override any beam with the same entity
                    252:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    253:                if (b->entity == ent)
                    254:                {
                    255:                        b->entity = ent;
                    256:                        b->model = model;
                    257:                        b->endtime = cl.time + 200;
                    258:                        VectorCopy (start, b->start);
                    259:                        VectorCopy (end, b->end);
                    260:                        VectorClear (b->offset);
                    261:                        return ent;
                    262:                }
                    263: 
                    264: // find a free beam
                    265:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    266:        {
                    267:                if (!b->model || b->endtime < cl.time)
                    268:                {
                    269:                        b->entity = ent;
                    270:                        b->model = model;
                    271:                        b->endtime = cl.time + 200;
                    272:                        VectorCopy (start, b->start);
                    273:                        VectorCopy (end, b->end);
                    274:                        VectorClear (b->offset);
                    275:                        return ent;
                    276:                }
                    277:        }
                    278:        Com_Printf ("beam list overflow!\n");   
                    279:        return ent;
                    280: }
                    281: 
                    282: /*
                    283: =================
                    284: CL_ParseBeam2
                    285: =================
                    286: */
                    287: int CL_ParseBeam2 (struct model_s *model)
                    288: {
                    289:        int             ent;
                    290:        vec3_t  start, end, offset;
                    291:        beam_t  *b;
                    292:        int             i;
                    293:        
                    294:        ent = MSG_ReadShort (&net_message);
                    295:        
                    296:        MSG_ReadPos (&net_message, start);
                    297:        MSG_ReadPos (&net_message, end);
                    298:        MSG_ReadPos (&net_message, offset);
                    299: 
                    300: // override any beam with the same entity
                    301:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    302:                if (b->entity == ent)
                    303:                {
                    304:                        b->entity = ent;
                    305:                        b->model = model;
                    306:                        b->endtime = cl.time + 200;
                    307:                        VectorCopy (start, b->start);
                    308:                        VectorCopy (end, b->end);
                    309:                        VectorCopy (offset, b->offset);
                    310:                        return ent;
                    311:                }
                    312: 
                    313: // find a free beam
                    314:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    315:        {
                    316:                if (!b->model || b->endtime < cl.time)
                    317:                {
                    318:                        b->entity = ent;
                    319:                        b->model = model;
                    320:                        b->endtime = cl.time + 200;
                    321:                        VectorCopy (start, b->start);
                    322:                        VectorCopy (end, b->end);
                    323:                        VectorCopy (offset, b->offset);
                    324:                        return ent;
                    325:                }
                    326:        }
                    327:        Com_Printf ("beam list overflow!\n");   
                    328:        return ent;
                    329: }
                    330: 
                    331: /*
                    332: =================
                    333: CL_ParseLaser
                    334: =================
                    335: */
                    336: void CL_ParseLaser (int colors)
                    337: {
                    338:        vec3_t  start;
                    339:        vec3_t  end;
                    340:        laser_t *l;
                    341:        int             i;
                    342: 
                    343:        MSG_ReadPos (&net_message, start);
                    344:        MSG_ReadPos (&net_message, end);
                    345: 
                    346:        for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
                    347:        {
                    348:                if (l->endtime < cl.time)
                    349:                {
                    350:                        l->ent.flags = RF_TRANSLUCENT | RF_BEAM;
                    351:                        VectorCopy (start, l->ent.origin);
                    352:                        VectorCopy (end, l->ent.oldorigin);
                    353:                        l->ent.alpha = 0.30;
                    354:                        l->ent.skinnum = (colors >> ((rand() % 4)*8)) & 0xff;
                    355:                        l->ent.model = NULL;
                    356:                        l->ent.frame = 4;
                    357:                        l->endtime = cl.time + 100;
                    358:                        return;
                    359:                }
                    360:        }
                    361: }
                    362: 
                    363: 
                    364: /*
                    365: =================
                    366: CL_ParseTEnt
                    367: =================
                    368: */
                    369: static byte splash_color[] = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8};
                    370: 
                    371: void CL_ParseTEnt (void)
                    372: {
                    373:        int             type;
                    374:        vec3_t  pos, pos2, dir;
                    375:        explosion_t     *ex;
                    376:        int             cnt;
                    377:        int             color;
                    378:        int             r;
                    379:        int             ent;
                    380: 
                    381:        type = MSG_ReadByte (&net_message);
                    382: 
                    383:        switch (type)
                    384:        {
                    385:        case TE_BLOOD:                  // bullet hitting flesh
                    386:                MSG_ReadPos (&net_message, pos);
                    387:                MSG_ReadDir (&net_message, dir);
                    388:                CL_ParticleEffect (pos, dir, 0xe8, 60);
                    389:                break;
                    390: 
                    391:        case TE_GUNSHOT:                        // bullet hitting wall
                    392:        case TE_SPARKS:
                    393:        case TE_BULLET_SPARKS:
                    394:                MSG_ReadPos (&net_message, pos);
                    395:                MSG_ReadDir (&net_message, dir);
                    396:                if (type == TE_GUNSHOT)
                    397:                        CL_ParticleEffect (pos, dir, 0, 40);
                    398:                else
                    399:                        CL_ParticleEffect (pos, dir, 0xe0, 6);
                    400: 
                    401:                if (type != TE_SPARKS)
                    402:                {
                    403:                        CL_SmokeAndFlash(pos);
                    404: 
                    405:                        // impact sound
                    406:                        cnt = rand()&15;
                    407:                        if (cnt == 1)
                    408:                                S_StartSound (pos, 0, 0, cl_sfx_ric1, 1, ATTN_NORM, 0);
                    409:                        else if (cnt == 2)
                    410:                                S_StartSound (pos, 0, 0, cl_sfx_ric2, 1, ATTN_NORM, 0);
                    411:                        else if (cnt == 3)
                    412:                                S_StartSound (pos, 0, 0, cl_sfx_ric3, 1, ATTN_NORM, 0);
                    413:                }
                    414: 
                    415:                break;
                    416:                
                    417:        case TE_SCREEN_SPARKS:
                    418:        case TE_SHIELD_SPARKS:
                    419:                MSG_ReadPos (&net_message, pos);
                    420:                MSG_ReadDir (&net_message, dir);
                    421:                if (type == TE_SCREEN_SPARKS)
                    422:                        CL_ParticleEffect (pos, dir, 0xd0, 40);
                    423:                else
                    424:                        CL_ParticleEffect (pos, dir, 0xb0, 40);
                    425:                //FIXME : replace or remove this sound
                    426:                S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                    427:                break;
                    428:                
                    429:        case TE_SHOTGUN:                        // bullet hitting wall
                    430:                MSG_ReadPos (&net_message, pos);
                    431:                MSG_ReadDir (&net_message, dir);
                    432:                CL_ParticleEffect (pos, dir, 0, 20);
                    433:                CL_SmokeAndFlash(pos);
                    434:                break;
                    435: 
                    436:        case TE_SPLASH:                 // bullet hitting water
                    437:                cnt = MSG_ReadByte (&net_message);
                    438:                MSG_ReadPos (&net_message, pos);
                    439:                MSG_ReadDir (&net_message, dir);
                    440:                r = MSG_ReadByte (&net_message);
                    441:                if (r > 6)
                    442:                        color = 0x00;
                    443:                else
                    444:                        color = splash_color[r];
                    445:                CL_ParticleEffect (pos, dir, color, cnt);
                    446: 
                    447:                if (r == SPLASH_SPARKS)
                    448:                {
                    449:                        r = rand() & 3;
                    450:                        if (r == 0)
                    451:                                S_StartSound (pos, 0, 0, cl_sfx_spark5, 1, ATTN_STATIC, 0);
                    452:                        else if (r == 1)
                    453:                                S_StartSound (pos, 0, 0, cl_sfx_spark6, 1, ATTN_STATIC, 0);
                    454:                        else
                    455:                                S_StartSound (pos, 0, 0, cl_sfx_spark7, 1, ATTN_STATIC, 0);
                    456:                }
                    457:                break;
                    458: 
                    459:        case TE_LASER_SPARKS:
                    460:                cnt = MSG_ReadByte (&net_message);
                    461:                MSG_ReadPos (&net_message, pos);
                    462:                MSG_ReadDir (&net_message, dir);
                    463:                color = MSG_ReadByte (&net_message);
                    464:                CL_ParticleEffect2 (pos, dir, color, cnt);
                    465:                break;
                    466: 
                    467:        case TE_BLASTER:                        // blaster hitting wall
                    468:                MSG_ReadPos (&net_message, pos);
                    469:                MSG_ReadDir (&net_message, dir);
                    470:                CL_BlasterParticles (pos, dir);
                    471: 
                    472:                ex = CL_AllocExplosion ();
                    473:                VectorCopy (pos, ex->ent.origin);
                    474:                ex->ent.angles[0] = acos(dir[2])/M_PI*180;
                    475:                ex->ent.angles[2] = atan2(dir[1], dir[0])/M_PI*180;
                    476:                ex->type = ex_misc;
                    477:                ex->ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT;
                    478:                ex->start = cl.frame.servertime - 100;
                    479:                ex->light = 150;
                    480:                ex->lightcolor[0] = 1;
                    481:                ex->lightcolor[1] = 1;
                    482:                ex->ent.model = cl_mod_explode;
                    483:                ex->frames = 4;
                    484:                S_StartSound (pos,  0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
                    485:                break;
                    486:                
                    487:        case TE_RAILTRAIL:                      // railgun effect
                    488:                MSG_ReadPos (&net_message, pos);
                    489:                MSG_ReadPos (&net_message, pos2);
                    490:                CL_RailTrail (pos, pos2);
                    491:                S_StartSound (pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0);
                    492:                break;
                    493: 
                    494:        case TE_PLASMATRAIL:
                    495:                MSG_ReadPos (&net_message, pos);
                    496:                MSG_ReadPos (&net_message, pos2);
                    497:                CL_PlasmaTrail (pos, pos2);
                    498:                S_StartSound (pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0);
                    499:                break;
                    500: 
                    501:        case TE_EXPLOSION2:
                    502:        case TE_GRENADE_EXPLOSION:
                    503:        case TE_GRENADE_EXPLOSION_WATER:
                    504:                MSG_ReadPos (&net_message, pos);
                    505: 
                    506:                ex = CL_AllocExplosion ();
                    507:                VectorCopy (pos, ex->ent.origin);
                    508:                ex->type = ex_poly;
                    509:                ex->ent.flags = RF_FULLBRIGHT;
                    510:                ex->start = cl.frame.servertime - 100;
                    511:                ex->light = 350;
                    512:                ex->lightcolor[0] = 1.0;
                    513:                ex->lightcolor[1] = 0.5;
                    514:                ex->lightcolor[2] = 0.5;
                    515:                ex->ent.model = cl_mod_explo4;
                    516:                ex->frames = 19;
                    517:                ex->baseframe = 30;
                    518:                ex->ent.angles[1] = rand() % 360;
                    519:                CL_ExplosionParticles (pos);
                    520:                if (type == TE_GRENADE_EXPLOSION_WATER)
                    521:                        S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0);
                    522:                else
                    523:                        S_StartSound (pos, 0, 0, cl_sfx_grenexp, 1, ATTN_NORM, 0);
                    524:                break;
                    525: 
                    526:        case TE_EXPLOSION1:
                    527:        case TE_ROCKET_EXPLOSION:
                    528:        case TE_ROCKET_EXPLOSION_WATER:
                    529:                MSG_ReadPos (&net_message, pos);
                    530: 
                    531:                ex = CL_AllocExplosion ();
                    532:                VectorCopy (pos, ex->ent.origin);
                    533:                ex->type = ex_poly;
                    534:                ex->ent.flags = RF_FULLBRIGHT;
                    535:                ex->start = cl.frame.servertime - 100;
                    536:                ex->light = 350;
                    537:                ex->lightcolor[0] = 1.0;
                    538:                ex->lightcolor[1] = 0.5;
                    539:                ex->lightcolor[2] = 0.5;
                    540:                ex->ent.angles[1] = rand() % 360;
                    541:                ex->ent.model = cl_mod_explo4;
                    542:                if (frand() < 0.5)
                    543:                        ex->baseframe = 15;
                    544:                ex->frames = 15;
                    545:                CL_ExplosionParticles (pos);
                    546:                if (type == TE_ROCKET_EXPLOSION_WATER)
                    547:                        S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0);
                    548:                else
                    549:                        S_StartSound (pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0);
                    550:                break;
                    551: 
                    552:        case TE_BFG_EXPLOSION:
                    553:                MSG_ReadPos (&net_message, pos);
                    554:                ex = CL_AllocExplosion ();
                    555:                VectorCopy (pos, ex->ent.origin);
                    556:                ex->type = ex_poly;
                    557:                ex->ent.flags = RF_FULLBRIGHT;
                    558:                ex->start = cl.frame.servertime - 100;
                    559:                ex->light = 350;
                    560:                ex->lightcolor[0] = 0.0;
                    561:                ex->lightcolor[1] = 1.0;
                    562:                ex->lightcolor[2] = 0.0;
                    563:                ex->ent.model = cl_mod_bfg_explo;
                    564:                ex->ent.flags |= RF_TRANSLUCENT;
                    565:                ex->ent.alpha = 0.30;
                    566:                ex->frames = 4;
                    567:                break;
                    568: 
                    569:        case TE_BFG_BIGEXPLOSION:
                    570:                MSG_ReadPos (&net_message, pos);
                    571:                CL_BFGExplosionParticles (pos);
                    572:                break;
                    573: 
                    574:        case TE_BFG_LASER:
                    575:                CL_ParseLaser (0xd0d1d2d3);
                    576:                break;
                    577: 
                    578:        case TE_BUBBLETRAIL:
                    579:                MSG_ReadPos (&net_message, pos);
                    580:                MSG_ReadPos (&net_message, pos2);
                    581:                CL_BubbleTrail (pos, pos2);
                    582:                break;
                    583: 
                    584:        case TE_PARASITE_ATTACK:
                    585:        case TE_MEDIC_CABLE_ATTACK:
                    586:                ent = CL_ParseBeam (cl_mod_parasite_segment);
                    587:                break;
                    588: 
                    589:        case TE_BOSSTPORT:                      // boss teleporting to station
                    590:                MSG_ReadPos (&net_message, pos);
                    591:                CL_BigTeleportParticles (pos);
                    592:                S_StartSound (pos, 0, 0, S_RegisterSound ("misc/bigtele.wav"), 1, ATTN_NONE, 0);
                    593:                break;
                    594: 
                    595:        case TE_GRAPPLE_CABLE:
                    596:                ent = CL_ParseBeam2 (cl_mod_grapple_cable);
                    597:                break;
                    598: 
                    599:        case TE_WELDING_SPARKS:
                    600:                cnt = MSG_ReadByte (&net_message);
                    601:                MSG_ReadPos (&net_message, pos);
                    602:                MSG_ReadDir (&net_message, dir);
                    603:                color = MSG_ReadByte (&net_message);
                    604:                CL_ParticleEffect2 (pos, dir, color, cnt);
                    605: 
                    606:                ex = CL_AllocExplosion ();
                    607:                VectorCopy (pos, ex->ent.origin);
                    608:                ex->type = ex_flash;
                    609:                // note to self
                    610:                // we need a better no draw flag
                    611:                ex->ent.flags = RF_BEAM;
                    612:                ex->start = cl.frame.servertime - 0.1;
                    613:                ex->light = 100 + (rand()%75);
                    614:                ex->lightcolor[0] = 1.0;
                    615:                ex->lightcolor[1] = 1.0;
                    616:                ex->lightcolor[2] = 0.3;
                    617:                ex->ent.model = cl_mod_flash;
                    618:                ex->frames = 2;
                    619:                break;
                    620: 
                    621:        case TE_GREENBLOOD:
                    622:                MSG_ReadPos (&net_message, pos);
                    623:                MSG_ReadDir (&net_message, dir);
                    624:                CL_ParticleEffect2 (pos, dir, 0xc0, 30);
                    625:                break;
                    626:        
                    627:        default:
                    628:                Com_Error (ERR_DROP, "CL_ParseTEnt: bad type");
                    629:        }
                    630: }
                    631: 
                    632: /*
                    633: =================
                    634: CL_AddBeams
                    635: =================
                    636: */
                    637: void CL_AddBeams (void)
                    638: {
                    639:        int                     i,j;
                    640:        beam_t          *b;
                    641:        vec3_t          dist, org;
                    642:        float           d;
                    643:        entity_t        ent;
                    644:        float           yaw, pitch;
                    645:        float           forward;
                    646: 
                    647: // update beams
                    648:        for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
                    649:        {
                    650:                if (!b->model || b->endtime < cl.time)
                    651:                        continue;
                    652: 
                    653:        // if coming from the player, update the start position
                    654:                if (b->entity == cl.playernum+1)        // entity 0 is the world
                    655:                {
                    656:                        VectorCopy (cl.refdef.vieworg, b->start);
                    657:                        b->start[2] -= 22;      // adjust for view height
                    658:                }
                    659: 
                    660:                VectorAdd (b->start, b->offset, org);
                    661: 
                    662:        // calculate pitch and yaw
                    663:                VectorSubtract (b->end, org, dist);
                    664: 
                    665:                if (dist[1] == 0 && dist[0] == 0)
                    666:                {
                    667:                        yaw = 0;
                    668:                        if (dist[2] > 0)
                    669:                                pitch = 90;
                    670:                        else
                    671:                                pitch = 270;
                    672:                }
                    673:                else
                    674:                {
                    675:                        yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI);
                    676:                        if (yaw < 0)
                    677:                                yaw += 360;
                    678:        
                    679:                        forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
                    680:                        pitch = (int) (atan2(dist[2], forward) * -180 / M_PI);
                    681:                        if (pitch < 0)
                    682:                                pitch += 360;
                    683:                }
                    684: 
                    685:        // add new entities for the beams
                    686:                d = VectorNormalize(dist);
                    687:                memset (&ent, 0, sizeof(ent));
                    688:                while (d > 0)
                    689:                {
                    690:                        VectorCopy (org, ent.origin);
                    691:                        ent.model = b->model;
                    692:                        ent.angles[0] = pitch;
                    693:                        ent.angles[1] = yaw;
                    694:                        ent.angles[2] = rand()%360;
                    695: 
                    696:                        V_AddEntity (&ent);
                    697: 
                    698:                        for (j=0 ; j<3 ; j++)
                    699:                                org[j] += dist[j]*30;
                    700:                        d -= 30;
                    701:                }
                    702:        }
                    703:        
                    704: }
                    705: 
                    706: /*
                    707: =================
                    708: CL_AddExplosions
                    709: =================
                    710: */
                    711: void CL_AddExplosions (void)
                    712: {
                    713:        entity_t        *ent;
                    714:        int                     i;
                    715:        explosion_t     *ex;
                    716:        float           frac;
                    717:        int                     f;
                    718: 
                    719:        memset (&ent, 0, sizeof(ent));
                    720: 
                    721:        for (i=0, ex=cl_explosions ; i< MAX_EXPLOSIONS ; i++, ex++)
                    722:        {
                    723:                if (ex->type == ex_free)
                    724:                        continue;
                    725:                frac = (cl.time - ex->start)/100.0;
                    726:                f = floor(frac);
                    727: 
                    728:                ent = &ex->ent;
                    729: 
                    730:                switch (ex->type)
                    731:                {
                    732:                case ex_mflash:
                    733:                        if (f >= ex->frames-1)
                    734:                                ex->type = ex_free;
                    735:                        break;
                    736:                case ex_misc:
                    737:                        if (f >= ex->frames-1)
                    738:                        {
                    739:                                ex->type = ex_free;
                    740:                                break;
                    741:                        }
                    742:                        ent->alpha = 1.0 - frac/(ex->frames-1);
                    743:                        break;
                    744:                case ex_flash:
                    745:                        if (f >= 1)
                    746:                        {
                    747:                                ex->type = ex_free;
                    748:                                break;
                    749:                        }
                    750:                        ent->alpha = 1.0;
                    751:                        break;
                    752:                case ex_poly:
                    753:                        if (f >= ex->frames-1)
                    754:                        {
                    755:                                ex->type = ex_free;
                    756:                                break;
                    757:                        }
                    758: 
                    759:                        ent->alpha = (16.0 - (float)f)/16.0;
                    760: 
                    761:                        if (f < 10)
                    762:                        {
                    763:                                ent->skinnum = (f>>1);
                    764:                                if (ent->skinnum < 0)
                    765:                                        ent->skinnum = 0;
                    766:                        }
                    767:                        else
                    768:                        {
                    769:                                ent->flags |= RF_TRANSLUCENT;
                    770:                                if (f < 13)
                    771:                                        ent->skinnum = 5;
                    772:                                else
                    773:                                        ent->skinnum = 6;
                    774:                        }
                    775:                        break;
                    776:                }
                    777: 
                    778:                if (ex->type == ex_free)
                    779:                        continue;
                    780:                if (ex->light)
                    781:                {
                    782:                        V_AddLight (ent->origin, ex->light*ent->alpha,
                    783:                                ex->lightcolor[0], ex->lightcolor[1], ex->lightcolor[2]);
                    784:                }
                    785: 
                    786:                VectorCopy (ent->origin, ent->oldorigin);
                    787: 
                    788:                if (f < 0)
                    789:                        f = 0;
                    790:                ent->frame = ex->baseframe + f + 1;
                    791:                ent->oldframe = ex->baseframe + f;
                    792:                ent->backlerp = 1.0 - cl.lerpfrac;
                    793: 
                    794:                V_AddEntity (ent);
                    795:        }
                    796: }
                    797: 
                    798: 
                    799: /*
                    800: =================
                    801: CL_AddLasers
                    802: =================
                    803: */
                    804: void CL_AddLasers (void)
                    805: {
                    806:        laser_t         *l;
                    807:        int                     i;
                    808: 
                    809:        for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
                    810:        {
                    811:                if (l->endtime >= cl.time)
                    812:                        V_AddEntity (&l->ent);
                    813:        }
                    814: }
                    815: 
                    816: 
                    817: /*
                    818: =================
                    819: CL_AddTEnts
                    820: =================
                    821: */
                    822: void CL_AddTEnts (void)
                    823: {
                    824:        CL_AddBeams ();
                    825:        CL_AddExplosions ();
                    826:        CL_AddLasers ();
                    827: }

unix.superglobalmegacorp.com

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