home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / relwep13 / cbnmods.qc next >
Encoding:
Text File  |  1996-08-22  |  9.7 KB  |  289 lines

  1. /*-------------------------------------------------------------------
  2. Filename : cbnmods.qc
  3. Author   : Cameron Newham
  4. Version  : 1.4
  5. Date     : 96/08/22
  6.  
  7. Description
  8. -----------
  9. Provides routines specific to my patches.  See the description
  10. file that came with the archive for further details.
  11.  
  12. Public Entry Points
  13. -------------------
  14. CN_Missile_Bubbles
  15. CN_Missile_Think
  16. CN_Ditch_Rockets
  17. CN_Client_Init_Think
  18. CN_NG_Jammed
  19. CN_SNG_Jammed
  20. --------------------------------------------------------------------*/
  21.  
  22. void() bubble_bob;
  23. void() GrenadeExplode; //Needed for CN_Missile_Think
  24. void(float num_bubbles) DeathBubbles;
  25.  
  26. /*-------------------------------------------------------------------
  27. Slightly modified version of Id's DeathBubblesSpawn
  28. --------------------------------------------------------------------*/
  29. void() MissileBubblesSpawn =
  30. {
  31. local entity    bubble;
  32.         bubble = spawn();
  33.         setmodel (bubble, "progs/s_bubble.spr");
  34.         setorigin (bubble, self.owner.origin);
  35.         bubble.movetype = MOVETYPE_NOCLIP;
  36.         bubble.solid = SOLID_NOT;
  37.         bubble.velocity = '0 0 15';
  38.         bubble.nextthink = time + 0.5;
  39.         bubble.think = bubble_bob;
  40.         bubble.classname = "bubble";
  41.         bubble.frame = 0;
  42.         bubble.cnt = 0;
  43.         setsize (bubble, '-8 -8 -8', '8 8 8');
  44.         self.nextthink = time + 0.1;
  45.         self.think = MissileBubblesSpawn;
  46.         self.air_finished = self.air_finished + 1;
  47.         if (self.air_finished >= self.bubble_count)
  48.                 remove(self);
  49. };
  50.  
  51. /*---------------------CN_Missile_Bubbles----------------------------
  52. Makes an underwater entity look like a real underwater entity by
  53. spraying out bubbles.  This is designed for use with rockets.
  54. --------------------------------------------------------------------*/
  55. void(float num_bubbles) CN_Missile_Bubbles =
  56. {
  57.   local vector  rocket_origin;
  58.   local entity  bubble_spawner;
  59.         
  60.         //rocket_origin = self.origin + ('0 -50 -50');
  61.         bubble_spawner = spawn();
  62.         setorigin (bubble_spawner, self.origin + '0 0 -60');
  63.         bubble_spawner.movetype = MOVETYPE_NONE;
  64.         bubble_spawner.solid = SOLID_NOT;
  65.         bubble_spawner.nextthink = time + 0.1;
  66.         bubble_spawner.think = MissileBubblesSpawn;
  67.         bubble_spawner.air_finished = 0;
  68.         bubble_spawner.owner = self;
  69.         bubble_spawner.bubble_count = num_bubbles;
  70.         return;
  71. };
  72.  
  73.  
  74. /*----------------------CN_Missile_Think-----------------------------
  75. Missile Velocity Correction.
  76. Correct the velocity of spikes, rockets and grenades underwater.  
  77. Simulates water resistance.  Also calls CN_Missile_Bubbles for rockets
  78. underwater.  Rockets are slowed in water and speed up again in air,
  79. while grenades are slowed by each passage through water.
  80. --------------------------------------------------------------------*/
  81. void() CN_Missile_Think =
  82. {
  83.   local vector v1;
  84.   local vector v2;
  85.  
  86.   // if it's a grenade then we must make it explode after
  87.   // it's duration expires
  88.  
  89.   if ((self.classname == "grenade") && (time > self.duration))
  90.   {
  91.     // this is a grenade and it's past its use-by date
  92.     self.think = GrenadeExplode;
  93.     self.nextthink = time + 0.1;
  94.   }
  95.   else
  96.   if (self.duration < time)
  97.     self.think = SUB_Remove;
  98.   else
  99.   {
  100.     self.nextthink = time + 0.1;
  101.  
  102.     v1 = self.origin;
  103.     v2 = v1;
  104.     traceline (v1, v2, TRUE, self);
  105.  
  106.     if (trace_inwater == TRUE) 
  107.     {
  108.       if ((random() > 0.72) && (self.classname == "rocket"))
  109.         CN_Missile_Bubbles(1);
  110.  
  111.       if (self.jump_flag == FALSE)
  112.       {
  113.         // correct velocity underwater if not underwater
  114.         // (jump_flag) already.
  115.         self.jump_flag = TRUE;  // now in water
  116.         self.swim_flag = TRUE;  // water->air transition not done
  117.         self.velocity = self.velocity * 0.4292;
  118.         self.angles = vectoangles(self.velocity);
  119.       }
  120.     }
  121.     else
  122.     {
  123.       // make sure we only do this for 1 water/surf transition
  124.       if (self.swim_flag == TRUE) 
  125.       {
  126.         if (self.classname == "rocket")
  127.         {
  128.           // correct velocity out of water for rockets
  129.           self.velocity = self.velocity * 2.33;
  130.         }
  131.         self.jump_flag = FALSE;  //out of water
  132.         self.swim_flag = FALSE;  //water->air transition finished
  133.       }
  134.     }
  135.   }
  136.   
  137. };
  138.  
  139. /*------------------------CN_Ditch_Rockets---------------------------
  140. Removes half your rockets, places them in a backpack and ejects
  141. it to the world.  You'll need this for when you get too many rockets
  142. and get weighed down.
  143. --------------------------------------------------------------------*/
  144. void() CN_Ditch_Rockets =
  145. {
  146.         local entity back_pack;
  147.         local float  num_to_ditch;  
  148.  
  149.         // if we have none or one then return!
  150.         if (self.ammo_rockets < 2)
  151.           return;
  152.  
  153.         // spawn a backpack
  154.         back_pack = spawn();
  155.  
  156.         // calculate number to ditch and set appropriate amounts
  157.         // for entity and backpack
  158.         num_to_ditch = self.ammo_rockets / 2;
  159.         num_to_ditch = floor(num_to_ditch);
  160.         back_pack.ammo_rockets = num_to_ditch;
  161.         self.ammo_rockets = self.ammo_rockets - num_to_ditch;
  162.  
  163.  
  164.         back_pack.owner = self;
  165.         makevectors(self.v_angle);
  166.         setorigin(back_pack, self.origin + '0 0 45');
  167.         back_pack.velocity = aim(self, 1000);
  168.         back_pack.velocity_x = back_pack.velocity_x * -340;
  169.         back_pack.velocity_y = back_pack.velocity_y * -340;
  170.         back_pack.velocity_z = back_pack.velocity_z * 380;
  171.         back_pack.angles = vectoangles(back_pack.velocity);
  172.         back_pack.flags = FL_ITEM;
  173.         back_pack.solid = SOLID_TRIGGER;
  174.         back_pack.movetype = MOVETYPE_TOSS;
  175.         back_pack.nextthink = time + 0.2;
  176.  
  177.         setmodel (back_pack, "progs/backpack.mdl");
  178.         setsize(back_pack, '-16 -16 0', '16 16 56');
  179.         back_pack.touch = BackpackTouch;
  180.         back_pack.nextthink = time + 120;    // remove pack after 120 secs
  181.         back_pack.think = SUB_Remove;
  182.  
  183.         sprint(self, "Dumped Rockets\n");
  184.  
  185.         W_SetCurrentAmmo();
  186. };
  187.  
  188. /*--------------------CN_Client_Init_Think---------------------------
  189. Startup messages
  190. --------------------------------------------------------------------*/
  191. void() CN_Client_Init_Think =
  192. {
  193.   sprint (self, "Realistic Weapons Version 1.3\n");
  194.   sprint (self, "by C. Newham (w_australia)\n");
  195.   sprint (self, "* Type 'help-rw' for help\n");
  196.   sprint (self, "* Type 'features-rw' for mod features\n");
  197.  
  198.   stuffcmd (self, "alias features-rw \"impulse 183\"\n");
  199.   stuffcmd (self, "alias dumpr \"impulse 182\"\n");
  200.   stuffcmd (self, "alias last \"impulse 181\"\n");
  201.   stuffcmd (self, "alias help-rw \"impulse 180\"\n");
  202. };
  203.  
  204. /*-------------------------CN_NG_Jammed-----------------------------
  205. See if Nailgun is jammed and possibly unjam it.
  206. --------------------------------------------------------------------*/
  207. void() CN_NG_Jammed =
  208. {
  209.           if ((self.use_counter_ng > 20) ||
  210.               ((time - self.use_last_ng) > 2.5))
  211.           {
  212.             //re-init for next sample quanta
  213.             //also do it if > 2.5 secs since last fire because of
  214.             //buggy algorithm i've used for unjamming
  215.             self.use_counter_ng = 0.0;
  216.             self.use_av_ng = 0.0;
  217.             self.use_last_ng = time;
  218.             self.jammed_ng = 0;
  219.           } else 
  220.           {
  221.             // get average firing rate
  222.             self.use_counter_ng = self.use_counter_ng + 1.0;
  223.             self.use_av_ng = (self.use_av_ng + (time - self.use_last_ng))/2.0;
  224.             self.use_last_ng = time;
  225.           }
  226.  
  227.           //look at whether to jam weapon or not
  228.           if ((self.use_counter_ng > 3.0) && (self.jammed_ng < 1.0))
  229.           {
  230.             //firing more than 3 - start testing over-use
  231.             if ((self.use_av_ng < 0.22) && (random() > 0.9675))
  232.             {
  233.               self.jammed_ng = 1.0;
  234.             }
  235.           } else
  236.           {
  237.             //look at unjaming the weapon
  238.             if ((self.use_av_ng > 2.2) && (self.use_counter_ng > 10.0)) {
  239.               self.jammed_ng = 0.0;
  240.               sprint (self, "Unjammed the Nailgun!\n");
  241.             }
  242.           }
  243. };      
  244.  
  245. /*-------------------------CN_SNG_Jammed----------------------------
  246. See if Super-Nailgun is jammed and possibly unjam it.
  247. --------------------------------------------------------------------*/
  248. void() CN_SNG_Jammed =
  249. {
  250.   local float delta_use;
  251.  
  252.  
  253.           delta_use = time - self.use_last_sng;
  254.           if ((self.use_counter_sng > 20) ||
  255.               ( delta_use > 2.5))
  256.           {
  257.             //re-init for next sample quanta
  258.             //also do it if > 2.5 secs since last fire because of
  259.             //buggy algorithm i've used for unjamming
  260.             self.use_counter_sng = 0.0;
  261.             self.use_av_sng = 0.0;
  262.             self.use_last_sng = time;
  263.             self.jammed_sng = 0;
  264.           } else 
  265.           {
  266.             // get average firing rate
  267.             self.use_counter_sng = self.use_counter_sng + 1.0;
  268.             self.use_av_sng = (self.use_av_sng + (time - self.use_last_sng))/2.0;
  269.             self.use_last_sng = time;
  270.           }
  271.  
  272.           //look at whether to jam weapon or not
  273.           if ((self.use_counter_sng > 3.0) && (self.jammed_sng < 1.0))
  274.           {
  275.             //firing more than 3 - start testing over-use
  276.             if ((self.use_av_sng < 0.22) && (random() > 0.945))
  277.             {
  278.               self.jammed_sng = 1.0;
  279.             }
  280.           } else
  281.           {
  282.             //look at unjaming the weapon
  283.             if ((self.use_av_sng > 2.2) && (self.use_counter_sng > 10.0)) {
  284.               self.jammed_sng = 0.0;
  285.               sprint (self, "Unjammed the Perforator!\n");
  286.             }
  287.           }
  288. };
  289.