home *** CD-ROM | disk | FTP | other *** search
/ Qu-ake / Qu-ake.iso / qu_ke / patches / 004 / HOOK.QC < prev    next >
Encoding:
Text File  |  1996-10-24  |  7.3 KB  |  252 lines

  1. //====================================================================
  2. //
  3. // GRAPPLING HOOK            by: Perecli Manole AKA Bort
  4. //
  5. //====================================================================
  6. // Aside from this new file, the following are the modifications
  7. // done to id's original source files:
  8. //--------------------------------------------------------------------
  9. // File: Progs.src
  10. // Location: before the "weapons.qc" line
  11. // Added: hook.qc
  12. //--------------------------------------------------------------------
  13. // File: Weapons.qc
  14. // Procedure: ImpulseCommands
  15. // Location: in the beginning of the function
  16. // Added: CheckGrapHook ();
  17. //--------------------------------------------------------------------
  18. // File: World.qc
  19. // Procedure: worldspawn
  20. // Location: after line "precache_model ("progs/s_spike.mdl");"
  21. // Added: precache_model ("progs/star.mdl");
  22. //        precache_model ("progs/bit.mdl");
  23. //--------------------------------------------------------------------
  24. // File: Weapons.qc
  25. // Procedure: W_Precache
  26. // Location: end of procedure
  27. // Added: precache_sound ("shambler/smack.wav");
  28. //        precache_sound ("blob/land1.wav");
  29. //--------------------------------------------------------------------
  30. // File: Defs.qc
  31. // Declaration group: player only fields
  32. // Location: after line ".float pain_finished;"
  33. // Added: .float hook;    
  34. //--------------------------------------------------------------------
  35.  
  36.  
  37. void(vector org, vector vel, float damage) SpawnBlood;    // prototype
  38. float () crandom;                               // prototype
  39.  
  40.  
  41. float    HOOK_OUT = 1;        // is hook currently extended? (bit flag)
  42. float    HOOK_ON = 2;        // is ACTIVE_HOOK impulse on? (bit flag)
  43. float ACTIVATE_HOOK = 98;    // impulse constant
  44. float    TERMINATE_HOOK = 97;    // impulse constant
  45.  
  46.  
  47. //--------------------------------------------------------------------
  48. // Disolves chain
  49. //--------------------------------------------------------------------
  50. void (entity Head) DisolveChain =
  51. {
  52.     local entity link;
  53.  
  54.     link = Head.goalentity;
  55.     while (link != world)
  56.     {
  57.         Head = link.goalentity;
  58.         remove (link);
  59.         link = Head;
  60.     }
  61. };
  62.  
  63.  
  64. //--------------------------------------------------------------------
  65. // Updated calculation of link positions
  66. //--------------------------------------------------------------------
  67. void () LinkPos =
  68. {
  69.     setorigin (self, self.owner.origin + ((self.enemy.origin + '0 0 16') - self.owner.origin) * self.weapon);
  70.     self.nextthink = time + 0.01;
  71. };
  72.  
  73.  
  74. //--------------------------------------------------------------------
  75. // Creates chain
  76. //--------------------------------------------------------------------
  77. entity (entity head, entity tail, float num) CreateChain =
  78. {
  79.     local entity link, prevlink;
  80.     local float linknum;
  81.  
  82.     linknum = num;
  83.     num = num + 1;
  84.     prevlink = world;
  85.     while (linknum > 0)
  86.     {
  87.         link = spawn();
  88.         link.goalentity = prevlink;
  89.         prevlink = link;
  90.         link.owner = head;
  91.         link.enemy = tail;
  92.         link.weapon = linknum / num;
  93.         link.movetype = MOVETYPE_NOCLIP;
  94.         link.solid = SOLID_NOT;
  95.         link.angles_z = 51 * linknum;
  96.         link.angles_y = 41 * linknum;
  97.         link.angles_x = 31 * linknum;
  98.         link.avelocity = '310 410 510';
  99.         setmodel (link, "progs/bit.mdl");
  100.         setsize (link, '0 0 0', '0 0 0');
  101.         setorigin (link, head.origin + ((tail.origin + '0 0 16') - head.origin) * link.weapon);
  102.         link.nextthink = time + 0.01;
  103.         link.think = LinkPos;
  104.         linknum = linknum - 1;
  105.     }
  106.     return link;
  107. };
  108.  
  109.  
  110. //--------------------------------------------------------------------
  111. // Removes star and detaches player
  112. //--------------------------------------------------------------------
  113. void () HookVanish =
  114. {
  115.     // removes flag of hook instance being present
  116.     self.owner.hook = self.owner.hook - (self.owner.hook & HOOK_OUT);
  117.         
  118.     DisolveChain (self);
  119.     remove (self);
  120. };
  121.  
  122.  
  123. //--------------------------------------------------------------------
  124. // Hook pulls player function
  125. //--------------------------------------------------------------------
  126. void () HookPull =
  127. {
  128.         local vector vel, spray;
  129.         local float v;
  130.  
  131.     if (     ((self.owner.hook & HOOK_ON) != HOOK_ON) || 
  132.         (self.owner.teleport_time > time) || 
  133.         (self.owner.deadflag) ||            // if player dies
  134.         (self.enemy.solid == SOLID_NOT)    )    // if target dies
  135.     {
  136.         HookVanish();
  137.         return;
  138.     }
  139.     
  140.     if (self.enemy.takedamage)
  141.         T_Damage (self.enemy, self, self.owner, 3);
  142.  
  143.     if (self.enemy.solid == SOLID_SLIDEBOX)
  144.     {
  145.         sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
  146.         spray_x = 100 * crandom();
  147.          spray_y = 100 * crandom();
  148.         spray_z = 100 * crandom() + 50;
  149.         SpawnBlood (self.origin, spray, 20);
  150.         setorigin (self, self.enemy.origin + self.enemy.mins + self.enemy.size * 0.5);
  151.     }
  152.  
  153.     self.velocity = self.enemy.velocity;
  154.         
  155.     vel = self.origin - (self.owner.origin + '0 0 16');
  156.     v = vlen (vel);
  157.     if (v <= 100)
  158.         vel = normalize(vel) * v * 7;  
  159.     if ( v > 100 )
  160.         vel = normalize(vel) * 700;  
  161.     self.owner.velocity = vel;
  162.     self.nextthink = time + 0.1;
  163. };
  164.  
  165.  
  166. //--------------------------------------------------------------------
  167. // Star's touch function
  168. //--------------------------------------------------------------------
  169. void() T_ChainTouch =
  170. {
  171.     if ((self.owner.hook & HOOK_ON) != HOOK_ON)
  172.     {
  173.         HookVanish();
  174.         return;
  175.     }
  176.  
  177.     if (other.takedamage)
  178.         T_Damage (other, self, self.owner, 10 );
  179.  
  180.      if (other.solid == SOLID_SLIDEBOX)
  181.     {
  182.         sound (self, CHAN_WEAPON, "shambler/smack.wav", 1, ATTN_NORM);    
  183.         SpawnBlood (self.origin, self.velocity, 10);
  184.         setorigin (self, other.origin + other.mins + other.size * 0.5);
  185.     }
  186.     else
  187.     {
  188.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  189.         self.avelocity = '0 0 0';
  190.     }
  191.  
  192.     self.velocity = other.velocity;
  193.  
  194.     self.enemy = other;
  195.     self.nextthink = time + 0.1;
  196.     self.think = HookPull;
  197.     self.touch = SUB_Null;
  198. };
  199.  
  200.  
  201. //--------------------------------------------------------------------
  202. // Shoots star
  203. //--------------------------------------------------------------------
  204. void(entity myself) W_FireChain =
  205. {
  206.     local entity star;
  207.  
  208.     star = spawn ();
  209.     star.owner = myself;
  210.     star.movetype = MOVETYPE_FLY;
  211.     star.solid = SOLID_BBOX;
  212.     setmodel (star, "progs/star.mdl");
  213.     setsize (star, '0 0 0', '0 0 0');     
  214.     makevectors (myself.v_angle);
  215.     setorigin (star, myself.origin + (v_forward*16) + '0 0 16' );
  216.     star.velocity = v_forward*1000;
  217.     star.angles = vectoangles(star.velocity);
  218.     star.avelocity = '0 0 600';
  219.     sound (myself, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  220.     
  221.     star.touch = T_ChainTouch;
  222.     star.nextthink = time + 0.7;     // reach length of grappling hook
  223.     star.think = HookVanish;
  224.     star.goalentity = CreateChain (star, myself, 8);
  225. };
  226.  
  227.  
  228. //--------------------------------------------------------------------
  229. // Checks impulse
  230. //--------------------------------------------------------------------
  231. void() CheckGrapHook = 
  232. {
  233.     if (((self.hook & HOOK_OUT) != HOOK_OUT) && (self.impulse == ACTIVATE_HOOK))
  234.     {
  235.         // flags that one instance of hook is spawned
  236.         self.hook = self.hook | HOOK_OUT;
  237.     
  238.         // flags last activated hook impulse as being ON 
  239.         self.hook = self.hook | HOOK_ON;   
  240.  
  241.         W_FireChain (self);
  242.         return;
  243.     }
  244.  
  245.     if (((self.hook & HOOK_OUT) == HOOK_OUT) && (self.impulse == TERMINATE_HOOK))
  246.     {
  247.         // flags last activated hook impulse as being OFF
  248.         self.hook = self.hook - (self.hook & HOOK_ON);
  249.         
  250.         return;
  251.     }
  252. };