home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / cl_tent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-28  |  9.3 KB  |  395 lines

  1. /*
  2. Copyright (C) 1996-1997 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. */
  20. // cl_tent.c -- client side temporary entities
  21.  
  22. #include "quakedef.h"
  23.  
  24. int     num_temp_entities;
  25. entity_t  cl_temp_entities[MAX_TEMP_ENTITIES];
  26. beam_t    cl_beams[MAX_BEAMS];
  27.  
  28. sfx_t     *cl_sfx_wizhit;
  29. sfx_t     *cl_sfx_knighthit;
  30. sfx_t     *cl_sfx_tink1;
  31. sfx_t     *cl_sfx_ric1;
  32. sfx_t     *cl_sfx_ric2;
  33. sfx_t     *cl_sfx_ric3;
  34. sfx_t     *cl_sfx_r_exp3;
  35. #ifdef QUAKE2
  36. sfx_t     *cl_sfx_imp;
  37. sfx_t     *cl_sfx_rail;
  38. #endif
  39.  
  40. /*
  41. =================
  42. CL_ParseTEnt
  43. =================
  44. */
  45. void CL_InitTEnts (void)
  46. {
  47.   cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav");
  48.   cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav");
  49.   cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav");
  50.   cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav");
  51.   cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav");
  52.   cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav");
  53.   cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav");
  54. #ifdef QUAKE2
  55.   cl_sfx_imp = S_PrecacheSound ("shambler/sattck1.wav");
  56.   cl_sfx_rail = S_PrecacheSound ("weapons/lstart.wav");
  57. #endif
  58. }
  59.  
  60. /*
  61. =================
  62. CL_ParseBeam
  63. =================
  64. */
  65. void CL_ParseBeam (model_t *m)
  66. {
  67.   int   ent;
  68.   vec3_t  start, end;
  69.   beam_t  *b;
  70.   int   i;
  71.   
  72.   ent = MSG_ReadShort ();
  73.   
  74.   start[0] = MSG_ReadCoord ();
  75.   start[1] = MSG_ReadCoord ();
  76.   start[2] = MSG_ReadCoord ();
  77.   
  78.   end[0] = MSG_ReadCoord ();
  79.   end[1] = MSG_ReadCoord ();
  80.   end[2] = MSG_ReadCoord ();
  81.  
  82. // override any beam with the same entity
  83.   for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
  84.     if (b->entity == ent)
  85.     {
  86.       b->entity = ent;
  87.       b->model = m;
  88.       b->endtime = cl.time + 0.2;
  89.       VectorCopy (start, b->start);
  90.       VectorCopy (end, b->end);
  91.       return;
  92.     }
  93.  
  94. // find a free beam
  95.   for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
  96.   {
  97.     if (!b->model || b->endtime < cl.time)
  98.     {
  99.       b->entity = ent;
  100.       b->model = m;
  101.       b->endtime = cl.time + 0.2;
  102.       VectorCopy (start, b->start);
  103.       VectorCopy (end, b->end);
  104.       return;
  105.     }
  106.   }
  107.   Con_Printf ("beam list overflow!\n"); 
  108. }
  109.  
  110. /*
  111. =================
  112. CL_ParseTEnt
  113. =================
  114. */
  115. void CL_ParseTEnt (void)
  116. {
  117.   int   type;
  118.   vec3_t  pos;
  119. #ifdef QUAKE2
  120.   vec3_t  endpos;
  121. #endif
  122.   dlight_t  *dl;
  123.   int   rnd;
  124.   int   colorStart, colorLength;
  125.  
  126.   type = MSG_ReadByte ();
  127.   switch (type)
  128.   {
  129.   case TE_WIZSPIKE:     // spike hitting wall
  130.     pos[0] = MSG_ReadCoord ();
  131.     pos[1] = MSG_ReadCoord ();
  132.     pos[2] = MSG_ReadCoord ();
  133.     R_RunParticleEffect (pos, vec3_origin, 20, 30);
  134.     S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
  135.     break;
  136.     
  137.   case TE_KNIGHTSPIKE:      // spike hitting wall
  138.     pos[0] = MSG_ReadCoord ();
  139.     pos[1] = MSG_ReadCoord ();
  140.     pos[2] = MSG_ReadCoord ();
  141.     R_RunParticleEffect (pos, vec3_origin, 226, 20);
  142.     S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
  143.     break;
  144.     
  145.   case TE_SPIKE:      // spike hitting wall
  146.     pos[0] = MSG_ReadCoord ();
  147.     pos[1] = MSG_ReadCoord ();
  148.     pos[2] = MSG_ReadCoord ();
  149. #ifdef GLTEST
  150.     Test_Spawn (pos);
  151. #else
  152.     R_RunParticleEffect (pos, vec3_origin, 0, 10);
  153. #endif
  154.     if ( rand() % 5 )
  155.       S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
  156.     else
  157.     {
  158.       rnd = rand() & 3;
  159.       if (rnd == 1)
  160.         S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
  161.       else if (rnd == 2)
  162.         S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
  163.       else
  164.         S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
  165.     }
  166.     break;
  167.   case TE_SUPERSPIKE:     // super spike hitting wall
  168.     pos[0] = MSG_ReadCoord ();
  169.     pos[1] = MSG_ReadCoord ();
  170.     pos[2] = MSG_ReadCoord ();
  171.     R_RunParticleEffect (pos, vec3_origin, 0, 20);
  172.  
  173.     if ( rand() % 5 )
  174.       S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
  175.     else
  176.     {
  177.       rnd = rand() & 3;
  178.       if (rnd == 1)
  179.         S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
  180.       else if (rnd == 2)
  181.         S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
  182.       else
  183.         S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
  184.     }
  185.     break;
  186.     
  187.   case TE_GUNSHOT:      // bullet hitting wall
  188.     pos[0] = MSG_ReadCoord ();
  189.     pos[1] = MSG_ReadCoord ();
  190.     pos[2] = MSG_ReadCoord ();
  191.     R_RunParticleEffect (pos, vec3_origin, 0, 20);
  192.     break;
  193.     
  194.   case TE_EXPLOSION:      // rocket explosion
  195.     pos[0] = MSG_ReadCoord ();
  196.     pos[1] = MSG_ReadCoord ();
  197.     pos[2] = MSG_ReadCoord ();
  198.     R_ParticleExplosion (pos);
  199.     dl = CL_AllocDlight (0);
  200.     VectorCopy (pos, dl->origin);
  201.     dl->radius = 350;
  202.     dl->die = cl.time + 0.5;
  203.     dl->decay = 300;
  204.     S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
  205.     break;
  206.     
  207.   case TE_TAREXPLOSION:     // tarbaby explosion
  208.     pos[0] = MSG_ReadCoord ();
  209.     pos[1] = MSG_ReadCoord ();
  210.     pos[2] = MSG_ReadCoord ();
  211.     R_BlobExplosion (pos);
  212.  
  213.     S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
  214.     break;
  215.  
  216.   case TE_LIGHTNING1:       // lightning bolts
  217.     CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true));
  218.     break;
  219.   
  220.   case TE_LIGHTNING2:       // lightning bolts
  221.     CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true));
  222.     break;
  223.   
  224.   case TE_LIGHTNING3:       // lightning bolts
  225.     CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true));
  226.     break;
  227.   
  228. // PGM 01/21/97 
  229.   case TE_BEAM:       // grappling hook beam
  230.     CL_ParseBeam (Mod_ForName("progs/beam.mdl", true));
  231.     break;
  232. // PGM 01/21/97
  233.  
  234.   case TE_LAVASPLASH: 
  235.     pos[0] = MSG_ReadCoord ();
  236.     pos[1] = MSG_ReadCoord ();
  237.     pos[2] = MSG_ReadCoord ();
  238.     R_LavaSplash (pos);
  239.     break;
  240.   
  241.   case TE_TELEPORT:
  242.     pos[0] = MSG_ReadCoord ();
  243.     pos[1] = MSG_ReadCoord ();
  244.     pos[2] = MSG_ReadCoord ();
  245.     R_TeleportSplash (pos);
  246.     break;
  247.     
  248.   case TE_EXPLOSION2:       // color mapped explosion
  249.     pos[0] = MSG_ReadCoord ();
  250.     pos[1] = MSG_ReadCoord ();
  251.     pos[2] = MSG_ReadCoord ();
  252.     colorStart = MSG_ReadByte ();
  253.     colorLength = MSG_ReadByte ();
  254.     R_ParticleExplosion2 (pos, colorStart, colorLength);
  255.     dl = CL_AllocDlight (0);
  256.     VectorCopy (pos, dl->origin);
  257.     dl->radius = 350;
  258.     dl->die = cl.time + 0.5;
  259.     dl->decay = 300;
  260.     S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
  261.     break;
  262.     
  263. #ifdef QUAKE2
  264.   case TE_IMPLOSION:
  265.     pos[0] = MSG_ReadCoord ();
  266.     pos[1] = MSG_ReadCoord ();
  267.     pos[2] = MSG_ReadCoord ();
  268.     S_StartSound (-1, 0, cl_sfx_imp, pos, 1, 1);
  269.     break;
  270.  
  271.   case TE_RAILTRAIL:
  272.     pos[0] = MSG_ReadCoord ();
  273.     pos[1] = MSG_ReadCoord ();
  274.     pos[2] = MSG_ReadCoord ();
  275.     endpos[0] = MSG_ReadCoord ();
  276.     endpos[1] = MSG_ReadCoord ();
  277.     endpos[2] = MSG_ReadCoord ();
  278.     S_StartSound (-1, 0, cl_sfx_rail, pos, 1, 1);
  279.     S_StartSound (-1, 1, cl_sfx_r_exp3, endpos, 1, 1);
  280.     R_RocketTrail (pos, endpos, 0+128);
  281.     R_ParticleExplosion (endpos);
  282.     dl = CL_AllocDlight (-1);
  283.     VectorCopy (endpos, dl->origin);
  284.     dl->radius = 350;
  285.     dl->die = cl.time + 0.5;
  286.     dl->decay = 300;
  287.     break;
  288. #endif
  289.  
  290.   default:
  291.     Sys_Error ("CL_ParseTEnt: bad type");
  292.   }
  293. }
  294.  
  295.  
  296. /*
  297. =================
  298. CL_NewTempEntity
  299. =================
  300. */
  301. entity_t *CL_NewTempEntity (void)
  302. {
  303.   entity_t  *ent;
  304.  
  305.   if (cl_numvisedicts == MAX_VISEDICTS)
  306.     return NULL;
  307.   if (num_temp_entities == MAX_TEMP_ENTITIES)
  308.     return NULL;
  309.   ent = &cl_temp_entities[num_temp_entities];
  310.   memset (ent, 0, sizeof(*ent));
  311.   num_temp_entities++;
  312.   cl_visedicts[cl_numvisedicts] = ent;
  313.   cl_numvisedicts++;
  314.  
  315.   ent->colormap = vid.colormap;
  316.   return ent;
  317. }
  318.  
  319.  
  320. /*
  321. =================
  322. CL_UpdateTEnts
  323. =================
  324. */
  325. void CL_UpdateTEnts (void)
  326. {
  327.   int     i;
  328.   beam_t    *b;
  329.   vec3_t    dist, org;
  330.   float   d;
  331.   entity_t  *ent;
  332.   float   yaw, pitch;
  333.   float   forward;
  334.  
  335.   num_temp_entities = 0;
  336.  
  337. // update lightning
  338.   for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
  339.   {
  340.     if (!b->model || b->endtime < cl.time)
  341.       continue;
  342.  
  343.   // if coming from the player, update the start position
  344.     if (b->entity == cl.viewentity)
  345.     {
  346.       VectorCopy (cl_entities[cl.viewentity].origin, b->start);
  347.     }
  348.  
  349.   // calculate pitch and yaw
  350.     VectorSubtract (b->end, b->start, dist);
  351.  
  352.     if (dist[1] == 0 && dist[0] == 0)
  353.     {
  354.       yaw = 0;
  355.       if (dist[2] > 0)
  356.         pitch = 90;
  357.       else
  358.         pitch = 270;
  359.     }
  360.     else
  361.     {
  362.       yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI);
  363.       if (yaw < 0)
  364.         yaw += 360;
  365.   
  366.       forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
  367.       pitch = (int) (atan2(dist[2], forward) * 180 / M_PI);
  368.       if (pitch < 0)
  369.         pitch += 360;
  370.     }
  371.  
  372.   // add new entities for the lightning
  373.     VectorCopy (b->start, org);
  374.     d = VectorNormalize(dist);
  375.     while (d > 0)
  376.     {
  377.       ent = CL_NewTempEntity ();
  378.       if (!ent)
  379.         return;
  380.       VectorCopy (org, ent->origin);
  381.       ent->model = b->model;
  382.       ent->angles[0] = pitch;
  383.       ent->angles[1] = yaw;
  384.       ent->angles[2] = rand()%360;
  385.  
  386.       for (i=0 ; i<3 ; i++)
  387.         org[i] += dist[i]*30;
  388.       d -= 30;
  389.     }
  390.   }
  391.   
  392. }
  393.  
  394.  
  395.